mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-09-07 18:23:46 +00:00
Documentation organization
This commit is contained in:
242
docs/developer/en/01_architecture_and_concepts.md
Normal file
242
docs/developer/en/01_architecture_and_concepts.md
Normal file
@@ -0,0 +1,242 @@
|
||||
|
||||
### Agent Framework OCI Architecture and Concepts
|
||||
|
||||
### Purpose of this document
|
||||
|
||||
This document **does not replace the root `README_en.md`** and does not duplicate the end-to-end agent development tutorial.
|
||||
|
||||
Use:
|
||||
|
||||
- [`README_en.md`](../../../README_en.md) to develop, configure, run and test an agent end to end;
|
||||
- this document to understand architecture, responsibility boundaries, components and where each implementation belongs;
|
||||
- the other manuals in this folder to deepen a specific capability or troubleshoot a problem.
|
||||
|
||||
The separation is intentional: there is **one main tutorial** and multiple **specialized reference manuals**.
|
||||
|
||||
### Source of truth
|
||||
|
||||
When documentation differs, use this order:
|
||||
|
||||
1. code for the version in use;
|
||||
2. `README.md` / `README_en.md` for the same version;
|
||||
3. normative SPECs/SDDs;
|
||||
4. specialized manuals in this folder;
|
||||
5. release notes and `README_old*` only as historical material.
|
||||
|
||||
### Platform mental model
|
||||
|
||||
Agent Framework OCI is a layered platform.
|
||||
|
||||
The **framework core** provides reusable, domain-neutral mechanisms: runtime, state, memory, routing, tool integration, guardrails, judges, persistence, observability and common contracts.
|
||||
|
||||
The **agent** contains use-case-specific behavior: intents, prompts, domain rules, agent-specific policies, business workflows, mappings, integrations and external components owned by that agent.
|
||||
|
||||
**Gateways** handle cross-cutting ingress, governance and integration concerns. They should not absorb agent business logic.
|
||||
|
||||
**MCP Servers** encapsulate tools and integrations with domain or legacy services. The **MCP Gateway** provides centralized tool catalog and governance.
|
||||
|
||||
### Main components
|
||||
|
||||
| Component | Primary responsibility | Must not contain |
|
||||
|---|---|---|
|
||||
| `libs/agent_framework/` | Generic runtime, contracts, state, memory, routing, guardrails, judges and common integrations | Company- or agent-specific business rules |
|
||||
| `templates/agent_template_backend/` | Executable reference for creating agents | A permanent fork of the core |
|
||||
| `apps/agent_gateway/` | Governed ingress, cross-cutting policies, rate limits, auth and metadata | Business workflow |
|
||||
| `apps/channel_gateway/` | Adapt channels to canonical contracts | Agent business logic |
|
||||
| `apps/mcp_gateway/` | Central tool catalog, authorization and execution | Conversational orchestration |
|
||||
| `mcp/servers/` | Domain tools and integrations | Global agent orchestration |
|
||||
| `evals/` | Certification and regression | Production business logic |
|
||||
| `deploy/` | Containers and Kubernetes artifacts | Functional rules |
|
||||
|
||||
### Conceptual request flow
|
||||
|
||||
```text
|
||||
Channel
|
||||
|
|
||||
v
|
||||
Channel Gateway
|
||||
|
|
||||
v
|
||||
Agent Gateway
|
||||
| governance / auth / rate limit / metadata
|
||||
v
|
||||
Agent backend
|
||||
|
|
||||
+--> Routing / stickiness / intent
|
||||
|
|
||||
+--> State / memory / checkpoint
|
||||
|
|
||||
+--> Guardrails / judges
|
||||
|
|
||||
+--> Workflow / transaction policies
|
||||
|
|
||||
+--> MCP Gateway
|
||||
|
|
||||
+--> MCP Server A --> legacy system
|
||||
+--> MCP Server B --> external service
|
||||
+--> MCP Server C --> domain API
|
||||
```
|
||||
|
||||
Not every deployment must use every component. Composition follows agent needs and platform contracts.
|
||||
|
||||
### Agent runtime
|
||||
|
||||
The current runtime is based on `AgentRuntimeMixin` and `RuntimeContext`.
|
||||
|
||||
The template imports runtime through `app.agents.runtime`, which re-exports the official framework implementation. This prevents each agent from maintaining a divergent copy.
|
||||
|
||||
Current APIs confirmed in this version include:
|
||||
|
||||
```python
|
||||
AgentRuntimeMixin.get_runtime_context()
|
||||
AgentRuntimeMixin.normalize_tools_by_intent()
|
||||
AgentRuntimeMixin.build_tool_arguments()
|
||||
AgentRuntimeMixin.execute_tools_for_intent()
|
||||
AgentRuntimeMixin.prepare_memory_context()
|
||||
AgentRuntimeMixin.build_messages()
|
||||
AgentRuntimeMixin.transaction_state_patch()
|
||||
AgentRuntimeMixin.transaction_clarification_message()
|
||||
AgentRuntimeMixin.transaction_confirmation_message()
|
||||
AgentRuntimeMixin.build_direct_mcp_answer()
|
||||
```
|
||||
|
||||
Developers should prefer these runtime capabilities instead of rebuilding equivalent logic inside each agent.
|
||||
|
||||
### Configuration versus code
|
||||
|
||||
A core framework principle is to keep selectable behavior in configuration.
|
||||
|
||||
Examples:
|
||||
|
||||
- agents and metadata: `config/agents.yaml`;
|
||||
- routing: `config/routing.yaml`;
|
||||
- tools: `config/tools.yaml`;
|
||||
- MCP Servers and mappings: corresponding MCP configuration;
|
||||
- LLM profiles: `llm_profiles.yaml`;
|
||||
- policies and extensions: capability-specific configuration.
|
||||
|
||||
Code implements mechanisms. YAML/config selects behavior whenever this can be done without weakening safety or contracts.
|
||||
|
||||
### Framework versus agent responsibility
|
||||
|
||||
A change belongs to the **framework** when it introduces a mechanism reusable by multiple agents.
|
||||
|
||||
A change belongs to the **agent** when it expresses company/domain behavior.
|
||||
|
||||
If the core must import a concrete agent module to work, that boundary is probably broken.
|
||||
|
||||
### State, memory and checkpoint are different concepts
|
||||
|
||||
**Execution state** represents what is happening in the turn/workflow.
|
||||
|
||||
**Conversation memory** preserves conversational context.
|
||||
|
||||
**Long-Term Memory** stores durable facts associated with business identity.
|
||||
|
||||
**Checkpointing** persists LangGraph state snapshots for resume.
|
||||
|
||||
An old checkpoint alone must not determine which transaction is active. Functional decisions should use canonical transaction state.
|
||||
|
||||
### Routing and execution are separate responsibilities
|
||||
|
||||
Routing answers: **which agent/intent should handle the message?**
|
||||
|
||||
Execution answers: **what should that agent do now?**
|
||||
|
||||
Route stickiness preserves continuity but must not block an explicit intent change. During a transaction, expected parameters and valid confirmation have precedence to avoid false intent shifts.
|
||||
|
||||
See [Routing, Stickiness and Intent Shift](./02_routing_stickiness_and_intent_shift.md).
|
||||
|
||||
### Tools and MCP
|
||||
|
||||
A tool is an invokable capability.
|
||||
|
||||
An MCP Server implements or exposes that capability.
|
||||
|
||||
The MCP Gateway organizes catalog, authorization, mapping and centralized execution.
|
||||
|
||||
The agent decides **when** a tool is needed; MCP determines **how** the corresponding service is accessed.
|
||||
|
||||
See [MCP, Tools, Policies and Parameter Extraction](./04_mcp_integration_tools_and_policies.md).
|
||||
|
||||
### Transactions
|
||||
|
||||
Side-effecting operations require different handling from read-only queries.
|
||||
|
||||
The framework provides state, confirmation, policy and deterministic workflow mechanisms. Concrete domain rules remain in the agent.
|
||||
|
||||
An LLM may participate in interpretation and composition, but it must not be the sole source of truth for claiming that a critical operation was executed.
|
||||
|
||||
See [Transactional Workflows and State](./03_transaction_workflows_and_state.md).
|
||||
|
||||
### Guardrails and judges
|
||||
|
||||
The core provides native mechanisms and extension points. Domain-specific guardrails/judges belong to the agent and should be loaded through configuration rather than hardcoded imports inside the core.
|
||||
|
||||
See [Guardrails, Judges and Transaction Evaluation](./06_guardrails_judges_and_transaction_evaluation.md).
|
||||
|
||||
### RAG, memory and tools are not interchangeable
|
||||
|
||||
- **RAG** retrieves knowledge.
|
||||
- **Memory** preserves context/facts.
|
||||
- **Tools** query or execute external capabilities.
|
||||
|
||||
Using the wrong mechanism creates difficult-to-diagnose behavior.
|
||||
|
||||
### Observability as a cross-cutting contract
|
||||
|
||||
Routing, agent, transaction, tool, guardrail, judge and failure events must be correlatable.
|
||||
|
||||
Observability records what happened; it must not become business-state control.
|
||||
|
||||
See [Observability, Persistence and Operational Readiness](./11_observability_persistence_and_operational_readiness.md).
|
||||
|
||||
### Where a new feature belongs
|
||||
|
||||
Before implementing a feature, ask:
|
||||
|
||||
1. Is it reusable by multiple agents?
|
||||
2. Does it contain domain-specific rules?
|
||||
3. Does it require state across turns?
|
||||
4. Does it produce side effects?
|
||||
5. Does it depend on an external system?
|
||||
6. Should it be configurable?
|
||||
7. Must it be observable?
|
||||
8. Must a guardrail/judge evaluate it?
|
||||
|
||||
A reusable capability normally starts in the core and is enabled/configured by the agent. A business rule normally starts in the agent and uses core interfaces.
|
||||
|
||||
### Anti-patterns
|
||||
|
||||
Avoid:
|
||||
|
||||
- importing a concrete agent package inside the core;
|
||||
- duplicating `AgentRuntimeMixin` per agent;
|
||||
- hardcoding agent, intent, tool or company names in runtime;
|
||||
- treating LLM output as proof of operation execution;
|
||||
- treating an old checkpoint as the active transaction;
|
||||
- executing transactional operations without required policy/confirmation;
|
||||
- directly coupling agents to many services when MCP Gateway is the intended layer;
|
||||
- creating a new functional document for every bug fix instead of updating the feature manual.
|
||||
|
||||
### Recommended path for a new developer
|
||||
|
||||
1. Read this architecture overview.
|
||||
2. Follow [`README_en.md`](../../../README_en.md) end to end.
|
||||
3. Use the specialized manual when reaching a specific capability.
|
||||
4. For failures, start from the [Developer Index](./INDEX_DEVELOPER_GUIDE.md), under **Search by problem**.
|
||||
5. Before copying historical code, confirm the API/import in the current template and core.
|
||||
|
||||
### Related documents
|
||||
|
||||
- [Main tutorial — README_en.md](../../../README_en.md)
|
||||
- [Routing, Stickiness and Intent Shift](./02_routing_stickiness_and_intent_shift.md)
|
||||
- [Transactional Workflows and State](./03_transaction_workflows_and_state.md)
|
||||
- [MCP, Tools, Policies and Parameters](./04_mcp_integration_tools_and_policies.md)
|
||||
- [Gateways and Authentication](./05_agent_gateway_mcp_gateway_and_auth.md)
|
||||
- [Guardrails and Judges](./06_guardrails_judges_and_transaction_evaluation.md)
|
||||
- [RAG and BusinessContext](./07_rag_business_context_and_grounding.md)
|
||||
- [Long-Term Memory and Checkpoint](./08_long_term_memory_and_checkpoint.md)
|
||||
- [LLM Rich Response](./09_llm_rich_response_reasoning.md)
|
||||
- [Performance, Cache and Async Runtime](./10_performance_cache_and_async_runtime.md)
|
||||
- [Observability and Operational Readiness](./11_observability_persistence_and_operational_readiness.md)
|
||||
828
docs/developer/en/02_routing_stickiness_and_intent_shift.md
Normal file
828
docs/developer/en/02_routing_stickiness_and_intent_shift.md
Normal file
@@ -0,0 +1,828 @@
|
||||
|
||||
### Routing, Route Stickiness and Intent Shift
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **routing, stickiness, intent shifts, deterministic/LLM routing and multi-agent isolation**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Routing, stickiness, intent shifts, deterministic/llm routing and multi-agent isolation.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### Multi-Agent Routing, Route Stickiness and Intent Shift
|
||||
|
||||
This guide defines how the platform selects an agent, preserves continuity and handles an explicit change of intent without trapping the user in the previous route.
|
||||
|
||||
### Routing modes
|
||||
|
||||
The template supports two architectural modes. **Enterprise Router** performs a routing decision and invokes the selected agent. **Supervisor** uses a supervisor node to coordinate the next agent. The mode is configuration-driven; domain agents should not reimplement routing infrastructure.
|
||||
|
||||
### Enterprise routing decision order
|
||||
|
||||
Routing should use the cheapest reliable signal first. Deterministic mappings/signals may resolve known intents. If deterministic discovery does not produce a valid route and LLM routing is enabled, the router can ask the configured routing model. This keeps LLM routing as a semantic capability without forcing every turn through an LLM.
|
||||
|
||||
### Semantic route stickiness
|
||||
|
||||
Route stickiness is a lightweight session-control classification executed before normal routing. It can return:
|
||||
|
||||
- `CONTINUE`: keep the active agent.
|
||||
- `ROUTE`: execute normal Enterprise Router logic.
|
||||
- `HUMAN_HANDOFF`: enter the global human-handoff node.
|
||||
- `END_SESSION`: enter the global session-ending node.
|
||||
|
||||
The classifier does not answer the user and does not call tools. Low confidence, timeout, invalid JSON or classifier failure falls back to normal routing. `CONTINUE` is valid only when there is an active agent; otherwise it is treated as `ROUTE`.
|
||||
|
||||
### Configuration
|
||||
|
||||
```env
|
||||
ENABLE_ROUTE_STICKINESS=true
|
||||
ROUTE_STICKINESS_LLM_PROFILE=route_continuity
|
||||
ROUTE_STICKINESS_CONFIDENCE_THRESHOLD=0.90
|
||||
ROUTE_STICKINESS_HISTORY_TURNS=2
|
||||
ROUTE_STICKINESS_MAX_TOKENS=80
|
||||
HUMAN_HANDOFF_MESSAGE=I will transfer your interaction to a person.
|
||||
END_SESSION_MESSAGE=Interaction ended. Thank you.
|
||||
```
|
||||
|
||||
Example lightweight profile:
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
route_continuity:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1-mini
|
||||
temperature: 0
|
||||
max_tokens: 80
|
||||
timeout_seconds: 5
|
||||
```
|
||||
|
||||
Use the smallest approved model that reliably classifies continuity in the target environment.
|
||||
|
||||
### Why deterministic intent shift still exists
|
||||
|
||||
Semantic stickiness cannot be allowed to suppress an explicit user request that clearly targets a different operation. Recent fixes introduced deterministic preemption for unequivocal intent changes before invoking the continuity LLM. This is a performance and correctness optimization, not a replacement for semantic routing.
|
||||
|
||||
Typical examples include moving from an informational query to a transactional action or from one tool-backed operation to another within the same agent.
|
||||
|
||||
### Routing precedence during an open transaction
|
||||
|
||||
An open transaction changes precedence. If the transaction is waiting for a required parameter and the user's message supplies that parameter, parameter extraction/merge wins over intent-shift detection. If the transaction is waiting for confirmation and the user provides an accepted confirmation/rejection, the transaction state machine wins. Only a genuinely explicit unrelated request should interrupt/reroute according to policy.
|
||||
|
||||
This prevents values such as a price, invoice identifier or product name from being mistaken for a new intent.
|
||||
|
||||
### Global session-control contracts
|
||||
|
||||
Human handoff should set a route/intent representing handoff, mark the request in metadata/state and emit the corresponding observability event. Selecting the actual human queue or platform remains an external channel/integration responsibility.
|
||||
|
||||
End-session should mark the session as ended and emit the global event. Physically closing an SSE/HTTP/voice/WhatsApp connection and applying TTL/expiration policy remains the responsibility of the channel/backend.
|
||||
|
||||
### Failure behavior
|
||||
|
||||
- No active agent + `CONTINUE` → route normally.
|
||||
- Low classifier confidence → route normally.
|
||||
- Classifier timeout/error/invalid output → route normally.
|
||||
- Explicit deterministic intent shift → do not let stickiness override it.
|
||||
- Valid transaction parameter/confirmation → continue transaction before rerouting.
|
||||
|
||||
### Testing
|
||||
|
||||
Regression coverage should include continuity, domain change, first-turn handoff, first-turn end-session, low confidence, invalid model output, no active agent, explicit intent shift within the same agent, informational→transactional shift and active-transaction parameter precedence.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If the route never changes, inspect the active agent, route-stickiness decision/confidence, deterministic intent-shift signal and current transaction state. If every turn reroutes, verify that the active-agent/session state is being persisted and that the continuity classifier receives the configured history. If routing makes unnecessary LLM calls, verify deterministic discovery/intent-shift is enabled before semantic fallback.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `Documentacao/Manual de Roteamento Multi-Agent.docx`
|
||||
- `Documentacao/Route_Stickiness_Semantica_Agent_Framework_OCI.docx`
|
||||
- `Documentacao/README_ROUTING_MODES.md`
|
||||
- `Documentacao/README_ENTERPRISE_ROUTING.md`
|
||||
- intent-shift release notes and route-stickiness test results under `Documentacao/`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### Semantic route stickiness reference
|
||||
|
||||
> Consolidated from `Documentacao/README_SEMANTIC_ROUTE_STICKINESS.md`.
|
||||
|
||||
### Purpose
|
||||
|
||||
This optional capability uses a lightweight LLM profile and no regex, phrase lists, or domain-specific language rules. It classifies each turn as:
|
||||
|
||||
- `CONTINUE`: keep the active agent;
|
||||
- `ROUTE`: run the regular Enterprise Router;
|
||||
- `HUMAN_HANDOFF`: request human assistance;
|
||||
- `END_SESSION`: finish the automated session.
|
||||
|
||||
The classifier does not answer the user, execute tools, or implement domain rules. Human handoff and session ending are handled by global graph nodes.
|
||||
|
||||
### Flow
|
||||
|
||||
```text
|
||||
Incoming turn
|
||||
-> lightweight semantic classifier
|
||||
CONTINUE + active agent -> active agent
|
||||
ROUTE / low confidence / error -> Enterprise Router
|
||||
HUMAN_HANDOFF -> human_handoff node
|
||||
END_SESSION -> end_session node
|
||||
```
|
||||
|
||||
`CONTINUE` is converted to `ROUTE` when there is no active agent. Global session actions can be detected on the first turn.
|
||||
|
||||
### Configuration
|
||||
|
||||
```dotenv
|
||||
ENABLE_ROUTE_STICKINESS=true
|
||||
ROUTE_STICKINESS_LLM_PROFILE=route_continuity
|
||||
ROUTE_STICKINESS_CONFIDENCE_THRESHOLD=0.90
|
||||
ROUTE_STICKINESS_HISTORY_TURNS=2
|
||||
ROUTE_STICKINESS_MAX_TOKENS=80
|
||||
HUMAN_HANDOFF_MESSAGE=I will transfer your request to a person.
|
||||
END_SESSION_MESSAGE=The session has ended. Thank you for contacting us.
|
||||
```
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
route_continuity:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1-mini
|
||||
temperature: 0
|
||||
max_tokens: 80
|
||||
timeout_seconds: 5
|
||||
```
|
||||
|
||||
Use the smallest approved model available in the target OCI environment.
|
||||
|
||||
### Human handoff contract
|
||||
|
||||
The router returns route `human_handoff`, intent `human_handoff`, `handoff=true`, and metadata `session_control=HUMAN_HANDOFF`. The graph node sets:
|
||||
|
||||
- `human_handoff_requested=true`;
|
||||
- `session_ended=false`;
|
||||
- `next_state=HUMAN_HANDOFF_REQUESTED`.
|
||||
|
||||
It emits `session.human_handoff.requested`. The customer integration remains responsible for choosing the human queue and protocol.
|
||||
|
||||
### End-session contract
|
||||
|
||||
The router returns route `end_session`, intent `end_session`, and metadata `session_control=END_SESSION`. The graph node sets:
|
||||
|
||||
- `session_ended=true`;
|
||||
- `human_handoff_requested=false`;
|
||||
- `next_state=SESSION_ENDED`.
|
||||
|
||||
It emits `session.end.requested`. Channel-specific session expiration or connection closing remains an integration responsibility.
|
||||
|
||||
### Safety behavior
|
||||
|
||||
- Only decisions above the configured confidence threshold are accepted.
|
||||
- Invalid JSON, timeout, low confidence, or errors fall back to the Enterprise Router.
|
||||
- Human handoff and session ending do not execute domain agents or MCP tools.
|
||||
- The classifier never selects a human queue and never physically closes a channel connection.
|
||||
|
||||
### Tests
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=libs/agent_framework/src pytest -q tests/unit/test_semantic_route_stickiness.py
|
||||
```
|
||||
|
||||
The suite covers CONTINUE, ROUTE, low confidence, invalid output, HUMAN_HANDOFF, END_SESSION, first-turn global actions, and CONTINUE without an active agent.
|
||||
|
||||
### Runtime routing responsibilities
|
||||
|
||||
> Consolidated from `specs/SPEC-002-Agent-Runtime.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O Agent Runtime executa o ciclo de vida conversacional do agente. A execução inclui normalização de contexto, estado LangGraph, memória, checkpoint, roteamento, supervisor, guardrails, MCP, RAG, LLM, judges, persistência e resposta final.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Workflow Builder | Compila o grafo LangGraph. |
|
||||
| State Manager | Mantém o estado de execução. |
|
||||
| Session Manager | Resolve sessão e conversation_key. |
|
||||
| Memory Manager | Carrega e persiste histórico. |
|
||||
| Checkpoint Manager | Persiste estado LangGraph. |
|
||||
| Input Guardrail Node | Executa guardrails de entrada. |
|
||||
| Router Node | Decide rota/intent. |
|
||||
| Supervisor Node | Decide handoff ou próximo agente quando habilitado. |
|
||||
| Agent Node | Executa agente de domínio. |
|
||||
| MCP Client/Router | Executa tools por contrato. |
|
||||
| RAG Service | Recupera contexto documental. |
|
||||
| Output Supervisor | Revisa resposta antes de saída. |
|
||||
| Output Guardrail Node | Executa guardrails de saída. |
|
||||
| Judge Node | Avalia resposta. |
|
||||
| Persistence Node | Persiste mensagens, memória e checkpoint. |
|
||||
|
||||
### State Model
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
context: dict
|
||||
business_context: dict
|
||||
tool_arguments: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
rag_metadata: dict
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
metadata: dict
|
||||
errors: list[dict]
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[start] --> B[input_guardrails]
|
||||
B --> C[routing_decision]
|
||||
C --> D[agent_execution]
|
||||
D --> E[output_supervisor]
|
||||
E --> F[output_guardrails]
|
||||
F --> G[judge]
|
||||
G --> H[persist]
|
||||
H --> I[end]
|
||||
C --> J[handoff]
|
||||
J --> C
|
||||
```
|
||||
|
||||
### Nós
|
||||
|
||||
| Nó | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| `input_guardrails` | `user_text`, `context` | `sanitized_input`, `guardrails` |
|
||||
| `routing_decision` | `sanitized_input`, `business_context` | `route`, `intent`, `mcp_tools` |
|
||||
| `agent_execution` | `state` completo | `response_text`, `mcp_results`, `rag_metadata` |
|
||||
| `output_supervisor` | `response_text` | `response_text` revisado |
|
||||
| `output_guardrails` | `response_text` | `response_text`, `guardrails` |
|
||||
| `judge` | `response_text`, evidências | `judges` |
|
||||
| `persist` | `state` completo | checkpoint, memória, mensagens |
|
||||
|
||||
### Router
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
mode: router
|
||||
fallback_agent: billing_agent
|
||||
enable_llm_router: false
|
||||
intents:
|
||||
billing_invoice_explanation:
|
||||
route: billing_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- cobrança
|
||||
- boleto
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
|
||||
```yaml
|
||||
supervisor:
|
||||
enabled: true
|
||||
profile: supervisor
|
||||
max_turns: 5
|
||||
handoff_enabled: true
|
||||
fallback_route: support_agent
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
| Provider | Uso |
|
||||
|---|---|
|
||||
| `memory` | Execução local e testes. |
|
||||
| `sqlite` | Desenvolvimento local persistente. |
|
||||
| `mongodb` | Checkpoint e histórico em ambiente distribuído. |
|
||||
| `autonomous` | Produção com Oracle Autonomous Database. |
|
||||
|
||||
### Checkpoints
|
||||
|
||||
Checkpoint contém:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_key": "default:telecom_contas:session-001",
|
||||
"checkpoint_id": "ckpt-001",
|
||||
"state": {},
|
||||
"pending_writes": [],
|
||||
"created_at": "2026-06-19T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Formato entregue ao LangGraph:
|
||||
|
||||
```python
|
||||
pending_writes: list[tuple[str, str, object]]
|
||||
```
|
||||
|
||||
### Business Context
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### Ordem de Prioridade dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AgentNode --> ToolList[mcp_tools]
|
||||
ToolList --> Mapping[mcp_parameter_mapping.yaml]
|
||||
Mapping --> MCP[MCP Gateway/Router]
|
||||
MCP --> Result[mcp_results]
|
||||
```
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```yaml
|
||||
rag:
|
||||
enabled: true
|
||||
namespace_strategy: agent_id
|
||||
top_k: 5
|
||||
profile_generation: rag_generation
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `runtime.started` | Execução iniciada. |
|
||||
| `runtime.session.loaded` | Sessão carregada. |
|
||||
| `runtime.memory.loaded` | Memória carregada. |
|
||||
| `runtime.checkpoint.loaded` | Checkpoint carregado. |
|
||||
| `runtime.route.selected` | Rota selecionada. |
|
||||
| `runtime.agent.started` | Agente iniciado. |
|
||||
| `runtime.agent.completed` | Agente concluído. |
|
||||
| `runtime.persist.completed` | Persistência concluída. |
|
||||
| `runtime.failed` | Falha controlada. |
|
||||
|
||||
### Erros
|
||||
|
||||
| Código | Condição | Tratamento |
|
||||
|---|---|---|
|
||||
| `RUNTIME_INVALID_REQUEST` | GatewayRequest inválido | 422 |
|
||||
| `RUNTIME_ROUTE_NOT_FOUND` | Nenhuma rota elegível | fallback ou resposta controlada |
|
||||
| `RUNTIME_CHECKPOINT_ERROR` | Falha em checkpoint | retry ou stateless conforme config |
|
||||
| `RUNTIME_MEMORY_ERROR` | Falha em memória | retry ou resposta controlada |
|
||||
| `RUNTIME_AGENT_ERROR` | Falha no agente | NOC + fallback |
|
||||
| `RUNTIME_TIMEOUT` | Timeout geral | resposta controlada |
|
||||
|
||||
|
||||
|
||||
### Contrato Durável de Estado Transacional
|
||||
|
||||
Hosts que utilizam `AgentRuntime` com transações multi-turno DEVEM declarar no `AgentState` os campos `active_transaction` e `last_transaction`. O primeiro é a fonte canônica da transação em andamento e deve sobreviver a checkpoint/resume; o segundo mantém o snapshot da última transação terminal.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
`selected_tool_call` e `pending_tool_call` são campos auxiliares/compatibilidade e não substituem o latch canônico. Durante `COLLECTING_PARAMETERS`, a retomada da transação e o consumo de parâmetros pendentes têm precedência sobre keyword routing genérico. Uma mudança de intenção só deve interromper a transação quando for inequívoca ou explicitamente solicitada pelo usuário.
|
||||
|
||||
O contrato completo, ciclo de vida, precedência de roteamento, checklist e testes regressivos estão em [`docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Runtime recebe GatewayRequest validado.
|
||||
- [ ] State contém tenant_id, agent_id, session_id, conversation_key, route e intent.
|
||||
- [ ] Input guardrails executam antes do roteamento.
|
||||
- [ ] Router ou Supervisor seleciona rota.
|
||||
- [ ] Agent Node executa sem acessar payload bruto de canal.
|
||||
- [ ] MCP é acessado por contrato.
|
||||
- [ ] RAG é acessado por serviço reutilizável.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
- [ ] Judges geram JudgeResult.
|
||||
- [ ] Memória e checkpoint são persistidos conforme provider.
|
||||
- [ ] Hosts transacionais declaram `active_transaction` e `last_transaction` no `AgentState`.
|
||||
- [ ] Durante `COLLECTING_PARAMETERS`, respostas a parâmetros pendentes têm precedência sobre keyword routing genérico.
|
||||
- [ ] Erros geram NOC e resposta controlada.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Governance constraints affecting routing
|
||||
|
||||
> Consolidated from `specs/SPEC-011-Governance-Model.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Governança é o conjunto de papéis, responsabilidades, controles, aprovações, evidências e processos que permite que a Agent Platform OCI seja usada por múltiplos times sem perder padronização, segurança, rastreabilidade e capacidade de evolução.
|
||||
|
||||
A governança não substitui a engenharia. Ela define como a engenharia evolui de forma controlada.
|
||||
|
||||
Em uma plataforma de agentes, governança cobre:
|
||||
|
||||
- quem pode criar agentes;
|
||||
- quem pode alterar prompts;
|
||||
- quem pode liberar MCP tools;
|
||||
- quem aprova mudanças de guardrails;
|
||||
- quem aprova modelos;
|
||||
- quem aprova datasets;
|
||||
- quem promove para produção;
|
||||
- quais evidências são obrigatórias;
|
||||
- como auditar decisões da plataforma.
|
||||
|
||||
### 2. Problema que resolve
|
||||
|
||||
Sem governança, cada time tende a criar agentes de forma diferente.
|
||||
|
||||
Problemas comuns:
|
||||
|
||||
- prompts sem versionamento;
|
||||
- MCP tools sem owner;
|
||||
- datasets ausentes;
|
||||
- agentes sem avaliação;
|
||||
- produção sem certification;
|
||||
- mudanças de modelo sem rastreabilidade;
|
||||
- guardrails duplicados;
|
||||
- regras de negócio dentro do runtime;
|
||||
- uso diferente da plataforma por cada fornecedor;
|
||||
- dificuldade de manutenção.
|
||||
|
||||
A governança cria um modelo único de adoção.
|
||||
|
||||
### 3. Domínios de governança
|
||||
|
||||
| Domínio | Escopo |
|
||||
| --- | --- |
|
||||
| Platform Governance | Framework, Runtime, Gateways, Evaluator, Certification Suite. |
|
||||
| Agent Governance | Agentes, prompts, regras de negócio, datasets e configs. |
|
||||
| Model Governance | LLM profiles, providers, fallback, custo e uso. |
|
||||
| MCP Governance | Tools, MCP servers, owners, SLAs, autorização e contratos. |
|
||||
| Data Governance | BusinessContext, RAG, datasets, memória e retenção. |
|
||||
| Security Governance | Identidade, autorização, secrets, auditoria e PII. |
|
||||
| Operational Governance | Deploy, monitoramento, alertas, SLOs e incidentes. |
|
||||
| Evaluation Governance | Judges, evaluator, certification e métricas. |
|
||||
|
||||
|
||||
### 4. Modelo de ownership
|
||||
|
||||
### 4.1. Platform Team
|
||||
|
||||
Responsável por:
|
||||
|
||||
- Agent Framework;
|
||||
- Agent Runtime;
|
||||
- Agent Gateway;
|
||||
- Channel Gateway;
|
||||
- AI Gateway;
|
||||
- MCP Gateway;
|
||||
- Evaluator;
|
||||
- Certification Suite;
|
||||
- contratos canônicos;
|
||||
- documentação da plataforma;
|
||||
- templates oficiais.
|
||||
|
||||
### 4.2. Domain Team
|
||||
|
||||
Responsável por:
|
||||
|
||||
- comportamento do agente;
|
||||
- prompts;
|
||||
- regras de negócio;
|
||||
- datasets;
|
||||
- configurações específicas;
|
||||
- validação funcional;
|
||||
- critérios de sucesso.
|
||||
|
||||
### 4.3. Integration Team
|
||||
|
||||
Responsável por:
|
||||
|
||||
- MCP servers;
|
||||
- APIs externas;
|
||||
- SLAs de tools;
|
||||
- contratos de integração;
|
||||
- credenciais de backend;
|
||||
- disponibilidade de sistemas externos.
|
||||
|
||||
### 4.4. SRE / DevOps
|
||||
|
||||
Responsável por:
|
||||
|
||||
- CI/CD;
|
||||
- deploy;
|
||||
- observabilidade;
|
||||
- alertas;
|
||||
- capacidade;
|
||||
- SLOs;
|
||||
- runbooks;
|
||||
- rollback.
|
||||
|
||||
### 4.5. Security / Architecture
|
||||
|
||||
Responsável por:
|
||||
|
||||
- segurança;
|
||||
- arquitetura;
|
||||
- policies;
|
||||
- Workload Identity;
|
||||
- secrets;
|
||||
- revisão de risco;
|
||||
- aprovação de exceções.
|
||||
|
||||
### 5. RACI
|
||||
|
||||
| Atividade | Platform | Domain | Integration | SRE | Security |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Framework change | R/A | C | I | C | C |
|
||||
| Runtime change | R/A | C | I | C | C |
|
||||
| New agent | C | R/A | C | I | I |
|
||||
| New MCP tool | C | C | R/A | I | C |
|
||||
| Prompt change | I | R/A | I | I | C |
|
||||
| Guardrail change | R | C | I | I | A |
|
||||
| Model profile change | R | C | I | I | C |
|
||||
| Production deploy | I | C | C | R/A | C |
|
||||
| Security review | I | C | C | C | R/A |
|
||||
| Certification | R/A | C | C | I | I |
|
||||
|
||||
|
||||
### 6. Governança de agentes
|
||||
|
||||
Todo agente deve possuir:
|
||||
|
||||
```yaml
|
||||
agent:
|
||||
id: telecom_contas
|
||||
owner: billing_team
|
||||
technical_owner: ai_platform_team
|
||||
business_objective: "Atendimento sobre faturas, pagamentos e cobranças"
|
||||
status: active
|
||||
version: 1.0.0
|
||||
```
|
||||
|
||||
Artefatos obrigatórios:
|
||||
|
||||
- `agents.yaml`;
|
||||
- `routing.yaml`;
|
||||
- `prompt_policy.yaml`;
|
||||
- `guardrails.yaml`;
|
||||
- `judges.yaml`;
|
||||
- `tools.yaml`;
|
||||
- `mcp_parameter_mapping.yaml`;
|
||||
- dataset de regressão;
|
||||
- testes;
|
||||
- evidências de evaluator;
|
||||
- evidências de certification.
|
||||
|
||||
### 7. Governança de prompts
|
||||
|
||||
Prompts devem ser versionados e rastreáveis.
|
||||
|
||||
```yaml
|
||||
prompt:
|
||||
name: billing_system_prompt
|
||||
version: 1.3.0
|
||||
owner: billing_team
|
||||
reviewed_at: 2026-06-19
|
||||
status: approved
|
||||
```
|
||||
|
||||
Mudanças de prompt exigem:
|
||||
|
||||
1. revisão do domain owner;
|
||||
2. execução de dataset;
|
||||
3. evaluator;
|
||||
4. comparação contra baseline;
|
||||
5. registro da versão.
|
||||
|
||||
### 8. Governança de guardrails
|
||||
|
||||
Guardrails globais pertencem à plataforma/segurança.
|
||||
|
||||
Guardrails por agente pertencem ao domínio, mas precisam seguir o contrato da plataforma.
|
||||
|
||||
```yaml
|
||||
guardrail:
|
||||
code: REVPREC
|
||||
version: 2.0.0
|
||||
owner: platform_security
|
||||
phase: output
|
||||
mode: enforce
|
||||
```
|
||||
|
||||
Mudanças em guardrails `enforce` exigem certification.
|
||||
|
||||
### 9. Governança de judges
|
||||
|
||||
Judges devem ter objetivo, métrica, threshold e owner.
|
||||
|
||||
```yaml
|
||||
judge:
|
||||
name: groundedness
|
||||
version: 1.1.0
|
||||
threshold: 0.70
|
||||
owner: platform_quality
|
||||
```
|
||||
|
||||
Mudanças de threshold exigem reexecução do evaluator.
|
||||
|
||||
### 10. Governança de modelos
|
||||
|
||||
Agentes não referenciam modelo diretamente.
|
||||
|
||||
O modelo é resolvido por profile.
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
judge:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1
|
||||
temperature: 0
|
||||
```
|
||||
|
||||
Mudanças de modelo exigem:
|
||||
|
||||
- validação de custo;
|
||||
- evaluator;
|
||||
- validação de qualidade;
|
||||
- validação de latência;
|
||||
- atualização de release notes.
|
||||
|
||||
### 11. Governança de MCP
|
||||
|
||||
Cada tool deve ter owner, SLA, timeout e contrato.
|
||||
|
||||
```yaml
|
||||
tool:
|
||||
name: consultar_fatura
|
||||
version: 1.0.0
|
||||
owner: billing_platform
|
||||
sla: p95_2s
|
||||
timeout_seconds: 30
|
||||
idempotent: true
|
||||
```
|
||||
|
||||
Tools mutáveis exigem política de confirmação.
|
||||
|
||||
### 12. Governança de datasets
|
||||
|
||||
Datasets são ativos de qualidade.
|
||||
|
||||
```yaml
|
||||
dataset:
|
||||
name: telecom_contas_regression
|
||||
version: 1.0.0
|
||||
owner: billing_team
|
||||
```
|
||||
|
||||
Datasets devem conter:
|
||||
|
||||
- entrada;
|
||||
- BusinessContext;
|
||||
- rota esperada;
|
||||
- tools esperadas;
|
||||
- critérios mínimos;
|
||||
- casos negativos;
|
||||
- casos de segurança.
|
||||
|
||||
### 13. Processo de aprovação
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Dev[Development] --> Tests[Tests]
|
||||
Tests --> Eval[Evaluator]
|
||||
Eval --> Cert[Certification]
|
||||
Cert --> Sec[Security Review]
|
||||
Sec --> Arch[Architecture Approval]
|
||||
Arch --> HML[Homologation]
|
||||
HML --> PROD[Production]
|
||||
```
|
||||
|
||||
### 14. Evidências obrigatórias
|
||||
|
||||
- relatório de testes;
|
||||
- relatório evaluator;
|
||||
- relatório certification;
|
||||
- trace Langfuse;
|
||||
- logs e métricas;
|
||||
- checklist de segurança;
|
||||
- release notes;
|
||||
- versão dos artefatos.
|
||||
|
||||
### 15. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Prompt sem owner | Dificulta manutenção e aprovação. | Definir owner no metadata. |
|
||||
| Tool sem SLA | Operação sem expectativa de resposta. | Registrar SLA em tools.yaml. |
|
||||
| Dataset ausente | Sem regressão objetiva. | Criar dataset mínimo. |
|
||||
| Guardrail hardcoded | Governança fora do YAML. | Mover para config. |
|
||||
| Modelo definido no agente | Quebra governança de modelos. | Usar AI Gateway profiles. |
|
||||
|
||||
|
||||
### 16. Critérios de aceite
|
||||
|
||||
- [ ] Cada agente possui owner funcional e técnico.
|
||||
- [ ] Prompts estão versionados.
|
||||
- [ ] Tools MCP possuem owner, SLA e versão.
|
||||
- [ ] Guardrails possuem owner e modo.
|
||||
- [ ] Judges possuem threshold e versão.
|
||||
- [ ] Datasets estão versionados.
|
||||
- [ ] Evaluator roda por agente.
|
||||
- [ ] Certification aprova antes de produção.
|
||||
- [ ] Release possui evidências.
|
||||
- [ ] Exceções são documentadas.
|
||||
830
docs/developer/en/03_transaction_workflows_and_state.md
Normal file
830
docs/developer/en/03_transaction_workflows_and_state.md
Normal file
@@ -0,0 +1,830 @@
|
||||
|
||||
### Transactional Workflows and State
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **transaction state, parameter collection, confirmation, pause/resume and execution evidence**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Transaction state, parameter collection, confirmation, pause/resume and execution evidence.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### Transaction Workflows, Multi-turn State and Resume
|
||||
|
||||
This guide is the canonical developer reference for side-effecting multi-turn operations.
|
||||
|
||||
### Why a deterministic transaction engine exists
|
||||
|
||||
A general-purpose LLM is useful for language understanding and composition, but it should not own the sequence of critical side effects. The framework therefore supports an optional deterministic LangGraph workflow engine. Domain YAML/actions stay with the agent; the framework supplies reusable orchestration and state semantics. Legacy direct-tool execution remains available for agents that have not opted into workflows.
|
||||
|
||||
### Canonical transaction state
|
||||
|
||||
The transaction object is the source of truth for the active operation. It should explicitly represent the current operation/tool/workflow, collected parameters, missing parameters, confirmation requirement/status, execution result/evidence and lifecycle status such as collecting, awaiting confirmation, executing, completed, failed or cancelled.
|
||||
|
||||
Checkpoint persistence is not a substitute for transaction state. A checkpoint may contain historical graph state; the runtime must still identify the canonical active transaction before resuming anything.
|
||||
|
||||
### Parameter merge
|
||||
|
||||
Parameter collection is incremental. Existing valid parameters remain in the transaction and newly extracted parameters are merged. The runtime must not discard previously collected values just because the latest message contains only one missing field.
|
||||
|
||||
When the user supplies a value expected by the active transaction, that parameter is processed before generic intent-shift routing. This is essential for natural language such as a bare amount, date, invoice id or service name.
|
||||
|
||||
### Confirmation
|
||||
|
||||
A transactional policy may require explicit confirmation. The workflow enters an awaiting-confirmation state and must not invoke the side-effecting MCP tool until confirmation is accepted. Rejection cancels/abandons the operation according to the workflow policy. Unrelated messages may be evaluated for intent shift instead of being coerced into confirmation.
|
||||
|
||||
### Pause and resume
|
||||
|
||||
A paused workflow resumes from persisted state and the next valid node. Resume logic must verify the active transaction rather than reopening every historical transaction found in checkpoints. Closed/completed/cancelled transactions remain closed.
|
||||
|
||||
### Operational evidence
|
||||
|
||||
Logical `COMPLETED` state alone is not proof that the external action succeeded. The final state and response should be grounded in execution evidence such as MCP results, returned operation/protocol identifiers or an explicit successful tool result. The framework distinguishes intent to execute, attempted execution and confirmed success.
|
||||
|
||||
### Framework versus agent ownership
|
||||
|
||||
The framework owns generic lifecycle/state handling, confirmation plumbing, pause/resume mechanics and tool-policy integration. The agent owns the business workflow definition, parameter descriptions, domain validation and tool/action mapping.
|
||||
|
||||
### Minimum regression matrix
|
||||
|
||||
Test at least: one-parameter collection, multiple parameters across turns, multiple parameters in one sentence, confirmation accept/reject, unrelated message during confirmation, parameter value that resembles an intent, pause/resume, backend restart, completed transaction followed by a new request, explicit transaction interruption, MCP success, MCP error/timeout and no-evidence failure.
|
||||
|
||||
### Common anti-patterns
|
||||
|
||||
Do not derive active transaction from checkpoint existence alone. Do not reset the full parameter map on each turn. Do not let route stickiness consume a valid transaction parameter. Do not mark success before receiving external evidence. Do not hardcode domain parameter names in shared transaction code.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`
|
||||
- `docs/ADR_TRANSACTIONAL_WORKFLOW_ENGINE.md`
|
||||
- `Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md`
|
||||
- `FIX_TRANSACTION_PARAMETER_PRECEDENCE.md`
|
||||
- `FIX_TRANSACTION_INTENT_LOOP.md`
|
||||
- `docs/TRANSACTION_OPERATIONAL_EVIDENCE_FIX.md`
|
||||
- `Documentacao/VALIDACAO_TRANSACIONAL_BACKEND_MCP.md`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### Full multi-turn transaction state developer guide
|
||||
|
||||
> Consolidated from `docs/TRANSACTION_STATE_DEVELOPER_GUIDE_en.md`.
|
||||
|
||||
This document defines the operational contract for multi-turn transactions in Agent Framework OCI. It is normative for hosts and templates that use `AgentRuntime`, LangGraph checkpoints, and transactional tools.
|
||||
|
||||
### 1. Goal
|
||||
|
||||
A transaction may span multiple turns:
|
||||
|
||||
```text
|
||||
User: cancel my order
|
||||
Framework: provide the order number
|
||||
User: PED-1001
|
||||
Framework: confirm cancellation?
|
||||
User: yes
|
||||
Framework: execute the tool
|
||||
```
|
||||
|
||||
The framework must preserve the transaction across all turns without relying on LLM reclassification, keyword routing, or re-extraction of parameters already collected.
|
||||
|
||||
### 2. Canonical transaction state
|
||||
|
||||
The canonical in-flight transaction is `active_transaction`.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
Every `AgentState` used by a host that enables multi-turn transactions **MUST** declare both fields. LangGraph uses the state schema for checkpoint persistence, so a field created dynamically by the runtime alone is not a safe durable contract.
|
||||
|
||||
Minimal example:
|
||||
|
||||
```python
|
||||
from typing import Any, TypedDict
|
||||
|
||||
class AgentState(TypedDict, total=False):
|
||||
# ...normal fields...
|
||||
selected_tool_call: dict[str, Any]
|
||||
pending_tool_call: dict[str, Any]
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
transaction_status: str
|
||||
missing_parameters: list[str]
|
||||
confirmation_required: bool
|
||||
confirmation_received: bool
|
||||
```
|
||||
|
||||
### 3. Field responsibilities
|
||||
|
||||
| Field | Responsibility | Rule |
|
||||
|---|---|---|
|
||||
| `active_transaction` | Canonical in-flight transaction | Must survive checkpoint/resume while active. |
|
||||
| `last_transaction` | Snapshot of the latest terminal transaction | Used for audit/evidence; does not automatically reactivate a transaction. |
|
||||
| `transaction_status` | Current logical status | E.g. `COLLECTING_PARAMETERS`, `AWAITING_CONFIRMATION`, `COMPLETED`, `CANCELLED`, `OUT_OF_SCOPE`. |
|
||||
| `missing_parameters` | Parameters still required | Must reflect canonical transaction state, not only the current message. |
|
||||
| `selected_tool_call` | Auxiliary/backward-compatible state | Must not replace `active_transaction` as canonical state. |
|
||||
| `pending_tool_call` | Auxiliary/backward-compatible state | May support compatibility but is not the primary latch. |
|
||||
| `next_state` | Workflow routing guidance | Keeps the correct node/agent during collection/confirmation. |
|
||||
| `transaction_pre_validation` | Pre-validation evidence | Stores validation before confirmation/execution. |
|
||||
| `transaction_evidence` | Execution evidence | Stores results and the transaction execution trail. |
|
||||
|
||||
### 4. Recommended lifecycle
|
||||
|
||||
```text
|
||||
IDLE
|
||||
↓ transactional intent
|
||||
COLLECTING_PARAMETERS
|
||||
↓ complete parameters
|
||||
PRE_VALIDATION (when configured)
|
||||
↓ eligible
|
||||
AWAITING_CONFIRMATION
|
||||
↓ positive confirmation
|
||||
EXECUTING
|
||||
↓
|
||||
COMPLETED
|
||||
```
|
||||
|
||||
Alternative terminal outcomes include `CANCELLED`, `OUT_OF_SCOPE`, and `FAILED`.
|
||||
|
||||
### 5. Incremental parameter merge
|
||||
|
||||
A later answer must complement the existing transaction instead of rebuilding it from the latest text only.
|
||||
|
||||
```python
|
||||
existing = dict((state.get("active_transaction") or {}).get("arguments") or {})
|
||||
new_values = {"amount": "71.99"}
|
||||
arguments = {**existing, **new_values}
|
||||
```
|
||||
|
||||
Previously collected arguments must remain available on subsequent turns.
|
||||
|
||||
### 6. Routing precedence during an active transaction
|
||||
|
||||
When `active_transaction` is in `COLLECTING_PARAMETERS`, the message must first be evaluated as a possible answer to pending parameters.
|
||||
|
||||
Normative precedence:
|
||||
|
||||
1. clearly fills a pending parameter → continue transaction;
|
||||
2. explicit cancel/abandon → cancel transaction;
|
||||
3. unambiguous new intent → interrupt and route;
|
||||
4. generic keyword in the same domain/agent → **do not** interrupt;
|
||||
5. ambiguous message → keep transaction and clarify.
|
||||
|
||||
| Current state | Message | Correct result |
|
||||
|---|---|---|
|
||||
| `retail_order_cancel`, missing `order_id` | `PED-1001` | Continue cancellation and fill `order_id`. |
|
||||
| `retail_order_cancel`, missing `order_id` | `the order is PED-1001` | Continue cancellation; `order` must not switch to tracking. |
|
||||
| contestation, missing `amount` | `R$ 71.99` | Continue contestation and fill amount. |
|
||||
| pending cancellation | `forget it, show my bill` | Explicit interruption is allowed. |
|
||||
| pending cancellation | `track my order` | Unambiguous shift to tracking is allowed. |
|
||||
|
||||
### 7. Checkpoint and resume
|
||||
|
||||
Before normal routing, restore the checkpoint with the same conversation identity (`tenant_id`, `agent_id`, `session_id`/`conversation_key` according to the host contract).
|
||||
|
||||
An active transaction must be resumed before generic keyword routing or LLM continuity. `COLLECTING_PARAMETERS` without `active_transaction` should be treated as inconsistent state and diagnosed rather than silently restarting the tool.
|
||||
|
||||
### 8. Framework vs. agent responsibility
|
||||
|
||||
Framework owns latch persistence, argument merge, collection/confirmation states, resume precedence, deterministic confirmation, idempotency/evidence, and checkpoint/resume.
|
||||
|
||||
The agent owns domain tools, required parameters, domain messages, domain eligibility/pre-validation, and customer-facing final responses. It must not create a parallel transaction engine.
|
||||
|
||||
### 9. New host/template checklist
|
||||
|
||||
- [ ] `AgentState` declares `active_transaction`.
|
||||
- [ ] `AgentState` declares `last_transaction`.
|
||||
- [ ] `transaction_status` and `missing_parameters` are declared when used.
|
||||
- [ ] Checkpoint provider is compatible with the state schema.
|
||||
- [ ] The same conversation identity is reused across turns.
|
||||
- [ ] New parameters are merged with previously collected arguments.
|
||||
- [ ] Pending parameter answers take precedence over generic keyword routing.
|
||||
- [ ] Explicit intent shifts remain possible.
|
||||
- [ ] Transactional agent responses propagate `transaction_state_patch(state)` where required by the template.
|
||||
- [ ] Multi-turn tests cover collection, confirmation, interruption, and resume.
|
||||
|
||||
### 10. Minimum regression tests
|
||||
|
||||
Test order cancellation with a pending `order_id`, contestation with a subject collected on the first turn and amount on the second, explicit interruption to a different intent, and checkpoint/resume using the same conversation identity.
|
||||
|
||||
### 11. Anti-patterns
|
||||
|
||||
- rebuilding the transaction from only the latest message;
|
||||
- using `selected_tool_call` as the only latch source;
|
||||
- removing `active_transaction` because it appears redundant;
|
||||
- allowing a generic keyword such as `order` to interrupt `order_id` collection;
|
||||
- keeping parameters only in node-local variables;
|
||||
- duplicating transaction confirmation in the agent prompt;
|
||||
- clearing the latch before a terminal state.
|
||||
|
||||
### 12. Project references
|
||||
|
||||
- `specs/SPEC-002-Agent-Runtime.md`
|
||||
- `specs/SPEC-010-Agent-Development.md`
|
||||
- `templates/agent_template_backend/app/state.py`
|
||||
- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py`
|
||||
- `libs/agent_framework/src/agent_framework/routing/enterprise_router.py`
|
||||
- `Tuning-Performance/Deterministic_Transactional_Workflow/`
|
||||
- `Tuning-Performance/Transaction_Pre_Validation/`
|
||||
- `Tuning-Performance/Transaction_Evidence/`
|
||||
|
||||
### Runtime state and execution model
|
||||
|
||||
> Consolidated from `specs/SPEC-002-Agent-Runtime.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O Agent Runtime executa o ciclo de vida conversacional do agente. A execução inclui normalização de contexto, estado LangGraph, memória, checkpoint, roteamento, supervisor, guardrails, MCP, RAG, LLM, judges, persistência e resposta final.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Workflow Builder | Compila o grafo LangGraph. |
|
||||
| State Manager | Mantém o estado de execução. |
|
||||
| Session Manager | Resolve sessão e conversation_key. |
|
||||
| Memory Manager | Carrega e persiste histórico. |
|
||||
| Checkpoint Manager | Persiste estado LangGraph. |
|
||||
| Input Guardrail Node | Executa guardrails de entrada. |
|
||||
| Router Node | Decide rota/intent. |
|
||||
| Supervisor Node | Decide handoff ou próximo agente quando habilitado. |
|
||||
| Agent Node | Executa agente de domínio. |
|
||||
| MCP Client/Router | Executa tools por contrato. |
|
||||
| RAG Service | Recupera contexto documental. |
|
||||
| Output Supervisor | Revisa resposta antes de saída. |
|
||||
| Output Guardrail Node | Executa guardrails de saída. |
|
||||
| Judge Node | Avalia resposta. |
|
||||
| Persistence Node | Persiste mensagens, memória e checkpoint. |
|
||||
|
||||
### State Model
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
context: dict
|
||||
business_context: dict
|
||||
tool_arguments: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
rag_metadata: dict
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
metadata: dict
|
||||
errors: list[dict]
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[start] --> B[input_guardrails]
|
||||
B --> C[routing_decision]
|
||||
C --> D[agent_execution]
|
||||
D --> E[output_supervisor]
|
||||
E --> F[output_guardrails]
|
||||
F --> G[judge]
|
||||
G --> H[persist]
|
||||
H --> I[end]
|
||||
C --> J[handoff]
|
||||
J --> C
|
||||
```
|
||||
|
||||
### Nós
|
||||
|
||||
| Nó | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| `input_guardrails` | `user_text`, `context` | `sanitized_input`, `guardrails` |
|
||||
| `routing_decision` | `sanitized_input`, `business_context` | `route`, `intent`, `mcp_tools` |
|
||||
| `agent_execution` | `state` completo | `response_text`, `mcp_results`, `rag_metadata` |
|
||||
| `output_supervisor` | `response_text` | `response_text` revisado |
|
||||
| `output_guardrails` | `response_text` | `response_text`, `guardrails` |
|
||||
| `judge` | `response_text`, evidências | `judges` |
|
||||
| `persist` | `state` completo | checkpoint, memória, mensagens |
|
||||
|
||||
### Router
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
mode: router
|
||||
fallback_agent: billing_agent
|
||||
enable_llm_router: false
|
||||
intents:
|
||||
billing_invoice_explanation:
|
||||
route: billing_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- cobrança
|
||||
- boleto
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
|
||||
```yaml
|
||||
supervisor:
|
||||
enabled: true
|
||||
profile: supervisor
|
||||
max_turns: 5
|
||||
handoff_enabled: true
|
||||
fallback_route: support_agent
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
| Provider | Uso |
|
||||
|---|---|
|
||||
| `memory` | Execução local e testes. |
|
||||
| `sqlite` | Desenvolvimento local persistente. |
|
||||
| `mongodb` | Checkpoint e histórico em ambiente distribuído. |
|
||||
| `autonomous` | Produção com Oracle Autonomous Database. |
|
||||
|
||||
### Checkpoints
|
||||
|
||||
Checkpoint contém:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_key": "default:telecom_contas:session-001",
|
||||
"checkpoint_id": "ckpt-001",
|
||||
"state": {},
|
||||
"pending_writes": [],
|
||||
"created_at": "2026-06-19T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Formato entregue ao LangGraph:
|
||||
|
||||
```python
|
||||
pending_writes: list[tuple[str, str, object]]
|
||||
```
|
||||
|
||||
### Business Context
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### Ordem de Prioridade dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AgentNode --> ToolList[mcp_tools]
|
||||
ToolList --> Mapping[mcp_parameter_mapping.yaml]
|
||||
Mapping --> MCP[MCP Gateway/Router]
|
||||
MCP --> Result[mcp_results]
|
||||
```
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```yaml
|
||||
rag:
|
||||
enabled: true
|
||||
namespace_strategy: agent_id
|
||||
top_k: 5
|
||||
profile_generation: rag_generation
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `runtime.started` | Execução iniciada. |
|
||||
| `runtime.session.loaded` | Sessão carregada. |
|
||||
| `runtime.memory.loaded` | Memória carregada. |
|
||||
| `runtime.checkpoint.loaded` | Checkpoint carregado. |
|
||||
| `runtime.route.selected` | Rota selecionada. |
|
||||
| `runtime.agent.started` | Agente iniciado. |
|
||||
| `runtime.agent.completed` | Agente concluído. |
|
||||
| `runtime.persist.completed` | Persistência concluída. |
|
||||
| `runtime.failed` | Falha controlada. |
|
||||
|
||||
### Erros
|
||||
|
||||
| Código | Condição | Tratamento |
|
||||
|---|---|---|
|
||||
| `RUNTIME_INVALID_REQUEST` | GatewayRequest inválido | 422 |
|
||||
| `RUNTIME_ROUTE_NOT_FOUND` | Nenhuma rota elegível | fallback ou resposta controlada |
|
||||
| `RUNTIME_CHECKPOINT_ERROR` | Falha em checkpoint | retry ou stateless conforme config |
|
||||
| `RUNTIME_MEMORY_ERROR` | Falha em memória | retry ou resposta controlada |
|
||||
| `RUNTIME_AGENT_ERROR` | Falha no agente | NOC + fallback |
|
||||
| `RUNTIME_TIMEOUT` | Timeout geral | resposta controlada |
|
||||
|
||||
|
||||
|
||||
### Contrato Durável de Estado Transacional
|
||||
|
||||
Hosts que utilizam `AgentRuntime` com transações multi-turno DEVEM declarar no `AgentState` os campos `active_transaction` e `last_transaction`. O primeiro é a fonte canônica da transação em andamento e deve sobreviver a checkpoint/resume; o segundo mantém o snapshot da última transação terminal.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
`selected_tool_call` e `pending_tool_call` são campos auxiliares/compatibilidade e não substituem o latch canônico. Durante `COLLECTING_PARAMETERS`, a retomada da transação e o consumo de parâmetros pendentes têm precedência sobre keyword routing genérico. Uma mudança de intenção só deve interromper a transação quando for inequívoca ou explicitamente solicitada pelo usuário.
|
||||
|
||||
O contrato completo, ciclo de vida, precedência de roteamento, checklist e testes regressivos estão em [`docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Runtime recebe GatewayRequest validado.
|
||||
- [ ] State contém tenant_id, agent_id, session_id, conversation_key, route e intent.
|
||||
- [ ] Input guardrails executam antes do roteamento.
|
||||
- [ ] Router ou Supervisor seleciona rota.
|
||||
- [ ] Agent Node executa sem acessar payload bruto de canal.
|
||||
- [ ] MCP é acessado por contrato.
|
||||
- [ ] RAG é acessado por serviço reutilizável.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
- [ ] Judges geram JudgeResult.
|
||||
- [ ] Memória e checkpoint são persistidos conforme provider.
|
||||
- [ ] Hosts transacionais declaram `active_transaction` e `last_transaction` no `AgentState`.
|
||||
- [ ] Durante `COLLECTING_PARAMETERS`, respostas a parâmetros pendentes têm precedência sobre keyword routing genérico.
|
||||
- [ ] Erros geram NOC e resposta controlada.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Canonical state contracts
|
||||
|
||||
> Consolidated from `specs/SPEC-012-Canonical-Contracts.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Contratos canônicos são estruturas padronizadas usadas para desacoplar canais, gateways, runtime, agentes, tools, LLMs, evaluator e observabilidade.
|
||||
|
||||
A plataforma usa contratos para garantir que componentes independentes possam evoluir sem quebrar uns aos outros.
|
||||
|
||||
### 2. Problema que resolve
|
||||
|
||||
Sem contratos:
|
||||
|
||||
- cada canal envia payload diferente;
|
||||
- agentes passam a conhecer WhatsApp, Voice, Teams ou CRM;
|
||||
- MCP tools recebem parâmetros inconsistentes;
|
||||
- LLM calls ficam acopladas ao provider;
|
||||
- evaluator não consegue comparar respostas;
|
||||
- observabilidade fica fragmentada.
|
||||
|
||||
Com contratos:
|
||||
|
||||
```text
|
||||
Canal → GatewayRequest → Runtime → BusinessContext → ToolInvocation → ToolResult
|
||||
```
|
||||
|
||||
### 3. Catálogo de contratos
|
||||
|
||||
| Contrato | Uso |
|
||||
| --- | --- |
|
||||
| GatewayRequest | Entrada canônica da plataforma. |
|
||||
| ChannelResponse | Resposta canônica ao canal. |
|
||||
| BusinessContext | Identidade canônica de negócio. |
|
||||
| AgentState | Estado interno do runtime. |
|
||||
| Session | Sessão técnica/conversacional. |
|
||||
| Checkpoint | Persistência de estado LangGraph. |
|
||||
| ToolInvocation | Chamada canônica de tool MCP. |
|
||||
| ToolResult | Resposta canônica de tool MCP. |
|
||||
| LLMRequest | Chamada canônica ao AI Gateway. |
|
||||
| LLMResponse | Resposta canônica do AI Gateway. |
|
||||
| EvaluationRun | Execução do evaluator. |
|
||||
| EvaluationResult | Resultado de avaliação. |
|
||||
| CertificationResult | Resultado de certificação. |
|
||||
| EventEnvelope | Envelope de eventos IC/NOC/GRL. |
|
||||
|
||||
|
||||
### 4. GatewayRequest
|
||||
|
||||
### 4.1. Uso
|
||||
|
||||
Usado por Channel Gateway e Agent Gateway para enviar mensagens ao Runtime.
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "web",
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"payload": {
|
||||
"message": "Quero consultar minha fatura",
|
||||
"session_id": "session-001",
|
||||
"user_id": "user-001",
|
||||
"message_id": "msg-001",
|
||||
"business_context": {
|
||||
"customer_key": "11999999999",
|
||||
"contract_key": "3000131180",
|
||||
"interaction_key": "301953872",
|
||||
"session_key": "session-001"
|
||||
},
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"contract_version": "gateway-request-v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2. Campos obrigatórios
|
||||
|
||||
- `channel`;
|
||||
- `payload.message`;
|
||||
- `payload.session_id`;
|
||||
- `payload.message_id`;
|
||||
- `tenant_id` quando multi-tenant;
|
||||
- `agent_id` quando não houver roteamento global.
|
||||
|
||||
### 5. ChannelResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "web",
|
||||
"session_id": "default:telecom_contas:session-001",
|
||||
"text": "Resposta final do agente.",
|
||||
"metadata": {
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"route": "billing_agent",
|
||||
"intent": "billing_invoice_explanation",
|
||||
"guardrails": [],
|
||||
"judges": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. BusinessContext
|
||||
|
||||
### 6.1. Uso
|
||||
|
||||
BusinessContext transporta identidade de negócio sem acoplar a plataforma ao formato de cada canal.
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### 6.2. Mapeamento para MCP
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_fatura:
|
||||
map:
|
||||
customer_key: msisdn
|
||||
contract_key: invoice_id
|
||||
interaction_key: ura_call_id
|
||||
session_key: session_id
|
||||
```
|
||||
|
||||
### 7. AgentState
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
business_context: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
```
|
||||
|
||||
### 8. ToolInvocation
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"tool_name": "consultar_fatura",
|
||||
"arguments": {
|
||||
"msisdn": "11999999999",
|
||||
"invoice_id": "3000131180"
|
||||
},
|
||||
"business_context": {
|
||||
"customer_key": "11999999999",
|
||||
"contract_key": "3000131180"
|
||||
},
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"trace_id": "trace-001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. ToolResult
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "consultar_fatura",
|
||||
"ok": true,
|
||||
"data": {
|
||||
"invoice_id": "3000131180",
|
||||
"valor_total": 249.90,
|
||||
"status": "ABERTA"
|
||||
},
|
||||
"cache": {
|
||||
"hit": false,
|
||||
"ttl_seconds": 300
|
||||
},
|
||||
"latency_ms": 140
|
||||
}
|
||||
```
|
||||
|
||||
### 10. LLMRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"profile": "judge",
|
||||
"operation": "judge.response_quality",
|
||||
"messages": [
|
||||
{"role": "system", "content": "Você é um avaliador."},
|
||||
{"role": "user", "content": "Avalie a resposta."}
|
||||
],
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"trace_id": "trace-001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 11. LLMResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "oci_openai",
|
||||
"model": "openai.gpt-4.1",
|
||||
"profile": "judge",
|
||||
"content": "Resultado",
|
||||
"usage": {
|
||||
"input_tokens": 1200,
|
||||
"output_tokens": 300,
|
||||
"total_tokens": 1500
|
||||
},
|
||||
"latency_ms": 820
|
||||
}
|
||||
```
|
||||
|
||||
### 12. EvaluationRun
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "eval-001",
|
||||
"agent_id": "telecom_contas",
|
||||
"source": "langfuse",
|
||||
"period_start": "2026-06-18T00:00:00Z",
|
||||
"period_end": "2026-06-19T00:00:00Z",
|
||||
"status": "running"
|
||||
}
|
||||
```
|
||||
|
||||
### 13. EventEnvelope
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "IC.AGENT_COMPLETED",
|
||||
"timestamp": "2026-06-19T12:00:00Z",
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"session_id": "session-001",
|
||||
"trace_id": "trace-001",
|
||||
"payload": {}
|
||||
}
|
||||
```
|
||||
|
||||
### 14. Regras de evolução
|
||||
|
||||
- campos novos devem ser opcionais;
|
||||
- campos obrigatórios não podem ser removidos dentro da mesma major;
|
||||
- mudança semântica exige nova versão;
|
||||
- contratos são versionados independentemente.
|
||||
|
||||
### 15. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Payload bruto no Runtime | Acopla canais ao core. | Usar GatewayRequest. |
|
||||
| Tool recebendo BusinessContext bruto sem mapping | Quebra contrato da tool. | Usar mcp_parameter_mapping.yaml. |
|
||||
| LLM direto no agente | Quebra AI Gateway. | Usar LLMRequest/profile. |
|
||||
| Campos sem versão | Dificulta migração. | Declarar contract_version. |
|
||||
|
||||
|
||||
### 16. Critérios de aceite
|
||||
|
||||
- [ ] GatewayRequest documentado e versionado.
|
||||
- [ ] ChannelResponse documentado e versionado.
|
||||
- [ ] BusinessContext usado por canais e MCP.
|
||||
- [ ] ToolInvocation e ToolResult padronizados.
|
||||
- [ ] LLMRequest e LLMResponse padronizados.
|
||||
- [ ] EvaluationRun e EvaluationResult padronizados.
|
||||
- [ ] EventEnvelope usado para IC/NOC/GRL.
|
||||
- [ ] Contratos possuem regras de evolução.
|
||||
831
docs/developer/en/04_mcp_integration_tools_and_policies.md
Normal file
831
docs/developer/en/04_mcp_integration_tools_and_policies.md
Normal file
@@ -0,0 +1,831 @@
|
||||
|
||||
### MCP, Tools, Policies and Parameter Extraction
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **tools, MCP Servers, mappings, read-only/transactional policies and parameter extraction**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Tools, mcp servers, mappings, read-only/transactional policies and parameter extraction.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### MCP Integration, Tools, Policies and Parameter Extraction
|
||||
|
||||
This guide explains how agents consume business capabilities through MCP without embedding service logic in the framework.
|
||||
|
||||
### MCP role
|
||||
|
||||
MCP is the integration boundary for tools. The framework/runtime selects and prepares a tool call; the MCP layer connects that logical tool to a service. Business authorization, atomicity and backend transaction guarantees remain responsibilities of the MCP Server/service implementation.
|
||||
|
||||
### Registering an MCP Server
|
||||
|
||||
For local execution, register the server in the backend/gateway MCP configuration with its transport, endpoint, enabled flag and description. Docker/Kubernetes configurations should use the service DNS name rather than localhost.
|
||||
|
||||
```yaml
|
||||
servers:
|
||||
crm:
|
||||
transport: http
|
||||
endpoint: http://localhost:8300/mcp
|
||||
enabled: true
|
||||
description: CRM MCP Server
|
||||
```
|
||||
|
||||
### Registering a tool
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_cliente:
|
||||
description: Query summarized customer data.
|
||||
mcp_server: crm
|
||||
enabled: true
|
||||
args_schema:
|
||||
customer_id: string
|
||||
document_id: string
|
||||
```
|
||||
|
||||
The tool description and parameter descriptions are part of runtime behavior. They should be precise enough for semantic selection/extraction and must not be hidden in Python hardcodes.
|
||||
|
||||
### Tool isolation per agent
|
||||
|
||||
Every agent should see only the tools it needs. Use an allowlist or agent-specific `tools.yaml`. This reduces prompt ambiguity and limits operational risk.
|
||||
|
||||
### Read-only versus transactional policies
|
||||
|
||||
Policy configuration is optional and lives with the deployable agent, not inside the shared library. A default may treat tools as read-only, while individual tools declare `operation_type: transactional`, `require_confirmation: true` and required parameters.
|
||||
|
||||
```yaml
|
||||
defaults:
|
||||
operation_type: read_only
|
||||
require_confirmation: false
|
||||
|
||||
tool_policies:
|
||||
alterar_plano:
|
||||
operation_type: transactional
|
||||
require_confirmation: true
|
||||
requires: [new_plan_id]
|
||||
```
|
||||
|
||||
If policy configuration is absent, legacy metadata in `tools.yaml` remains valid. Old tools without a policy must keep their previous behavior.
|
||||
|
||||
### Confirmation contract
|
||||
|
||||
A blocked transactional call must not reach MCP. The runtime returns policy metadata explaining why it was blocked. Confirmation must be represented by the transaction/runtime confirmation contract; a random textual field containing the word `true` is not sufficient evidence.
|
||||
|
||||
### LLM-based parameter extraction
|
||||
|
||||
Parameter extraction supports natural language and multi-turn collection. The user may provide `name=value`, a natural phrase, only the value when one parameter is unambiguously missing, or several parameters in one turn. Extraction uses the active tool/workflow schema and parameter descriptions; it must not rely on a domain-specific regex list in the framework.
|
||||
|
||||
Extracted values are merged into the active transaction before generic rerouting decisions. If extraction cannot determine a required value reliably, the agent asks for the missing parameter rather than inventing it.
|
||||
|
||||
### MCP Server implementation
|
||||
|
||||
A server exposes a tool catalog/schema and a call endpoint/transport. The business implementation validates the arguments, invokes the backend and returns a structured success/error result. Transactional services should implement authorization/idempotency as appropriate to the backend contract.
|
||||
|
||||
### Security and observability checklist
|
||||
|
||||
- Explicit schema and description for every tool.
|
||||
- Explicit confirmation for configured side effects.
|
||||
- Tool allowlist per agent.
|
||||
- Sensitive-result sanitization/masking before user presentation.
|
||||
- Trace/span/event for each MCP invocation.
|
||||
- Configured timeouts/retries.
|
||||
- Do not expose MCP Servers publicly without authentication, TLS and network controls.
|
||||
- Separate read-only and transactional operations.
|
||||
|
||||
Recommended telemetry includes tenant, agent, session, tool, MCP server, latency, success/error and argument-key metadata without leaking sensitive values.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `Documentacao/Manual_Integracao_MCP_Servers_Agent_Framework.docx`
|
||||
- `Documentacao/README_TOOL_POLICIES.md`
|
||||
- `Documentacao/RELEASE_NOTES_TOOL_POLICIES.md`
|
||||
- `Documentacao/RELEASE_NOTES_MCP_PARAMETER_EXTRACTION_FIX.md`
|
||||
- `Documentacao/README_MCP.md`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### MCP discovery and catalog details
|
||||
|
||||
> Consolidated from `docs/MCP_GATEWAY_DISCOVERY.md`.
|
||||
|
||||
### Goal
|
||||
|
||||
This evolution allows the MCP Gateway to discover tools from registered MCP Servers by reading a manifest or catalog endpoint.
|
||||
|
||||
The framework still points to a single MCP Gateway:
|
||||
|
||||
```env
|
||||
MCP_GATEWAY_ENABLED=true
|
||||
MCP_GATEWAY_URL=http://localhost:8300
|
||||
MCP_GATEWAY_TIMEOUT_SECONDS=60
|
||||
```
|
||||
|
||||
The MCP Gateway can point to many MCP Servers:
|
||||
|
||||
```text
|
||||
Agent Framework
|
||||
-> MCP Gateway
|
||||
-> telecom_mcp_server
|
||||
-> retail_mcp_server
|
||||
-> nf_items_mcp_server
|
||||
-> any other MCP Server
|
||||
```
|
||||
|
||||
### What is automatic
|
||||
|
||||
After a server is registered in `apps/mcp_gateway/config/mcp_gateway.yaml` with `discover: true`, the gateway can:
|
||||
|
||||
- call its manifest/catalog endpoint;
|
||||
- normalize the returned tool list;
|
||||
- publish the tools in `GET /v1/tools`;
|
||||
- execute the discovered tool through `POST /v1/tools/{tool_name}/invoke`.
|
||||
|
||||
### What is still explicit
|
||||
|
||||
The gateway does not scan the network or GitHub by itself. You still register the MCP Server endpoint in YAML.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
servers:
|
||||
nf_items:
|
||||
enabled: true
|
||||
discover: true
|
||||
protocol: legacy_http
|
||||
transport: http
|
||||
url: http://localhost:8400/mcp
|
||||
catalog_endpoint: /tools
|
||||
invoke_endpoint: /tools/call
|
||||
timeout_seconds: 30
|
||||
```
|
||||
|
||||
If `catalog_endpoint` is omitted, the gateway tries:
|
||||
|
||||
```text
|
||||
/.well-known/mcp-server.json
|
||||
/manifest
|
||||
/mcp/tools
|
||||
/tools/list
|
||||
/tools
|
||||
/v1/tools
|
||||
```
|
||||
|
||||
### Expected manifest/catalog formats
|
||||
|
||||
The gateway accepts common shapes:
|
||||
|
||||
```json
|
||||
{
|
||||
"server_id": "nf_items",
|
||||
"tools": [
|
||||
{
|
||||
"name": "buscar_notas_por_criterios",
|
||||
"description": "Search invoice items by criteria.",
|
||||
"input_schema": {
|
||||
"cliente": "string",
|
||||
"estado": "string",
|
||||
"preco": "number",
|
||||
"ean": "string",
|
||||
"margem": "number"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
It also accepts:
|
||||
|
||||
```json
|
||||
{"tools": [...]}
|
||||
```
|
||||
|
||||
```json
|
||||
{"data": {"tools": [...]}}
|
||||
```
|
||||
|
||||
```json
|
||||
{"capabilities": {"tools": [...]}}
|
||||
```
|
||||
|
||||
### New endpoints
|
||||
|
||||
### List discovery servers
|
||||
|
||||
```bash
|
||||
curl http://localhost:8300/v1/discovery/servers | jq
|
||||
```
|
||||
|
||||
### Force catalog sync
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8300/v1/discovery/sync | jq
|
||||
```
|
||||
|
||||
### List merged static + discovered tools
|
||||
|
||||
```bash
|
||||
curl http://localhost:8300/v1/tools | jq
|
||||
```
|
||||
|
||||
### Precedence rule
|
||||
|
||||
Static tools configured under `tools:` override discovered tools with the same name. This allows operations teams to override timeout, cache, allowed agents, required business keys, and endpoint behavior safely.
|
||||
|
||||
### Plugging a new MCP Server
|
||||
|
||||
1. Start the MCP Server.
|
||||
2. Confirm that it exposes a catalog or manifest endpoint.
|
||||
3. Add it under `servers:` in `mcp_gateway.yaml` with `discover: true`.
|
||||
4. Restart the MCP Gateway or call `POST /v1/discovery/sync`.
|
||||
5. Confirm the tool appears in `GET /v1/tools`.
|
||||
6. Invoke the tool through the gateway.
|
||||
|
||||
### Example invocation
|
||||
|
||||
```bash
|
||||
curl -s -X POST http://localhost:8300/v1/tools/buscar_notas_por_criterios/invoke \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"channel": "web",
|
||||
"tool_name": "buscar_notas_por_criterios",
|
||||
"arguments": {
|
||||
"cliente": "CLIENTE-001",
|
||||
"estado": "SP",
|
||||
"preco": 100.0,
|
||||
"ean": "7890000000000",
|
||||
"margem": 0.05
|
||||
},
|
||||
"business_context": {
|
||||
"session_key": "session-001"
|
||||
}
|
||||
}' | jq
|
||||
```
|
||||
|
||||
### MCP Gateway specification
|
||||
|
||||
> Consolidated from `specs/SPEC-004-MCP-Gateway.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O MCP Gateway centraliza catálogo, autorização, roteamento, execução, cache, timeout, retry, observabilidade e resposta padronizada de tools MCP.
|
||||
|
||||
### Endpoints
|
||||
|
||||
| Método | Endpoint | Descrição |
|
||||
|---|---|---|
|
||||
| `GET` | `/health` | Health check. |
|
||||
| `GET` | `/ready` | Readiness check. |
|
||||
| `GET` | `/v1/tools` | Catálogo de tools. |
|
||||
| `GET` | `/v1/tools/{tool_name}` | Detalhe da tool. |
|
||||
| `POST` | `/v1/tools/{tool_name}/invoke` | Execução de tool. |
|
||||
| `GET` | `/v1/servers` | Lista MCP servers. |
|
||||
|
||||
### ToolInvocation
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"tool_name": "consultar_fatura",
|
||||
"arguments": {
|
||||
"msisdn": "11999999999",
|
||||
"invoice_id": "3000131180",
|
||||
"session_id": "default:telecom_contas:session-001"
|
||||
},
|
||||
"business_context": {
|
||||
"customer_key": "11999999999",
|
||||
"contract_key": "3000131180",
|
||||
"session_key": "session-001"
|
||||
},
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"trace_id": "trace-001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ToolResult
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "consultar_fatura",
|
||||
"ok": true,
|
||||
"data": {
|
||||
"invoice_id": "3000131180",
|
||||
"valor_total": 249.90,
|
||||
"vencimento": "2026-06-10",
|
||||
"status": "ABERTA"
|
||||
},
|
||||
"cache": {
|
||||
"hit": false,
|
||||
"ttl_seconds": 300
|
||||
},
|
||||
"latency_ms": 140,
|
||||
"metadata": {
|
||||
"server": "telecom"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### mcp_servers.yaml
|
||||
|
||||
```yaml
|
||||
servers:
|
||||
telecom:
|
||||
transport: http
|
||||
url: http://telecom-mcp:8001/mcp
|
||||
enabled: true
|
||||
timeout_seconds: 30
|
||||
|
||||
retail:
|
||||
transport: http
|
||||
url: http://retail-mcp:8002/mcp
|
||||
enabled: true
|
||||
timeout_seconds: 30
|
||||
```
|
||||
|
||||
### tools.yaml
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_fatura:
|
||||
server: telecom
|
||||
enabled: true
|
||||
idempotent: true
|
||||
cache_ttl_seconds: 300
|
||||
allowed_agents:
|
||||
- telecom_contas
|
||||
required_business_keys:
|
||||
- customer_key
|
||||
- contract_key
|
||||
|
||||
solicitar_devolucao:
|
||||
server: retail
|
||||
enabled: true
|
||||
idempotent: false
|
||||
requires_confirmation: true
|
||||
allowed_agents:
|
||||
- retail_orders
|
||||
```
|
||||
|
||||
### mcp_parameter_mapping.yaml
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_fatura:
|
||||
map:
|
||||
customer_key: msisdn
|
||||
contract_key: invoice_id
|
||||
interaction_key: ura_call_id
|
||||
session_key: session_id
|
||||
```
|
||||
|
||||
### Autorização
|
||||
|
||||
```yaml
|
||||
authorization:
|
||||
default_policy: deny
|
||||
agents:
|
||||
telecom_contas:
|
||||
allowed_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
- consultar_plano
|
||||
```
|
||||
|
||||
### Cache
|
||||
|
||||
| Regra | Valor |
|
||||
|---|---|
|
||||
| Chave | `tenant_id:agent_id:tool_name:hash(arguments)` |
|
||||
| Aplicação | Apenas tools idempotentes |
|
||||
| Bypass | `metadata.cache_bypass=true` |
|
||||
| TTL | `cache_ttl_seconds` |
|
||||
| Escrita | Não cachear operações mutáveis |
|
||||
|
||||
### Retry e Timeout
|
||||
|
||||
```yaml
|
||||
execution:
|
||||
default_timeout_seconds: 30
|
||||
retry:
|
||||
enabled: true
|
||||
max_attempts: 2
|
||||
backoff_ms: 250
|
||||
circuit_breaker:
|
||||
enabled: true
|
||||
failure_threshold: 5
|
||||
recovery_seconds: 60
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `mcp.tool.requested` | Tool requisitada. |
|
||||
| `mcp.tool.authorized` | Autorização aprovada. |
|
||||
| `mcp.tool.denied` | Autorização negada. |
|
||||
| `mcp.tool.started` | Execução iniciada. |
|
||||
| `mcp.tool.completed` | Execução concluída. |
|
||||
| `mcp.tool.failed` | Execução falhou. |
|
||||
| `mcp.cache.hit` | Cache hit. |
|
||||
| `mcp.cache.miss` | Cache miss. |
|
||||
|
||||
### Métricas
|
||||
|
||||
| Métrica | Dimensões |
|
||||
|---|---|
|
||||
| `mcp_tool_calls_total` | tool, server, tenant, agent, status |
|
||||
| `mcp_tool_latency_ms` | tool, server |
|
||||
| `mcp_tool_errors_total` | tool, server, error_type |
|
||||
| `mcp_cache_hits_total` | tool |
|
||||
| `mcp_cache_misses_total` | tool |
|
||||
|
||||
### Segurança
|
||||
|
||||
- Tools são negadas por padrão.
|
||||
- Argumentos sensíveis são mascarados.
|
||||
- Tools mutáveis exigem confirmação quando configurado.
|
||||
- MCP servers não recebem payload bruto de canal.
|
||||
- Credenciais de backend são mantidas nos MCP servers ou secret store.
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Catálogo de tools retorna tools habilitadas.
|
||||
- [ ] ToolInvocation é validado antes da execução.
|
||||
- [ ] Autorização por agente é aplicada.
|
||||
- [ ] Parâmetros são derivados do BusinessContext.
|
||||
- [ ] Cache só é aplicado a tools idempotentes.
|
||||
- [ ] Timeout/retry/circuit breaker são configuráveis.
|
||||
- [ ] Eventos e métricas são emitidos.
|
||||
- [ ] Falhas retornam ToolResult padronizado.
|
||||
- [ ] MCP servers são substituíveis por configuração.
|
||||
- [ ] Tools críticas possuem testes de contrato.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Política mínima de operação
|
||||
|
||||
Antes de encaminhar uma tool, o runtime deve aplicar a política opcional do backend em `config/tool_policies.yaml`. Os tipos canônicos são `read_only` e `transactional`; esta última pode exigir confirmação booleana explícita e campos obrigatórios. A ausência do arquivo não é erro e preserva os campos legados de `tools.yaml`. A política conversacional não substitui autenticação, autorização, idempotência nem atomicidade no MCP Server.
|
||||
|
||||
### Agent tool integration requirements
|
||||
|
||||
> Consolidated from `specs/SPEC-010-Agent-Development.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
Esta SPEC define o padrão para criação de agentes usando templates, configuração YAML, BusinessContext, MCP, guardrails, judges, RAG, memória, observabilidade e evals.
|
||||
|
||||
### Estrutura do Template
|
||||
|
||||
```text
|
||||
templates/agent_template_backend/
|
||||
├── app/
|
||||
│ ├── main.py
|
||||
│ ├── state.py
|
||||
│ ├── workflows/
|
||||
│ │ └── agent_graph.py
|
||||
│ ├── agents/
|
||||
│ │ ├── runtime.py
|
||||
│ │ └── domain_agent.py
|
||||
│ └── examples/
|
||||
├── config/
|
||||
│ ├── agents.yaml
|
||||
│ ├── routing.yaml
|
||||
│ ├── tools.yaml
|
||||
│ ├── mcp_servers.yaml
|
||||
│ ├── mcp_parameter_mapping.yaml
|
||||
│ ├── identity.yaml
|
||||
│ ├── guardrails.yaml
|
||||
│ ├── judges.yaml
|
||||
│ ├── prompt_policy.yaml
|
||||
│ └── agents/<agent_id>/
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
└── .env.example
|
||||
```
|
||||
|
||||
### Responsabilidades do Framework
|
||||
|
||||
- LangGraph;
|
||||
- memória;
|
||||
- checkpoint;
|
||||
- sessão;
|
||||
- router;
|
||||
- supervisor;
|
||||
- guardrails;
|
||||
- judges;
|
||||
- telemetry;
|
||||
- MCP integration;
|
||||
- RAG genérico;
|
||||
- cache;
|
||||
- providers LLM;
|
||||
- event bus.
|
||||
|
||||
### Responsabilidades do Agente
|
||||
|
||||
- prompts de domínio;
|
||||
- regras de negócio;
|
||||
- schemas específicos;
|
||||
- decisão de uso de evidências;
|
||||
- tratamento de campos obrigatórios;
|
||||
- mensagens de domínio;
|
||||
- ICs de jornada;
|
||||
- datasets de eval específicos.
|
||||
|
||||
### Registro do Agente
|
||||
|
||||
```yaml
|
||||
agents:
|
||||
financeiro_agent:
|
||||
enabled: true
|
||||
description: "Agente financeiro"
|
||||
profile: financeiro_agent
|
||||
rag_namespace: financeiro
|
||||
allowed_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Roteamento
|
||||
|
||||
```yaml
|
||||
intents:
|
||||
financeiro_consulta_fatura:
|
||||
route: financeiro_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- boleto
|
||||
- cobrança
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
```
|
||||
|
||||
### Tool Mapping
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_fatura:
|
||||
map:
|
||||
customer_key: msisdn
|
||||
contract_key: invoice_id
|
||||
interaction_key: ura_call_id
|
||||
session_key: session_id
|
||||
```
|
||||
|
||||
### Classe de Agente
|
||||
|
||||
```python
|
||||
class FinanceiroAgent(AgentRuntimeMixin):
|
||||
name = "financeiro_agent"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
llm,
|
||||
telemetry=None,
|
||||
tool_router=None,
|
||||
rag_service=None,
|
||||
cache=None,
|
||||
settings=None,
|
||||
observer=None,
|
||||
memory=None,
|
||||
summary_memory=None,
|
||||
):
|
||||
self.llm = llm
|
||||
self.telemetry = telemetry
|
||||
self.tool_router = tool_router
|
||||
self.rag_service = rag_service
|
||||
self.cache = cache
|
||||
self.settings = settings
|
||||
self.observer = observer
|
||||
self.memory = memory
|
||||
self.summary_memory = summary_memory
|
||||
|
||||
async def run(self, state):
|
||||
await self._emit_ic("IC.FINANCEIRO_AGENT_STARTED", state, {})
|
||||
tool_context = await self._collect_mcp_context(state)
|
||||
rag_context, rag_metadata = await self._retrieve_rag_context(state)
|
||||
response = await self._invoke_llm_cached(
|
||||
state,
|
||||
"FinanceiroAgent",
|
||||
[
|
||||
{"role": "system", "content": "Você é um agente financeiro."},
|
||||
{"role": "user", "content": state.get("sanitized_input") or state.get("user_text", "")},
|
||||
],
|
||||
)
|
||||
await self._emit_ic("IC.FINANCEIRO_AGENT_COMPLETED", state, {})
|
||||
return {
|
||||
"response_text": response,
|
||||
"mcp_results": tool_context,
|
||||
"rag_metadata": rag_metadata,
|
||||
}
|
||||
```
|
||||
|
||||
### Ordem de Confiança dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### Prompt Policy
|
||||
|
||||
```yaml
|
||||
prompt_policy:
|
||||
system_prompt_path: prompts/system.md
|
||||
response_style: concise
|
||||
require_evidence: true
|
||||
allow_tool_usage: true
|
||||
```
|
||||
|
||||
### Guardrails por Agente
|
||||
|
||||
```yaml
|
||||
input:
|
||||
- code: FIN_INPUT_POLICY
|
||||
enabled: true
|
||||
mode: observe
|
||||
|
||||
output:
|
||||
- code: FIN_OUTPUT_COMPLIANCE
|
||||
enabled: true
|
||||
mode: enforce
|
||||
```
|
||||
|
||||
### Judges por Agente
|
||||
|
||||
```yaml
|
||||
judges:
|
||||
- name: response_quality
|
||||
enabled: true
|
||||
threshold: 0.75
|
||||
- name: groundedness
|
||||
enabled: true
|
||||
threshold: 0.70
|
||||
```
|
||||
|
||||
### Dataset de Eval
|
||||
|
||||
```yaml
|
||||
dataset:
|
||||
name: financeiro_agent_regression
|
||||
version: 1.0.0
|
||||
items:
|
||||
- id: fin-001
|
||||
input: "Quero consultar minha fatura"
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
expected:
|
||||
route: financeiro_agent
|
||||
tools:
|
||||
- consultar_fatura
|
||||
min_scores:
|
||||
quality: 0.75
|
||||
groundedness: 0.70
|
||||
```
|
||||
|
||||
|
||||
### Contrato obrigatório para agentes transacionais
|
||||
|
||||
Ao criar um agente que usa tools transacionais do framework, o desenvolvedor não deve criar um motor paralelo de coleta/confirmação. Deve reutilizar `AgentRuntime` e garantir que o `AgentState` do host mantenha o latch durável:
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
Durante uma transação ativa, parâmetros já coletados são preservados e novos valores são mesclados incrementalmente. Em `COLLECTING_PARAMETERS`, uma resposta que satisfaz um parâmetro pendente tem precedência sobre keywords genéricas. Mudanças de intenção explícitas e inequívocas continuam permitidas.
|
||||
|
||||
Antes de publicar um novo template/host, execute os cenários multi-turno descritos no [`Transaction State Developer Guide`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Testes
|
||||
|
||||
| Teste | Escopo |
|
||||
|---|---|
|
||||
| Unitário | Classe do agente. |
|
||||
| Routing | Intent e rota. |
|
||||
| MCP Mapping | BusinessContext para argumentos. |
|
||||
| Guardrails | Entrada e saída. |
|
||||
| Judges | Scores mínimos. |
|
||||
| Runtime | Execução completa. |
|
||||
| Memory | Continuidade de conversa. |
|
||||
| Checkpoint | Resume/replay. |
|
||||
| Observability | Trace e eventos. |
|
||||
| Certification | Evidências finais. |
|
||||
|
||||
### Definition of Done
|
||||
|
||||
- agente registrado;
|
||||
- rota configurada;
|
||||
- tools declaradas;
|
||||
- mapping definido;
|
||||
- prompts versionados;
|
||||
- guardrails configurados;
|
||||
- judges configurados;
|
||||
- dataset criado;
|
||||
- testes executados;
|
||||
- traces gerados;
|
||||
- certification suite aprovada;
|
||||
- documentação do agente atualizada.
|
||||
|
||||
### Anti-patterns
|
||||
|
||||
- agente criando sessão;
|
||||
- agente abrindo SSE;
|
||||
- agente compilando LangGraph;
|
||||
- agente chamando sistema externo diretamente;
|
||||
- prompt hardcoded sem política;
|
||||
- lógica genérica duplicada no agente;
|
||||
- payload bruto de canal dentro do agente;
|
||||
- ausência de dataset de eval.
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Novo agente é criado sem alterar core do framework.
|
||||
- [ ] Se houver transações multi-turno, `AgentState` declara `active_transaction` e `last_transaction`.
|
||||
- [ ] Configuração ocorre por YAML e `.env`.
|
||||
- [ ] Agente usa BusinessContext.
|
||||
- [ ] Agente acessa MCP por router/gateway.
|
||||
- [ ] Agente não conhece payload bruto de canal.
|
||||
- [ ] Guardrails e judges são configurados.
|
||||
- [ ] Dataset de eval existe.
|
||||
- [ ] Testes mínimos executam.
|
||||
- [ ] Trace completo é gerado.
|
||||
- [ ] Definition of Done é atendida.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
1161
docs/developer/en/05_agent_gateway_mcp_gateway_and_auth.md
Normal file
1161
docs/developer/en/05_agent_gateway_mcp_gateway_and_auth.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,689 @@
|
||||
|
||||
### Guardrails, Judges and Transaction Evaluation
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **native/external guardrails, judges, transactional sampling and grounding**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Native/external guardrails, judges, transactional sampling and grounding.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### Guardrails, Judges and Transaction Evaluation
|
||||
|
||||
This guide explains validation layers and how agent-specific policies extend the framework without introducing domain coupling.
|
||||
|
||||
### Guardrail stages
|
||||
|
||||
Input guardrails validate/sanitize/block user input before domain execution. Output guardrails validate the produced response before it leaves the runtime. Optional rails can be enabled according to agent/environment policy.
|
||||
|
||||
### Agent-owned extensions
|
||||
|
||||
The framework exposes an SPI/configuration model for external guardrails and judges. An agent points configuration to implementation classes in its own package. The shared framework must not import concrete telecom, retail or company validation modules.
|
||||
|
||||
Synchronous validators may execute in worker threads; asynchronous validators execute on the event loop. Independent judges may execute concurrently to reduce latency while the configured logical result order is preserved.
|
||||
|
||||
### Transactional judge sampling
|
||||
|
||||
Normal evaluation may use sampling, but transactional interactions can be configured with `always_run_for_transactional`. Transaction detection occurs before applying `sample_rate` so critical side-effecting paths are not randomly skipped.
|
||||
|
||||
Signals may include transaction lifecycle state, required/received confirmation, selected or pending tool call, tool-policy result and MCP execution results. Detection intentionally uses multiple signals instead of depending on a single field.
|
||||
|
||||
### Operational evidence
|
||||
|
||||
Judges must distinguish a model claim from an executed action. MCP results and transaction evidence provide grounding for assertions such as cancellation, credit, update or protocol creation.
|
||||
|
||||
### Compatibility
|
||||
|
||||
Legacy validators may use temporary compatibility shims during migration, but new code should depend on the external SPI/configuration. Native framework guardrails continue to coexist with agent-specific policies.
|
||||
|
||||
### Testing
|
||||
|
||||
Test allow/sanitize/block behavior, exceptions/fail-closed behavior where configured, sync/async external validators, judge concurrency, transactional sample-rate bypass, MCP evidence propagation and isolation between two agents with different policies.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `Documentacao/README_GUARDRAILS_IMPLEMENTADOS.md`
|
||||
- `docs/EXTERNAL_GUARDRAILS_JUDGES.md`
|
||||
- `docs/JUDGES_TRANSACTIONAL_SAMPLING_FIX.md`
|
||||
- Global Supervisor and guardrail validation records under `docs/`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### External guardrails and judges SPI
|
||||
|
||||
> Consolidated from `docs/EXTERNAL_GUARDRAILS_JUDGES.md`.
|
||||
|
||||
`agent_framework_oci` supports agent-owned guardrails and judges without importing domain code into the core.
|
||||
|
||||
```yaml
|
||||
output:
|
||||
- code: ACME_POLICY
|
||||
type: external
|
||||
class: app.extensions.guardrails:AcmePolicyRail
|
||||
```
|
||||
|
||||
```yaml
|
||||
judges:
|
||||
- name: acme_quality
|
||||
type: external
|
||||
class: app.extensions.judges:AcmeQualityJudge
|
||||
threshold: 0.7
|
||||
```
|
||||
|
||||
Native entries remain unchanged. External synchronous `evaluate()` methods execute in worker threads via `asyncio.to_thread`; asynchronous methods execute concurrently on the framework event loop. Judges run concurrently with `asyncio.gather`, preserving YAML result order. Agent plugins should reuse the LLM supplied by the framework rather than instantiate a separate provider.
|
||||
|
||||
The core must not reference a concrete agent package, company, product, telecom identifier or domain-specific policy. Domain-specific variants belong to the agent and should receive distinct public codes/names.
|
||||
|
||||
### Compatibility rule
|
||||
Domain policies must not be replaced by cosmetically generic text inside the core while losing the original policy. The generic core implementation and the agent-specific implementation may coexist; the embedding agent explicitly selects its own code/name in YAML.
|
||||
|
||||
Legacy business validators should migrate to the agent domain. A temporary compatibility shim is acceptable for old imports, but new application code must import the agent-owned implementation.
|
||||
|
||||
### Guardrails specification
|
||||
|
||||
> Consolidated from `specs/SPEC-005-Guardrails.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
Guardrails são políticas executadas sobre entrada, saída, tool calls, RAG e respostas finais. A plataforma suporta guardrails globais, por agente, por canal e por fase.
|
||||
|
||||
### Fases
|
||||
|
||||
| Fase | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| Input | `user_text`, `context` | `sanitized_input`, `GuardrailResult` |
|
||||
| Tool | `ToolInvocation` | tool permitida/bloqueada |
|
||||
| RAG | query/contexto recuperado | contexto aprovado/filtrado |
|
||||
| Output | `response_text` | resposta aprovada/sanitizada/bloqueada |
|
||||
| Review | resposta + evidências | decisão final |
|
||||
|
||||
### GuardrailResult
|
||||
|
||||
```json
|
||||
{
|
||||
"code": "PINJ",
|
||||
"phase": "input",
|
||||
"status": "blocked",
|
||||
"severity": "high",
|
||||
"score": 0.98,
|
||||
"message": "Entrada bloqueada por política.",
|
||||
"details": {
|
||||
"matched_policy": "prompt_injection"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuração Global
|
||||
|
||||
```yaml
|
||||
input:
|
||||
- code: MSK
|
||||
enabled: true
|
||||
mode: enforce
|
||||
- code: VLOOP
|
||||
enabled: true
|
||||
mode: enforce
|
||||
- code: PINJ
|
||||
enabled: true
|
||||
mode: enforce
|
||||
|
||||
output:
|
||||
- code: REVPREC
|
||||
enabled: true
|
||||
mode: enforce
|
||||
- code: DLEX_OUT
|
||||
enabled: true
|
||||
mode: enforce
|
||||
- code: PINJ
|
||||
enabled: true
|
||||
mode: observe
|
||||
```
|
||||
|
||||
### Configuração por Agente
|
||||
|
||||
```yaml
|
||||
agents:
|
||||
telecom_contas:
|
||||
input:
|
||||
- code: BILLING_INPUT_POLICY
|
||||
enabled: true
|
||||
mode: observe
|
||||
output:
|
||||
- code: BILLING_COMPLIANCE
|
||||
enabled: true
|
||||
mode: enforce
|
||||
```
|
||||
|
||||
### Modos
|
||||
|
||||
| Modo | Comportamento |
|
||||
|---|---|
|
||||
| `enforce` | Aplica bloqueio, máscara ou alteração. |
|
||||
| `observe` | Registra sem bloquear. |
|
||||
| `fail_open` | Em erro técnico, prossegue e emite NOC. |
|
||||
| `fail_closed` | Em erro técnico, bloqueia. |
|
||||
|
||||
### Tipos
|
||||
|
||||
| Tipo | Implementação |
|
||||
|---|---|
|
||||
| Determinístico | Regex, listas, tamanho, estrutura, regras. |
|
||||
| LLM | Classificação semântica por profile. |
|
||||
| Híbrido | Determinístico + LLM em casos ambíguos. |
|
||||
|
||||
### Profiles LLM
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
guardrail:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1
|
||||
temperature: 0
|
||||
max_tokens: 600
|
||||
|
||||
grl:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1
|
||||
temperature: 0
|
||||
max_tokens: 700
|
||||
```
|
||||
|
||||
### Fluxo
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Input] --> B[Deterministic Guardrails]
|
||||
B --> C{Blocked?}
|
||||
C -- yes --> D[Safe Response]
|
||||
C -- no --> E[LLM Guardrails]
|
||||
E --> F{Approved?}
|
||||
F -- no --> D
|
||||
F -- yes --> G[Runtime]
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `guardrail.started` | Execução iniciada. |
|
||||
| `guardrail.completed` | Execução concluída. |
|
||||
| `guardrail.blocked` | Conteúdo bloqueado. |
|
||||
| `guardrail.masked` | Conteúdo mascarado. |
|
||||
| `guardrail.failed` | Falha técnica. |
|
||||
| `guardrail.observe` | Política observacional registrada. |
|
||||
|
||||
### Códigos Base
|
||||
|
||||
| Código | Fase | Uso |
|
||||
|---|---|---|
|
||||
| `MSK` | input/output | Mascaramento. |
|
||||
| `VLOOP` | input | Detecção de loop. |
|
||||
| `PINJ` | input/output | Prompt injection. |
|
||||
| `REVPREC` | output | Revisão de precisão. |
|
||||
| `DLEX_OUT` | output | Controle de dados e linguagem na saída. |
|
||||
| `RAGSEC` | rag/output | Segurança de contexto recuperado. |
|
||||
|
||||
### Testes
|
||||
|
||||
| Teste | Objetivo |
|
||||
|---|---|
|
||||
| Unitário | Validar guardrail isolado. |
|
||||
| Config | Validar YAML e schema. |
|
||||
| Integração | Validar execução no workflow. |
|
||||
| Observabilidade | Validar eventos e traces. |
|
||||
| Negativo | Validar bloqueio. |
|
||||
| Observe-only | Validar não bloqueio. |
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Guardrails globais são carregados por YAML.
|
||||
- [ ] Guardrails por agente sobrescrevem ou complementam globais.
|
||||
- [ ] GuardrailResult é gerado para cada execução.
|
||||
- [ ] Modo enforce bloqueia quando aplicável.
|
||||
- [ ] Modo observe não bloqueia.
|
||||
- [ ] Falhas técnicas seguem política configurada.
|
||||
- [ ] Guardrails LLM usam profile dedicado.
|
||||
- [ ] Eventos e métricas são emitidos.
|
||||
- [ ] Testes cobrem casos positivos e negativos.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Evaluation specification
|
||||
|
||||
> Consolidated from `specs/SPEC-006-Evals.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
A camada de Evals executa avaliação online, avaliação offline, regressão, certificação e publicação de métricas. Ela padroniza a validação de agentes, prompts, tools, respostas e guardrails.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Online Judges | Avaliação durante a execução. |
|
||||
| Offline Evaluator | Avaliação batch de conversas. |
|
||||
| Dataset Runner | Execução de datasets versionados. |
|
||||
| Regression Runner | Comparação entre versões. |
|
||||
| Certification Suite | Validação técnica e funcional. |
|
||||
| Metrics Engine | Cálculo de métricas. |
|
||||
| Persistence | Persistência de runs e itens. |
|
||||
| Exporter | Exportação TXT.GZ/JSON/HTML. |
|
||||
| Publisher | Publicação de scores no Langfuse. |
|
||||
|
||||
### Fluxo Offline
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Start EvaluationRun] --> B[Collect Conversations]
|
||||
B --> C[Normalize Items]
|
||||
C --> D[Run Judges]
|
||||
D --> E[Calculate Metrics]
|
||||
E --> F[Persist Results]
|
||||
F --> G[Export Reports]
|
||||
G --> H[Publish Scores]
|
||||
H --> I[Complete Run]
|
||||
```
|
||||
|
||||
### EvaluationRun
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "eval-20260619-001",
|
||||
"agent_id": "telecom_contas",
|
||||
"source": "langfuse",
|
||||
"period_start": "2026-06-18T00:00:00Z",
|
||||
"period_end": "2026-06-19T00:00:00Z",
|
||||
"status": "running",
|
||||
"limit": 500,
|
||||
"metadata": {
|
||||
"profile": "judge",
|
||||
"dataset": "production-sample"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### EvaluationItem
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_id": "default:telecom_contas:session-001",
|
||||
"trace_id": "trace-001",
|
||||
"agent_id": "telecom_contas",
|
||||
"input": "Quero consultar minha fatura",
|
||||
"output": "Sua fatura está aberta...",
|
||||
"evidence": {
|
||||
"mcp_results": [],
|
||||
"rag_context": ""
|
||||
},
|
||||
"scores": {
|
||||
"quality": 0.86,
|
||||
"groundedness": 0.78,
|
||||
"safety": 1.0,
|
||||
"resolution": 0.91
|
||||
},
|
||||
"findings": []
|
||||
}
|
||||
```
|
||||
|
||||
### Métricas
|
||||
|
||||
| Métrica | Descrição | Faixa |
|
||||
|---|---|---|
|
||||
| `quality` | Clareza, completude e utilidade. | 0–1 |
|
||||
| `groundedness` | Aderência a evidências MCP/RAG. | 0–1 |
|
||||
| `safety` | Conformidade de segurança. | 0–1 |
|
||||
| `resolution` | Capacidade de resolver a intenção. | 0–1 |
|
||||
| `tool_correctness` | Uso correto de tools. | 0–1 |
|
||||
| `policy_compliance` | Aderência a regras de domínio. | 0–1 |
|
||||
|
||||
### Dataset
|
||||
|
||||
```yaml
|
||||
dataset:
|
||||
name: telecom_contas_billing
|
||||
version: 1.0.0
|
||||
items:
|
||||
- id: billing-001
|
||||
input: "Quero consultar minha fatura"
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
expected:
|
||||
route: billing_agent
|
||||
tools:
|
||||
- consultar_fatura
|
||||
min_scores:
|
||||
quality: 0.75
|
||||
groundedness: 0.70
|
||||
safety: 1.0
|
||||
```
|
||||
|
||||
### Judges
|
||||
|
||||
```yaml
|
||||
judges:
|
||||
- name: response_quality
|
||||
enabled: true
|
||||
threshold: 0.7
|
||||
profile: judge
|
||||
|
||||
- name: groundedness
|
||||
enabled: true
|
||||
threshold: 0.6
|
||||
profile: judge
|
||||
|
||||
- name: safety
|
||||
enabled: true
|
||||
threshold: 1.0
|
||||
profile: judge
|
||||
```
|
||||
|
||||
### CLI
|
||||
|
||||
```bash
|
||||
af-evaluator run \
|
||||
--agent-id telecom_contas \
|
||||
--source langfuse \
|
||||
--period-start 2026-06-18T00:00:00Z \
|
||||
--period-end 2026-06-19T00:00:00Z \
|
||||
--limit 500
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
| Método | Endpoint | Descrição |
|
||||
|---|---|---|
|
||||
| `POST` | `/evaluation/runs` | Cria run. |
|
||||
| `GET` | `/evaluation/runs/{run_id}` | Consulta run. |
|
||||
| `GET` | `/evaluation/runs/{run_id}/items` | Lista itens. |
|
||||
| `POST` | `/evaluation/datasets/{name}/run` | Executa dataset. |
|
||||
| `GET` | `/health` | Health check. |
|
||||
|
||||
### Persistência
|
||||
|
||||
| Tabela | Conteúdo |
|
||||
|---|---|
|
||||
| `EVAL_RUNS` | Runs executadas. |
|
||||
| `EVAL_ITEMS` | Conversas avaliadas. |
|
||||
| `EVAL_SCORES` | Scores por métrica. |
|
||||
| `EVAL_FINDINGS` | Achados. |
|
||||
| `EVAL_EXPORTS` | Arquivos exportados. |
|
||||
|
||||
### Certificação
|
||||
|
||||
A Certification Suite valida:
|
||||
|
||||
- endpoints de health;
|
||||
- GatewayRequest;
|
||||
- roteamento;
|
||||
- MCP tools;
|
||||
- guardrails;
|
||||
- judges;
|
||||
- memória;
|
||||
- checkpoint;
|
||||
- Langfuse/OTEL;
|
||||
- datasets mínimos;
|
||||
- evidências JSON/HTML.
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `eval.run.started` | Run iniciada. |
|
||||
| `eval.item.completed` | Item avaliado. |
|
||||
| `eval.run.completed` | Run concluída. |
|
||||
| `eval.run.failed` | Run falhou. |
|
||||
| `eval.score.published` | Score publicado. |
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Evaluator executa runs por período/agente.
|
||||
- [ ] Langfuse é fonte suportada.
|
||||
- [ ] Datasets são versionados.
|
||||
- [ ] LLM Judges usam profile `judge`.
|
||||
- [ ] Scores são persistidos.
|
||||
- [ ] TXT.GZ/JSON/HTML são exportáveis.
|
||||
- [ ] Scores podem ser publicados no Langfuse.
|
||||
- [ ] Certification Suite gera evidências.
|
||||
- [ ] Métricas mínimas são padronizadas.
|
||||
- [ ] Falhas permitem retomada por checkpoint de run.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Evaluation and certification framework
|
||||
|
||||
> Consolidated from `specs/SPEC-019-Evaluation-and-Certification-Framework.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Evaluation mede qualidade e comportamento. Certification valida prontidão técnica e funcional.
|
||||
|
||||
Evaluator responde:
|
||||
|
||||
```text
|
||||
O agente respondeu bem?
|
||||
A resposta está fundamentada?
|
||||
A tool certa foi chamada?
|
||||
Houve regressão?
|
||||
```
|
||||
|
||||
Certification responde:
|
||||
|
||||
```text
|
||||
O agente está pronto para rodar?
|
||||
Endpoints funcionam?
|
||||
MCP funciona?
|
||||
Guardrails funcionam?
|
||||
Observabilidade funciona?
|
||||
```
|
||||
|
||||
### 2. Arquitetura
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Runtime[Runtime] --> LF[Langfuse]
|
||||
LF --> Eval[Offline Evaluator]
|
||||
Dataset[Datasets] --> Eval
|
||||
Eval --> Scores[Scores]
|
||||
Eval --> Reports[Reports]
|
||||
Cert[Certification Suite] --> Runtime
|
||||
Cert --> Evidence[Evidences]
|
||||
```
|
||||
|
||||
### 3. Métricas
|
||||
|
||||
| Métrica | Descrição |
|
||||
| --- | --- |
|
||||
| quality | Clareza, completude e utilidade. |
|
||||
| groundedness | Aderência a evidências MCP/RAG. |
|
||||
| safety | Conformidade de segurança. |
|
||||
| resolution | Resolve a intenção. |
|
||||
| tool_correctness | Usa tools corretas. |
|
||||
| route_accuracy | Rota/intenção corretas. |
|
||||
| policy_compliance | Aderência à política de domínio. |
|
||||
|
||||
|
||||
### 4. Dataset
|
||||
|
||||
```yaml
|
||||
dataset:
|
||||
name: telecom_contas_regression
|
||||
version: 1.0.0
|
||||
items:
|
||||
- id: billing-001
|
||||
input: "Quero consultar minha fatura"
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
expected:
|
||||
route: billing_agent
|
||||
tools:
|
||||
- consultar_fatura
|
||||
min_scores:
|
||||
quality: 0.75
|
||||
groundedness: 0.70
|
||||
```
|
||||
|
||||
### 5. EvaluationRun
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "eval-001",
|
||||
"agent_id": "telecom_contas",
|
||||
"source": "langfuse",
|
||||
"period_start": "2026-06-18T00:00:00Z",
|
||||
"period_end": "2026-06-19T00:00:00Z",
|
||||
"status": "running"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. CLI
|
||||
|
||||
```bash
|
||||
af-evaluator run --agent-id telecom_contas --dataset datasets/telecom_contas.yaml
|
||||
```
|
||||
|
||||
### 7. Certification
|
||||
|
||||
Valida:
|
||||
|
||||
- health;
|
||||
- GatewayRequest;
|
||||
- routing;
|
||||
- identity;
|
||||
- MCP;
|
||||
- RAG;
|
||||
- guardrails;
|
||||
- judges;
|
||||
- memory;
|
||||
- checkpoint;
|
||||
- Langfuse;
|
||||
- OTEL.
|
||||
|
||||
### 8. Evidências
|
||||
|
||||
- JSON;
|
||||
- HTML;
|
||||
- TXT.GZ legado;
|
||||
- scores Langfuse;
|
||||
- logs;
|
||||
- traces;
|
||||
- screenshots quando aplicável.
|
||||
|
||||
### 9. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Dataset só com casos felizes | Baixa cobertura. | Incluir negativos e bordas. |
|
||||
| Evaluator sem baseline | Sem comparação. | Registrar baseline. |
|
||||
| Certification sem MCP real/mock | Integração não validada. | Criar tool test. |
|
||||
| Judge sem threshold | Sem critério objetivo. | Definir threshold. |
|
||||
|
||||
|
||||
### 10. Critérios de aceite
|
||||
|
||||
- [ ] Dataset versionado.
|
||||
- [ ] Evaluator executado.
|
||||
- [ ] Scores persistidos.
|
||||
- [ ] Certification executada.
|
||||
- [ ] Relatórios gerados.
|
||||
- [ ] Thresholds definidos.
|
||||
- [ ] Casos negativos incluídos.
|
||||
- [ ] Scores publicados quando aplicável.
|
||||
803
docs/developer/en/07_rag_business_context_and_grounding.md
Normal file
803
docs/developer/en/07_rag_business_context_and_grounding.md
Normal file
@@ -0,0 +1,803 @@
|
||||
|
||||
### RAG, BusinessContext and Grounding
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **RAG, providers, BusinessContext, retrieved context and grounding**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Rag, providers, businesscontext, retrieved context and grounding.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### RAG, Enterprise Providers, BusinessContext and Grounding
|
||||
|
||||
This guide covers configurable retrieval and its relationship with tools, memory and agent context.
|
||||
|
||||
### Provider selection
|
||||
|
||||
RAG is provider-based. The standard implementation and the enterprise KBDB implementation are selected through configuration rather than through domain branches in the agent code. Provider-specific connection/index settings remain environment/configuration concerns.
|
||||
|
||||
### Runtime role
|
||||
|
||||
Retrieved knowledge is injected into the execution context so the agent can ground informational responses. RAG does not replace transactional tool execution and it is not the same as long-term memory. Use RAG for external/reference knowledge, MCP for live business operations/data and LTM for durable user/customer facts.
|
||||
|
||||
### KBDB Enterprise
|
||||
|
||||
The KBDB provider is an alternative backend with its own configuration while preserving the framework-facing retrieval contract. Agent code should not need to know which provider is active.
|
||||
|
||||
### BusinessContext
|
||||
|
||||
BusinessContext v2 carries generic business identifiers resolved from domain aliases. RAG filters, tool calls and telemetry can consume these canonical keys without introducing `msisdn`, invoice/order naming or other domain fields into shared modules.
|
||||
|
||||
### MCP sufficiency and grounding
|
||||
|
||||
When a tool result already contains sufficient authoritative data for the requested answer, the runtime can avoid unnecessary retrieval/composition work according to the configured response path. Conversely, a RAG answer must not claim a transactional action occurred merely because documentation describes how the action works.
|
||||
|
||||
### Sample validation
|
||||
|
||||
The project contains sample PDFs/policies for billing, orders, products, support and business-context/RAG flow. Use them to validate ingestion/embedding/retrieval and ask targeted questions whose expected answer is present in one document.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `docs/RAG_PROVIDER_KBDB.md`
|
||||
- `docs/README_rag_samples.md`
|
||||
- `Documentacao/README_TEMPLATE_BUSINESS_CONTEXT_V2.md`
|
||||
- operational RAG/cache notes in `Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### RAG provider implementation notes
|
||||
|
||||
> Consolidated from `docs/RAG_PROVIDER_KBDB.md`.
|
||||
|
||||
O framework passa a suportar dois backends de retrieval pelo mesmo contrato `RagService`, sem alterar os agentes nem `_retrieve_rag_context()`.
|
||||
|
||||
### Seleção
|
||||
|
||||
```env
|
||||
RAG_PROVIDER=standard # default: comportamento anterior
|
||||
# ou
|
||||
RAG_PROVIDER=kbdb # KBDB enterprise
|
||||
```
|
||||
|
||||
A seleção é exclusiva por processo. Os dois RAGs não executam juntos e não compartilham vector store, graph store ou ingestão.
|
||||
|
||||
### `standard`
|
||||
|
||||
Mantém integralmente o RAG já existente no `agent_framework_oci`: `VECTOR_STORE_PROVIDER`, `GRAPH_STORE_PROVIDER`, embedding, query rewrite, compression, retrieval guardrails e geração continuam válidos.
|
||||
|
||||
### `kbdb`
|
||||
|
||||
O framework integra somente a porta estável de serving do projeto KBDB:
|
||||
|
||||
`PKG_KB_SERVING.SEARCH_KNOWLEDGE_BASE`
|
||||
|
||||
O pipeline enterprise continua externo ao runtime do agente e preserva sua própria arquitetura RAW → SILVER → GOLD, HVI/hybrid search, property graph, publicação, lifecycle, auditoria e observabilidade.
|
||||
|
||||
O envelope KBDB é adaptado para `RagResult`/`VectorDocument`; portanto os agentes existentes continuam chamando `_retrieve_rag_context()` e os retrieval guardrails do framework continuam depois do retrieval.
|
||||
|
||||
### Configuração
|
||||
|
||||
```env
|
||||
RAG_PROVIDER=kbdb
|
||||
RAG_TOP_K=5
|
||||
KBDB_DB_USER=KB_USER
|
||||
KBDB_DB_PASSWORD=...
|
||||
KBDB_DB_DSN=...
|
||||
KBDB_DB_WALLET_LOCATION=...
|
||||
KBDB_DB_WALLET_PASSWORD=...
|
||||
KBDB_SEARCH_TYPE=hybrid
|
||||
KBDB_NODE_EXPANSION=true
|
||||
KBDB_NODE_MAX_RELATED=8
|
||||
KBDB_GRAPH_CROSS_REF=false
|
||||
KBDB_MAX_CROSS_REF_HOPS=1
|
||||
KBDB_DOCUMENT_TYPE=customer_safe
|
||||
KBDB_METADATA_JSON=
|
||||
KBDB_MIN_SCORE=
|
||||
```
|
||||
|
||||
Quando `RAG_PROVIDER=kbdb`, `KBDB_DB_USER`, `KBDB_DB_PASSWORD` e `KBDB_DB_DSN` são obrigatórios. O KBDB usa conexão isolada porque pode residir em outro Autonomous. `KBDB_DB_DSN` segue a mesma semântica de `ADB_DSN`: use o alias TNS existente no `tnsnames.ora` da wallet indicada por `KBDB_DB_WALLET_LOCATION`, e não uma URL `tcps://...`.
|
||||
|
||||
### Isolamento e compatibilidade
|
||||
|
||||
- `RAG_PROVIDER=standard` não importa nem conecta ao KBDB.
|
||||
- `RAG_PROVIDER=kbdb` não instancia vector/graph stores do RAG padrão.
|
||||
- Ingestão por `RagService.add_documents()` não é permitida no modo KBDB: deve passar pelo pipeline/publicação KBDB.
|
||||
- Query rewrite e context compression continuam opcionais e são aplicados pela camada comum do framework.
|
||||
- `AgentRuntimeMixin._retrieve_rag_context()` e os agentes permanecem inalterados.
|
||||
- Falhas do KBDB seguem a semântica existente do framework: retrieval é evidência auxiliar e a exceção é convertida em metadata técnica sem derrubar a jornada.
|
||||
|
||||
|
||||
### Resposta direta de tool e RAG
|
||||
|
||||
O framework não considera mais que um resultado MCP estruturado é, por si só, uma resposta suficiente ao usuário.
|
||||
|
||||
Uma política `response.renderer` define somente **como** apresentar o resultado. Ela não encerra o fluxo antes de RAG/LLM. Para uma tool deliberadamente produzir uma resposta final direta, a aplicação deve declarar explicitamente:
|
||||
|
||||
```yaml
|
||||
response:
|
||||
mode: renderer
|
||||
renderer: meu.renderer
|
||||
direct: true
|
||||
```
|
||||
|
||||
Sem `direct: true`, o resultado da tool permanece como evidência MCP e o fluxo segue para `_retrieve_rag_context()` e composição LLM. Isso permite, por exemplo, que uma consulta operacional de plano seja combinada com conhecimento documental do KBDB quando a pergunta pedir regras, políticas ou explicações.
|
||||
|
||||
O core do framework não possui fallback por nome de tool (`consultar_plano`, `consultar_pedido`, etc.). Regras de apresentação pertencem à aplicação/domínio.
|
||||
|
||||
|
||||
### Suficiência MCP e grounding
|
||||
|
||||
Um resultado MCP bem-sucedido **não** faz o framework pular RAG automaticamente.
|
||||
O domínio só pode declarar suficiência documental explicitamente no payload com
|
||||
`rag_sufficient=true` ou `knowledge_sufficient=true`. Essa decisão é genérica e
|
||||
não depende do nome da tool nem de palavras-chave de telecom/retail.
|
||||
|
||||
No provider `kbdb`, `KBDB_GROUNDED_ONLY=true` é o padrão. Quando a busca KBDB
|
||||
retorna vazia, bloqueada ou com erro, a composição LLM pode usar fatos comprovados
|
||||
por MCP/business context, mas não pode completar a parte documental com conhecimento
|
||||
paramétrico do modelo. Deve informar que não há evidência suficiente na base.
|
||||
|
||||
Eventos do ProductAgent registram `IC.PRODUCT_RAG_CONTEXT_EVALUATED` em toda
|
||||
tentativa/decisão e `IC.PRODUCT_RAG_CONTEXT_RETRIEVED` somente quando há contexto
|
||||
recuperado. Os metadados incluem `provider`, `status`, `document_count`, `reason`,
|
||||
`error`, `query`, `namespace` e `latency_ms`.
|
||||
|
||||
### RAG sample validation guide
|
||||
|
||||
> Consolidated from `docs/README_rag_samples.md`.
|
||||
|
||||
These PDF files are synthetic, searchable sample documents created to validate the RAG embedding and retrieval flow of `agent_template_backend`.
|
||||
|
||||
### Files
|
||||
|
||||
- `01_billing_agent_invoice_policy.pdf` - sample knowledge for `billing_agent`
|
||||
- `02_orders_agent_lifecycle_policy.pdf` - sample knowledge for `orders_agent`
|
||||
- `03_product_agent_catalog_policy.pdf` - sample knowledge for `product_agent`
|
||||
- `04_support_agent_sla_policy.pdf` - sample knowledge for `support_agent`
|
||||
- `05_business_context_rag_flow.pdf` - sample knowledge about BusinessContext, identity.yaml and MCP parameter mapping
|
||||
|
||||
### How to use
|
||||
|
||||
Copy the PDF files to the backend documentation directory:
|
||||
|
||||
```bash
|
||||
mkdir -p agent_template_backend/docs/rag_samples
|
||||
cp *.pdf agent_template_backend/docs/rag_samples/
|
||||
```
|
||||
|
||||
For a local smoke test, use:
|
||||
|
||||
```env
|
||||
VECTOR_STORE_PROVIDER=sqlite
|
||||
EMBEDDING_PROVIDER=mock
|
||||
SQLITE_DB_PATH=./data/agent_framework.db
|
||||
RAG_TOP_K=4
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
python scripts/generate_rag_embeddings.py \
|
||||
--docs-dir ./agent_template_backend/docs/rag_samples \
|
||||
--namespace default
|
||||
```
|
||||
|
||||
For production-like semantic embeddings with OCI Generative AI, use:
|
||||
|
||||
```env
|
||||
VECTOR_STORE_PROVIDER=autonomous
|
||||
EMBEDDING_PROVIDER=oci
|
||||
OCI_COMPARTMENT_ID=ocid1.compartment.oc1..xxxx
|
||||
OCI_REGION=us-chicago-1
|
||||
OCI_EMBEDDING_MODEL=cohere.embed-multilingual-v3.0
|
||||
```
|
||||
|
||||
### Suggested retrieval test questions
|
||||
|
||||
- What is a prorated charge?
|
||||
- When can the OrdersAgent open an exchange request?
|
||||
- Which SKU represents the AI Agents book?
|
||||
- What is the target response for a critical support ticket?
|
||||
- How does BusinessContext map customer_key to MCP tool parameters?
|
||||
|
||||
### Runtime integration constraints
|
||||
|
||||
> Consolidated from `specs/SPEC-002-Agent-Runtime.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O Agent Runtime executa o ciclo de vida conversacional do agente. A execução inclui normalização de contexto, estado LangGraph, memória, checkpoint, roteamento, supervisor, guardrails, MCP, RAG, LLM, judges, persistência e resposta final.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Workflow Builder | Compila o grafo LangGraph. |
|
||||
| State Manager | Mantém o estado de execução. |
|
||||
| Session Manager | Resolve sessão e conversation_key. |
|
||||
| Memory Manager | Carrega e persiste histórico. |
|
||||
| Checkpoint Manager | Persiste estado LangGraph. |
|
||||
| Input Guardrail Node | Executa guardrails de entrada. |
|
||||
| Router Node | Decide rota/intent. |
|
||||
| Supervisor Node | Decide handoff ou próximo agente quando habilitado. |
|
||||
| Agent Node | Executa agente de domínio. |
|
||||
| MCP Client/Router | Executa tools por contrato. |
|
||||
| RAG Service | Recupera contexto documental. |
|
||||
| Output Supervisor | Revisa resposta antes de saída. |
|
||||
| Output Guardrail Node | Executa guardrails de saída. |
|
||||
| Judge Node | Avalia resposta. |
|
||||
| Persistence Node | Persiste mensagens, memória e checkpoint. |
|
||||
|
||||
### State Model
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
context: dict
|
||||
business_context: dict
|
||||
tool_arguments: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
rag_metadata: dict
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
metadata: dict
|
||||
errors: list[dict]
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[start] --> B[input_guardrails]
|
||||
B --> C[routing_decision]
|
||||
C --> D[agent_execution]
|
||||
D --> E[output_supervisor]
|
||||
E --> F[output_guardrails]
|
||||
F --> G[judge]
|
||||
G --> H[persist]
|
||||
H --> I[end]
|
||||
C --> J[handoff]
|
||||
J --> C
|
||||
```
|
||||
|
||||
### Nós
|
||||
|
||||
| Nó | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| `input_guardrails` | `user_text`, `context` | `sanitized_input`, `guardrails` |
|
||||
| `routing_decision` | `sanitized_input`, `business_context` | `route`, `intent`, `mcp_tools` |
|
||||
| `agent_execution` | `state` completo | `response_text`, `mcp_results`, `rag_metadata` |
|
||||
| `output_supervisor` | `response_text` | `response_text` revisado |
|
||||
| `output_guardrails` | `response_text` | `response_text`, `guardrails` |
|
||||
| `judge` | `response_text`, evidências | `judges` |
|
||||
| `persist` | `state` completo | checkpoint, memória, mensagens |
|
||||
|
||||
### Router
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
mode: router
|
||||
fallback_agent: billing_agent
|
||||
enable_llm_router: false
|
||||
intents:
|
||||
billing_invoice_explanation:
|
||||
route: billing_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- cobrança
|
||||
- boleto
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
|
||||
```yaml
|
||||
supervisor:
|
||||
enabled: true
|
||||
profile: supervisor
|
||||
max_turns: 5
|
||||
handoff_enabled: true
|
||||
fallback_route: support_agent
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
| Provider | Uso |
|
||||
|---|---|
|
||||
| `memory` | Execução local e testes. |
|
||||
| `sqlite` | Desenvolvimento local persistente. |
|
||||
| `mongodb` | Checkpoint e histórico em ambiente distribuído. |
|
||||
| `autonomous` | Produção com Oracle Autonomous Database. |
|
||||
|
||||
### Checkpoints
|
||||
|
||||
Checkpoint contém:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_key": "default:telecom_contas:session-001",
|
||||
"checkpoint_id": "ckpt-001",
|
||||
"state": {},
|
||||
"pending_writes": [],
|
||||
"created_at": "2026-06-19T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Formato entregue ao LangGraph:
|
||||
|
||||
```python
|
||||
pending_writes: list[tuple[str, str, object]]
|
||||
```
|
||||
|
||||
### Business Context
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### Ordem de Prioridade dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AgentNode --> ToolList[mcp_tools]
|
||||
ToolList --> Mapping[mcp_parameter_mapping.yaml]
|
||||
Mapping --> MCP[MCP Gateway/Router]
|
||||
MCP --> Result[mcp_results]
|
||||
```
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```yaml
|
||||
rag:
|
||||
enabled: true
|
||||
namespace_strategy: agent_id
|
||||
top_k: 5
|
||||
profile_generation: rag_generation
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `runtime.started` | Execução iniciada. |
|
||||
| `runtime.session.loaded` | Sessão carregada. |
|
||||
| `runtime.memory.loaded` | Memória carregada. |
|
||||
| `runtime.checkpoint.loaded` | Checkpoint carregado. |
|
||||
| `runtime.route.selected` | Rota selecionada. |
|
||||
| `runtime.agent.started` | Agente iniciado. |
|
||||
| `runtime.agent.completed` | Agente concluído. |
|
||||
| `runtime.persist.completed` | Persistência concluída. |
|
||||
| `runtime.failed` | Falha controlada. |
|
||||
|
||||
### Erros
|
||||
|
||||
| Código | Condição | Tratamento |
|
||||
|---|---|---|
|
||||
| `RUNTIME_INVALID_REQUEST` | GatewayRequest inválido | 422 |
|
||||
| `RUNTIME_ROUTE_NOT_FOUND` | Nenhuma rota elegível | fallback ou resposta controlada |
|
||||
| `RUNTIME_CHECKPOINT_ERROR` | Falha em checkpoint | retry ou stateless conforme config |
|
||||
| `RUNTIME_MEMORY_ERROR` | Falha em memória | retry ou resposta controlada |
|
||||
| `RUNTIME_AGENT_ERROR` | Falha no agente | NOC + fallback |
|
||||
| `RUNTIME_TIMEOUT` | Timeout geral | resposta controlada |
|
||||
|
||||
|
||||
|
||||
### Contrato Durável de Estado Transacional
|
||||
|
||||
Hosts que utilizam `AgentRuntime` com transações multi-turno DEVEM declarar no `AgentState` os campos `active_transaction` e `last_transaction`. O primeiro é a fonte canônica da transação em andamento e deve sobreviver a checkpoint/resume; o segundo mantém o snapshot da última transação terminal.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
`selected_tool_call` e `pending_tool_call` são campos auxiliares/compatibilidade e não substituem o latch canônico. Durante `COLLECTING_PARAMETERS`, a retomada da transação e o consumo de parâmetros pendentes têm precedência sobre keyword routing genérico. Uma mudança de intenção só deve interromper a transação quando for inequívoca ou explicitamente solicitada pelo usuário.
|
||||
|
||||
O contrato completo, ciclo de vida, precedência de roteamento, checklist e testes regressivos estão em [`docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Runtime recebe GatewayRequest validado.
|
||||
- [ ] State contém tenant_id, agent_id, session_id, conversation_key, route e intent.
|
||||
- [ ] Input guardrails executam antes do roteamento.
|
||||
- [ ] Router ou Supervisor seleciona rota.
|
||||
- [ ] Agent Node executa sem acessar payload bruto de canal.
|
||||
- [ ] MCP é acessado por contrato.
|
||||
- [ ] RAG é acessado por serviço reutilizável.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
- [ ] Judges geram JudgeResult.
|
||||
- [ ] Memória e checkpoint são persistidos conforme provider.
|
||||
- [ ] Hosts transacionais declaram `active_transaction` e `last_transaction` no `AgentState`.
|
||||
- [ ] Durante `COLLECTING_PARAMETERS`, respostas a parâmetros pendentes têm precedência sobre keyword routing genérico.
|
||||
- [ ] Erros geram NOC e resposta controlada.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Business context contracts
|
||||
|
||||
> Consolidated from `specs/SPEC-012-Canonical-Contracts.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Contratos canônicos são estruturas padronizadas usadas para desacoplar canais, gateways, runtime, agentes, tools, LLMs, evaluator e observabilidade.
|
||||
|
||||
A plataforma usa contratos para garantir que componentes independentes possam evoluir sem quebrar uns aos outros.
|
||||
|
||||
### 2. Problema que resolve
|
||||
|
||||
Sem contratos:
|
||||
|
||||
- cada canal envia payload diferente;
|
||||
- agentes passam a conhecer WhatsApp, Voice, Teams ou CRM;
|
||||
- MCP tools recebem parâmetros inconsistentes;
|
||||
- LLM calls ficam acopladas ao provider;
|
||||
- evaluator não consegue comparar respostas;
|
||||
- observabilidade fica fragmentada.
|
||||
|
||||
Com contratos:
|
||||
|
||||
```text
|
||||
Canal → GatewayRequest → Runtime → BusinessContext → ToolInvocation → ToolResult
|
||||
```
|
||||
|
||||
### 3. Catálogo de contratos
|
||||
|
||||
| Contrato | Uso |
|
||||
| --- | --- |
|
||||
| GatewayRequest | Entrada canônica da plataforma. |
|
||||
| ChannelResponse | Resposta canônica ao canal. |
|
||||
| BusinessContext | Identidade canônica de negócio. |
|
||||
| AgentState | Estado interno do runtime. |
|
||||
| Session | Sessão técnica/conversacional. |
|
||||
| Checkpoint | Persistência de estado LangGraph. |
|
||||
| ToolInvocation | Chamada canônica de tool MCP. |
|
||||
| ToolResult | Resposta canônica de tool MCP. |
|
||||
| LLMRequest | Chamada canônica ao AI Gateway. |
|
||||
| LLMResponse | Resposta canônica do AI Gateway. |
|
||||
| EvaluationRun | Execução do evaluator. |
|
||||
| EvaluationResult | Resultado de avaliação. |
|
||||
| CertificationResult | Resultado de certificação. |
|
||||
| EventEnvelope | Envelope de eventos IC/NOC/GRL. |
|
||||
|
||||
|
||||
### 4. GatewayRequest
|
||||
|
||||
### 4.1. Uso
|
||||
|
||||
Usado por Channel Gateway e Agent Gateway para enviar mensagens ao Runtime.
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "web",
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"payload": {
|
||||
"message": "Quero consultar minha fatura",
|
||||
"session_id": "session-001",
|
||||
"user_id": "user-001",
|
||||
"message_id": "msg-001",
|
||||
"business_context": {
|
||||
"customer_key": "11999999999",
|
||||
"contract_key": "3000131180",
|
||||
"interaction_key": "301953872",
|
||||
"session_key": "session-001"
|
||||
},
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"contract_version": "gateway-request-v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2. Campos obrigatórios
|
||||
|
||||
- `channel`;
|
||||
- `payload.message`;
|
||||
- `payload.session_id`;
|
||||
- `payload.message_id`;
|
||||
- `tenant_id` quando multi-tenant;
|
||||
- `agent_id` quando não houver roteamento global.
|
||||
|
||||
### 5. ChannelResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "web",
|
||||
"session_id": "default:telecom_contas:session-001",
|
||||
"text": "Resposta final do agente.",
|
||||
"metadata": {
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"route": "billing_agent",
|
||||
"intent": "billing_invoice_explanation",
|
||||
"guardrails": [],
|
||||
"judges": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. BusinessContext
|
||||
|
||||
### 6.1. Uso
|
||||
|
||||
BusinessContext transporta identidade de negócio sem acoplar a plataforma ao formato de cada canal.
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### 6.2. Mapeamento para MCP
|
||||
|
||||
```yaml
|
||||
tools:
|
||||
consultar_fatura:
|
||||
map:
|
||||
customer_key: msisdn
|
||||
contract_key: invoice_id
|
||||
interaction_key: ura_call_id
|
||||
session_key: session_id
|
||||
```
|
||||
|
||||
### 7. AgentState
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
business_context: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
```
|
||||
|
||||
### 8. ToolInvocation
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"tool_name": "consultar_fatura",
|
||||
"arguments": {
|
||||
"msisdn": "11999999999",
|
||||
"invoice_id": "3000131180"
|
||||
},
|
||||
"business_context": {
|
||||
"customer_key": "11999999999",
|
||||
"contract_key": "3000131180"
|
||||
},
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"trace_id": "trace-001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. ToolResult
|
||||
|
||||
```json
|
||||
{
|
||||
"tool_name": "consultar_fatura",
|
||||
"ok": true,
|
||||
"data": {
|
||||
"invoice_id": "3000131180",
|
||||
"valor_total": 249.90,
|
||||
"status": "ABERTA"
|
||||
},
|
||||
"cache": {
|
||||
"hit": false,
|
||||
"ttl_seconds": 300
|
||||
},
|
||||
"latency_ms": 140
|
||||
}
|
||||
```
|
||||
|
||||
### 10. LLMRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"profile": "judge",
|
||||
"operation": "judge.response_quality",
|
||||
"messages": [
|
||||
{"role": "system", "content": "Você é um avaliador."},
|
||||
{"role": "user", "content": "Avalie a resposta."}
|
||||
],
|
||||
"metadata": {
|
||||
"request_id": "req-001",
|
||||
"trace_id": "trace-001"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 11. LLMResponse
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "oci_openai",
|
||||
"model": "openai.gpt-4.1",
|
||||
"profile": "judge",
|
||||
"content": "Resultado",
|
||||
"usage": {
|
||||
"input_tokens": 1200,
|
||||
"output_tokens": 300,
|
||||
"total_tokens": 1500
|
||||
},
|
||||
"latency_ms": 820
|
||||
}
|
||||
```
|
||||
|
||||
### 12. EvaluationRun
|
||||
|
||||
```json
|
||||
{
|
||||
"run_id": "eval-001",
|
||||
"agent_id": "telecom_contas",
|
||||
"source": "langfuse",
|
||||
"period_start": "2026-06-18T00:00:00Z",
|
||||
"period_end": "2026-06-19T00:00:00Z",
|
||||
"status": "running"
|
||||
}
|
||||
```
|
||||
|
||||
### 13. EventEnvelope
|
||||
|
||||
```json
|
||||
{
|
||||
"event_type": "IC.AGENT_COMPLETED",
|
||||
"timestamp": "2026-06-19T12:00:00Z",
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"session_id": "session-001",
|
||||
"trace_id": "trace-001",
|
||||
"payload": {}
|
||||
}
|
||||
```
|
||||
|
||||
### 14. Regras de evolução
|
||||
|
||||
- campos novos devem ser opcionais;
|
||||
- campos obrigatórios não podem ser removidos dentro da mesma major;
|
||||
- mudança semântica exige nova versão;
|
||||
- contratos são versionados independentemente.
|
||||
|
||||
### 15. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Payload bruto no Runtime | Acopla canais ao core. | Usar GatewayRequest. |
|
||||
| Tool recebendo BusinessContext bruto sem mapping | Quebra contrato da tool. | Usar mcp_parameter_mapping.yaml. |
|
||||
| LLM direto no agente | Quebra AI Gateway. | Usar LLMRequest/profile. |
|
||||
| Campos sem versão | Dificulta migração. | Declarar contract_version. |
|
||||
|
||||
|
||||
### 16. Critérios de aceite
|
||||
|
||||
- [ ] GatewayRequest documentado e versionado.
|
||||
- [ ] ChannelResponse documentado e versionado.
|
||||
- [ ] BusinessContext usado por canais e MCP.
|
||||
- [ ] ToolInvocation e ToolResult padronizados.
|
||||
- [ ] LLMRequest e LLMResponse padronizados.
|
||||
- [ ] EvaluationRun e EvaluationResult padronizados.
|
||||
- [ ] EventEnvelope usado para IC/NOC/GRL.
|
||||
- [ ] Contratos possuem regras de evolução.
|
||||
1176
docs/developer/en/08_long_term_memory_and_checkpoint.md
Normal file
1176
docs/developer/en/08_long_term_memory_and_checkpoint.md
Normal file
File diff suppressed because it is too large
Load Diff
506
docs/developer/en/09_llm_rich_response_reasoning.md
Normal file
506
docs/developer/en/09_llm_rich_response_reasoning.md
Normal file
@@ -0,0 +1,506 @@
|
||||
|
||||
### LLM Rich Response and reasoning_content
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **`ainvoke_response()`, inference metadata and optional `reasoning_content`**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
`ainvoke_response()`, inference metadata and optional `reasoning_content`.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### LLM Rich Response and reasoning_content
|
||||
|
||||
The LLM abstraction keeps the legacy string-returning API and adds an opt-in structured response for consumers that need inference metadata.
|
||||
|
||||
### Legacy API
|
||||
|
||||
`ainvoke()` continues to return `str`. Existing agents do not need to change and callers that do not need metadata should keep using it.
|
||||
|
||||
### Rich API
|
||||
|
||||
`ainvoke_response()` returns a structured object containing the final content and, when available, `reasoning_content`, usage, model and provider metadata.
|
||||
|
||||
`reasoning_content` is optional. The framework never fabricates it. If a provider/model does not expose this field, the value is `None`. The reasoning field remains separate from final user-visible content.
|
||||
|
||||
### Backoffice use
|
||||
|
||||
A Backoffice consumer that needs model-decision metadata may opt into `ainvoke_response()` while agent runtime paths that only need final content keep using `ainvoke()`.
|
||||
|
||||
### Provider compatibility
|
||||
|
||||
Custom providers that only implement the legacy method continue to work through fallback behavior: the framework wraps the returned text as rich content and leaves reasoning metadata unset. Provider implementations that support richer metadata can override/implement the rich path directly.
|
||||
|
||||
### Testing
|
||||
|
||||
Cover legacy return type, provider with reasoning, provider without reasoning, fallback custom provider, usage/model/provider metadata and failure behavior.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `docs/LLM_RICH_RESPONSE.md`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### LLM runtime contract context
|
||||
|
||||
> Consolidated from `specs/SPEC-002-Agent-Runtime.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O Agent Runtime executa o ciclo de vida conversacional do agente. A execução inclui normalização de contexto, estado LangGraph, memória, checkpoint, roteamento, supervisor, guardrails, MCP, RAG, LLM, judges, persistência e resposta final.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Workflow Builder | Compila o grafo LangGraph. |
|
||||
| State Manager | Mantém o estado de execução. |
|
||||
| Session Manager | Resolve sessão e conversation_key. |
|
||||
| Memory Manager | Carrega e persiste histórico. |
|
||||
| Checkpoint Manager | Persiste estado LangGraph. |
|
||||
| Input Guardrail Node | Executa guardrails de entrada. |
|
||||
| Router Node | Decide rota/intent. |
|
||||
| Supervisor Node | Decide handoff ou próximo agente quando habilitado. |
|
||||
| Agent Node | Executa agente de domínio. |
|
||||
| MCP Client/Router | Executa tools por contrato. |
|
||||
| RAG Service | Recupera contexto documental. |
|
||||
| Output Supervisor | Revisa resposta antes de saída. |
|
||||
| Output Guardrail Node | Executa guardrails de saída. |
|
||||
| Judge Node | Avalia resposta. |
|
||||
| Persistence Node | Persiste mensagens, memória e checkpoint. |
|
||||
|
||||
### State Model
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
context: dict
|
||||
business_context: dict
|
||||
tool_arguments: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
rag_metadata: dict
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
metadata: dict
|
||||
errors: list[dict]
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[start] --> B[input_guardrails]
|
||||
B --> C[routing_decision]
|
||||
C --> D[agent_execution]
|
||||
D --> E[output_supervisor]
|
||||
E --> F[output_guardrails]
|
||||
F --> G[judge]
|
||||
G --> H[persist]
|
||||
H --> I[end]
|
||||
C --> J[handoff]
|
||||
J --> C
|
||||
```
|
||||
|
||||
### Nós
|
||||
|
||||
| Nó | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| `input_guardrails` | `user_text`, `context` | `sanitized_input`, `guardrails` |
|
||||
| `routing_decision` | `sanitized_input`, `business_context` | `route`, `intent`, `mcp_tools` |
|
||||
| `agent_execution` | `state` completo | `response_text`, `mcp_results`, `rag_metadata` |
|
||||
| `output_supervisor` | `response_text` | `response_text` revisado |
|
||||
| `output_guardrails` | `response_text` | `response_text`, `guardrails` |
|
||||
| `judge` | `response_text`, evidências | `judges` |
|
||||
| `persist` | `state` completo | checkpoint, memória, mensagens |
|
||||
|
||||
### Router
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
mode: router
|
||||
fallback_agent: billing_agent
|
||||
enable_llm_router: false
|
||||
intents:
|
||||
billing_invoice_explanation:
|
||||
route: billing_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- cobrança
|
||||
- boleto
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
|
||||
```yaml
|
||||
supervisor:
|
||||
enabled: true
|
||||
profile: supervisor
|
||||
max_turns: 5
|
||||
handoff_enabled: true
|
||||
fallback_route: support_agent
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
| Provider | Uso |
|
||||
|---|---|
|
||||
| `memory` | Execução local e testes. |
|
||||
| `sqlite` | Desenvolvimento local persistente. |
|
||||
| `mongodb` | Checkpoint e histórico em ambiente distribuído. |
|
||||
| `autonomous` | Produção com Oracle Autonomous Database. |
|
||||
|
||||
### Checkpoints
|
||||
|
||||
Checkpoint contém:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_key": "default:telecom_contas:session-001",
|
||||
"checkpoint_id": "ckpt-001",
|
||||
"state": {},
|
||||
"pending_writes": [],
|
||||
"created_at": "2026-06-19T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Formato entregue ao LangGraph:
|
||||
|
||||
```python
|
||||
pending_writes: list[tuple[str, str, object]]
|
||||
```
|
||||
|
||||
### Business Context
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### Ordem de Prioridade dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AgentNode --> ToolList[mcp_tools]
|
||||
ToolList --> Mapping[mcp_parameter_mapping.yaml]
|
||||
Mapping --> MCP[MCP Gateway/Router]
|
||||
MCP --> Result[mcp_results]
|
||||
```
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```yaml
|
||||
rag:
|
||||
enabled: true
|
||||
namespace_strategy: agent_id
|
||||
top_k: 5
|
||||
profile_generation: rag_generation
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `runtime.started` | Execução iniciada. |
|
||||
| `runtime.session.loaded` | Sessão carregada. |
|
||||
| `runtime.memory.loaded` | Memória carregada. |
|
||||
| `runtime.checkpoint.loaded` | Checkpoint carregado. |
|
||||
| `runtime.route.selected` | Rota selecionada. |
|
||||
| `runtime.agent.started` | Agente iniciado. |
|
||||
| `runtime.agent.completed` | Agente concluído. |
|
||||
| `runtime.persist.completed` | Persistência concluída. |
|
||||
| `runtime.failed` | Falha controlada. |
|
||||
|
||||
### Erros
|
||||
|
||||
| Código | Condição | Tratamento |
|
||||
|---|---|---|
|
||||
| `RUNTIME_INVALID_REQUEST` | GatewayRequest inválido | 422 |
|
||||
| `RUNTIME_ROUTE_NOT_FOUND` | Nenhuma rota elegível | fallback ou resposta controlada |
|
||||
| `RUNTIME_CHECKPOINT_ERROR` | Falha em checkpoint | retry ou stateless conforme config |
|
||||
| `RUNTIME_MEMORY_ERROR` | Falha em memória | retry ou resposta controlada |
|
||||
| `RUNTIME_AGENT_ERROR` | Falha no agente | NOC + fallback |
|
||||
| `RUNTIME_TIMEOUT` | Timeout geral | resposta controlada |
|
||||
|
||||
|
||||
|
||||
### Contrato Durável de Estado Transacional
|
||||
|
||||
Hosts que utilizam `AgentRuntime` com transações multi-turno DEVEM declarar no `AgentState` os campos `active_transaction` e `last_transaction`. O primeiro é a fonte canônica da transação em andamento e deve sobreviver a checkpoint/resume; o segundo mantém o snapshot da última transação terminal.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
`selected_tool_call` e `pending_tool_call` são campos auxiliares/compatibilidade e não substituem o latch canônico. Durante `COLLECTING_PARAMETERS`, a retomada da transação e o consumo de parâmetros pendentes têm precedência sobre keyword routing genérico. Uma mudança de intenção só deve interromper a transação quando for inequívoca ou explicitamente solicitada pelo usuário.
|
||||
|
||||
O contrato completo, ciclo de vida, precedência de roteamento, checklist e testes regressivos estão em [`docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Runtime recebe GatewayRequest validado.
|
||||
- [ ] State contém tenant_id, agent_id, session_id, conversation_key, route e intent.
|
||||
- [ ] Input guardrails executam antes do roteamento.
|
||||
- [ ] Router ou Supervisor seleciona rota.
|
||||
- [ ] Agent Node executa sem acessar payload bruto de canal.
|
||||
- [ ] MCP é acessado por contrato.
|
||||
- [ ] RAG é acessado por serviço reutilizável.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
- [ ] Judges geram JudgeResult.
|
||||
- [ ] Memória e checkpoint são persistidos conforme provider.
|
||||
- [ ] Hosts transacionais declaram `active_transaction` e `last_transaction` no `AgentState`.
|
||||
- [ ] Durante `COLLECTING_PARAMETERS`, respostas a parâmetros pendentes têm precedência sobre keyword routing genérico.
|
||||
- [ ] Erros geram NOC e resposta controlada.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Compatibility rules
|
||||
|
||||
> Consolidated from `specs/SPEC-013-Versioning-and-Compatibility-Model.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Versionamento define como a plataforma evolui sem quebrar projetos existentes. Compatibilidade define quais versões de framework, runtime, gateways, contracts, templates, prompts, tools e evaluator podem operar juntas.
|
||||
|
||||
### 2. Problema que resolve
|
||||
|
||||
Sem modelo de versionamento:
|
||||
|
||||
- uma mudança em GatewayRequest quebra canais;
|
||||
- uma mudança em MCP tool quebra agentes;
|
||||
- um prompt alterado muda comportamento sem rastreabilidade;
|
||||
- evaluator muda score sem histórico;
|
||||
- templates ficam incompatíveis com runtime;
|
||||
- produção usa imagem `latest` sem controle.
|
||||
|
||||
### 3. Semantic Versioning
|
||||
|
||||
Formato:
|
||||
|
||||
```text
|
||||
MAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
Regras:
|
||||
|
||||
| Parte | Significado |
|
||||
| --- | --- |
|
||||
| MAJOR | Mudança incompatível. |
|
||||
| MINOR | Nova capacidade compatível. |
|
||||
| PATCH | Correção sem mudança de contrato. |
|
||||
|
||||
|
||||
### 4. Artefatos versionados
|
||||
|
||||
| Artefato | Modelo |
|
||||
| --- | --- |
|
||||
| agent_framework | SemVer |
|
||||
| agent_runtime | SemVer alinhado ao framework |
|
||||
| agent_gateway | SemVer + Docker tag |
|
||||
| channel_gateway | SemVer + Docker tag |
|
||||
| ai_gateway | SemVer + Docker tag |
|
||||
| mcp_gateway | SemVer + Docker tag |
|
||||
| templates | versão da plataforma |
|
||||
| contracts | contract-name-vN |
|
||||
| prompts | SemVer |
|
||||
| datasets | SemVer |
|
||||
| guardrails | SemVer por código |
|
||||
| judges | SemVer por judge |
|
||||
| mcp_tools | SemVer por tool |
|
||||
| evaluator | SemVer |
|
||||
| certification_suite | SemVer + ruleset version |
|
||||
|
||||
|
||||
### 5. Contract versioning
|
||||
|
||||
Exemplos:
|
||||
|
||||
```text
|
||||
gateway-request-v1
|
||||
business-context-v1
|
||||
tool-invocation-v1
|
||||
llm-request-v1
|
||||
```
|
||||
|
||||
Permitido na mesma versão major:
|
||||
|
||||
- adicionar campos opcionais;
|
||||
- adicionar metadata;
|
||||
- adicionar enum documentado.
|
||||
|
||||
Não permitido:
|
||||
|
||||
- remover campo obrigatório;
|
||||
- mudar tipo;
|
||||
- mudar significado;
|
||||
- alterar regra obrigatória.
|
||||
|
||||
### 6. Compatibility Matrix
|
||||
|
||||
```yaml
|
||||
compatibility:
|
||||
- framework: "1.4.x"
|
||||
runtime: "1.4.x"
|
||||
agent_gateway: "1.4.x"
|
||||
supported: true
|
||||
- framework: "1.4.x"
|
||||
runtime: "2.0.x"
|
||||
supported: false
|
||||
```
|
||||
|
||||
### 7. Política de depreciação
|
||||
|
||||
Ciclo:
|
||||
|
||||
```text
|
||||
Active → Deprecated → Retired
|
||||
```
|
||||
|
||||
Período recomendado:
|
||||
|
||||
```text
|
||||
12 meses
|
||||
```
|
||||
|
||||
### 8. Política de migração
|
||||
|
||||
Mudanças major exigem:
|
||||
|
||||
- migration guide;
|
||||
- compatibility matrix;
|
||||
- rollback strategy;
|
||||
- certification;
|
||||
- evaluator;
|
||||
- release notes.
|
||||
|
||||
### 9. Estratégia de rollback
|
||||
|
||||
Rollback deve considerar:
|
||||
|
||||
- imagem Docker;
|
||||
- versão do pacote;
|
||||
- versão dos YAMLs;
|
||||
- versão do contrato;
|
||||
- migration de banco;
|
||||
- dataset;
|
||||
- prompts.
|
||||
|
||||
### 10. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Usar latest em produção | Deploy não reprodutível. | Usar tag explícita. |
|
||||
| Mudar prompt sem versão | Sem rastreabilidade. | Versionar prompt. |
|
||||
| Adicionar campo obrigatório em contrato v1 | Quebra clientes. | Criar v2. |
|
||||
| Atualizar evaluator sem baseline | Scores não comparáveis. | Registrar versão e metodologia. |
|
||||
|
||||
|
||||
### 11. Critérios de aceite
|
||||
|
||||
- [ ] Todos os componentes têm versão.
|
||||
- [ ] Contratos têm versão independente.
|
||||
- [ ] Matriz de compatibilidade publicada.
|
||||
- [ ] Release notes publicadas.
|
||||
- [ ] Migrações major possuem guide.
|
||||
- [ ] Rollback definido.
|
||||
- [ ] Prompts e datasets versionados.
|
||||
- [ ] Evaluator e certification registram versão.
|
||||
499
docs/developer/en/10_performance_cache_and_async_runtime.md
Normal file
499
docs/developer/en/10_performance_cache_and_async_runtime.md
Normal file
@@ -0,0 +1,499 @@
|
||||
|
||||
### Performance, Cache and Async Runtime
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **concurrency, caching, reduction of LLM calls and cross-loop fixes**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Concurrency, caching, reduction of llm calls and cross-loop fixes.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### Performance, Cache, Concurrency and Asynchronous Runtime
|
||||
|
||||
This guide collects optimizations that reduce latency without changing functional semantics.
|
||||
|
||||
### Optimization principles
|
||||
|
||||
Use deterministic signals before expensive semantic calls when they are reliable; execute independent work concurrently; avoid recomputing retrieval/tool metadata; cache only when correctness allows it; and keep I/O asynchronous without sharing loop-bound primitives incorrectly.
|
||||
|
||||
### MCP/RAG/Judges
|
||||
|
||||
MCP preparation and repeated metadata operations can be reused where safe. RAG should avoid repeated retrieval/embedding work through configured cache layers. Independent judges can execute concurrently instead of serially.
|
||||
|
||||
Transactional judge rules still override normal sampling optimization: performance must not skip critical evaluation.
|
||||
|
||||
### Routing optimization
|
||||
|
||||
Explicit intent-shift signals can preempt the route-continuity LLM. This reduces token consumption and latency while preserving semantic fallback for ambiguous cases.
|
||||
|
||||
### Cross-loop deadlock fix
|
||||
|
||||
Sequence generation/observability previously could wait on synchronization primitives associated with another event loop. The fix removes cross-loop waiting and keeps sequencing safe for asynchronous runtime and tests that create multiple loops.
|
||||
|
||||
### Validation
|
||||
|
||||
Performance tests should measure latency and call counts, not only functional output. Regression coverage should include concurrent judges, cached/uncached RAG behavior, MCP reuse paths, deterministic routing preemption and observer/sequence calls across separate event loops.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `docs/PERFORMANCE_OPTIMIZATIONS_MCP_JUDGES_RAG.md`
|
||||
- `Documentacao/FIX_DEADLOCK_SEQUENCE_CROSS_LOOP.md`
|
||||
- operational notes in `Documentacao/README_MAX_OPERACIONAL.md` and `README_FIRST_MAX_OPERATIONAL_FIXES.md`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### Runtime execution requirements
|
||||
|
||||
> Consolidated from `specs/SPEC-002-Agent-Runtime.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
O Agent Runtime executa o ciclo de vida conversacional do agente. A execução inclui normalização de contexto, estado LangGraph, memória, checkpoint, roteamento, supervisor, guardrails, MCP, RAG, LLM, judges, persistência e resposta final.
|
||||
|
||||
### Componentes
|
||||
|
||||
| Componente | Responsabilidade |
|
||||
|---|---|
|
||||
| Workflow Builder | Compila o grafo LangGraph. |
|
||||
| State Manager | Mantém o estado de execução. |
|
||||
| Session Manager | Resolve sessão e conversation_key. |
|
||||
| Memory Manager | Carrega e persiste histórico. |
|
||||
| Checkpoint Manager | Persiste estado LangGraph. |
|
||||
| Input Guardrail Node | Executa guardrails de entrada. |
|
||||
| Router Node | Decide rota/intent. |
|
||||
| Supervisor Node | Decide handoff ou próximo agente quando habilitado. |
|
||||
| Agent Node | Executa agente de domínio. |
|
||||
| MCP Client/Router | Executa tools por contrato. |
|
||||
| RAG Service | Recupera contexto documental. |
|
||||
| Output Supervisor | Revisa resposta antes de saída. |
|
||||
| Output Guardrail Node | Executa guardrails de saída. |
|
||||
| Judge Node | Avalia resposta. |
|
||||
| Persistence Node | Persiste mensagens, memória e checkpoint. |
|
||||
|
||||
### State Model
|
||||
|
||||
```python
|
||||
class AgentState(TypedDict, total=False):
|
||||
user_text: str
|
||||
sanitized_input: str
|
||||
response_text: str
|
||||
tenant_id: str
|
||||
agent_id: str
|
||||
channel: str
|
||||
session_id: str
|
||||
conversation_key: str
|
||||
message_id: str
|
||||
route: str
|
||||
intent: str
|
||||
context: dict
|
||||
business_context: dict
|
||||
tool_arguments: dict
|
||||
mcp_tools: list[str]
|
||||
mcp_results: list[dict]
|
||||
rag_context: str
|
||||
rag_metadata: dict
|
||||
guardrails: list[dict]
|
||||
judges: list[dict]
|
||||
metadata: dict
|
||||
errors: list[dict]
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[start] --> B[input_guardrails]
|
||||
B --> C[routing_decision]
|
||||
C --> D[agent_execution]
|
||||
D --> E[output_supervisor]
|
||||
E --> F[output_guardrails]
|
||||
F --> G[judge]
|
||||
G --> H[persist]
|
||||
H --> I[end]
|
||||
C --> J[handoff]
|
||||
J --> C
|
||||
```
|
||||
|
||||
### Nós
|
||||
|
||||
| Nó | Entrada | Saída |
|
||||
|---|---|---|
|
||||
| `input_guardrails` | `user_text`, `context` | `sanitized_input`, `guardrails` |
|
||||
| `routing_decision` | `sanitized_input`, `business_context` | `route`, `intent`, `mcp_tools` |
|
||||
| `agent_execution` | `state` completo | `response_text`, `mcp_results`, `rag_metadata` |
|
||||
| `output_supervisor` | `response_text` | `response_text` revisado |
|
||||
| `output_guardrails` | `response_text` | `response_text`, `guardrails` |
|
||||
| `judge` | `response_text`, evidências | `judges` |
|
||||
| `persist` | `state` completo | checkpoint, memória, mensagens |
|
||||
|
||||
### Router
|
||||
|
||||
```yaml
|
||||
routing:
|
||||
mode: router
|
||||
fallback_agent: billing_agent
|
||||
enable_llm_router: false
|
||||
intents:
|
||||
billing_invoice_explanation:
|
||||
route: billing_agent
|
||||
keywords:
|
||||
- fatura
|
||||
- cobrança
|
||||
- boleto
|
||||
mcp_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
```
|
||||
|
||||
### Supervisor
|
||||
|
||||
```yaml
|
||||
supervisor:
|
||||
enabled: true
|
||||
profile: supervisor
|
||||
max_turns: 5
|
||||
handoff_enabled: true
|
||||
fallback_route: support_agent
|
||||
```
|
||||
|
||||
### Memory
|
||||
|
||||
| Provider | Uso |
|
||||
|---|---|
|
||||
| `memory` | Execução local e testes. |
|
||||
| `sqlite` | Desenvolvimento local persistente. |
|
||||
| `mongodb` | Checkpoint e histórico em ambiente distribuído. |
|
||||
| `autonomous` | Produção com Oracle Autonomous Database. |
|
||||
|
||||
### Checkpoints
|
||||
|
||||
Checkpoint contém:
|
||||
|
||||
```json
|
||||
{
|
||||
"conversation_key": "default:telecom_contas:session-001",
|
||||
"checkpoint_id": "ckpt-001",
|
||||
"state": {},
|
||||
"pending_writes": [],
|
||||
"created_at": "2026-06-19T12:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
Formato entregue ao LangGraph:
|
||||
|
||||
```python
|
||||
pending_writes: list[tuple[str, str, object]]
|
||||
```
|
||||
|
||||
### Business Context
|
||||
|
||||
```yaml
|
||||
business_context:
|
||||
customer_key: "11999999999"
|
||||
contract_key: "3000131180"
|
||||
interaction_key: "301953872"
|
||||
account_key: null
|
||||
resource_key: null
|
||||
session_key: "session-001"
|
||||
metadata:
|
||||
source_channel: web
|
||||
```
|
||||
|
||||
### Ordem de Prioridade dos Dados
|
||||
|
||||
1. `tool_arguments`
|
||||
2. `business_context`
|
||||
3. `context`
|
||||
4. `session.metadata`
|
||||
5. `state`
|
||||
6. extração complementar do texto
|
||||
|
||||
### MCP Integration
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
AgentNode --> ToolList[mcp_tools]
|
||||
ToolList --> Mapping[mcp_parameter_mapping.yaml]
|
||||
Mapping --> MCP[MCP Gateway/Router]
|
||||
MCP --> Result[mcp_results]
|
||||
```
|
||||
|
||||
### RAG Integration
|
||||
|
||||
```yaml
|
||||
rag:
|
||||
enabled: true
|
||||
namespace_strategy: agent_id
|
||||
top_k: 5
|
||||
profile_generation: rag_generation
|
||||
```
|
||||
|
||||
### Eventos
|
||||
|
||||
| Evento | Descrição |
|
||||
|---|---|
|
||||
| `runtime.started` | Execução iniciada. |
|
||||
| `runtime.session.loaded` | Sessão carregada. |
|
||||
| `runtime.memory.loaded` | Memória carregada. |
|
||||
| `runtime.checkpoint.loaded` | Checkpoint carregado. |
|
||||
| `runtime.route.selected` | Rota selecionada. |
|
||||
| `runtime.agent.started` | Agente iniciado. |
|
||||
| `runtime.agent.completed` | Agente concluído. |
|
||||
| `runtime.persist.completed` | Persistência concluída. |
|
||||
| `runtime.failed` | Falha controlada. |
|
||||
|
||||
### Erros
|
||||
|
||||
| Código | Condição | Tratamento |
|
||||
|---|---|---|
|
||||
| `RUNTIME_INVALID_REQUEST` | GatewayRequest inválido | 422 |
|
||||
| `RUNTIME_ROUTE_NOT_FOUND` | Nenhuma rota elegível | fallback ou resposta controlada |
|
||||
| `RUNTIME_CHECKPOINT_ERROR` | Falha em checkpoint | retry ou stateless conforme config |
|
||||
| `RUNTIME_MEMORY_ERROR` | Falha em memória | retry ou resposta controlada |
|
||||
| `RUNTIME_AGENT_ERROR` | Falha no agente | NOC + fallback |
|
||||
| `RUNTIME_TIMEOUT` | Timeout geral | resposta controlada |
|
||||
|
||||
|
||||
|
||||
### Contrato Durável de Estado Transacional
|
||||
|
||||
Hosts que utilizam `AgentRuntime` com transações multi-turno DEVEM declarar no `AgentState` os campos `active_transaction` e `last_transaction`. O primeiro é a fonte canônica da transação em andamento e deve sobreviver a checkpoint/resume; o segundo mantém o snapshot da última transação terminal.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
`selected_tool_call` e `pending_tool_call` são campos auxiliares/compatibilidade e não substituem o latch canônico. Durante `COLLECTING_PARAMETERS`, a retomada da transação e o consumo de parâmetros pendentes têm precedência sobre keyword routing genérico. Uma mudança de intenção só deve interromper a transação quando for inequívoca ou explicitamente solicitada pelo usuário.
|
||||
|
||||
O contrato completo, ciclo de vida, precedência de roteamento, checklist e testes regressivos estão em [`docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`](../docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md).
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Runtime recebe GatewayRequest validado.
|
||||
- [ ] State contém tenant_id, agent_id, session_id, conversation_key, route e intent.
|
||||
- [ ] Input guardrails executam antes do roteamento.
|
||||
- [ ] Router ou Supervisor seleciona rota.
|
||||
- [ ] Agent Node executa sem acessar payload bruto de canal.
|
||||
- [ ] MCP é acessado por contrato.
|
||||
- [ ] RAG é acessado por serviço reutilizável.
|
||||
- [ ] Output guardrails executam antes da resposta final.
|
||||
- [ ] Judges geram JudgeResult.
|
||||
- [ ] Memória e checkpoint são persistidos conforme provider.
|
||||
- [ ] Hosts transacionais declaram `active_transaction` e `last_transaction` no `AgentState`.
|
||||
- [ ] Durante `COLLECTING_PARAMETERS`, respostas a parâmetros pendentes têm precedência sobre keyword routing genérico.
|
||||
- [ ] Erros geram NOC e resposta controlada.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Operational performance and SRE requirements
|
||||
|
||||
> Consolidated from `specs/SPEC-020-Operational-Readiness-and-SRE-Model.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Operational Readiness define os requisitos mínimos para operar a Agent Platform OCI em produção com confiabilidade, observabilidade, capacidade de resposta a incidentes e recuperação.
|
||||
|
||||
### 2. Componentes operados
|
||||
|
||||
- Agent Gateway;
|
||||
- Channel Gateway;
|
||||
- Agent Runtime;
|
||||
- AI Gateway;
|
||||
- MCP Gateway;
|
||||
- MCP Servers;
|
||||
- Evaluator;
|
||||
- bancos/repositórios;
|
||||
- Langfuse/OTEL;
|
||||
- Redis/Mongo/ADB quando usados.
|
||||
|
||||
### 3. Health e readiness
|
||||
|
||||
Endpoints mínimos:
|
||||
|
||||
```text
|
||||
GET /health
|
||||
GET /ready
|
||||
GET /version
|
||||
```
|
||||
|
||||
### 4. SLOs
|
||||
|
||||
| Componente | Latência | Disponibilidade |
|
||||
| --- | --- | --- |
|
||||
| Agent Gateway | p95 < 1s | 99.5% |
|
||||
| Agent Runtime | p95 < 5s | 99.0% |
|
||||
| AI Gateway | p95 < 10s | 99.0% |
|
||||
| MCP Gateway | p95 < 2s | 99.0% |
|
||||
| Evaluator | janela batch | execução diária |
|
||||
|
||||
|
||||
### 5. Métricas
|
||||
|
||||
- requests_total;
|
||||
- request_latency_ms;
|
||||
- errors_total;
|
||||
- active_sessions;
|
||||
- llm_tokens_total;
|
||||
- llm_cost_estimated;
|
||||
- mcp_tool_calls_total;
|
||||
- guardrail_blocks_total;
|
||||
- judge_scores;
|
||||
- evaluator_scores.
|
||||
|
||||
### 6. Dashboards
|
||||
|
||||
Dashboards mínimos:
|
||||
|
||||
- Platform Overview;
|
||||
- Runtime;
|
||||
- Gateway;
|
||||
- AI Gateway;
|
||||
- MCP Gateway;
|
||||
- Guardrails;
|
||||
- Evaluator;
|
||||
- Cost/Usage;
|
||||
- Incidents.
|
||||
|
||||
### 7. Alertas
|
||||
|
||||
| Alerta | Condição |
|
||||
| --- | --- |
|
||||
| HighErrorRate | 5xx acima do limite. |
|
||||
| LatencySLOBreach | p95 acima do SLO. |
|
||||
| LLMProviderDown | Falhas consecutivas no provider. |
|
||||
| MCPTimeoutSpike | Aumento de timeout MCP. |
|
||||
| GuardrailSpike | Aumento anômalo de bloqueios. |
|
||||
| EvaluatorFailed | Run falhou. |
|
||||
|
||||
|
||||
### 8. Runbooks
|
||||
|
||||
Runbook deve conter:
|
||||
|
||||
- sintoma;
|
||||
- impacto;
|
||||
- consultas;
|
||||
- dashboards;
|
||||
- logs;
|
||||
- ações;
|
||||
- rollback;
|
||||
- escalonamento.
|
||||
|
||||
### 9. Incident management
|
||||
|
||||
Fluxo:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Detect[Detect] --> Triage[Triage]
|
||||
Triage --> Mitigate[Mitigate]
|
||||
Mitigate --> Recover[Recover]
|
||||
Recover --> Postmortem[Postmortem]
|
||||
```
|
||||
|
||||
### 10. Capacidade
|
||||
|
||||
Avaliar:
|
||||
|
||||
- QPS;
|
||||
- sessões simultâneas;
|
||||
- tokens/minuto;
|
||||
- chamadas MCP/minuto;
|
||||
- latência de provider;
|
||||
- uso de memória;
|
||||
- storage de checkpoints.
|
||||
|
||||
### 11. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Sem readiness | Tráfego antes do app estar pronto. | Implementar /ready. |
|
||||
| Sem alertas MCP | Falha silenciosa. | Criar alertas por tool. |
|
||||
| Sem runbook | MTTR alto. | Criar runbooks por incidente. |
|
||||
| Sem custo LLM | Sem controle financeiro. | Registrar tokens/custos. |
|
||||
|
||||
|
||||
### 12. Production readiness checklist
|
||||
|
||||
- [ ] Health checks ativos.
|
||||
- [ ] Readiness checks ativos.
|
||||
- [ ] Logs estruturados.
|
||||
- [ ] Métricas exportadas.
|
||||
- [ ] Traces exportados.
|
||||
- [ ] Dashboards criados.
|
||||
- [ ] Alertas configurados.
|
||||
- [ ] Runbooks disponíveis.
|
||||
- [ ] Rollback validado.
|
||||
- [ ] SLOs definidos.
|
||||
- [ ] Capacidade estimada.
|
||||
- [ ] Incident process definido.
|
||||
@@ -0,0 +1,824 @@
|
||||
|
||||
### Observability, Persistence and Operational Readiness
|
||||
|
||||
### How to use this manual
|
||||
|
||||
This is a **specialized reference manual**. It does not replace the main tutorial.
|
||||
|
||||
- To build an agent end to end, use [`README_en.md`](../../../README_en.md).
|
||||
- Use this document when implementing, deep-diving or troubleshooting **telemetry, IC/NOC/GRL, correlation, sequencing, persistence and operational diagnostics**.
|
||||
- Historical examples consolidated here must be interpreted against the current framework API.
|
||||
- If documentation differs, the current code and root README take precedence.
|
||||
|
||||
### Relationship with the main tutorial
|
||||
|
||||
`README_en.md` introduces this capability as part of the normal development flow. This manual consolidates details previously spread across `docs/`, `Documentacao/`, release notes, validation records and specialized guides.
|
||||
|
||||
Its purpose is to answer **“how does this feature work in depth and how do I troubleshoot it?”** without becoming a second copy of the main tutorial.
|
||||
|
||||
### Scope
|
||||
|
||||
Telemetry, ic/noc/grl, correlation, sequencing, persistence and operational diagnostics.
|
||||
|
||||
### Consolidated technical content
|
||||
|
||||
### Observability, Persistence and Operational Readiness
|
||||
|
||||
This guide consolidates the FIRST-ready operational capabilities that turn the framework into an observable, persistent platform rather than a stateless demo.
|
||||
|
||||
### End-to-end correlation
|
||||
|
||||
Every request should preserve correlation across channel/gateway, selected agent, LangGraph execution, guardrails, judges, MCP calls and final response. Tenant, agent, session, request/trace and transaction identifiers should remain consistent across emitted events.
|
||||
|
||||
### Langfuse and OpenTelemetry
|
||||
|
||||
Langfuse provides LLM/trace-oriented observability while OpenTelemetry supports vendor-neutral traces/metrics/log integration. The runtime adapters should wrap the real execution path rather than emitting synthetic telemetry disconnected from the actual graph/tool call.
|
||||
|
||||
### LangGraph telemetry
|
||||
|
||||
Graph execution should be traced around the real nodes/edges so route decisions, agent execution and failures are visible. SSE responses must preserve correlation even though delivery is streamed.
|
||||
|
||||
### Persistent state
|
||||
|
||||
Enterprise configurations may use Oracle Autonomous Database for durable platform data. Checkpoints, sessions, long-term memory and analytics have different retention/consistency requirements and should not be collapsed into a single logical table just because they share a database technology.
|
||||
|
||||
### Token and cost accounting
|
||||
|
||||
Model usage metadata can be persisted/aggregated for operational and financial visibility. Rich provider usage metadata should be preferred when available; missing provider fields must not be invented.
|
||||
|
||||
### Cache
|
||||
|
||||
Enterprise cache reduces repeated work for safe reusable operations. Cache keys must include the identity/context necessary to prevent cross-agent or cross-tenant leakage.
|
||||
|
||||
### Operational validation
|
||||
|
||||
Before production, validate failure paths, telemetry delivery, disabled-observability behavior, persistence restart, SSE correlation, tool latency/error spans, guardrail/judge events and token/cost accounting. Also validate the Global Supervisor configuration if that routing mode is used.
|
||||
|
||||
### Source material consolidated
|
||||
|
||||
- `Documentacao/README_FIRST_READY.md`
|
||||
- `Documentacao/README_FIRST_ENTERPRISE_PLUS.md`
|
||||
- `Documentacao/README_FIRST_ENTERPRISE_DELTA.md`
|
||||
- `Documentacao/README_MAX_OPERACIONAL.md`
|
||||
- Global Supervisor validation records under `docs/`
|
||||
|
||||
### Detailed normative and implementation reference
|
||||
|
||||
The sections below preserve the detailed English project specifications and implementation guides relevant to this capability. They are included here so a developer does not need to reconstruct the behavior from separate documents.
|
||||
|
||||
### Observability specification
|
||||
|
||||
> Consolidated from `specs/SPEC-007-Observability.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
Observabilidade cobre logs, métricas, traces, eventos IC/NOC/GRL, Langfuse, OpenTelemetry, dashboards, alertas e evidências operacionais.
|
||||
|
||||
### Correlação
|
||||
|
||||
Campos obrigatórios:
|
||||
|
||||
```text
|
||||
request_id
|
||||
trace_id
|
||||
session_id
|
||||
conversation_key
|
||||
tenant_id
|
||||
agent_id
|
||||
channel
|
||||
message_id
|
||||
route
|
||||
intent
|
||||
```
|
||||
|
||||
### Logs
|
||||
|
||||
Formato:
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": "2026-06-19T12:00:00Z",
|
||||
"level": "INFO",
|
||||
"service": "agent-runtime",
|
||||
"event": "runtime.route.selected",
|
||||
"tenant_id": "default",
|
||||
"agent_id": "telecom_contas",
|
||||
"session_id": "default:telecom_contas:session-001",
|
||||
"trace_id": "trace-001",
|
||||
"route": "billing_agent",
|
||||
"intent": "billing_invoice_explanation"
|
||||
}
|
||||
```
|
||||
|
||||
### Traces
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
T[conversation trace] --> A[gateway.received]
|
||||
T --> B[channel.normalized]
|
||||
T --> C[runtime.started]
|
||||
T --> D[guardrails.input]
|
||||
T --> E[routing]
|
||||
T --> F[agent.execution]
|
||||
F --> G[mcp.tool]
|
||||
F --> H[llm.generation]
|
||||
T --> I[guardrails.output]
|
||||
T --> J[judges]
|
||||
T --> K[persist]
|
||||
```
|
||||
|
||||
### Métricas
|
||||
|
||||
| Métrica | Dimensões |
|
||||
|---|---|
|
||||
| `requests_total` | service, tenant, agent, channel, status |
|
||||
| `request_latency_ms` | service, route, intent |
|
||||
| `active_sessions` | tenant, agent |
|
||||
| `llm_tokens_total` | provider, model, profile |
|
||||
| `llm_cost_estimated` | provider, model, tenant, agent |
|
||||
| `mcp_tool_calls_total` | tool, server, status |
|
||||
| `mcp_tool_latency_ms` | tool, server |
|
||||
| `guardrail_blocks_total` | code, phase, agent |
|
||||
| `judge_scores` | metric, agent, route |
|
||||
| `errors_total` | service, component, error_type |
|
||||
|
||||
### Langfuse
|
||||
|
||||
Dados registrados:
|
||||
|
||||
- trace de conversa;
|
||||
- spans técnicos;
|
||||
- generations LLM;
|
||||
- prompts e respostas quando permitido;
|
||||
- tokens;
|
||||
- custos;
|
||||
- latência;
|
||||
- scores;
|
||||
- metadados;
|
||||
- erros.
|
||||
|
||||
### OpenTelemetry
|
||||
|
||||
Configuração:
|
||||
|
||||
```yaml
|
||||
otel:
|
||||
enabled: true
|
||||
service_name: agent-runtime
|
||||
exporter: otlp
|
||||
endpoint: http://otel-collector:4317
|
||||
```
|
||||
|
||||
### IC/NOC/GRL
|
||||
|
||||
| Família | Eventos |
|
||||
|---|---|
|
||||
| IC | `IC.GATEWAY_RECEIVED`, `IC.AGENT_STARTED`, `IC.AGENT_COMPLETED` |
|
||||
| NOC | `NOC.RUNTIME_FAILED`, `NOC.MCP_TIMEOUT`, `NOC.LLM_FAILED` |
|
||||
| GRL | `GRL.INPUT_BLOCKED`, `GRL.OUTPUT_BLOCKED`, `GRL.MASK_APPLIED` |
|
||||
|
||||
### Dashboards
|
||||
|
||||
| Dashboard | Conteúdo |
|
||||
|---|---|
|
||||
| Platform Overview | tráfego, erros, latência, sessões. |
|
||||
| Agent Runtime | rotas, intents, memória, checkpoints. |
|
||||
| LLM Usage | tokens, custo, latência, provider/model. |
|
||||
| MCP Operations | chamadas, erros, cache, latência. |
|
||||
| Guardrails | bloqueios, observe-only, códigos. |
|
||||
| Evals | scores, trends, regressões. |
|
||||
| Channels | tráfego por canal, erros, retries. |
|
||||
|
||||
### Alertas
|
||||
|
||||
| Alerta | Condição |
|
||||
|---|---|
|
||||
| `GatewayHighErrorRate` | Erros 5xx acima do limite. |
|
||||
| `RuntimeLatencyHigh` | p95 acima do SLO. |
|
||||
| `LLMProviderUnavailable` | falhas consecutivas de provider. |
|
||||
| `MCPToolTimeoutSpike` | aumento de timeouts. |
|
||||
| `GuardrailBlockSpike` | aumento anômalo de bloqueios. |
|
||||
| `EvaluatorRunFailed` | run batch falhou. |
|
||||
| `CheckpointFailure` | falha persistente em checkpoint. |
|
||||
|
||||
### Mascaramento
|
||||
|
||||
Campos mascarados:
|
||||
|
||||
- tokens;
|
||||
- API keys;
|
||||
- senhas;
|
||||
- secrets;
|
||||
- CPF/CNPJ, quando aplicável;
|
||||
- telefone, quando configurado;
|
||||
- payload bruto de canal;
|
||||
- documentos sensíveis.
|
||||
|
||||
### Evidências
|
||||
|
||||
Relatórios de homologação incluem:
|
||||
|
||||
- health checks;
|
||||
- logs de execução;
|
||||
- traces Langfuse;
|
||||
- métricas;
|
||||
- resultados de guardrails;
|
||||
- resultados de judges;
|
||||
- chamadas MCP;
|
||||
- chamadas LLM;
|
||||
- relatório do evaluator;
|
||||
- relatório da certification suite.
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Todos os serviços emitem logs estruturados.
|
||||
- [ ] Trace correlaciona gateway, runtime, MCP, LLM, guardrails e judges.
|
||||
- [ ] Langfuse recebe traces quando habilitado.
|
||||
- [ ] OTEL exporta spans quando habilitado.
|
||||
- [ ] Métricas mínimas estão disponíveis.
|
||||
- [ ] Dashboards estão definidos.
|
||||
- [ ] Alertas estão definidos.
|
||||
- [ ] Segredos e PII são mascarados.
|
||||
- [ ] Evaluator consome dados observáveis.
|
||||
- [ ] Certification Suite gera evidências.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Operational readiness and SRE model
|
||||
|
||||
> Consolidated from `specs/SPEC-020-Operational-Readiness-and-SRE-Model.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Operational Readiness define os requisitos mínimos para operar a Agent Platform OCI em produção com confiabilidade, observabilidade, capacidade de resposta a incidentes e recuperação.
|
||||
|
||||
### 2. Componentes operados
|
||||
|
||||
- Agent Gateway;
|
||||
- Channel Gateway;
|
||||
- Agent Runtime;
|
||||
- AI Gateway;
|
||||
- MCP Gateway;
|
||||
- MCP Servers;
|
||||
- Evaluator;
|
||||
- bancos/repositórios;
|
||||
- Langfuse/OTEL;
|
||||
- Redis/Mongo/ADB quando usados.
|
||||
|
||||
### 3. Health e readiness
|
||||
|
||||
Endpoints mínimos:
|
||||
|
||||
```text
|
||||
GET /health
|
||||
GET /ready
|
||||
GET /version
|
||||
```
|
||||
|
||||
### 4. SLOs
|
||||
|
||||
| Componente | Latência | Disponibilidade |
|
||||
| --- | --- | --- |
|
||||
| Agent Gateway | p95 < 1s | 99.5% |
|
||||
| Agent Runtime | p95 < 5s | 99.0% |
|
||||
| AI Gateway | p95 < 10s | 99.0% |
|
||||
| MCP Gateway | p95 < 2s | 99.0% |
|
||||
| Evaluator | janela batch | execução diária |
|
||||
|
||||
|
||||
### 5. Métricas
|
||||
|
||||
- requests_total;
|
||||
- request_latency_ms;
|
||||
- errors_total;
|
||||
- active_sessions;
|
||||
- llm_tokens_total;
|
||||
- llm_cost_estimated;
|
||||
- mcp_tool_calls_total;
|
||||
- guardrail_blocks_total;
|
||||
- judge_scores;
|
||||
- evaluator_scores.
|
||||
|
||||
### 6. Dashboards
|
||||
|
||||
Dashboards mínimos:
|
||||
|
||||
- Platform Overview;
|
||||
- Runtime;
|
||||
- Gateway;
|
||||
- AI Gateway;
|
||||
- MCP Gateway;
|
||||
- Guardrails;
|
||||
- Evaluator;
|
||||
- Cost/Usage;
|
||||
- Incidents.
|
||||
|
||||
### 7. Alertas
|
||||
|
||||
| Alerta | Condição |
|
||||
| --- | --- |
|
||||
| HighErrorRate | 5xx acima do limite. |
|
||||
| LatencySLOBreach | p95 acima do SLO. |
|
||||
| LLMProviderDown | Falhas consecutivas no provider. |
|
||||
| MCPTimeoutSpike | Aumento de timeout MCP. |
|
||||
| GuardrailSpike | Aumento anômalo de bloqueios. |
|
||||
| EvaluatorFailed | Run falhou. |
|
||||
|
||||
|
||||
### 8. Runbooks
|
||||
|
||||
Runbook deve conter:
|
||||
|
||||
- sintoma;
|
||||
- impacto;
|
||||
- consultas;
|
||||
- dashboards;
|
||||
- logs;
|
||||
- ações;
|
||||
- rollback;
|
||||
- escalonamento.
|
||||
|
||||
### 9. Incident management
|
||||
|
||||
Fluxo:
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
Detect[Detect] --> Triage[Triage]
|
||||
Triage --> Mitigate[Mitigate]
|
||||
Mitigate --> Recover[Recover]
|
||||
Recover --> Postmortem[Postmortem]
|
||||
```
|
||||
|
||||
### 10. Capacidade
|
||||
|
||||
Avaliar:
|
||||
|
||||
- QPS;
|
||||
- sessões simultâneas;
|
||||
- tokens/minuto;
|
||||
- chamadas MCP/minuto;
|
||||
- latência de provider;
|
||||
- uso de memória;
|
||||
- storage de checkpoints.
|
||||
|
||||
### 11. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Sem readiness | Tráfego antes do app estar pronto. | Implementar /ready. |
|
||||
| Sem alertas MCP | Falha silenciosa. | Criar alertas por tool. |
|
||||
| Sem runbook | MTTR alto. | Criar runbooks por incidente. |
|
||||
| Sem custo LLM | Sem controle financeiro. | Registrar tokens/custos. |
|
||||
|
||||
|
||||
### 12. Production readiness checklist
|
||||
|
||||
- [ ] Health checks ativos.
|
||||
- [ ] Readiness checks ativos.
|
||||
- [ ] Logs estruturados.
|
||||
- [ ] Métricas exportadas.
|
||||
- [ ] Traces exportados.
|
||||
- [ ] Dashboards criados.
|
||||
- [ ] Alertas configurados.
|
||||
- [ ] Runbooks disponíveis.
|
||||
- [ ] Rollback validado.
|
||||
- [ ] SLOs definidos.
|
||||
- [ ] Capacidade estimada.
|
||||
- [ ] Incident process definido.
|
||||
|
||||
### Deployment operational requirements
|
||||
|
||||
> Consolidated from `specs/SPEC-008-Deployment.md`.
|
||||
|
||||
### Escopo
|
||||
|
||||
Deployment cobre empacotamento, CI/CD, Kubernetes/OKE, Docker, secrets, autenticação OCI, health checks, rollback e operação dos componentes.
|
||||
|
||||
### Componentes Deployáveis
|
||||
|
||||
| Componente | Artefato |
|
||||
|---|---|
|
||||
| Agent Gateway | Docker image + Kubernetes Deployment |
|
||||
| Channel Gateway | Docker image + Kubernetes Deployment |
|
||||
| AI Gateway | Docker image + Kubernetes Deployment |
|
||||
| MCP Gateway | Docker image + Kubernetes Deployment |
|
||||
| Agent Backend | Docker image + Kubernetes Deployment |
|
||||
| MCP Server | Docker image + Kubernetes Deployment |
|
||||
| Evaluator API | Docker image + Kubernetes Deployment |
|
||||
| Evaluator Batch | Kubernetes CronJob |
|
||||
| Frontend Demo | Docker image opcional |
|
||||
|
||||
### Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[Commit] --> B[Lint]
|
||||
B --> C[Type Check]
|
||||
C --> D[Unit Tests]
|
||||
D --> E[Contract Tests]
|
||||
E --> F[Security Scan]
|
||||
F --> G[Build Wheel]
|
||||
G --> H[Build Images]
|
||||
H --> I[Publish]
|
||||
I --> J[Deploy Dev]
|
||||
J --> K[Smoke Tests]
|
||||
K --> L[Certification]
|
||||
L --> M[Deploy HML/Prod]
|
||||
```
|
||||
|
||||
### Stages
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- validate
|
||||
- lint
|
||||
- type_check
|
||||
- unit_test
|
||||
- contract_test
|
||||
- security_scan
|
||||
- build_package
|
||||
- build_image
|
||||
- publish
|
||||
- deploy_dev
|
||||
- smoke_test
|
||||
- certification
|
||||
- deploy_hml
|
||||
- deploy_prod
|
||||
```
|
||||
|
||||
### Kubernetes Deployment
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: agent-runtime
|
||||
labels:
|
||||
app: agent-runtime
|
||||
component: runtime
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: agent-runtime
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: agent-runtime
|
||||
spec:
|
||||
serviceAccountName: agent-runtime-sa
|
||||
containers:
|
||||
- name: agent-runtime
|
||||
image: registry/agent-runtime:1.0.0
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: agent-runtime-config
|
||||
- secretRef:
|
||||
name: agent-runtime-secrets
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /ready
|
||||
port: 8000
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: 8000
|
||||
```
|
||||
|
||||
### Service
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: agent-runtime
|
||||
spec:
|
||||
selector:
|
||||
app: agent-runtime
|
||||
ports:
|
||||
- port: 8000
|
||||
targetPort: 8000
|
||||
```
|
||||
|
||||
### OCI Authentication
|
||||
|
||||
| Ambiente | Modo |
|
||||
|---|---|
|
||||
| Local | `config_file` |
|
||||
| Local com endpoint OpenAI-Compatible | API key |
|
||||
| OCI Compute | `instance_principal` |
|
||||
| OKE | `workload_identity` ou `resource_principal` |
|
||||
| Testes | `mock` |
|
||||
|
||||
### Variáveis
|
||||
|
||||
```env
|
||||
LLM_PROVIDER=oci_sdk
|
||||
OCI_AUTH_MODE=workload_identity
|
||||
ENABLE_LANGFUSE=true
|
||||
ENABLE_OTEL=true
|
||||
SESSION_REPOSITORY_PROVIDER=autonomous
|
||||
MEMORY_REPOSITORY_PROVIDER=autonomous
|
||||
CHECKPOINT_REPOSITORY_PROVIDER=autonomous
|
||||
```
|
||||
|
||||
### Secrets
|
||||
|
||||
| Secret | Uso |
|
||||
|---|---|
|
||||
| `LANGFUSE_PUBLIC_KEY` | Langfuse |
|
||||
| `LANGFUSE_SECRET_KEY` | Langfuse |
|
||||
| `OCI_GENAI_API_KEY` | OCI OpenAI-Compatible |
|
||||
| `ADB_PASSWORD` | Autonomous Database |
|
||||
| `MCP_BACKEND_TOKEN` | Integrações MCP |
|
||||
| `OTEL_AUTH_TOKEN` | Exportador OTEL, se aplicável |
|
||||
|
||||
### Health Checks
|
||||
|
||||
| Endpoint | Uso |
|
||||
|---|---|
|
||||
| `/health` | Processo vivo. |
|
||||
| `/ready` | Pronto para tráfego. |
|
||||
| `/version` | Versão de build. |
|
||||
| `/debug/env` | Ambiente sem segredos, quando habilitado. |
|
||||
|
||||
### Rollback
|
||||
|
||||
Itens considerados:
|
||||
|
||||
- tag da imagem;
|
||||
- versão do pacote Python;
|
||||
- versão dos schemas;
|
||||
- versão dos YAMLs;
|
||||
- migrations;
|
||||
- datasets de eval;
|
||||
- contracts;
|
||||
- dashboards.
|
||||
|
||||
### Smoke Tests
|
||||
|
||||
```bash
|
||||
curl -f http://agent-runtime:8000/health
|
||||
curl -f http://agent-gateway:9000/health
|
||||
curl -f http://mcp-gateway:8300/health
|
||||
curl -f http://ai-gateway:9100/health
|
||||
```
|
||||
|
||||
### Certification Stage
|
||||
|
||||
A pipeline executa:
|
||||
|
||||
- health checks;
|
||||
- contrato GatewayRequest;
|
||||
- roteamento;
|
||||
- MCP invoke;
|
||||
- LLM mock/real conforme ambiente;
|
||||
- guardrails;
|
||||
- judges;
|
||||
- memória/checkpoint;
|
||||
- relatório JSON/HTML.
|
||||
|
||||
|
||||
### Requisitos Não Funcionais
|
||||
|
||||
| Categoria | Requisito |
|
||||
|---|---|
|
||||
| Disponibilidade | Componentes deployáveis expõem `/health` e `/ready`. |
|
||||
| Escalabilidade | Apps stateless escalam horizontalmente. Estado conversacional fica em repositórios externos. |
|
||||
| Segurança | Segredos são fornecidos por secret store ou Kubernetes Secrets. |
|
||||
| Observabilidade | Logs, métricas e traces usam correlação por request_id, trace_id, session_id, tenant_id e agent_id. |
|
||||
| Auditabilidade | Decisões de rota, guardrail, judge, MCP e LLM são rastreáveis. |
|
||||
| Portabilidade | Execução suportada em local, Docker Compose e Kubernetes/OKE. |
|
||||
| Configuração | Comportamento variável é controlado por `.env` e YAML versionado. |
|
||||
|
||||
|
||||
### Critérios de Aceite
|
||||
|
||||
- [ ] Cada app possui Dockerfile.
|
||||
- [ ] Cada app possui manifest Kubernetes.
|
||||
- [ ] CI executa lint, type check e testes.
|
||||
- [ ] Contract tests validam contratos principais.
|
||||
- [ ] Security scan executa antes do publish.
|
||||
- [ ] Secrets não são versionados.
|
||||
- [ ] Workload Identity está configurado em OKE.
|
||||
- [ ] Health/readiness/liveness estão ativos.
|
||||
- [ ] Smoke tests rodam após deploy.
|
||||
- [ ] Rollback está documentado.
|
||||
|
||||
|
||||
### Glossário
|
||||
|
||||
| Termo | Definição |
|
||||
|---|---|
|
||||
| Agent Platform | Plataforma composta por runtime, gateways, evaluator, templates, contratos e componentes operacionais. |
|
||||
| Agent Framework | Biblioteca/core reutilizável com contratos, guardrails, judges, memória, telemetria, providers e utilitários. |
|
||||
| Agent Runtime | Motor de execução de agentes baseado em LangGraph, estado, sessão, memória, checkpoints, roteamento e ciclo de vida. |
|
||||
| Agent Gateway | Aplicação deployável de entrada, roteamento e orquestração entre backends/agentes. |
|
||||
| Channel Gateway | Aplicação ou módulo de normalização de payloads de canais para GatewayRequest. |
|
||||
| AI Gateway | Aplicação de governança, roteamento e abstração de chamadas LLM/embedding. |
|
||||
| MCP Gateway | Aplicação de governança e roteamento de tools MCP. |
|
||||
| Evaluator | Camada de avaliação online/offline, regressão e certificação. |
|
||||
| Business Context | Conjunto de chaves canônicas de negócio: customer_key, contract_key, interaction_key, account_key, resource_key e session_key. |
|
||||
|
||||
### Release management and CI/CD
|
||||
|
||||
> Consolidated from `specs/SPEC-017-Release-Management-and-CICD.md`.
|
||||
|
||||
### Agent Platform OCI
|
||||
|
||||
Version: 1.0.0
|
||||
|
||||
|
||||
---
|
||||
|
||||
### Padrão de leitura
|
||||
|
||||
Cada SPEC está organizada para servir tanto como contrato arquitetural quanto como guia prático de adoção.
|
||||
|
||||
A estrutura usada é:
|
||||
|
||||
1. Conceito.
|
||||
2. Problema que resolve.
|
||||
3. Quando usar.
|
||||
4. Quando não usar.
|
||||
5. Arquitetura.
|
||||
6. Implementação.
|
||||
7. Exemplos.
|
||||
8. Erros comuns.
|
||||
9. Critérios de aceite.
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 1. Conceito
|
||||
|
||||
Release management define como mudanças entram na plataforma, são testadas, empacotadas, publicadas, promovidas e auditadas.
|
||||
|
||||
CI/CD automatiza validações e reduz risco operacional.
|
||||
|
||||
### 2. Pipeline padrão
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
C[Commit] --> L[Lint]
|
||||
L --> TC[Type Check]
|
||||
TC --> UT[Unit Tests]
|
||||
UT --> IT[Integration Tests]
|
||||
IT --> CT[Contract Tests]
|
||||
CT --> SS[Security Scan]
|
||||
SS --> B[Build]
|
||||
B --> P[Publish]
|
||||
P --> DD[Deploy Dev]
|
||||
DD --> ST[Smoke Tests]
|
||||
ST --> CERT[Certification]
|
||||
CERT --> HML[Deploy HML]
|
||||
HML --> PROD[Deploy Prod]
|
||||
```
|
||||
|
||||
### 3. Stages
|
||||
|
||||
| Stage | Função |
|
||||
| --- | --- |
|
||||
| validate | Validação inicial de estrutura. |
|
||||
| lint | Estilo e erros simples. |
|
||||
| type_check | Tipos e contratos Python. |
|
||||
| unit_test | Testes unitários. |
|
||||
| integration_test | Integrações locais. |
|
||||
| contract_test | Contratos JSON/YAML/API. |
|
||||
| security_scan | Dependências, secrets e imagens. |
|
||||
| build_package | Wheel/package. |
|
||||
| build_image | Imagem Docker. |
|
||||
| publish | Registry/artifacts. |
|
||||
| deploy_dev | Ambiente dev. |
|
||||
| smoke_test | Health e chamadas básicas. |
|
||||
| certification | Certification Suite. |
|
||||
| deploy_hml | Homologação. |
|
||||
| deploy_prod | Produção. |
|
||||
|
||||
|
||||
### 4. Artefatos de release
|
||||
|
||||
- imagem Docker;
|
||||
- pacote Python;
|
||||
- release notes;
|
||||
- matriz de compatibilidade;
|
||||
- migration guide quando necessário;
|
||||
- evaluator report;
|
||||
- certification report;
|
||||
- SBOM quando aplicável;
|
||||
- evidência de scan;
|
||||
- changelog.
|
||||
|
||||
### 5. Exemplo de pipeline
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
- contract
|
||||
- security
|
||||
- build
|
||||
- publish
|
||||
- deploy
|
||||
- certification
|
||||
```
|
||||
|
||||
### 6. Gates
|
||||
|
||||
| Gate | Quando aplica |
|
||||
| --- | --- |
|
||||
| Architecture Gate | Mudanças estruturais, contratos, runtime, gateways. |
|
||||
| Security Gate | Segredos, identidade, dados sensíveis, MCP externo. |
|
||||
| Quality Gate | Testes, evaluator, certification. |
|
||||
| Operations Gate | Dashboards, alertas, runbook, rollback. |
|
||||
|
||||
|
||||
### 7. Estratégia de rollback
|
||||
|
||||
Rollback deve restaurar:
|
||||
|
||||
- imagem anterior;
|
||||
- configuração anterior;
|
||||
- contrato anterior;
|
||||
- prompt anterior;
|
||||
- dataset anterior quando necessário;
|
||||
- migration de banco quando aplicável.
|
||||
|
||||
### 8. Erros comuns
|
||||
|
||||
| Erro | Impacto | Correção |
|
||||
| --- | --- | --- |
|
||||
| Deploy sem certification | Risco funcional. | Rodar certification no pipeline. |
|
||||
| Sem release notes | Sem rastreabilidade. | Publicar release notes. |
|
||||
| Sem contract tests | Quebra integração. | Adicionar testes de contrato. |
|
||||
| Sem rollback | Risco operacional. | Definir estratégia de rollback. |
|
||||
|
||||
|
||||
### 9. Critérios de aceite
|
||||
|
||||
- [ ] Pipeline executa lint, type check e testes.
|
||||
- [ ] Contract tests executam.
|
||||
- [ ] Security scan executa.
|
||||
- [ ] Imagem Docker gerada.
|
||||
- [ ] Artifacts publicados.
|
||||
- [ ] Smoke tests executados.
|
||||
- [ ] Certification executada.
|
||||
- [ ] Release notes publicadas.
|
||||
- [ ] Rollback definido.
|
||||
- [ ] Evidências arquivadas.
|
||||
129
docs/developer/en/INDEX_DEVELOPER_GUIDE.md
Normal file
129
docs/developer/en/INDEX_DEVELOPER_GUIDE.md
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
### Developer Index — Agent Framework OCI
|
||||
|
||||
### How to use this documentation
|
||||
|
||||
The documentation has three clear levels:
|
||||
|
||||
1. **Main tutorial:** [`README_en.md`](../../../README_en.md) — build, configure, run and test an agent end to end.
|
||||
2. **Architecture:** [01 — Architecture and Concepts](./01_architecture_and_concepts.md) — components, boundaries and implementation placement.
|
||||
3. **Specialized references:** manuals `02` through `11` — deep implementation and troubleshooting by capability.
|
||||
|
||||
If you are creating a new agent, start with the main README.
|
||||
|
||||
If something is not working, use **Search by problem** below.
|
||||
|
||||
### Search by problem
|
||||
|
||||
| Problem / question | Usually involves | Go to |
|
||||
|---|---|---|
|
||||
| Framework selects the wrong agent/intent | routing, intents, thresholds, deterministic/LLM mode | [Routing and Stickiness](./02_routing_stickiness_and_intent_shift.md) |
|
||||
| Agent stays stuck on the same subject | route stickiness, intent shift, handoff | [Routing and Stickiness](./02_routing_stickiness_and_intent_shift.md) |
|
||||
| A parameter answer is mistaken for a new intent | transaction precedence, parameter extraction | [Transactional Workflows](./03_transaction_workflows_and_state.md) |
|
||||
| Transaction keeps asking for the same parameter | transaction state, extractor, schema | [Transactional Workflows](./03_transaction_workflows_and_state.md) and [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| “yes/no” confirmation does not continue the flow | confirmation state | [Transactional Workflows](./03_transaction_workflows_and_state.md) |
|
||||
| A closed transaction reappears | old checkpoint vs active transaction | [Transactional Workflows](./03_transaction_workflows_and_state.md) and [LTM/Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| System claims an operation ran but there is no evidence | MCP results, `COMPLETED`, transaction judges | [Transactional Workflows](./03_transaction_workflows_and_state.md) and [Guardrails/Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| A tool is missing | tools config, MCP catalog/discovery | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| MCP Server is missing from catalog | registration, manifest/discovery, MCP Gateway | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) and [Gateways](./05_agent_gateway_mcp_gateway_and_auth.md) |
|
||||
| Tool parameters are wrong | schema, mapping, BusinessContext, extraction | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| Transactional tool executes without confirmation | policy, `require_confirmation` | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| 401 between gateway/backend/MCP | Basic Auth, hop credentials | [Gateways and Auth](./05_agent_gateway_mcp_gateway_and_auth.md) |
|
||||
| Need to decide framework vs agent ownership | core/agent boundary | [Architecture and Concepts](./01_architecture_and_concepts.md) |
|
||||
| Agent-specific guardrail breaks another agent | extension model, domain imports | [Guardrails and Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| Judge does not run for a transaction | sampling, transaction signals | [Guardrails and Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| Groundedness gets the wrong context | RAG context, MCP evidence, judge inputs | [RAG/Grounding](./07_rag_business_context_and_grounding.md) |
|
||||
| RAG returns no useful content | provider, ingestion, embeddings | [RAG/Grounding](./07_rag_business_context_and_grounding.md) |
|
||||
| Unsure whether to use RAG, memory or a tool | responsibility separation | [Architecture and Concepts](./01_architecture_and_concepts.md) |
|
||||
| Memory disappears across sessions | LTM vs conversation memory | [LTM and Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| Memory leaks across customer/agent | identity isolation | [LTM and Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| Need `reasoning_content` | `ainvoke_response()` | [LLM Rich Response](./09_llm_rich_response_reasoning.md) |
|
||||
| `reasoning_content` is `None` | provider/model does not expose it | [LLM Rich Response](./09_llm_rich_response_reasoning.md) |
|
||||
| Too many LLM calls | deterministic routing, concurrency, cache | [Performance](./10_performance_cache_and_async_runtime.md) |
|
||||
| Deadlock across event loops | cross-loop runtime/sequence | [Performance](./10_performance_cache_and_async_runtime.md) |
|
||||
| Logs/traces do not correlate the same agent | labels, IDs, observability mapping | [Observability](./11_observability_persistence_and_operational_readiness.md) |
|
||||
| Historical example no longer compiles | stale docs vs current API | [README Alignment Validation](./VALIDATION_README_ALIGNMENT.md) |
|
||||
| Need to create a new agent from scratch | complete flow | [`README_en.md`](../../../README_en.md) |
|
||||
|
||||
### Search by feature
|
||||
|
||||
### [01 — Architecture and Concepts](./01_architecture_and_concepts.md)
|
||||
|
||||
**What it is:** component, contract and responsibility-boundary reference.
|
||||
|
||||
**Use it when:** understanding the platform or deciding where a feature belongs.
|
||||
|
||||
### [02 — Routing, Route Stickiness and Intent Shift](./02_routing_stickiness_and_intent_shift.md)
|
||||
|
||||
**What it is:** agent/intent discovery, stickiness, handoff and intent-shift reference.
|
||||
|
||||
**Use it when:** routing is wrong or session continuity behaves incorrectly.
|
||||
|
||||
### [03 — Transactional Workflows and State](./03_transaction_workflows_and_state.md)
|
||||
|
||||
**What it is:** multi-turn transaction lifecycle, states, confirmation, resume and execution evidence.
|
||||
|
||||
**Use it when:** transactions loop, resume incorrectly or perform critical operations.
|
||||
|
||||
### [04 — MCP, Tools, Policies and Parameter Extraction](./04_mcp_integration_tools_and_policies.md)
|
||||
|
||||
**What it is:** tools, MCP Servers, mappings, policies and extraction reference.
|
||||
|
||||
**Use it when:** building or troubleshooting tool integration.
|
||||
|
||||
### [05 — Agent Gateway, MCP Gateway and Authentication](./05_agent_gateway_mcp_gateway_and_auth.md)
|
||||
|
||||
**What it is:** gateway responsibilities, governance and component authentication.
|
||||
|
||||
**Use it when:** troubleshooting ingress, catalog, authorization or gateway deployment.
|
||||
|
||||
### [06 — Guardrails, Judges and Transaction Evaluation](./06_guardrails_judges_and_transaction_evaluation.md)
|
||||
|
||||
**What it is:** native/external validation, judges, grounding and transaction evaluation.
|
||||
|
||||
**Use it when:** validation blocks, skips or evaluates incorrectly.
|
||||
|
||||
### [07 — RAG, BusinessContext and Grounding](./07_rag_business_context_and_grounding.md)
|
||||
|
||||
**What it is:** RAG providers, retrieved context, BusinessContext and grounding.
|
||||
|
||||
**Use it when:** retrieved knowledge does not reach the runtime/judge correctly.
|
||||
|
||||
### [08 — Long-Term Memory and Checkpoint](./08_long_term_memory_and_checkpoint.md)
|
||||
|
||||
**What it is:** durable memory, conversational memory, identity and state snapshots.
|
||||
|
||||
**Use it when:** context disappears, leaks or resumes incorrectly.
|
||||
|
||||
### [09 — LLM Rich Response and reasoning_content](./09_llm_rich_response_reasoning.md)
|
||||
|
||||
**What it is:** structured inference output beyond the `str` returned by `ainvoke()`.
|
||||
|
||||
**Use it when:** consumers require provider metadata, usage or reasoning exposed by the provider.
|
||||
|
||||
### [10 — Performance, Cache and Async Runtime](./10_performance_cache_and_async_runtime.md)
|
||||
|
||||
**What it is:** concurrency, caching, LLM and event-loop optimization reference.
|
||||
|
||||
**Use it when:** reducing avoidable latency or diagnosing deadlocks.
|
||||
|
||||
### [11 — Observability, Persistence and Operational Readiness](./11_observability_persistence_and_operational_readiness.md)
|
||||
|
||||
**What it is:** correlation, events, labels, sequencing, persistence and production diagnostics.
|
||||
|
||||
**Use it when:** proving execution paths or diagnosing production behavior.
|
||||
|
||||
### Main tutorial
|
||||
|
||||
[`README_en.md`](../../../README_en.md) remains the complete step-by-step guide.
|
||||
|
||||
### Maintenance
|
||||
|
||||
Do not create another tutorial parallel to the root README.
|
||||
|
||||
When a feature evolves:
|
||||
|
||||
- update the README only when the normal developer flow changes;
|
||||
- update the specialized manual with behavior, configuration, examples and troubleshooting;
|
||||
- update SPECs when contracts change;
|
||||
- keep release notes as history, not as the only current documentation.
|
||||
71
docs/developer/en/VALIDATION_README_ALIGNMENT.md
Normal file
71
docs/developer/en/VALIDATION_README_ALIGNMENT.md
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
### Documentation Alignment Validation
|
||||
|
||||
### Purpose
|
||||
|
||||
Record how this version's documentation was reorganized and which sources developers should trust.
|
||||
|
||||
### Structural decision
|
||||
|
||||
The root `README_en.md` / `README.md` is the **single end-to-end main tutorial**.
|
||||
|
||||
The former `01_architecture_and_agent_development.md` was removed because it repeated much of the README but not all of it. That created ambiguity: two documents appeared to teach the same workflow while one was partial.
|
||||
|
||||
The new structure replaces it with `01_architecture_and_concepts.md`, containing only architecture, concepts, responsibilities and extension criteria.
|
||||
|
||||
### `README_old2.md` validation
|
||||
|
||||
`Documentacao/README_old2.md` remains useful as historical material but is not the primary development source.
|
||||
|
||||
Later evolution found in the current README/code includes SPECs/SDDs, richer `llm_profiles.yaml` guidance, Channel Gateway, canonical contracts, current memory composition, `RuntimeContext`, tool helpers, transaction helpers, direct MCP responses and gateway/RAG/memory/policy evolution.
|
||||
|
||||
### Main README correction
|
||||
|
||||
The generated package corrects this typo:
|
||||
|
||||
```python
|
||||
from app.agents.financeiro_agent import FinanceirotAgent
|
||||
```
|
||||
|
||||
to:
|
||||
|
||||
```python
|
||||
from app.agents.financeiro_agent import FinanceiroAgent
|
||||
```
|
||||
|
||||
The correct class is confirmed by code and the rest of the documentation.
|
||||
|
||||
### APIs confirmed in the current implementation
|
||||
|
||||
```python
|
||||
AgentRuntimeMixin.get_runtime_context()
|
||||
AgentRuntimeMixin.normalize_tools_by_intent()
|
||||
AgentRuntimeMixin.build_tool_arguments()
|
||||
AgentRuntimeMixin.execute_tools_for_intent()
|
||||
AgentRuntimeMixin.prepare_memory_context()
|
||||
AgentRuntimeMixin.build_messages()
|
||||
AgentRuntimeMixin.transaction_state_patch()
|
||||
AgentRuntimeMixin.transaction_clarification_message()
|
||||
AgentRuntimeMixin.transaction_confirmation_message()
|
||||
AgentRuntimeMixin.build_direct_mcp_answer()
|
||||
```
|
||||
|
||||
### Trust order
|
||||
|
||||
1. version code;
|
||||
2. main README for the same version;
|
||||
3. SPECs/SDDs;
|
||||
4. specialized manuals;
|
||||
5. release notes;
|
||||
6. `README_old*` documents.
|
||||
|
||||
### Future maintenance rule
|
||||
|
||||
A feature evolution should update:
|
||||
|
||||
1. the main README **only when the normal development path changes**;
|
||||
2. the feature's specialized manual with technical detail, behavior, configuration and troubleshooting;
|
||||
3. the SPEC when a contract changes;
|
||||
4. a release note when historical recording is needed.
|
||||
|
||||
Do not create another “main manual” for a feature. Do not keep functional corrections permanently only in release notes.
|
||||
265
docs/developer/pt/01_architecture_and_concepts.md
Normal file
265
docs/developer/pt/01_architecture_and_concepts.md
Normal file
@@ -0,0 +1,265 @@
|
||||
|
||||
### Arquitetura e Conceitos do Agent Framework OCI
|
||||
|
||||
### Propósito deste documento
|
||||
|
||||
Este documento **não substitui o `README.md` da raiz** e não repete o tutorial de criação de agente.
|
||||
|
||||
Use:
|
||||
|
||||
- [`README.md`](../../../README.md) para desenvolver, configurar, executar e testar um agente de ponta a ponta;
|
||||
- este documento para compreender a arquitetura, os limites de responsabilidade, os componentes e onde cada tipo de implementação deve ficar;
|
||||
- os demais manuais desta pasta para aprofundar uma capacidade específica ou solucionar um problema.
|
||||
|
||||
A separação é intencional: existe **um único tutorial principal** e vários **manuais de referência especializados**.
|
||||
|
||||
### Fonte de verdade
|
||||
|
||||
Quando existir divergência documental, use esta ordem:
|
||||
|
||||
1. código da versão em uso;
|
||||
2. `README.md` / `README_en.md` da mesma versão;
|
||||
3. SPECs/SDDs normativas;
|
||||
4. manuais especializados desta pasta;
|
||||
5. release notes e `README_old*` apenas como histórico.
|
||||
|
||||
### Modelo mental da plataforma
|
||||
|
||||
O Agent Framework OCI deve ser entendido como uma plataforma em camadas.
|
||||
|
||||
O **framework core** fornece mecanismos reutilizáveis e neutros de domínio: runtime, estado, memória, roteamento, integração de tools, guardrails, judges, persistência, observabilidade e contratos comuns.
|
||||
|
||||
O **agente** contém aquilo que é específico do caso de uso: intents, prompts, regras de domínio, policies específicas, workflow de negócio, mapeamentos, integrações e componentes externos pertencentes àquele agente.
|
||||
|
||||
Os **gateways** tratam responsabilidades transversais de entrada, governança e integração. Eles não devem absorver a lógica de negócio do agente.
|
||||
|
||||
Os **MCP Servers** encapsulam ferramentas e integrações com serviços de domínio ou legados. O **MCP Gateway** fornece catálogo e governança centralizada dessas tools.
|
||||
|
||||
### Componentes principais
|
||||
|
||||
| Componente | Responsabilidade principal | Não deve conter |
|
||||
|---|---|---|
|
||||
| `libs/agent_framework/` | Runtime genérico, contratos, estado, memória, routing, guardrails, judges, integrações comuns | Regra específica de uma empresa ou agente |
|
||||
| `templates/agent_template_backend/` | Referência executável para criação de agentes | Fork permanente do core |
|
||||
| `apps/agent_gateway/` | Entrada governada, policies transversais, rate limit, autenticação, metadados | Workflow de negócio |
|
||||
| `apps/channel_gateway/` | Adaptação dos canais ao contrato canônico | Regra de negócio do agente |
|
||||
| `apps/mcp_gateway/` | Catálogo, autorização e execução central de tools | Lógica conversacional |
|
||||
| `mcp/servers/` | Integrações e tools por domínio | Orquestração global do agente |
|
||||
| `evals/` | Certificação e regressão | Lógica produtiva |
|
||||
| `deploy/` | Containers e Kubernetes | Regras funcionais |
|
||||
|
||||
### Fluxo conceitual de uma requisição
|
||||
|
||||
Uma requisição típica percorre as seguintes responsabilidades:
|
||||
|
||||
```text
|
||||
Canal
|
||||
|
|
||||
v
|
||||
Channel Gateway
|
||||
|
|
||||
v
|
||||
Agent Gateway
|
||||
| governança / autenticação / rate limit / metadata
|
||||
v
|
||||
Backend do agente
|
||||
|
|
||||
+--> Routing / stickiness / intent
|
||||
|
|
||||
+--> Estado / memória / checkpoint
|
||||
|
|
||||
+--> Guardrails / judges
|
||||
|
|
||||
+--> Workflow / políticas transacionais
|
||||
|
|
||||
+--> MCP Gateway
|
||||
|
|
||||
+--> MCP Server A --> sistema legado
|
||||
+--> MCP Server B --> serviço externo
|
||||
+--> MCP Server C --> API de domínio
|
||||
```
|
||||
|
||||
Nem toda implantação precisa utilizar todos os componentes. A composição deve seguir a necessidade do agente e os contratos da plataforma.
|
||||
|
||||
### Runtime do agente
|
||||
|
||||
O runtime atual é baseado em `AgentRuntimeMixin` e `RuntimeContext`.
|
||||
|
||||
O template importa o runtime através de `app.agents.runtime`, que reexporta a implementação oficial do framework. O objetivo é impedir que cada agente mantenha sua própria cópia divergente do runtime.
|
||||
|
||||
Entre as APIs atuais confirmadas no código estão:
|
||||
|
||||
```python
|
||||
AgentRuntimeMixin.get_runtime_context()
|
||||
AgentRuntimeMixin.normalize_tools_by_intent()
|
||||
AgentRuntimeMixin.build_tool_arguments()
|
||||
AgentRuntimeMixin.execute_tools_for_intent()
|
||||
AgentRuntimeMixin.prepare_memory_context()
|
||||
AgentRuntimeMixin.build_messages()
|
||||
AgentRuntimeMixin.transaction_state_patch()
|
||||
AgentRuntimeMixin.transaction_clarification_message()
|
||||
AgentRuntimeMixin.transaction_confirmation_message()
|
||||
AgentRuntimeMixin.build_direct_mcp_answer()
|
||||
```
|
||||
|
||||
Essas APIs representam capacidades do runtime. O desenvolvedor deve preferi-las a reconstruir manualmente a mesma lógica dentro de cada agente.
|
||||
|
||||
### Configuração versus código
|
||||
|
||||
Uma diretriz central do framework é que comportamento configurável permaneça em configuração.
|
||||
|
||||
Exemplos:
|
||||
|
||||
- agentes e metadados: `config/agents.yaml`;
|
||||
- roteamento: `config/routing.yaml`;
|
||||
- tools: `config/tools.yaml`;
|
||||
- MCP Servers e mappings: configuração MCP correspondente;
|
||||
- perfis de LLM: `llm_profiles.yaml`;
|
||||
- policies e extensões: arquivos de configuração específicos da capacidade.
|
||||
|
||||
O código deve implementar mecanismos. YAML/config deve escolher comportamento sempre que isso puder ser feito sem comprometer segurança ou contratos.
|
||||
|
||||
### Separação entre framework e agente
|
||||
|
||||
Uma mudança pertence ao **framework** quando introduz um mecanismo reutilizável por diferentes agentes.
|
||||
|
||||
Exemplos:
|
||||
|
||||
- nova SPI de guardrail;
|
||||
- novo contrato de resposta rica de LLM;
|
||||
- nova capacidade genérica de checkpoint;
|
||||
- novo mecanismo configurável de tool policy;
|
||||
- nova estratégia genérica de routing.
|
||||
|
||||
Uma mudança pertence ao **agente** quando expressa uma regra de um domínio ou empresa.
|
||||
|
||||
Exemplos:
|
||||
|
||||
- quais cobranças podem ser contestadas;
|
||||
- um prompt específico de telecom;
|
||||
- regras de VAS;
|
||||
- códigos internos de uma empresa;
|
||||
- mapeamento de um serviço legado;
|
||||
- fraseologia específica.
|
||||
|
||||
Se o core precisa importar um módulo concreto do agente para funcionar, essa separação provavelmente foi quebrada.
|
||||
|
||||
### Estado, memória e checkpoint são conceitos diferentes
|
||||
|
||||
**Estado de execução** representa o que está acontecendo no turno e no workflow.
|
||||
|
||||
**Memória de conversa** preserva contexto conversacional.
|
||||
|
||||
**Long-Term Memory** guarda fatos duráveis associados a uma identidade de negócio.
|
||||
|
||||
**Checkpoint** persiste snapshots do estado LangGraph para retomada.
|
||||
|
||||
Um checkpoint antigo não deve, sozinho, determinar qual transação está ativa. A decisão funcional deve usar o estado transacional canônico.
|
||||
|
||||
### Routing e execução são responsabilidades diferentes
|
||||
|
||||
O routing responde: **qual agente/intent deve tratar esta mensagem?**
|
||||
|
||||
A execução responde: **o que esse agente deve fazer agora?**
|
||||
|
||||
Route stickiness preserva continuidade, mas não deve impedir uma mudança explícita de intenção. Durante uma transação, parâmetros esperados e confirmação válida têm precedência para evitar falsos intent shifts.
|
||||
|
||||
Detalhes completos: [Roteamento, Stickiness e Intent Shift](./02_routing_stickiness_and_intent_shift.md).
|
||||
|
||||
### Tools e MCP
|
||||
|
||||
Uma tool representa uma capacidade invocável.
|
||||
|
||||
O MCP Server implementa ou expõe essa capacidade.
|
||||
|
||||
O MCP Gateway organiza catálogo, autorização, mapping e execução centralizada.
|
||||
|
||||
O agente decide **quando** uma tool deve ser usada dentro do seu fluxo; a tool/MCP decide **como** acessar o serviço correspondente.
|
||||
|
||||
Detalhes completos: [MCP, Tools, Policies e Extração de Parâmetros](./04_mcp_integration_tools_and_policies.md).
|
||||
|
||||
### Transações
|
||||
|
||||
Operações com efeitos colaterais exigem tratamento diferente de consultas.
|
||||
|
||||
O framework fornece mecanismos de estado, confirmação, políticas e workflow determinístico. Regras concretas permanecem no agente.
|
||||
|
||||
O LLM pode participar da interpretação e composição, mas não deve ser a única fonte de verdade para afirmar que uma operação crítica foi executada.
|
||||
|
||||
Detalhes completos: [Workflows Transacionais e Estado](./03_transaction_workflows_and_state.md).
|
||||
|
||||
### Guardrails e Judges
|
||||
|
||||
Guardrails controlam ou validam comportamento durante o processamento.
|
||||
|
||||
Judges avaliam qualidade, grounding e outros critérios.
|
||||
|
||||
O core fornece mecanismos nativos e pontos de extensão. Guardrails/judges específicos de um domínio devem ser carregados pelo agente por configuração, evitando imports específicos dentro do framework.
|
||||
|
||||
Detalhes completos: [Guardrails, Judges e Avaliação Transacional](./06_guardrails_judges_and_transaction_evaluation.md).
|
||||
|
||||
### RAG, memória e ferramentas não são equivalentes
|
||||
|
||||
- **RAG** recupera conhecimento.
|
||||
- **Memory** preserva contexto/fatos.
|
||||
- **Tool** executa ou consulta uma capacidade externa.
|
||||
|
||||
Escolher o mecanismo errado cria bugs difíceis de diagnosticar. Uma informação que precisa ser atualizada em sistema não deve ser resolvida apenas por RAG; um fato durável do cliente não deve depender apenas do histórico do prompt.
|
||||
|
||||
### Observabilidade como contrato transversal
|
||||
|
||||
Roteamento, agente, transação, tool, guardrail, judge e falha precisam ser correlacionáveis.
|
||||
|
||||
Observabilidade deve registrar o que aconteceu, mas não controlar estado de negócio. Sequence, trace IDs e labels são infraestrutura de diagnóstico e auditoria.
|
||||
|
||||
Detalhes completos: [Observabilidade, Persistência e Prontidão Operacional](./11_observability_persistence_and_operational_readiness.md).
|
||||
|
||||
### Onde colocar uma nova funcionalidade
|
||||
|
||||
Antes de implementar, faça estas perguntas:
|
||||
|
||||
1. A capacidade é reutilizável por diferentes agentes?
|
||||
2. Existe regra específica de domínio?
|
||||
3. Precisa de estado entre turnos?
|
||||
4. Produz efeito colateral?
|
||||
5. Depende de sistema externo?
|
||||
6. Deve ser configurável?
|
||||
7. Precisa aparecer em observabilidade?
|
||||
8. Precisa ser avaliada por guardrail/judge?
|
||||
|
||||
Uma feature reutilizável normalmente começa no core e é habilitada/configurada pelo agente. Uma regra de negócio normalmente começa no agente e usa interfaces do core.
|
||||
|
||||
### Anti-padrões
|
||||
|
||||
Evite:
|
||||
|
||||
- importar pacote concreto de um agente dentro do core;
|
||||
- duplicar `AgentRuntimeMixin` em cada agente;
|
||||
- codificar nomes de agentes, intents, tools ou empresas no runtime;
|
||||
- usar resposta do LLM como prova de execução de operação;
|
||||
- confundir checkpoint antigo com transação ativa;
|
||||
- executar operação transacional sem política/confirmacão quando ela é requerida;
|
||||
- acoplar agente diretamente a dezenas de serviços quando o MCP Gateway é a camada prevista;
|
||||
- criar um novo documento funcional para cada bug fix em vez de atualizar o manual da feature.
|
||||
|
||||
### Caminho recomendado para um novo desenvolvedor
|
||||
|
||||
1. Leia a visão arquitetural neste documento.
|
||||
2. Siga o [`README.md`](../../../README.md) do início ao fim para criar e executar um agente.
|
||||
3. Quando chegar a uma capacidade específica, use o manual especializado correspondente.
|
||||
4. Para falhas, comece pelo [Índice de Desenvolvimento](./INDEX_DEVELOPER_GUIDE.md), na seção **Buscar pelo problema**.
|
||||
5. Antes de copiar código antigo, confirme API/import no template e no core atuais.
|
||||
|
||||
### Documentos relacionados
|
||||
|
||||
- [Tutorial principal — README.md](../../../README.md)
|
||||
- [Roteamento, Stickiness e Intent Shift](./02_routing_stickiness_and_intent_shift.md)
|
||||
- [Workflows Transacionais e Estado](./03_transaction_workflows_and_state.md)
|
||||
- [MCP, Tools, Policies e Parâmetros](./04_mcp_integration_tools_and_policies.md)
|
||||
- [Gateways e Autenticação](./05_agent_gateway_mcp_gateway_and_auth.md)
|
||||
- [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md)
|
||||
- [RAG e BusinessContext](./07_rag_business_context_and_grounding.md)
|
||||
- [Long-Term Memory e Checkpoint](./08_long_term_memory_and_checkpoint.md)
|
||||
- [LLM Rich Response](./09_llm_rich_response_reasoning.md)
|
||||
- [Performance, Cache e Runtime Assíncrono](./10_performance_cache_and_async_runtime.md)
|
||||
- [Observabilidade e Prontidão Operacional](./11_observability_persistence_and_operational_readiness.md)
|
||||
1441
docs/developer/pt/02_routing_stickiness_and_intent_shift.md
Normal file
1441
docs/developer/pt/02_routing_stickiness_and_intent_shift.md
Normal file
File diff suppressed because it is too large
Load Diff
560
docs/developer/pt/03_transaction_workflows_and_state.md
Normal file
560
docs/developer/pt/03_transaction_workflows_and_state.md
Normal file
@@ -0,0 +1,560 @@
|
||||
|
||||
### Workflows Transacionais e Estado
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **estado transacional, coleta de parâmetros, confirmação, pausa/retomada e evidência operacional**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Estado transacional, coleta de parâmetros, confirmação, pausa/retomada e evidência operacional.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Workflows Transacionais, Estado Multi-turno e Retomada
|
||||
|
||||
Guia de implementação para operações multi-etapas, fonte canônica do estado transacional, confirmação, merge de parâmetros, pausa/retomada, evidência operacional e interação com roteamento.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Guia de estado transacional multi-turno
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`.
|
||||
|
||||
Este documento define o contrato operacional para transações multi-turno no Agent Framework OCI. Ele é normativo para hosts e templates que utilizam `AgentRuntime`, checkpoint LangGraph e tools transacionais.
|
||||
|
||||
### 1. Objetivo
|
||||
|
||||
Uma transação pode atravessar vários turnos. Exemplo:
|
||||
|
||||
```text
|
||||
Usuário: quero cancelar o pedido
|
||||
Framework: informe o número do pedido
|
||||
Usuário: PED-1001
|
||||
Framework: confirma o cancelamento?
|
||||
Usuário: sim
|
||||
Framework: executa a tool
|
||||
```
|
||||
|
||||
O framework precisa preservar a transação entre todos esses turnos sem depender de reclassificação por LLM, keyword routing ou reextração de parâmetros já obtidos.
|
||||
|
||||
### 2. Fonte canônica do estado transacional
|
||||
|
||||
O estado canônico da transação em andamento é `active_transaction`.
|
||||
|
||||
```python
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
```
|
||||
|
||||
Todo `AgentState` usado por um host que habilita transações multi-turno **DEVE** declarar os dois campos. Como o LangGraph usa o schema do state para persistência/checkpoint, um campo criado apenas dinamicamente pelo runtime não é um contrato durável seguro.
|
||||
|
||||
Exemplo mínimo:
|
||||
|
||||
```python
|
||||
from typing import Any, TypedDict
|
||||
|
||||
class AgentState(TypedDict, total=False):
|
||||
# ...campos normais...
|
||||
selected_tool_call: dict[str, Any]
|
||||
pending_tool_call: dict[str, Any]
|
||||
active_transaction: dict[str, Any]
|
||||
last_transaction: dict[str, Any]
|
||||
transaction_status: str
|
||||
missing_parameters: list[str]
|
||||
confirmation_required: bool
|
||||
confirmation_received: bool
|
||||
```
|
||||
|
||||
### 3. Papel de cada campo
|
||||
|
||||
| Campo | Papel | Regra |
|
||||
|---|---|---|
|
||||
| `active_transaction` | Fonte canônica da transação ativa | Deve sobreviver a checkpoint/resume enquanto a transação estiver ativa. |
|
||||
| `last_transaction` | Snapshot da última transação terminal | Usado para auditoria, evidência e continuidade controlada; não reativa automaticamente a transação. |
|
||||
| `transaction_status` | Estado lógico atual | Ex.: `COLLECTING_PARAMETERS`, `AWAITING_CONFIRMATION`, `COMPLETED`, `CANCELLED`, `OUT_OF_SCOPE`. |
|
||||
| `missing_parameters` | Parâmetros ainda necessários | Deve refletir o estado canônico da transação, não apenas a mensagem corrente. |
|
||||
| `selected_tool_call` | Estado auxiliar/compatibilidade | Não deve substituir `active_transaction` como fonte canônica. |
|
||||
| `pending_tool_call` | Estado auxiliar/compatibilidade | Pode ser usado por compatibilidade, mas não como latch principal. |
|
||||
| `next_state` | Orientação de roteamento do workflow | Ajuda a manter o nó/agente correto durante coleta/confirmação. |
|
||||
| `transaction_pre_validation` | Evidência de pré-validação | Mantém resultado de validação antes da confirmação/execução. |
|
||||
| `transaction_evidence` | Evidências da execução | Mantém resultados e trilha de execução da transação. |
|
||||
|
||||
### 4. Ciclo de vida recomendado
|
||||
|
||||
```text
|
||||
IDLE
|
||||
↓ intenção transacional
|
||||
COLLECTING_PARAMETERS
|
||||
↓ parâmetros completos
|
||||
PRE_VALIDATION (quando configurado)
|
||||
↓ elegível
|
||||
AWAITING_CONFIRMATION
|
||||
↓ confirmação positiva
|
||||
EXECUTING
|
||||
↓
|
||||
COMPLETED
|
||||
```
|
||||
|
||||
Saídas terminais alternativas:
|
||||
|
||||
```text
|
||||
CANCELLED
|
||||
OUT_OF_SCOPE
|
||||
FAILED
|
||||
```
|
||||
|
||||
O runtime pode representar algumas fases internamente sem um `transaction_status` público separado. O requisito é preservar o latch e não perder argumentos já coletados.
|
||||
|
||||
### 5. Merge incremental de parâmetros
|
||||
|
||||
Uma resposta posterior deve complementar a transação existente, nunca recriá-la apenas a partir do texto atual.
|
||||
|
||||
```python
|
||||
existing = dict((state.get("active_transaction") or {}).get("arguments") or {})
|
||||
new_values = {"valor": "71.99"}
|
||||
arguments = {**existing, **new_values}
|
||||
```
|
||||
|
||||
Exemplo esperado:
|
||||
|
||||
```text
|
||||
Turno 1: subject = "TIM CTRL Redes Sociais 8.0"
|
||||
Turno 2: valor = "71.99"
|
||||
Resultado: subject + valor permanecem disponíveis
|
||||
```
|
||||
|
||||
### 6. Precedência de roteamento durante transação
|
||||
|
||||
Quando existe `active_transaction` em `COLLECTING_PARAMETERS`, a mensagem deve primeiro ser avaliada como possível resposta aos parâmetros pendentes.
|
||||
|
||||
Precedência normativa:
|
||||
|
||||
1. parâmetro pendente claramente preenchido → continuar a transação;
|
||||
2. cancelamento/abandono explícito → cancelar a transação;
|
||||
3. nova intenção inequívoca → interromper a transação e rotear;
|
||||
4. keyword genérica do mesmo domínio/agente → **não** interromper a transação;
|
||||
5. mensagem ambígua → manter a transação e clarificar.
|
||||
|
||||
Exemplos:
|
||||
|
||||
| Estado atual | Mensagem | Resultado correto |
|
||||
|---|---|---|
|
||||
| `retail_order_cancel`, falta `order_id` | `PED-1001` | Continua cancelamento e preenche `order_id`. |
|
||||
| `retail_order_cancel`, falta `order_id` | `o pedido é o PED-1001` | Continua cancelamento; `pedido` não deve virar tracking. |
|
||||
| contestação, falta `valor` | `R$ 71,99` | Continua contestação e preenche `valor`. |
|
||||
| cancelamento pendente | `esquece, quero ver minha fatura` | Interrupção explícita permitida. |
|
||||
| cancelamento pendente | `quero rastrear pedido` | Mudança inequívoca para tracking permitida. |
|
||||
|
||||
### 7. Checkpoint e retomada
|
||||
|
||||
Antes de executar roteamento normal, o host deve restaurar o checkpoint usando a mesma identidade de conversa (`tenant_id`, `agent_id`, `session_id`/`conversation_key` conforme contrato do host).
|
||||
|
||||
Após a restauração:
|
||||
|
||||
```text
|
||||
active_transaction existe
|
||||
↓
|
||||
status ativo?
|
||||
↓ sim
|
||||
retomar a transação antes de keyword routing / continuity LLM
|
||||
```
|
||||
|
||||
Um estado `COLLECTING_PARAMETERS` sem `active_transaction` deve ser tratado como inconsistência de estado e observado/diagnosticado; não deve silenciosamente reiniciar a tool a partir da mensagem corrente.
|
||||
|
||||
### 8. O que pertence ao framework e ao agente
|
||||
|
||||
Framework:
|
||||
|
||||
- persistência do latch;
|
||||
- merge de argumentos;
|
||||
- estados de coleta/confirmação;
|
||||
- precedência de retomada;
|
||||
- confirmação determinística;
|
||||
- idempotência e evidência;
|
||||
- checkpoint/resume.
|
||||
|
||||
Agente:
|
||||
|
||||
- definição das tools de domínio;
|
||||
- parâmetros obrigatórios e mensagens de domínio;
|
||||
- regras de elegibilidade específicas;
|
||||
- pre-validation específica, quando houver;
|
||||
- resposta final ao cliente.
|
||||
|
||||
O agente não deve implementar um segundo motor transacional paralelo ao `AgentRuntime`.
|
||||
|
||||
### 9. Checklist para novos hosts/templates
|
||||
|
||||
- [ ] `AgentState` declara `active_transaction`.
|
||||
- [ ] `AgentState` declara `last_transaction`.
|
||||
- [ ] `transaction_status` e `missing_parameters` fazem parte do state quando usados.
|
||||
- [ ] O host usa checkpoint compatível com o schema do state.
|
||||
- [ ] A mesma `conversation_key` é usada entre turnos da mesma conversa.
|
||||
- [ ] Parâmetros já coletados são mesclados com novos valores.
|
||||
- [ ] Respostas a parâmetros têm precedência sobre keyword routing genérico.
|
||||
- [ ] Mudança explícita de intenção continua possível.
|
||||
- [ ] O agente usa `transaction_state_patch(state)` ao retornar respostas transacionais quando o template o exige.
|
||||
- [ ] Existem testes multi-turno para coleta, confirmação, interrupção e resume.
|
||||
|
||||
### 10. Testes regressivos mínimos
|
||||
|
||||
```text
|
||||
A. cancelamento de pedido
|
||||
1. "quero cancelar pedido"
|
||||
2. "o pedido é o PED-1001"
|
||||
Esperado: continua retail_order_cancel; não vira retail_order_tracking.
|
||||
|
||||
B. contestação
|
||||
1. "não contratei TIM CTRL Redes Sociais 8.0"
|
||||
2. "R$ 71,99"
|
||||
Esperado: subject e valor chegam juntos à pre-validation.
|
||||
|
||||
C. interrupção explícita
|
||||
1. iniciar transação e deixar parâmetro pendente
|
||||
2. "esquece, quero ver minha fatura"
|
||||
Esperado: transação é interrompida e nova intenção é roteada.
|
||||
|
||||
D. checkpoint/resume
|
||||
1. iniciar transação
|
||||
2. persistir/checkpoint
|
||||
3. reconstruir execução usando a mesma conversation_key
|
||||
4. fornecer o parâmetro faltante
|
||||
Esperado: active_transaction é restaurado e concluído sem reiniciar a tool.
|
||||
```
|
||||
|
||||
### 11. Anti-patterns
|
||||
|
||||
- reconstruir a transação somente a partir da última mensagem;
|
||||
- usar `selected_tool_call` como única fonte do latch;
|
||||
- remover `active_transaction` do `AgentState` por parecer redundante;
|
||||
- permitir uma keyword genérica como `pedido` interromper coleta de `order_id`;
|
||||
- armazenar parâmetros apenas em variáveis locais do nó;
|
||||
- duplicar confirmação transacional no prompt do agente;
|
||||
- limpar o latch antes do estado terminal.
|
||||
|
||||
### 12. Referências no projeto
|
||||
|
||||
- `specs/SPEC-002-Agent-Runtime.md`
|
||||
- `specs/SPEC-010-Agent-Development.md`
|
||||
- `templates/agent_template_backend/app/state.py`
|
||||
- `libs/agent_framework/src/agent_framework/runtime/agent_runtime.py`
|
||||
- `libs/agent_framework/src/agent_framework/routing/enterprise_router.py`
|
||||
- `Tuning-Performance/Deterministic_Transactional_Workflow/`
|
||||
- `Tuning-Performance/Transaction_Pre_Validation/`
|
||||
- `Tuning-Performance/Transaction_Evidence/`
|
||||
|
||||
### Decisão arquitetural do motor de workflows
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/ADR_TRANSACTIONAL_WORKFLOW_ENGINE.md`.
|
||||
|
||||
### Decisão
|
||||
|
||||
Adicionar ao framework uma capacidade opcional de execução determinística baseada em LangGraph. O motor é genérico; definições YAML e actions de domínio permanecem nos agentes.
|
||||
|
||||
### Razão
|
||||
|
||||
Operações multi-etapas com efeitos colaterais não devem depender do LLM para escolher a sequência crítica. A solução reduz tokens, latência e variação, além de melhorar auditoria, testes e versionamento.
|
||||
|
||||
### Compatibilidade
|
||||
|
||||
`execution.mode` assume `direct_tool`. Projetos existentes continuam usando MCP diretamente. A adoção de workflow é explícita por tool e pode ser controlada por `ENABLE_TRANSACTIONAL_WORKFLOWS`.
|
||||
|
||||
### Limites desta entrega
|
||||
|
||||
A base inclui validação, versionamento por arquivo, registry, execução sync/async, condições, retry por nó, cache de grafos e adapter de policy. Persistência corporativa de execution records, compensação/Saga, autorização por escopo e emissão de IC/NOC específica devem ser conectadas às abstrações existentes de cada deployment antes do uso em transações financeiras críticas.
|
||||
|
||||
### Implementação dos workflows determinísticos
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md`.
|
||||
|
||||
### Entrega
|
||||
|
||||
Foi adicionada ao `agent_framework_oci` uma capacidade opcional para executar transações multi-etapas como workflows determinísticos compilados em LangGraph.
|
||||
|
||||
### Módulo novo
|
||||
|
||||
`libs/agent_framework/src/agent_framework/workflows/`
|
||||
|
||||
- `models.py`: contratos Pydantic e validação estrutural;
|
||||
- `repository.py`: resolução de versão ativa e leitura de YAML imutável;
|
||||
- `registry.py`: registro desacoplado de actions sync/async;
|
||||
- `runtime.py`: compilação, cache e execução do StateGraph;
|
||||
- `tool_executor.py`: integração com a política da tool;
|
||||
- `__init__.py`: API pública.
|
||||
|
||||
### Política expandida
|
||||
|
||||
`ToolPolicy` agora aceita:
|
||||
|
||||
```yaml
|
||||
execution:
|
||||
mode: direct_tool | workflow | agent
|
||||
workflow: nome_do_workflow
|
||||
version: active | 1
|
||||
```
|
||||
|
||||
O default permanece `direct_tool`, preservando compatibilidade.
|
||||
|
||||
### Configuração
|
||||
|
||||
Foram adicionados:
|
||||
|
||||
- `ENABLE_TRANSACTIONAL_WORKFLOWS=false`;
|
||||
- `WORKFLOWS_PATH=./workflows`.
|
||||
|
||||
### Template
|
||||
|
||||
Inclui um exemplo completo de devolução de pedido com:
|
||||
|
||||
- confirmação e campos obrigatórios pela política;
|
||||
- workflow YAML versionado;
|
||||
- actions de domínio no backend;
|
||||
- bifurcação determinística baseada no resultado da validação.
|
||||
|
||||
### Validação realizada
|
||||
|
||||
- `tests/unit/test_tool_policies.py`: 4 testes aprovados;
|
||||
- compilação Python de framework, template e novos testes: aprovada;
|
||||
- o teste funcional novo do LangGraph foi criado, mas não pôde ser executado neste container porque `langgraph` não está instalado no ambiente. A dependência já está declarada no `pyproject.toml` do framework.
|
||||
|
||||
### Escopo e segurança
|
||||
|
||||
Esta entrega cria o motor e a integração de política. Para operações críticas em produção ainda é necessário conectar:
|
||||
|
||||
- execution store persistente;
|
||||
- idempotência de negócio nas actions/APIs;
|
||||
- autorização por escopo;
|
||||
- telemetria IC/NOC específica de workflow;
|
||||
- compensação/Saga quando aplicável;
|
||||
- estratégia corporativa de timeout e retry.
|
||||
|
||||
Esses itens foram explicitamente documentados para evitar a falsa impressão de que retry por si só garante segurança transacional.
|
||||
|
||||
### Precedência da coleta de parâmetros
|
||||
|
||||
> Conteúdo consolidado a partir de `FIX_TRANSACTION_PARAMETER_PRECEDENCE.md`.
|
||||
|
||||
Esta correção remove a extração textual hardcoded de parâmetros transacionais e faz a coleta de `policy.requires` por um extrator LLM genérico.
|
||||
|
||||
### Regra de precedência
|
||||
|
||||
Enquanto existir uma transação ativa, o framework trata o turno nesta ordem:
|
||||
|
||||
```text
|
||||
ACTIVE_TRANSACTION
|
||||
|
|
||||
+-- COLLECTING_PARAMETERS
|
||||
| |
|
||||
| +-- LLM tenta extrair SOMENTE os parâmetros ainda pendentes
|
||||
| |
|
||||
| +-- extraiu >= 1 ?
|
||||
| |
|
||||
| +-- SIM -> continua a transação; NÃO avalia intent_shift
|
||||
| |
|
||||
| +-- NÃO -> libera EnterpriseRouter para avaliar intent_shift
|
||||
|
|
||||
+-- AWAITING_CONFIRMATION
|
||||
|
|
||||
+-- reconhece confirmação/rejeição explícita
|
||||
|
|
||||
+-- reconheceu ?
|
||||
|
|
||||
+-- SIM -> continua/cancela a transação; NÃO avalia intent_shift
|
||||
|
|
||||
+-- NÃO -> libera EnterpriseRouter para avaliar intent_shift
|
||||
```
|
||||
|
||||
### TransactionParameterExtractor
|
||||
|
||||
Novo componente:
|
||||
|
||||
`libs/agent_framework/src/agent_framework/runtime/transaction_parameters.py`
|
||||
|
||||
A extração textual dos parâmetros de negócio é feita exclusivamente por LLM. O componente recebe:
|
||||
|
||||
- nome da tool/transação ativa;
|
||||
- parâmetros atualmente pendentes;
|
||||
- argumentos já conhecidos;
|
||||
- schema/tipos declarados em `tools.yaml` quando disponíveis;
|
||||
- descrição da tool;
|
||||
- mensagem atual do usuário.
|
||||
|
||||
Ele não conhece nomes de domínio como `order_id`, `reason`, `subject`, `valor`, TIM ou retail. Não há regex de entidades de negócio.
|
||||
|
||||
A LLM pode interpretar, por exemplo:
|
||||
|
||||
- `PED-1001` quando só há um parâmetro compatível pendente;
|
||||
- `o pedido é PED-1001`;
|
||||
- `PED-1001, desisti da compra` preenchendo dois parâmetros no mesmo turno;
|
||||
- respostas com o nome do parâmetro seguido do valor;
|
||||
- respostas apenas com o valor, quando semanticamente inequívocas.
|
||||
|
||||
Em caso de dúvida, o prompt manda retornar `null`. Uma nova solicitação não deve ser transformada em valor de parâmetro.
|
||||
|
||||
### Separação de responsabilidades
|
||||
|
||||
`tool_policies.yaml` continua sendo a fonte de verdade para `requires`.
|
||||
|
||||
`tools.yaml` pode fornecer tipos via `args_schema` e descrição da tool para melhorar a interpretação sem introduzir código específico de domínio.
|
||||
|
||||
`mcp_parameter_mapping.yaml` continua responsável pelos parâmetros auxiliares/contrato MCP. As strategies do mapper são explicitamente excluídas dos campos presentes em `policy.requires`, para não misturar extração MCP com coleta transacional.
|
||||
|
||||
O `EnterpriseRouter` usa o mesmo extrator LLM apenas como *probe* de precedência. Se pelo menos um parâmetro pendente for encontrado, o turno permanece no estado transacional. Os valores extraídos são colocados no metadata da decisão e reutilizados pelo runtime, evitando uma segunda chamada LLM no mesmo turno.
|
||||
|
||||
### Profile LLM
|
||||
|
||||
Foi adicionado aos templates:
|
||||
|
||||
```yaml
|
||||
transaction_parameter_extraction:
|
||||
provider: oci_openai
|
||||
model: openai.gpt-4.1-mini
|
||||
temperature: 0
|
||||
max_tokens: 500
|
||||
timeout_seconds: 8
|
||||
```
|
||||
|
||||
Generation/component:
|
||||
|
||||
- `llm.transaction_parameter_extraction`
|
||||
- `transaction_parameter_extraction`
|
||||
|
||||
### Limpeza de estado
|
||||
|
||||
Em `intent_shift`, `transaction_pre_validation` da transação abandonada é removido para não contaminar a nova transação. O resultado de pre-validation continua preservado enquanto pertence à própria transação para auditoria.
|
||||
|
||||
### Testes adicionados
|
||||
|
||||
`tests/test_transaction_parameter_llm_precedence.py`
|
||||
|
||||
Cobertura:
|
||||
|
||||
1. dois parâmetros extraídos no mesmo turno;
|
||||
2. um parâmetro preenchido ganha precedência sobre keyword que indicaria outra intent;
|
||||
3. nenhum parâmetro encontrado libera `intent_shift`;
|
||||
4. ausência do antigo `_extract_action_arguments()` hardcoded;
|
||||
5. confirmação `sim` ganha precedência sobre intent shift.
|
||||
|
||||
### Correção de loop entre transação e intent
|
||||
|
||||
> Conteúdo consolidado a partir de `FIX_TRANSACTION_INTENT_LOOP.md`.
|
||||
|
||||
Correção aplicada em 2026-08-20 para impedir que uma sessão fique presa em `COLLECTING_PARAMETERS` ou `AWAITING_CONFIRMATION` quando o usuário muda explicitamente de assunto.
|
||||
|
||||
### Comportamento corrigido
|
||||
|
||||
Antes:
|
||||
|
||||
1. uma transação entrava em `COLLECTING_PARAMETERS`;
|
||||
2. `next_state` forçava o mesmo agente via `state_policies`;
|
||||
3. toda mensagem seguinte era tratada como tentativa de preencher o parâmetro faltante;
|
||||
4. uma nova intenção como `quais sao meus servicos` permanecia presa no fluxo anterior.
|
||||
|
||||
Agora:
|
||||
|
||||
- o `EnterpriseRouter` verifica mudança explícita de intenção antes de aplicar o lock de estado;
|
||||
- keyword explícita tem prioridade;
|
||||
- quando necessário, o LLM router pode detectar mudança com confiança >= `router.confidence_threshold`;
|
||||
- a decisão recebe `metadata.transaction_interruption=intent_shift`;
|
||||
- o runtime encerra a transação pendente como `CANCELLED`, limpa `next_state`, parâmetros e latches, e prossegue com a nova intent;
|
||||
- cancelamentos explícitos como `cancele essa operação anterior` funcionam também durante `COLLECTING_PARAMETERS`.
|
||||
|
||||
### Testes adicionados
|
||||
|
||||
- mudança de intent durante `COLLECTING_PARAMETERS`;
|
||||
- resposta curta/baixa confiança permanece na transação;
|
||||
- cancelamento explícito durante coleta de parâmetros;
|
||||
- limpeza do estado transacional antes de executar a nova intent.
|
||||
|
||||
Testes focados: 19 passed.
|
||||
|
||||
### Evidência operacional de execução
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/TRANSACTION_OPERATIONAL_EVIDENCE_FIX.md`.
|
||||
|
||||
### Problem
|
||||
|
||||
A confirmed transactional tool result was available only in the execution turn. On a later read-only turn, conversational memory could still mention the prior transaction (for example, a cancellation protocol), while the groundedness judge received only the current MCP results. This could classify a factually correct follow-up as unsupported.
|
||||
|
||||
### Fix
|
||||
|
||||
The framework now records completed/failed transactional tool outcomes as bounded operational evidence in LangGraph state/checkpoint (`transaction_evidence`). This is operational state, not Long Term Memory.
|
||||
|
||||
For each new turn, the runtime correlates previous transaction evidence with the current resource using generic identifiers (`*_id`, `order_id`, `invoice_id`, `asset_id`, `resource_key`, etc.). Only relevant evidence is materialized as `relevant_transaction_evidence`.
|
||||
|
||||
The same relevant evidence is:
|
||||
|
||||
- injected into the answering LLM prompt;
|
||||
- merged with current MCP results for groundedness judges;
|
||||
- exposed in response metadata as `transaction_evidence` for diagnostics;
|
||||
- emitted with the completion telemetry event.
|
||||
|
||||
The history is bounded to the 10 most recent transaction outcomes, and at most 5 correlated entries are injected for a turn.
|
||||
|
||||
### Expected retail example
|
||||
|
||||
1. `cancelar_pedido(PED-1001)` returns protocol `CANCEL-2026-001`.
|
||||
2. The result is persisted as transaction evidence.
|
||||
3. The next `consultar_pedido(PED-1001)` returns `EM_TRANSPORTE`.
|
||||
4. The answering agent and groundedness judge receive both the current order result and the prior cancellation evidence.
|
||||
5. A response that mentions `CANCEL-2026-001` is grounded rather than treated as an unsupported claim.
|
||||
|
||||
### Validação integrada Backend/MCP
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/VALIDACAO_TRANSACIONAL_BACKEND_MCP.md`.
|
||||
|
||||
### Correções implementadas
|
||||
|
||||
- `mcp_tools` é tratado como allowlist, não como lista de execução automática.
|
||||
- Tools `read_only` continuam disponíveis para enriquecimento de contexto.
|
||||
- Somente uma tool transacional compatível com a solicitação é selecionada.
|
||||
- `require_confirmation: true` cria `pending_tool_call` e `AWAITING_CONFIRMATION`.
|
||||
- O turno de confirmação executa a chamada pendente com `confirmed: true`.
|
||||
- O estado expõe `selected_tool_call`, `tool_policy_result`, `confirmation_required`, `confirmation_received` e `transaction_status`.
|
||||
- `reason` foi padronizado entre catálogo, mapping e FastMCP Retail.
|
||||
- Pedido `123` e `PED-ENTREGUE` retornam status `ENTREGUE` para testes positivos.
|
||||
- A keyword genérica `produto` foi removida da intenção Telecom para não capturar devoluções Retail.
|
||||
- Templates `Normal` e `Route_Stickness` em `Tuning-Performance` foram atualizados.
|
||||
|
||||
### Teste recomendado
|
||||
|
||||
1. `Quero devolver o pedido 123 porque me arrependi da compra.`
|
||||
2. Esperado: `transaction_status=AWAITING_CONFIRMATION`, sem execução de `solicitar_devolucao`.
|
||||
3. `Sim, confirmo a devolução.`
|
||||
4. Esperado: `transaction_status=COMPLETED` e execução única de `solicitar_devolucao`.
|
||||
|
||||
### Resultado automatizado
|
||||
|
||||
```text
|
||||
7 passed
|
||||
```
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `docs/TRANSACTION_STATE_DEVELOPER_GUIDE.md`
|
||||
- `docs/ADR_TRANSACTIONAL_WORKFLOW_ENGINE.md`
|
||||
- `Documentacao/IMPLEMENTACAO_WORKFLOWS_TRANSACIONAIS.md`
|
||||
- `FIX_TRANSACTION_PARAMETER_PRECEDENCE.md`
|
||||
- `FIX_TRANSACTION_INTENT_LOOP.md`
|
||||
- `docs/TRANSACTION_OPERATIONAL_EVIDENCE_FIX.md`
|
||||
- `Documentacao/VALIDACAO_TRANSACIONAL_BACKEND_MCP.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
826
docs/developer/pt/04_mcp_integration_tools_and_policies.md
Normal file
826
docs/developer/pt/04_mcp_integration_tools_and_policies.md
Normal file
@@ -0,0 +1,826 @@
|
||||
|
||||
### MCP, Tools, Policies e Extração de Parâmetros
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **tools, MCP Servers, mappings, policies read-only/transacionais e extração de parâmetros**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Tools, mcp servers, mappings, policies read-only/transacionais e extração de parâmetros.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Integração MCP, Tools, Políticas e Extração de Parâmetros
|
||||
|
||||
Manual de desenvolvimento para integrar MCP Servers, registrar tools, isolar tools por agente, configurar políticas read-only/transacionais, confirmação e extração contextual de parâmetros.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Manual completo de integração MCP Servers
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/Manual_Integracao_MCP_Servers_Agent_Framework.docx`.
|
||||
|
||||
Manual de Integração com Servidores MCP
|
||||
Agent Framework Multi-Agent - Router, Supervisor, Tools e Servidores Externos
|
||||
Este documento explica os conceitos de MCP, como o projeto atual integra servidores MCP, como subir os servidores de exemplo Telecom e Retail, como configurar tools por agente e como evoluir a implementação para um MCP mais aderente ao padrão oficial. O objetivo é servir como guia de desenvolvimento, operação local e implantação em container/OCI.
|
||||
|
||||
### Conceitos de MCP
|
||||
|
||||
MCP significa Model Context Protocol. Ele define uma forma padronizada para aplicações de IA acessarem contexto externo, ferramentas e capacidades de sistemas fora do modelo. Em vez de colocar integrações diretamente dentro do prompt ou dentro do agente, o MCP separa a responsabilidade: o agente decide o que precisa, e um servidor MCP oferece tools, resources e prompts de forma controlada.
|
||||
No padrão oficial, o MCP usa mensagens JSON-RPC e define transportes como stdio e Streamable HTTP. O projeto atual usa uma implementação HTTP simplificada para facilitar entendimento e testes locais, com endpoints REST /mcp/tools/list e /mcp/tools/call. Isso é adequado para tutorial e prototipação, mas pode ser evoluído para um client MCP oficial posteriormente.
|
||||
|
||||
### Como o projeto atual organiza MCP
|
||||
|
||||
A estrutura relevante do projeto é:
|
||||
```
|
||||
projeto_multi_agent_isolado/
|
||||
agent_framework/
|
||||
src/agent_framework/mcp/
|
||||
client.py
|
||||
models.py
|
||||
registry.py
|
||||
tool_router.py
|
||||
|
||||
agent_template_backend/
|
||||
config/
|
||||
mcp_servers.yaml
|
||||
mcp_servers.docker.yaml
|
||||
tools.yaml
|
||||
mcp_parameter_mapping.yaml
|
||||
app/
|
||||
main.py
|
||||
workflows/agent_graph.py
|
||||
|
||||
mcp_servers/
|
||||
telecom_mcp_server/
|
||||
main.py
|
||||
requirements.txt
|
||||
Dockerfile
|
||||
retail_mcp_server/
|
||||
main.py
|
||||
requirements.txt
|
||||
Dockerfile
|
||||
|
||||
scripts/
|
||||
run_mcp_servers.sh
|
||||
docker-compose.yml
|
||||
```
|
||||
|
||||
### Componentes principais
|
||||
|
||||
|
||||
### Contrato HTTP simplificado usado no projeto
|
||||
|
||||
```
|
||||
GET /mcp/tools/list
|
||||
POST /mcp/tools/call
|
||||
|
||||
Payload de chamada:
|
||||
{
|
||||
"tool_name": "consultar_fatura",
|
||||
"arguments": {
|
||||
"msisdn": "11999999999",
|
||||
"invoice_id": "INV-001"
|
||||
}
|
||||
}
|
||||
|
||||
Resposta esperada:
|
||||
{
|
||||
"ok": true,
|
||||
"result": { ... },
|
||||
"metadata": {
|
||||
"server": "telecom",
|
||||
"tool": "consultar_fatura"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Como subir os servidores MCP de exemplo
|
||||
|
||||
O projeto possui dois servidores MCP de exemplo: Telecom e Retail. Eles são FastAPI apps independentes. O servidor Telecom roda na porta 8100 e expõe tools como consultar_fatura, consultar_pagamentos, consultar_plano e listar_servicos. O servidor Retail roda na porta 8200 e expõe tools como consultar_pedido, consultar_entrega, solicitar_troca e solicitar_devolucao.
|
||||
|
||||
### Subida local via script
|
||||
|
||||
```
|
||||
cd projeto_multi_agent_isolado
|
||||
bash ./scripts/run_mcp_servers.sh
|
||||
```
|
||||
O script cria uma venv no diretório raiz, instala as dependências dos servidores MCP e sobe os dois processos uvicorn em background:
|
||||
```
|
||||
Telecom MCP: http://localhost:8100
|
||||
Retail MCP: http://localhost:8200
|
||||
```
|
||||
|
||||
### Subida manual do Telecom MCP
|
||||
|
||||
```
|
||||
cd projeto_multi_agent_isolado
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r mcp_servers/telecom_mcp_server/requirements.txt
|
||||
uvicorn --app-dir mcp_servers/telecom_mcp_server main:app --host 0.0.0.0 --port 8100
|
||||
```
|
||||
|
||||
### Subida manual do Retail MCP
|
||||
|
||||
```
|
||||
cd projeto_multi_agent_isolado
|
||||
source .venv/bin/activate
|
||||
pip install -r mcp_servers/retail_mcp_server/requirements.txt
|
||||
uvicorn --app-dir mcp_servers/retail_mcp_server main:app --host 0.0.0.0 --port 8200
|
||||
```
|
||||
|
||||
### Subida com Docker Compose
|
||||
|
||||
```
|
||||
cd projeto_multi_agent_isolado
|
||||
docker compose up --build
|
||||
```
|
||||
No Docker Compose, o backend usa mcp_servers.docker.yaml porque, dentro da rede do compose, localhost apontaria para o próprio container do backend. Por isso os endpoints usam nomes de serviço: telecom-mcp e retail-mcp.
|
||||
```
|
||||
services:
|
||||
telecom-mcp:
|
||||
ports:
|
||||
- "8100:8100"
|
||||
|
||||
retail-mcp:
|
||||
ports:
|
||||
- "8200:8200"
|
||||
|
||||
backend:
|
||||
environment:
|
||||
MCP_SERVERS_CONFIG_PATH: /app/config/mcp_servers.docker.yaml
|
||||
depends_on:
|
||||
- telecom-mcp
|
||||
- retail-mcp
|
||||
```
|
||||
|
||||
### Como testar as tools MCP
|
||||
|
||||
|
||||
### Health check direto nos servidores
|
||||
|
||||
```
|
||||
curl http://localhost:8100/health
|
||||
curl http://localhost:8200/health
|
||||
```
|
||||
|
||||
### Listar tools diretamente no Telecom MCP
|
||||
|
||||
```
|
||||
curl http://localhost:8100/mcp/tools/list
|
||||
```
|
||||
|
||||
### Chamar tool diretamente no Telecom MCP
|
||||
|
||||
```
|
||||
curl -X POST http://localhost:8100/mcp/tools/call -H 'Content-Type: application/json' -d '{
|
||||
"tool_name": "consultar_fatura",
|
||||
"arguments": {
|
||||
"msisdn": "11999999999",
|
||||
"invoice_id": "INV-001"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Chamar tool diretamente no Retail MCP
|
||||
|
||||
```
|
||||
curl -X POST http://localhost:8200/mcp/tools/call -H 'Content-Type: application/json' -d '{
|
||||
"tool_name": "consultar_pedido",
|
||||
"arguments": {
|
||||
"order_id": "PED-1001",
|
||||
"customer_id": "C-001"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Testar via backend do agente
|
||||
|
||||
Após subir os servidores MCP e o backend, o backend disponibiliza endpoints de debug para listar e chamar tools através do MCPToolRouter.
|
||||
```
|
||||
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
|
||||
curl http://localhost:8000/debug/mcp/tools
|
||||
|
||||
curl -X POST http://localhost:8000/debug/mcp/call/consultar_fatura -H 'Content-Type: application/json' -d '{"msisdn":"11999999999","invoice_id":"INV-001"}'
|
||||
```
|
||||
|
||||
### Como o agente chama MCP no fluxo
|
||||
|
||||
O agente não precisa conhecer a URL do servidor. Ele chama uma tool lógica pelo MCPToolRouter. O fluxo esperado é:
|
||||
```
|
||||
Usuário
|
||||
-> FastAPI /gateway/message
|
||||
-> Guardrails de input
|
||||
-> Router ou Supervisor escolhe o agente
|
||||
-> LangGraph executa o agent graph
|
||||
-> Agent decide usar uma tool
|
||||
-> MCPToolRouter.call("consultar_fatura", {...})
|
||||
-> MCPRegistry resolve servidor telecom
|
||||
-> MCPHttpClient chama http://localhost:8100/mcp/tools/call
|
||||
-> Resultado volta ao agent graph
|
||||
-> Guardrails de output
|
||||
-> Judges
|
||||
-> Resposta final
|
||||
```
|
||||
|
||||
### Exemplo conceitual em Python
|
||||
|
||||
```
|
||||
result = await tool_router.call(
|
||||
"consultar_fatura",
|
||||
{
|
||||
"msisdn": context.get("msisdn"),
|
||||
"invoice_id": context.get("invoice_id"),
|
||||
},
|
||||
)
|
||||
|
||||
if result.ok:
|
||||
dados_fatura = result.result
|
||||
else:
|
||||
# fallback controlado, telemetria e resposta segura
|
||||
erro = result.error
|
||||
```
|
||||
|
||||
### Exemplo via mensagem do gateway
|
||||
|
||||
```
|
||||
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"
|
||||
}
|
||||
}
|
||||
}'
|
||||
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"
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### Como configurar novos servidores e tools
|
||||
|
||||
|
||||
### Adicionar um novo MCP Server
|
||||
|
||||
Edite agent_template_backend/config/mcp_servers.yaml para execução local:
|
||||
```
|
||||
servers:
|
||||
crm:
|
||||
transport: http
|
||||
endpoint: http://localhost:8300/mcp
|
||||
enabled: true
|
||||
description: MCP Server de CRM.
|
||||
```
|
||||
Edite agent_template_backend/config/mcp_servers.docker.yaml para execução em Docker:
|
||||
```
|
||||
servers:
|
||||
crm:
|
||||
transport: http
|
||||
endpoint: http://crm-mcp:8300/mcp
|
||||
enabled: true
|
||||
description: MCP Server de CRM via docker-compose.
|
||||
```
|
||||
|
||||
### Registrar uma nova tool
|
||||
|
||||
Edite agent_template_backend/config/tools.yaml:
|
||||
```
|
||||
tools:
|
||||
consultar_cliente:
|
||||
description: Consulta dados cadastrais resumidos do cliente.
|
||||
mcp_server: crm
|
||||
enabled: true
|
||||
args_schema:
|
||||
customer_id: string
|
||||
document_id: string
|
||||
```
|
||||
|
||||
### Implementar o endpoint no servidor MCP
|
||||
|
||||
```
|
||||
TOOLS = {
|
||||
"consultar_cliente": {
|
||||
"description": "Consulta dados cadastrais resumidos do cliente.",
|
||||
"input_schema": {
|
||||
"customer_id": "string",
|
||||
"document_id": "string"
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@app.post("/mcp/tools/call")
|
||||
async def call_tool(call: ToolCall):
|
||||
if call.tool_name == "consultar_cliente":
|
||||
return {
|
||||
"ok": True,
|
||||
"result": {
|
||||
"customer_id": call.arguments.get("customer_id"),
|
||||
"status": "ATIVO",
|
||||
"segmento": "PREMIUM"
|
||||
},
|
||||
"metadata": {"server": "crm", "tool": "consultar_cliente"}
|
||||
}
|
||||
```
|
||||
|
||||
### Como isolar MCP por agente
|
||||
|
||||
Em uma arquitetura multi-agent, nem todo agente deve enxergar todas as tools. O agente de pedidos pode usar consultar_pedido e consultar_entrega. O agente de contas pode usar consultar_fatura e consultar_pagamentos. Esse isolamento reduz risco operacional, melhora governança e simplifica o prompt de cada agente.
|
||||
|
||||
### Opção simples: allowlist por agente
|
||||
|
||||
```
|
||||
agents:
|
||||
- agent_id: billing_agent
|
||||
allowed_tools:
|
||||
- consultar_fatura
|
||||
- consultar_pagamentos
|
||||
- consultar_plano
|
||||
- listar_servicos
|
||||
|
||||
- agent_id: orders_agent
|
||||
allowed_tools:
|
||||
- consultar_pedido
|
||||
- consultar_entrega
|
||||
- solicitar_troca
|
||||
- solicitar_devolucao
|
||||
```
|
||||
|
||||
### Opção recomendada: tools por arquivo de configuração
|
||||
|
||||
Para projetos grandes, cada agente pode ter seu próprio arquivo tools.yaml, guardrails.yaml e judges.yaml. Isso mantém isolamento real por agente e facilita versionamento.
|
||||
```
|
||||
config/agents/telecom_contas/
|
||||
prompt_policy.yaml
|
||||
guardrails.yaml
|
||||
judges.yaml
|
||||
tools.yaml
|
||||
|
||||
config/agents/retail_orders/
|
||||
prompt_policy.yaml
|
||||
guardrails.yaml
|
||||
judges.yaml
|
||||
tools.yaml
|
||||
```
|
||||
|
||||
### Como implantar com Docker e OCI
|
||||
|
||||
|
||||
### Implantação local com Docker Compose
|
||||
|
||||
O docker-compose.yml atual já possui serviços separados para telecom-mcp, retail-mcp, backend e frontend. Essa separação é correta porque MCP Servers devem ser escaláveis e versionáveis de forma independente do backend do agente.
|
||||
```
|
||||
docker compose up --build
|
||||
|
||||
# URLs externas para teste local:
|
||||
http://localhost:8100/health
|
||||
http://localhost:8200/health
|
||||
http://localhost:8000/debug/mcp/tools
|
||||
http://localhost:5173
|
||||
```
|
||||
|
||||
### Implantação em OCI/OKE
|
||||
|
||||
Em Kubernetes/OKE, cada MCP Server deve ser implantado como Deployment + Service. O backend do agente aponta para o DNS interno do Service. Exemplo conceitual:
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: telecom-mcp
|
||||
spec:
|
||||
selector:
|
||||
app: telecom-mcp
|
||||
ports:
|
||||
- port: 8100
|
||||
targetPort: 8100
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: telecom-mcp
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
matchLabels:
|
||||
app: telecom-mcp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: telecom-mcp
|
||||
spec:
|
||||
containers:
|
||||
- name: telecom-mcp
|
||||
image: <registry>/telecom-mcp:1.0.0
|
||||
ports:
|
||||
- containerPort: 8100
|
||||
```
|
||||
|
||||
### Configuração do backend em Kubernetes
|
||||
|
||||
```
|
||||
servers:
|
||||
telecom:
|
||||
transport: http
|
||||
endpoint: http://telecom-mcp.default.svc.cluster.local:8100/mcp
|
||||
enabled: true
|
||||
|
||||
retail:
|
||||
transport: http
|
||||
endpoint: http://retail-mcp.default.svc.cluster.local:8200/mcp
|
||||
enabled: true
|
||||
```
|
||||
|
||||
### Segurança, guardrails e observabilidade
|
||||
|
||||
MCP aumenta muito a capacidade do agente, mas também aumenta a superfície de risco. Uma tool pode consultar dados sensíveis, abrir protocolos, cancelar serviços, gerar créditos ou executar ações de negócio. Por isso, a integração precisa ser protegida antes, durante e depois da chamada.
|
||||
|
||||
### Checklist de segurança mínimo
|
||||
|
||||
- Toda tool deve ter descrição clara e schema de argumentos.
|
||||
- Toda tool de ação deve exigir confirmação explícita do usuário antes da execução.
|
||||
- Cada agente deve ter allowlist de tools.
|
||||
- Dados sensíveis retornados por MCP devem passar por masking/sanitização antes da resposta final.
|
||||
- Toda chamada MCP deve gerar trace/span/event em Langfuse ou OpenTelemetry.
|
||||
- Timeouts e limites de retries devem ser configurados por tool ou por servidor.
|
||||
- Não expor MCP Servers diretamente à internet sem autenticação, TLS e controle de rede.
|
||||
- Separar tools read-only de tools transacionais.
|
||||
|
||||
### Telemetria recomendada
|
||||
|
||||
```
|
||||
span: mcp.tool_call
|
||||
attributes:
|
||||
tenant_id
|
||||
agent_id
|
||||
session_id
|
||||
tool_name
|
||||
mcp_server
|
||||
latency_ms
|
||||
ok
|
||||
error
|
||||
input_argument_keys
|
||||
result_size
|
||||
|
||||
event: mcp.tool_call.completed
|
||||
metadata:
|
||||
tool_name
|
||||
server
|
||||
ok
|
||||
error
|
||||
```
|
||||
|
||||
### Evolução para MCP oficial
|
||||
|
||||
O projeto atual usa um contrato HTTP simplificado. Para produção corporativa, existem duas opções. A primeira é manter esse contrato interno por simplicidade, desde que ele seja bem documentado, seguro e versionado. A segunda é evoluir para um client/server MCP oficial com JSON-RPC, stdio ou Streamable HTTP.
|
||||
|
||||
### Passo a passo completo para o desenvolvedor
|
||||
|
||||
```
|
||||
# 1. Baixar e abrir o projeto
|
||||
cd projeto_multi_agent_isolado
|
||||
|
||||
# 2. Subir servidores MCP de exemplo
|
||||
bash ./scripts/run_mcp_servers.sh
|
||||
|
||||
# 3. Em outro terminal, subir backend
|
||||
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
|
||||
|
||||
# 4. Validar tools carregadas pelo backend
|
||||
curl http://localhost:8000/debug/mcp/tools
|
||||
|
||||
# 5. Chamar tool Telecom
|
||||
curl -X POST http://localhost:8000/debug/mcp/call/consultar_fatura -H 'Content-Type: application/json' -d '{"msisdn":"11999999999","invoice_id":"INV-001"}'
|
||||
|
||||
# 6. Chamar tool Retail
|
||||
curl -X POST http://localhost:8000/debug/mcp/call/consultar_pedido -H 'Content-Type: application/json' -d '{"order_id":"PED-1001","customer_id":"C-001"}'
|
||||
|
||||
# 7. Testar pelo gateway conversacional
|
||||
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"}}}'
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
|
||||
### Referências
|
||||
|
||||
- Model Context Protocol Specification: https://modelcontextprotocol.io/specification
|
||||
- MCP Transports: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports
|
||||
- MCP Resources: https://modelcontextprotocol.io/specification/2025-06-18/server/resources
|
||||
- Reference MCP Servers: https://github.com/modelcontextprotocol/servers
|
||||
- LangChain MCP Adapters: https://docs.langchain.com/oss/python/langchain/mcp
|
||||
- Arquivos do projeto: agent_framework/src/agent_framework/mcp/*, agent_template_backend/config/mcp_servers.yaml, agent_template_backend/config/tools.yaml, mcp_servers/*
|
||||
|
||||
### Políticas read-only e transacionais
|
||||
|
||||
O framework aplica uma política conversacional mínima imediatamente antes da chamada MCP. A classificação read_only identifica consultas; transactional identifica operações que alteram estado. Autorização, idempotência, validação e atomicidade continuam sob responsabilidade do MCP Server.
|
||||
|
||||
### Configuração no backend
|
||||
|
||||
A configuração é opcional e fica em config/tool_policies.yaml no agent_template_backend. O caminho pode ser definido por TOOL_POLICIES_PATH. Não coloque políticas de domínio dentro da biblioteca compartilhada.
|
||||
Exemplo:
|
||||
defaults:
|
||||
operation_type: read_only
|
||||
require_confirmation: false
|
||||
tool_policies:
|
||||
alterar_plano:
|
||||
operation_type: transactional
|
||||
require_confirmation: true
|
||||
requires: [new_plan_id]
|
||||
|
||||
### Execução e compatibilidade
|
||||
|
||||
- A confirmação deve chegar como confirmed: true ou confirmation: true; texto com valor true não é suficiente.
|
||||
- Se tool_policies.yaml não existir, permanecem válidos tool_type, requires, confirmation_required e execution_policy de tools.yaml.
|
||||
- Tools antigas sem política continuam funcionando sem alteração de comportamento.
|
||||
- Uma chamada bloqueada não alcança o MCP e retorna metadados blocked_by_policy, operation_type e policy_source.
|
||||
|
||||
### Políticas read-only e transacionais
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_TOOL_POLICIES.md`.
|
||||
|
||||
### Objetivo
|
||||
|
||||
O framework diferencia operações de consulta (`read_only`) e operações que alteram estado (`transactional`) imediatamente antes da chamada MCP. Essa classificação não substitui autorização, idempotência ou regras de negócio do servidor MCP; ela acrescenta somente a proteção conversacional mínima, especialmente confirmação explícita.
|
||||
|
||||
### Onde configurar
|
||||
|
||||
A parametrização pertence ao backend da aplicação:
|
||||
|
||||
```text
|
||||
templates/agent_template_backend/config/tool_policies.yaml
|
||||
```
|
||||
|
||||
A biblioteca compartilhada contém apenas o loader e a validação. O caminho é opcional:
|
||||
|
||||
```dotenv
|
||||
TOOL_POLICIES_PATH=./config/tool_policies.yaml
|
||||
```
|
||||
|
||||
### Exemplo
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
|
||||
defaults:
|
||||
operation_type: read_only
|
||||
require_confirmation: false
|
||||
|
||||
tool_policies:
|
||||
consultar_plano:
|
||||
operation_type: read_only
|
||||
|
||||
alterar_plano:
|
||||
operation_type: transactional
|
||||
require_confirmation: true
|
||||
requires: [new_plan_id]
|
||||
```
|
||||
|
||||
Para executar `alterar_plano`, os argumentos precisam conter `new_plan_id` e um booleano literal de confirmação:
|
||||
|
||||
```json
|
||||
{"new_plan_id": "CONTROLE_100", "confirmed": true}
|
||||
```
|
||||
|
||||
Também é aceito `"confirmation": true`. Strings como `"true"` não são aceitas como confirmação.
|
||||
|
||||
### Compatibilidade
|
||||
|
||||
- Se `tool_policies.yaml` não existir, o framework continua usando `tool_type`, `requires`, `confirmation_required` e `execution_policy` de `tools.yaml`.
|
||||
- Tools antigas sem política continuam executando como antes.
|
||||
- Uma política explícita no arquivo novo prevalece para `operation_type` e confirmação daquela tool.
|
||||
- O catálogo `tools.yaml` continua sendo a fonte de endpoint, schema, habilitação e cache.
|
||||
- O novo arquivo não deve ser colocado em `libs/agent_framework`, pois as decisões variam por aplicação e domínio.
|
||||
|
||||
### Fluxo de execução
|
||||
|
||||
```text
|
||||
agente -> MCPToolRouter -> validação da política -> mapeamento de parâmetros -> MCP Gateway/Server
|
||||
```
|
||||
|
||||
Uma chamada bloqueada retorna `ok=false`, `metadata.blocked_by_policy=true`, o tipo da operação e a origem da política. O servidor MCP permanece a autoridade final para autenticação, autorização, validação, idempotência e transação de negócio.
|
||||
|
||||
### Migração recomendada
|
||||
|
||||
1. Atualize a biblioteca sem criar o arquivo: o comportamento permanece legado.
|
||||
2. Crie `config/tool_policies.yaml` no backend.
|
||||
3. Cadastre primeiro apenas operações transacionais que exigem confirmação.
|
||||
4. Teste chamadas sem confirmação, com confirmação booleana e com campos obrigatórios ausentes.
|
||||
5. Remova gradualmente duplicações de confirmação de `tools.yaml` quando todos os templates consumidores já usarem a nova configuração.
|
||||
|
||||
|
||||
### Runtime transacional mínimo (correção de amarração)
|
||||
|
||||
A lista `mcp_tools` do roteamento é uma **allowlist**, não uma ordem para executar todas as ferramentas. O runtime agora:
|
||||
|
||||
1. executa automaticamente somente ferramentas `read_only`;
|
||||
2. seleciona no máximo uma ação transacional compatível com o pedido do usuário;
|
||||
3. quando `require_confirmation: true`, persiste `pending_tool_call` e `transaction_status: AWAITING_CONFIRMATION`;
|
||||
4. no turno de confirmação, reutiliza a mesma chamada e executa com `confirmed: true`;
|
||||
5. publica no estado `available_mcp_tools`, `selected_tool_call`, `tool_policy_result`, `confirmation_required` e `confirmation_received`.
|
||||
|
||||
Para o cenário de exemplo, o pedido `123` (ou `PED-ENTREGUE`) retorna `ENTREGUE` no MCP Retail. Use:
|
||||
|
||||
```text
|
||||
Quero devolver o pedido 123 porque me arrependi da compra.
|
||||
Sim, confirmo a devolução.
|
||||
```
|
||||
|
||||
O contrato MCP foi padronizado para usar `reason` tanto no catálogo quanto no servidor FastMCP. `tool_policies.yaml` prevalece sobre os campos legados de `tools.yaml`; estes permanecem alinhados nos templates para compatibilidade.
|
||||
|
||||
### Integração e compatibilidade das tool policies
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/RELEASE_NOTES_TOOL_POLICIES.md`.
|
||||
|
||||
### Alterações
|
||||
|
||||
- Novo `ToolPolicyRegistry` opcional na biblioteca compartilhada.
|
||||
- Validação central no `MCPToolRouter`, inclusive para chamadas diretas.
|
||||
- Tipos mínimos `read_only` e `transactional`.
|
||||
- Confirmação estrita por `confirmed: true` ou `confirmation: true`.
|
||||
- Suporte opcional a campos obrigatórios por política.
|
||||
- Fallback automático para `tool_type`, `requires`, `confirmation_required` e `execution_policy` de `tools.yaml`.
|
||||
- `config/tool_policies.yaml` e variável `TOOL_POLICIES_PATH` nos templates principais, Day Zero e variantes de `Tuning-Performance/Normal` e `Tuning-Performance/Route_Stickness`.
|
||||
- Testes unitários de política e compatibilidade adicionados em `tests/unit/test_tool_policies.py`.
|
||||
|
||||
### Verificações executadas
|
||||
|
||||
- Compilação de `libs`, `templates`, `Tuning-Performance` e `tests`: aprovada.
|
||||
- Validação estrutural dos seis arquivos YAML: aprovada.
|
||||
- Casos isolados do loader (política transacional, confirmação, ausência de arquivo e ausência de cadastro): aprovados.
|
||||
- Renderização dos dois manuais Word atualizados: aprovada, sem cortes ou sobreposição nas páginas adicionadas.
|
||||
|
||||
### Limitação do ambiente de validação
|
||||
|
||||
A suíte `pytest` foi preparada, mas não pôde ser executada integralmente neste ambiente porque `pytest` e as dependências de runtime do projeto não estavam instalados e o acesso ao índice de pacotes expirou. Para reproduzir em um ambiente do projeto:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=libs/agent_framework/src:templates/agent_template_backend python -m pytest -q
|
||||
```
|
||||
|
||||
### Correção de integração backend/MCP
|
||||
- `mcp_tools` passou a ser tratado como allowlist.
|
||||
- Ações não são mais executadas automaticamente junto com consultas.
|
||||
- Confirmação transacional é persistida e retomada no turno seguinte.
|
||||
- Corrigida incompatibilidade `reason`/`motivo` no MCP Retail.
|
||||
- Adicionado pedido entregue determinístico para testes (`123`).
|
||||
- Removida keyword genérica `produto` da intenção Telecom para evitar colisão com devoluções Retail.
|
||||
- Templates Normal e Route_Stickness em `Tuning-Performance` foram sincronizados.
|
||||
|
||||
### Extração contextual de parâmetros MCP
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/RELEASE_NOTES_MCP_PARAMETER_EXTRACTION_FIX.md`.
|
||||
|
||||
### Problema corrigido
|
||||
|
||||
O bloco `extract` do `mcp_parameter_mapping.yaml` existia na configuração e na
|
||||
documentação, mas não era executado pelo runtime. Além disso, valores do
|
||||
Business Context podiam sobrescrever argumentos explícitos, fazendo
|
||||
`contract_key` substituir o `order_id` informado pelo usuário.
|
||||
|
||||
### Correções
|
||||
|
||||
- implementação da extração genérica `strategy: llm` após a escolha da tool;
|
||||
- suporte preservado para `strategy: month_name_pt`;
|
||||
- profile dedicado `mcp_parameter_extraction`;
|
||||
- telemetria `llm.mcp_parameter_extraction`;
|
||||
- `extract` deixou de ser interpretado como mapeamento simples;
|
||||
- argumentos explícitos/extraídos têm precedência sobre Business Context;
|
||||
- remoção de `contract_key: order_id` dos templates;
|
||||
- `order_id` configurado como `string`;
|
||||
- atualização das variantes em `Tuning-Performance`.
|
||||
|
||||
### Resultado esperado
|
||||
|
||||
Para a mensagem `consultar pedido 123`, a chamada MCP deve receber
|
||||
`order_id=123`, mesmo quando o Business Context contém outro `contract_key`.
|
||||
|
||||
### Uso local de MCP tools
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_MCP.md`.
|
||||
|
||||
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`.
|
||||
|
||||
### Operações read-only e transacionais
|
||||
|
||||
Use `config/tool_policies.yaml` no backend para classificar somente as operações que precisam de tratamento adicional. A validação é aplicada no roteador central antes do MCP Gateway/Server. O arquivo é opcional e templates antigos continuam usando as políticas já presentes em `tools.yaml`. A configuração completa e o roteiro de migração estão em [README_TOOL_POLICIES.md](README_TOOL_POLICIES.md).
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `Documentacao/Manual_Integracao_MCP_Servers_Agent_Framework.docx`
|
||||
- `Documentacao/README_TOOL_POLICIES.md`
|
||||
- `Documentacao/RELEASE_NOTES_TOOL_POLICIES.md`
|
||||
- `Documentacao/RELEASE_NOTES_MCP_PARAMETER_EXTRACTION_FIX.md`
|
||||
- `Documentacao/README_MCP.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
2466
docs/developer/pt/05_agent_gateway_mcp_gateway_and_auth.md
Normal file
2466
docs/developer/pt/05_agent_gateway_mcp_gateway_and_auth.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,229 @@
|
||||
|
||||
### Guardrails, Judges e Avaliação Transacional
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **guardrails nativos/externos, judges, sampling transacional e grounding**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Guardrails nativos/externos, judges, sampling transacional e grounding.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Guardrails, Judges e Avaliação Transacional
|
||||
|
||||
Manual para guardrails de entrada/saída, extensões específicas por agente, judges externos, execução obrigatória em transações e sinais/evidências usados na avaliação.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Guardrails implementados no framework
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_GUARDRAILS_IMPLEMENTADOS.md`.
|
||||
|
||||
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"],
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
### SPI de guardrails e judges externos
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/EXTERNAL_GUARDRAILS_JUDGES.md`.
|
||||
|
||||
`agent_framework_oci` supports agent-owned guardrails and judges without importing domain code into the core.
|
||||
|
||||
```yaml
|
||||
output:
|
||||
- code: ACME_POLICY
|
||||
type: external
|
||||
class: app.extensions.guardrails:AcmePolicyRail
|
||||
```
|
||||
|
||||
```yaml
|
||||
judges:
|
||||
- name: acme_quality
|
||||
type: external
|
||||
class: app.extensions.judges:AcmeQualityJudge
|
||||
threshold: 0.7
|
||||
```
|
||||
|
||||
Native entries remain unchanged. External synchronous `evaluate()` methods execute in worker threads via `asyncio.to_thread`; asynchronous methods execute concurrently on the framework event loop. Judges run concurrently with `asyncio.gather`, preserving YAML result order. Agent plugins should reuse the LLM supplied by the framework rather than instantiate a separate provider.
|
||||
|
||||
The core must not reference a concrete agent package, company, product, telecom identifier or domain-specific policy. Domain-specific variants belong to the agent and should receive distinct public codes/names.
|
||||
|
||||
### Compatibility rule
|
||||
Domain policies must not be replaced by cosmetically generic text inside the core while losing the original policy. The generic core implementation and the agent-specific implementation may coexist; the embedding agent explicitly selects its own code/name in YAML.
|
||||
|
||||
Legacy business validators should migrate to the agent domain. A temporary compatibility shim is acceptable for old imports, but new application code must import the agent-owned implementation.
|
||||
|
||||
### Execução obrigatória de judges em transações
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/JUDGES_TRANSACTIONAL_SAMPLING_FIX.md`.
|
||||
|
||||
### Problema
|
||||
|
||||
Mesmo com `always_run_for_transactional: true`, os judges podiam ser ignorados
|
||||
pela amostragem porque o nó `judge` enviava apenas `context`, `route`, `intent` e
|
||||
`mcp_results`. Os campos transacionais produzidos pelo runtime não chegavam ao
|
||||
`JudgePipeline`.
|
||||
|
||||
### Correção
|
||||
|
||||
O nó `judge` agora repassa:
|
||||
|
||||
- `transaction_status`
|
||||
- `confirmation_required`
|
||||
- `confirmation_received`
|
||||
- `tool_policy_result`
|
||||
- `selected_tool_call`
|
||||
- `pending_tool_call`
|
||||
- `mcp_results` como evidência
|
||||
|
||||
O `JudgePipeline` detecta transações por múltiplos sinais e avalia
|
||||
`always_run_for_transactional` antes de aplicar `sample_rate`.
|
||||
|
||||
Com a configuração abaixo, consultas comuns continuam sendo amostradas em 25%,
|
||||
mas turnos `AWAITING_CONFIRMATION`, `COMPLETED`, `FAILED` ou `CANCELLED` executam
|
||||
os judges sempre.
|
||||
|
||||
```yaml
|
||||
enabled: true
|
||||
sample_rate: 0.25
|
||||
always_run_for_transactional: true
|
||||
```
|
||||
|
||||
### Validação do Global Supervisor
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/docs_GLOBAL_SUPERVISOR_VALIDATION.txt`.
|
||||
|
||||
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.
|
||||
|
||||
### Validação de eventos de guardrail
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/docs_VALIDATION_GUARDRAILS_IC.txt`.
|
||||
|
||||
VALIDATION REPORT - guardrails parallel fail-fast + observer IC
|
||||
Date: 2026-06-03
|
||||
|
||||
compileall: OK
|
||||
smoke-tests: OK
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `Documentacao/README_GUARDRAILS_IMPLEMENTADOS.md`
|
||||
- `docs/EXTERNAL_GUARDRAILS_JUDGES.md`
|
||||
- `docs/JUDGES_TRANSACTIONAL_SAMPLING_FIX.md`
|
||||
- `docs/docs_GLOBAL_SUPERVISOR_VALIDATION.txt`
|
||||
- `docs/docs_VALIDATION_GUARDRAILS_IC.txt`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
396
docs/developer/pt/07_rag_business_context_and_grounding.md
Normal file
396
docs/developer/pt/07_rag_business_context_and_grounding.md
Normal file
@@ -0,0 +1,396 @@
|
||||
|
||||
### RAG, BusinessContext e Grounding
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **RAG, providers, BusinessContext, contexto recuperado e grounding**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Rag, providers, businesscontext, contexto recuperado e grounding.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### RAG, Providers Enterprise, BusinessContext e Grounding
|
||||
|
||||
Guia de integração de conhecimento recuperado, seleção entre providers de RAG, configuração KBDB, amostras, suficiência MCP e uso do BusinessContext como contrato de dados.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Provider RAG Standard versus KBDB Enterprise
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/RAG_PROVIDER_KBDB.md`.
|
||||
|
||||
O framework passa a suportar dois backends de retrieval pelo mesmo contrato `RagService`, sem alterar os agentes nem `_retrieve_rag_context()`.
|
||||
|
||||
### Seleção
|
||||
|
||||
```env
|
||||
RAG_PROVIDER=standard # default: comportamento anterior
|
||||
# ou
|
||||
RAG_PROVIDER=kbdb # KBDB enterprise
|
||||
```
|
||||
|
||||
A seleção é exclusiva por processo. Os dois RAGs não executam juntos e não compartilham vector store, graph store ou ingestão.
|
||||
|
||||
### `standard`
|
||||
|
||||
Mantém integralmente o RAG já existente no `agent_framework_oci`: `VECTOR_STORE_PROVIDER`, `GRAPH_STORE_PROVIDER`, embedding, query rewrite, compression, retrieval guardrails e geração continuam válidos.
|
||||
|
||||
### `kbdb`
|
||||
|
||||
O framework integra somente a porta estável de serving do projeto KBDB:
|
||||
|
||||
`PKG_KB_SERVING.SEARCH_KNOWLEDGE_BASE`
|
||||
|
||||
O pipeline enterprise continua externo ao runtime do agente e preserva sua própria arquitetura RAW → SILVER → GOLD, HVI/hybrid search, property graph, publicação, lifecycle, auditoria e observabilidade.
|
||||
|
||||
O envelope KBDB é adaptado para `RagResult`/`VectorDocument`; portanto os agentes existentes continuam chamando `_retrieve_rag_context()` e os retrieval guardrails do framework continuam depois do retrieval.
|
||||
|
||||
### Configuração
|
||||
|
||||
```env
|
||||
RAG_PROVIDER=kbdb
|
||||
RAG_TOP_K=5
|
||||
KBDB_DB_USER=KB_USER
|
||||
KBDB_DB_PASSWORD=...
|
||||
KBDB_DB_DSN=...
|
||||
KBDB_DB_WALLET_LOCATION=...
|
||||
KBDB_DB_WALLET_PASSWORD=...
|
||||
KBDB_SEARCH_TYPE=hybrid
|
||||
KBDB_NODE_EXPANSION=true
|
||||
KBDB_NODE_MAX_RELATED=8
|
||||
KBDB_GRAPH_CROSS_REF=false
|
||||
KBDB_MAX_CROSS_REF_HOPS=1
|
||||
KBDB_DOCUMENT_TYPE=customer_safe
|
||||
KBDB_METADATA_JSON=
|
||||
KBDB_MIN_SCORE=
|
||||
```
|
||||
|
||||
Quando `RAG_PROVIDER=kbdb`, `KBDB_DB_USER`, `KBDB_DB_PASSWORD` e `KBDB_DB_DSN` são obrigatórios. O KBDB usa conexão isolada porque pode residir em outro Autonomous. `KBDB_DB_DSN` segue a mesma semântica de `ADB_DSN`: use o alias TNS existente no `tnsnames.ora` da wallet indicada por `KBDB_DB_WALLET_LOCATION`, e não uma URL `tcps://...`.
|
||||
|
||||
### Isolamento e compatibilidade
|
||||
|
||||
- `RAG_PROVIDER=standard` não importa nem conecta ao KBDB.
|
||||
- `RAG_PROVIDER=kbdb` não instancia vector/graph stores do RAG padrão.
|
||||
- Ingestão por `RagService.add_documents()` não é permitida no modo KBDB: deve passar pelo pipeline/publicação KBDB.
|
||||
- Query rewrite e context compression continuam opcionais e são aplicados pela camada comum do framework.
|
||||
- `AgentRuntimeMixin._retrieve_rag_context()` e os agentes permanecem inalterados.
|
||||
- Falhas do KBDB seguem a semântica existente do framework: retrieval é evidência auxiliar e a exceção é convertida em metadata técnica sem derrubar a jornada.
|
||||
|
||||
|
||||
### Resposta direta de tool e RAG
|
||||
|
||||
O framework não considera mais que um resultado MCP estruturado é, por si só, uma resposta suficiente ao usuário.
|
||||
|
||||
Uma política `response.renderer` define somente **como** apresentar o resultado. Ela não encerra o fluxo antes de RAG/LLM. Para uma tool deliberadamente produzir uma resposta final direta, a aplicação deve declarar explicitamente:
|
||||
|
||||
```yaml
|
||||
response:
|
||||
mode: renderer
|
||||
renderer: meu.renderer
|
||||
direct: true
|
||||
```
|
||||
|
||||
Sem `direct: true`, o resultado da tool permanece como evidência MCP e o fluxo segue para `_retrieve_rag_context()` e composição LLM. Isso permite, por exemplo, que uma consulta operacional de plano seja combinada com conhecimento documental do KBDB quando a pergunta pedir regras, políticas ou explicações.
|
||||
|
||||
O core do framework não possui fallback por nome de tool (`consultar_plano`, `consultar_pedido`, etc.). Regras de apresentação pertencem à aplicação/domínio.
|
||||
|
||||
|
||||
### Suficiência MCP e grounding
|
||||
|
||||
Um resultado MCP bem-sucedido **não** faz o framework pular RAG automaticamente.
|
||||
O domínio só pode declarar suficiência documental explicitamente no payload com
|
||||
`rag_sufficient=true` ou `knowledge_sufficient=true`. Essa decisão é genérica e
|
||||
não depende do nome da tool nem de palavras-chave de telecom/retail.
|
||||
|
||||
No provider `kbdb`, `KBDB_GROUNDED_ONLY=true` é o padrão. Quando a busca KBDB
|
||||
retorna vazia, bloqueada ou com erro, a composição LLM pode usar fatos comprovados
|
||||
por MCP/business context, mas não pode completar a parte documental com conhecimento
|
||||
paramétrico do modelo. Deve informar que não há evidência suficiente na base.
|
||||
|
||||
Eventos do ProductAgent registram `IC.PRODUCT_RAG_CONTEXT_EVALUATED` em toda
|
||||
tentativa/decisão e `IC.PRODUCT_RAG_CONTEXT_RETRIEVED` somente quando há contexto
|
||||
recuperado. Os metadados incluem `provider`, `status`, `document_count`, `reason`,
|
||||
`error`, `query`, `namespace` e `latency_ms`.
|
||||
|
||||
### Amostras e testes de RAG
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/README_rag_samples.md`.
|
||||
|
||||
These PDF files are synthetic, searchable sample documents created to validate the RAG embedding and retrieval flow of `agent_template_backend`.
|
||||
|
||||
### Files
|
||||
|
||||
- `01_billing_agent_invoice_policy.pdf` - sample knowledge for `billing_agent`
|
||||
- `02_orders_agent_lifecycle_policy.pdf` - sample knowledge for `orders_agent`
|
||||
- `03_product_agent_catalog_policy.pdf` - sample knowledge for `product_agent`
|
||||
- `04_support_agent_sla_policy.pdf` - sample knowledge for `support_agent`
|
||||
- `05_business_context_rag_flow.pdf` - sample knowledge about BusinessContext, identity.yaml and MCP parameter mapping
|
||||
|
||||
### How to use
|
||||
|
||||
Copy the PDF files to the backend documentation directory:
|
||||
|
||||
```bash
|
||||
mkdir -p agent_template_backend/docs/rag_samples
|
||||
cp *.pdf agent_template_backend/docs/rag_samples/
|
||||
```
|
||||
|
||||
For a local smoke test, use:
|
||||
|
||||
```env
|
||||
VECTOR_STORE_PROVIDER=sqlite
|
||||
EMBEDDING_PROVIDER=mock
|
||||
SQLITE_DB_PATH=./data/agent_framework.db
|
||||
RAG_TOP_K=4
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
python scripts/generate_rag_embeddings.py \
|
||||
--docs-dir ./agent_template_backend/docs/rag_samples \
|
||||
--namespace default
|
||||
```
|
||||
|
||||
For production-like semantic embeddings with OCI Generative AI, use:
|
||||
|
||||
```env
|
||||
VECTOR_STORE_PROVIDER=autonomous
|
||||
EMBEDDING_PROVIDER=oci
|
||||
OCI_COMPARTMENT_ID=ocid1.compartment.oc1..xxxx
|
||||
OCI_REGION=us-chicago-1
|
||||
OCI_EMBEDDING_MODEL=cohere.embed-multilingual-v3.0
|
||||
```
|
||||
|
||||
### Suggested retrieval test questions
|
||||
|
||||
- What is a prorated charge?
|
||||
- When can the OrdersAgent open an exchange request?
|
||||
- Which SKU represents the AI Agents book?
|
||||
- What is the target response for a critical support ticket?
|
||||
- How does BusinessContext map customer_key to MCP tool parameters?
|
||||
|
||||
### BusinessContext v2
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_TEMPLATE_BUSINESS_CONTEXT_V2.md`.
|
||||
|
||||
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.
|
||||
|
||||
### Integração operacional de RAG e cache
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md`.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `docs/RAG_PROVIDER_KBDB.md`
|
||||
- `docs/README_rag_samples.md`
|
||||
- `Documentacao/README_TEMPLATE_BUSINESS_CONTEXT_V2.md`
|
||||
- `Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
636
docs/developer/pt/08_long_term_memory_and_checkpoint.md
Normal file
636
docs/developer/pt/08_long_term_memory_and_checkpoint.md
Normal file
@@ -0,0 +1,636 @@
|
||||
|
||||
### Long-Term Memory e Checkpoint
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **LTM, memória de conversa, isolamento por identidade e persistência de estado**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Ltm, memória de conversa, isolamento por identidade e persistência de estado.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Long-Term Memory e Checkpoint Enterprise
|
||||
|
||||
Manual de implementação de memória durável, isolamento por identidade, stores, extração, integração LangGraph, testes de persistência e diferenças entre LTM, histórico, sumário e checkpoint.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Implementação completa de Long-Term Memory
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/Manual_Long_Term_Memory_PT.md`.
|
||||
|
||||
### Conceito
|
||||
|
||||
A Long-Term Memory (LTM) é a capacidade do `agent_framework` de armazenar e recuperar fatos duradouros além da duração de uma sessão de conversa.
|
||||
|
||||
Diferentemente do histórico de mensagens, que normalmente está associado a um `session_id`, a memória de longo prazo é associada à identidade de negócio do usuário ou cliente. Na implementação atual, essa identidade é composta por:
|
||||
|
||||
```text
|
||||
tenant_id
|
||||
agent_id
|
||||
customer_key
|
||||
```
|
||||
|
||||
Isso permite que um agente recupere preferências, informações de identidade, projetos e restrições mesmo quando uma nova sessão é criada.
|
||||
|
||||
### Para que serve
|
||||
|
||||
A Long-Term Memory serve para:
|
||||
|
||||
- manter continuidade entre sessões;
|
||||
- personalizar respostas;
|
||||
- evitar que o usuário repita informações já fornecidas;
|
||||
- reduzir a necessidade de enviar todo o histórico ao modelo;
|
||||
- armazenar preferências, projetos atuais, nomes preferidos e restrições;
|
||||
- isolar a memória entre tenants, agentes e clientes.
|
||||
|
||||
Exemplo:
|
||||
|
||||
```text
|
||||
Sessão A:
|
||||
"Me chame de Cris. Minha linguagem preferida é Python."
|
||||
|
||||
Sessão B, com outro session_id e o mesmo customer_key:
|
||||
"O que você lembra sobre mim?"
|
||||
|
||||
Resposta esperada:
|
||||
"Seu nome preferido é Cris e sua linguagem preferida é Python."
|
||||
```
|
||||
|
||||
### Diferença entre os tipos de memória
|
||||
|
||||
### Conversation Memory
|
||||
|
||||
Mantém as mensagens da conversa atual e normalmente está associada ao `session_id`.
|
||||
|
||||
### Summary Memory
|
||||
|
||||
Mantém um resumo da conversa para reduzir o tamanho do contexto enviado ao modelo.
|
||||
|
||||
### Long-Term Memory
|
||||
|
||||
Mantém fatos duradouros entre sessões e é associada à identidade de negócio, principalmente ao `customer_key`.
|
||||
|
||||
### Componentes da funcionalidade
|
||||
|
||||
### LongTermMemoryManager
|
||||
|
||||
Responsável por coordenar:
|
||||
|
||||
- carregamento das memórias;
|
||||
- recuperação por identidade;
|
||||
- renderização do contexto;
|
||||
- extração de novos fatos;
|
||||
- persistência dos fatos;
|
||||
- deduplicação e atualização.
|
||||
|
||||
### LongTermMemoryStore
|
||||
|
||||
Interface de persistência utilizada pelo manager.
|
||||
|
||||
### SQLiteLongTermMemoryStore
|
||||
|
||||
Implementação de referência baseada em SQLite.
|
||||
|
||||
É apropriada para:
|
||||
|
||||
- desenvolvimento local;
|
||||
- testes;
|
||||
- demonstrações;
|
||||
- ambientes de baixa escala.
|
||||
|
||||
### InMemoryLongTermMemoryStore
|
||||
|
||||
Implementação em memória utilizada para testes rápidos.
|
||||
|
||||
O conteúdo é perdido quando o processo do backend é encerrado.
|
||||
|
||||
### LongTermMemoryExtractor
|
||||
|
||||
Responsável por identificar fatos duradouros nas mensagens.
|
||||
|
||||
Exemplos de fatos:
|
||||
|
||||
```text
|
||||
preferred_name = Cris
|
||||
preferred_language = Python
|
||||
current_project = Atlas
|
||||
```
|
||||
|
||||
### LongTermMemoryItem
|
||||
|
||||
Modelo que representa um item persistido, incluindo identidade, chave, valor, categoria, confiança e metadados.
|
||||
|
||||
### AgentRuntime
|
||||
|
||||
Carrega a memória antes da execução do agente e injeta o contexto no prompt.
|
||||
|
||||
### Nó persist_long_term_memory
|
||||
|
||||
Nó do LangGraph responsável por persistir os fatos após a geração e validação da resposta final.
|
||||
|
||||
### Estrutura dos arquivos
|
||||
|
||||
```text
|
||||
libs/
|
||||
└── agent_framework/
|
||||
└── src/
|
||||
└── agent_framework/
|
||||
└── memory/
|
||||
├── __init__.py
|
||||
├── long_term_extractor.py
|
||||
├── long_term_memory.py
|
||||
├── long_term_models.py
|
||||
└── long_term_store.py
|
||||
```
|
||||
|
||||
### Fluxo de execução
|
||||
|
||||
```text
|
||||
Mensagem do usuário
|
||||
│
|
||||
▼
|
||||
AgentRuntime.prepare_memory_context()
|
||||
│
|
||||
├── Conversation Memory
|
||||
├── Summary Memory
|
||||
└── Long-Term Memory
|
||||
│
|
||||
▼
|
||||
long_term_memory_context
|
||||
│
|
||||
▼
|
||||
Prompt do agente
|
||||
│
|
||||
▼
|
||||
Agente
|
||||
│
|
||||
▼
|
||||
Guardrails / Judges / Supervisor
|
||||
│
|
||||
▼
|
||||
persist_long_term_memory
|
||||
│
|
||||
▼
|
||||
LongTermMemoryExtractor
|
||||
│
|
||||
▼
|
||||
LongTermMemoryStore
|
||||
```
|
||||
|
||||
### Configuração do framework
|
||||
|
||||
### Novos módulos
|
||||
|
||||
Copie os arquivos:
|
||||
|
||||
```text
|
||||
libs/agent_framework/src/agent_framework/memory/long_term_extractor.py
|
||||
libs/agent_framework/src/agent_framework/memory/long_term_memory.py
|
||||
libs/agent_framework/src/agent_framework/memory/long_term_models.py
|
||||
libs/agent_framework/src/agent_framework/memory/long_term_store.py
|
||||
```
|
||||
|
||||
### Atualização de memory/__init__.py
|
||||
|
||||
Exporte os componentes da Long-Term Memory:
|
||||
|
||||
```python
|
||||
from agent_framework.memory.long_term_memory import (
|
||||
LongTermMemoryManager,
|
||||
create_long_term_memory_manager,
|
||||
)
|
||||
from agent_framework.memory.long_term_models import LongTermMemoryItem
|
||||
from agent_framework.memory.long_term_store import (
|
||||
InMemoryLongTermMemoryStore,
|
||||
LongTermMemoryStore,
|
||||
SQLiteLongTermMemoryStore,
|
||||
create_long_term_memory_store,
|
||||
)
|
||||
```
|
||||
|
||||
### Atualização de settings.py
|
||||
|
||||
Adicione as configurações:
|
||||
|
||||
```python
|
||||
ENABLE_LONG_TERM_MEMORY: bool = False
|
||||
LONG_TERM_MEMORY_PROVIDER: str = "sqlite"
|
||||
LONG_TERM_MEMORY_SQLITE_PATH: str = "./data/agent_framework.db"
|
||||
LONG_TERM_MEMORY_TABLE: str = "agentfw_long_term_memory"
|
||||
LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS: int = 20
|
||||
LONG_TERM_MEMORY_MIN_CONFIDENCE: float = 0.70
|
||||
LONG_TERM_MEMORY_AUTO_EXTRACT: bool = True
|
||||
LONG_TERM_MEMORY_INJECT_CONTEXT: bool = True
|
||||
```
|
||||
|
||||
### Integração com AgentRuntime
|
||||
|
||||
O runtime deve:
|
||||
|
||||
1. verificar se a funcionalidade está habilitada;
|
||||
2. criar o manager quando necessário;
|
||||
3. recuperar os fatos pela identidade;
|
||||
4. preencher o estado;
|
||||
5. injetar o contexto no prompt.
|
||||
|
||||
Campos adicionados ao estado:
|
||||
|
||||
```python
|
||||
long_term_memories: list[dict]
|
||||
long_term_memory_context: str
|
||||
long_term_memory_write_result: dict
|
||||
```
|
||||
|
||||
### Inicialização no AgentWorkflow
|
||||
|
||||
O manager deve ser criado no `AgentWorkflow`:
|
||||
|
||||
```python
|
||||
self.long_term_memory_manager = create_long_term_memory_manager(
|
||||
settings,
|
||||
telemetry=telemetry,
|
||||
)
|
||||
```
|
||||
|
||||
### Inicialização correta dos agentes
|
||||
|
||||
O `long_term_memory_manager` não deve ser passado pelo `agent_kwargs` caso os construtores de `BillingAgent`, `ProductAgent`, `OrdersAgent` e `SupportAgent` não declarem esse parâmetro.
|
||||
|
||||
Esta inicialização causa erro:
|
||||
|
||||
```python
|
||||
agent_kwargs = {
|
||||
"telemetry": telemetry,
|
||||
"settings": settings,
|
||||
"memory": memory,
|
||||
"summary_memory": summary_memory,
|
||||
"long_term_memory_manager": self.long_term_memory_manager,
|
||||
}
|
||||
|
||||
self.billing = BillingAgent(llm, **agent_kwargs)
|
||||
```
|
||||
|
||||
Erro resultante:
|
||||
|
||||
```text
|
||||
TypeError: BillingAgent.__init__() got an unexpected keyword argument
|
||||
'long_term_memory_manager'
|
||||
```
|
||||
|
||||
A forma recomendada é criar os agentes com a assinatura já existente e injetar o manager como atributo após a inicialização:
|
||||
|
||||
```python
|
||||
agent_kwargs = {
|
||||
"telemetry": telemetry,
|
||||
"tool_router": getattr(self, "tool_router", None),
|
||||
"rag_service": self.rag_service,
|
||||
"cache": self.cache,
|
||||
"settings": settings,
|
||||
"observer": self.observer,
|
||||
"memory": memory,
|
||||
"summary_memory": summary_memory,
|
||||
}
|
||||
|
||||
self.billing = BillingAgent(llm, **agent_kwargs)
|
||||
self.product = ProductAgent(llm, **agent_kwargs)
|
||||
self.orders = OrdersAgent(llm, **agent_kwargs)
|
||||
self.support = SupportAgent(llm, **agent_kwargs)
|
||||
|
||||
for agent in (
|
||||
self.billing,
|
||||
self.product,
|
||||
self.orders,
|
||||
self.support,
|
||||
):
|
||||
agent.long_term_memory_manager = self.long_term_memory_manager
|
||||
```
|
||||
|
||||
Essa abordagem evita alterar os construtores de todos os agentes e mantém a funcionalidade encapsulada no framework.
|
||||
|
||||
### Configuração do LangGraph
|
||||
|
||||
Registre o nó:
|
||||
|
||||
```python
|
||||
builder.add_node(
|
||||
"persist_long_term_memory",
|
||||
self._node(
|
||||
"persist_long_term_memory",
|
||||
self.persist_long_term_memory,
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
Altere o fluxo:
|
||||
|
||||
```python
|
||||
builder.add_edge(
|
||||
"supervisor_review",
|
||||
"persist_long_term_memory",
|
||||
)
|
||||
builder.add_edge(
|
||||
"persist_long_term_memory",
|
||||
"persist",
|
||||
)
|
||||
```
|
||||
|
||||
Implemente o método:
|
||||
|
||||
```python
|
||||
async def persist_long_term_memory(
|
||||
self,
|
||||
state: AgentState,
|
||||
) -> dict[str, object]:
|
||||
result = await self.long_term_memory_manager.persist_turn(state)
|
||||
|
||||
return {
|
||||
"long_term_memory_write_result": result,
|
||||
}
|
||||
```
|
||||
|
||||
Fluxo final:
|
||||
|
||||
```text
|
||||
supervisor_review
|
||||
│
|
||||
▼
|
||||
persist_long_term_memory
|
||||
│
|
||||
▼
|
||||
persist
|
||||
```
|
||||
|
||||
### Variáveis de ambiente
|
||||
|
||||
```env
|
||||
ENABLE_LONG_TERM_MEMORY=true
|
||||
|
||||
LONG_TERM_MEMORY_PROVIDER=sqlite
|
||||
LONG_TERM_MEMORY_SQLITE_PATH=./data/agent_framework.db
|
||||
LONG_TERM_MEMORY_TABLE=agentfw_long_term_memory
|
||||
|
||||
LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20
|
||||
LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70
|
||||
LONG_TERM_MEMORY_AUTO_EXTRACT=true
|
||||
LONG_TERM_MEMORY_INJECT_CONTEXT=true
|
||||
```
|
||||
|
||||
### Caminho do banco SQLite
|
||||
|
||||
O caminho relativo é resolvido a partir do diretório em que o backend é iniciado.
|
||||
|
||||
Para evitar que bancos diferentes sejam criados acidentalmente, prefira um caminho absoluto em ambientes de desenvolvimento:
|
||||
|
||||
```env
|
||||
LONG_TERM_MEMORY_SQLITE_PATH=/mnt/c/Asus_Projects/agent_platform_oci_long_term_memory/data/agent_framework.db
|
||||
```
|
||||
|
||||
Crie a pasta antes de iniciar:
|
||||
|
||||
```bash
|
||||
mkdir -p data
|
||||
```
|
||||
|
||||
### Como testar
|
||||
|
||||
### Teste 1 — Gravação
|
||||
|
||||
Envie:
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "default:telecom_contas:memory-session-a",
|
||||
"customer_key": "11999999999",
|
||||
"message": "Me chame de Cris. Minha linguagem preferida é Python e meu projeto atual se chama Atlas."
|
||||
}
|
||||
```
|
||||
|
||||
### Teste 2 — Recuperação em outra sessão
|
||||
|
||||
Utilize outro `session_id`, mantendo o mesmo `customer_key`:
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "default:telecom_contas:memory-session-b",
|
||||
"customer_key": "11999999999",
|
||||
"message": "O que você lembra sobre mim, minhas preferências e meu projeto?"
|
||||
}
|
||||
```
|
||||
|
||||
Resultado esperado:
|
||||
|
||||
```text
|
||||
Seu nome preferido é Cris.
|
||||
Sua linguagem preferida é Python.
|
||||
Seu projeto atual se chama Atlas.
|
||||
```
|
||||
|
||||
### Teste 3 — Isolamento
|
||||
|
||||
Utilize outro cliente:
|
||||
|
||||
```json
|
||||
{
|
||||
"session_id": "default:telecom_contas:memory-session-c",
|
||||
"customer_key": "outro-cliente",
|
||||
"message": "Qual é meu nome preferido e qual é meu projeto atual?"
|
||||
}
|
||||
```
|
||||
|
||||
Os dados de `11999999999` não devem aparecer.
|
||||
|
||||
### Teste 4 — Reinicialização do frontend
|
||||
|
||||
Reinicie ou resete o frontend e confirme que ele continua enviando o mesmo `customer_key`.
|
||||
|
||||
A memória deve sobreviver à troca do `session_id`. O reset do frontend não apaga o SQLite.
|
||||
|
||||
### Teste 5 — Reinicialização do backend
|
||||
|
||||
Reinicie o Uvicorn e repita a consulta.
|
||||
|
||||
Com:
|
||||
|
||||
```env
|
||||
LONG_TERM_MEMORY_PROVIDER=sqlite
|
||||
```
|
||||
|
||||
a memória deve continuar disponível.
|
||||
|
||||
Com:
|
||||
|
||||
```env
|
||||
LONG_TERM_MEMORY_PROVIDER=memory
|
||||
```
|
||||
|
||||
a memória será perdida quando o processo for encerrado.
|
||||
|
||||
### Verificação direta no SQLite
|
||||
|
||||
Localize o banco:
|
||||
|
||||
```bash
|
||||
find . -name "agent_framework.db" -type f
|
||||
```
|
||||
|
||||
Abra:
|
||||
|
||||
```bash
|
||||
sqlite3 ./data/agent_framework.db
|
||||
```
|
||||
|
||||
Consulte:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
tenant_id,
|
||||
agent_id,
|
||||
customer_key,
|
||||
memory_type,
|
||||
memory_key,
|
||||
memory_value,
|
||||
confidence,
|
||||
created_at,
|
||||
updated_at
|
||||
FROM agentfw_long_term_memory
|
||||
ORDER BY updated_at DESC;
|
||||
```
|
||||
|
||||
### Critérios de sucesso
|
||||
|
||||
A implementação está funcionando quando:
|
||||
|
||||
- a memória é recuperada com outro `session_id`;
|
||||
- o mesmo `customer_key` recupera os fatos anteriores;
|
||||
- outro `customer_key` não acessa esses fatos;
|
||||
- reiniciar o frontend não apaga a memória;
|
||||
- reiniciar o backend não apaga a memória quando o provider é SQLite;
|
||||
- o nó `persist_long_term_memory` é executado;
|
||||
- o prompt recebe `long_term_memory_context`.
|
||||
|
||||
### Boas práticas
|
||||
|
||||
- Persistir somente fatos duradouros.
|
||||
- Não armazenar a conversa completa como Long-Term Memory.
|
||||
- Isolar dados por `tenant_id`, `agent_id` e `customer_key`.
|
||||
- Não utilizar `session_id` como identidade permanente do usuário.
|
||||
- Persistir somente depois das validações finais.
|
||||
- Evitar armazenar resultados temporários de ferramentas.
|
||||
- Registrar telemetria de leitura, escrita, atualização e falha.
|
||||
- Definir políticas de retenção e exclusão.
|
||||
- Usar caminho absoluto para SQLite em ambientes com múltiplos diretórios de execução.
|
||||
- Migrar para um banco corporativo em ambientes de produção e alta disponibilidade.
|
||||
|
||||
### Limitações da implementação de referência
|
||||
|
||||
A implementação atual utiliza extração baseada em regras e SQLite como provider de referência.
|
||||
|
||||
Evoluções recomendadas:
|
||||
|
||||
- extração de fatos com LLM;
|
||||
- memória semântica com vetores;
|
||||
- memória episódica;
|
||||
- expiração e versionamento;
|
||||
- deduplicação semântica;
|
||||
- política de consentimento;
|
||||
- API de consulta e exclusão;
|
||||
- provider Oracle Autonomous Database;
|
||||
- criptografia e classificação de dados sensíveis.
|
||||
|
||||
### Checkpoint Enterprise no LangGraph
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_CHECKPOINT_ENTERPRISE.md`.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `Documentacao/Manual_Long_Term_Memory_PT.md`
|
||||
- `Documentacao/README_CHECKPOINT_ENTERPRISE.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
118
docs/developer/pt/09_llm_rich_response_reasoning.md
Normal file
118
docs/developer/pt/09_llm_rich_response_reasoning.md
Normal file
@@ -0,0 +1,118 @@
|
||||
|
||||
### LLM Rich Response e reasoning_content
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **`ainvoke_response()`, metadados de inferência e `reasoning_content` opcional**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
`ainvoke_response()`, metadados de inferência e `reasoning_content` opcional.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### LLM Rich Response e reasoning_content
|
||||
|
||||
Guia para usar a API opt-in de resposta estruturada do LLM sem quebrar o contrato legado de ainvoke(), incluindo reasoning_content, usage, model, provider, fallback e testes.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### API rica de resposta LLM
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/LLM_RICH_RESPONSE.md`.
|
||||
|
||||
### Objetivo
|
||||
|
||||
O framework mantém `ainvoke()` como API retrocompatível, retornando apenas `str`, e adiciona `ainvoke_response()` para consumidores que precisam de metadados adicionais da inferência, incluindo `reasoning_content` quando o modelo/provider/API o disponibilizar.
|
||||
|
||||
### APIs
|
||||
|
||||
### API legada — sem alteração
|
||||
|
||||
```python
|
||||
answer = await llm.ainvoke(messages)
|
||||
assert isinstance(answer, str)
|
||||
```
|
||||
|
||||
Nenhum agente existente precisa ser alterado.
|
||||
|
||||
### Nova API rica — opt-in
|
||||
|
||||
```python
|
||||
response = await llm.ainvoke_response(messages)
|
||||
|
||||
answer = response.content
|
||||
reasoning = response.reasoning_content
|
||||
usage = response.usage
|
||||
model = response.model
|
||||
provider = response.provider
|
||||
```
|
||||
|
||||
`reasoning_content` é `str | None`. `None` é o comportamento esperado quando o modelo, provider ou API não expõe reasoning textual.
|
||||
|
||||
### Backoffice
|
||||
|
||||
Um consumidor que antes fazia:
|
||||
|
||||
```python
|
||||
answer = await llm.ainvoke(messages)
|
||||
template = extract_response(answer)
|
||||
```
|
||||
|
||||
pode passar a fazer:
|
||||
|
||||
```python
|
||||
response = await llm.ainvoke_response(messages)
|
||||
template = extract_response(response.content)
|
||||
reasoning_content = response.reasoning_content
|
||||
```
|
||||
|
||||
A lógica que espera texto continua recebendo `response.content`; o reasoning fica separado e não contamina resposta, cache, memória, judges ou guardrails.
|
||||
|
||||
### Compatibilidade de providers customizados
|
||||
|
||||
`LLMProvider.ainvoke_response()` possui fallback. Um provider externo que implemente apenas `ainvoke()` continua funcionando e recebe automaticamente um `LLMResponse(content=<texto>)`, com `reasoning_content=None`.
|
||||
|
||||
Providers nativos (`mock`, OpenAI-compatible/OCI OpenAI e OCI SDK) implementam a resposta rica e tentam preservar reasoning quando presente.
|
||||
|
||||
### Garantias de compatibilidade
|
||||
|
||||
- `ainvoke()` continua retornando `str`.
|
||||
- Nenhum router, judge, RAG, memória, cache ou runtime existente foi migrado para a nova API.
|
||||
- `reasoning_content` nunca é fabricado pelo framework.
|
||||
- Ausência de reasoning não gera erro.
|
||||
- O output existente de telemetria continua sendo o conteúdo final, sem anexar reasoning automaticamente.
|
||||
|
||||
### Testes
|
||||
|
||||
Os testes específicos estão em `tests/unit/test_llm_rich_response.py` e verificam:
|
||||
|
||||
1. provider legado que só implementa `ainvoke()`;
|
||||
2. manutenção do retorno `str` em `ainvoke()`;
|
||||
3. retorno de `LLMResponse` em `ainvoke_response()`;
|
||||
4. reasoning via atributo direto;
|
||||
5. reasoning via `model_extra`;
|
||||
6. ausência de reasoning e extração no formato OCI SDK.
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `docs/LLM_RICH_RESPONSE.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
356
docs/developer/pt/10_performance_cache_and_async_runtime.md
Normal file
356
docs/developer/pt/10_performance_cache_and_async_runtime.md
Normal file
@@ -0,0 +1,356 @@
|
||||
|
||||
### Performance, Cache e Runtime Assíncrono
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **concorrência, cache, redução de chamadas LLM e correções cross-loop**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Concorrência, cache, redução de chamadas llm e correções cross-loop.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Performance, Cache, Concorrência e Runtime Assíncrono
|
||||
|
||||
Manual das otimizações no caminho crítico de MCP, RAG e Judges, redução de chamadas LLM, preempção determinística e correção de deadlock cross-loop no sequenciamento.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Otimizações MCP, RAG e Judges
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/PERFORMANCE_OPTIMIZATIONS_MCP_JUDGES_RAG.md`.
|
||||
|
||||
- `mcp_tools` permanece allowlist; somente a consulta selecionada por `selection_keywords` é executada.
|
||||
- Extração `strategy: hybrid` tenta `pattern` regex antes do perfil LLM.
|
||||
- RAG é ignorado quando MCP bem-sucedido é suficiente, salvo perguntas de política/regra.
|
||||
- `mcp_results` é fornecido como evidência ao groundedness judge.
|
||||
- `judges.yaml` aceita `sample_rate` e `always_run_for_transactional`.
|
||||
- Consultas estruturadas simples podem retornar resposta determinística sem LLM do agente.
|
||||
|
||||
### Mudança de consulta para ação transacional
|
||||
|
||||
A route stickiness é preemptada quando uma keyword explícita configurada em `routing.yaml` identifica outra intent/agente. Assim, uma sessão em `retail_order_tracking` muda para `retail_support_exchange_return` ao receber pedidos como “devolver pedido”. Além disso, respostas diretas de tools read-only são bloqueadas quando a mensagem contém `selection_keywords` de qualquer tool transacional registrada.
|
||||
|
||||
As palavras de ação ficam em `config/tools.yaml`; o runtime não mantém aliases de domínio hardcoded.
|
||||
|
||||
|
||||
### Preempção determinística de mudança explícita de intent
|
||||
|
||||
A stickiness não chama um segundo LLM quando a mensagem contém uma mudança explícita que pode ser reconhecida deterministicamente. Keywords multi-token configuradas em `routing.yaml` aceitam até três tokens intermediários, preservando a ordem. Assim, `cancelar pedido` reconhece `quero cancelar meu pedido`, `cancelar o meu pedido` e `pode cancelar esse pedido`. Nesse caso a nova intent preempta a stickiness e o metadado `keyword_match_strategy=ordered_tokens` permite auditar a decisão. Mensagens sem sinal explícito continuam usando a route stickiness normalmente.
|
||||
|
||||
### Correção de deadlock cross-loop
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/FIX_DEADLOCK_SEQUENCE_CROSS_LOOP.md`.
|
||||
|
||||
### Problema
|
||||
|
||||
A API síncrona `agent_framework.observer.event()` podia ser chamada em uma worker thread sem event loop ativo. Nesse caso, a implementação anterior executava `asyncio.run(aevent(...))`, criando um novo event loop temporário. Ao mesmo tempo, `analytics/tim_sequence.py` compartilhava instâncias globais de `asyncio.Lock` (`_mongo_index_lock` e `_memory_lock`) entre chamadas que podiam vir de event loops diferentes.
|
||||
|
||||
Na primeira operação Mongo, `_ensure_mongo_ttl_index_once()` mantinha `_mongo_index_lock` durante a criação do índice TTL. A contenção por outro loop podia deixar a segunda chamada aguardando indefinidamente.
|
||||
|
||||
### Alterações aplicadas
|
||||
|
||||
1. `observer.py`
|
||||
- removido `asyncio.run()` do caminho síncrono de `event()`;
|
||||
- adicionado um event loop dedicado e reutilizável para chamadas síncronas;
|
||||
- submissão cross-thread feita com `asyncio.run_coroutine_threadsafe()`;
|
||||
- encerramento best-effort do loop no shutdown do processo.
|
||||
|
||||
2. `analytics/tim_sequence.py`
|
||||
- `_mongo_index_lock`: `asyncio.Lock` -> `threading.Lock`;
|
||||
- `_memory_lock`: `asyncio.Lock` -> `threading.Lock`;
|
||||
- inicialização do índice TTL movida para uma função síncrona protegida por lock de thread e chamada via `asyncio.to_thread()`;
|
||||
- o contador de fallback em memória usa uma seção crítica curta e thread-safe.
|
||||
|
||||
3. Testes
|
||||
- `tests/test_observer_cross_loop_deadlock_fix.py` valida:
|
||||
- múltiplas worker threads usando `event()` compartilham o mesmo loop síncrono do observer;
|
||||
- sequence em memória permanece monotônica entre event loops independentes;
|
||||
- criação do índice TTL ocorre apenas uma vez sob contenção cross-loop.
|
||||
|
||||
### Validação executada
|
||||
|
||||
```bash
|
||||
PYTHONPATH=libs/agent_framework/src pytest -q tests/test_observer_cross_loop_deadlock_fix.py
|
||||
```
|
||||
|
||||
Resultado: `3 passed`.
|
||||
|
||||
A suíte completa do repositório possui falhas preexistentes/independentes desta alteração, incluindo conflitos de coleta de arquivos `test_long_term_memory.py`, caminhos estáticos de template e testes de checkpoint/workflow. Esses itens não foram alterados por esta correção.
|
||||
|
||||
### Recursos operacionais de performance
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_MAX_OPERACIONAL.md`.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Ajustes finais de cache, RAG e telemetria
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md`.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `docs/PERFORMANCE_OPTIMIZATIONS_MCP_JUDGES_RAG.md`
|
||||
- `Documentacao/FIX_DEADLOCK_SEQUENCE_CROSS_LOOP.md`
|
||||
- `Documentacao/README_MAX_OPERACIONAL.md`
|
||||
- `Documentacao/README_FIRST_MAX_OPERATIONAL_FIXES.md`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
@@ -0,0 +1,685 @@
|
||||
|
||||
### Observabilidade, Persistência e Prontidão Operacional
|
||||
|
||||
### Como usar este manual
|
||||
|
||||
Este é um **manual de referência especializado**. Ele não substitui o tutorial principal.
|
||||
|
||||
- Para criar um agente do início ao fim, use [`README.md`](../../../README.md).
|
||||
- Use este documento quando precisar implementar, aprofundar ou diagnosticar **telemetria, IC/NOC/GRL, correlação, sequência, persistência e diagnóstico operacional**.
|
||||
- Os exemplos históricos consolidados aqui devem ser lidos à luz da API atual do framework.
|
||||
- Em caso de divergência, o código da versão e o `README.md` atual prevalecem.
|
||||
|
||||
### Relação com o tutorial principal
|
||||
|
||||
O `README.md` apresenta essa capacidade no fluxo normal de desenvolvimento. Este manual reúne detalhes que estavam distribuídos em `docs/`, `Documentacao/`, release notes, validações e guias especializados.
|
||||
|
||||
O objetivo aqui é responder **“como essa feature funciona em profundidade e como eu resolvo problemas nela?”**, sem transformar este arquivo em uma segunda cópia do tutorial principal.
|
||||
|
||||
### Escopo
|
||||
|
||||
Telemetria, ic/noc/grl, correlação, sequência, persistência e diagnóstico operacional.
|
||||
|
||||
### Conteúdo técnico consolidado
|
||||
|
||||
### Observabilidade, Persistência e Prontidão Operacional
|
||||
|
||||
Guia consolidado das capacidades FIRST-ready: correlação ponta-a-ponta, Langfuse, OpenTelemetry, SSE observável, persistência Oracle, token/cost accounting, cache e telemetria LangGraph.
|
||||
|
||||
### Como usar este documento
|
||||
|
||||
Este é o documento consolidado de desenvolvimento para este assunto. Ele reúne arquitetura, configuração, exemplos, comportamento de runtime, compatibilidade, testes e troubleshooting que antes estavam distribuídos em vários arquivos. As seções de origem foram preservadas quando traziam detalhes técnicos distintos; notas de release foram incorporadas como comportamento atual ou histórico de correção.
|
||||
|
||||
### Base FIRST-ready e observabilidade
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_FIRST_READY.md`.
|
||||
|
||||
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.
|
||||
|
||||
### Extensões Enterprise Plus
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_FIRST_ENTERPRISE_PLUS.md`.
|
||||
|
||||
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.
|
||||
|
||||
### Delta para padrão FIRST
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_FIRST_ENTERPRISE_DELTA.md`.
|
||||
|
||||
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.
|
||||
|
||||
### Operação máxima e contabilização
|
||||
|
||||
> Conteúdo consolidado a partir de `Documentacao/README_MAX_OPERACIONAL.md`.
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### Validação complementar do supervisor
|
||||
|
||||
> Conteúdo consolidado a partir de `docs/docs_GLOBAL_SUPERVISOR_VALIDATION.txt`.
|
||||
|
||||
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.
|
||||
|
||||
### Arquivos de origem
|
||||
|
||||
Os arquivos abaixo foram consolidados neste manual:
|
||||
|
||||
- `Documentacao/README_FIRST_READY.md`
|
||||
- `Documentacao/README_FIRST_ENTERPRISE_PLUS.md`
|
||||
- `Documentacao/README_FIRST_ENTERPRISE_DELTA.md`
|
||||
- `Documentacao/README_MAX_OPERACIONAL.md`
|
||||
- `docs/docs_GLOBAL_SUPERVISOR_VALIDATION.txt`
|
||||
|
||||
### Regra de manutenção
|
||||
|
||||
Novas correções ou evoluções deste tema devem atualizar este documento consolidado. Release notes podem continuar existindo como histórico, mas não devem ser necessárias para compreender ou implementar a funcionalidade.
|
||||
134
docs/developer/pt/INDEX_DEVELOPER_GUIDE.md
Normal file
134
docs/developer/pt/INDEX_DEVELOPER_GUIDE.md
Normal file
@@ -0,0 +1,134 @@
|
||||
|
||||
### Índice de Desenvolvimento — Agent Framework OCI
|
||||
|
||||
### Como usar esta documentação
|
||||
|
||||
A documentação possui três níveis claros:
|
||||
|
||||
1. **Tutorial principal:** [`README.md`](../../../README.md) — criação, configuração, execução e teste de um agente do início ao fim.
|
||||
2. **Arquitetura:** [01 — Arquitetura e Conceitos](./01_architecture_and_concepts.md) — componentes, responsabilidades e onde implementar cada coisa.
|
||||
3. **Referências especializadas:** manuais `02` a `11` — implementação profunda e troubleshooting por capacidade.
|
||||
|
||||
Se você está começando um novo agente, comece pelo `README.md`.
|
||||
|
||||
Se algo não está funcionando, use **Buscar pelo problema** abaixo.
|
||||
|
||||
### Buscar pelo problema
|
||||
|
||||
| Problema / dúvida | O que normalmente está envolvido | Onde procurar |
|
||||
|---|---|---|
|
||||
| O framework não encontra o agente/intenção correta | routing, intents, threshold, modo determinístico/LLM | [Routing e Stickiness](./02_routing_stickiness_and_intent_shift.md) |
|
||||
| O agente fica preso no mesmo assunto e não troca de intent | route stickiness, intent shift, handoff | [Routing e Stickiness](./02_routing_stickiness_and_intent_shift.md) |
|
||||
| Uma resposta que deveria preencher parâmetro é interpretada como novo intent | precedência transacional, parameter extraction | [Workflows Transacionais](./03_transaction_workflows_and_state.md) |
|
||||
| A transação fica pedindo o mesmo parâmetro | estado transacional, extractor, schema | [Workflows Transacionais](./03_transaction_workflows_and_state.md) e [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| A confirmação “sim/não” não continua o fluxo | confirmation state, transaction state | [Workflows Transacionais](./03_transaction_workflows_and_state.md) |
|
||||
| Uma transação encerrada reaparece | checkpoint antigo versus estado transacional ativo | [Workflows Transacionais](./03_transaction_workflows_and_state.md) e [LTM/Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| O sistema diz que executou algo, mas não existe evidência | MCP result, estado `COMPLETED`, judges transacionais | [Workflows Transacionais](./03_transaction_workflows_and_state.md) e [Guardrails/Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| Uma tool não aparece ou não é encontrada | `tools.yaml`, catálogo MCP, discovery | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| MCP Server não aparece no catálogo | registration, manifest/discovery, MCP Gateway | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) e [Gateways](./05_agent_gateway_mcp_gateway_and_auth.md) |
|
||||
| Parâmetros enviados à tool estão errados | schema, mapping, BusinessContext, extractor | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| Uma operação transacional executa sem confirmação | tool policy, `require_confirmation` | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| Uma busca por nome exige correspondência exata demais | extração/mapeamento de parâmetros e lógica do agente | [MCP/Tools](./04_mcp_integration_tools_and_policies.md) |
|
||||
| Recebo 401 entre gateway/backend/MCP | Basic Auth, credenciais por hop | [Gateways e Auth](./05_agent_gateway_mcp_gateway_and_auth.md) |
|
||||
| Preciso decidir se algo pertence ao framework ou ao agente | boundary core/agente | [Arquitetura e Conceitos](./01_architecture_and_concepts.md) |
|
||||
| Guardrail específico de um agente está quebrando outro | extensibilidade, imports de domínio no core | [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| Judge não roda em uma transação | sampling, `always_run_for_transactional`, sinais transacionais | [Guardrails e Judges](./06_guardrails_judges_and_transaction_evaluation.md) |
|
||||
| Groundedness está avaliando sem contexto correto | RAG context, MCP evidence, judge inputs | [RAG/Grounding](./07_rag_business_context_and_grounding.md) |
|
||||
| RAG não encontra conteúdo | provider, ingestão, embeddings, configuração | [RAG/Grounding](./07_rag_business_context_and_grounding.md) |
|
||||
| Não sei se usar RAG, memória ou tool | separação de responsabilidades | [Arquitetura e Conceitos](./01_architecture_and_concepts.md) e [RAG/Grounding](./07_rag_business_context_and_grounding.md) |
|
||||
| Memória desaparece ao trocar de sessão | LTM versus conversation memory | [LTM e Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| Memória de um cliente/agente aparece em outro | identity key, tenant/agent/customer isolation | [LTM e Checkpoint](./08_long_term_memory_and_checkpoint.md) |
|
||||
| Preciso recuperar `reasoning_content` | `ainvoke_response()` | [LLM Rich Response](./09_llm_rich_response_reasoning.md) |
|
||||
| `reasoning_content` vem `None` | provider/model não expõe o campo | [LLM Rich Response](./09_llm_rich_response_reasoning.md) |
|
||||
| Há chamadas LLM desnecessárias | routing determinístico, concorrência, cache | [Performance](./10_performance_cache_and_async_runtime.md) |
|
||||
| Há deadlock ou espera entre event loops | cross-loop sequence/runtime | [Performance](./10_performance_cache_and_async_runtime.md) |
|
||||
| Logs/traces não correlacionam o mesmo agente | labels, IDs e mapeamento de observabilidade | [Observabilidade](./11_observability_persistence_and_operational_readiness.md) |
|
||||
| Sequence está interferindo no processamento | implementação assíncrona de sequência | [Observabilidade](./11_observability_persistence_and_operational_readiness.md) e [Performance](./10_performance_cache_and_async_runtime.md) |
|
||||
| Um exemplo antigo não compila | documentação histórica versus API atual | [Validação README x Código](./VALIDATION_README_ALIGNMENT.md) |
|
||||
| Preciso criar um agente novo do zero | fluxo completo | [`README.md`](../../../README.md) |
|
||||
| Preciso saber onde colocar uma nova feature | arquitetura e boundaries | [Arquitetura e Conceitos](./01_architecture_and_concepts.md) |
|
||||
|
||||
### Buscar pela funcionalidade
|
||||
|
||||
### [01 — Arquitetura e Conceitos](./01_architecture_and_concepts.md)
|
||||
|
||||
**O que é:** visão dos componentes, contratos e limites de responsabilidade.
|
||||
|
||||
**Use quando:** precisar entender a plataforma, decidir onde implementar algo ou evitar acoplamento entre core e agente.
|
||||
|
||||
### [02 — Routing, Route Stickiness e Intent Shift](./02_routing_stickiness_and_intent_shift.md)
|
||||
|
||||
**O que é:** referência completa de descoberta de agente/intent, stickiness, handoff e mudança de intenção.
|
||||
|
||||
**Use quando:** a mensagem cai no agente errado, não troca de intent ou perde continuidade.
|
||||
|
||||
### [03 — Workflows Transacionais e Estado](./03_transaction_workflows_and_state.md)
|
||||
|
||||
**O que é:** ciclo transacional multi-turno, estados, confirmação, pausa/retomada e evidência operacional.
|
||||
|
||||
**Use quando:** há loops, confirmações incorretas, retomadas erradas ou operações críticas.
|
||||
|
||||
### [04 — MCP, Tools, Policies e Extração de Parâmetros](./04_mcp_integration_tools_and_policies.md)
|
||||
|
||||
**O que é:** referência de tools, MCP Servers, mappings, policies e parameter extraction.
|
||||
|
||||
**Use quando:** integração/execução de tool está incorreta ou precisa ser criada.
|
||||
|
||||
### [05 — Agent Gateway, MCP Gateway e Autenticação](./05_agent_gateway_mcp_gateway_and_auth.md)
|
||||
|
||||
**O que é:** responsabilidades dos gateways, governança e autenticação entre componentes.
|
||||
|
||||
**Use quando:** houver problema de entrada, catálogo, autorização, 401 ou deployment dos gateways.
|
||||
|
||||
### [06 — Guardrails, Judges e Avaliação Transacional](./06_guardrails_judges_and_transaction_evaluation.md)
|
||||
|
||||
**O que é:** validações nativas/externas, judges, grounding e regras para turnos transacionais.
|
||||
|
||||
**Use quando:** uma validação bloqueia, não roda ou produz avaliação incorreta.
|
||||
|
||||
### [07 — RAG, BusinessContext e Grounding](./07_rag_business_context_and_grounding.md)
|
||||
|
||||
**O que é:** providers de RAG, contexto recuperado, BusinessContext e grounding.
|
||||
|
||||
**Use quando:** conhecimento recuperado não chega corretamente ao agente/judge.
|
||||
|
||||
### [08 — Long-Term Memory e Checkpoint](./08_long_term_memory_and_checkpoint.md)
|
||||
|
||||
**O que é:** memória durável, memória conversacional, identidade e snapshots de estado.
|
||||
|
||||
**Use quando:** contexto some, vaza ou workflow retoma do lugar errado.
|
||||
|
||||
### [09 — LLM Rich Response e reasoning_content](./09_llm_rich_response_reasoning.md)
|
||||
|
||||
**O que é:** resposta estruturada de inferência além do `str` retornado por `ainvoke()`.
|
||||
|
||||
**Use quando:** consumidores precisam de metadados, usage ou reasoning disponibilizado pelo provider.
|
||||
|
||||
### [10 — Performance, Cache e Runtime Assíncrono](./10_performance_cache_and_async_runtime.md)
|
||||
|
||||
**O que é:** otimizações de concorrência, cache, LLM e event loops.
|
||||
|
||||
**Use quando:** houver latência evitável, processamento serial ou deadlock.
|
||||
|
||||
### [11 — Observabilidade, Persistência e Prontidão Operacional](./11_observability_persistence_and_operational_readiness.md)
|
||||
|
||||
**O que é:** correlação, eventos, labels, sequence, persistência e diagnóstico.
|
||||
|
||||
**Use quando:** for necessário provar o caminho executado ou diagnosticar produção.
|
||||
|
||||
### Tutorial principal
|
||||
|
||||
[`README.md`](../../../README.md) continua sendo a referência para o passo a passo completo:
|
||||
|
||||
`arquitetura → configuração → criação do agente → registro → estado → routing → tools → MCP → identidade → execução → testes → gateways → memória → RAG`.
|
||||
|
||||
### Manutenção
|
||||
|
||||
Não crie outro tutorial paralelo ao `README.md`.
|
||||
|
||||
Ao evoluir uma feature:
|
||||
|
||||
- atualize o README somente se o fluxo normal de desenvolvimento mudou;
|
||||
- atualize o manual especializado com comportamento, configuração, exemplos e troubleshooting;
|
||||
- atualize SPECs se o contrato mudou;
|
||||
- mantenha release notes como histórico, não como única documentação atual.
|
||||
84
docs/developer/pt/VALIDATION_README_ALIGNMENT.md
Normal file
84
docs/developer/pt/VALIDATION_README_ALIGNMENT.md
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
### Validação de Alinhamento da Documentação
|
||||
|
||||
### Objetivo
|
||||
|
||||
Registrar como a documentação desta versão foi reorganizada e quais fontes devem ser usadas pelo desenvolvedor.
|
||||
|
||||
### Decisão estrutural
|
||||
|
||||
O `README.md` da raiz é o **único tutorial principal ponta a ponta**.
|
||||
|
||||
O antigo `01_architecture_and_agent_development.md` foi removido porque repetia grande parte do README, mas não todo ele. Isso criava ambiguidade: dois documentos aparentavam ensinar a mesma coisa, porém um era parcial.
|
||||
|
||||
A nova estrutura substitui esse arquivo por `01_architecture_and_concepts.md`, que contém apenas arquitetura, conceitos, responsabilidades e critérios de extensão.
|
||||
|
||||
### Validação de `README_old2.md`
|
||||
|
||||
`Documentacao/README_old2.md` permanece útil como histórico, mas não é fonte principal para desenvolvimento.
|
||||
|
||||
Foram encontradas evoluções posteriores no README atual e no código, incluindo:
|
||||
|
||||
- SPECs/SDDs;
|
||||
- configuração mais completa de `llm_profiles.yaml`;
|
||||
- Channel Gateway e contratos canônicos;
|
||||
- `memory` e `summary_memory` no ciclo atual do agente;
|
||||
- `prepare_memory_context()` e `build_messages()`;
|
||||
- `RuntimeContext`;
|
||||
- `normalize_tools_by_intent()`;
|
||||
- `build_tool_arguments()`;
|
||||
- `execute_tools_for_intent()`;
|
||||
- helpers de estado transacional;
|
||||
- respostas MCP diretas;
|
||||
- evolução de gateways, RAG, memória e políticas.
|
||||
|
||||
### Correção aplicada ao README principal
|
||||
|
||||
Foi corrigido no pacote gerado o typo:
|
||||
|
||||
```python
|
||||
from app.agents.financeiro_agent import FinanceirotAgent
|
||||
```
|
||||
|
||||
para:
|
||||
|
||||
```python
|
||||
from app.agents.financeiro_agent import FinanceiroAgent
|
||||
```
|
||||
|
||||
A classe correta é confirmada pelo código e pelo restante da documentação.
|
||||
|
||||
### APIs confirmadas na implementação atual
|
||||
|
||||
```python
|
||||
AgentRuntimeMixin.get_runtime_context()
|
||||
AgentRuntimeMixin.normalize_tools_by_intent()
|
||||
AgentRuntimeMixin.build_tool_arguments()
|
||||
AgentRuntimeMixin.execute_tools_for_intent()
|
||||
AgentRuntimeMixin.prepare_memory_context()
|
||||
AgentRuntimeMixin.build_messages()
|
||||
AgentRuntimeMixin.transaction_state_patch()
|
||||
AgentRuntimeMixin.transaction_clarification_message()
|
||||
AgentRuntimeMixin.transaction_confirmation_message()
|
||||
AgentRuntimeMixin.build_direct_mcp_answer()
|
||||
```
|
||||
|
||||
### Ordem de confiança
|
||||
|
||||
1. código da versão;
|
||||
2. README principal da mesma versão;
|
||||
3. SPECs/SDDs;
|
||||
4. manuais especializados;
|
||||
5. release notes;
|
||||
6. documentos `README_old*`.
|
||||
|
||||
### Regra de manutenção futura
|
||||
|
||||
Uma evolução de feature deve atualizar:
|
||||
|
||||
1. o README principal, **somente se alterar o caminho normal de desenvolvimento**;
|
||||
2. o manual especializado da feature, com detalhes técnicos, comportamento, configuração e troubleshooting;
|
||||
3. a SPEC, quando houver mudança de contrato;
|
||||
4. release note, quando for necessário registrar a mudança histórica.
|
||||
|
||||
Não crie um novo “manual principal” para uma feature. Não mantenha correções funcionais permanentemente apenas em release notes.
|
||||
Reference in New Issue
Block a user