# compass_backoffice — Manual de execução e testes ## 1. O que é o `compass_backoffice` O `compass_backoffice` é um backend de agente para atendimento operacional de Backoffice/ANATEL, migrado para utilizar o `agent_framework_oci` como motor principal de execução. Ele foi construído para receber solicitações de backoffice, reclamações ANATEL, protocolos, casos de cliente e demandas operacionais, acionar ferramentas externas por MCP, consultar contexto via RAG, aplicar guardrails, registrar observabilidade IC/NOC/GRL e produzir uma resposta controlada pelo workflow corporativo do framework. Em termos práticos, o projeto permite testar um agente de backoffice com: - entrada conversacional via `/gateway/message`; - entrada REST compatível com o contrato legado via `/agent/process-and-stream` e rotas relacionadas; - roteamento por intents configuradas em YAML; - execução de ferramentas pelo `MCPToolRouter` do framework; - isolamento por `tenant_id`, `agent_id`, `session_id` e `BusinessContext`; - RAG, memória, checkpoints, cache, telemetria, guardrails, judges e output supervisor do `agent_framework_oci`. ## 2. Finalidade da aplicação O agente foi criado para apoiar fluxos como: - triagem de reclamações ANATEL; - consulta de protocolo, chamado, cliente, contrato, linha, CPF/CNPJ e contexto operacional; - enriquecimento de caso usando IMDB/PMID, Siebel, Speech Analytics, TAIS KB, ABRT e Portabilidade; - geração de rascunho ou resposta para emulador ANATEL; - registro controlado de ação operacional, parecer, conclusão, encaminhamento ou atualização de demanda; - validação de segurança, conformidade, precisão e aderência ao domínio antes da resposta final. O objetivo da migração é evitar que o agente tenha um grafo paralelo ou regras “quebra-galho”. A aplicação deve delegar ao framework tudo que o framework já oferece: workflow, roteamento, identidade, MCP, RAG, guardrails, judges, observabilidade, memória, checkpoint e cache. ## 3. Arquitetura resumida Fluxo principal do agente conversacional: ```text HTTP /gateway/message ou /gateway/message/sse -> ChannelGateway -> IdentityResolver + BusinessContext -> SessionRepository / Memory / Checkpoint -> AgentWorkflow LangGraph -> input_guardrails -> routing_decision -> backoffice_agent -> output_supervisor -> output_guardrails -> judge -> supervisor_review -> persist -> ChannelResponse ``` Fluxo REST legado adaptado ao framework: ```text HTTP /agent/process-and-stream -> BackofficeRestChannelAdapter -> BackofficeWorkflowDispatcher -> BackofficeWorkflowExecutor -> etapas framework-native de guardrails, output supervisor, judges, telemetry e persistência ``` Fluxo de ferramentas: ```text BackofficeAgent -> MCPToolRouter do agent_framework_oci -> config/tools.yaml -> config/mcp_parameter_mapping.yaml -> config/mcp_servers.yaml -> Backoffice MCP Server HTTP na porta 8010 -> backend mock, REST, Oracle ou clientes TIM ``` ## 4. Componentes principais do projeto ```text app/main.py ``` API FastAPI principal. Inicializa LLM, memória, summary memory, sessão, checkpoint, cache, ChannelGateway, analytics, observer, MCPToolRouter, IdentityResolver, AgentWorkflow, executor REST e rotas de debug/teste. ```text app/workflows/agent_graph.py ``` Workflow LangGraph principal. Usa componentes do framework para guardrails, roteamento, supervisor, output supervisor, judges, RAG, telemetria profunda de LangGraph e persistência. ```text app/agents/backoffice_agent.py ``` Agente de domínio Backoffice/ANATEL. Ele não deve recriar capacidades do framework. Recebe `intent`, `route`, `mcp_tools` e contexto do workflow; consulta RAG; aciona ferramentas MCP; emite IC/NOC/GRL; gera a resposta final. ```text app/workflows/backoffice_workflow_executor.py app/workflows/backoffice_workflow_dispatcher.py app/channels/backoffice_rest_adapter.py ``` Camada de compatibilidade para contratos REST de backoffice. Preserva endpoints antigos, mas executa o fluxo dentro do runtime do framework. ```text config/agents.yaml ``` Registra o agente `backoffice_anatel`, define o agent default e aponta configs específicas de prompt, guardrails, judges, MCP e tools. ```text config/routing.yaml ``` Define intents, palavras-chave, exemplos, tools por intent e state policies. O roteamento ativo padrão é `router`, com fallback para `backoffice_agent`. ```text config/agents/backoffice_anatel/guardrails.yaml ``` Configuração de guardrails específica do agente. Ativa rails de entrada e saída como `INPUT_SIZE`, `MSK`, `PINJ`, `TOX`, `DLEX_IN`, `RAGSEC`, `VLOOP`, `REVPREC`, `DLEX_OUT`, `OOS`, `CMP` e `AOFERTA`. ```text config/agents/backoffice_anatel/judges.yaml ``` Configuração de judges pós-resposta para avaliação de qualidade, precisão e aderência. ```text config/tools.yaml ``` Contrato das ferramentas disponíveis para o agente. Exemplos: `consultar_reclamacao`, `consultar_cliente_backoffice`, `consultar_siebel_caso`, `consultar_imdb_cliente`, `consultar_speech_analytics`, `consultar_tais_kb`, `consultar_abrt`, `consultar_portabilidade`, `registrar_acao_backoffice` e ferramentas do emulador. ```text config/mcp_parameter_mapping.yaml ``` Mapeia `BusinessContext` canônico para argumentos das tools MCP. Exemplo: `interaction_key -> protocol_id`, `customer_key -> customer_key`, `contract_key -> contract_key`, `session_key -> operator_session`. ```text mcp_servers/backoffice_mcp_server/ ``` Servidor MCP HTTP compatível com o `MCPToolRouter` do framework. Expõe `/health`, `/tools/list` e `/tools/call`. ## 5. O que o projeto utiliza do `agent_framework_oci` O `compass_backoffice` utiliza as seguintes capacidades do framework: | Capacidade do framework | Uso no projeto | |---|---| | LangGraph / workflow corporativo | `app/workflows/agent_graph.py` | | ChannelGateway | Normalização/renderização de mensagens por canal | | IdentityResolver | Resolução de identidade técnica e `BusinessContext` | | BusinessContext | Chaves canônicas para MCP e sessão | | AgentProfileRegistry | Carregamento de `config/agents.yaml` | | EnterpriseRouter | Roteamento por intents em `config/routing.yaml` | | Supervisor | Modo alternativo quando `ROUTING_MODE=supervisor` | | GuardrailPipeline | Guardrails de entrada e saída | | OutputSupervisor | Revisão/retry/sanitize/block de resposta | | JudgePipeline | Avaliação pós-resposta | | MCPToolRouter | Chamada de tools via servidor MCP HTTP | | RagService | Consulta RAG nativa do framework | | Cache | Cache criado por `create_cache(settings)` | | Memory | Histórico conversacional | | ConversationSummaryMemory | Resumo de conversa | | SessionRepository | Sessões persistentes | | CheckpointRepository | Checkpoints por sessão | | Telemetry / Langfuse | Spans, eventos, usage e debug | | AgentObserver / Analytics | Emissão de IC, NOC e GRL | | SSEHub | Eventos SSE por sessão | ## 6. Pré-requisitos ### 6.1 Python O `pyproject.toml` declara: ```text requires-python = >=3.11 ``` Recomendação prática: ```text Python 3.11 ou 3.12 ``` O `Dockerfile` usa `python:3.12-slim`. ### 6.2 Dependências Python O projeto possui `requirements.txt` com dependências como: - `fastapi` - `uvicorn[standard]` - `pydantic` - `pydantic-settings` - `python-dotenv` - `langgraph` - `langchain-core` - `openai` - `oci` - `oracledb` - `pymongo` - `redis` - `PyYAML` - `langfuse` - `httpx` - `opentelemetry-*` - `pytest` - `pytest-asyncio` - `motor` - `aiokafka` - `google-auth` - `requests` - `tenacity` - `python-json-logger` ### 6.3 `agent_framework_oci` O backend depende do pacote `agent_framework_oci`, importado como `agent_framework`. Existem duas formas comuns de disponibilizar o framework: #### Opção A — instalação editável local Estrutura sugerida: ```text workspace/ agent_framework_oci/ compass_backoffice/ ``` Instalação: ```bash cd workspace/compass_backoffice python -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install -e ../agent_framework_oci pip install -r requirements.txt ``` Se o diretório do framework tiver outro nome, ajuste o caminho do `pip install -e`. #### Opção B — Docker O `Dockerfile` espera copiar o framework para `/agent_framework`. Em builds Docker, garanta que o contexto inclua o diretório do framework conforme esperado pelo arquivo. ### 6.4 Serviços opcionais Para testes locais mínimos, é possível usar SQLite e MCP mock. Para execução integrada, podem ser necessários: - Redis, se o cache estiver configurado para Redis; - MongoDB, se algum repositório estiver configurado para Mongo; - Oracle Autonomous DB, se memória/checkpoint/RAG/TAIS real forem usados; - Langfuse, se telemetria estiver habilitada; - credenciais OCI Generative AI; - credenciais TIM/Siebel/PMID/Speech/TAIS, se o MCP estiver em modo real. ## 7. Configuração local Crie o `.env` principal: ```bash cp .env.example .env ``` Principais variáveis para teste local: ```env APP_ENV=local LOG_LEVEL=INFO CORS_ORIGINS=* DEFAULT_AGENT_ID=backoffice_anatel ROUTING_MODE=router ENABLE_SSE=true ENABLE_PARALLEL_GUARDRAILS=true GUARDRAILS_FAIL_FAST=true SESSION_REPOSITORY_PROVIDER=sqlite MEMORY_REPOSITORY_PROVIDER=sqlite CHECKPOINT_REPOSITORY_PROVIDER=sqlite USAGE_REPOSITORY_PROVIDER=sqlite SQLITE_DB_PATH=.local/backoffice_framework.db LLM_PROVIDER=oci_openai LLM_MODEL=cohere.command-r-08-2024 MCP_ENABLED=true MCP_SERVERS_CONFIG_PATH=config/mcp_servers.yaml MCP_PARAMETER_MAPPING_PATH=config/mcp_parameter_mapping.yaml BACKOFFICE_MCP_BASE_URL=http://localhost:8010 ``` Para rodar com LLM real, preencha também as variáveis do provider OCI/OpenAI-compatible exigidas pelo seu `agent_framework_oci`, por exemplo endpoint, chave, profile, região e compartment. Para testes sem integrações reais de backoffice, configure o MCP em modo mock. ## 8. Como subir o Legacy Backoffice MCP Server Crie o arquivo de ambiente do MCP: ```bash cp .env.backoffice_mcp.example .env.backoffice_mcp ``` Para teste local com dados simulados: ```env BACKOFFICE_MCP_HOST=0.0.0.0 BACKOFFICE_MCP_PORT=8010 BACKOFFICE_MCP_USE_MOCK=true BACKOFFICE_MCP_BACKEND_TYPE=mock ``` Suba o servidor MCP: ```bash source .venv/bin/activate ./scripts/run_backoffice_mcp.sh ``` Teste o health: ```bash curl http://localhost:8010/health ``` Liste as tools: ```bash curl http://localhost:8010/tools/list ``` Chamada direta de tool: ```bash curl --location 'http://localhost:8010/tools/call' \ --header 'Content-Type: application/json' \ --data '{ "name": "consultar_reclamacao", "arguments": { "protocol_id": "202603279001551", "customer_key": "06252533106" } }' ``` ### Modos de backend do MCP O MCP server suporta os modos abaixo: | Modo | Uso | |---|---| | `mock` | Teste local com dados simulados em memória | | `rest` | Chamada para backend REST configurado por `BACKOFFICE_MCP_REST_BASE_URL` | | `oracle` | Placeholder para integração Oracle real | | `tim_clients` | Uso de clientes TIM/develop configurados no `.env` | Para usar integrações reais, desative mock e preencha as credenciais correspondentes: ```env BACKOFFICE_MCP_USE_MOCK=false BACKOFFICE_MCP_BACKEND_TYPE=tim_clients BACKOFFICE_MCP_FAIL_OPEN_ON_BACKEND_ERROR=true ``` ## 9. Como subir a aplicação principal Em outro terminal: ```bash cd compass_backoffice source .venv/bin/activate mkdir -p .local uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload ``` Teste o health: ```bash curl http://localhost:8000/health ``` Endpoints úteis de diagnóstico: ```bash curl http://localhost:8000/agents curl http://localhost:8000/debug/env curl http://localhost:8000/debug/mcp/tools curl http://localhost:8000/test-llm ``` Teste de identidade: ```bash curl --location 'http://localhost:8000/debug/identity' \ --header 'Content-Type: application/json' \ --data '{ "channel": "web", "agent_id": "backoffice_anatel", "tenant_id": "default", "payload": { "message": "Consultar protocolo 202603279001551 do CPF 06252533106", "session_id": "teste-readme-001", "user_id": "operador" } }' ``` Teste de roteamento: ```bash curl --location 'http://localhost:8000/debug/route' \ --header 'Content-Type: application/json' \ --data '{ "channel": "web", "agent_id": "backoffice_anatel", "tenant_id": "default", "payload": { "message": "Preciso analisar uma reclamação da ANATEL do protocolo 202603279001551", "session_id": "teste-readme-001", "user_id": "operador" } }' ``` ## 10. Teste conversacional pelo gateway do framework ```bash curl --location 'http://localhost:8000/gateway/message' \ --header 'Content-Type: application/json' \ --data '{ "channel": "web", "agent_id": "backoffice_anatel", "tenant_id": "default", "payload": { "message": "Preciso analisar a reclamação ANATEL protocolo 202603279001551 do CPF 06252533106. A TIM está ligando cobrando planos que o cliente diz não ter assinado.", "session_id": "teste-backoffice-001", "user_id": "operador-bko", "business_context": { "customer_key": "06252533106", "interaction_key": "202603279001551", "session_key": "teste-backoffice-001" } } }' ``` Resposta esperada em alto nível: - `text` com resposta do agente; - `metadata.agent_id = backoffice_anatel`; - `metadata.route` e/ou `metadata.intent`; - `metadata.business_context` resolvido; - `metadata.mcp_results`, quando tools forem acionadas; - `metadata.guardrails` e `metadata.judges`, quando habilitados/retornados pelo pipeline. ## 11. Teste com SSE Primeiro envie uma mensagem com SSE habilitado: ```bash curl --location 'http://localhost:8000/gateway/message/sse' \ --header 'Content-Type: application/json' \ --data '{ "channel": "web", "agent_id": "backoffice_anatel", "tenant_id": "default", "payload": { "message": "Consultar protocolo ANATEL 202603279001551", "session_id": "teste-sse-001", "user_id": "operador-bko", "business_context": { "interaction_key": "202603279001551", "customer_key": "06252533106" } } }' ``` Depois acompanhe os eventos usando o `conversation_key` retornado na resposta. Em geral, o formato é: ```text tenant_id:agent_id:session_id ``` Exemplo: ```bash curl -N 'http://localhost:8000/gateway/events/default:backoffice_anatel:teste-sse-001' ``` Eventos esperados: - `flow.start` - `session.upserted` - `message.received` - `workflow.started` - `workflow.completed` - `message.responded` - `flow.end` ## 12. Teste com o curl anexado O arquivo anexado `curl_test.txt` usa a rota: ```text POST /agent/process-and-stream ``` Esse endpoint preserva o contrato REST do backoffice e passa pelo adapter framework-native. Com a aplicação na porta 8000, execute o conteúdo do arquivo: ```bash bash curl_test.txt ``` Ou copie o curl abaixo: ```bash curl --location 'http://localhost:8000/agent/process-and-stream' \ --header 'Content-Type: application/json' \ --data-raw '{ "caseType": "anatel", "origin": { "sourceSystem": "turbina_odc", "submittedBy": { "userId": "f8052701", "name": "Nicolas Silva", "email": null } }, "crmProtocol": "DS-987654321", "ticketId": "ert", "customer": { "cpfCnpj": "06252533106", "phones": ["62981152324"], "msisdn": "62981152324", "name": "Nicolas Ferreira da Silva", "email": "nicolas.silva@exemplo.com.br", "govBrSeal": null, "odcCustomer": false, "contumazCustomer": false, "address": { "cep": "01001-000", "street": "Praca da Se", "neighborhood": "Se", "city": "Sao Paulo", "state": "SP" }, "subscriber": { "cpfCnpj": "06252533106", "subscriberName": "Assinante Exemplo", "contactPhone": "62981152324", "contactName": "Nicolas Ferreira da Silva" } }, "complaint": { "complaintProtocol": "202603279001551", "actionType": "nova", "providerProtocol": null, "inputChannel": "Anatel", "service": "Celular Pós-pago", "firstService": "Celular Pós-pago", "modality": "Cobrança", "motive": "Operadora liga ou envia mensagens indevidas de cobrança", "description": "A TIM está me ligando cobrando planos que eu não assinei. Quero que parem", "openedAt": "2026-03-27T11:45:00-03:00", "dueAt": null } }' ``` ## 13. Teste de MCP via backend principal O backend principal também permite chamar tools usando o router do framework: ```bash curl --location 'http://localhost:8000/debug/mcp/call/consultar_reclamacao' \ --header 'Content-Type: application/json' \ --data '{ "business_context": { "interaction_key": "202603279001551", "customer_key": "06252533106", "session_key": "teste-mcp-001" } }' ``` Esse teste é importante porque valida o caminho correto: ```text FastAPI principal -> MCPToolRouter -> mcp_parameter_mapping.yaml -> Backoffice MCP Server ``` Não é recomendado chamar clientes TIM/Siebel diretamente dentro do agente. O caminho correto é via MCP. ## 14. Como subir com Docker Compose O projeto inclui `docker-compose.yml` com dois serviços: - `backoffice-api`, porta `8000`; - `backoffice-mcp`, porta `8010`. Execute: ```bash cp .env.example .env cp .env.backoffice_mcp.example .env.backoffice_mcp docker compose up --build ``` Teste: ```bash curl http://localhost:8000/health curl http://localhost:8010/health ``` Observação: confira o `Dockerfile` e o contexto de build. Ele espera que o framework esteja disponível no contexto como `agent_framework` e a aplicação como `agent_template_backend`. Se a pasta local tiver outro nome, ajuste o Dockerfile ou o contexto antes do build. ## 15. Guardrails, judges e output supervisor O agente usa duas camadas de configuração: ```text config/guardrails.yaml config/agents/backoffice_anatel/guardrails.yaml ``` A configuração específica do agente é a mais importante para o `backoffice_anatel`. Guardrails de entrada configurados: - `INPUT_SIZE` - `MSK` - `PINJ` - `TOX` - `DLEX_IN` - `RAGSEC` - `VLOOP` Guardrails de saída configurados: - `REVPREC` - `DLEX_OUT` - `OOS` - `CMP` - `AOFERTA` O workflow também usa: - `OutputSupervisor`, para revisão, retry, sanitização ou bloqueio; - `JudgePipeline`, para avaliação pós-resposta; - `supervisor_review`, para revisão final do fluxo. ## 16. IC, NOC e GRL A emissão de observabilidade passa por: ```text AgentObserver create_analytics_publisher(settings) src.compat.framework_observer.configure(...) ``` No agente de backoffice, os eventos principais aparecem em `app/agents/backoffice_agent.py`. Exemplos de ICs usados no agente: - `AGA.001`: entrada recebida pelo agente nativo; - `AGA.018`: contexto canônico validado; - `AGA.012`: RAG/TAIS KB consultado; - `AGA.014`: ferramentas MCP selecionadas; - `AGA.008`: registro operacional ignorado por ausência de `action_text`; - `AGA.010`: Speech Analytics consultado; - `AGA.011`: cliente/IMDB consultado; - `AGA.020`: templates/TAIS consultados; - `AGA.006`: ação operacional solicitada; - `AGA.043`: resposta produzida. Exemplo de NOC: - `NOC.001`: conclusão do agente nativo de backoffice. Os GRLs são esperados principalmente nas etapas de guardrails/output supervisor/judges do framework e nos pontos de observabilidade plugados pelo `AgentObserver`. ## 17. RAG O workflow inicializa: ```text create_embedding_provider(settings) RagService(settings, telemetry=telemetry) ``` O agente usa RAG para enriquecer a resposta quando configurado. O namespace de referência do agente aparece em `config/agents.yaml`: ```yaml metadata: rag_namespace: backoffice_anatel ``` Para uso real do RAG, configure no `.env` os providers e stores exigidos pelo `agent_framework_oci`, como embeddings OCI, vector store e credenciais de banco quando aplicável. ## 18. Rotas disponíveis ### Framework/gateway ```text GET /health GET /agents GET /debug/env GET /test-llm POST /debug/route POST /debug/identity GET /debug/usage GET /debug/mcp/tools POST /debug/mcp/call/{tool_name} POST /gateway/message POST /gateway/message/sse GET /gateway/events/{session_id} GET /sessions/{session_id}/messages GET /sessions/{session_id}/checkpoint ``` ### Contratos REST de backoffice preservados ```text POST /agent/process-ticket POST /agent/execute POST /agent/process-and-stream POST /agent/search-tais-kb POST /case/{transaction_id}/response-emulator/generate POST /case/{transaction_id}/response-emulator/finalize GET /case/{transaction_id}/response-emulator POST /emulator-rag/search GET /health/live GET /health/ready GET /debug/backoffice/parity ``` ### MCP server ```text GET /health GET /tools/list POST /tools/call ``` ## 19. Validação estrutural Antes de executar testes funcionais, valide sintaxe e imports básicos: ```bash python -m compileall -q app src tools mcp_servers python tools/validate_parity.py ``` ## 20. Troubleshooting ### `ModuleNotFoundError: agent_framework` Instale o framework em modo editável: ```bash pip install -e ../agent_framework_oci ``` Ou ajuste o `PYTHONPATH` temporariamente: ```bash export PYTHONPATH="../agent_framework_oci:$PYTHONPATH" ``` ### `/debug/mcp/tools` sem tools Verifique: ```env MCP_ENABLED=true MCP_SERVERS_CONFIG_PATH=config/mcp_servers.yaml MCP_PARAMETER_MAPPING_PATH=config/mcp_parameter_mapping.yaml ``` E confirme se o MCP está ativo: ```bash curl http://localhost:8010/health ``` ### MCP retorna erro de conexão Confirme se `config/mcp_servers.yaml` aponta para: ```yaml endpoint: http://localhost:8010 ``` No Docker, o endpoint deve ser o nome do serviço: ```yaml endpoint: http://backoffice-mcp:8010 ``` ### LLM não responde Teste: ```bash curl http://localhost:8000/test-llm ``` Se falhar, revise as variáveis do provider OCI/OpenAI-compatible. ### SQLite não cria banco Crie a pasta local: ```bash mkdir -p .local ``` ### Endpoint legado funciona, mas gateway não aciona tools Teste o roteamento: ```bash curl http://localhost:8000/debug/mcp/tools ``` Depois teste `/debug/route` e confirme se a intent retorna `mcp_tools`. ## 21. Sequência recomendada de teste local ```bash # Terminal 1 cd compass_backoffice source .venv/bin/activate cp .env.backoffice_mcp.example .env.backoffice_mcp ./scripts/run_backoffice_mcp.sh ``` ```bash # Terminal 2 cd compass_backoffice source .venv/bin/activate cp .env.example .env mkdir -p .local uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload ``` ```bash # Terminal 3 cd compass_backoffice source .venv/bin/activate cd legacy_backend uvicorn mock_imdb_server:app --port 8011 ``` ```bash # Terminal 4 curl http://localhost:8010/health curl http://localhost:8000/health curl http://localhost:8000/debug/mcp/tools bash curl_test.txt ``` ## 22. Diretriz de evolução Ao evoluir o `compass_backoffice`, mantenha a regra arquitetural: - identidade e chaves de negócio: `IdentityResolver` e `BusinessContext`; - roteamento: `config/routing.yaml` e `EnterpriseRouter`; - ferramentas externas: `MCPToolRouter` + MCP server; - conhecimento: `RagService` do framework; - segurança e conformidade: guardrails, output supervisor e judges do framework; - observabilidade: `AgentObserver`, IC, NOC, GRL, Langfuse e telemetry; - persistência: memória, sessão e checkpoint do framework. Só implemente código de domínio fora do framework quando a capacidade realmente não existir no `agent_framework_oci`.