21. ACP (Agent Communication Protocol)
Il supporto ACP (Agent Communication Protocol) in MALDA consente agli agenti MALDA di comunicare con agenti ACP esterni e di esporre agenti MALDA come agenti conformi ad ACP. Così si può orchestrare agenti distribuiti tra sistemi e framework diversi.
21.1 Panoramica
ACP è un protocollo aperto per la comunicazione da agente ad agente: gli agenti AI possono collaborare attraverso framework, linguaggi di programmazione e organizzazioni diverse. L'implementazione ACP di MALDA fornisce:
- ACPClient: Collegarsi ad agenti ACP esterni e inviare messaggi
- ACPServer: Esporre agenti MALDA come agenti conformi ad ACP via HTTP
- ACPAgentTool: Usare agenti ACP esterni come tool per gli agenti MALDA
21.2 Classe ACPClient
La classe ACPClient consente agli agenti MALDA di comunicare con agenti ACP esterni tramite REST API.
Costruttore
var client = new ACPClient(baseUrl, apiKey?);
Parametri:
baseUrl(string): URL di base del server ACP (es. "https://acp.example.com")apiKey(string, opzionale): API key per l'autenticazione (token Bearer)
Proprietà
baseUrl(string): L'URL di base del server ACPisConnected(boolean): Restituisce sempretrueper il client HTTP
Metodi
discoverAgents(): Restituisce un array degli agenti disponibili dal server ACPgetAgentManifest(agentId): Ottiene il manifest (metadati) di un agente specificosendMessage(agentId, message, timeoutMs?, sessionId?): Invia un messaggio in modo sincrono e restituisce la risposta. IlsessionIdopzionale mantiene la history tra un run e l'altro (vedi 21.11)sendMessageAsync(agentId, message, timeoutMs?): Invia un messaggio in modo asincrono e restituisce il run IDsendMessageStream(agentId, message, timeoutMs?): Invia un messaggio con streaming e restituisce la risposta accumulatagetRunStatus(agentId, runId): Ottiene lo stato di un'esecuzione agente in corsocancelRun(agentId, runId): Annulla un'esecuzione agente in corsoresumeRun(agentId, runId, input): Riprende un'esecuzione agente in attesa, fornendo un inputgetSession(sessionId): Ottiene i dettagli della sessione, inclusa la history
Esempio: scoprire e comunicare con agenti esterni
// Create ACP client
var client = new ACPClient("https://acp.example.com", "my-api-key");
// Discover available agents
var agents = client.discoverAgents();
print("Available agents:");
var i = 0;
while (i < length(agents)) {
var agent = agents[i];
print(agent.name + ": " + agent.description);
i = i + 1;
}
// Send message to an external ACP agent
var response = client.sendMessage("translation-agent", "Translate 'Hello' to Spanish", 5000);
print("Response: " + response);
21.3 Classe ACPServer
La classe ACPServer espone agenti MALDA come agenti conformi ad ACP tramite un HTTP server, così i client ACP esterni possono comunicare con gli agenti MALDA.
Costruttore
var server = new ACPServer(port);
Parametri:
port(integer): Numero di porta su cui ascoltare (1-65535)
Proprietà
port(integer): Il numero di porta su cui il server è in ascoltoisRunning(boolean): Se il server è al momento in esecuzione
Metodi
registerAgent(agentId, agentInstance, manifest?): Registra un agente MALDA come agente conforme ad ACPstart(): Avvia il server ACP e inizia ad ascoltare le richiestestop(): Arresta il server ACPgetRegisteredAgents(): Restituisce un array degli agenti registrati
Endpoint REST API
ACPServer espone i seguenti endpoint REST:
GET /agents: Elenca tutti gli agenti registratiGET /agents/{id}: Ottiene il manifest dell'agentePOST /agents/{id}/runs: Invia un messaggio a un agente (crea un run)
Esempio: esporre un agente MALDA come agente ACP
// Create a MALDA agent
var client = new OpenRouterClient();
var myAgent = new Agent(
"CodeHelper",
"coding assistant",
"You help with programming tasks.",
client
);
// Expose as ACP agent
var server = new ACPServer(8080);
server.registerAgent("code-helper-001", myAgent, {
"name": "CodeHelper",
"description": "A coding assistant agent",
"version": "1.0.0"
});
server.start();
print("MALDA agent exposed at http://localhost:8080/agents/code-helper-001");
// Keep server running
while (server.isRunning) {
sleep(1000);
}
21.4 Classe ACPAgentTool
La classe ACPAgentTool incapsula un agente ACP esterno come tool MALDA, così può essere usato dagli agenti MALDA tramite tool calling.
Costruttore
var tool = new ACPAgentTool(acpClient, agentId, description);
Parametri:
acpClient(ACPClient): Un'istanza ACPClient collegata al server ACPagentId(string): L'ID dell'agente ACP esterno da usare come tooldescription(string): Descrizione di cosa fa il tool (usata dall'LLM per la selezione del tool)
Esempio: usare un agente ACP esterno come tool
// Create ACP client
var acpClient = new ACPClient("https://acp.example.com");
// Create tool wrapper for external ACP agent
var translationTool = new ACPAgentTool(
acpClient,
"translation-agent",
"Translates text between languages"
);
// Add to MALDA agent
var client = new OpenRouterClient();
var myAgent = new Agent("Helper", "assistant", "You help users", client);
myAgent.addTool(translationTool);
// Agent can now use the external ACP agent via tool calling
var response = myAgent.think("Translate 'Hello' to Spanish");
print(response.content);
21.5 Casi d'uso
Orchestrazione distribuita di agenti
Collegare agenti MALDA con agenti in esecuzione in altri sistemi:
// Local MALDA agents
var writer = new Agent("Writer", "writer", "...", client);
var editor = new Agent("Editor", "editor", "...", client);
// External ACP agent
var acpClient = new ACPClient("https://acp.example.com");
var translator = new ACPAgentTool(acpClient, "translation-agent", "Translates text");
// Orchestrate workflow
function createMultilingualDoc(topic) {
// Step 1: Local agent writes
var doc = writer.think("Write about: " + topic);
// Step 2: External ACP agent translates (via tool)
editor.addTool(translator);
editor.getConversation().addUserMessage("Translate to Spanish: " + doc.content);
var translated = editor.getConversation().send();
return translated.content;
}
Esporre agenti MALDA a sistemi esterni
Rendere gli agenti MALDA disponibili ad altri sistemi compatibili con ACP:
var server = new ACPServer(8080);
server.registerAgent("malda-coder", codingAgent);
server.registerAgent("malda-reviewer", reviewAgent);
server.start();
// External systems can now communicate with MALDA agents via ACP protocol
21.6 ACP vs MCP
ACP e MCP servono scopi diversi:
- MCP (Model Context Protocol): Collega applicazioni AI a tool e origini dati. Focus: un modello, molti tool
- ACP (Agent Communication Protocol): Abilita la comunicazione tra agenti AI indipendenti. Focus: molti agenti, comunicazione peer-to-peer
Si possono usare insieme: gli agenti MALDA possono usare tool MCP (tramite MCPClient) e anche comunicare con altri agenti tramite ACP.
21.7 Formato dei messaggi
ACP usa un formato di messaggio con più parti, ciascuna con contenuto e un tipo MIME. MALDA converte automaticamente:
- In uscita: stringhe MALDA → formato messaggio ACP (una sola parte di testo)
- In ingresso: formato messaggio ACP → stringhe MALDA (unisce tutte le parti di testo)
Così gli agenti MALDA lavorano con ACP senza dover gestire direttamente il formato dei messaggi.
21.8 Modalità di esecuzione
Esecuzione sincrona
Modalità predefinita: attende che l'agente completi:
var response = client.sendMessage("agent-id", "Hello");
print(response);
Esecuzione asincrona
Restituisce subito il run ID; poi si interroga lo stato:
var runId = client.sendMessageAsync("agent-id", "Hello");
var status = client.getRunStatus("agent-id", runId);
while (status.status == "in-progress" || status.status == "created") {
sleep(100);
status = client.getRunStatus("agent-id", runId);
}
print("Final status: " + status.status);
if (status.message != null) {
print("Response: " + status.message);
}
Esecuzione in streaming
Riceve aggiornamenti incrementali tramite Server-Sent Events:
var response = client.sendMessageStream("agent-id", "Hello");
print("Streamed response: " + response);
21.9 Annullamento di un run
Le esecuzioni agente di lunga durata si possono annullare:
var runId = client.sendMessageAsync("agent-id", "Long running task");
// ... later ...
client.cancelRun("agent-id", runId);
21.10 Await/Resume
__ACP_AWAIT__:… è una convenzione dell'agente, non una keyword MALDA. Se la risposta dell'agente inizia con quel marker, il server ACP marca il run come awaiting e il client chiama resumeRun con l'input utente. Stessa idea: Examples/ACP/await_resume.malda. Questi campioni richiedono due processi (server e client).
// Agent code (uses special marker or tool)
// When agent needs input, it responds with: "__ACP_AWAIT__:Please provide your name"
// Client code
var runId = client.sendMessageAsync("agent-id", "Ask for user name");
var status = client.getRunStatus("agent-id", runId);
if (status.status == "awaiting") {
var userInput = input("Enter your name: ");
var response = client.resumeRun("agent-id", runId, userInput);
print(response);
}
21.11 Gestione delle sessioni
Mantenere conversazioni con stato attraverso più run:
var sessionId = "session-" + random();
var response1 = client.sendMessage("agent-id", "My name is Alice", 30000, sessionId);
var response2 = client.sendMessage("agent-id", "What is my name?", 30000, sessionId);
var session = client.getSession(sessionId);
print("Session history: " + length(session.history) + " runs");
21.12 Gestione degli errori
Le operazioni ACP possono sollevare eccezioni in questi casi:
- Errori di rete nel collegamento ai server ACP
- ID agente non validi o agenti mancanti
- Errori di timeout in attesa delle risposte dell'agente
- Formati di messaggio non validi
Gli errori sono restituiti come oggetti strutturati con i campi code, message e, opzionalmente, data. In produzione, metti sempre le chiamate ACP in blocchi try-catch:
try {
var response = client.sendMessage("agent-id", "Hello", 5000);
print(response);
} catch (error) {
print("Error: " + error);
}
Vedi anche
- 18. Orchestrazione di agenti - Creare e usare agenti MALDA
- 20. Server MCP - Protocollo MCP per tool e origini dati
- 27. Server REST API - Creare REST API in MALDA
- Schizzi eseguibili in
Examples/ACP/