Skip to main content
Skip to content

Рулевое управление и очередь

Два паттерна взаимодействия позволяют пользователям отправлять сообщения, пока агент уже работает: управление перенаправляет агента в середине хода, а очередь буферных сообщений для последовательной обработки после завершения текущего хода.

Обзор

Когда сессия активно обрабатывает ход, входящие сообщения могут доставляться в одном из двух режимов через mode поле на MessageOptions:

РежимBehaviorСценарий использования
"immediate" (рулевое управление)Вводится в текущий ход LLM«На самом деле, не создавай этот файл — используй другой подход»
"enqueue" (очередь)Поставлен в очередь и обработан после окончания текущего хода«После этого тоже починьте тесты»

Диаграмма: диаграмма последовательностей, показывающая описанный процесс.

Происхождение сообщений

Задайте необязательный источник при пересылке сообщения из другого агента. Определяемый источник агента сериализуется как agent-<id>. Оставьте исходный набор неустановленным для обычных пользователей, чтобы сохранить значения по умолчанию среды выполнения. Интерфейсы API отправки и ожидания поддерживают источник "enqueue" и "immediate" доставку.

SDKИдентифицированный источник агента
Node.js / TypeScriptsource: "agent-sender-id"
Pythonsource=AgentMessageSource("sender-id")
GoSource: copilot.MessageSourceAgent("sender-id")
.NETSource = MessageSource.Agent("sender-id")
Java.setSource(MessageSource.agent("sender-id"))
Rust.with_source(MessageSource::Agent("sender-id".into()))

Типизированные API также поддерживают user и system. Используется system для внутреннего контекста приложения, а не в качестве замены определяемого агента. Проверка подлинности агента позволяет среде выполнения различать входные данные агента от авторизации человека при сохранении поведения управления сообщениями агента. Наследуйте идентификатор отправителя из метаданных доверенного приложения, никогда не из текста сообщения.

Источник определяет источник. Срочность запросов в режиме доставки. Ни для того, чтобы получатель не создает видимый ответ, и источник не устанавливает флаги выставления счетов. Среда выполнения применяет существующие правила планирования. Вызывающие средства Rust, использующие типизированный API RPC, также могут передаваться MessageSource в rpc::SendRequest::with_source(...).

Успешное подтверждение высокого уровня send возвращает идентификатор сообщения и подтверждает принятие, а не то, что получатель использовал сообщение. Не перенаправлять принятое сообщение автоматически, так как ответ не отображается. Отправка и ожидание может завершиться бездействующего события без сообщения помощника.

Предупреждение

Удаленные серверные серверы не обязательно сохраняют конечный конечный источник. Сеанс агента может включать источник в локальное эхо без его переноса в удаленный HTTP-запрос. Локальное исходное событие не доказывает, что удаленный рабочий сотрудник получил то же доказательство.

Рулевое управление (режим мгновенности)

Управление посылает сообщение, которое вводится непосредственно в текущий оборот агента. Агент видит сообщение в реальном времени и корректирует его ответ — полезно для коррекции курса без прерывания хода.

Языки кода navigation

TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
    model: "gpt-5.4",
    onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Start a long-running task
const msgId = await session.send({
    prompt: "Refactor the authentication module to use sessions",
});

// While the agent is working, steer it
await session.send({
    prompt: "Actually, use JWT tokens instead of sessions",
    mode: "immediate",
});

Как работает внутреннее управление

  1. Сообщение добавляется в очередь ImmediatePromptProcessor времени выполнения
  2. Перед следующим запросом LLM в текущем ходу процессор вводит сообщение в разговор
  3. Агент воспринимает сообщение управления как сообщение нового пользователя и корректирует его ответ
  4. Если поворот завершается до обработки сообщения о рулевом управлении, он автоматически переводится в обычную очередь на следующий ход

Примечание.

Сообщения управления — это лучшее усилие в текущем ходу. Если агент уже выполнил вызов инструмента, управление вступает в силу после завершения этого вызова, но всё ещё в пределах того же хода.

Очередь (режим очереди)

Очередь буферизирует сообщения для последовательной обработки после завершения текущего хода. Каждое очередное сообщение начинает свой полный ход. Это режим по умолчанию — если пропустить mode, SDK использует "enqueue".

Языки кода navigation

TypeScript
import { CopilotClient } from "@github/copilot-sdk";

const client = new CopilotClient();
await client.start();

