Agent-Client-Protokoll-Architektur
ACP standardisiert die Beziehung zwischen einer Coding-Oberfläche und einem Coding-Agenten. Es gibt ihnen eine gemeinsame Möglichkeit, Fähigkeiten zu etablieren, eine Projektsitzung zu öffnen, Prompts auszutauschen, Fortschritt zu streamen, Berechtigungen anzufordern, Arbeit abzubrechen und die Sitzung zu schließen oder fortzusetzen.
Die zwei Rollen
| Rolle | Verantwortlichkeiten |
|---|---|
| Client / Host | Startet den Agentenprozess, stellt die menschliche Oberfläche bereit, wählt den Workspace aus, stellt optionale Dateien, Terminals und MCP-Server bereit, wendet die Berechtigungsrichtlinie an und rendert Live-Updates |
| ACP-Agent | Nimmt Projektsitzungen und Prompts an, führt Codierungsarbeiten aus, meldet Nachrichten und Tool-Aktivitäten, fragt bei Bedarf nach Berechtigungen und gibt einen typisierten Stoppgrund zurück |
ADK-Rust kann beide Rollen einnehmen. Das sind zwei Bereitstellungsrichtungen, nicht zwei verschiedene Protokolle.
Wenn ADK-Rust einen anderen Coding-Agenten konsumiert, ist die linke Seite ADK-Rust und die
rechte Seite der externe Prozess. Wenn ein Editor einen ADK-Rust-Agenten konsumiert,
besitzt der Editor die linke Seite und AcpServer besitzt die rechte Seite.
Ein ACP-Durchlauf
Die Verbindung ist bidirektional. Ein Client muss weiter lesen, während ein Prompt läuft, weil der Agent vor der endgültigen Prompt-Antwort Benachrichtigungen oder Berechtigungsanfragen senden kann.
Sitzungsidentität und Zustand
Eine ACP-Sitzung identifiziert eine fortlaufende Unterhaltung über ein Projekt.
Sie enthält ein absolutes cwd, optionale zusätzliche Verzeichnisse, mehrere Prompts,
gestreamte Updates und einen Lebenszyklus. Im Server ADK-Rust wird eine ACP-Sitzung
einer ADK-Rust-Sitzung zugeordnet, damit Modellhistorie und Sitzungszustand an derselben
Unterhaltung hängen bleiben.
Das Schließen einer aktiven Verbindung ist etwas anderes als das Löschen persistierter Historie:
session/closegibt die aktive Sitzung und ihre Prozesse frei;session/resumehängt an den persistierten ADK-Sitzungszustand an;session/loadreaktiviert eine persistierte Sitzung und spielt ihre gespeicherte Unterhaltung dem Client als geordnetesession/update-Benachrichtigungen vor, bevor die Anfrage abgeschlossen wird;session/forkverzweigt eine persistierte Sitzung in eine neue Sitzungs-ID, deren gespeicherte Historie eine Kopie der Historie der Quelle ist, wobei die Quelle unverändert bleibt;session/deleteentfernt die persistierte Sitzung;session/listgibt Sitzungen zurück, die über den konfiguriertenSessionServicesichtbar sind.
session/load validiert das angegebene cwd gegen das gespeicherte Arbeitsverzeichnis
der Sitzung auf dieselbe Weise wie session/resume, und gibt für eine unbekannte Sitzungs-ID
einen Sitzung-nicht-gefunden-Fehler zurück. Replay ordnet jedes gespeicherte Benutzer-,
Agenten-, Denk- und Tool-Ereignis seiner entsprechenden SessionUpdate-Variante in
ursprünglicher chronologischer Reihenfolge zu, sodass ein sich erneut verbindender Editor
die sichtbare Historie in der Reihenfolge wiederherstellt, in der sie passiert ist.
Interaktive Sitzungssteuerung
Ein Agent kann dem Client interaktive Steuerelemente bereitstellen, indem er einen
SessionControls-Provider angibt. Wenn er das tut, kündigt der Server sie in den
session/new-, session/load-, session/resume- und session/fork-Antworten an:
- Modi — eine Menge benannter Modi (zum Beispiel „ask“ versus „code“) mit einer
aktuellen Auswahl.
session/set_modevalidiert den angeforderten Modus gegen die angekündigte Menge, speichert ihn und gibt einCurrentModeUpdateaus; ein unbekannter Modus wird abgelehnt und der aktuelle Modus bleibt unverändert. - Konfigurationsoptionen — Auswahlen und Schalter, die ein Client lesen und ändern kann.
session/set_config_optionvalidiert den Wert gegen die deklarierten Auswahlmöglichkeiten der Option, speichert ihn und gibt einConfigOptionUpdateaus; eine unbekannte Option oder ein ungültiger Wert wird abgelehnt. - Verfügbare Befehle — ACP-Slash-Befehle, die als
AvailableCommandsUpdateangezeigt werden, wenn eine Sitzung aktiv wird.
Modus- und Konfigurationsauswahlen werden im ADK-Sitzungszustand beibehalten (acp:mode,
acp:config:<id>), sodass sie Laden, Wiederaufnehmen und Fork überstehen. Ein aufgezeichneter Sitzungs-
titel erscheint bei Aktivierung und immer dann, wenn er sich ändert, als SessionInfoUpdate. Eine
Plan-Update-Zuordnung existiert, bleibt aber inaktiv, bis eine ADK-Plan-Primitive
Plan-Einträge bereitstellt. Ein Agent, der keinen SessionControls bereitstellt, kündigt keine
Modi und keine Optionen an, wodurch die angekündigten Fähigkeiten genau mit dem
übereinstimmen, was der Server implementiert.
Inhalte überschreiten die Grenze durch eine Zuordnung
Prompts, die von einem Client eingehen, und Updates, die zurück zu ihm gestreamt werden, laufen beide
durch ein einziges Inhaltsmodul, das ACP-ContentBlock-Werte in
adk_core::Part-Werte und zurück abbildet. Eine einzige Zuordnung in beide Richtungen bedeutet, dass
der Prompt-Parser des Servers, der Streamer des Servers und der Client alle darüber
einig sind, wie jeder Inhaltstyp dargestellt wird.
Die Zuordnung bewahrt Nutzdaten treu. Textblöcke werden unverändert mit der Zeichenkette zu Part::Text abgebildet. Eingebettete Ressourcenblöcke werden zu Part::EmbeddedResource abgebildet,
wobei die Quelle URI, der optionale MIME-Typ und der Inhalt erhalten bleiben. Eine Textressource
wird in beide Richtungen unverändert übertragen und niemals base64-kodiert; eine
binäre Ressource wird über die Leitung base64-kodiert und auf der Seite von ADK der Grenze
in rohe Bytes dekodiert. Bild- und Audioblöcke werden zu Part::InlineData abgebildet,
wobei MIME-Typ und dekodierte Bytes erhalten bleiben; der Server kündigt diese Prompt-Medien an
und akzeptiert sie, und der Client überträgt nicht-textuellen ADK-Inhalt (eingebettete Ressource,
Bild, Audio) als passenden ACP-Block, statt ihn zu verwerfen.
Streaming-Updates transportieren mehr als Text
Während ein Prompt läuft, übersetzt der Server typisierte ADK-Ereignisse in ACP-
session/update-Benachrichtigungen. Modelltext und Gedanken werden zu Nachrichten- und
Gedanken-Chunks, und eingebetteter Ressourceninhalt wird zu einem eingebetteten Ressourcen-Nachrichten-Chunk. Darüber hinaus geben zwei Arten von Updates einem Client
eine reichere Sicht auf den Durchlauf:
- Nutzungs-Updates. Wenn ein ADK-Ereignis Nutzungsmetadaten enthält, sendet der Server
ein
UsageUpdate, das die gemeldeten Token-Zahlen widerspiegelt, plus Kosten in USD, wenn die Laufzeitumgebung sie meldet. Ereignisse ohne Nutzungsmetadaten erzeugen kein Update, und der Server erfindet niemals Zählwerte. - Reiche Tool-Call-Updates. Ein Tool-Aufruf beginnt als ein
ToolCallmit einer Tool-kind, die aus dem deklarierten Verhalten des Tools abgeleitet wird. Sein späteresToolCallUpdateträgt den Tool-Ergebnisinhalt und die Dateispeicherorte, die das Tool als betroffen meldet, sodass ein Editor Diffs und Listen betroffener Dateien darstellen kann. Das Update behält dieselbe Kennung wie das ursprünglicheToolCallbei und bewahrt so die Korrelation über den Durchlauf hinweg.
Die Client-Richtung hat die passende Treue. Wenn eine ADK-Rust-Anwendung einen External_Agent verarbeitet, stellt ihre Streaming-Oberfläche (OutputChunk) nicht nur Agententext und Gedanken bereit, sondern auch die External_Agent-ToolCallUpdate (als id-korrelierte Tool-Aktualisierung, die Status, Typ, Titel, Inhalts-Text und betroffene Dateipositionen trägt) sowie die UsageUpdate (verwendete Tokens und Größe, plus Kosten und Währung, wenn gemeldet). Der Text der Agentennachricht wird unverändert wie zuvor bereitgestellt, sodass bestehende Textverbraucher nicht beeinträchtigt werden.
Berechtigungsanfragen überbrücken Tool-Bestätigungen
Ein ADK-Rust-Agent kann einen Durchlauf anhalten, bis eine Person einen Tool-Aufruf genehmigt (ToolConfirmationRequest). Auf der Serverseite wird diese Pause zu einer nativen ACP-session/request_permission-Anfrage, die das Tool und seine Argumente beschreibt. Das Ergebnis des Clients setzt den Durchlauf fort: Eine Genehmigung wird zu allow abgebildet, und sowohl eine Ablehnung als auch eine Abbruchaktion werden beide zu deny abgebildet, sodass eine abgebrochene Anfrage das Tool nie ausführt. Jedes Ergebnis wird über seine Function-Call-ID dem exakten Aufruf zugeordnet und über seine Tool-Bestätigungsentscheidungen an den Runner zurückgegeben. Die verschachtelte Berechtigungsanfrage wird aus der erzeugten Prompt-Task heraus ausgelöst, sodass die äußere session/prompt-Antwort weiterhin normal abgeschlossen wird.
Fähigkeiten sind ein Vertrag
Initialisierung ist kein dekorativer Handshake. Jede Seite kündigt nur die Operationen und Inhalte an, die sie unterstützt. ADK-Rust nutzt diese Fähigkeiten, um das Senden optionaler HTTP- oder SSE-MCP-Konfiguration an einen Agenten zu vermeiden, der nur stdio akzeptiert, und es kündigt Datei-System- oder Terminal-Host-Operationen nur an, wenn die Anwendung die entsprechende Implementierung bereitstellt.
Der Server kündigt genau die Inhaltstypen an, die sein Prompt-Handler akzeptiert. Er kündigt die embedded_context-, image- und audio-Prompt-Fähigkeiten an, weil eingebettete Ressourceninhalte auf adk_core::Part::EmbeddedResource abgebildet werden und Bild- und Audioinhalte auf adk_core::Part::InlineData abgebildet werden. Er kündigt load_session an, weil er einen session/load-Handler registriert, und die fork-Sitzungsfähigkeit, weil er einen session/fork-Handler registriert. Sitzungsmodi und Konfigurationsoptionen werden nur angekündigt, wenn der Agent einen SessionControls-Provider bereitstellt; ein Agent ohne einen solchen kündigt also keines von beiden an. Entfernte Transportwege, Modellauswahlen und experimentelle Protokollerweiterungen bleiben unangezeigt. Eine Prompt-Anfrage, die einen Inhaltstyp enthält, den der Server nicht angekündigt hat, wird mit einem beschreibenden Fehler abgewiesen, statt teilweise verarbeitet zu werden. Aufrufer sollten gegen das ausgehandelte Fähigkeitsobjekt entwerfen, statt anzunehmen, dass jede ACP-Implementierung dieselbe Oberfläche hat.