O que você vai construir
Uma aplicação Agent-Lab completa e executável: um serviço FastAPI que hospeda um agente de eco, um servidor MCP, persistência em PostgreSQL e instrumentação com OpenTelemetry — tudo gerado por um único comando, sem nenhuma conexão manual. No caminho, você vai criar uma instância de agente via REST, enviar uma mensagem a ela e acompanhar os traces do framework.
Pré-requisitos
- Python 3.12+ e uv (
pip install uv) - Docker (ou outro runtime de containers) em execução
Nenhuma chave de API é necessária para este tutorial — o agente de eco não chama um LLM. Agentes baseados em LLM vêm em seguida (consulte Próximos passos).
1. Crie a estrutura do projeto
uvx cookiecutter gh:btech-software/agent-lab --directory cookiecutterResponda às perguntas — os valores padrão geram um projeto chamado My Agent App:
cd my-agent-appO scaffold é um consumidor leve do framework, e não um fork. btech-agent-lab é
uma dependência comum em pyproject.toml; seu código fica ao lado dela e a estende por
meio da API pública.
2. Entenda o que você recebeu
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.tomlAbra my_agent_app/main.py — esta é a aplicação inteira:
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 — o próprio agente:
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,
)Dois pontos a observar:
@discoverable_agent("my_agent_app_echo")— esse único decorator registra a classe sob umagent_type. Sem edições no registro, sem mudanças de schema: a API REST validaagent_typecontra o registro dinamicamente.AgentUtilsé injetado pelo construtor por meio do container de DI. Declare mais dependências comextra_deps=("my_provider",)e adicione os providers correspondentes emcore/container.py(consulte o Guia do desenvolvedor).
3. Teste antes de executar
Os testes unitários do scaffold inicializam a aplicação inteira sem nenhuma infraestrutura:
uv lock && uv sync --group dev --group test
make test_unitVocê também recebe a versão de integração — make test_integration sobe containers
reais de Postgres, Redis e Vault via testcontainers (requer Docker).
4. Execute a aplicação
docker compose up --build -d
curl http://localhost:18000/status/livenessA stack é composta pela aplicação (porta 18000), PostgreSQL com pgvector (três bancos de dados: relacional, vetores e checkpoints do LangGraph), Redis para atualizações de status via pub/sub e Vault para segredos. A documentação interativa do OpenAPI fica em http://localhost:18000/docs.
A autenticação vem desativada no scaffold (
auth.enabled: false). Quando você a ativar, toda requisição precisará de um bearer token — consulte Autenticação com Keycloak.
5. Converse com seu agente via REST
Agentes são instâncias de uma implementação, criadas e configuradas pela API. Crie uma:
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"}' | jqCopie o id da resposta e, em seguida, envie uma mensagem ao agente:
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!"
}' | jqA resposta volta de forma síncrona:
{
"message_role": "assistant",
"message_content": "Echo: Hello, framework!",
"agent_id": "<agent_id>",
"id": "…"
}Essa ida e volta exercitou a stack inteira: requisição REST → consulta ao registro →
container de DI → seu agente → persistência da mensagem (e a resposta também é
armazenada — confira com POST /messages/list). O catálogo completo está na
Referência da API REST.
6. Acompanhe o trace
A observabilidade do Agent-Lab é simplesmente OpenTelemetry. Quando a variável de
ambiente OTEL_EXPORTER_OTLP_ENDPOINT está definida, a aplicação exporta
traces/métricas/logs OTLP; quando não está, o tracing fica simplesmente desativado —
sem mudanças de código em nenhum dos casos.
Execute a stack do Grafana incluída no framework (a partir do repositório do framework) e aponte sua aplicação para o collector dela:
# 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 -dEnvie outra mensagem e abra o Grafana em
http://localhost:3000 (admin/admin) para explorar o
dashboard Agent-Lab: o span HTTP, as consultas SQL e — para agentes baseados em
LLM — cada chamada de modelo com a contagem de tokens. Prefere uma plataforma de
observabilidade de LLM hospedada? Defina LANGFUSE_HOST/LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY
(ou LANGWATCH_ENDPOINT/LANGWATCH_API_KEY) — detalhes no
guia de observabilidade.
7. Encontre-o em um cliente MCP
O scaffold já inclui uma ferramenta MCP (my_agent_app/mcp/tools.py) exposta em
/mcp, ao lado das ferramentas de descoberta de agentes, histórico e mensagens do
framework. Experimente com o MCP Inspector:
npx @modelcontextprotocol/inspectorConecte-se a http://localhost:18000/mcp (Streamable HTTP), liste as ferramentas e
chame my_agent_app_hello_tool. O mesmo servidor funciona com o Claude Desktop e com
qualquer cliente MCP — consulte o Guia do servidor MCP.
Próximos passos
| Página | |
|---|---|
| 🏗️ Construa um agente real (baseado em LLM) | Guia do desenvolvedor — Construindo workflows agênticos |
| ⚙️ Configure bancos de dados, autenticação e segredos | Referência de configuração |
| 🌐 Catálogo completo de endpoints | Referência da API REST |
| 🧪 Avalie o comportamento dos agentes com um LLM juiz | Testes e simulações |
| 🚀 Coloque em produção | Guia de implantação |