Skip to main content

Copilot SDK におけるメッセージのステアリングとキューイング

アクティブな Copilot SDK セッションにメッセージを送信して、途中でそれを再設定したり、フォローアップタスクをキューに入れたりします。

この機能を使用できるユーザーについて

GitHub Copilot SDK は、すべての Copilot プランで使用できます。

メモ

          Copilot SDK は現在 テクニカル プレビューです。 機能と可用性は変更される場合があります。

エージェントが動作している間に、ユーザーは次の 2 つの対話パターンを利用してメッセージを送信できます。ステアリングは途中でエージェントの進行を変更し、キューイングは現在のターンが完了した後に順次処理 (先入れ先出し (FIFO)) のためにメッセージをバッファにキューイングします。

セッションがターンをアクティブに処理している場合、受信メッセージは、modeMessageOptions フィールドを使用して、次の 2 つのモードのいずれかで配信できます。

モード行動利用シーン
          `"immediate"` (ステアリング) | LLMの**現在の**ターンに挿入 | "実際には、そのファイルを作成しないでください。別のアプローチを使用してください" |

| "enqueue" (キューイング) | 現在のターンが終了した にキューに入れ、処理される | "この後、テストも修正します" |

ステアリングフローとキューフローのシーケンス図については、 github/copilot-sdk リポジトリを参照してください。

ステアリング (イミディエイト モード)

ステアリングは、エージェントの現在のターンに直接挿入されるメッセージを送信します。 エージェントはリアルタイムでメッセージを確認し、それに応じて応答を調整します。ターンを中止せずにコースの修正に役立ちます。

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 リポジトリを参照してください。

ステアリングの内部構造

  1. メッセージはランタイムの ImmediatePromptProcessor キューに追加されます。
  2. 現在のターン内の次の LLM 要求の前に、プロセッサはメッセージを会話に挿入します。
  3. エージェントは、ステアリング メッセージを新しいユーザー メッセージとして認識し、応答を調整します。
  4. ステアリング メッセージが処理される前にターンが完了すると、次のターンの通常のキューに自動的に移動されます。

メモ

メッセージの転送は、現在のターン内で可能な限りベストを尽くします。 エージェントが既にツール呼び出しにコミットしている場合、その呼び出しが完了した後でも同じターン内でステアリングが有効になります。

キューイング (エンキュー モード)

メッセージをキューに登録すると、現在のターンが終了した後に順に処理されます。 キューに登録された各メッセージは、独自のフル ターンを開始します。 これは既定のモードです。 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 リポジトリを参照してください。

キューイングの内部での動作

  1. メッセージは、セッションの itemQueueQueuedItemとして追加されます。
  2. 現在のターンが完了し、セッションがアイドル状態になると、 processQueuedItems() が実行されます。
  3. 項目は FIFO 順にデキューされます。各メッセージは完全なエージェントターンをトリガーします。
  4. ターンが終了したときにステアリング メッセージが保留中であった場合は、キューの先頭に移動されます。
  5. キューが空になるまで処理が続行され、セッションによってアイドル 状態のイベントが生成されます。

ステアリングとキューイングの組み合わせ

両方のパターンを 1 つのセッションで一緒に使用できます。 ステアリングは、キューに入ったメッセージが自分のターンを待機している間、現在のターンに影響します。

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 リポジトリを参照してください。

ステアリングとキューイングの選択

シナリオパターンなぜでしょうか
エージェントが間違った方向に進んでいるステアリング進行状況を失うことなく現在のターンをリダイレクトします
あなたは、エージェントが行うべきことを思いついた。キューイング現在の作業を中断しません。次に実行
エージェントが間違いを犯しようとしていますステアリング間違いが犯される前に介入する
複数のタスクを連結するキューイングFIFO の順序付けにより、予測可能な実行が保証されます
現在のタスクにコンテキストを追加するステアリングエージェントが自身の現在の推論に組み込む
関連のない要求をバッチ処理する場合キューイングそれぞれが明確なコンテキストで完全なターンを行います

ステアリングとキューを使用して 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 を使用して、セッションを誘導およびキューに登録できます。

メッセージオプション

Languageフィールドタイプデフォルト説明
Node.jsmode"enqueue" | "immediate""enqueue"メッセージ配信モード
PythonmodeLiteral["enqueue", "immediate"]"enqueue"メッセージ配信モード
GoModestring"enqueue"メッセージ配信モード
.NETModestring?"enqueue"メッセージ配信モード

配送モード

モード影響アクティブターン中待機中
"enqueue"次のターンの順番待ちFIFO キューでの待機新しいターンをすぐに開始する
"immediate"現在のターンに挿入する次の LLM 呼び出しの前に挿入新しいターンをすぐに開始する

メモ

セッションがアイドル状態 (未処理)、両方のモードが同じように動作します。メッセージはすぐに新しいターンを開始します。

ベスト プラクティス

  •         **既定ではキューに登録**されます。ほとんどのメッセージに対して `"enqueue"` (または省略 `mode`) を使用します。 これは予測可能であり、進行中の作業を中断するリスクはありません。
    
  •         **修正のためにステアリングを予約**する - エージェントが間違ったことを積極的に行っており、先に進む前にリダイレクトする必要がある場合は、 `"immediate"` を使用します。
    
  •         **指示メッセージを簡潔に保つ** - エージェントはコースの修正をすばやく理解する必要があります。 長く複雑なステアリング メッセージは、現在のコンテキストを混乱させる可能性があります。
    
  •         **オーバーステアを行わない** - 複数の迅速なステアリング メッセージによってターン品質が低下する可能性があります。 方向を大幅に変更する必要がある場合は、ターンを中止して新たに開始することを検討してください。
    
  •         **UI にキューの状態を表示**する - ユーザーが保留中の内容を把握できるように、キューに登録されたメッセージの数を表示します。 アイドル 状態のイベントをリッスンして、表示をクリアします。
    
  •         **ステアリングからキューへのフォールバックを処理**する - ターンが完了した後にステアリング メッセージが到着すると、自動的にキューに移動されます。 この遷移を反映するように UI を設計します。