Cosa creerai
Un'applicazione Agent-Lab completa ed eseguibile: un servizio FastAPI che ospita un agente echo, un server MCP, persistenza su PostgreSQL e strumentazione OpenTelemetry, tutto generato da un solo comando, senza alcun collegamento manuale. Lungo il percorso creerai un'istanza di agente via REST, le invierai un messaggio e osserverai le trace del framework.
Prerequisiti
- Python 3.12+ e uv (
pip install uv) - Docker (o un altro container runtime), in esecuzione
Per questo tutorial non servono API key: l'agente echo non chiama alcun LLM. Gli agenti basati su LLM vengono dopo (vedi Prossimi passi).
1. Crea lo scaffold del progetto
uvx cookiecutter gh:btech-software/agent-lab --directory cookiecutterRispondi alle domande; i valori predefiniti generano un progetto chiamato My Agent App:
cd my-agent-appLo scaffold è un semplice consumatore del framework, non un fork. btech-agent-lab
è una normale dipendenza in pyproject.toml; il tuo codice si affianca a essa e la
estende tramite l'API pubblica.
2. Scopri cosa hai ottenuto
my-agent-app/
├── my_agent_app/
│ ├── main.py # the composition root — one create_app() call
│ ├── core/container.py # your DI container — add providers here
│ ├── agents/echo/agent.py # your first agent (echo)
│ └── mcp/tools.py # your first MCP tool
├── config-dev.yml / config-test.yml / config-docker.yml
├── tests/ # unit tests (no infra) + optional testcontainers suite
├── compose.yml # app + postgres (pgvector) + redis + vault
└── Makefile, docker/, .github/, pyproject.tomlApri my_agent_app/main.py: questa è l'intera applicazione:
from agent_lab import create_app
from my_agent_app.core.container import Container
# An explicit scan_packages list replaces agent_lab's DEFAULT_SCAN_PACKAGES:
# only this project's agents, MCP tools, and prompts are discovered — none of
# the framework's built-in examples. Add "agent_lab.services.agent_types" or
# "agent_lab.interface.mcp" here if you want the built-ins back.
app = create_app(
container=Container(),
scan_packages=[
"my_agent_app.agents",
"my_agent_app.mcp",
],
)E my_agent_app/agents/echo/agent.py, l'agente vero e proprio:
from langchain_core.messages import AIMessage
from langgraph.graph import MessagesState
from agent_lab import AgentBase, AgentUtils, discoverable_agent
from agent_lab.interface.api.messages.schema import Message, MessageRequest
from agent_lab.services.tasks import TaskProgress
@discoverable_agent("my_agent_app_echo")
class EchoAgent(AgentBase):
"""Minimal agent: echoes the incoming message without calling an LLM."""
def __init__(self, agent_utils: AgentUtils):
super().__init__(agent_utils)
def create_default_settings(self, agent_id: str, schema: str):
pass
def get_input_params(self, message_request: MessageRequest, schema: str) -> dict:
return message_request.model_dump()
def process_message(self, message_request: MessageRequest, schema: str) -> Message:
message_content, response_data = self.format_response(
MessagesState(
messages=[AIMessage(content=f"Echo: {message_request.message_content}")]
)
)
self.task_notification_service.publish_update(
task_progress=TaskProgress(
agent_id=message_request.agent_id,
status="completed",
message_content=message_content,
response_data=response_data,
)
)
return Message(
message_role="assistant",
message_content=message_content,
response_data=response_data,
agent_id=message_request.agent_id,
)Due aspetti da notare:
@discoverable_agent("my_agent_app_echo"): quel solo decorator registra la classe con unagent_type. Nessuna modifica al registro, nessuna modifica allo schema: la REST API validaagent_typerispetto al registro in modo dinamico.AgentUtilsviene iniettato tramite il costruttore dal container DI. Dichiara altre dipendenze conextra_deps=("my_provider",)e aggiungi i provider corrispondenti incore/container.py(vedi la Guida per sviluppatori).
3. Testa prima di eseguire
Gli unit test dello scaffold avviano l'intera applicazione senza alcuna infrastruttura:
uv lock && uv sync --group dev --group test
make test_unitÈ inclusa anche la variante di integrazione: make test_integration avvia container
reali di Postgres, Redis e Vault tramite testcontainers (richiede Docker).
4. Esegui l'app
docker compose up --build -d
curl http://localhost:18000/status/livenessLo stack comprende l'app (porta 18000), PostgreSQL con pgvector (tre database: relazionale, vettori, checkpoint LangGraph), Redis per gli aggiornamenti di stato pub/sub e Vault per i segreti. La documentazione OpenAPI interattiva si trova su http://localhost:18000/docs.
L'autenticazione è disabilitata nello scaffold (
auth.enabled: false). Quando la abiliti, ogni richiesta richiede un bearer token: vedi Autenticazione con Keycloak.
5. Comunica con il tuo agente via REST
Gli agenti sono istanze di un'implementazione, create e configurate tramite l'API. Creane una:
curl -s -X POST http://localhost:18000/agents/create \
-H "Content-Type: application/json" \
-d '{"agent_name": "my-first-agent", "agent_type": "my_agent_app_echo"}' | jqCopia l'id dalla risposta, poi invia un messaggio:
curl -s -X POST http://localhost:18000/messages/post \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<agent_id>",
"message_role": "human",
"message_content": "Hello, framework!"
}' | jqLa risposta arriva in modo sincrono:
{
"message_role": "assistant",
"message_content": "Echo: Hello, framework!",
"agent_id": "<agent_id>",
"id": "…"
}Questo round-trip ha coinvolto l'intero stack: richiesta REST → ricerca nel registro →
container DI → il tuo agente → persistenza del messaggio (anche la risposta viene
salvata: verificalo con POST /messages/list). Il catalogo completo è nel
Riferimento della REST API.
6. Osserva la trace
L'osservabilità di Agent-Lab è semplicemente OpenTelemetry. Quando la variabile
d'ambiente OTEL_EXPORTER_OTLP_ENDPOINT è impostata, l'app esporta trace/metriche/log
OTLP; quando non è impostata, il tracing è semplicemente disattivato. In nessuno dei
due casi servono modifiche al codice.
Avvia lo stack Grafana incluso nel framework (dal repository del framework) e punta la tua app verso il suo collector:
# In the agent-lab framework repo — collector on :4318, Grafana UI on :3000
docker compose -f compose-grafana.yml up --build
# Back in your project — restart the app with the endpoint set
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 docker compose up --build -dInvia un altro messaggio, poi apri Grafana su
http://localhost:3000 (admin/admin) ed esplora la
dashboard Agent-Lab: lo span HTTP, le query SQL e, per gli agenti basati su LLM,
ogni chiamata al modello con il conteggio dei token. Preferisci una piattaforma di
osservabilità per LLM in hosting? Imposta invece
LANGFUSE_HOST/LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY (oppure LANGWATCH_ENDPOINT/
LANGWATCH_API_KEY): i dettagli sono nella guida all'osservabilità.
7. Ritrovalo in un client MCP
Lo scaffold include già un tool MCP (my_agent_app/mcp/tools.py) esposto su /mcp,
insieme ai tool del framework per la discovery degli agenti, la cronologia e la
messaggistica. Provalo con MCP Inspector:
npx @modelcontextprotocol/inspectorConnettiti a http://localhost:18000/mcp (Streamable HTTP), elenca i tool e invoca
my_agent_app_hello_tool. Lo stesso server funziona con Claude Desktop e con
qualsiasi client MCP: vedi la guida al server MCP.
Prossimi passi
| Pagina | |
|---|---|
| 🏗️ Crea un vero agente (basato su LLM) | Guida per sviluppatori — Creare workflow agentici |
| ⚙️ Configura database, autenticazione, segreti | Riferimento della configurazione |
| 🌐 Catalogo completo degli endpoint | Riferimento della REST API |
| 🧪 Valuta il comportamento degli agenti con un LLM giudice | Test e simulazioni |
| 🚀 Mettilo in produzione | Guida al deployment |