ACP (Agent Client Protocol) (Deutsch)
Was ist ACP?
Abschnitt betitelt „Was ist ACP?“ACP (Agent Client Protocol) ist ein „CLI-as-Backend“-Transport für OmniRoute. Anstatt HTTP-API-Aufrufe an KI-Anbieter abzufangen, startet ACP CLI-Agenten als untergeordnete Prozesse und übermittelt Prompts über deren native Schnittstelle.
Warum ACP verwenden?
Abschnitt betitelt „Warum ACP verwenden?“| Vorteil | Beschreibung |
|---|---|
| Keine API-Schlüssel benötigt | Verwendet Ihre bestehende CLI-Authentifizierung |
| Natives Protokoll | Verwendet das native Ein-/Ausgabeformat der jeweiligen CLI |
| Automatische Erkennung | Erkennt auf Ihrem System installierte CLIs |
| 15 integrierte Agenten | Für beliebte CLI-Tools vorkonfiguriert |
| Benutzerdefinierte Agenten | Fügen Sie über die Einstellungen eigene CLI-Tools hinzu |
| Prozessverwaltung | Verwaltet den Lebenszyklus (Starten, Senden, Beenden) |
Unterstützte CLI-Agenten
Abschnitt betitelt „Unterstützte CLI-Agenten“ACP unterstützt standardmäßig 15 integrierte CLI-Agenten:
| Agenten-ID | Anzeigename | Binärdatei | Protokoll |
|---|---|---|---|
codex |
OpenAI Codex CLI | codex |
stdio |
claude |
Claude Code CLI | claude |
stdio |
goose |
Goose CLI | goose |
stdio |
openclaw |
OpenClaw | openclaw |
stdio |
aider |
Aider | aider |
stdio |
opencode |
OpenCode | opencode |
stdio |
cline |
Cline | cline |
stdio |
qwen |
Qwen Code | qwen --acp |
stdio |
forge |
ForgeCode | forge |
stdio |
amazon-q |
Amazon Q Developer | q |
stdio |
interpreter |
Open Interpreter | interpreter |
stdio |
cursor-cli |
Cursor CLI | cursor |
stdio |
warp |
Warp AI | warp |
stdio |
gemini |
Gemini CLI | gemini |
stdio |
zcode |
ZCode | zcode |
stdio |
Benutzerdefinierte Agenten
Abschnitt betitelt „Benutzerdefinierte Agenten“Sie können über die Einstellungen eigene CLI-Agenten hinzufügen. Benutzerdefinierte Agenten unterstützen dieselben Funktionen wie integrierte Agenten.
Schnellstart
Abschnitt betitelt „Schnellstart“Schritt 1: Einen CLI-Agenten installieren
Abschnitt betitelt „Schritt 1: Einen CLI-Agenten installieren“# Beispiel: Claude Code CLI installierennpm install -g @anthropic-ai/claude-code
# Installation überprüfenclaude --versionSchritt 2: Automatische ACP-Erkennung
Abschnitt betitelt „Schritt 2: Automatische ACP-Erkennung“ACP erkennt auf Ihrem System installierte CLI-Agenten automatisch. Es ist keine Konfiguration erforderlich!
Schritt 3: ACP-Transport verwenden
Abschnitt betitelt „Schritt 3: ACP-Transport verwenden“Nach der Erkennung kann ACP als Transport für jeden unterstützten Anbieter verwendet werden. OmniRoute verwendet ACP automatisch, wenn die CLI verfügbar ist.
Funktionsweise von ACP
Abschnitt betitelt „Funktionsweise von ACP“Architektur
Abschnitt betitelt „Architektur“┌─────────────────┐│ OmniRoute ││ (HTTP-Proxy) │└────────┬────────┘ │ │ spawn() ▼┌─────────────────┐│ Untergeordneter ││ Prozess ││ (CLI-Agent) ││ ││ stdin ◄──────┤ Prompt senden│ stdout ──────►│ Antwort empfangen│ stderr ──────►│ Fehler empfangen└─────────────────┘Prozesslebenszyklus
Abschnitt betitelt „Prozesslebenszyklus“- Starten — ACP erstellt einen untergeordneten Prozess für den CLI-Agenten
- Senden — ACP schreibt Prompts in stdin des Prozesses
- Empfangen — ACP liest Antworten aus stdout/stderr
- Inaktivitätserkennung — ACP wartet 2 Sekunden ohne Aktivität, bevor die Antwort als vollständig betrachtet wird
- Beenden — ACP beendet den Prozess (SIGTERM, anschließend SIGKILL nach 5 Sekunden)
Kommunikationsprotokoll
Abschnitt betitelt „Kommunikationsprotokoll“ACP verwendet stdio (Standardeingabe/-ausgabe) für die Kommunikation mit CLI-Agenten. Das Protokoll funktioniert folgendermaßen:
- Prompt senden — Mit einem Zeilenumbruch in stdin schreiben
- Auf Antwort warten — Aus stdout lesen, bis Inaktivität eintritt (2 Sekunden ohne Ausgabe)
- Zeitüberschreitung — Standardmäßig 120 Sekunden (konfigurierbar)
API-Referenz
Abschnitt betitelt „API-Referenz“Registry-Funktionen
Abschnitt betitelt „Registry-Funktionen“detectInstalledAgents()
Abschnitt betitelt „detectInstalledAgents()“Erkennt alle auf dem System installierten CLI-Agenten. Die Ergebnisse werden 60 Sekunden lang zwischengespeichert.
import { detectInstalledAgents } from "@/lib/acp";
const agents = detectInstalledAgents();// Gibt zurück: CliAgentInfo[]
interface CliAgentInfo { id: string; // z. B. "codex", "claude" name: string; // Anzeigename binary: string; // Name der auszuführenden Binärdatei versionCommand: string; // Befehl zur Versionserkennung version: string | null; // Erkannte Version (null, falls nicht installiert) installed: boolean; // Gibt an, ob der Agent installiert ist providerAlias: string; // Anbieter-ID in OmniRoute spawnArgs: string[]; // Beim Start zu übergebende Argumente protocol: "stdio" | "http"; // Kommunikationsprotokoll isCustom?: boolean; // Gibt an, ob dies ein benutzerdefinierter Agent ist}getAvailableAgents()
Abschnitt betitelt „getAvailableAgents()“Ruft nur die Agenten ab, die installiert und für ACP verfügbar sind.
import { getAvailableAgents } from "@/lib/acp";
const available = getAvailableAgents();// Gibt zurück: CliAgentInfo[] (nur installierte Agenten)getAgentById(id)
Abschnitt betitelt „getAgentById(id)“Ruft einen bestimmten Agenten anhand seiner ID ab.
import { getAgentById } from "@/lib/acp";
const agent = getAgentById("claude");// Gibt zurück: CliAgentInfo | undefinedsetCustomAgents(agents)
Abschnitt betitelt „setCustomAgents(agents)“Legt benutzerdefinierte Agentendefinitionen aus den Einstellungen fest.
import { setCustomAgents } from "@/lib/acp";
setCustomAgents([ { id: "my-custom-cli", name: "My Custom CLI", binary: "mycli", versionCommand: "mycli --version", providerAlias: "my-provider", spawnArgs: [], protocol: "stdio", },]);Manager-Funktionen
Abschnitt betitelt „Manager-Funktionen“acpManager.spawn(agentId, binary, args, env)
Abschnitt betitelt „acpManager.spawn(agentId, binary, args, env)“Startet einen neuen CLI-Agentenprozess.
import { acpManager } from "@/lib/acp";
const session = acpManager.spawn("claude", "claude", ["--print", "--output-format", "json"], { /* benutzerdefinierte Umgebungsvariablen */});// Gibt zurück: AcpSessionZulässige Agenten-IDs: ["claude", "codex", "gemini", "qwen"]
acpManager.sendPrompt(sessionId, prompt, timeoutMs)
Abschnitt betitelt „acpManager.sendPrompt(sessionId, prompt, timeoutMs)“Sendet eine Eingabeaufforderung an einen CLI-Agenten und erfasst die Antwort.
import { acpManager } from "@/lib/acp";
const response = await acpManager.sendPrompt( "acp-claude-1234567890-abc123", "What is 2+2?", 120000 // Zeitüberschreitung nach 2 Minuten);// Gibt zurück: Promise<string>acpManager.kill(sessionId)
Abschnitt betitelt „acpManager.kill(sessionId)“Beendet eine Sitzung und führt die Bereinigung durch.
import { acpManager } from "@/lib/acp";
const killed = acpManager.kill("acp-claude-1234567890-abc123");// Gibt zurück: booleanacpManager.getActiveSessions()
Abschnitt betitelt „acpManager.getActiveSessions()“Ruft alle aktiven Sitzungen ab.
import { acpManager } from "@/lib/acp";
const sessions = acpManager.getActiveSessions();// Gibt zurück: AcpSession[]acpManager.killAll()
Abschnitt betitelt „acpManager.killAll()“Beendet alle Sitzungen.
import { acpManager } from "@/lib/acp";
acpManager.killAll();Sitzungsschnittstelle
Abschnitt betitelt „Sitzungsschnittstelle“interface AcpSession { id: string; // Eindeutige Sitzungs-ID agentId: string; // Agenten-ID (z. B. "claude") process: ChildProcess; // Handle des untergeordneten Prozesses alive: boolean; // Gibt an, ob der Prozess aktiv ist stdoutBuffer: string; // Akkumulierter stdout-Puffer stderrBuffer: string; // Akkumulierter stderr-Puffer createdAt: Date; // Erstellungszeitstempel}Ereignisse
Abschnitt betitelt „Ereignisse“Der AcpManager erweitert EventEmitter und löst die folgenden Ereignisse aus:
Wird ausgelöst, wenn der CLI-Agent in stdout schreibt.
acpManager.on("stdout", ({ sessionId, data }) => { console.log(`[${sessionId}] stdout: ${data}`);});Wird ausgelöst, wenn der CLI-Agent in stderr schreibt.
acpManager.on("stderr", ({ sessionId, data }) => { console.error(`[${sessionId}] stderr: ${data}`);});Wird ausgelöst, wenn der CLI-Agentenprozess beendet wird.
acpManager.on("exit", ({ sessionId, code, signal }) => { console.log(`[${sessionId}] exited with code ${code}, signal ${signal}`);});Wird ausgelöst, wenn beim CLI-Agentenprozess ein Fehler auftritt.
acpManager.on("error", ({ sessionId, error }) => { console.error(`[${sessionId}] error: ${error}`);});Konfiguration
Abschnitt betitelt „Konfiguration“Umgebungsvariablen
Abschnitt betitelt „Umgebungsvariablen“ACP übernimmt alle Umgebungsvariablen des übergeordneten Prozesses und kann um benutzerdefinierte Umgebungsvariablen erweitert werden:
acpManager.spawn("claude", "claude", [], { ANTHROPIC_API_KEY: "sk-...", DEBUG: "true",});Startargumente
Abschnitt betitelt „Startargumente“Jeder Agent verfügt über standardmäßige Startargumente, die in der Registry definiert sind. Sie können diese überschreiben:
acpManager.spawn("claude", "claude", ["--print", "--verbose"], {});Zeitüberschreitungen
Abschnitt betitelt „Zeitüberschreitungen“Die standardmäßige Zeitüberschreitung für Prompts beträgt 120 Sekunden (2 Minuten). Sie können sie überschreiben:
await acpManager.sendPrompt(sessionId, prompt, 300000); // 5 MinutenErkennungs-Cache
Abschnitt betitelt „Erkennungs-Cache“Die Agentenerkennung wird für 60 Sekunden zwischengespeichert, um aufwendige Dateisystem-Scans zu vermeiden. So erzwingen Sie eine Aktualisierung:
import { refreshAgentCache } from "@/lib/acp";
refreshAgentCache();Sicherheit
Abschnitt betitelt „Sicherheit“Verhinderung von Befehlsinjektionen
Abschnitt betitelt „Verhinderung von Befehlsinjektionen“ACP validiert Versionsbefehle, um Angriffe durch Befehlsinjektion zu verhindern:
const DISALLOWED_VERSION_COMMAND_CHARS = /[;&|<>`$\r\n]/;Versionsbefehle, die diese Zeichen enthalten, werden abgelehnt:
;— Befehlstrennzeichen&— Hintergrundprozess|— Pipe<,>— Umleitung`— Befehlsersetzung$— Variablenexpansion\r,\n— Zeilenumbrüche
Validierung des Binärdateinamens
Abschnitt betitelt „Validierung des Binärdateinamens“ACP validiert, dass die Binärdatei des Versionsbefehls dem erwarteten Binärdateinamen entspricht (außer bei benutzerdefinierten Agenten).
Prozessisolierung
Abschnitt betitelt „Prozessisolierung“Jede ACP-Sitzung wird in einem eigenen untergeordneten Prozess ausgeführt. Der Prozess wird beendet, wenn die Sitzung endet oder das Zeitlimit überschritten wird.
Leistung
Abschnitt betitelt „Leistung“Erkennungsleistung
Abschnitt betitelt „Erkennungsleistung“- Erster Aufruf: ~50-200ms (führt für jeden Agenten den Befehl
versionaus) - Zwischengespeicherte Aufrufe: <1ms (Rückgabe aus dem Cache)
- Cache-TTL: 60 Sekunden
Prompt-Leistung
Abschnitt betitelt „Prompt-Leistung“- Starten: ~50-100ms
- Prompt senden: ~10-50ms
- Auf Antwort warten: Hängt vom CLI-Agenten ab (typischerweise 1-30 Sekunden)
- Beenden: ~5 Sekunden (SIGTERM) + sofort (SIGKILL)
Ressourcennutzung
Abschnitt betitelt „Ressourcennutzung“- Arbeitsspeicher pro Sitzung: ~10-50MB (hängt vom CLI-Agenten ab)
- CPU: Minimal (E/A-gebunden)
- Festplatte: Keine
Fehlerbehebung
Abschnitt betitelt „Fehlerbehebung“Fehler „Unknown agent“
Abschnitt betitelt „Fehler „Unknown agent““Problem: acpManager.spawn() löst Unknown agent: <id> aus
Lösung: In spawn() sind nur diese Agenten zulässig:
claudecodexgeminiqwen
Andere Agenten müssen manuell oder über benutzerdefinierte Agentendefinitionen gestartet werden.
Fehler „Session not alive“
Abschnitt betitelt „Fehler „Session not alive““Problem: acpManager.sendPrompt() löst Session ${sessionId} is not alive aus
Lösung: Die Sitzung wurde möglicherweise beendet oder abgebrochen. Überprüfen Sie den Sitzungsstatus:
const session = acpManager.getSession(sessionId);if (!session?.alive) { // Sitzung erneut starten acpManager.spawn("claude", "claude", [], {});}Fehler „ACP timeout“
Abschnitt betitelt „Fehler „ACP timeout““Problem: acpManager.sendPrompt() löst ACP timeout after 120000ms aus
Lösung: Erhöhen Sie die Zeitüberschreitung:
await acpManager.sendPrompt(sessionId, prompt, 300000); // 5 MinutenCLI nicht erkannt
Abschnitt betitelt „CLI nicht erkannt“Problem: detectInstalledAgents() findet Ihre CLI nicht
Lösungen:
- PATH überprüfen: Stellen Sie sicher, dass sich die CLI im PATH Ihres Systems befindet
- Versionsbefehl überprüfen: Führen Sie
claude --versionmanuell aus - Berechtigungen überprüfen: Stellen Sie sicher, dass die CLI ausführbar ist
- Benutzerdefinierter Agent: Fügen Sie eine benutzerdefinierte Agentendefinition für nicht standardmäßige CLIs hinzu
Zugriff verweigert
Abschnitt betitelt „Zugriff verweigert“Problem: ACP kann die CLI nicht ausführen
Lösungen:
- Dateiberechtigungen überprüfen:
chmod +x /usr/local/bin/claude - Eigentümer überprüfen: Stellen Sie sicher, dass OmniRoute über Lese- und Ausführungsberechtigungen verfügt
- SELinux/AppArmor überprüfen: Kann das Starten von Prozessen blockieren
Beispiele
Abschnitt betitelt „Beispiele“Beispiel 1: Claude Code starten und verwenden
Abschnitt betitelt „Beispiel 1: Claude Code starten und verwenden“import { acpManager, detectInstalledAgents } from "@/lib/acp";
// Installierte Agenten erkennenconst agents = detectInstalledAgents();const claude = agents.find((a) => a.id === "claude");
if (claude?.installed) { // Eine neue Sitzung starten const session = acpManager.spawn("claude", claude.binary, ["--print", "--output-format", "json"]);
// Einen Prompt senden const response = await acpManager.sendPrompt( session.id, "Explain quantum computing in 100 words" );
console.log("Claude's response:", response);
// Ressourcen bereinigen acpManager.kill(session.id);}Beispiel 2: Automatische Erkennung mit Ausweichlösung
Abschnitt betitelt „Beispiel 2: Automatische Erkennung mit Ausweichlösung“import { acpManager, getAvailableAgents } from "@/lib/acp";
const available = getAvailableAgents();
// Zuerst Claude versuchen, andernfalls auf Codex ausweichenlet agentId = "claude";if (!available.find((a) => a.id === "claude")) { if (available.find((a) => a.id === "codex")) { agentId = "codex"; } else { throw new Error("No ACP-compatible CLI agent found"); }}
const agent = available.find((a) => a.id === agentId)!;const session = acpManager.spawn(agentId, agent.binary, agent.spawnArgs);
const response = await acpManager.sendPrompt(session.id, "Hello!");
acpManager.kill(session.id);Beispiel 3: Benutzerdefinierter Agent
Abschnitt betitelt „Beispiel 3: Benutzerdefinierter Agent“import { setCustomAgents, detectInstalledAgents } from "@/lib/acp";
// Einen benutzerdefinierten CLI-Agenten registrierensetCustomAgents([ { id: "my-llm-cli", name: "My LLM CLI", binary: "myllm", versionCommand: "myllm --version", providerAlias: "my-llm-provider", spawnArgs: ["--format", "json"], protocol: "stdio", },]);
// detectInstalledAgents() enthält nun auch "my-llm-cli"const agents = detectInstalledAgents();Wie geht es weiter?
Abschnitt betitelt „Wie geht es weiter?“- API-Referenz — REST-API-Endpunkte
- Anbieterreferenz — Alle 352 Anbieter
- MCP-Server — Integration des Model Context Protocol
- A2A-Server — Agent-to-Agent-Protokoll
- Cloud-Agent — Cloudbasierte Agenten
Referenz
Abschnitt betitelt „Referenz“- AionUi-Projekt — Inspiration für die automatische ACP-Erkennung
- ACP-Quellcode — Implementierungsdetails
manager.ts— Verwaltung des Prozesslebenszyklusregistry.ts— Erkennung und Registrierung von Agentenindex.ts— Exporte der öffentlichen API
HagiCode
HagiCode ist ein agentischer Coding-Arbeitsplatz mit strukturierten Workflows, Multi-Agent-Ausführung und Hero-Dungeon-Ansichten.
Mit einem intelligenteren, schnelleren und unterhaltsameren agentischen Workflow wird aus Ideen nutzbare Software.

- SmartStrukturierte Workflows machen aus Absichten einen umsetzbaren Weg von der Idee bis zur Auslieferung.
- EfficientMulti-Agent-Workflows führen Recherche, Umsetzung und Prüfung parallel aus.
- FunHero Dungeon macht lange Coding-Sitzungen anschaulich und gemeinschaftlich.