mirror of
https://github.com/hoshikawa2/agent_platform_oci.git
synced 2026-07-09 14:04:19 +00:00
First commit
This commit is contained in:
312
specs/SPEC-012-Canonical-Contracts.md
Normal file
312
specs/SPEC-012-Canonical-Contracts.md
Normal file
@@ -0,0 +1,312 @@
|
||||
# SPEC-012 — Canonical Contracts
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user