跳至主要内容

在 Copilot SDK 中进行 Steering 与 Queueing 消息

向活动的 Copilot SDK 会话发送消息,以在回合中途重定向或排队后续任务。

谁可以使用此功能?

GitHub Copilot SDK 在所有 Copilot 计划中均可使用。

注意

Copilot SDK 目前处于公开预览阶段。功能和可用性可能会更改。

有两种交互模式允许用户在代理已经工作时发送消息:steering 在回合进行中重定向代理,queueing 则在当前回合完成后,将消息缓冲起来按顺序(先进先出(FIFO))处理。

当会话正在积极处理一个回合时,传入的消息可以通过 MessageOptions 上的 mode 字段以两种模式之一进行投递。

模式行为使用场景
"immediate"(steering)注入到 当前 LLM 回合中"Actually, don't create that file—use a different approach"
"enqueue"(queueing)在当前回合结束后 排队并处理"After this, also fix the tests"

有关 steering 与 queueing 流程的时序图,请参阅 github/copilot-sdk 仓库

Steering(即时模式)

Steering 发送的消息会直接注入到代理当前的回合中。代理实时看到该消息并相应地调整其响应——这对于在不中止回合的情况下进行方向校正非常有用。

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: "approved" }),
});

// 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",
});

关于 Python、Go 和 .NET 的示例,请参阅 github/copilot-sdk 仓库。Java 示例请参阅 github/copilot-sdk-java 仓库

Steering 的内部工作原理

  1. 该消息被添加到运行时的 ImmediatePromptProcessor 队列中。
  2. 在当前回合的下一个 LLM 请求之前,处理器会将该消息注入对话中。
  3. 代理将 steering 消息视为新的用户消息并调整其响应。
  4. 如果回合在 steering 消息处理之前完成,它会自动移至常规队列,等待下一个回合。

注意

Steering 消息在当前回合内以尽力而为的方式处理。如果代理已经提交了工具调用,steering 会在该调用完成后生效,但仍然在同一回合内。

Queueing(入队模式)

Queueing 将消息缓冲,以在当前回合结束后顺序处理。每条排队的消息都会启动其自己的完整回合。这是默认模式——如果省略 mode,SDK 将使用 "enqueue"

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: "approved" }),
});

// 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

关于 Python、Go 和 .NET 的示例,请参阅 github/copilot-sdk 仓库。Java 示例请参阅 github/copilot-sdk-java 仓库

Queueing 的内部工作原理

  1. 该消息作为 QueuedItem 被添加到会话的 itemQueue 中。
  2. 当当前回合完成且会话进入空闲状态时,processQueuedItems() 将运行。
  3. 项目按 FIFO 顺序出队——每条消息都会触发一次完整的代理回合。
  4. 如果回合结束时有 pending 的 steering 消息,它会被移动到队列前端。
  5. 处理将持续进行,直至队列为空,此后会话会发出空闲事件。

组合 Steering 与 Queueing

可以在同一会话中同时使用这两种模式。Steering 影响当前回合,而排队的消息则等待它们各自的回合。

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

// 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",
});

以下是 Python 示例,请参阅 github/copilot-sdk 仓库。Java 示例请参阅 github/copilot-sdk-java 仓库

在 Steering 与 Queueing 之间的选择

情形模式为什么
代理走上了错误的路径Steering在不丢失进度的情况下重定向当前回合
你想到了一件代理也应该做的事Queueing不干扰当前工作;随即在之后执行
代理即将犯错Steering在错误提交前进行干预
你想要串联多个任务QueueingFIFO 顺序确保可预测的执行
你想为当前任务添加上下文Steering代理将其纳入当前推理中
你想批量处理不相关的请求Queueing每个请求都有自己的完整回合和干净的上下文

使用 Steering 与 Queueing 构建 UI

以下是构建支持两种模式的交互式 UI 的模式示例

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 参考

您可以使用 Copilot SDK 会话 API 对会话进行 steering 与 queueing。

MessageOptions

语言字段类型默认值描述
Node.jsmode"enqueue" | "immediate""enqueue"消息投递模式
PythonmodeLiteral["enqueue", "immediate"]"enqueue"消息投递模式
Go模式string"enqueue"消息投递模式
.NET模式string?"enqueue"消息投递模式

投递模式

模式效果在活跃回合期间在空闲期间
"enqueue"排队等待下一个回合在 FIFO 队列中等待立即启动新回合
"immediate"注入到当前回合在下一个 LLM 调用前注入立即启动新回合

注意

当会话处于空闲(未处理)状态时,两种模式表现相同——消息会立即启动新回合。

最佳实践

  • 默认使用 queueing——对大多数消息使用 "enqueue"(或省略 mode)。这种方式可预测且不会冒险中断正在进行的工作。
  • 将 steering 留给纠正使用——当代理正在执行错误操作且需要在其进一步进行之前进行重定向时,使用 "immediate"
  • 保持 steering 消息简洁——代理需要快速理解方向校正。过长或复杂的 steering 消息可能会扰乱当前上下文。
  • 避免过度 steering——频繁的快速 steering 消息会降低回合质量。如果需要显著改变方向,考虑中止当前回合并重新开始。
  • 在 UI 中显示队列状态——展示排队消息的数量,让用户了解待处理内容。监听空闲事件以清除显示。
  • 处理 steering 转为 queue 的回退情况——如果在回合完成后收到 steering 消息,它会自动转入队列。请在 UI 设计中体现此转变。
© . This site is unofficial and not affiliated with GitHub, Inc.