Files
AI-inovyo-assistende-db/docs/architecture.md
2026-05-14 15:29:03 -03:00

9.0 KiB

Arquitetura

Visão Geral

O Assistente Analítico é composto por três camadas principais: interface (Streamlit e FastAPI), agente de IA (LangGraph com Bedrock) e dados (DynamoDB).

┌─────────────────────────────────────────────────────────┐
│                    Interfaces                           │
│  ┌────────────────────┐  ┌────────────────────────┐     │
│  │ Streamlit (8501)   │  │   FastAPI (8000)       │     │
│  │ front.py           │  │   api.py               │     │
│  └────────┬───────────┘  └──────────┬─────────────┘     │
│           │                         │                   │
│           └──────────┬──────────────┘                   │
│                      ▼                                  │
│         orquestrador.main(query, history, model, base)  │
│                      │                                  │
│  ┌───────────────────▼──────────────────────────┐       │
│  │          agent_bedrock — LangGraph           │       │
│  │  ┌────────┐    ┌───────┐    ┌────────────┐   │       │
│  │  │ Model  │───▶│Router │───▶│   Tools    │   │       │
│  │  │  Node  │◀───│       │    │   Node     │   │       │
│  │  └────────┘    └───────┘    └────────────┘   │       │
│  └──────────────────────────────────────────────┘       │
│                                                         │
│  ┌──────────────────────────────────────────────┐       │
│  │              Serviços AWS                    │       │
│  │  ┌──────────┐ ┌────────────────────────────┐ │       │
│  │  │ Bedrock  │ │          DynamoDB          │ │       │
│  │  │  (LLMs)  │ │  (contexto + dados pré-    │ │       │
│  │  └──────────┘ │   processados)             │ │       │
│  │               └────────────────────────────┘ │       │
│  └──────────────────────────────────────────────┘       │
│                                                         │
│  ┌──────────────────────────────────────────────┐       │
│  │           Observabilidade                    │       │
│  │  ┌──────────┐ ┌──────────────────────────┐   │       │
│  │  │ Langfuse │ │     CloudWatch Logs      │   │       │
│  │  └──────────┘ └──────────────────────────┘   │       │
│  └──────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────┘

Módulos do Backend

O pacote backend é organizado por responsabilidade:

backend/
├── config.py         ← variáveis de ambiente
├── dynamo.py         ← depende de config
├── tools.py          ← depende de config, dynamo
├── agent_bedrock.py  ← depende de config, tools
└── orquestrador.py   ← depende de config, dynamo, agent_bedrock

Não há dependências circulares entre os módulos.

config.py

Lê todas as variáveis de ambiente na inicialização e exporta como constantes:

Variável Descrição
TABLE Tabela DynamoDB
REGION Região AWS
AWS_ACCOUNT ID da conta AWS
SECRET_NAME Nome do secret no Secrets Manager

dynamo.py

  • Instancia o cliente dynamodb (boto3) usando REGION
  • get_secret() — busca credenciais do Langfuse no Secrets Manager
  • Inicializa o objeto langfuse na carga do módulo
  • get_contexto(dashboard: str) -> dict — carrega contexto, filtro e itens disponíveis do DynamoDB para o dashboard informado

tools.py

Define a classe ReportTools, instanciada por requisição com o mapeamento de IDs local → real.

ReportTools(id_mapping: dict[str, str])
├── get_variable_value(id, variable)   — busca uma variável no DynamoDB
├── get_variables_list(id)             — lista as variáveis disponíveis para um ID
└── as_tools() -> list[StructuredTool] — retorna as tools prontas para o agente
Tool (nome exposto ao LLM) Método Descrição
get_variable_value get_variable_value(id, variable) Busca o valor de uma variável no DynamoDB para o ID informado
get_variable_list get_variables_list(id) Lista as variáveis disponíveis para o ID informado

Os IDs expostos ao LLM são locais (id_1, id_2, …). Internamente cada método converte o ID local para o ID real do DynamoDB via self.id_mapping. Por usar estado de instância em vez de variável global, múltiplas requisições simultâneas ficam completamente isoladas.

agent_bedrock.py

  • AgentState — TypedDict com messages e current_step
  • create_bedrock_llm(model_id, region, tools) — instancia ChatBedrockConverse e vincula as tools via bind_tools
  • call_model(state, llm) — nó do grafo: invoca o LLM
  • call_tools(state, tools_map) — nó do grafo: executa as tool calls usando o tools_map da requisição
  • should_continue(state) — roteador: "tools" se há tool_calls, "end" se não
  • create_agent(inference_profile_arn, region, tools) — constrói tools_map = {t.name: t for t in tools}, monta e compila o StateGraph

Fluxo do Grafo:

SystemMessage + HumanMessage
        │
        ▼
   ┌─────────┐
   │  model  │ ◄── LLM via Bedrock
   └────┬────┘
        │
   should_continue?
        ├── tool_calls → ┌───────┐
        │                │ tools │ → executa tools → volta ao model
        │                └───────┘
        └── (fim) → [END]

orquestrador.py

Ponto de entrada da lógica de negócio. A função main(user_query, history, model, base):

  1. Chama get_contexto(base) para carregar o contexto do dashboard
  2. Constrói id_mapping (id_1, id_2, … → IDs reais do DynamoDB) e local_items (IDs locais → descrições)
  3. Instancia ReportTools(id_mapping) com o mapeamento isolado da requisição
  4. Monta o SYSTEM_PROMPT dinamicamente com contexto, regras de filtro, local_items e histórico
  5. Cria o agente via create_agent(model, REGION, tools=report_tools.as_tools())
  6. Invoca o agente com o estado inicial
  7. Agrega tokens de todos os AIMessage do estado final
  8. Retorna response, input_tokens, output_tokens, total_tokens

Interfaces

front.py — Streamlit (porta 8501)

  • Importa from backend import orquestrador
  • Lista bases disponíveis consultando DynamoDB (item_type_index, item_type = "contexto")
  • Seleção de modelo LLM e base via st.selectbox
  • Histórico de conversas em session_state
  • Efeito de digitação caractere a caractere
  • Exibe consumo de tokens por resposta

api.py — FastAPI (porta 8000)

  • Importa from .backend import orquestrador
  • GET / — health check
  • POST /agent — recebe QueryRequest, chama orquestrador.main(), retorna QueryResponse

Modelos LLM Suportados

Modelo Provider Prefixo de Rota
anthropic.claude-haiku-4-5-20251001-v1:0 Anthropic us
anthropic.claude-sonnet-4-5-20250929-v1:0 Anthropic global
meta.llama4-maverick-17b-instruct-v1:0 Meta us
meta.llama4-scout-17b-instruct-v1:0 Meta us
amazon.nova-lite-v1:0 Amazon us
amazon.nova-pro-v1:0 Amazon us
amazon.nova-2-lite-v1:0 Amazon global

Todos acessados via AWS Bedrock inference profiles cross-region. O ARN é construído dinamicamente com REGION e AWS_ACCOUNT.