Initial commit

This commit is contained in:
2026-05-14 15:29:03 -03:00
parent 82ac556ecc
commit 54bcf081f6
31 changed files with 3132 additions and 518 deletions

144
docs/development.md Normal file
View File

@@ -0,0 +1,144 @@
# Desenvolvimento
## Estrutura do Projeto
```
agente-bd/
├── code/ # Código da aplicação
│ ├── app/
│ │ ├── api.py # FastAPI — endpoints REST
│ │ ├── front.py # Streamlit — interface web
│ │ └── backend/
│ │ ├── __init__.py # Marca o diretório como pacote Python
│ │ ├── config.py # Variáveis de ambiente
│ │ ├── dynamo.py # DynamoDB, Langfuse, get_contexto
│ │ ├── tools.py # ReportTools: get_variable_value, get_variables_list
│ │ ├── agent_bedrock.py # LLM Bedrock, grafo LangGraph
│ │ └── orquestrador.py # main() — ponto de entrada
│ ├── utils/
│ │ └── dynamodb_read_table.py # Utilitários DynamoDB
│ ├── main.py # Entry point
│ ├── Dockerfile # Imagem Docker
│ ├── entrypoint.sh # Script de inicialização
│ └── requirements.txt # Dependências Python
├── infra/ # Infraestrutura como Código
│ ├── ecr/ # Stack ECR
│ ├── ecs_alb/ # Stack ECS + ALB
│ └── langfuse/ # Stack Langfuse
├── docs/ # Esta documentação
└── Makefile # Automação de build e deploy
```
## Responsabilidades dos Módulos do Backend
### `config.py`
Lê todas as variáveis de ambiente obrigatórias na carga do módulo e as exporta como constantes. Qualquer módulo que precise de configuração importa daqui.
### `dynamo.py`
- Instancia o cliente `dynamodb` e o objeto `langfuse` na carga do módulo
- `get_secret()` — busca as credenciais do Langfuse no AWS Secrets Manager
- `get_contexto(dashboard: str) -> dict` — retorna `contexto`, `filter` e `items_disponiveis` para o dashboard informado
### `tools.py`
Define a classe `ReportTools` com as ferramentas do agente:
- `ReportTools(id_mapping)` — instanciada por requisição; `id_mapping` converte IDs locais (`id_1`, `id_2`, …) para os IDs reais do DynamoDB
- `get_variable_value(id, variable)` — busca o valor de uma variável no DynamoDB
- `get_variables_list(id)` — lista as variáveis disponíveis para um ID
- `as_tools()` — retorna a lista de `StructuredTool` com nomes `get_variable_value` e `get_variable_list`
### `agent_bedrock.py`
- `AgentState` — TypedDict com `messages` e `current_step`
- `create_bedrock_llm(model_id, region, tools)` — instancia `ChatBedrockConverse` e vincula as tools
- `call_model(state, llm)`, `call_tools(state, tools_map)`, `should_continue(state)` — nós e roteador do grafo LangGraph
- `create_agent(inference_profile_arn, region, tools)` — monta o `tools_map` e compila o `StateGraph`
### `orquestrador.py`
Função `main(user_query, history, model, base)`:
- Carrega contexto via `get_contexto(base)`
- Constrói `id_mapping` e `local_items` para isolar IDs reais do LLM
- Instancia `ReportTools(id_mapping)` e passa as tools ao agente
- Monta o system prompt com `local_items` no lugar dos IDs reais
- Cria e invoca o agente
- Retorna resposta e contagem de tokens
## Cadeia de Imports
```
config.py
dynamo.py ←── config
tools.py ←── config, dynamo
agent_bedrock.py ←── config
orquestrador.py ←── config, dynamo, agent_bedrock, tools
api.py / front.py ←── orquestrador (via pacote backend)
```
## Dependências Principais
| Pacote | Uso |
|--------|-----|
| `boto3` | SDK AWS (DynamoDB, Secrets Manager) |
| `langchain` | Framework de orquestração LLM |
| `langchain-aws` | Integração LangChain + AWS Bedrock |
| `langgraph` | Framework de agentes baseado em grafos |
| `streamlit` | Interface web interativa |
| `fastapi` | Framework de API REST |
| `uvicorn` | Servidor ASGI |
| `langfuse` | Observabilidade e tracing de LLMs |
## Fluxo de Desenvolvimento
1. **Fazer alterações** — Editar os arquivos em `code/app/`
3. **Testar localmente** — Rodar FastAPI + Streamlit ou via Docker
4. **Validar** — Executar scripts de teste em `scripts/`
5. **Build e deploy** — Seguir o [guia de deploy](deployment.md)
## Adicionando uma Nova Ferramenta ao Agente
Todas as ferramentas vivem na classe `ReportTools` em `tools.py`. Basta:
1. Adicionar o método à classe:
```python
def minha_nova_tool(self, param: str) -> str:
"""Descrição da tool para o LLM."""
real_id = self.id_mapping.get(param, param) # se precisar resolver ID
# implementação
return resultado
```
2. Registrá-lo em `as_tools()`:
```python
def as_tools(self) -> list:
return [
...,
StructuredTool.from_function(
self.minha_nova_tool,
name="minha_nova_tool",
description="Descrição da tool para o LLM.",
),
]
```
Não é necessário alterar `agent_bedrock.py` — o `tools_map` é construído dinamicamente a partir da lista retornada por `as_tools()`.
## Adicionando um Novo Modelo LLM
Em `agent_bedrock.py`, adicionar o novo modelo aos três dicionários em `create_bedrock_llm()`:
- `MODEL_ARNS` — ARN do inference profile
- `PROVIDER` — provider (`anthropic`, `meta`, `amazon`)
- `prefix` — prefixo de rota (`us` ou `global`)
E adicionar o model ID à lista `MODELS` em `front.py`.