Definire un agente e utilizzarla¶
Traduzione automatica dell'originale francese.
Tre oggetti da posizionare, nell'ordine indicato. Nessuno è facoltativo: saltare il secondo crea un agente il cui utilizzo non è imputabile a nessuno.
flowchart TD
e["1 · Équipe<br/>budget commun, un projet"] --> c["2 · Clé virtuelle<br/>une par agent = imputation"]
c --> a["3 · Agent<br/>carte + limites + contrat"]
a --> u["Consommation<br/>script · workflow · chat · autre agent"]
1. Il team¶
Gestisce il budget di un progetto e raggruppa le sue chiavi. Un singolo agente non ha bisogno di un team; due agenti dello stesso progetto, se — altrimenti i loro budget non si sommano.
curl -sX POST "$PROXY/team/new" -H "Authorization: Bearer $CLE_ADMIN" \
-H 'Content-Type: application/json' \
-d '{"team_alias":"<projet>","max_budget":0.5,"budget_duration":"1d"}'
2. La chiave virtuale — una per agente¶
È l'intero meccanismo di imputazione. Senza di essa, tutti spendono sotto lo stesso nome e il pannello di controllo mostra numeri che non rispondono a nessuna domanda.
curl -sX POST "$PROXY/key/generate" -H "Authorization: Bearer $CLE_ADMIN" \
-H 'Content-Type: application/json' \
-d '{"key_alias":"<projet>-<agent>","team_id":"<id>",
"models":["<alias1>","<alias2>"],
"max_budget":0.5,"budget_duration":"1d",
"metadata":{"role":"agent-projet","agent":"<agent>"}}'
La chiave viene salvata nel portafoglio, immediatamente, mai in un file del repository: vedere Salvare un segreto dal portafoglio.
Un budget taglia
Una volta raggiunto, la chiave viene rifiutata. Per un agente di base, a cui nessuno presta attenzione, questo fornisce un servizio inutilizzabile, con un lavoro che si esaurisce. È necessario calibrare al di sopra del picco misurato, e configurare l'avviso di budget (Configurare una notifica).
3. L'agente¶
curl -sX POST "$PROXY/v1/agents" -H "Authorization: Bearer $CLE_ADMIN" \
-H 'Content-Type: application/json' -d '{
"agent_name": "<nom>",
"agent_card_params": {
"protocolVersion": "0.3",
"name": "<Nom affiché>",
"description": "<ce qu'"'"'il fait, et ce qu'"'"'il ne fera jamais>",
"url": "http://<hôte>:<port>/a2a/<nom>",
"version": "1.0.0",
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/markdown"],
"skills": [{
"id": "<verbe>", "name": "<verbe — ce qu'"'"'il établit>",
"description": "<ce que cette compétence rend, et ce qu'"'"'elle ne rend pas>",
"tags": ["<axe>"], "examples": ["<appel typique>"]
}]
},
"object_permission": { "models": ["<alias1>","<alias2>"] },
"rpm_limit": 6
}'
| Campo | Ciò che decide |
|---|---|
agent_name |
L'identificatore stabile. È questo che viene associato, mai l'agent_id: un agente ricreato dall'interfaccia utente cambia l'ID e mantiene il suo nome |
agent_card_params |
La scheda A2A fornita agli chiamanti — nome, descrizione, competenze, formati |
agent_card_params.url |
Dove il proxy digiterà. Se non c'è nulla dietro, la scheda mente |
object_permission.models |
L'elenco dei modelli. Un secondo livello di protezione, distinto da quello della chiave |
rpm_limit, tpm_limit |
Il tasso. session_* limita una conversazione, non l'intero agente |
Utilizzare l'agente¶
Quattro modalità, dalla più universale a quella più specifica.
A. Come un modello normale — il percorso che serve il 90% dei casi¶
curl -sX POST "$PROXY/v1/chat/completions" -H "Authorization: Bearer $CLE" \
-H 'Content-Type: application/json' \
-d '{"model":"a2a/<nom>","messages":[{"role":"user","content":"<consigne>"}]}'
Il proxy riconosce il prefisso a2a/, risolve l'agente nel suo registro, lo traduce in message/send e traduce nuovamente la risposta. Tutto ciò che comunica già con un modello comunica ora con l'agente: l'interfaccia di chat lo vede nella sua lista, il motore dei workflow lo vede anche, e uno script di tre righe non ha nulla di speciale da fare.
Con una riserva che non è teorica: questa risoluzione legge il registro in memoria del proxy. Dopo un riavvio, fallisce per tutti finché gli agenti non sono stati riapplicati – vedi l'incidente n. 4.
B. In A2A, per un cliente che conosce il protocollo¶
curl -s "$PROXY/a2a/<id>/.well-known/agent-card.json" -H "Authorization: Bearer $CLE"
curl -sX POST "$PROXY/a2a/<id>/message/send" -H "Authorization: Bearer $CLE" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":"1","method":"message/send","params":{"message":{
"role":"user","parts":[{"kind":"text","text":"<consigne>"}],"messageId":"<uuid>"}}}'
Da utilizzare quando si vuole il ciclo di attività – un lavoro che dura, un monitoraggio dello stato, artefatti forniti lungo il percorso.
C. Da uno script di sistema, senza passare per A2A¶
Questo è il caso di un agente che è un programma da riga di comando su una macchina, non un server. Lo script legge la sua definizione nel registro, quindi avvia l'eseguibile stesso:
agent, provenance, contrat = charge(AGENT_DE_SECOURS) # GET /v1/agents
print(f"définition : {provenance}") # litellm | cache | code
Tre cose da rispettare, e tutte sono costose da riscoprire:
- La lettura avviene con la chiave dell'agente stesso. Il registro risponde a una chiave ordinaria: non è necessario che una chiave di amministrazione sia presente sulla macchina che esegue.
- Una cache locale e la provenienza visualizzata. Un agente che gira su una copia di sicurezza produce la stessa uscita, nello stesso momento, allo stesso costo: questa riga è l'unica differenza visibile tra "aggiornato" e "proxy silenzioso da tre giorni".
- Un'etichetta di imputazione sulla chiamata
x-litellm-tags, altrimenti la spesa è attribuibile alla chiave ma non al lavoro.
D. Tra agenti¶
Un agente registrato può chiamare un altro agente utilizzando la stessa chiave. È qui che object_permission.agents serve: definire chi può chiamare chi.
Gli errori, tutti misurati¶
1. L'interfaccia di amministrazione sovrascrive litellm_params
Il modulo riscrive questo campo utilizzando solo i suoi campi. Qualsiasi dato che viene memorizzato in esso – un contratto di esecuzione, metadati interni – scompare al primo utente che apre l'agente e lo salva. Senza messaggi, senza tracce, a parte in updated_by.
Misurato: 21 campi posizionati alle 07:52, eliminati alle 08:13 dello stesso giorno. La mappa, i limiti e l'elenco dei modelli, invece, erano intatti.
Da ricordare: ciò che deve durare va nella mappa. Ciò che viene memorizzato in litellm_params necessita di una fonte esterna e di un'azione che lo ripristini.
2. La mappa elimina ciò che non conosce, restituendo 200
capabilities.extensions – il punto normativo per i metadati interni – viene filtrato al momento dell'inserimento. Solo streaming, pushNotifications e stateTransitionHistory sopravvivono. La creazione ha successo, la mappa torna incompleta, ma non viene segnalato alcun errore.
3. L'operazione di lettura non è valida
Rileggere una mappa e poi restituirla così com'è fallisce con il codice 422, sui campi di sicurezza che il proxy ha creato autonomamente. Basta rimuovere questi campi dal corpo: verranno ripristinati. Tutte le operazioni di lettura / modifica / riscrittura devono eliminarli.
4. Il registro vive in memoria: un riavvio del proxy lo svuota
L'elenco degli agenti non viene controllato dalla base all'avvio: contiene solo gli agenti creati o modificati dopo l'avvio del processo. Dopo un riavvio, esistono ancora, e possono essere raggiunti tramite il loro identificativo, ma l'elenco è vuoto, e soprattutto a2a/<nom> smette di funzionare: la risoluzione legge lo stesso registro. Tutto ciò che consumava l'agente come modello si interrompe, senza alcun avviso, mentre il proxy rimane healthy e i modelli rispondono.
Misurato due volte nella stessa ora, il 13 settembre 2026, su sei agenti.
Tre azioni, in questo ordine: conservare l'identificativo di ogni agente nella sua definizione (quando l'elenco è dimenticato, è l'unico riferimento rimasto); far sì che la condizione sia controllata invece di segnalare "assente", il che potrebbe tentare una creazione e rendere "già esistente"; e riapplicare – un semplice scambio di dati lo riporta nel registro.
Il riavvio si automatizza senza rischi, perché il conflitto è falso: la base e la fonte dicono la stessa cosa, non c'è nulla da risolvere. Ma solo in questo caso – non appena si verifica una discrepanza di un'altra natura, si prevede e non si interviene, altrimenti si sovrascriverebbe il lavoro di qualcun altro.
5. Una modifica parziale sostituisce
Un PATCH non fonde: i campi mancanti del corpo vengono persi. È sempre necessario restituire l'oggetto completo. E un contratto incompleto si comporta esattamente come un contratto completo, poiché ciò che manca ricade sui valori predefiniti del codice – da cui l'importanza di un consumatore che annuncia ciò che ha effettivamente letto.
Controlli¶
# La définition telle que le registre la sert, et rien d'autre
curl -s "$PROXY/v1/agents" -H "Authorization: Bearer $CLE" | jq '.[] | {agent_name, rpm_limit}'
# Ce que l'exécutant a réellement chargé, à son dernier run
<commande de l'agent> 2>&1 >/dev/null | head -1
# Qui a modifié l'agent en dernier — un humain dans l'UI s'y voit
curl -s "$PROXY/v1/agents/<id>" -H "Authorization: Bearer $CLE_ADMIN" \
| jq '{updated_at, updated_by}'
Dernière vérification de cette page : 2026-09-13