const session = await client.createSession({
    model: "gpt-5.4",
    onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Send an initial task
await session.send({ prompt: "Set up the project structure" });

// Queue follow-up tasks while the agent is busy
await session.send({
    prompt: "Add unit tests for the auth module",
    mode: "enqueue",
});

await session.send({
    prompt: "Update the README with setup instructions",
    mode: "enqueue",
});

// Messages are processed in FIFO order after each turn completes

Как работает внутренняя очередь

  1. Сообщение добавляется в сессии itemQueue в виде QueuedItem
  2. Когда текущий ход заканчивается и сессия становится бездействующей, processQueuedItems() запускается
  3. Элементы выставляются из очереди в порядке FIFO — каждое сообщение запускает полный агентный ход
  4. Если на момент окончания поворота сообщение о рулевом управлении было ожидаемым, оно перемещается в начало очереди
  5. Обработка продолжается до тех пор, пока очередь не опустеет, после чего сессия выпускает событие простоя

Совмещение рулевого управления и очереди

Вы можете использовать оба узора вместе за одну сессию. Управление влияет на текущий ход, пока сообщения в очереди ждут своих ходов:

Языки кода navigation

TypeScript
const session = await client.createSession({
    model: "gpt-5.4",
    onPermissionRequest: async () => ({ kind: "approve-once" }),
});

// Start a task
await session.send({ prompt: "Refactor the database layer" });

// Steer the current work
await session.send({
    prompt: "Make sure to keep backwards compatibility with the v1 API",
    mode: "immediate",
});

// Queue a follow-up for after this turn
await session.send({
    prompt: "Now add migration scripts for the schema changes",
    mode: "enqueue",
});

Выбор между рулём и очередью

ScenarioPatternПочему
Агент идёт по неправильному пути
Рулевое управлениеПеренаправляет текущий ход без потери прогресса
Вы придумали, что агент тоже должен сделать
ОчередьНе мешает текущей работе; Следующие сезоны
Агент вот-вот совершит ошибку
Рулевое управлениеВмешивается до совершения ошибки
Нужно объединять несколько задач в цепочку
ОчередьПорядок FIFO обеспечивает предсказуемое выполнение
Вы хотите добавить контекст к текущей задаче
Рулевое управлениеАгент включает это в свою текущую логику
Вы хотите делать пакетные несвязанные запросы
ОчередьКаждый из них получает свой полный ход с чистым контекстом

Создание интерфейса с управлением и очередями

Вот схема создания интерактивного интерфейса, поддерживающего оба режима:

import { CopilotClient, CopilotSession } from "@github/copilot-sdk";

interface PendingMessage {
    prompt: string;
    mode: "immediate" | "enqueue";
    sentAt: Date;
}

class InteractiveChat {
    private session: CopilotSession;
    private isProcessing = false;
    private pendingMessages: PendingMessage[] = [];

    constructor(session: CopilotSession) {
        this.session = session;

        session.on((event) => {
            if (event.type === "session.idle") {
                this.isProcessing = false;
                this.onIdle();
            }
            if (event.type === "assistant.message") {
                this.renderMessage(event);
            }
        });
    }

    async sendMessage(prompt: string): Promise<void> {
        if (!this.isProcessing) {
            this.isProcessing = true;
            await this.session.send({ prompt });
            return;
        }

        // Session is busy — let the user choose how to deliver
        // Your UI would present this choice (e.g., buttons, keyboard shortcuts)
    }

    async steer(prompt: string): Promise<void> {
        this.pendingMessages.push({
            prompt,
            mode: "immediate",
            sentAt: new Date(),
        });
        await this.session.send({ prompt, mode: "immediate" });
    }

    async enqueue(prompt: string): Promise<void> {
        this.pendingMessages.push({
            prompt,
            mode: "enqueue",
            sentAt: new Date(),
        });
        await this.session.send({ prompt, mode: "enqueue" });
    }

    private onIdle(): void {
        this.pendingMessages = [];
        // Update UI to show session is ready for new input
    }

    private renderMessage(event: unknown): void {
        // Render assistant message in your UI
    }
}

Справочник по API

MessageOptions

ЯзыкПолеТипПо умолчаниюDescription
Node.jsmode"enqueue" | "immediate""enqueue"Режим доставки сообщений
PythonmodeLiteral["enqueue", "immediate"]"enqueue"Режим доставки сообщений
GoModestring"enqueue"Режим доставки сообщений
.NETModestring?"enqueue"Режим доставки сообщений

Режимы доставки

РежимЭффектВо время активного поворотаВо время простоя
"enqueue"Очередь на следующий ходОжидания в очереди FIFOСразу начинает новый ход
"immediate"Впрыск в ход токаВведено перед следующим вызовом LLMСразу начинает новый ход

Примечание.

Когда сессия находится в режиме простоя (не обрабатывается), оба режима ведут себя одинаково — сообщение сразу начинает новый ход.

Лучшие практики

  1. По умолчанию очередь — используйте "enqueue" (или опускайте mode) для большинства сообщений. Это предсказуемо и не мешает работе в процессе.

  2. Резервируйте рулевое управление для исправлений — используйте "immediate" тогда, когда агент активно делает что-то не так, и вам нужно перенаправить его, прежде чем он пойдёт дальше.

  3. Держите сообщения управления лаконичными — агенту нужно быстро понять корректировку курса. Длинные, сложные сообщения управления могут запутать текущий контекст.

  4. Не переусердствуйте — несколько сообщений о быстром рулевом управлении могут ухудшить качество поворота. Если нужно сильно изменить направление, подумайте о том, чтобы прервать поворот и начать с чистого листа.

  5. Покажите состояние очереди в интерфейсе — откажите количество поставленных в очередь сообщений, чтобы пользователи знали, что ожидается. Прислушивайтесь к событиям простоя, чтобы очистить дисплей.

  6. Обрабатывайте запасной вариант руления в очередь — если после завершения поворота приходит сообщение о рулевом управлении, оно автоматически переносится в очередь. Спроектируйте свой интерфейс так, чтобы отражать этот переход.

См. также