mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-07-09 22:04:21 +00:00
First commit
This commit is contained in:
24
Documentacao/.oca/custom_code_review_guidelines.txt
Normal file
24
Documentacao/.oca/custom_code_review_guidelines.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
# Sample guideline, please follow similar structure for guideline with code samples
|
||||
# 1. Suggest using streams instead of simple loops for better readability.
|
||||
# <example>
|
||||
# *Comment:
|
||||
# Category: Minor
|
||||
# Issue: Use streams instead of a loop for better readability.
|
||||
# Code Block:
|
||||
#
|
||||
# ```java
|
||||
# // Calculate squares of numbers
|
||||
# List<Integer> squares = new ArrayList<>();
|
||||
# for (int number : numbers) {
|
||||
# squares.add(number * number);
|
||||
# }
|
||||
# ```
|
||||
# Recommendation:
|
||||
#
|
||||
# ```java
|
||||
# // Calculate squares of numbers
|
||||
# List<Integer> squares = Arrays.stream(numbers)
|
||||
# .map(n -> n * n) // Map each number to its square
|
||||
# .toList();
|
||||
# ```
|
||||
# </example>
|
||||
BIN
Documentacao/Arquitetura_Geral_Agent_Framework_OCI.docx
Normal file
BIN
Documentacao/Arquitetura_Geral_Agent_Framework_OCI.docx
Normal file
Binary file not shown.
BIN
Documentacao/Manual de Roteamento Multi-Agent.docx
Normal file
BIN
Documentacao/Manual de Roteamento Multi-Agent.docx
Normal file
Binary file not shown.
BIN
Documentacao/Manual_Desenvolvedor_AI_Agent_Framework_OCI.docx
Normal file
BIN
Documentacao/Manual_Desenvolvedor_AI_Agent_Framework_OCI.docx
Normal file
Binary file not shown.
BIN
Documentacao/Manual_Integracao_MCP_Servers_Agent_Framework.docx
Normal file
BIN
Documentacao/Manual_Integracao_MCP_Servers_Agent_Framework.docx
Normal file
Binary file not shown.
68
Documentacao/README_CHECKPOINT_ENTERPRISE.md
Normal file
68
Documentacao/README_CHECKPOINT_ENTERPRISE.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Checkpoint Enterprise no Agent Framework OCI
|
||||
|
||||
Esta versão adiciona quatro capacidades ao checkpointer do LangGraph usado pelo framework:
|
||||
|
||||
1. **Checkpoint Integrity**: cada checkpoint é salvo dentro de um envelope com `schema_version`, `checkpoint_id`, `payload_hash` SHA-256 e `created_at`. Na leitura, o hash é recalculado. Se o payload foi truncado, alterado ou corrompido, o checkpoint é ignorado no recovery.
|
||||
2. **Checkpoint Compaction**: checkpoints antigos são removidos automaticamente conforme a configuração `CHECKPOINT_COMPACT_EVERY` e `CHECKPOINT_KEEP_LAST`. Isso evita crescimento infinito da tabela `workflow_checkpoints`.
|
||||
3. **Resilient Checkpointer**: gravações e leituras usam retry com backoff e jitter. A camada resiliente funciona sobre memory, SQLite e Oracle/Autonomous Database.
|
||||
4. **Checkpoint Recovery**: ao recuperar o estado, o framework varre os últimos checkpoints e retorna o mais recente válido, pulando checkpoints corrompidos.
|
||||
|
||||
## Configuração
|
||||
|
||||
No `.env`:
|
||||
|
||||
```env
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
|
||||
ENABLE_RESILIENT_CHECKPOINTER=true
|
||||
ENABLE_CHECKPOINT_INTEGRITY=true
|
||||
ENABLE_CHECKPOINT_COMPACTION=true
|
||||
CHECKPOINT_COMPACT_EVERY=50
|
||||
CHECKPOINT_KEEP_LAST=20
|
||||
CHECKPOINT_RECOVERY_SCAN_LIMIT=25
|
||||
CHECKPOINT_RETRY_MAX_ATTEMPTS=3
|
||||
CHECKPOINT_RETRY_BASE_DELAY_SECONDS=0.05
|
||||
CHECKPOINT_RETRY_MAX_DELAY_SECONDS=1.0
|
||||
CHECKPOINT_RETRY_JITTER_SECONDS=0.05
|
||||
```
|
||||
|
||||
Para produção com múltiplos pods, prefira:
|
||||
|
||||
```env
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=autonomous
|
||||
ADB_USER=...
|
||||
ADB_PASSWORD=...
|
||||
ADB_DSN=...
|
||||
ADB_WALLET_LOCATION=...
|
||||
ADB_TABLE_PREFIX=AGENTFW
|
||||
```
|
||||
|
||||
## Uso no LangGraph
|
||||
|
||||
```python
|
||||
from agent_framework.checkpoints import create_langgraph_checkpointer
|
||||
|
||||
checkpointer = create_langgraph_checkpointer(settings)
|
||||
graph = builder.compile(checkpointer=checkpointer)
|
||||
|
||||
config = {"configurable": {"thread_id": session_id}}
|
||||
result = graph.invoke(input_state, config=config)
|
||||
```
|
||||
|
||||
O `thread_id` continua sendo a chave de recuperação da conversa. Em ambiente com Load Balancer, qualquer pod consegue retomar a execução se usar o mesmo repositório persistente.
|
||||
|
||||
## Arquivos alterados
|
||||
|
||||
- `agent_framework/src/agent_framework/checkpoints/checkpoint_repository.py`
|
||||
- `agent_framework/src/agent_framework/checkpoints/langgraph_saver.py`
|
||||
- `agent_framework/src/agent_framework/checkpoints/__init__.py`
|
||||
- `agent_framework/src/agent_framework/config/settings.py`
|
||||
- `tests/unit/test_resilient_checkpointer.py`
|
||||
|
||||
## Observação importante
|
||||
|
||||
O provider `memory` agora também usa o `RepositoryCheckpointSaver` quando `ENABLE_RESILIENT_CHECKPOINTER=true`. Para voltar ao `MemorySaver` puro do LangGraph em testes locais, configure:
|
||||
|
||||
```env
|
||||
ENABLE_RESILIENT_CHECKPOINTER=false
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=memory
|
||||
```
|
||||
114
Documentacao/README_ENTERPRISE_ROUTING.md
Normal file
114
Documentacao/README_ENTERPRISE_ROUTING.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# AI Agent Platform — Enterprise Routing Edition
|
||||
|
||||
Esta versão inclui o projeto completo com:
|
||||
|
||||
- `agent_framework`: framework reutilizável.
|
||||
- `agent_template_backend`: backend FastAPI com LangGraph, OCI Generative AI, Langfuse, guardrails, judges, supervisor e roteamento enterprise.
|
||||
- `agent_frontend`: frontend web independente.
|
||||
- `templates/template_telecom_billing_product`: template de exemplo para telecom com agentes de Fatura e Produto.
|
||||
- `templates/template_retail_orders_support`: template de exemplo para e-commerce com agentes de Pedido e Suporte.
|
||||
|
||||
## Roteamento enterprise
|
||||
|
||||
O roteamento fica em:
|
||||
|
||||
```text
|
||||
agent_framework/src/agent_framework/routing/
|
||||
```
|
||||
|
||||
Componentes principais:
|
||||
|
||||
- `models.py`: modelos `IntentDefinition`, `RouterStatePolicy`, `RouteDecision`.
|
||||
- `config_loader.py`: carrega o YAML de intents e políticas.
|
||||
- `enterprise_router.py`: decide o agente de destino por estado, keyword, LLM ou fallback.
|
||||
|
||||
O template usa:
|
||||
|
||||
```text
|
||||
agent_template_backend/config/routing.yaml
|
||||
```
|
||||
|
||||
## Ordem de decisão
|
||||
|
||||
1. Estado conversacional (`state_policies`).
|
||||
2. Keywords/intents configuráveis.
|
||||
3. LLM Router opcional (`ENABLE_LLM_ROUTER=true`).
|
||||
4. Fallback (`router.fallback_agent`).
|
||||
|
||||
## Como testar roteamento sem chamar o agente final
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/debug/route \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"channel": "web",
|
||||
"payload": {
|
||||
"text": "Minha fatura veio alta",
|
||||
"user_id": "u1",
|
||||
"channel_id": "browser-1",
|
||||
"context": {"msisdn": "5511999999999"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Resposta esperada:
|
||||
|
||||
```json
|
||||
{
|
||||
"route": "billing_agent",
|
||||
"agent": "billing_agent",
|
||||
"intent": "billing_invoice_explanation",
|
||||
"method": "keyword"
|
||||
}
|
||||
```
|
||||
|
||||
## Como habilitar roteamento por LLM
|
||||
|
||||
No `.env` do backend:
|
||||
|
||||
```env
|
||||
LLM_PROVIDER=oci_openai
|
||||
OCI_GENAI_API_KEY=...
|
||||
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
|
||||
OCI_GENAI_MODEL=openai.gpt-4.1
|
||||
ENABLE_LLM_ROUTER=true
|
||||
ROUTING_CONFIG_PATH=./config/routing.yaml
|
||||
```
|
||||
|
||||
## Como adicionar novo agente
|
||||
|
||||
1. Criar classe do agente em `agent_template_backend/app/agents/`.
|
||||
2. Instanciar o agente em `AgentWorkflow.__init__`.
|
||||
3. Adicionar node no LangGraph.
|
||||
4. Adicionar a rota no `add_conditional_edges`.
|
||||
5. Criar intent no `config/routing.yaml` apontando `agent: nome_do_agente`.
|
||||
|
||||
## Templates incluídos
|
||||
|
||||
### Template 1 — Telecom
|
||||
|
||||
Diretório:
|
||||
|
||||
```text
|
||||
templates/template_telecom_billing_product
|
||||
```
|
||||
|
||||
Agentes:
|
||||
|
||||
- BillingAgent
|
||||
- ProductAgent
|
||||
|
||||
### Template 2 — Retail/E-commerce
|
||||
|
||||
Diretório:
|
||||
|
||||
```text
|
||||
templates/template_retail_orders_support
|
||||
```
|
||||
|
||||
Agentes:
|
||||
|
||||
- OrdersAgent
|
||||
- SupportAgent
|
||||
|
||||
Este segundo template mostra como reutilizar a mesma arquitetura para outro domínio de negócio.
|
||||
23
Documentacao/README_FIRST_ENTERPRISE_DELTA.md
Normal file
23
Documentacao/README_FIRST_ENTERPRISE_DELTA.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Delta Implementado para Padrão FIRST
|
||||
|
||||
Esta versão corrige as prioridades levantadas na comparação com o FIRST:
|
||||
|
||||
1. Oracle Session Repository real
|
||||
2. Oracle Message History real
|
||||
3. Oracle LangGraph Checkpoint Repository real
|
||||
4. LangGraph Deep Telemetry
|
||||
5. Token Accounting
|
||||
6. Cost Accounting
|
||||
7. Session Lock SSE
|
||||
8. Replay Buffer SSE
|
||||
9. KeepAlive SSE
|
||||
10. Recovery por Last-Event-ID
|
||||
11. Redis Provider e Distributed Cache
|
||||
12. Oracle Vector Provider
|
||||
13. Oracle Graph Provider
|
||||
14. RAG Telemetry
|
||||
15. Langfuse Generation Tracking
|
||||
16. OpenTelemetry/Event Bus compatível
|
||||
17. OCI Streaming Exporter preservado
|
||||
|
||||
A lógica de domínio continua genérica; o framework não copia regras específicas de cobrança do FIRST.
|
||||
45
Documentacao/README_FIRST_ENTERPRISE_PLUS.md
Normal file
45
Documentacao/README_FIRST_ENTERPRISE_PLUS.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Agent Framework FIRST Enterprise Plus
|
||||
|
||||
Esta versão evolui o framework nos quatro blocos solicitados:
|
||||
|
||||
1. **Langfuse Enterprise completo**
|
||||
- `Telemetry.span()` com trace/session/user/metadata/tags.
|
||||
- `Telemetry.generation()` com `usage`, token/cost metadata e compatibilidade Langfuse v2/v3.
|
||||
- `Telemetry.score()` para judges/avaliações.
|
||||
- Eventos arbitrários são registrados como spans seguros para evitar `Unknown observation type` no Langfuse.
|
||||
|
||||
2. **Token/Cost Accounting completo**
|
||||
- `TokenUsageCollector` suporta `prompt_tokens`, `completion_tokens`, `cached_tokens`, `reasoning_tokens` e `total_tokens`.
|
||||
- Tabela de preços por modelo via `MODEL_PRICES_JSON`.
|
||||
- Conversão USD→BRL via `USD_BRL_RATE`.
|
||||
- Persistência em `UsageRepository` e endpoint `/debug/usage`.
|
||||
|
||||
3. **Redis distribuído**
|
||||
- `DistributedCache`: L1 memória + L2 Redis/SQLite/Oracle.
|
||||
- `RedisCache` com `redis.asyncio` quando disponível e fallback sync.
|
||||
- Namespace por `CACHE_KEY_PREFIX`.
|
||||
- Telemetria de cache hit/miss/set/delete.
|
||||
|
||||
4. **Oracle Vector + PGQL reais**
|
||||
- `OracleVectorStore` usa `VECTOR_DISTANCE(..., COSINE)` e `TO_VECTOR()` no Oracle 23ai.
|
||||
- Tentativa automática de criar vector index quando suportado.
|
||||
- `OracleGraphStore` usa tabelas `GRAPH_NODE` e `GRAPH_EDGE`.
|
||||
- Suporte a criação de Property Graph e consulta por `GRAPH_TABLE`/PGQL, com fallback SQL.
|
||||
|
||||
Também foi corrigido o problema de duplicação SSE por replay + fila live usando controle de `max_replayed_id` no `SSEHub.subscribe()`.
|
||||
|
||||
## Testes
|
||||
|
||||
```bash
|
||||
PYTHONPATH=agent_framework/src pytest -q tests/unit
|
||||
```
|
||||
|
||||
Resultado validado nesta geração:
|
||||
|
||||
```text
|
||||
17 passed
|
||||
```
|
||||
|
||||
## Segurança
|
||||
|
||||
Os arquivos `.env` foram higienizados para não conter chaves reais. Configure suas credenciais localmente antes de usar OCI/Langfuse.
|
||||
105
Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md
Normal file
105
Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Ajustes operacionais finais — padrão FIRST
|
||||
|
||||
Esta versão corrige os gaps identificados na comparação contra o FIRST.
|
||||
|
||||
## Correções aplicadas
|
||||
|
||||
### 1. Checkpoint LangGraph operacional
|
||||
|
||||
O workflow não compila mais com `MemorySaver()` diretamente. Foi criado o adaptador:
|
||||
|
||||
```text
|
||||
agent_framework/checkpoints/langgraph_saver.py
|
||||
```
|
||||
|
||||
Ele conecta o LangGraph ao repository configurado do framework:
|
||||
|
||||
- `memory`
|
||||
- `sqlite`
|
||||
- `oracle` / `autonomous`
|
||||
|
||||
No workflow:
|
||||
|
||||
```python
|
||||
builder.compile(checkpointer=create_langgraph_checkpointer(self.settings))
|
||||
```
|
||||
|
||||
### 2. Telemetria LangGraph envolvendo a execução real
|
||||
|
||||
Foi adicionado wrapper de nó no workflow:
|
||||
|
||||
```python
|
||||
self._node("billing_agent", self.billing_agent)
|
||||
```
|
||||
|
||||
Assim o span/evento `langgraph.node.*` envolve a execução real do nó, não apenas um bloco vazio.
|
||||
|
||||
Eventos emitidos:
|
||||
|
||||
- `langgraph.node.started`
|
||||
- `langgraph.node.completed`
|
||||
- `langgraph.node.failed`
|
||||
- `langgraph.edge.selected`
|
||||
|
||||
### 3. RAG integrado aos agentes
|
||||
|
||||
Os agentes agora recebem `RagService` e usam o contexto recuperado no prompt:
|
||||
|
||||
- BillingAgent
|
||||
- ProductAgent
|
||||
- OrdersAgent
|
||||
- SupportAgent
|
||||
|
||||
O RAG usa:
|
||||
|
||||
- `VECTOR_STORE_PROVIDER=memory|sqlite|oracle|autonomous`
|
||||
- `GRAPH_STORE_PROVIDER=memory|oracle|autonomous`
|
||||
- `RAG_TOP_K`
|
||||
|
||||
### 4. Cache integrado ao runtime dos agentes
|
||||
|
||||
Criado mixin:
|
||||
|
||||
```text
|
||||
agent_template_backend/app/agents/runtime.py
|
||||
```
|
||||
|
||||
Ele adiciona:
|
||||
|
||||
- busca RAG padronizada;
|
||||
- chave de cache para chamada LLM;
|
||||
- hit/miss com telemetria;
|
||||
- cache distribuído via `create_cache(settings)`.
|
||||
|
||||
### 5. Testes unitários
|
||||
|
||||
Criada pasta:
|
||||
|
||||
```text
|
||||
tests/unit
|
||||
```
|
||||
|
||||
Cobertura inicial:
|
||||
|
||||
- cache;
|
||||
- SSE;
|
||||
- RAG;
|
||||
- checkpoint saver;
|
||||
- telemetria LangGraph;
|
||||
- runtime dos agentes;
|
||||
- verificação estática do workflow;
|
||||
- imports principais.
|
||||
|
||||
Validação local executada:
|
||||
|
||||
```text
|
||||
12 passed
|
||||
```
|
||||
|
||||
## Como testar
|
||||
|
||||
```bash
|
||||
cd projeto_agent_framework_first_ready
|
||||
pip install -r agent_template_backend/requirements.txt
|
||||
pytest -q tests/unit
|
||||
```
|
||||
379
Documentacao/README_FIRST_READY.md
Normal file
379
Documentacao/README_FIRST_READY.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# Projeto Agent Framework FIRST-ready
|
||||
|
||||
Esta versão mantém a arquitetura do `meu_projeto_agent_framework` e adiciona os padrões operacionais encontrados no projeto FIRST.
|
||||
|
||||
## Recursos adicionados
|
||||
|
||||
1. **SSE no padrão FIRST**
|
||||
- `GET /gateway/events/{session_id}` para stream `text/event-stream`.
|
||||
- `POST /gateway/message/sse` para processar mensagem emitindo eventos SSE.
|
||||
- Eventos: `connected`, `flow.start`, `session.upserted`, `message.received`, `workflow.started`, `workflow.completed`, `message.responded`, `flow.end`.
|
||||
- Keepalive configurável por `SSE_KEEPALIVE_SECONDS`.
|
||||
- Lock por sessão para evitar concorrência dentro da mesma conversa.
|
||||
- Replay de eventos via `Last-Event-ID` ou query param `last_event_id`.
|
||||
|
||||
2. **Persistência de sessão e mensagens**
|
||||
- Implementado provider `sqlite`, executável localmente.
|
||||
- `SESSION_REPOSITORY_PROVIDER=sqlite`.
|
||||
- `MEMORY_REPOSITORY_PROVIDER=sqlite`.
|
||||
- Tabelas locais: `agent_sessions`, `agent_messages`.
|
||||
- Idempotência por `message_id`.
|
||||
|
||||
3. **Checkpoint persistente**
|
||||
- Implementado provider `sqlite` para checkpoint final do workflow.
|
||||
- `CHECKPOINT_REPOSITORY_PROVIDER=sqlite`.
|
||||
- Endpoint de leitura: `GET /sessions/{session_id}/checkpoint`.
|
||||
|
||||
4. **Histórico de mensagens**
|
||||
- Endpoint: `GET /sessions/{session_id}/messages`.
|
||||
- Histórico usado como memória conversacional antes de chamar o LangGraph.
|
||||
|
||||
5. **Cache**
|
||||
- Novo módulo `agent_framework.cache.cache`.
|
||||
- Suporta cache local em memória e Redis se `ENABLE_REDIS_CACHE=true`.
|
||||
|
||||
6. **RAG / Vector Store**
|
||||
- `agent_framework.rag.vector_store` agora possui `InMemoryVectorStore`, `SQLiteVectorStore` e contrato `AutonomousVectorStore`.
|
||||
- A versão SQLite usa busca lexical local para desenvolvimento.
|
||||
- O contrato permite trocar por Oracle Vector Search sem alterar a camada de aplicação.
|
||||
|
||||
7. **Observabilidade**
|
||||
- Mantém Langfuse existente.
|
||||
- Acrescenta eventos de gateway/SSE/workflow com `session_id`, `agent_id`, `tenant_id`, `message_id`, rota e intenção.
|
||||
|
||||
## Arquitetura resultante
|
||||
|
||||
```text
|
||||
Browser
|
||||
|-- POST /gateway/message/sse
|
||||
|-- GET /gateway/events/{session_id}
|
||||
|
|
||||
FastAPI Template Backend
|
||||
|
|
||||
ChannelGateway
|
||||
|
|
||||
SessionRepository + MessageHistory + CheckpointRepository
|
||||
|
|
||||
LangGraph AgentWorkflow
|
||||
|
|
||||
Guardrails -> Router/Supervisor -> Agent -> Output Guardrails -> Judges
|
||||
|
|
||||
Telemetry / Langfuse / OCI Streaming
|
||||
```
|
||||
|
||||
## Como rodar localmente
|
||||
|
||||
```bash
|
||||
cd agent_template_backend
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
pip install -e ../agent_framework
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
Frontend:
|
||||
|
||||
```bash
|
||||
cd agent_frontend
|
||||
python -m http.server 3000
|
||||
```
|
||||
|
||||
Abra:
|
||||
|
||||
```text
|
||||
http://localhost:3000
|
||||
```
|
||||
|
||||
## Variáveis principais
|
||||
|
||||
```env
|
||||
SESSION_REPOSITORY_PROVIDER=sqlite
|
||||
MEMORY_REPOSITORY_PROVIDER=sqlite
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
|
||||
VECTOR_STORE_PROVIDER=sqlite
|
||||
SQLITE_DB_PATH=./data/agent_framework.db
|
||||
ENABLE_SSE=true
|
||||
SSE_KEEPALIVE_SECONDS=15
|
||||
ENABLE_MESSAGE_IDEMPOTENCY=true
|
||||
```
|
||||
|
||||
## Teste via curl
|
||||
|
||||
Mensagem normal:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"text":"teste","message":"teste","session_id":"s1","user_id":"u1","message_id":"m1"}}'
|
||||
```
|
||||
|
||||
Mensagem com SSE:
|
||||
|
||||
```bash
|
||||
curl -N http://localhost:8000/gateway/events/s1
|
||||
```
|
||||
|
||||
Em outro terminal:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message/sse \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"text":"teste","message":"teste","session_id":"s1","user_id":"u1","message_id":"m2"}}'
|
||||
```
|
||||
|
||||
Histórico:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/sessions/s1/messages
|
||||
```
|
||||
|
||||
Checkpoint:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/sessions/s1/checkpoint
|
||||
```
|
||||
|
||||
## Observação importante
|
||||
|
||||
A versão adicionada é executável localmente com SQLite. As classes `AutonomousSessionRepository`, `DatabaseMessageHistory`, `AutonomousCheckpointRepository` e `AutonomousVectorStore` mantêm o contrato para Oracle Autonomous Database, mas nesta entrega usam SQLite como backend local para permitir rodar e testar sem infraestrutura Oracle.
|
||||
|
||||
## Evolução de Observabilidade no padrão FIRST
|
||||
|
||||
Esta versão adiciona uma camada corporativa de observabilidade ao framework, mantendo os componentes reutilizáveis dentro de `agent_framework`.
|
||||
|
||||
### Componentes adicionados
|
||||
|
||||
```text
|
||||
agent_framework/observability/
|
||||
├── context.py # ContextVar: request_id, session_id, user_id, tenant_id, agent_id, channel, ura_call_id, workflow_id, message_id
|
||||
├── telemetry.py # Facade central: span, event, generation, rag_event, cache_event, checkpoint_event
|
||||
├── event_bus.py # Event bus interno para plugar logs, SSE, OCI Streaming, Elastic, Phoenix etc.
|
||||
├── otel.py # OpenTelemetry opcional via OTLP
|
||||
├── workflow_events.py # workflow.started, node.started, node.completed, edge.selected, workflow.failed
|
||||
├── guardrail_events.py # guardrail.<CODE>.evaluated e guardrail.<CODE>.blocked
|
||||
├── judge_events.py # judge.<NAME>.evaluated
|
||||
├── streaming_events.py # sse.connected, sse.keepalive, sse.event.emitted
|
||||
└── decorators.py # decorator @traced para classes do framework
|
||||
```
|
||||
|
||||
### Correlação ponta-a-ponta
|
||||
|
||||
Cada chamada HTTP cria ou propaga `x-request-id` e o fluxo de mensagem vincula:
|
||||
|
||||
```text
|
||||
request_id → tenant_id → agent_id → session_id → user_id → channel → message_id → workflow_id
|
||||
```
|
||||
|
||||
O contexto usa `ContextVar`, portanto funciona em chamadas assíncronas, FastAPI, LangGraph e providers LLM.
|
||||
|
||||
### Langfuse
|
||||
|
||||
Ative no `.env`:
|
||||
|
||||
```env
|
||||
ENABLE_LANGFUSE=true
|
||||
LANGFUSE_PUBLIC_KEY=pk-lf-...
|
||||
LANGFUSE_SECRET_KEY=sk-lf-...
|
||||
LANGFUSE_HOST=http://localhost:3000
|
||||
```
|
||||
|
||||
O framework registra:
|
||||
|
||||
```text
|
||||
Trace de conversa
|
||||
├── http.request
|
||||
├── agent.gateway_message
|
||||
├── workflow.langgraph.ainvoke
|
||||
├── workflow.input_guardrails
|
||||
│ └── guardrail.<CODE>.evaluated / blocked
|
||||
├── workflow.routing_decision
|
||||
├── workflow.agent.<agent>
|
||||
│ └── generation.<model>
|
||||
├── workflow.output_guardrails
|
||||
├── workflow.judge
|
||||
│ └── judge.<NAME>.evaluated
|
||||
├── workflow.supervisor_review
|
||||
├── workflow.persist
|
||||
└── sse.event.emitted / sse.keepalive
|
||||
```
|
||||
|
||||
### OpenTelemetry
|
||||
|
||||
Ative no `.env`:
|
||||
|
||||
```env
|
||||
ENABLE_OTEL=true
|
||||
OTEL_SERVICE_NAME=agent-framework-template
|
||||
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
|
||||
```
|
||||
|
||||
Com isso, os mesmos spans são exportados via OTLP para Elastic, Grafana Tempo, Jaeger, Collector ou outro backend compatível.
|
||||
|
||||
### SSE observável
|
||||
|
||||
O `SSEHub` agora registra eventos de:
|
||||
|
||||
- conexão aberta;
|
||||
- replay de eventos;
|
||||
- evento emitido;
|
||||
- keepalive;
|
||||
- lock por sessão no processamento de mensagem.
|
||||
|
||||
### Guardrails e Judges
|
||||
|
||||
Além dos eventos agregados (`guardrails.input.completed`, `judges.completed`), cada decisão individual gera telemetria própria:
|
||||
|
||||
```text
|
||||
guardrail.MSK.evaluated
|
||||
guardrail.OOS.blocked
|
||||
judge.response_quality.evaluated
|
||||
judge.groundedness.evaluated
|
||||
```
|
||||
|
||||
### Extensão para outros backends
|
||||
|
||||
A classe `Telemetry.event_bus` permite plugar novos handlers sem alterar o workflow. Exemplo:
|
||||
|
||||
```python
|
||||
async def enviar_para_elastic(event):
|
||||
...
|
||||
|
||||
telemetry.event_bus.subscribe(enviar_para_elastic)
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Evolução FIRST Enterprise Completa
|
||||
|
||||
Esta versão recebeu os componentes que faltavam para aproximar o framework do padrão operacional do projeto FIRST:
|
||||
|
||||
### Persistência Oracle Autonomous Database
|
||||
|
||||
Foram adicionados providers reais Oracle:
|
||||
|
||||
- `OracleSessionRepository`
|
||||
- `OracleMessageHistory`
|
||||
- `OracleCheckpointRepository`
|
||||
- `OracleCache`
|
||||
- `OracleVectorStore`
|
||||
- `OracleGraphStore`
|
||||
- `OracleStore`
|
||||
|
||||
Tabelas criadas automaticamente com prefixo configurável `ADB_TABLE_PREFIX`:
|
||||
|
||||
- `<PREFIX>_AGENT_SESSION`
|
||||
- `<PREFIX>_AGENT_MESSAGE`
|
||||
- `<PREFIX>_WORKFLOW_CHECKPOINT`
|
||||
- `<PREFIX>_WORKFLOW_CHECKPOINT_WRITE`
|
||||
- `<PREFIX>_WORKFLOW_CHECKPOINT_BLOB`
|
||||
- `<PREFIX>_SSE_EVENT`
|
||||
- `<PREFIX>_CACHE_ENTRY`
|
||||
- `<PREFIX>_RAG_DOCUMENT`
|
||||
- `<PREFIX>_GRAPH_EDGE`
|
||||
|
||||
### Configuração Oracle
|
||||
|
||||
```env
|
||||
SESSION_REPOSITORY_PROVIDER=oracle
|
||||
MEMORY_REPOSITORY_PROVIDER=oracle
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=oracle
|
||||
CACHE_BACKEND_PROVIDER=oracle
|
||||
VECTOR_STORE_PROVIDER=oracle
|
||||
GRAPH_STORE_PROVIDER=oracle
|
||||
SSE_STORE_PROVIDER=oracle
|
||||
|
||||
ADB_USER=ADMIN
|
||||
ADB_PASSWORD=***
|
||||
ADB_DSN=meu_adb_high
|
||||
ADB_WALLET_LOCATION=/path/wallet
|
||||
ADB_WALLET_PASSWORD=***
|
||||
ADB_TABLE_PREFIX=AGENTFW
|
||||
```
|
||||
|
||||
### SSE Enterprise
|
||||
|
||||
O SSE agora possui:
|
||||
|
||||
- lock por sessão (`SessionLockManager`)
|
||||
- keepalive configurável
|
||||
- replay por `Last-Event-ID`
|
||||
- persistência de eventos em SQLite ou Oracle
|
||||
- telemetria de conexão, replay, keepalive e desconexão
|
||||
|
||||
Endpoint:
|
||||
|
||||
```text
|
||||
GET /gateway/events/{session_id}?last_event_id=123
|
||||
```
|
||||
|
||||
### LangGraph Deep Telemetry
|
||||
|
||||
Foi adicionado `LangGraphDeepTelemetry` com eventos:
|
||||
|
||||
- `langgraph.node.started`
|
||||
- `langgraph.node.completed`
|
||||
- `langgraph.node.failed`
|
||||
- `langgraph.edge.selected`
|
||||
|
||||
Esses eventos são enviados para o Event Bus, Langfuse e OpenTelemetry quando habilitados.
|
||||
|
||||
### Token e Cost Accounting
|
||||
|
||||
Foi adicionado:
|
||||
|
||||
- `TokenUsageCollector`
|
||||
- `CostTracker`
|
||||
- cálculo de `prompt_tokens`, `completion_tokens`, `cached_tokens`, `total_tokens`
|
||||
- cálculo de `cost_usd` e `cost_brl`
|
||||
|
||||
Configuração opcional:
|
||||
|
||||
```env
|
||||
USD_BRL_RATE=5.0
|
||||
MODEL_PRICES_JSON={"openai.gpt-4.1":{"input_per_1m":"2.00","output_per_1m":"8.00"}}
|
||||
```
|
||||
|
||||
### Cache Enterprise
|
||||
|
||||
O cache agora é em cascata:
|
||||
|
||||
```text
|
||||
L1: InMemory
|
||||
L2: Redis, SQLite ou Oracle
|
||||
```
|
||||
|
||||
Configuração:
|
||||
|
||||
```env
|
||||
ENABLE_REDIS_CACHE=true
|
||||
REDIS_URL=redis://localhost:6379/0
|
||||
```
|
||||
|
||||
ou:
|
||||
|
||||
```env
|
||||
CACHE_BACKEND_PROVIDER=oracle
|
||||
```
|
||||
|
||||
### RAG Oracle 23ai
|
||||
|
||||
Foi adicionado `OracleVectorStore`, com suporte a coluna `VECTOR` e `VECTOR_DISTANCE()` quando um embedding provider for conectado.
|
||||
Sem embedding provider, mantém fallback lexical para desenvolvimento local.
|
||||
|
||||
Também foi adicionado `OracleGraphStore` com tabela de arestas, pronto para evoluir para PGQL/Property Graph.
|
||||
|
||||
### Langfuse
|
||||
|
||||
Cada chamada LLM agora gera `generation` com:
|
||||
|
||||
- input
|
||||
- output
|
||||
- model
|
||||
- provider
|
||||
- token usage
|
||||
- cost metadata
|
||||
|
||||
Além disso, spans de workflow, guardrails, judges, RAG, cache, checkpoint, SSE e LangGraph são publicados pelo mesmo Event Bus.
|
||||
|
||||
62
Documentacao/README_GUARDRAILS_IMPLEMENTADOS.md
Normal file
62
Documentacao/README_GUARDRAILS_IMPLEMENTADOS.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Guardrails implementados no framework
|
||||
|
||||
Esta versão adiciona uma camada pragmática de guardrails ao `agent_framework`, inspirada na separação de rails por estágio: input, output, retrieval e execução/tool.
|
||||
|
||||
## Rails de input
|
||||
|
||||
- `MSIZE` — bloqueia mensagens excessivamente grandes.
|
||||
- `MSK` — mascara CPF, CNPJ, telefone, e-mail, cartão, CEP, RG, tokens e chaves.
|
||||
- `TOX` — detecta toxicidade e registra severidade sem bloquear por padrão.
|
||||
- `PINJ` — detecta prompt injection e registra score.
|
||||
- `JBRK` — detecta jailbreak/roleplay de burla e registra score.
|
||||
- `VLOOP` — bloqueia loop conversacional repetitivo.
|
||||
|
||||
## Rails de output
|
||||
|
||||
- `PII_OUT` — mascara PII na resposta do agente.
|
||||
- `CMP` — suaviza promessas absolutas e linguagem de garantia excessiva.
|
||||
- `REVPREC` — bloqueia verbalização de ação operacional sem confirmação de tool.
|
||||
- `GND` — sinaliza groundedness/risco quando há resposta específica sem evidência.
|
||||
- `ALUC_RISK` — marca risco de alucinação para telemetria e judges.
|
||||
|
||||
## Rails opcionais
|
||||
|
||||
- `RET_REL` — valida relevância de chunks de retrieval por score mínimo.
|
||||
- `TOOL_VAL` — valida ferramenta MCP/tool, argumentos obrigatórios, valores negativos e allowlist.
|
||||
|
||||
## Arquivos alterados
|
||||
|
||||
- `agent_framework/src/agent_framework/guardrails/rails.py`
|
||||
- `agent_framework/src/agent_framework/guardrails/pipeline.py`
|
||||
- `agent_framework/src/agent_framework/guardrails/__init__.py`
|
||||
|
||||
## Uso rápido
|
||||
|
||||
```python
|
||||
from agent_framework.guardrails.pipeline import GuardrailPipeline
|
||||
|
||||
pipeline = GuardrailPipeline()
|
||||
|
||||
sanitized_input, input_decisions = await pipeline.run_input(
|
||||
user_text,
|
||||
{"history_texts": history_texts},
|
||||
)
|
||||
|
||||
final_answer, output_decisions = await pipeline.run_output(
|
||||
answer,
|
||||
context,
|
||||
)
|
||||
```
|
||||
|
||||
Para tools/MCP:
|
||||
|
||||
```python
|
||||
_, decisions = await pipeline.run_tool(
|
||||
"cancelar_produto",
|
||||
{"produto": "VAS", "valor": 0},
|
||||
{
|
||||
"required_args": ["produto"],
|
||||
"allowed_tools": ["cancelar_produto", "consultar_fatura"],
|
||||
},
|
||||
)
|
||||
```
|
||||
139
Documentacao/README_MAX_OPERACIONAL.md
Normal file
139
Documentacao/README_MAX_OPERACIONAL.md
Normal file
@@ -0,0 +1,139 @@
|
||||
# Projeto Agent Framework — FIRST Operational Max
|
||||
|
||||
Esta versão adiciona os ajustes operacionais que faltavam para aproximar o framework do padrão FIRST em produção.
|
||||
|
||||
## Ajustes incluídos nesta versão
|
||||
|
||||
### 1. Langfuse Enterprise Adapter
|
||||
Novo módulo:
|
||||
|
||||
```text
|
||||
agent_framework/observability/langfuse_enterprise.py
|
||||
```
|
||||
|
||||
Inclui adaptador compatível com SDKs Langfuse v2/v3 para:
|
||||
|
||||
- atualização de trace;
|
||||
- score/avaliação de trace;
|
||||
- prompt registry quando suportado pelo SDK;
|
||||
- isolamento das diferenças de API do Langfuse.
|
||||
|
||||
### 2. Token e Cost Accounting persistente
|
||||
Novo pacote:
|
||||
|
||||
```text
|
||||
agent_framework/billing/
|
||||
```
|
||||
|
||||
Inclui:
|
||||
|
||||
- `UsageRecord`
|
||||
- `SQLiteUsageRepository`
|
||||
- `OracleUsageRepository`
|
||||
- `create_usage_repository(settings)`
|
||||
|
||||
O provider LLM agora registra automaticamente:
|
||||
|
||||
- `prompt_tokens`
|
||||
- `completion_tokens`
|
||||
- `cached_tokens`
|
||||
- `total_tokens`
|
||||
- `cost_usd`
|
||||
- `cost_brl`
|
||||
- `tenant_id`
|
||||
- `agent_id`
|
||||
- `session_id`
|
||||
- `message_id`
|
||||
|
||||
Novo endpoint:
|
||||
|
||||
```http
|
||||
GET /debug/usage
|
||||
GET /debug/usage?tenant_id=default
|
||||
GET /debug/usage?session_id=<id>
|
||||
```
|
||||
|
||||
### 3. RAG Service operacional
|
||||
Novo módulo:
|
||||
|
||||
```text
|
||||
agent_framework/rag/rag_service.py
|
||||
```
|
||||
|
||||
Inclui:
|
||||
|
||||
- `RagService.add_documents()`
|
||||
- `RagService.retrieve()`
|
||||
- `RagResult.as_prompt_context()`
|
||||
- telemetria de latência, quantidade de documentos, top scores e grafo.
|
||||
|
||||
### 4. Configuração nova
|
||||
Variável adicionada:
|
||||
|
||||
```env
|
||||
USAGE_REPOSITORY_PROVIDER=sqlite
|
||||
```
|
||||
|
||||
Valores:
|
||||
|
||||
```text
|
||||
sqlite
|
||||
oracle
|
||||
autonomous
|
||||
```
|
||||
|
||||
### 5. Compatibilidade operacional local
|
||||
Por padrão, a contabilização de uso usa SQLite mesmo que o restante esteja em memória. Assim é possível testar localmente sem Oracle.
|
||||
|
||||
## Teste rápido
|
||||
|
||||
```bash
|
||||
cd agent_template_backend
|
||||
uvicorn app.main:app --host 0.0.0.0 --port 8000
|
||||
```
|
||||
|
||||
Teste uma mensagem:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"text":"teste","user_id":"u1","session_id":"s1"}}'
|
||||
```
|
||||
|
||||
Verifique uso/custo:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/debug/usage
|
||||
```
|
||||
|
||||
## Para rodar com padrão mais próximo de produção
|
||||
|
||||
```env
|
||||
SESSION_REPOSITORY_PROVIDER=sqlite
|
||||
MEMORY_REPOSITORY_PROVIDER=sqlite
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=sqlite
|
||||
USAGE_REPOSITORY_PROVIDER=sqlite
|
||||
CACHE_BACKEND_PROVIDER=sqlite
|
||||
VECTOR_STORE_PROVIDER=sqlite
|
||||
ENABLE_LANGFUSE=true
|
||||
LANGFUSE_HOST=http://localhost:3000
|
||||
LANGFUSE_PUBLIC_KEY=...
|
||||
LANGFUSE_SECRET_KEY=...
|
||||
```
|
||||
|
||||
Para Autonomous Database:
|
||||
|
||||
```env
|
||||
SESSION_REPOSITORY_PROVIDER=oracle
|
||||
MEMORY_REPOSITORY_PROVIDER=oracle
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=oracle
|
||||
USAGE_REPOSITORY_PROVIDER=oracle
|
||||
CACHE_BACKEND_PROVIDER=oracle
|
||||
VECTOR_STORE_PROVIDER=oracle
|
||||
GRAPH_STORE_PROVIDER=oracle
|
||||
ADB_USER=...
|
||||
ADB_PASSWORD=...
|
||||
ADB_DSN=...
|
||||
ADB_WALLET_LOCATION=...
|
||||
ADB_TABLE_PREFIX=AGENTFW
|
||||
```
|
||||
75
Documentacao/README_MCP.md
Normal file
75
Documentacao/README_MCP.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# AI Agent Platform com MCP Tools
|
||||
|
||||
Esta versão adiciona uma camada MCP ao framework:
|
||||
|
||||
- `agent_framework.mcp.MCPToolRouter`
|
||||
- `agent_template_backend/config/mcp_servers.yaml`
|
||||
- `agent_template_backend/config/tools.yaml`
|
||||
- `mcp_servers/telecom_mcp_server`
|
||||
- `mcp_servers/retail_mcp_server`
|
||||
|
||||
## Subir localmente
|
||||
|
||||
Terminal 1:
|
||||
|
||||
```bash
|
||||
bash ./scripts/run_mcp_servers.sh
|
||||
```
|
||||
|
||||
Terminal 2:
|
||||
|
||||
```bash
|
||||
cd agent_template_backend
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -e ../agent_framework
|
||||
pip install -r requirements.txt
|
||||
uvicorn app.main:app --reload --reload-dir app --reload-dir config --port 8000
|
||||
```
|
||||
|
||||
Terminal 3:
|
||||
|
||||
```bash
|
||||
cd agent_frontend
|
||||
python -m http.server 5173
|
||||
```
|
||||
|
||||
## Testes rápidos
|
||||
|
||||
Listar tools MCP carregadas pelo backend:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/debug/mcp/tools
|
||||
```
|
||||
|
||||
Chamar tool diretamente via backend:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/debug/mcp/call/consultar_fatura \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"msisdn":"11999999999","invoice_id":"INV-001"}'
|
||||
```
|
||||
|
||||
Roteamento Telecom + MCP:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"session_id":"sess-tel-1","message":"Minha fatura veio alta","context":{"msisdn":"11999999999","invoice_id":"INV-001"}}}'
|
||||
```
|
||||
|
||||
Roteamento Retail + MCP:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"session_id":"sess-ret-1","message":"Meu pedido não chegou","context":{"order_id":"PED-1001","customer_id":"C-001"}}}'
|
||||
```
|
||||
|
||||
## Docker Compose
|
||||
|
||||
```bash
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
No compose, o backend usa `config/mcp_servers.docker.yaml` para apontar para `telecom-mcp` e `retail-mcp`.
|
||||
108
Documentacao/README_MULTI_AGENT_ISOLATION.md
Normal file
108
Documentacao/README_MULTI_AGENT_ISOLATION.md
Normal file
@@ -0,0 +1,108 @@
|
||||
# Multi-agent isolation
|
||||
|
||||
Esta versão permite subir mais de um `agent_template` no mesmo backend e chavear por `agent_id` sem misturar estado.
|
||||
|
||||
## O que ficou isolado
|
||||
|
||||
A chave lógica usada pelo backend é:
|
||||
|
||||
```text
|
||||
tenant_id:agent_id:session_id
|
||||
```
|
||||
|
||||
Com isso ficam isolados:
|
||||
|
||||
- memória conversacional;
|
||||
- checkpoints do LangGraph (`thread_id`);
|
||||
- telemetria/tags;
|
||||
- prompts por perfil de agente;
|
||||
- configuração de guardrails por agente;
|
||||
- configuração de judges por agente;
|
||||
- metadados de sessão.
|
||||
|
||||
## Arquivo principal
|
||||
|
||||
```text
|
||||
agent_template_backend/config/agents.yaml
|
||||
```
|
||||
|
||||
Exemplo:
|
||||
|
||||
```yaml
|
||||
default_agent_id: telecom_contas
|
||||
agents:
|
||||
- agent_id: telecom_contas
|
||||
prompt_policy_path: ./config/agents/telecom_contas/prompt_policy.yaml
|
||||
guardrails_config_path: ./config/agents/telecom_contas/guardrails.yaml
|
||||
judges_config_path: ./config/agents/telecom_contas/judges.yaml
|
||||
|
||||
- agent_id: retail_orders
|
||||
prompt_policy_path: ./config/agents/retail_orders/prompt_policy.yaml
|
||||
guardrails_config_path: ./config/agents/retail_orders/guardrails.yaml
|
||||
judges_config_path: ./config/agents/retail_orders/judges.yaml
|
||||
```
|
||||
|
||||
## Como escolher o agente na chamada
|
||||
|
||||
### Telecom
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"channel": "web",
|
||||
"agent_id": "telecom_contas",
|
||||
"tenant_id": "tim",
|
||||
"payload": {
|
||||
"session_id": "sessao-123",
|
||||
"user_id": "cliente-1",
|
||||
"message": "Quero entender minha fatura",
|
||||
"context": {"invoice_id": "FAT-001"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Retail
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/gateway/message \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"channel": "web",
|
||||
"agent_id": "retail_orders",
|
||||
"tenant_id": "loja",
|
||||
"payload": {
|
||||
"session_id": "sessao-123",
|
||||
"user_id": "cliente-1",
|
||||
"message": "Onde está meu pedido?",
|
||||
"context": {"order_id": "PED-001"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Mesmo usando o mesmo `session_id`, as conversas ficam separadas porque as chaves finais serão:
|
||||
|
||||
```text
|
||||
tim:telecom_contas:sessao-123
|
||||
loja:retail_orders:sessao-123
|
||||
```
|
||||
|
||||
## Endpoints úteis
|
||||
|
||||
```text
|
||||
GET /agents
|
||||
GET /health
|
||||
POST /debug/route
|
||||
POST /gateway/message
|
||||
```
|
||||
|
||||
## Como adicionar um novo agent_template
|
||||
|
||||
1. Crie uma pasta em `agent_template_backend/config/agents/<novo_agent_id>/`.
|
||||
2. Adicione `prompt_policy.yaml`, `guardrails.yaml` e `judges.yaml`.
|
||||
3. Registre o agente em `config/agents.yaml`.
|
||||
4. Chame `/gateway/message` usando `agent_id=<novo_agent_id>`.
|
||||
|
||||
## Observação arquitetural
|
||||
|
||||
O backend continua usando um único processo FastAPI e um único framework instalado, mas o estado persistido não usa mais `session_id` sozinho. Isso evita que dois agentes compartilhem memória, checkpoints ou decisões de governança acidentalmente.
|
||||
281
Documentacao/README_ROUTING_MODES.md
Normal file
281
Documentacao/README_ROUTING_MODES.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# Modos de roteamento multi-agent: Enterprise Router e Supervisor
|
||||
|
||||
Este projeto suporta dois desenhos arquiteturais para roteamento entre agentes, sem precisar criar dois frameworks diferentes.
|
||||
|
||||
## Modos disponíveis
|
||||
|
||||
Configure por variável de ambiente:
|
||||
|
||||
```bash
|
||||
ROUTING_MODE=router
|
||||
```
|
||||
|
||||
ou:
|
||||
|
||||
```bash
|
||||
ROUTING_MODE=supervisor
|
||||
```
|
||||
|
||||
Também existe a chave documental em `agent_template_backend/config/routing.yaml`:
|
||||
|
||||
```yaml
|
||||
router:
|
||||
mode: router
|
||||
```
|
||||
|
||||
A variável de ambiente `ROUTING_MODE` é a forma recomendada para ativar um modo em runtime, especialmente em Docker, Kubernetes ou OCI.
|
||||
|
||||
---
|
||||
|
||||
## Opção 1: Enterprise Router
|
||||
|
||||
Fluxo:
|
||||
|
||||
```text
|
||||
Usuário
|
||||
-> Input Guardrails
|
||||
-> EnterpriseRouter
|
||||
-> AgentRegistry
|
||||
-> 1 agente especialista
|
||||
-> Output Guardrails
|
||||
-> Judges
|
||||
-> Supervisor Review
|
||||
-> Persistência/eventos
|
||||
```
|
||||
|
||||
Uso recomendado quando cada mensagem deve ser atendida por um único agente especialista.
|
||||
|
||||
Exemplos:
|
||||
|
||||
- `Minha fatura veio alta` -> `billing_agent`
|
||||
- `Onde está meu pedido?` -> `orders_agent`
|
||||
- `Quero trocar um produto com defeito` -> `support_agent`
|
||||
|
||||
Vantagens:
|
||||
|
||||
- Menor latência.
|
||||
- Menor custo de tokens.
|
||||
- Debug mais simples.
|
||||
- Mais fácil de operar em produção.
|
||||
|
||||
Limitação:
|
||||
|
||||
- Uma mensagem com múltiplos assuntos precisa ser roteada para um agente principal ou tratada por handoff.
|
||||
|
||||
---
|
||||
|
||||
## Opção 2: Supervisor
|
||||
|
||||
Fluxo:
|
||||
|
||||
```text
|
||||
Usuário
|
||||
-> Input Guardrails
|
||||
-> Supervisor.route_plan
|
||||
-> supervisor_agent
|
||||
-> billing_agent opcional
|
||||
-> orders_agent opcional
|
||||
-> product_agent opcional
|
||||
-> support_agent opcional
|
||||
-> Consolidação
|
||||
-> Output Guardrails
|
||||
-> Judges
|
||||
-> Supervisor Review
|
||||
-> Persistência/eventos
|
||||
```
|
||||
|
||||
Uso recomendado quando uma única mensagem pode envolver vários agentes.
|
||||
|
||||
Exemplo:
|
||||
|
||||
```text
|
||||
Meu pedido não chegou e também fui cobrado duas vezes.
|
||||
```
|
||||
|
||||
Neste caso, o supervisor pode acionar:
|
||||
|
||||
- `orders_agent`
|
||||
- `billing_agent`
|
||||
|
||||
Vantagens:
|
||||
|
||||
- Suporta múltiplas intenções na mesma mensagem.
|
||||
- Permite consolidação de respostas.
|
||||
- Facilita cenários enterprise com vários domínios.
|
||||
|
||||
Custos:
|
||||
|
||||
- Maior latência.
|
||||
- Maior consumo de tokens.
|
||||
- Mais complexidade operacional.
|
||||
|
||||
---
|
||||
|
||||
## O que foi alterado no código
|
||||
|
||||
### 1. Configuração
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
agent_framework/src/agent_framework/config/settings.py
|
||||
```
|
||||
|
||||
Foi adicionada a configuração:
|
||||
|
||||
```python
|
||||
ROUTING_MODE: Literal['router','supervisor'] = 'router'
|
||||
```
|
||||
|
||||
### 2. Workflow LangGraph
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
agent_template_backend/app/workflows/agent_graph.py
|
||||
```
|
||||
|
||||
O nó `enterprise_route` foi substituído por um nó genérico:
|
||||
|
||||
```text
|
||||
routing_decision
|
||||
```
|
||||
|
||||
Esse nó decide o caminho com base em `ROUTING_MODE`:
|
||||
|
||||
- `router` usa `EnterpriseRouter`.
|
||||
- `supervisor` usa `Supervisor.route_plan`.
|
||||
|
||||
Também foi adicionado o nó:
|
||||
|
||||
```text
|
||||
supervisor_agent
|
||||
```
|
||||
|
||||
Ele executa um ou mais agentes e consolida o resultado.
|
||||
|
||||
### 3. Supervisor
|
||||
|
||||
Arquivo:
|
||||
|
||||
```text
|
||||
agent_framework/src/agent_framework/supervisor/supervisor.py
|
||||
```
|
||||
|
||||
Foi adicionada a estrutura:
|
||||
|
||||
```python
|
||||
SupervisorPlan
|
||||
```
|
||||
|
||||
E o método:
|
||||
|
||||
```python
|
||||
route_plan(state)
|
||||
```
|
||||
|
||||
Esse método retorna uma lista de agentes a executar.
|
||||
|
||||
### 4. Debug
|
||||
|
||||
Endpoint:
|
||||
|
||||
```text
|
||||
POST /debug/route
|
||||
```
|
||||
|
||||
Agora respeita `ROUTING_MODE` e permite verificar rapidamente como uma mensagem será roteada.
|
||||
|
||||
---
|
||||
|
||||
## Como testar localmente
|
||||
|
||||
### Instalação
|
||||
|
||||
```bash
|
||||
cd agent_template_backend
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -U pip setuptools wheel
|
||||
pip install -e ../agent_framework
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Modo Router
|
||||
|
||||
```bash
|
||||
export ROUTING_MODE=router
|
||||
uvicorn app.main:app --reload --port 8000
|
||||
```
|
||||
|
||||
Teste:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/debug/route \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"text":"Onde está meu pedido?","session_id":"s1"}}'
|
||||
```
|
||||
|
||||
Resultado esperado:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "router",
|
||||
"route": "orders_agent"
|
||||
}
|
||||
```
|
||||
|
||||
### Modo Supervisor
|
||||
|
||||
```bash
|
||||
export ROUTING_MODE=supervisor
|
||||
uvicorn app.main:app --reload --port 8000
|
||||
```
|
||||
|
||||
Teste:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8000/debug/route \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"channel":"web","payload":{"text":"Meu pedido atrasou e minha fatura veio duplicada","session_id":"s2"}}'
|
||||
```
|
||||
|
||||
Resultado esperado:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "supervisor",
|
||||
"route": "supervisor_agent",
|
||||
"agents": ["billing_agent", "orders_agent"]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Isolamento
|
||||
|
||||
A chave lógica de isolamento permanece:
|
||||
|
||||
```text
|
||||
tenant_id:agent_id:session_id
|
||||
```
|
||||
|
||||
Use essa chave para memória, sessão, checkpoint e telemetria. Em produção, recomenda-se padronizar `agent_id` por agente especialista ou por template, dependendo do nível de isolamento desejado.
|
||||
|
||||
---
|
||||
|
||||
## Recomendação
|
||||
|
||||
Comece em produção com:
|
||||
|
||||
```bash
|
||||
ROUTING_MODE=router
|
||||
```
|
||||
|
||||
Ative:
|
||||
|
||||
```bash
|
||||
ROUTING_MODE=supervisor
|
||||
```
|
||||
|
||||
quando houver necessidade real de múltiplos agentes na mesma mensagem.
|
||||
86
Documentacao/README_TEMPLATE_BUSINESS_CONTEXT_V2.md
Normal file
86
Documentacao/README_TEMPLATE_BUSINESS_CONTEXT_V2.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Template Backend/Frontend alinhado ao BusinessContext v2
|
||||
|
||||
Este pacote atualiza o `agent_template_backend` e o `agent_frontend` para refletir o framework novo, onde as chaves vindas do canal/front-end são resolvidas uma vez como chaves canônicas e propagadas pelas camadas até o MCP Server.
|
||||
|
||||
## Fluxo implementado
|
||||
|
||||
1. O front-end envia `tenant_id`, `agent_id`, `session_id` e `business_context`.
|
||||
2. O backend normaliza a mensagem via `ChannelGateway` preservando todo o payload no `context`.
|
||||
3. O backend usa `IdentityResolver` com `config/identity.yaml` para gerar `BusinessContext`:
|
||||
- `customer_key`
|
||||
- `contract_key`
|
||||
- `interaction_key`
|
||||
- `account_key`
|
||||
- `resource_key`
|
||||
- `session_key`
|
||||
4. O workflow recebe `context.business_context`.
|
||||
5. Os agentes de exemplo não montam mais argumentos específicos como `msisdn`, `invoice_id` ou `order_id` diretamente.
|
||||
6. O `MCPToolRouter` usa `config/mcp_parameter_mapping.yaml` para converter chaves canônicas em parâmetros reais de cada tool MCP.
|
||||
|
||||
## Arquivos principais ajustados
|
||||
|
||||
- `agent_template_backend/app/main.py`
|
||||
- carrega `IdentityResolver`;
|
||||
- resolve `BusinessContext` por mensagem;
|
||||
- persiste as chaves na sessão/memória/metadata/SSE;
|
||||
- adiciona `/debug/identity`.
|
||||
|
||||
- `agent_template_backend/app/agents/runtime.py`
|
||||
- adiciona `_collect_mcp_context()` centralizado;
|
||||
- repassa `business_context` e `original_context` para o MCP Router.
|
||||
|
||||
- `agent_template_backend/app/agents/*_agent.py`
|
||||
- agentes passam a usar `_collect_mcp_context()` em vez de montar argumentos específicos.
|
||||
|
||||
- `agent_template_backend/config/identity.yaml`
|
||||
- define como campos do canal/front-end alimentam as chaves canônicas.
|
||||
|
||||
- `agent_template_backend/config/mcp_parameter_mapping.yaml`
|
||||
- define como chaves canônicas viram parâmetros reais por tool MCP.
|
||||
|
||||
- `agent_frontend/index.html` e `agent_frontend/app.js`
|
||||
- adicionam campos de `tenant`, `agent` e chaves canônicas;
|
||||
- enviam `business_context` no payload;
|
||||
- mantêm aliases de domínio para compatibilidade (`msisdn`, `invoice_id`, `order_id`, etc.).
|
||||
|
||||
## Teste rápido
|
||||
|
||||
Suba backend, frontend e MCP servers. Depois teste:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:8000/health | jq
|
||||
|
||||
curl -s -X POST http://localhost:8000/debug/identity \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"channel":"web",
|
||||
"tenant_id":"default",
|
||||
"agent_id":"telecom_contas",
|
||||
"payload":{
|
||||
"message":"Minha fatura veio alta",
|
||||
"session_id":"teste-001",
|
||||
"msisdn":"11999999999",
|
||||
"invoice_id":"3000131180",
|
||||
"ura_call_id":"URA-123",
|
||||
"business_context":{
|
||||
"customer_key":"11999999999",
|
||||
"contract_key":"3000131180",
|
||||
"interaction_key":"URA-123",
|
||||
"session_key":"teste-001"
|
||||
}
|
||||
}
|
||||
}' | jq
|
||||
|
||||
curl -s -X POST http://localhost:8000/debug/mcp/call/consultar_fatura \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"business_context": {
|
||||
"customer_key":"11999999999",
|
||||
"contract_key":"3000131180",
|
||||
"interaction_key":"URA-123",
|
||||
"session_key":"teste-001"
|
||||
}
|
||||
}' | jq
|
||||
```
|
||||
|
||||
No log do backend, procure por `mcp.tool.mapped`. Ele deve indicar as chaves mapeadas e `has_msisdn=true`, `has_invoice_id=true` para o domínio telecom.
|
||||
28
Documentacao/README_TESTES_UNITARIOS.md
Normal file
28
Documentacao/README_TESTES_UNITARIOS.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Testes unitários do framework
|
||||
|
||||
Esta versão inclui uma pasta `tests/unit` cobrindo os componentes principais:
|
||||
|
||||
- cache local e distribuído;
|
||||
- SSE com encode, persistência e replay;
|
||||
- RAG com busca vetorial em memória;
|
||||
- checkpoint saver compatível com LangGraph;
|
||||
- telemetria profunda de LangGraph;
|
||||
- runtime dos agentes com cache/RAG;
|
||||
- verificação estática do workflow para garantir que não usa mais `MemorySaver()` diretamente.
|
||||
|
||||
## Como executar
|
||||
|
||||
```bash
|
||||
cd projeto_agent_framework_first_ready
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r agent_template_backend/requirements.txt
|
||||
pip install pytest pytest-asyncio
|
||||
pytest -q
|
||||
```
|
||||
|
||||
Para rodar apenas os testes unitários:
|
||||
|
||||
```bash
|
||||
pytest -q tests/unit
|
||||
```
|
||||
113
Documentacao/README_old.md
Normal file
113
Documentacao/README_old.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# AI Agent Platform — LangGraph + OCI
|
||||
|
||||
Monorepo com três projetos independentes:
|
||||
|
||||
- `agent_framework/`: biblioteca reutilizável para agentes escaláveis.
|
||||
- `agent_template_backend/`: backend FastAPI usando o framework, com dois agentes, roteador, máquina de estados, sessão persistente e gateway de canais.
|
||||
- `agent_frontend/`: frontend web simples e independente para conversar com o backend via gateway HTTP.
|
||||
|
||||
## Visão de arquitetura
|
||||
|
||||
```text
|
||||
Frontend Web / WhatsApp / Voz / Texto
|
||||
↓
|
||||
Channel Gateway + Adapters
|
||||
↓
|
||||
SessionRepository persistente
|
||||
↓
|
||||
Supervisor / Router Agent
|
||||
↓
|
||||
LangGraph StateGraph
|
||||
↓
|
||||
Agent A Agent B
|
||||
↓ ↓
|
||||
Guardrails → LLM OCI Generative AI → Output Guardrails → Judges
|
||||
↓
|
||||
Memory / RAG / Vector / Graph / Telemetry / Streaming
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Quickstart local
|
||||
|
||||
Suba a estrutura de Langfuse, MongoDB, REDIS para seu ambiente de desenvolvimento:
|
||||
|
||||
Vá até o folder ./agent_framework/Infrastructure_Langfuse/, onde existe o docker-compose.yml e execute:
|
||||
|
||||
```bash
|
||||
docker compose up
|
||||
```
|
||||
O langfuse estará em:
|
||||
|
||||
```bash
|
||||
http://localhost:3005
|
||||
```
|
||||
Crie sua Organização e seu projeto
|
||||
|
||||

|
||||
|
||||
Será criado também um MongoDB e um REDIS, logo seu .env terá a configuração para apontar para estes recursos conteinerizados.
|
||||
Você pode também apontar para um banco de dados Autonomous Oracle, basta configurar no arquivo .env.
|
||||
|
||||
Depois compile do Agent Framework dentro do agent_template_backend (agente template que se utiliza do Framework):
|
||||
|
||||
Obs: configure o arquivo .env.
|
||||
|
||||
Terminal 1:
|
||||
|
||||
```bash
|
||||
cd agent_framework_oci
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
cd agent_template_backend
|
||||
pip install -e ../agent_framework
|
||||
pip install -r requirements.txt
|
||||
uvicorn app.main:app --reload --reload-dir app --reload-dir config --port 8000
|
||||
```
|
||||
|
||||
Terminal 2:
|
||||
|
||||
```bash
|
||||
cd agent_framework_oci
|
||||
bash ./scripts/run_mcp_servers.sh
|
||||
```
|
||||
|
||||
Terminal 3:
|
||||
|
||||
```bash
|
||||
cd agent_framework_oci
|
||||
cd agent_frontend
|
||||
python -m http.server 5173
|
||||
```
|
||||
|
||||
Abra `http://localhost:5173`.
|
||||
|
||||
## OCI LLM
|
||||
|
||||
Configure no `.env`:
|
||||
|
||||
```env
|
||||
LLM_PROVIDER=oci_openai
|
||||
OCI_GENAI_BASE_URL=https://inference.generativeai.sa-saopaulo-1.oci.oraclecloud.com/openai/v1
|
||||
OCI_GENAI_MODEL=openai.gpt-4.1
|
||||
OCI_GENAI_API_KEY=...
|
||||
```
|
||||
|
||||
Para rodar sem credenciais, use:
|
||||
|
||||
```env
|
||||
LLM_PROVIDER=mock
|
||||
```
|
||||
|
||||
## Estado do projeto
|
||||
|
||||
Este é um template de referência funcional/simulável. Conectores reais de Autonomous Database, MongoDB, Redis, Langfuse, OCI Streaming e OCI GenAI estão isolados por interfaces/adapters para facilitar evolução e deploy.
|
||||
|
||||
## Enterprise Routing Edition
|
||||
|
||||
Esta versão também possui `README_ENTERPRISE_ROUTING.md`, com detalhes sobre roteamento por estado, intents configuráveis, LLM Router opcional e dois templates de exemplo.
|
||||
|
||||
## Multi-agent isolation
|
||||
|
||||
Esta distribuição inclui suporte para múltiplos `agent_template` no mesmo backend.
|
||||
Consulte `README_MULTI_AGENT_ISOLATION.md`.
|
||||
1545
Documentacao/README_old2.md
Normal file
1545
Documentacao/README_old2.md
Normal file
File diff suppressed because it is too large
Load Diff
38
Documentacao/docs_GLOBAL_SUPERVISOR_VALIDATION.txt
Normal file
38
Documentacao/docs_GLOBAL_SUPERVISOR_VALIDATION.txt
Normal file
@@ -0,0 +1,38 @@
|
||||
VALIDAÇÃO - GLOBAL SUPERVISOR
|
||||
|
||||
Alterações implementadas:
|
||||
|
||||
1. Framework
|
||||
- agent_framework.global_supervisor.models
|
||||
- agent_framework.global_supervisor.config
|
||||
- agent_framework.global_supervisor.session_store
|
||||
- agent_framework.global_supervisor.router
|
||||
- agent_framework.global_supervisor.client
|
||||
|
||||
2. Novo serviço
|
||||
- agent_gateway/app/main.py
|
||||
- agent_gateway/app/settings.py
|
||||
- agent_gateway/config/backends.yaml
|
||||
- agent_gateway/README.md
|
||||
- agent_gateway/Dockerfile
|
||||
- agent_gateway/docs/ARQUITETURA_GLOBAL_SUPERVISOR.md
|
||||
|
||||
3. Docker Compose
|
||||
- serviço agent-gateway adicionado na porta 8010.
|
||||
|
||||
Validações executadas:
|
||||
|
||||
- python3 -m compileall -q agent_framework/src/agent_framework/global_supervisor agent_gateway/app
|
||||
Resultado: OK
|
||||
|
||||
- Smoke test do roteamento híbrido:
|
||||
Entrada 1: "Minha fatura veio alta" -> contas
|
||||
Entrada 2: "e esse valor?" na mesma session_id -> contas por active_backend
|
||||
Resultado: OK
|
||||
|
||||
- Smoke test de import do app FastAPI:
|
||||
from app.main import app, registry, router
|
||||
Resultado: OK
|
||||
|
||||
Observação:
|
||||
- O proxy SSE do gateway foi deixado como etapa futura. O endpoint /gateway/message/sse já roteia e encaminha como mensagem normal; para SSE fim-a-fim, pode-se implementar proxy de /gateway/events/{session_id} para o backend ativo.
|
||||
5
Documentacao/docs_VALIDATION_GUARDRAILS_IC.txt
Normal file
5
Documentacao/docs_VALIDATION_GUARDRAILS_IC.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
VALIDATION REPORT - guardrails parallel fail-fast + observer IC
|
||||
Date: 2026-06-03
|
||||
|
||||
compileall: OK
|
||||
smoke-tests: OK
|
||||
BIN
Documentacao/img.png
Normal file
BIN
Documentacao/img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Reference in New Issue
Block a user