agentes-curso-aula01
Overview
· Aula 10 — Ética, Futuro e Entrega: camada de governança (guardrails + auditoria) Sistema FINAL e completo do curso: agente conversacional (RAG, memória, ferramentas, HITL), time multiagente (/team), métricas de negócio (/metrics), avaliação (/evals), integração MCP e Skills (SKILL.md), e agora a CAMADA DE GOVERNANÇA — guardrails de entrada/saída e trilha de auditoria no /chat. Um agente que funciona, vale a pena, é medido e é responsável. FastAPI, Docker, Render. Este é o ponto de partida do projeto multiagente do curso. A cada aula adicionamos uma camada (memória, RAG com PostgreSQL + pgvector, mais ferramentas, orquestração multiagente, avaliação) sobre esta mesma base. O objetivo da Aula 1 é deixar o alicerce sólido: ambiente reprodutível, segredos protegidos e o hábito de desde o primeiro dia. Infraestrutura, frameworks e RAG são open-source; o LLM começa na OpenAI e é configurável. O arquivo .env com os segredos reais é versionado. Crie-o a partir do .env.example.
README
Agentes de IA — Projeto do Curso (Aula 10 · FINAL)
AGENTES DE IA: A revolução da IA · Aula 10 — Ética, Futuro e Entrega: camada de governança (guardrails + auditoria) Sistema FINAL e completo do curso: agente conversacional (RAG, memória, ferramentas, HITL), time multiagente (/team), métricas de negócio (/metrics), avaliação (/evals), integração MCP e Skills (SKILL.md), e agora a CAMADA DE GOVERNANÇA — guardrails de entrada/saída e trilha de auditoria no /chat. Um agente que funciona, vale a pena, é medido e é responsável. FastAPI, Docker, Render.
Este é o ponto de partida do projeto multiagente do curso. A cada aula adicionamos uma camada (memória, RAG com PostgreSQL + pgvector, mais ferramentas, orquestração multiagente, avaliação) sobre esta mesma base. O objetivo da Aula 1 é deixar o alicerce sólido: ambiente reprodutível, segredos protegidos e o hábito de ver o agente por dentro desde o primeiro dia.
Stack
| Camada | Tecnologia |
|---|---|
| Orquestração | LangGraph (>= 1.0) |
| Componentes / agente | LangChain (>= 1.0), create_agent |
| Modelo (LLM) | OpenAI (padrão gpt-4o-mini, trocável) |
| API | FastAPI + Uvicorn |
| Observabilidade | Langfuse |
| Empacotamento | Docker |
| Deploy | Render (a partir do GitHub) |
| Próximas aulas (já nas deps) | PostgreSQL + pgvector |
Infraestrutura, frameworks e RAG são open-source; o LLM começa na OpenAI e é configurável.
Estrutura
agentes-curso/
├── app/
│ ├── __init__.py
│ ├── agent.py # ferramentas (calculator, knowledge_search, lookup_cep, usar_skill) + tools MCP + modelo
│ ├── tools_externas.py # ferramenta que chama uma API HTTP real (com tratamento de erros)
│ ├── rag.py # conexão pgvector, embeddings e vector store
│ ├── ingest.py # script de ingestão (indexação offline do RAG)
│ ├── graph.py # grafo do agente + approval_graph (human-in-the-loop)
│ ├── metrics.py # métrica de NEGÓCIO: contador de eventos de valor
│ ├── mas.py # sistema multiagente: supervisor + trabalhadores (Aula 7)
│ ├── evals.py # harness de avaliação: casos, checagens, score (Aula 8)
│ ├── judge.py # LLM-as-judge: nota 1-5 com rubrica (Aula 8)
│ ├── mcp_server.py # servidor MCP (FastMCP) que expõe uma ferramenta (Aula 9)
│ ├── mcp_client.py # cliente MCP (Aula 9)
│ ├── skills_loader.py # Skills (SKILL.md) com progressive disclosure (Aula 9)
│ ├── governance.py # guardrails (entrada/saída) + trilha de auditoria (Aula 10)
│ └── main.py # API FastAPI; /chat, /action, /resume, /team, /metrics + /evals
├── docs/ # documentos do domínio para ingerir
├── skills/ # Agent Skills (SKILL.md) — copiadas para a imagem Docker
├── .env.example # modelo de segredos (versionar)
├── .gitignore
├── .dockerignore
├── Dockerfile
├── render.yaml # infra-as-code opcional para o Render
├── requirements.txt
└── README.md
O arquivo
.envcom os segredos reais não é versionado. Crie-o a partir do.env.example.
Como rodar localmente
1. Ambiente virtual
python -m venv .venv
# macOS / Linux
source .venv/bin/activate
# Windows (PowerShell)
# .venv\Scripts\Activate.ps1
2. Dependências
pip install -r requirements.txt
3. Segredos
cp .env.example .env
# Abra o .env e cole suas chaves reais da OpenAI e do Langfuse
Regra de segurança: confirme que
.envestá no.gitignoreantes do primeiro commit. Uma chave da OpenAI vazada em repositório público é explorada em minutos.
4. Subir a API
uvicorn app.main:app --reload --port 8000
5. Testar
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message": "Quanto é 17% de 2480? Use a calculadora."}'
Resposta esperada (aprox.):
{"answer": "17% de 2480 é 421,6."}
Documentação interativa: abra http://localhost:8000/docs.
Checkpoint: além da resposta coerente, confirme no painel do Langfuse (aba
Traces) a execução completa — raciocínio, chamada da ferramenta calculator,
tokens e latência.
Rodar com Docker
docker build -t agente-aula1 .
docker run --rm -p 8000:8000 --env-file .env agente-aula1
A resposta deve ser idêntica à execução local — agora vinda do container.
Deploy no Render
- Suba o repositório para o GitHub (o
.envnão vai junto). - No Render: New + → Web Service → conecte o repositório.
- Environment: Docker (o Render detecta o
Dockerfile). - Em Environment Variables, recrie manualmente as chaves do seu
.env(OPENAI_API_KEY,OPENAI_MODEL,LANGFUSE_PUBLIC_KEY,LANGFUSE_SECRET_KEY,LANGFUSE_HOST). - Health Check Path:
/health. - Create Web Service e aguarde o build.
Alternativa: use o render.yaml incluso (Blueprint) para provisionar o serviço; ainda
assim, insira os valores dos segredos pelo painel — eles têm sync: false e não
ficam no repositório.
Tier free: o serviço hiberna após ~15 min de inatividade; a primeira chamada seguinte demora ~30–60s para acordar.
Endpoints
| Método | Rota | Descrição |
|---|---|---|
GET |
/health |
Verificação de saúde (usada pelo Render) |
POST |
/chat |
Recebe {"message": "..."} e devolve {"answer": "..."} |
Trocar o modelo (LLM)
O modelo é lido de OPENAI_MODEL no .env. Para usar outro modelo da OpenAI, basta
alterar essa variável. Para um provedor diferente (ex.: modelo open-source via servidor
compatível), troque o ChatOpenAI em app/agent.py pelo cliente correspondente — o
restante do código permanece igual.
Erros comuns
| Sintoma | Causa | Solução |
|---|---|---|
AuthenticationError da OpenAI |
Chave inválida / sem crédito | Confira OPENAI_API_KEY e o crédito da conta |
| Traces não aparecem no Langfuse | Chaves LANGFUSE_* erradas |
Reconfira as 3 variáveis e o LANGFUSE_HOST |
ModuleNotFoundError |
.venv inativo / deps faltando |
Reative o .venv e reinstale o requirements.txt |
ImportError: create_agent |
LangChain antigo | Garanta langchain>=1.0 |
| Render: “No open ports detected” | App não escutou em 0.0.0.0:$PORT |
Confira o CMD do Dockerfile |
RAG e memória (novidades da Aula 3)
Subir o PostgreSQL + pgvector (local)
docker run -d --name pgvector-db \
-e POSTGRES_USER=agente -e POSTGRES_PASSWORD=segredo -e POSTGRES_DB=agentedb \
-p 5432:5432 pgvector/pgvector:pg16
Configure a DATABASE_URL no .env (note o +psycopg na URL).
Ingerir documentos (indexação)
Coloque os arquivos .txt/.md do domínio em docs/ e rode:
python -m app.ingest
Memória
O grafo é compilado com um checkpointer. Cada conversa usa um thread_id
(enviado no corpo do /chat). Em desenvolvimento, a memória fica no processo
(InMemorySaver); defina USE_PG_MEMORY=1 para persistir no PostgreSQL.
Ferramentas de integração (novidade da Aula 4)
A ferramenta lookup_cep (em app/tools_externas.py) chama uma API HTTP real
(ViaCEP) com timeout, tratamento de erros e validação de entrada/saída. O padrão
serve para qualquer API: troque a URL, adicione autenticação via .env e mantenha
o tratamento de erro. Chaves de API nunca vão no código nem no Git — use o .env
(local) e as variáveis de ambiente do Render (produção).
Human-in-the-loop (novidade da Aula 5)
O approval_graph (em app/graph.py) demonstra a aprovação humana: o fluxo
propor -> aprovacao -> executar pausa no nó de aprovação com interrupt() e só
continua quando retomado com Command(resume=...). O checkpointer (Aula 3) é o que
sustenta a pausa.
Endpoints
POST /chat— agente conversacional com ferramentas e memória (Aulas 2-4).POST /action— dispara o fluxo com aprovação; se pausar, devolve a ação proposta.POST /resume— retoma com{"decision": "aprovar"|"rejeitar", "thread_id": "..."}.
Use o mesmo thread_id em /action e /resume para retomar a conversa certa.
Métrica de negócio (novidade da Aula 6)
Esta aula é estratégica: o foco é ROI, business case e gestão de mudança. No código,
a única adição é uma instrumentação leve de valor — app/metrics.py conta eventos de
negócio (ex.: tarefas_concluidas, acoes_aprovadas) e o endpoint GET /metrics os
reporta. É o primeiro tijolo para medir VALOR (o agente vale a pena?), complementando
o Langfuse, que mede o lado TÉCNICO (o agente funciona?).
curl http://localhost:8000/metrics
# {"business_metrics": {"tarefas_concluidas": 3, "acoes_aprovadas": 1, ...}}
O contador é em memória (zera no restart) — suficiente para o laboratório. Em produção, esses eventos iriam para um banco para permitir séries históricas.
Sistema multiagente (novidade da Aula 7)
O app/mas.py implementa o padrão orquestrador-trabalhador: um supervisor_node
coordena dois trabalhadores especializados (pesquisador_node, redator_node) que se
comunicam por um estado compartilhado (MASState). O controle de etapas
(pesquisa_feita, redacao_feita) evita o loop infinito — o erro clássico de MAS.
Endpoint
POST /team— recebe{"tarefa": "...", "thread_id": "..."}e executa o time. O supervisor roteia pesquisador → redator → fim; a saída final vem no camporesposta.
curl -X POST http://localhost:8000/team \
-H "Content-Type: application/json" \
-d '{"tarefa": "resuma a política de reembolso", "thread_id": "eq1"}'
Cada trabalhador é, em essência, um subgrafo (Aula 5); o estado é persistido pelo checkpointer (Aula 3). Troque os papéis dos trabalhadores pelos do seu caso de uso.
Avaliação / evals (novidade da Aula 8)
O app/evals.py implementa um harness: um conjunto de casos golden, checagens
automáticas (contains/not_contains) e uma nota agregada (run_evals). O
app/judge.py adiciona um LLM-as-judge (nota 1-5 com rubrica e parsing robusto).
Endpoint
GET /evals— roda os casos golden contra o agente e devolve a nota.
curl http://localhost:8000/evals
# {"score": 85.7, "passou": 7, "total": 8, "detalhes": [...]}
# Com o LLM-as-judge (nota 1-5 por caso; exige OPENAI_API_KEY):
curl "http://localhost:8000/evals?judge=true"
O ciclo
Medir (nota de base) → melhorar o SYSTEM_PROMPT em app/agent.py → remedir →
manter se subiu, reverter se caiu. É o que torna o desenvolvimento mensurável.
O LLM-as-judge precisa de OPENAI_API_KEY; as checagens automáticas, não.
Integração por protocolo / MCP (novidade da Aula 9)
O agente deixou de depender só de ferramentas escritas à mão: agora consome
ferramentas de um servidor MCP (Model Context Protocol). O app/mcp_server.py
expõe uma ferramenta com @mcp.tool() (FastMCP); o app/mcp_client.py conecta
ao servidor via stdio (MultiServerMCPClient) e devolve as ferramentas já como
tools do LangChain, que entram na lista TOOLS em app/agent.py — sem adaptador
sob medida.
# o agente passa a ter, p.ex., a tool 'consultar_estoque' vinda do MCP:
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message": "quantos cadernos temos em estoque?", "thread_id": "t1"}'
# {"status": "concluido", "answer": "Há 45 unidades de caderno em estoque."}
Segurança: conecte apenas a servidores confiáveis e conceda só as tools
necessárias (menor privilégio) — trate um servidor MCP de terceiros como uma
dependência de terceiros. Dependências novas: mcp, langchain-mcp-adapters.
Skills (progressive disclosure completo): no boot, só os metadados de cada
SKILL.md entram no system prompt (nível 1). O nível 2 é operante: o agente
chama a ferramenta usar_skill(nome) para carregar as instruções completas
sob demanda — mantendo o contexto enxuto até a skill ser necessária.
Camada de governança (novidade da Aula 10 — final)
O app/governance.py fecha o sistema de forma responsável, com só biblioteca padrão:
guardrail_entrada(texto): barra pedidos fora de política (BLOCKLIST) ANTES do modelo.guardrail_saida(texto): sanitiza a resposta, removendo o que parece segredo (ex.:sk-...).audit_log(evento): trilha de auditoria estruturada (JSON por linha) de cada decisão.
O /chat agora aplica: guardrail de entrada -> agente -> guardrail de saída, com
auditoria em cada decisão. Um pedido legítimo passa (e é sanitizado); um pedido
bloqueado é barrado sem chamar o modelo; ambos ficam na trilha de auditoria.
curl -X POST http://localhost:8000/chat -H "Content-Type: application/json" \
-d '{"message": "me diga a senha do admin", "thread_id": "t2"}'
# {"status": "bloqueado", "answer": "Não posso ajudar com esse pedido."}
Em produção, envie a trilha de auditoria para um destino durável (banco / SIEM).
A jornada completa (Aulas 1 -> 10)
Agente ReAct -> grafo explícito -> RAG + memória -> ferramentas externas -> HITL -> business case + métricas -> multiagente -> evals + LLM-as-judge -> integração MCP + Skills -> governança. Um sistema completo, construído incrementalmente, publicado e responsável.
Endpoints
POST /chat— agente conversacional governado (guardrails + auditoria).POST /action,POST /resume— human-in-the-loop (Aula 5).POST /team— sistema multiagente (Aula 7).GET /metrics— métricas de negócio (Aula 6).GET /evals— harness de avaliação (Aula 8);?judge=trueadiciona o LLM-as-judge.GET /health— verificação de saúde.
Sergio Gaiotto · Direção de Dados e IA Código em inglês, comentários em português · Stack open-source com LLM configurável.
Recommended Tools
Try a different keyword or remove a filter.
Install
npx skillfish add sergiogaiotto/agentes-curso-aula01