- Файл Attachment (
type: "file"): предоставляет абсолютный путь; время выполнения считывает файл с диска, конвертирует его в base64 и отправляет в LLM. - Blob attachment (
type: "blob"): предоставляет данные с кодом base64 напрямую; полезно, когда изображение уже находится в памяти (например, скриншоты, сгенерированные изображения или данные из API).
Обзор

| Концепция | Description |
|---|---|
| Вложение файла | Вложение с type: "file" и абсолют path к образу на диске |
| Прикрепление в виде капли | Вложение с type: "blob", закодированным dataв базе 64 , и — mimeTypeне требуется дисковый ввод-вывод |
| Автоматическое кодирование | Для вложений файлов runtime считывает изображение и автоматически конвертирует его в base64 |
| Автоматическое изменение размера | Время выполнения автоматически изменяет или снижает качество изображений, превышающих специфические для модели ограничения |
| Возможности обзора | Модель должна capabilities.supports.vision = true обрабатывать изображения |
Быстрый старт — вложение файла
Прикрепите файл изображения к любому сообщению, используя тип вложения файла. Путь должен быть абсолютным путём к образу на диске.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session = await client.createSession({
model: "gpt-4.1",
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
await session.send({
prompt: "Describe what you see in this image",
attachments: [
{
type: "file",
path: "/absolute/path/to/screenshot.png",
},
],
});
from copilot import CopilotClient, PermissionDecisionApproveOnce
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
model="gpt-4.1",
)
await session.send(
"Describe what you see in this image",
attachments=[
{
"type": "file",
"path": "/absolute/path/to/screenshot.png",
},
],
)
package main
import (
"context"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
path := "/absolute/path/to/screenshot.png"
session.Send(ctx, copilot.MessageOptions{
Prompt: "Describe what you see in this image",
Attachments: []copilot.Attachment{
&copilot.UserMessageAttachmentFile{
DisplayName: "screenshot.png",
Path: path,
},
},
})
}
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
path := "/absolute/path/to/screenshot.png"
session.Send(ctx, copilot.MessageOptions{
Prompt: "Describe what you see in this image",
Attachments: []copilot.Attachment{
&copilot.UserMessageAttachmentFile{
DisplayName: "screenshot.png",
Path: path,
},
},
})
using GitHub.Copilot;
using GitHub.Copilot.Rpc;
public static class ImageInputExample
{
public static async Task Main()
{
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
OnPermissionRequest = (req, inv) =>
Task.FromResult(PermissionDecision.ApproveOnce()),
});
await session.SendAsync(new MessageOptions
{
Prompt = "Describe what you see in this image",
Attachments = new List<UserMessageAttachment>
{
new UserMessageAttachmentFile
{
Path = "/absolute/path/to/screenshot.png",
DisplayName = "screenshot.png",
},
},
});
}
}
using GitHub.Copilot;
using GitHub.Copilot.Rpc;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
OnPermissionRequest = (req, inv) =>
Task.FromResult(PermissionDecision.ApproveOnce()),
});
await session.SendAsync(new MessageOptions
{
Prompt = "Describe what you see in this image",
Attachments = new List<UserMessageAttachment>
{
new UserMessageAttachmentFile
{
Path = "/absolute/path/to/screenshot.png",
DisplayName = "screenshot.png",
},
},
});
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import java.util.List;
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
session.send(new MessageOptions()
.setPrompt("Describe what you see in this image")
.setAttachments(List.of(
new Attachment("file", "/absolute/path/to/screenshot.png", "screenshot.png")
))
).get();
}
Быстрый старт — прикрепление к каплям
Если у вас уже есть данные изображения в памяти (например, скриншот, сделанный вашим приложением, или изображение, полученное из API), используйте вложение blob, чтобы отправить их напрямую без записи на диск.
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
await client.start();
const session = await client.createSession({
model: "gpt-4.1",
onPermissionRequest: async () => ({ kind: "approve-once" }),
});
const base64ImageData = "..."; // your base64-encoded image
await session.send({
prompt: "Describe what you see in this image",
attachments: [
{
type: "blob",
data: base64ImageData,
mimeType: "image/png",
displayName: "screenshot.png",
},
],
});
from copilot import CopilotClient, PermissionDecisionApproveOnce
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),
model="gpt-4.1",
)
base64_image_data = "..." # your base64-encoded image
await session.send(
"Describe what you see in this image",
attachments=[
{
"type": "blob",
"data": base64_image_data,
"mimeType": "image/png",
"displayName": "screenshot.png",
},
],
)
package main
import (
"context"
copilot "github.com/github/copilot-sdk/go"
"github.com/github/copilot-sdk/go/rpc"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
client.Start(ctx)
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {
return &rpc.PermissionDecisionApproveOnce{}, nil
},
})
base64ImageData := "..."
mimeType := "image/png"
displayName := "screenshot.png"
session.Send(ctx, copilot.MessageOptions{
Prompt: "Describe what you see in this image",
Attachments: []copilot.Attachment{
&copilot.UserMessageAttachmentBlob{
Data: base64ImageData,
MIMEType: mimeType,
DisplayName: &displayName,
},
},
})
}
mimeType := "image/png"
displayName := "screenshot.png"
session.Send(ctx, copilot.MessageOptions{
Prompt: "Describe what you see in this image",
Attachments: []copilot.Attachment{
&copilot.UserMessageAttachmentBlob{
Data: base64ImageData, // base64-encoded string
MIMEType: mimeType,
DisplayName: &displayName,
},
},
})
using GitHub.Copilot;
using GitHub.Copilot.Rpc;
public static class BlobAttachmentExample
{
public static async Task Main()
{
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
OnPermissionRequest = (req, inv) =>
Task.FromResult(PermissionDecision.ApproveOnce()),
});
var base64ImageData = "...";
await session.SendAsync(new MessageOptions
{
Prompt = "Describe what you see in this image",
Attachments = new List<UserMessageAttachment>
{
new UserMessageAttachmentBlob
{
Data = base64ImageData,
MimeType = "image/png",
DisplayName = "screenshot.png",
},
},
});
}
}
await session.SendAsync(new MessageOptions
{
Prompt = "Describe what you see in this image",
Attachments = new List<UserMessageAttachment>
{
new UserMessageAttachmentBlob
{
Data = base64ImageData,
MimeType = "image/png",
DisplayName = "screenshot.png",
},
},
});
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
import java.util.List;
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(
new SessionConfig()
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
var base64ImageData = "..."; // your base64-encoded image
session.send(new MessageOptions()
.setPrompt("Describe what you see in this image")
.setAttachments(List.of(
new BlobAttachment()
.setData(base64ImageData)
.setMimeType("image/png")
.setDisplayName("screenshot.png")
))
).get();
}
Поддерживаемые форматы
Поддерживаемые форматы изображений включают JPG, PNG, GIF и другие распространённые типы изображений. Для вложения файлов среда выполнения считывает образ с диска и конвертирует его по необходимости. Для blob-вложений вы предоставляете данные base64 и тип MIME напрямую. Используйте PNG или JPEG для наилучших результатов, так как это самые популярные форматы.
Поле capabilities.limits.vision.supported_media_types модели показывает точные типы MIME, которые она принимает.
Автоматическая обработка
Среда выполнения автоматически обрабатывает изображения, соответствующие ограничениям модели. Ручное изменение размера не требуется.
- Изображения, превышающие лимиты размеров или размеров модели, автоматически изменяются (сохраняя соотношение сторон) или уменьшаются по качеству.
- Если изображение не может быть перенесено в пределы ограничений после обработки, оно пропускается и не отправляется в LLM.
- Поле модели
capabilities.limits.vision.max_prompt_image_sizeуказывает максимальный размер изображения в байтах.
Вы можете проверить эти ограничения во время выполнения через объект возможностей модели. Для лучшего опыта используйте изображения разумного размера в формате PNG или JPEG.
Возможности модели зрения
Не все модели поддерживают зрение. Проверьте возможности модели перед отправкой изображений.
Поля возможностей
| Поле | Тип | Description |
|---|---|---|
capabilities.supports.vision | boolean | Может ли модель обрабатывать входные изображения |
capabilities.limits.vision.supported_media_types | string[] | Типы MIME, которые принимает модель (например, ["image/png", "image/jpeg"]) |
capabilities.limits.vision.max_prompt_images | number | Максимальное количество изображений в каждом запросе |
capabilities.limits.vision.max_prompt_image_size | number | Максимальный размер изображения в байтах |
Тип ограничений зрения
interface VisionCapabilities {
vision?: {
supported_media_types: string[];
max_prompt_images: number;
max_prompt_image_size: number; // bytes
};
}
vision?: {
supported_media_types: string[];
max_prompt_images: number;
max_prompt_image_size: number; // bytes
};
Получение изображений
Когда инструменты возвращают изображения (например, скриншоты или сгенерированные диаграммы), результат содержит "image" блоки контента с данными, закодированными в base64.
| Поле | Тип | Description |
|---|---|---|
type | "image" | Дискриминатор типа блока контента |
data | string | Данные изображений, закодированных в Base64, |
mimeType | string | Тип MIME (например, "image/png") |
Эти блоки изображений появляются в tool.execution_complete результатах событий. Смотрите руководство AUTOTITLE , чтобы узнать полный жизненный цикл события.
Советы и ограничения
| Tip | Details |
|---|---|
| Используйте PNG или JPEG напрямую | Избегает накладных расходов на конвертацию — эти данные отправляются в LLM as-is |
| Держите изображения разумного размера | Большие изображения могут быть снижены по качеству, что приводит к потере важных деталей |
| Используйте абсолютные пути для вложения файлов | Среда выполнения читает файлы с диска; Относительные пути могут неправильно разрешиться |
| Используйте вложения blob для данных в памяти | Когда у вас уже есть данные base64 (например, скриншоты, ответы API), blob избегает ненужного дискового ввода-вывода |
| Сначала проверьте поддержку зрения | Отправка изображений в модель без зрения приводит к трате токен без визуального понимания |
| Поддерживается несколько изображений | Прикрепите несколько вложений в одном сообщении, до предела лимита max_prompt_images модели |
| SVG не поддерживается | SVG-файлы являются текстовыми и не подлежат обработке изображений |
См. также
- События потоковых сессий: жизненный цикл события, включая блоки содержимого результатов инструментов
- Рулевое управление и очередь: отправка последующих сообщений с вложениями