mirror of
https://github.com/hoshikawa2/compass_backoffice.git
synced 2026-07-09 13:54:20 +00:00
Compare commits
3 Commits
12aeec2c0c
...
0c184cb9f0
| Author | SHA1 | Date | |
|---|---|---|---|
| 0c184cb9f0 | |||
| 58efb44bc1 | |||
| 9af4e10a92 |
31
FRAMEWORK_NATIVE_CORRECTIONS.md
Normal file
31
FRAMEWORK_NATIVE_CORRECTIONS.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Correções framework-native aplicadas no Compass Backoffice
|
||||||
|
|
||||||
|
Este pacote foi corrigido para reduzir forks locais e usar o máximo possível do `agent_framework_oci`.
|
||||||
|
|
||||||
|
## Correções principais
|
||||||
|
|
||||||
|
1. `app/agents/runtime.py` deixou de manter um runtime próprio.
|
||||||
|
- Agora reexporta `AgentRuntimeMixin`, `RuntimeContext` e `MessageBuilder` diretamente de `agent_framework.runtime.agent_runtime`.
|
||||||
|
- Isso ativa o comportamento nativo do framework para MCP, cache MCP por `args_schema`, deduplicação intra-turno, RAG, memória, cache LLM e eventos IC/NOC/GRL.
|
||||||
|
|
||||||
|
2. `BackofficeWorkflowExecutor` passou a carregar judges pelo profile do agente.
|
||||||
|
- Antes: `JudgePipeline()` usava o caminho global por padrão.
|
||||||
|
- Agora: `JudgePipeline(settings=settings, config_path=self.agent_profile.get("judges_config_path"))`.
|
||||||
|
- Com isso o agente `backoffice_anatel` usa `config/agents/backoffice_anatel/judges.yaml`.
|
||||||
|
|
||||||
|
3. `config/guardrails.yaml` foi alinhado com `config/agents/backoffice_anatel/guardrails.yaml`.
|
||||||
|
- Evita que estágios do framework que leem o arquivo global executem uma política mais fraca.
|
||||||
|
- Guardrails ativos: `INPUT_SIZE`, `MSK`, `PINJ`, `TOX`, `DLEX_IN`, `RAGSEC`, `VLOOP`, `REVPREC`, `DLEX_OUT`, `OOS`, `CMP`, `AOFERTA`.
|
||||||
|
|
||||||
|
4. `config/judges.yaml` foi alinhado com `config/agents/backoffice_anatel/judges.yaml`.
|
||||||
|
- Evita divergência entre execução global e execução por agente.
|
||||||
|
- Inclui judges de qualidade, groundedness e políticas específicas do domínio backoffice.
|
||||||
|
|
||||||
|
5. `config/tools.yaml` recebeu política declarativa de MCP.
|
||||||
|
- Tools de consulta: `tool_type: read` e `cache.enabled: true`.
|
||||||
|
- Tools mutáveis/de ação: `tool_type: action`, `requires` e `cache.enabled: false`.
|
||||||
|
- A chave de cache passa a ser controlada pelo runtime do framework usando `args_schema`.
|
||||||
|
|
||||||
|
## Regra arquitetural preservada
|
||||||
|
|
||||||
|
As regras genéricas de segurança, qualidade, vazamento, repetição, escopo, groundedness e revisão de resposta ficam no framework. As regras específicas do domínio ANATEL/Backoffice permanecem como workflow de domínio, porque representam etapas de negócio e não guardrails reutilizáveis.
|
||||||
@@ -860,6 +860,15 @@ uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Terminal 3
|
# Terminal 3
|
||||||
|
cd compass_backoffice
|
||||||
|
source .venv/bin/activate
|
||||||
|
cd legacy_backend
|
||||||
|
uvicorn mock_imdb_server:app --port 8011
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Terminal 4
|
||||||
curl http://localhost:8010/health
|
curl http://localhost:8010/health
|
||||||
curl http://localhost:8000/health
|
curl http://localhost:8000/health
|
||||||
curl http://localhost:8000/debug/mcp/tools
|
curl http://localhost:8000/debug/mcp/tools
|
||||||
|
|||||||
@@ -1,267 +1,12 @@
|
|||||||
from __future__ import annotations
|
"""Framework-native agent runtime facade.
|
||||||
|
|
||||||
import hashlib
|
Compass Backoffice must not maintain a forked runtime for MCP, RAG, cache,
|
||||||
from typing import Any
|
telemetry, memory or IC/NOC/GRL behavior. The application imports the runtime
|
||||||
|
mixin directly from agent_framework_oci so fixes in the framework (for example
|
||||||
|
MCP cache using args_schema, BusinessContext mapping and tool deduplication) are
|
||||||
|
picked up by this backend without duplicating code here.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from agent_framework.runtime.agent_runtime import AgentRuntimeMixin, MessageBuilder, RuntimeContext
|
||||||
|
|
||||||
class AgentRuntimeMixin:
|
__all__ = ["AgentRuntimeMixin", "MessageBuilder", "RuntimeContext"]
|
||||||
"""Mixin operacional para agentes.
|
|
||||||
|
|
||||||
Integra RAG, cache, telemetria e chamadas MCP usando BusinessContext.
|
|
||||||
Os agentes não precisam conhecer nomes reais de parâmetros do domínio
|
|
||||||
(msisdn, invoice_id, order_id etc.); eles repassam as chaves canônicas e
|
|
||||||
o MCPParameterMapper converte para cada tool configurada.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
async def _emit_ic(self, code: str, state: dict[str, Any], payload: dict[str, Any] | None = None, component: str | None = None) -> None:
|
|
||||||
"""Emite Item de Controle (IC) sem impactar a execução do agente.
|
|
||||||
|
|
||||||
Este helper é intencionalmente fail-open: erro de observabilidade não
|
|
||||||
pode quebrar a jornada de negócio do agente. O desenvolvedor pode usar
|
|
||||||
o mesmo padrão para ICs específicos da sua squad.
|
|
||||||
"""
|
|
||||||
observer = getattr(self, "observer", None)
|
|
||||||
if not observer:
|
|
||||||
return
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
base = {
|
|
||||||
"session_id": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
"tenant_id": state.get("tenant_id"),
|
|
||||||
"agent_id": state.get("agent_id"),
|
|
||||||
"route": state.get("route"),
|
|
||||||
"intent": state.get("intent"),
|
|
||||||
"message_id": ctx.get("message_id"),
|
|
||||||
"channel_id": ctx.get("channel"),
|
|
||||||
}
|
|
||||||
base.update(payload or {})
|
|
||||||
try:
|
|
||||||
await observer.emit_ic(code, base, component=component or f"agent.{getattr(self, 'name', 'unknown')}")
|
|
||||||
except Exception:
|
|
||||||
return
|
|
||||||
|
|
||||||
async def _emit_noc(self, code: str, state: dict[str, Any], payload: dict[str, Any] | None = None, component: str | None = None) -> None:
|
|
||||||
"""Emite evento NOC sem acoplar a lógica de negócio à observabilidade."""
|
|
||||||
observer = getattr(self, "observer", None)
|
|
||||||
if not observer:
|
|
||||||
return
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
base = {
|
|
||||||
"session_id": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
"tenant_id": state.get("tenant_id"),
|
|
||||||
"agent_id": state.get("agent_id"),
|
|
||||||
"route": state.get("route"),
|
|
||||||
"intent": state.get("intent"),
|
|
||||||
"message_id": ctx.get("message_id"),
|
|
||||||
"channel_id": ctx.get("channel"),
|
|
||||||
}
|
|
||||||
base.update(payload or {})
|
|
||||||
try:
|
|
||||||
await observer.emit_noc(code, base, component=component or f"agent.{getattr(self, 'name', 'unknown')}")
|
|
||||||
except Exception:
|
|
||||||
return
|
|
||||||
|
|
||||||
async def _emit_grl(self, code: str, state: dict[str, Any], payload: dict[str, Any] | None = None, component: str | None = None) -> None:
|
|
||||||
"""Emite evento GRL opcional para custom rails implementados no backend."""
|
|
||||||
observer = getattr(self, "observer", None)
|
|
||||||
if not observer:
|
|
||||||
return
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
base = {
|
|
||||||
"session_id": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
"tenant_id": state.get("tenant_id"),
|
|
||||||
"agent_id": state.get("agent_id"),
|
|
||||||
"route": state.get("route"),
|
|
||||||
"intent": state.get("intent"),
|
|
||||||
"message_id": ctx.get("message_id"),
|
|
||||||
"channel_id": ctx.get("channel"),
|
|
||||||
}
|
|
||||||
base.update(payload or {})
|
|
||||||
try:
|
|
||||||
await observer.emit_grl(code, base, component=component or f"agent.{getattr(self, 'name', 'unknown')}")
|
|
||||||
except Exception:
|
|
||||||
return
|
|
||||||
|
|
||||||
async def _retrieve_rag_context(self, state: dict[str, Any]) -> tuple[str, dict[str, Any]]:
|
|
||||||
rag_service = getattr(self, "rag_service", None)
|
|
||||||
if not rag_service:
|
|
||||||
return "", {"enabled": False}
|
|
||||||
text = state.get("sanitized_input") or state.get("user_text") or ""
|
|
||||||
namespace = (
|
|
||||||
(state.get("agent_profile") or {}).get("rag_namespace")
|
|
||||||
or state.get("agent_id")
|
|
||||||
or state.get("route")
|
|
||||||
or "default"
|
|
||||||
)
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
business_context = ctx.get("business_context") or {}
|
|
||||||
graph_node = (
|
|
||||||
ctx.get("graph_node")
|
|
||||||
or business_context.get("customer_key")
|
|
||||||
or business_context.get("contract_key")
|
|
||||||
or ctx.get("customer_id")
|
|
||||||
)
|
|
||||||
result = await rag_service.retrieve(text, namespace=namespace, graph_node=graph_node)
|
|
||||||
context = result.as_prompt_context()
|
|
||||||
return context, {
|
|
||||||
"enabled": True,
|
|
||||||
"namespace": namespace,
|
|
||||||
"latency_ms": result.latency_ms,
|
|
||||||
"document_count": len(result.documents),
|
|
||||||
"graph_neighbors": len(result.graph_neighbors),
|
|
||||||
"top_document_ids": [d.id for d in result.documents[:5]],
|
|
||||||
"top_scores": [d.score for d in result.documents[:5]],
|
|
||||||
}
|
|
||||||
|
|
||||||
async def _call_mcp_tool(self, tool: str, arguments: dict[str, Any] | None, state: dict[str, Any]) -> dict[str, Any]:
|
|
||||||
"""Chama uma ferramenta via MCPToolRouter usando o contrato canônico do framework.
|
|
||||||
|
|
||||||
Use este helper quando o agente precisa passar argumentos específicos
|
|
||||||
além do BusinessContext mapeado em mcp_parameter_mapping.yaml.
|
|
||||||
Observabilidade IC.MCP_TOOL_CALLED/IC.TOOL_CALLED permanece uniforme.
|
|
||||||
"""
|
|
||||||
if not getattr(self, "tool_router", None):
|
|
||||||
return {"ok": False, "tool_name": tool, "error": "tool_router não configurado"}
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
business_context = ctx.get("business_context") or state.get("business_context") or {}
|
|
||||||
original_context = {
|
|
||||||
**ctx,
|
|
||||||
"tenant_id": state.get("tenant_id"),
|
|
||||||
"agent_id": state.get("agent_id"),
|
|
||||||
"session_id": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
"conversation_key": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
}
|
|
||||||
observer = getattr(self, "observer", None)
|
|
||||||
if observer:
|
|
||||||
await observer.emit_ic(
|
|
||||||
"IC.MCP_TOOL_CALLED",
|
|
||||||
{
|
|
||||||
"session_id": original_context.get("conversation_key") or original_context.get("session_id"),
|
|
||||||
"tenant_id": original_context.get("tenant_id"),
|
|
||||||
"agent_id": original_context.get("agent_id"),
|
|
||||||
"tool_name": tool,
|
|
||||||
"framework_native": True,
|
|
||||||
},
|
|
||||||
component="agent_runtime.native_mcp",
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
res = await self.tool_router.call(
|
|
||||||
tool,
|
|
||||||
arguments or {},
|
|
||||||
business_context=business_context,
|
|
||||||
original_context=original_context,
|
|
||||||
)
|
|
||||||
result_payload = res.model_dump(mode="json") if hasattr(res, "model_dump") else dict(res)
|
|
||||||
except Exception as exc:
|
|
||||||
result_payload = {"ok": False, "tool_name": tool, "error": str(exc), "error_type": type(exc).__name__}
|
|
||||||
result_payload.setdefault("tool_name", tool)
|
|
||||||
if observer:
|
|
||||||
await observer.emit_ic(
|
|
||||||
"IC.TOOL_CALLED",
|
|
||||||
{
|
|
||||||
"session_id": original_context.get("conversation_key") or original_context.get("session_id"),
|
|
||||||
"tenant_id": original_context.get("tenant_id"),
|
|
||||||
"agent_id": original_context.get("agent_id"),
|
|
||||||
"tool_name": tool,
|
|
||||||
"ok": result_payload.get("ok"),
|
|
||||||
"server_name": result_payload.get("server_name"),
|
|
||||||
"error": result_payload.get("error"),
|
|
||||||
"framework_native": True,
|
|
||||||
},
|
|
||||||
component="agent_runtime.native_mcp",
|
|
||||||
)
|
|
||||||
return result_payload
|
|
||||||
|
|
||||||
async def _collect_mcp_context(self, state: dict[str, Any]) -> list[dict[str, Any]]:
|
|
||||||
results: list[dict[str, Any]] = []
|
|
||||||
if not getattr(self, "tool_router", None):
|
|
||||||
return results
|
|
||||||
tools = state.get("mcp_tools") or []
|
|
||||||
ctx = state.get("context") or {}
|
|
||||||
business_context = ctx.get("business_context") or state.get("business_context") or {}
|
|
||||||
original_context = {
|
|
||||||
**ctx,
|
|
||||||
"tenant_id": state.get("tenant_id"),
|
|
||||||
"agent_id": state.get("agent_id"),
|
|
||||||
"session_id": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
"conversation_key": state.get("conversation_key") or state.get("session_id"),
|
|
||||||
}
|
|
||||||
for tool in tools:
|
|
||||||
observer = getattr(self, "observer", None)
|
|
||||||
if observer:
|
|
||||||
await observer.emit_ic(
|
|
||||||
"IC.MCP_TOOL_CALLED",
|
|
||||||
{
|
|
||||||
"session_id": original_context.get("conversation_key") or original_context.get("session_id"),
|
|
||||||
"tenant_id": original_context.get("tenant_id"),
|
|
||||||
"agent_id": original_context.get("agent_id"),
|
|
||||||
"tool_name": tool,
|
|
||||||
},
|
|
||||||
component="agent_runtime",
|
|
||||||
)
|
|
||||||
res = await self.tool_router.call(
|
|
||||||
tool,
|
|
||||||
{},
|
|
||||||
business_context=business_context,
|
|
||||||
original_context=original_context,
|
|
||||||
)
|
|
||||||
result_payload = res.model_dump(mode="json")
|
|
||||||
if observer:
|
|
||||||
await observer.emit_ic(
|
|
||||||
"IC.TOOL_CALLED",
|
|
||||||
{
|
|
||||||
"session_id": original_context.get("conversation_key") or original_context.get("session_id"),
|
|
||||||
"tenant_id": original_context.get("tenant_id"),
|
|
||||||
"agent_id": original_context.get("agent_id"),
|
|
||||||
"tool_name": tool,
|
|
||||||
"ok": result_payload.get("ok"),
|
|
||||||
"server_name": result_payload.get("server_name"),
|
|
||||||
"error": result_payload.get("error"),
|
|
||||||
},
|
|
||||||
component="agent_runtime",
|
|
||||||
)
|
|
||||||
results.append(result_payload)
|
|
||||||
return results
|
|
||||||
|
|
||||||
async def _cache_get(self, key: str):
|
|
||||||
cache = getattr(self, "cache", None)
|
|
||||||
if not cache:
|
|
||||||
return None
|
|
||||||
return await cache.get(key)
|
|
||||||
|
|
||||||
async def _cache_set(self, key: str, value: Any, ttl_seconds: int | None = None):
|
|
||||||
cache = getattr(self, "cache", None)
|
|
||||||
if not cache:
|
|
||||||
return
|
|
||||||
await cache.set(key, value, ttl_seconds)
|
|
||||||
|
|
||||||
def _llm_cache_key(self, state: dict[str, Any], agent_name: str, prompt_parts: list[Any]) -> str:
|
|
||||||
business_context = (state.get("context") or {}).get("business_context") or {}
|
|
||||||
raw = "|".join([
|
|
||||||
agent_name,
|
|
||||||
state.get("tenant_id") or "",
|
|
||||||
state.get("agent_id") or "",
|
|
||||||
state.get("intent") or "",
|
|
||||||
business_context.get("customer_key") or "",
|
|
||||||
business_context.get("contract_key") or "",
|
|
||||||
business_context.get("interaction_key") or "",
|
|
||||||
state.get("sanitized_input") or state.get("user_text") or "",
|
|
||||||
repr(prompt_parts),
|
|
||||||
])
|
|
||||||
return "llm:" + hashlib.sha256(raw.encode("utf-8")).hexdigest()
|
|
||||||
|
|
||||||
async def _invoke_llm_cached(self, state: dict[str, Any], agent_name: str, messages: list[dict[str, str]]):
|
|
||||||
ttl = int(getattr(getattr(self, "settings", None), "CACHE_TTL_SECONDS", 300) or 300)
|
|
||||||
key = self._llm_cache_key(state, agent_name, messages)
|
|
||||||
cached = await self._cache_get(key)
|
|
||||||
if cached is not None:
|
|
||||||
telemetry = getattr(self, "telemetry", None)
|
|
||||||
if telemetry:
|
|
||||||
await telemetry.event("cache.llm.hit", {"agent": agent_name, "key": key}, kind="cache")
|
|
||||||
return cached
|
|
||||||
telemetry = getattr(self, "telemetry", None)
|
|
||||||
if telemetry:
|
|
||||||
await telemetry.event("cache.llm.miss", {"agent": agent_name, "key": key}, kind="cache")
|
|
||||||
answer = await self.llm.ainvoke(messages)
|
|
||||||
await self._cache_set(key, answer, ttl)
|
|
||||||
return answer
|
|
||||||
|
|||||||
@@ -220,7 +220,10 @@ class BackofficeWorkflowExecutor:
|
|||||||
enable_parallel=bool(getattr(settings, "ENABLE_PARALLEL_GUARDRAILS", True)),
|
enable_parallel=bool(getattr(settings, "ENABLE_PARALLEL_GUARDRAILS", True)),
|
||||||
fail_fast=bool(getattr(settings, "GUARDRAILS_FAIL_FAST", True)),
|
fail_fast=bool(getattr(settings, "GUARDRAILS_FAIL_FAST", True)),
|
||||||
)
|
)
|
||||||
self.judges = JudgePipeline()
|
self.judges = JudgePipeline(
|
||||||
|
settings=settings,
|
||||||
|
config_path=self.agent_profile.get("judges_config_path"),
|
||||||
|
)
|
||||||
self.supervisor = Supervisor()
|
self.supervisor = Supervisor()
|
||||||
self.workflow_telemetry = WorkflowTelemetry(telemetry)
|
self.workflow_telemetry = WorkflowTelemetry(telemetry)
|
||||||
self.guardrail_telemetry = GuardrailTelemetry(telemetry)
|
self.guardrail_telemetry = GuardrailTelemetry(telemetry)
|
||||||
|
|||||||
@@ -1,54 +1,34 @@
|
|||||||
|
# Source of truth for global/default guardrails in Compass Backoffice.
|
||||||
|
# This file is intentionally aligned with config/agents/backoffice_anatel/guardrails.yaml
|
||||||
|
# so framework stages that read the global path and stages that read the agent profile
|
||||||
|
# apply the same policy set.
|
||||||
agent_id: backoffice_anatel
|
agent_id: backoffice_anatel
|
||||||
profile: backoffice_anatel_enterprise
|
profile: backoffice_anatel
|
||||||
|
|
||||||
input:
|
input:
|
||||||
- code: INPUT_SIZE
|
- code: INPUT_SIZE
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
max_chars: 12000
|
|
||||||
- code: MSK
|
- code: MSK
|
||||||
enabled: true
|
enabled: true
|
||||||
action: sanitize
|
|
||||||
- code: PINJ
|
- code: PINJ
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
- code: TOX
|
- code: TOX
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
- code: DLEX_IN
|
- code: DLEX_IN
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
- code: RAGSEC
|
- code: RAGSEC
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
- code: VLOOP
|
- code: VLOOP
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
output:
|
output:
|
||||||
- code: REVPREC
|
- code: REVPREC
|
||||||
enabled: true
|
enabled: true
|
||||||
action: sanitize
|
|
||||||
- code: DLEX_OUT
|
- code: DLEX_OUT
|
||||||
enabled: true
|
enabled: true
|
||||||
action: sanitize
|
|
||||||
- code: OOS
|
- code: OOS
|
||||||
enabled: true
|
enabled: true
|
||||||
action: review
|
|
||||||
- code: CMP
|
- code: CMP
|
||||||
enabled: true
|
enabled: true
|
||||||
action: review
|
|
||||||
- code: AOFERTA
|
- code: AOFERTA
|
||||||
enabled: true
|
enabled: true
|
||||||
action: block
|
|
||||||
business_rules:
|
|
||||||
require_evidence_for:
|
|
||||||
- protocolo
|
|
||||||
- cliente
|
|
||||||
- contrato
|
|
||||||
- status_siebel
|
|
||||||
- acao_operacional
|
|
||||||
forbid_without_tool_ok:
|
|
||||||
- registrar_acao_backoffice
|
|
||||||
- registrar_acao_siebel
|
|
||||||
domain_workflows:
|
|
||||||
checklist: src.agent.graphs.main_graph.create_main_agent_graph
|
|
||||||
response_emulator: src.agent.graphs.emulator_graph.create_emulator_graph
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
|
# Source of truth for global/default judges in Compass Backoffice.
|
||||||
|
# Aligned with config/agents/backoffice_anatel/judges.yaml to avoid running a
|
||||||
|
# weaker judge set when the framework is configured with the global path.
|
||||||
agent_id: backoffice_anatel
|
agent_id: backoffice_anatel
|
||||||
|
profile: judge
|
||||||
|
fail_closed: true
|
||||||
judges:
|
judges:
|
||||||
- name: response_quality
|
- name: response_quality
|
||||||
enabled: true
|
enabled: true
|
||||||
@@ -8,13 +13,21 @@ judges:
|
|||||||
threshold: 0.80
|
threshold: 0.80
|
||||||
- name: backoffice_no_fabricated_protocol
|
- name: backoffice_no_fabricated_protocol
|
||||||
enabled: true
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
description: Verifica se a resposta não inventa protocolo, cliente, contrato, SLA ou status operacional.
|
description: Verifica se a resposta não inventa protocolo, cliente, contrato, SLA ou status operacional.
|
||||||
- name: siebel_action_requires_tool_ok
|
- name: siebel_action_requires_tool_ok
|
||||||
enabled: true
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.85
|
||||||
description: Bloqueia confirmação de registro/fechamento Siebel sem evidência ok/registered.
|
description: Bloqueia confirmação de registro/fechamento Siebel sem evidência ok/registered.
|
||||||
- name: anatel_domain_traceability
|
- name: anatel_domain_traceability
|
||||||
enabled: true
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
description: Exige rastreabilidade para decisão de cancelamento, reclassificação, tratamento ou encaminhamento.
|
description: Exige rastreabilidade para decisão de cancelamento, reclassificação, tratamento ou encaminhamento.
|
||||||
- name: response_emulator_policy
|
- name: response_emulator_policy
|
||||||
enabled: true
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
description: Valida resposta formal ANATEL gerada pelo emulador antes de persistir/aprovar/fechar.
|
description: Valida resposta formal ANATEL gerada pelo emulador antes de persistir/aprovar/fechar.
|
||||||
|
|||||||
@@ -1,8 +1,34 @@
|
|||||||
|
# Source of truth for global/default guardrails in Compass Backoffice.
|
||||||
|
# This file is intentionally aligned with config/agents/backoffice_anatel/guardrails.yaml
|
||||||
|
# so framework stages that read the global path and stages that read the agent profile
|
||||||
|
# apply the same policy set.
|
||||||
|
agent_id: backoffice_anatel
|
||||||
|
profile: backoffice_anatel
|
||||||
|
|
||||||
input:
|
input:
|
||||||
|
- code: INPUT_SIZE
|
||||||
|
enabled: true
|
||||||
- code: MSK
|
- code: MSK
|
||||||
enabled: true
|
enabled: true
|
||||||
|
- code: PINJ
|
||||||
|
enabled: true
|
||||||
|
- code: TOX
|
||||||
|
enabled: true
|
||||||
|
- code: DLEX_IN
|
||||||
|
enabled: true
|
||||||
|
- code: RAGSEC
|
||||||
|
enabled: true
|
||||||
- code: VLOOP
|
- code: VLOOP
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|
||||||
output:
|
output:
|
||||||
- code: REVPREC
|
- code: REVPREC
|
||||||
enabled: true
|
enabled: true
|
||||||
|
- code: DLEX_OUT
|
||||||
|
enabled: true
|
||||||
|
- code: OOS
|
||||||
|
enabled: true
|
||||||
|
- code: CMP
|
||||||
|
enabled: true
|
||||||
|
- code: AOFERTA
|
||||||
|
enabled: true
|
||||||
|
|||||||
@@ -1,7 +1,33 @@
|
|||||||
|
# Source of truth for global/default judges in Compass Backoffice.
|
||||||
|
# Aligned with config/agents/backoffice_anatel/judges.yaml to avoid running a
|
||||||
|
# weaker judge set when the framework is configured with the global path.
|
||||||
|
agent_id: backoffice_anatel
|
||||||
|
profile: judge
|
||||||
|
fail_closed: true
|
||||||
judges:
|
judges:
|
||||||
- name: response_quality
|
- name: response_quality
|
||||||
enabled: true
|
enabled: true
|
||||||
threshold: 0.7
|
threshold: 0.75
|
||||||
- name: groundedness
|
- name: groundedness
|
||||||
enabled: true
|
enabled: true
|
||||||
threshold: 0.6
|
threshold: 0.80
|
||||||
|
- name: backoffice_no_fabricated_protocol
|
||||||
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
|
description: Verifica se a resposta não inventa protocolo, cliente, contrato, SLA ou status operacional.
|
||||||
|
- name: siebel_action_requires_tool_ok
|
||||||
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.85
|
||||||
|
description: Bloqueia confirmação de registro/fechamento Siebel sem evidência ok/registered.
|
||||||
|
- name: anatel_domain_traceability
|
||||||
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
|
description: Exige rastreabilidade para decisão de cancelamento, reclassificação, tratamento ou encaminhamento.
|
||||||
|
- name: response_emulator_policy
|
||||||
|
enabled: true
|
||||||
|
type: llm
|
||||||
|
threshold: 0.80
|
||||||
|
description: Valida resposta formal ANATEL gerada pelo emulador antes de persistir/aprovar/fechar.
|
||||||
|
|||||||
@@ -3,60 +3,110 @@ tools:
|
|||||||
description: Consulta reclamação/protocolo de backoffice/ANATEL.
|
description: Consulta reclamação/protocolo de backoffice/ANATEL.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 300
|
||||||
args_schema: { protocol_id: string, customer_key: string, interaction_key: string }
|
args_schema: { protocol_id: string, customer_key: string, interaction_key: string }
|
||||||
consultar_cliente_backoffice:
|
consultar_cliente_backoffice:
|
||||||
description: Consulta contexto operacional do cliente para backoffice.
|
description: Consulta contexto operacional do cliente para backoffice.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 600
|
||||||
args_schema: { customer_key: string, contract_key: string, session_key: string }
|
args_schema: { customer_key: string, contract_key: string, session_key: string }
|
||||||
registrar_acao_backoffice:
|
registrar_acao_backoffice:
|
||||||
description: Registra ação operacional, parecer ou encaminhamento no sistema de backoffice.
|
description: Registra ação operacional, parecer ou encaminhamento no sistema de backoffice.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: action
|
||||||
|
requires: [protocol_id, action_text, operator_session]
|
||||||
|
confirmation_required: false
|
||||||
|
cache:
|
||||||
|
enabled: false
|
||||||
args_schema: { protocol_id: string, action_text: string, operator_session: string }
|
args_schema: { protocol_id: string, action_text: string, operator_session: string }
|
||||||
|
|
||||||
consultar_siebel_caso:
|
consultar_siebel_caso:
|
||||||
description: Consulta caso/SR no Siebel.
|
description: Consulta caso/SR no Siebel.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 300
|
||||||
args_schema: { protocol_id: string, interaction_key: string, customer_key: string }
|
args_schema: { protocol_id: string, interaction_key: string, customer_key: string }
|
||||||
registrar_acao_siebel:
|
registrar_acao_siebel:
|
||||||
description: Registra ação, reclassificação ou fechamento no Siebel.
|
description: Registra ação, reclassificação ou fechamento no Siebel.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: action
|
||||||
|
requires: [protocol_id, action_text, operator_session]
|
||||||
|
confirmation_required: false
|
||||||
|
cache:
|
||||||
|
enabled: false
|
||||||
args_schema: { protocol_id: string, action_text: string, operator_session: string }
|
args_schema: { protocol_id: string, action_text: string, operator_session: string }
|
||||||
consultar_imdb_cliente:
|
consultar_imdb_cliente:
|
||||||
description: Consulta enriquecimento IMDB/PMID do cliente.
|
description: Consulta enriquecimento IMDB/PMID do cliente.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 600
|
||||||
args_schema: { customer_key: string, contract_key: string, session_key: string }
|
args_schema: { customer_key: string, contract_key: string, session_key: string }
|
||||||
consultar_speech_analytics:
|
consultar_speech_analytics:
|
||||||
description: Consulta histórico/resumo do Speech Analytics.
|
description: Consulta histórico/resumo do Speech Analytics.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 600
|
||||||
args_schema: { protocol_id: string, customer_key: string, interaction_key: string }
|
args_schema: { protocol_id: string, customer_key: string, interaction_key: string }
|
||||||
consultar_tais_kb:
|
consultar_tais_kb:
|
||||||
description: Consulta TAIS Knowledge Base/RAG e templates.
|
description: Consulta TAIS Knowledge Base/RAG e templates.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 900
|
||||||
args_schema: { query: string, protocol_id: string, customer_key: string }
|
args_schema: { query: string, protocol_id: string, customer_key: string }
|
||||||
consultar_abrt:
|
consultar_abrt:
|
||||||
description: Consulta ABRT associado ao cliente/caso.
|
description: Consulta ABRT associado ao cliente/caso.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 600
|
||||||
args_schema: { customer_key: string, protocol_id: string }
|
args_schema: { customer_key: string, protocol_id: string }
|
||||||
consultar_portabilidade:
|
consultar_portabilidade:
|
||||||
description: Consulta status de portabilidade.
|
description: Consulta status de portabilidade.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 600
|
||||||
args_schema: { customer_key: string, contract_key: string }
|
args_schema: { customer_key: string, contract_key: string }
|
||||||
buscar_templates_emulador:
|
buscar_templates_emulador:
|
||||||
description: Busca templates/documentos para Response Emulator.
|
description: Busca templates/documentos para Response Emulator.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: read
|
||||||
|
cache:
|
||||||
|
enabled: true
|
||||||
|
ttl_seconds: 900
|
||||||
args_schema: { protocol_id: string, query: string }
|
args_schema: { protocol_id: string, query: string }
|
||||||
gerar_rascunho_emulador:
|
gerar_rascunho_emulador:
|
||||||
description: Gera rascunho de resposta do Response Emulator.
|
description: Gera rascunho de resposta do Response Emulator.
|
||||||
mcp_server: backoffice
|
mcp_server: backoffice
|
||||||
enabled: true
|
enabled: true
|
||||||
|
tool_type: action
|
||||||
|
requires: [protocol_id]
|
||||||
|
cache:
|
||||||
|
enabled: false
|
||||||
args_schema: { protocol_id: string, selected_actions: array, operator_instructions: string }
|
args_schema: { protocol_id: string, selected_actions: array, operator_instructions: string }
|
||||||
|
|||||||
Reference in New Issue
Block a user