3.8 KiB
3.8 KiB
Ajuste de Orquestração + Guardrail de FAQ (Captain/Jasmine)
Data: 24/02/2026
Autor: Codex (AI Developer)
Objetivo
Garantir que o agente não responda “não sei / não tenho acesso” sem antes consultar FAQ, e evitar que a conversa fique presa em um cenário que ignora FAQ.
Problema Observado
- Em algumas conversas, o agente respondia corretamente usando FAQ (ex.: preços), mas em outras respostas dizia que “não tinha acesso” (ex.: senha do Wi-Fi).
- Isso gerava comportamento inconsistente e perda de confiança.
Causa-Raiz
-
Sticky de cenário no histórico
O runner podia iniciar o turno no últimoagent_namedo histórico (ex.: cenário de disponibilidade), em vez de iniciar no orquestrador principal. -
Guardrail com detecção ampla demais de
faq_lookup
A checagem consideravafaq_lookupemresult.messagesinteiro.
Se houvefaq_lookupem turno anterior, isso podia bloquear o fallback no turno atual.
O que foi implementado
1) Início de turno sempre pelo orquestrador
- O contexto da execução foi padronizado para iniciar no agente principal (
current_agentdo assistente). - O
conversation_historyenviado ao runner zeraagent_namedas mensagens para evitar lock indevido em cenário.
2) Guardrail de FAQ para respostas de incerteza
- Foi criado um guardrail em
AgentRunnerService:- Detecta respostas de incerteza (
não sei,não tenho, etc.). - Se não houve
faq_lookupno turno atual, dispara fallback de FAQ via busca semântica (@assistant.responses.approved.search(query)). - Se encontrar resposta no FAQ, substitui a resposta final.
- Se não encontrar, responde explicitamente:
- “Consultei o FAQ e não encontrei essa informação cadastrada ainda...”
- Evita resposta genérica “não sei” sem contexto.
- Detecta respostas de incerteza (
3) Correção de escopo do faq_lookup
- A verificação agora considera apenas mensagens após a última pergunta do usuário do turno atual.
- Isso evita falso positivo de
faq_lookupantigo.
Arquivos Alterados
/Users/user/Dev/Produtos/Chatwoot-fazer-ai/fazer-ai-kanban/chatwoot/enterprise/app/services/captain/assistant/agent_runner_service.rb/Users/user/Dev/Produtos/Chatwoot-fazer-ai/fazer-ai-kanban/chatwoot/spec/enterprise/services/captain/assistant/agent_runner_service_spec.rb
Testes e Validação
- Executado:
bundle exec rspec spec/enterprise/services/captain/assistant/agent_runner_service_spec.rb
- Resultado:
- 29 examples, 0 failures
Casos cobertos em teste:
- fallback aplicado quando resposta incerta vem sem
faq_lookup; - não aplica fallback quando
faq_lookupocorreu no turno atual; - aplica fallback quando
faq_lookupocorreu apenas em turno anterior; - retorna mensagem explícita de “FAQ não encontrado” quando busca não acha nada.
Observabilidade (logs)
Foram mantidos logs para rastrear guardrail:
- Trigger do guardrail com query;
- Quantidade de resultados encontrados na busca FAQ;
- Falha de fallback (se houver exception).
Impacto Prático
- O agente deixa de “desistir” sem consultar conhecimento.
- Reduz respostas incoerentes entre perguntas parecidas.
- Mantém handoff para humano apenas quando realmente necessário.
Limitações Atuais
- Se o FAQ estiver mal cadastrado ou com baixa qualidade semântica, o fallback ainda pode não encontrar resposta.
- O guardrail atua em respostas de incerteza; não corrige respostas erradas factualmente quando o modelo responde com confiança indevida.
Próximos Passos Recomendados
- Revisar/normalizar entradas de FAQ críticas (Wi-Fi, horários, políticas, preços).
- Adicionar métrica de “fallback guardrail acionado” por inbox/assistente.
- Opcional: forçar política “FAQ-first” para intents informativas antes de responder livremente.