{"meta":{"title":"Steuerung und Warteschlangen","intro":"Zwei Interaktionsmuster ermöglichen es Benutzern, Nachrichten zu senden, während der Agent bereits arbeitet: Steuerung leitet den Agent mitten in der Runde um, und Warteschlange puffert Nachrichten für die sequentielle Verarbeitung, nachdem die aktuelle Runde abgeschlossen ist.","product":"GitHub Copilot","breadcrumbs":[{"href":"/de/enterprise-cloud@latest/copilot","title":"GitHub Copilot"},{"href":"/de/enterprise-cloud@latest/copilot/how-tos","title":"Vorgehensweisen"},{"href":"/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk","title":"Copilot SDK"},{"href":"/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features","title":"Funktionen"},{"href":"/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/steering-and-queueing","title":"Steuerung und Warteschlangenverwaltung"}],"documentType":"article"},"body":"# Steuerung und Warteschlangen\n\nZwei Interaktionsmuster ermöglichen es Benutzern, Nachrichten zu senden, während der Agent bereits arbeitet: Steuerung leitet den Agent mitten in der Runde um, und Warteschlange puffert Nachrichten für die sequentielle Verarbeitung, nachdem die aktuelle Runde abgeschlossen ist.\n\n<!-- markdownlint-disable GHD046 GHD005 -->\n\n<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->\n\n## Übersicht\n\nWenn eine Sitzung aktiv eine Runde verarbeitet, können eingehende Nachrichten in einem von zwei Modi über das Feld `mode` auf `MessageOptions` zugestellt werden:\n\n| Modus                        | Behavior                                                                          | Anwendungsfall                                                                     |\n| ---------------------------- | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |\n| `\"immediate\"` (Lenkung)      | In den **aktuellen** LLM-Turn eingeschleust                                       | \"Erstellen Sie diese Datei tatsächlich nicht – verwenden Sie einen anderen Ansatz\" |\n| `\"enqueue\"` (Warteschlangen) | In Warteschlange gestellt und verarbeitet **nach** Beendigung der aktuellen Runde | „Danach korrigieren der Tests“                                                     |\n\n![Diagramm: Sequenzdiagramm mit dem beschriebenen Prozess.](/assets/images/help/copilot/copilot-sdk/features-steering-and-queueing-diagram-0.png)\n\n## Lenkung (Sofortiger Modus)\n\nDie Lenkung sendet eine Nachricht, die direkt in den aktuellen Spielzug des Agenten eingespeist wird. Der Agent sieht die Nachricht in Echtzeit und passt seine Antwort entsprechend an – nützlich für die Kurskorrektur, ohne die Drehung abzubrechen.\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nawait client.start();\n\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Start a long-running task\nconst msgId = await session.send({\n    prompt: \"Refactor the authentication module to use sessions\",\n});\n\n// While the agent is working, steer it\nawait session.send({\n    prompt: \"Actually, use JWT tokens instead of sessions\",\n    mode: \"immediate\",\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient, PermissionDecisionApproveOnce\n\nasync def main():\n    client = CopilotClient()\n    await client.start()\n\n    session = await client.create_session(\n        on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n        model=\"gpt-5.4\",\n    )\n\n    # Start a long-running task\n    msg_id = await session.send(\n        \"Refactor the authentication module to use sessions\",\n    )\n\n    # While the agent is working, steer it\n    await session.send(\n        \"Actually, use JWT tokens instead of sessions\",\n        mode=\"immediate\",\n    )\n\n    await client.stop()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    copilot \"github.com/github/copilot-sdk/go\"\n    \"github.com/github/copilot-sdk/go/rpc\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    client := copilot.NewClient(nil)\n    if err := client.Start(ctx); err != nil {\n        log.Fatal(err)\n    }\n    defer client.Stop()\n\n    session, err := client.CreateSession(ctx, &copilot.SessionConfig{\n        Model: \"gpt-5.4\",\n        OnPermissionRequest: func(req copilot.PermissionRequest, inv copilot.PermissionInvocation) (rpc.PermissionDecision, error) {\n            return &rpc.PermissionDecisionApproveOnce{}, nil\n        },\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Start a long-running task\n    _, err = session.Send(ctx, copilot.MessageOptions{\n        Prompt: \"Refactor the authentication module to use sessions\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // While the agent is working, steer it\n    _, err = session.Send(ctx, copilot.MessageOptions{\n        Prompt: \"Actually, use JWT tokens instead of sessions\",\n        Mode:   \"immediate\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n}\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\nusing GitHub.Copilot;\nusing GitHub.Copilot.Rpc;\n\nawait using var client = new CopilotClient();\nawait using var session = await client.CreateSessionAsync(new SessionConfig\n{\n    Model = \"gpt-5.4\",\n    OnPermissionRequest = (req, inv) =>\n        Task.FromResult(PermissionDecision.ApproveOnce()),\n});\n\n// Start a long-running task\nvar msgId = await session.SendAsync(new MessageOptions\n{\n    Prompt = \"Refactor the authentication module to use sessions\"\n});\n\n// While the agent is working, steer it\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Actually, use JWT tokens instead of sessions\",\n    Mode = \"immediate\"\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\ntry (var client = new CopilotClient()) {\n    client.start().get();\n\n    var session = client.createSession(\n        new SessionConfig()\n            .setModel(\"gpt-5.4\")\n            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n    ).get();\n\n    // Start a long-running task\n    session.send(new MessageOptions()\n        .setPrompt(\"Refactor the authentication module to use sessions\")\n    ).get();\n\n    // While the agent is working, steer it\n    session.send(new MessageOptions()\n        .setPrompt(\"Actually, use JWT tokens instead of sessions\")\n        .setMode(\"immediate\")\n    ).get();\n}\n```\n\n</div>\n\n</div>\n\n### Funktionsweise der Steuerung intern\n\n1. Die Nachricht wird der `ImmediatePromptProcessor`-Warteschlange der Runtime hinzugefügt.\n2. Vor der nächsten LLM-Anfrage innerhalb des aktuellen Turns fügt der Prozessor die Nachricht in die Konversation ein.\n3. Der Agent sieht die Lenkungsnachricht als neue Benutzernachricht und passt seine Antwort an.\n4. Wenn der Abbiegevorgang abgeschlossen ist, bevor die Lenknachricht verarbeitet wird, wird er automatisch für den nächsten Abbiegevorgang in die reguläre Warteschlange verschoben.\n\n> \\[!NOTE]\n> Steuerungsnachrichten werden innerhalb der aktuellen Runde nach bestem Wissen und Gewissen bearbeitet. Wenn der Agent bereits einen Tool-Aufruf kommittiert hat, wird die Lenkung erst nach Abschluss dieses Aufrufs, aber noch innerhalb derselben Runde wirksam.\n\n## Warteschlangen (Enqueue-Modus)\n\nIn der Warteschlange werden Nachrichten gepuffert, die nach Abschluss der aktuellen Runde der Reihe nach verarbeitet werden. Jede in die Warteschlange eingereihte Nachricht startet einen eigenen vollständigen Durchlauf. Dies ist der Standardmodus – wenn Sie weglassen `mode`, verwendet `\"enqueue\"`das SDK .\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nimport { CopilotClient } from \"@github/copilot-sdk\";\n\nconst client = new CopilotClient();\nawait client.start();\n\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Send an initial task\nawait session.send({ prompt: \"Set up the project structure\" });\n\n// Queue follow-up tasks while the agent is busy\nawait session.send({\n    prompt: \"Add unit tests for the auth module\",\n    mode: \"enqueue\",\n});\n\nawait session.send({\n    prompt: \"Update the README with setup instructions\",\n    mode: \"enqueue\",\n});\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nfrom copilot import CopilotClient, PermissionDecisionApproveOnce\n\nasync def main():\n    client = CopilotClient()\n    await client.start()\n\n    session = await client.create_session(\n        on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n        model=\"gpt-5.4\",\n    )\n\n    # Send an initial task\n    await session.send(\"Set up the project structure\")\n\n    # Queue follow-up tasks while the agent is busy\n    await session.send(\n        \"Add unit tests for the auth module\",\n        mode=\"enqueue\",\n    )\n\n    await session.send(\n        \"Update the README with setup instructions\",\n        mode=\"enqueue\",\n    )\n\n    # Messages are processed in FIFO order after each turn completes\n    await client.stop()\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"go\" data-label=\"Go\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Go</div>\n\n```golang\n// Send an initial task\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Set up the project structure\",\n})\n\n// Queue follow-up tasks while the agent is busy\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Add unit tests for the auth module\",\n    Mode:   \"enqueue\",\n})\n\nsession.Send(ctx, copilot.MessageOptions{\n    Prompt: \"Update the README with setup instructions\",\n    Mode:   \"enqueue\",\n})\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"dotnet\" data-label=\".NET\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">.NET</div>\n\n```csharp\n// Send an initial task\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Set up the project structure\"\n});\n\n// Queue follow-up tasks while the agent is busy\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Add unit tests for the auth module\",\n    Mode = \"enqueue\"\n});\n\nawait session.SendAsync(new MessageOptions\n{\n    Prompt = \"Update the README with setup instructions\",\n    Mode = \"enqueue\"\n});\n\n// Messages are processed in FIFO order after each turn completes\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"java\" data-label=\"Java\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Java</div>\n\n```java\nimport com.github.copilot.CopilotClient;\nimport com.github.copilot.rpc.*;\n\ntry (var client = new CopilotClient()) {\n    client.start().get();\n\n    var session = client.createSession(\n        new SessionConfig()\n            .setModel(\"gpt-5.4\")\n            .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)\n    ).get();\n\n    // Send an initial task\n    session.send(new MessageOptions().setPrompt(\"Set up the project structure\")).get();\n\n    // Queue follow-up tasks while the agent is busy\n    session.send(new MessageOptions()\n        .setPrompt(\"Add unit tests for the auth module\")\n        .setMode(\"enqueue\")\n    ).get();\n\n    session.send(new MessageOptions()\n        .setPrompt(\"Update the README with setup instructions\")\n        .setMode(\"enqueue\")\n    ).get();\n\n    // Messages are processed in FIFO order after each turn completes\n}\n```\n\n</div>\n\n</div>\n\n### Wie die Warteschlange intern funktioniert\n\n1. Die Nachricht wird dem `itemQueue` der Sitzung als `QueuedItem` hinzugefügt.\n2. Wenn die aktuelle Runde abgeschlossen ist und die Sitzung inaktiv wird, wird `processQueuedItems()` ausgeführt\n3. Die Nachrichten werden in der FIFO-Reihenfolge abgearbeitet – jede Nachricht triggert eine vollständige Runde des Agenten\n4. Wenn bei Beendigung der Runde eine Steuerungsnachricht anstand, wird sie an den Anfang der Warteschlange verschoben\n5. Die Verarbeitung wird fortgesetzt, bis die Warteschlange leer ist, und dann gibt die Sitzung ein Leerlaufereignis aus.\n\n## Kombination von Steuerung und Warteschlangenverwaltung\n\nSie können beide Muster in einer einzigen Sitzung verwenden. Die Steuerung wirkt sich auf die aktuelle Runde aus, während die Nachrichten in der Warteschlange auf ihre eigene Runde warten:\n\n<div class=\"ghd-codetabs\">\n<div class=\"ghd-codetab\" data-lang=\"typescript\" data-label=\"TypeScript\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">TypeScript</div>\n\n```typescript\nconst session = await client.createSession({\n    model: \"gpt-5.4\",\n    onPermissionRequest: async () => ({ kind: \"approve-once\" }),\n});\n\n// Start a task\nawait session.send({ prompt: \"Refactor the database layer\" });\n\n// Steer the current work\nawait session.send({\n    prompt: \"Make sure to keep backwards compatibility with the v1 API\",\n    mode: \"immediate\",\n});\n\n// Queue a follow-up for after this turn\nawait session.send({\n    prompt: \"Now add migration scripts for the schema changes\",\n    mode: \"enqueue\",\n});\n```\n\n</div>\n\n<div class=\"ghd-codetab\" data-lang=\"python\" data-label=\"Python\"><div class=\"ghd-codetab-fallback-label\" role=\"heading\" aria-level=\"3\">Python</div>\n\n```python\nsession = await client.create_session(\n    on_permission_request=lambda req, inv: PermissionDecisionApproveOnce(),\n    model=\"gpt-5.4\",\n)\n\n# Start a task\nawait session.send(\"Refactor the database layer\")\n\n# Steer the current work\nawait session.send(\n    \"Make sure to keep backwards compatibility with the v1 API\",\n    mode=\"immediate\",\n)\n\n# Queue a follow-up for after this turn\nawait session.send(\n    \"Now add migration scripts for the schema changes\",\n    mode=\"enqueue\",\n)\n```\n\n</div>\n\n</div>\n\n## Auswahl zwischen Lenkung und Warteschlangen\n\n| Szenario                                                    | Pattern                                                             | Warum? |\n| ----------------------------------------------------------- | ------------------------------------------------------------------- | ------ |\n| Der Agent geht auf den falschen Pfad.                       |                                                                     |        |\n| **Lenkung**                                                 | Leitet den aktuellen Vorgang um, ohne den Fortschritt zu verlieren  |        |\n| Sie dachten an etwas, was der Agent auch tun sollte         |                                                                     |        |\n| **Warteschlangenbildung**                                   | Unterbricht die aktuelle Arbeit nicht; wird als nächstes ausgeführt |        |\n| Agent ist dabei, einen Fehler zu machen                     |                                                                     |        |\n| **Lenkung**                                                 | Greift ein, bevor der Fehler begangen wird                          |        |\n| Sie möchten mehrere Vorgänge verketten                      |                                                                     |        |\n| **Warteschlangenbildung**                                   | FIFO-Sortierung gewährleistet vorhersehbare Ausführung              |        |\n| Sie möchten der aktuellen Aufgabe Kontext hinzufügen        |                                                                     |        |\n| **Lenkung**                                                 | Der Agent bezieht sie in sein aktuelles Reasoning ein               |        |\n| Sie möchten unverbundene Anfragen in Batches zusammenfassen |                                                                     |        |\n| **Warteschlangenbildung**                                   | Jede erhält ihre eigene vollständige Runde mit sauberem Kontext     |        |\n\n## Erstellen einer Benutzeroberfläche mit Steuerung und Warteschlangen\n\nHier ist ein Muster zum Erstellen einer interaktiven Benutzeroberfläche, die beide Modi unterstützt:\n\n```typescript\nimport { CopilotClient, CopilotSession } from \"@github/copilot-sdk\";\n\ninterface PendingMessage {\n    prompt: string;\n    mode: \"immediate\" | \"enqueue\";\n    sentAt: Date;\n}\n\nclass InteractiveChat {\n    private session: CopilotSession;\n    private isProcessing = false;\n    private pendingMessages: PendingMessage[] = [];\n\n    constructor(session: CopilotSession) {\n        this.session = session;\n\n        session.on((event) => {\n            if (event.type === \"session.idle\") {\n                this.isProcessing = false;\n                this.onIdle();\n            }\n            if (event.type === \"assistant.message\") {\n                this.renderMessage(event);\n            }\n        });\n    }\n\n    async sendMessage(prompt: string): Promise<void> {\n        if (!this.isProcessing) {\n            this.isProcessing = true;\n            await this.session.send({ prompt });\n            return;\n        }\n\n        // Session is busy — let the user choose how to deliver\n        // Your UI would present this choice (e.g., buttons, keyboard shortcuts)\n    }\n\n    async steer(prompt: string): Promise<void> {\n        this.pendingMessages.push({\n            prompt,\n            mode: \"immediate\",\n            sentAt: new Date(),\n        });\n        await this.session.send({ prompt, mode: \"immediate\" });\n    }\n\n    async enqueue(prompt: string): Promise<void> {\n        this.pendingMessages.push({\n            prompt,\n            mode: \"enqueue\",\n            sentAt: new Date(),\n        });\n        await this.session.send({ prompt, mode: \"enqueue\" });\n    }\n\n    private onIdle(): void {\n        this.pendingMessages = [];\n        // Update UI to show session is ready for new input\n    }\n\n    private renderMessage(event: unknown): void {\n        // Render assistant message in your UI\n    }\n}\n```\n\n## API-Referenz\n\n### Nachrichtenoptionen\n\n| Sprache | Feld   | Typ                               | Vorgabe     | Description                   |\n| ------- | ------ | --------------------------------- | ----------- | ----------------------------- |\n| Node.js | `mode` | `\"enqueue\" \\| \"immediate\"`        | `\"enqueue\"` | Nachrichtenübermittlungsmodus |\n| Python  | `mode` | `Literal[\"enqueue\", \"immediate\"]` | `\"enqueue\"` | Nachrichtenübermittlungsmodus |\n| Go      | `Mode` | `string`                          | `\"enqueue\"` | Nachrichtenübermittlungsmodus |\n| .NET    | `Mode` | `string?`                         | `\"enqueue\"` | Nachrichtenübermittlungsmodus |\n\n### Liefermodi\n\n| Modus         | Auswirkung                         | Während einer aktiven Drehung         | Während des Leerlaufs             |\n| ------------- | ---------------------------------- | ------------------------------------- | --------------------------------- |\n| `\"enqueue\"`   | Warteschlange für nächsten Schritt | Wartezeiten in der FIFO-Warteschlange | Startet sofort eine neue Drehung. |\n| `\"immediate\"` | In die aktuelle Runde einfügen     | Vor dem nächsten LLM-Aufruf eingefügt | Startet sofort eine neue Drehung. |\n\n> \\[!NOTE]\n> Wenn sich die Sitzung im Leerlauf befindet (keine Verarbeitung), verhalten sich beide Modi identisch – die Nachricht startet sofort eine neue Drehung.\n\n## Bewährte Methoden\n\n1. **Standard für Warteschlangen**-Verwenden Sie `\"enqueue\"` (oder lassen Sie `mode` weg) für die meisten Nachrichten. Es ist vorhersagbar und riskiert keine Unterbrechung der laufenden Arbeit.\n\n2. **Behalten Sie sich die Steuerung für Korrekturen vor** – Verwenden Sie `\"immediate\"`, wenn der Agent aktiv fehlerhaft handelt und Sie ihn korrigieren müssen, bevor es weitergeht.\n\n3. **Halten Sie die Lenkungsnachrichten kurz –** Der Agent muss die Kurskorrektur schnell verstehen. Lange, komplexe Lenkungsmeldungen können den aktuellen Kontext verwirren.\n\n4. **Nicht übersteuern** – Mehrere schnelle Lenkmeldungen können die Drehqualität beeinträchtigen. Wenn Sie die Richtung erheblich ändern müssen, sollten Sie die Drehung abbrechen und neu beginnen.\n\n5. **Anzeigen des Warteschlangenstatus in der Benutzeroberfläche** – Zeigen Sie die Anzahl der in die Warteschlange eingereihten Nachrichten an, damit Benutzer wissen, was aussteht. Warten Sie auf Idle-Ereignisse, um die Anzeige zu löschen.\n\n6. **Handhaben Sie den Fallback von Steuerung zu Warteschlange**-Wenn eine Nachricht zur Steuerung eintrifft, nachdem die Runde abgeschlossen ist, wird sie automatisch in die Warteschlange verschoben. Entwerfen Sie Ihre Benutzeroberfläche so, dass sie diesen Übergang widerspiegelt.\n\n## Siehe auch\n\n* [Erstellen Sie Ihre erste Copilot-gestützte App](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/getting-started): Einrichten einer Sitzung und Senden von Nachrichten\n* [Angepasste Agents und Orchestrierung von Unteragenten](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/custom-agents): Spezialisierte Agenten mit abgegrenzten Tools definieren\n* [Sitzungshaken](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/hooks/hooks-overview): Reagieren auf Sitzungslebenszyklusereignisse\n* [Wiederaufnahme und Persistenz der Sitzung](/de/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/features/session-persistence): Fortsetzen von Sitzungen über Neustarts hinweg"}