Ce que vous allez construire
Une application Agent-Lab complète et exécutable : un service FastAPI qui héberge un agent d'écho, un serveur MCP, la persistance PostgreSQL et l'instrumentation OpenTelemetry — le tout généré par une seule commande, sans aucun câblage manuel. En chemin, vous créerez une instance d'agent via REST, vous lui enverrez un message et vous observerez les traces du framework.
Prérequis
- Python 3.12+ et uv (
pip install uv) - Docker (ou un autre runtime de conteneurs), en cours d'exécution
Aucune clé d'API n'est nécessaire pour ce tutoriel — l'agent d'écho n'appelle aucun LLM. Les agents reposant sur un LLM viendront ensuite (voir Et ensuite ?).
1. Générer le projet
uvx cookiecutter gh:btech-software/agent-lab --directory cookiecutterRépondez aux questions — les valeurs par défaut produisent un projet nommé My Agent App :
cd my-agent-appLe projet généré est un simple consommateur du framework, et non un fork. btech-agent-lab
est une dépendance ordinaire dans pyproject.toml ; votre code vit à côté et l'étend
via l'API publique.
2. Comprendre ce que vous avez obtenu
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.tomlOuvrez my_agent_app/main.py — voici l'application tout entière :
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",
],
)Et my_agent_app/agents/echo/agent.py — l'agent lui-même :
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,
)Deux points à remarquer :
@discoverable_agent("my_agent_app_echo")— ce seul décorateur enregistre la classe sous unagent_type. Aucune modification du registre ni du schéma : l'API REST valide dynamiquementagent_typepar rapport au registre.AgentUtilsest injecté via le constructeur par le conteneur DI. Déclarez d'autres dépendances avecextra_deps=("my_provider",)et ajoutez les providers correspondants àcore/container.py(voir le Guide du développeur).
3. Tester avant d'exécuter
Les tests unitaires du projet généré démarrent l'application complète sans aucune infrastructure :
uv lock && uv sync --group dev --group test
make test_unitVous disposez aussi de la variante d'intégration — make test_integration démarre de vrais conteneurs Postgres,
Redis et Vault via testcontainers (Docker requis).
4. Lancer l'application
docker compose up --build -d
curl http://localhost:18000/status/livenessLa stack comprend l'application (port 18000), PostgreSQL avec pgvector (trois bases de données : relationnelle, vecteurs, checkpoints LangGraph), Redis pour les mises à jour d'état pub/sub, et Vault pour les secrets. La documentation OpenAPI interactive est disponible à l'adresse http://localhost:18000/docs.
L'authentification est désactivée dans le projet généré (
auth.enabled: false). Lorsque vous l'activez, chaque requête nécessite un jeton bearer — voir Authentification avec Keycloak.
5. Converser avec votre agent via REST
Les agents sont des instances d'une implémentation, créées et configurées via l'API. Créez-en une :
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"}' | jqCopiez l'id de la réponse, puis envoyez-lui un message :
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 réponse revient de manière synchrone :
{
"message_role": "assistant",
"message_content": "Echo: Hello, framework!",
"agent_id": "<agent_id>",
"id": "…"
}Cet aller-retour a sollicité toute la stack : requête REST → recherche dans le registre → conteneur
DI → votre agent → persistance du message (la réponse est elle aussi stockée — vérifiez avec
POST /messages/list). Le catalogue complet se trouve dans la Référence de l'API REST.
6. Observer la trace
L'observabilité d'Agent-Lab, c'est simplement OpenTelemetry. Lorsque la variable d'environnement
OTEL_EXPORTER_OTLP_ENDPOINT est définie, l'application exporte des traces, métriques et logs OTLP ; lorsqu'elle
n'est pas définie, le traçage est tout simplement désactivé — aucune modification de code dans un cas comme dans l'autre.
Lancez la stack Grafana fournie avec le framework (depuis le dépôt du framework) et faites pointer votre application vers son collecteur :
# 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 -dEnvoyez un autre message, puis ouvrez Grafana à l'adresse
http://localhost:3000 (admin/admin) et explorez le tableau de bord
Agent-Lab : le span HTTP, les requêtes SQL et — pour les agents reposant sur un LLM —
chaque appel de modèle avec le nombre de jetons. Vous préférez une plateforme hébergée d'observabilité LLM ? Définissez
plutôt LANGFUSE_HOST/LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY (ou LANGWATCH_ENDPOINT/
LANGWATCH_API_KEY) — détails dans le guide d'observabilité.
7. Le retrouver dans un client MCP
Le projet généré fournit déjà un outil MCP (my_agent_app/mcp/tools.py) exposé sur
/mcp, aux côtés des outils du framework pour la découverte d'agents, l'historique et la messagerie. Essayez-le
avec MCP Inspector :
npx @modelcontextprotocol/inspectorConnectez-vous à http://localhost:18000/mcp (Streamable HTTP), listez les outils et appelez
my_agent_app_hello_tool. Le même serveur fonctionne avec Claude Desktop et n'importe quel client
MCP — voir le Guide du serveur MCP.
Et ensuite ?
| Page | |
|---|---|
| 🏗️ Créer un véritable agent (reposant sur un LLM) | Guide du développeur — Créer des workflows agentiques |
| ⚙️ Configurer les bases de données, l'authentification, les secrets | Référence de configuration |
| 🌐 Catalogue complet des points de terminaison | Référence de l'API REST |
| 🧪 Évaluer le comportement des agents avec un LLM juge | Tests et simulations |
| 🚀 Mettre en production | Guide de déploiement |