adjustments: manual v4
This commit is contained in:
@@ -144,6 +144,34 @@ Exemplos:
|
||||
|
||||
Se o core precisa importar um módulo concreto do agente para funcionar, essa separação provavelmente foi quebrada.
|
||||
|
||||
### Pastas de extensão do agente no template
|
||||
|
||||
O `agent_template_backend` materializa alguns pontos de extensão do framework em pastas locais. Essas pastas **não duplicam o core**: elas contêm configuração declarativa ou implementação específica do domínio que é registrada/consumida pelos mecanismos genéricos de `agent_framework`.
|
||||
|
||||
```text
|
||||
templates/agent_template_backend/
|
||||
├── workflows/
|
||||
│ ├── <workflow>.vN.yaml # definição versionada do fluxo determinístico
|
||||
│ └── <workflow>.active.yaml # versão ativa selecionada pelo agente
|
||||
└── app/
|
||||
├── workflow_actions/ # actions de negócio chamadas pelos workflows YAML
|
||||
├── presentation/ # renderers determinísticos específicos do domínio
|
||||
└── observability/ # adapters/observers e integração local de telemetria
|
||||
```
|
||||
|
||||
A fronteira arquitetural é:
|
||||
|
||||
| Pasta do template | Deve conter | Permanece no core |
|
||||
| --- | --- | --- |
|
||||
| `workflows/` | YAMLs declarativos e versionados do domínio | parser, validação, registry, executor, pause/resume e runtime de workflow |
|
||||
| `app/workflow_actions/` | funções de negócio registradas com `@workflow_action` | decorator, registry, execução, política de retry e infraestrutura de idempotência |
|
||||
| `app/presentation/` | renderers que transformam resultados confiáveis em resposta de domínio | registry de renderers, seleção do modo de resposta e fallback do runtime |
|
||||
| `app/observability/` | observer/adapters, mappings e enriquecimento específicos do agente | contratos IC/NOC/GRL, correlação, OTEL/Langfuse, exporters e runtime de observabilidade |
|
||||
|
||||
Regra prática: se uma implementação poderia ser usada sem conhecer telecom, varejo, cobrança, pedido ou outro domínio específico, ela provavelmente pertence ao `agent_framework`, e não a uma dessas pastas do agente. O core também não deve importar módulos concretos dessas pastas; o agente registra suas extensões no startup.
|
||||
|
||||
Detalhes: [Workflows Transacionais e Estado](./03_transaction_workflows_and_state.md), [Workflows transacionais avançados](./13_workflows_transacionais_avancados.md), [Observabilidade, Persistência e Prontidão Operacional](./11_observability_persistence_and_operational_readiness.md) e [Apresentação, recuperação e observabilidade](./15_apresentacao_recuperacao_e_observabilidade.md).
|
||||
|
||||
### Estado, memória e checkpoint são conceitos diferentes
|
||||
|
||||
**Estado de execução** representa o que está acontecendo no turno e no workflow.
|
||||
|
||||
@@ -257,6 +257,27 @@ Esperado: active_transaction é restaurado e concluído sem reiniciar a tool.
|
||||
- `Tuning-Performance/Transaction_Pre_Validation/`
|
||||
- `Tuning-Performance/Transaction_Evidence/`
|
||||
|
||||
### Organização física de `workflows/` no template
|
||||
|
||||
No `agent_template_backend`, as definições declarativas ficam na raiz `workflows/` do próprio agente:
|
||||
|
||||
```text
|
||||
templates/agent_template_backend/
|
||||
└── workflows/
|
||||
├── devolucao_pedido.v1.yaml
|
||||
└── devolucao_pedido.active.yaml
|
||||
```
|
||||
|
||||
Essa pasta pertence ao **agente**, porque expressa a sequência de negócio, versões e decisões daquele domínio. O mecanismo que interpreta esses arquivos pertence ao **framework**. Portanto:
|
||||
|
||||
- não implemente parser, executor ou registry dentro de `workflows/`;
|
||||
- não coloque código Python nessa pasta; actions Python ficam em `app/workflow_actions/`;
|
||||
- mantenha versões imutáveis (`*.vN.yaml`) e uma definição ativa válida (`*.active.yaml`);
|
||||
- use `WORKFLOWS_PATH` quando o host precisar apontar para outro diretório;
|
||||
- mudanças genéricas em pause/resume, retry, validação ou execução devem ser feitas no módulo `agent_framework.workflows`, não copiadas para o template.
|
||||
|
||||
O fluxo completo é: **YAML em `workflows/` → engine do framework → `node.action` → registry de actions → função em `app/workflow_actions/`**.
|
||||
|
||||
### Decisão arquitetural do motor de workflows
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/ADR_TRANSACTIONAL_WORKFLOW_ENGINE.md`.
|
||||
|
||||
@@ -683,6 +683,44 @@ Validações executadas:
|
||||
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.
|
||||
|
||||
### Papel de `app/observability/` no agente
|
||||
|
||||
O framework contém a infraestrutura genérica de observabilidade; o template contém apenas o ponto de integração específico do agente. No `agent_template_backend`, a estrutura de referência é:
|
||||
|
||||
```text
|
||||
app/observability/
|
||||
├── __init__.py
|
||||
└── telemetry_observer.py
|
||||
```
|
||||
|
||||
`app/observability/` é apropriado para:
|
||||
|
||||
- construir/configurar o observer usado pelo agente;
|
||||
- enriquecer eventos com metadados específicos disponíveis no host;
|
||||
- adaptar o contrato do agente a integrações externas;
|
||||
- registrar callbacks/adapters do template;
|
||||
- aplicar mappings/overlays específicos do agente quando previstos por configuração.
|
||||
|
||||
Ele **não** deve conter uma segunda implementação de OpenTelemetry, Langfuse, IC/NOC/GRL, sequence, exporters, correlação ou persistência. Esses mecanismos são transversais e pertencem ao `agent_framework`.
|
||||
|
||||
A dependência esperada é:
|
||||
|
||||
```text
|
||||
app/observability/telemetry_observer.py
|
||||
│ configura/compõe
|
||||
▼
|
||||
agent_framework.observability + contratos compartilhados
|
||||
│
|
||||
├── Langfuse
|
||||
├── OpenTelemetry
|
||||
├── IC / NOC / GRL
|
||||
└── exporters / mappings / pub-sub
|
||||
```
|
||||
|
||||
Ao criar um novo agente, prefira reutilizar o adapter de referência e alterar somente configuração/metadados de domínio. Se uma mudança for necessária para vários agentes, implemente-a no core e mantenha `app/observability/` fino.
|
||||
|
||||
**Anti-padrões:** importar diretamente SDKs de telemetria em cada agente para emitir eventos equivalentes; codificar labels históricos no runtime do agente; usar eventos de observabilidade como fonte de verdade do estado transacional; enviar prompt integral, segredo, PII ou payload financeiro bruto.
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
@@ -114,6 +114,37 @@ async def registrar_devolucao(params: dict, state: dict) -> dict:
|
||||
|
||||
O nome do decorator deve ser igual a `node.action`. A assinatura obrigatória é `(params: dict, state: dict) -> dict`. O módulo precisa ser importado no startup para registrar decorators. Actions devem devolver dados serializáveis; não devolva cliente HTTP, conexão, exception ou coroutine.
|
||||
|
||||
### Organização de `app/workflow_actions/`
|
||||
|
||||
No template, actions específicas do domínio ficam em `app/workflow_actions/`. O exemplo distribuído usa:
|
||||
|
||||
```text
|
||||
app/workflow_actions/
|
||||
├── __init__.py
|
||||
└── devolucao.py
|
||||
```
|
||||
|
||||
Esse diretório deve conter **somente implementação de negócio acionável pelo workflow** e pequenas funções auxiliares diretamente relacionadas. O motor de workflows, o decorator, o registry, a persistência, o mecanismo de pause/resume e a infraestrutura genérica de idempotência continuam no `agent_framework`.
|
||||
|
||||
Uma organização maior pode separar actions por domínio ou agregado:
|
||||
|
||||
```text
|
||||
app/workflow_actions/
|
||||
├── billing.py
|
||||
├── orders.py
|
||||
└── vas.py
|
||||
```
|
||||
|
||||
Regras:
|
||||
|
||||
- o `node.action` do YAML deve corresponder ao nome registrado em `@workflow_action`;
|
||||
- importe os módulos necessários no startup para que o registry seja populado antes da primeira execução;
|
||||
- não faça o core importar `app.workflow_actions.*`; o sentido da dependência é do agente para o framework;
|
||||
- não use a action como um segundo router ou como um novo runtime de agentes; ela deve executar uma etapa de negócio bem delimitada;
|
||||
- para efeitos externos, use a política e a infraestrutura de idempotência do framework e persista apenas resultados confirmados.
|
||||
|
||||
**Anti-padrão:** copiar classes de `agent_framework.workflows` para `app/workflow_actions/` para customizar um caso local. Se o mecanismo genérico não atende, estenda o framework por uma interface reutilizável; mantenha apenas a regra específica no agente.
|
||||
|
||||
### Idempotência do efeito externo
|
||||
|
||||
```python idempotency-example
|
||||
|
||||
@@ -37,6 +37,27 @@ def register_financial_renderers() -> None:
|
||||
|
||||
Importe e execute `register_financial_renderers()` uma vez no startup. A assinatura é keyword-only e deve aceitar `tool_name`, `result`, `state` e `agent_label`. Retorne `None` quando faltarem campos obrigatórios para permitir o fallback previsto pelo runtime. Nunca interpolar o payload inteiro: selecione campos permitidos, mascare identidade e formate valores explicitamente.
|
||||
|
||||
### Organização de `app/presentation/`
|
||||
|
||||
No `agent_template_backend`, renderers específicos do domínio ficam em:
|
||||
|
||||
```text
|
||||
app/presentation/
|
||||
├── __init__.py
|
||||
└── tool_renderers.py
|
||||
```
|
||||
|
||||
A pasta existe para separar **como um resultado confiável do domínio deve ser apresentado** da infraestrutura genérica que seleciona e executa renderers. Assim:
|
||||
|
||||
- `app/presentation/` implementa funções como `financial.balance`, `billing.invoice` ou outro renderer específico do agente;
|
||||
- `agent_framework.presentation` mantém registry, contrato de chamada e mecanismo genérico de integração com o runtime;
|
||||
- `config/tools.yaml` seleciona `response.mode: renderer` e o nome do renderer;
|
||||
- o startup do agente importa/registra os renderers uma única vez.
|
||||
|
||||
Renderers não devem buscar dados, decidir autorização, executar tools, alterar estado transacional ou reinterpretar um resultado usando LLM. A entrada já deve representar um resultado autorizado/confiável; o renderer apenas seleciona, mascara e formata campos.
|
||||
|
||||
**Anti-padrão:** criar em `app/presentation/` uma cópia do registry ou do pipeline de apresentação do framework. Se vários agentes precisarem do mesmo mecanismo de formatação/seleção, ele deve evoluir no core; somente a apresentação específica do domínio fica no agente.
|
||||
|
||||
### Output Supervisor
|
||||
|
||||
O Output Supervisor valida a resposta candidata antes da saída final. Ele pode permitir, sanitizar, solicitar retry, bloquear, entregar a humano ou observar. `OUTPUT_SUPERVISOR_MAX_RETRIES` deve ter limite pequeno; cada retry precisa de orientação objetiva e a resposta reescrita deve passar novamente pelos controles. Não use retry para erro permanente de autorização ou indisponibilidade.
|
||||
|
||||
Reference in New Issue
Block a user