Ajustes conforme relatorio de testes 2026-08-27
This commit is contained in:
@@ -679,6 +679,74 @@ A funcionalidade é aditiva. Entradas determinísticas já suportadas continuam
|
||||
|
||||
Para confirmações semânticas, o framework registra a geração como `transaction.confirmation.semantic_classifier` e acrescenta ao metadata do roteamento a fonte `semantic`, a classificação retornada e o contexto conversacional relevante utilizado. Para confirmações literais, a fonte permanece `deterministic`.
|
||||
|
||||
### `expected_input.semantic_classifier.unmatched_value` e `reprompt`
|
||||
|
||||
Workflows pausados podem aceitar respostas literais e também interpretar respostas livres por semântica. Quando o `semantic_classifier` é habilitado, uma fala que **não representa com segurança nenhuma das classes válidas** não deve ser forçada para `SIM`, `NAO` ou `CONTINUAR`. Para esse caso, o workflow pode declarar um valor sentinela com `unmatched_value`.
|
||||
|
||||
Exemplo:
|
||||
|
||||
```yaml
|
||||
expected_input:
|
||||
key: resposta_usuario
|
||||
allowed_values:
|
||||
- SIM
|
||||
- NAO
|
||||
- CONTINUAR
|
||||
normalize: upper_strip
|
||||
reprompt: >
|
||||
Não entendi. Essa explicação resolveu sua dúvida?
|
||||
Responda sim ou não.
|
||||
|
||||
semantic_classifier:
|
||||
enabled: true
|
||||
include_relevant_context: true
|
||||
unmatched_value: OUTRO
|
||||
prompt: |
|
||||
Classifique a fala do cliente em exatamente uma das opções válidas quando houver
|
||||
significado suficiente.
|
||||
|
||||
SIM: entendimento/aceite inequívoco.
|
||||
NAO: negativa inequívoca.
|
||||
CONTINUAR: fala compreensível que complementa ou continua a solicitação.
|
||||
OUTRO: fala incompreensível, desconexa ou insuficiente para qualquer classe válida.
|
||||
|
||||
Retorne somente SIM, NAO, CONTINUAR ou OUTRO.
|
||||
|
||||
option_actions:
|
||||
CONTINUAR:
|
||||
action: contextual_reentry
|
||||
```
|
||||
|
||||
O contrato é:
|
||||
|
||||
```text
|
||||
SIM -> resume com SIM
|
||||
NAO -> resume com NAO
|
||||
CONTINUAR -> executa a option_action configurada (por exemplo contextual_reentry)
|
||||
OUTRO -> não é usado como valor de resume; devolve o reprompt e mantém o workflow pausado
|
||||
```
|
||||
|
||||
Regras importantes:
|
||||
|
||||
- `unmatched_value` é **sentinela do classificador**, não uma resposta de negócio;
|
||||
- não adicione o sentinela a `allowed_values`; `allowed_values` continua descrevendo apenas valores que podem ser consumidos pelo workflow;
|
||||
- `CONTINUAR` deve ser usado somente quando a fala é compreensível e realmente continua o assunto; uma fala sem significado contextual suficiente deve produzir `unmatched_value` e cair em `reprompt`;
|
||||
- o `reprompt` não encerra nem reinicia a execução: o mesmo workflow permanece `PAUSED`, aguardando nova resposta;
|
||||
- valores internos como `SIM`, `NAO`, `CONTINUAR` e o sentinela não devem vazar como resposta final do agente.
|
||||
|
||||
Exemplo comportamental:
|
||||
|
||||
```text
|
||||
Pergunta pendente: "Com essa explicação, sanei sua dúvida?"
|
||||
|
||||
"sim" -> SIM
|
||||
"não resolveu" -> NAO
|
||||
"mas e a cobrança de R$ 14,99?" -> CONTINUAR -> contextual_reentry
|
||||
"ano" -> OUTRO -> reprompt
|
||||
```
|
||||
|
||||
A opção é **opt-in por workflow**. Workflows que não declaram `semantic_classifier.unmatched_value` preservam o contrato anterior. Isso evita que uma evolução específica de um fluxo altere silenciosamente os demais workflows/agentes.
|
||||
|
||||
### Compatibilidade de interrupts duráveis no pause/resume
|
||||
|
||||
O runtime não usa `snapshot.next` isoladamente para decidir se um workflow está pausado. Um `next` pode representar trabalho auxiliar do LangGraph, inclusive nós sintéticos criados pelo framework como `__pause` e `__continue`.
|
||||
|
||||
@@ -95,6 +95,35 @@ Uma resposta criada em função de um bloqueio de entrada ainda é uma saída do
|
||||
|
||||
Isso permite que `DLEX_OUT`, `PINJ`, `TOXOUT`, Output Supervisor e outras políticas removam ou sanitizem informação que não deva ser apresentada.
|
||||
|
||||
## COER, `expected_input` e `reprompt` em workflows pausados
|
||||
|
||||
Quando existe um `expected_input.semantic_classifier` ativo, o framework pode delegar a decisão semântica ao contrato do workflow em vez de tratar imediatamente uma entrada ambígua como bloqueio genérico de `COER`. Nesse modo, o guardrail pode aparecer como permitido/delegado, por exemplo com mecanismo `expected_input_semantic_classifier`.
|
||||
|
||||
O workflow continua responsável por diferenciar:
|
||||
|
||||
```text
|
||||
resposta válida e compreensível -> classe válida / option_action
|
||||
resposta sem significado suficiente -> unmatched_value -> reprompt
|
||||
```
|
||||
|
||||
Exemplo de configuração:
|
||||
|
||||
```yaml
|
||||
expected_input:
|
||||
allowed_values: [SIM, NAO, CONTINUAR]
|
||||
reprompt: "Não entendi. Essa explicação resolveu sua dúvida? Responda sim ou não."
|
||||
semantic_classifier:
|
||||
enabled: true
|
||||
unmatched_value: OUTRO
|
||||
option_actions:
|
||||
CONTINUAR:
|
||||
action: contextual_reentry
|
||||
```
|
||||
|
||||
Nesse contrato, `CONTINUAR` não significa "qualquer coisa que não seja SIM ou NAO". Ele representa uma fala **coerente e contextual** que continua o assunto. Uma entrada como `ano`, sem significado suficiente para a pergunta pendente, deve retornar o sentinela `OUTRO` e produzir o `reprompt`, mantendo o mesmo workflow pausado.
|
||||
|
||||
`OUTRO` não deve ser adicionado a `allowed_values` nem enviado ao runtime como valor de resume. A descrição completa do contrato está em [03 — Workflows Transacionais e Estado](./03_transaction_workflows_and_state.md#expected_inputsemantic_classifierunmatched_value-e-reprompt).
|
||||
|
||||
## Relação com `agent_graph.py`
|
||||
|
||||
Esta feature é responsabilidade da orquestração do template, porque define a precedência entre nós do grafo e o estado do turno.
|
||||
@@ -151,6 +180,8 @@ input_guardrails bloqueou
|
||||
Cubra pelo menos:
|
||||
|
||||
- `COER=false` gera solicitação de esclarecimento, não mensagem genérica de segurança;
|
||||
- com `expected_input.semantic_classifier.unmatched_value`, entrada incoerente/sem significado suficiente aciona `reprompt` e mantém o workflow `PAUSED`;
|
||||
- uma entrada compreensível fora de SIM/NAO pode seguir `CONTINUAR -> contextual_reentry` sem ser confundida com uma entrada incoerente;
|
||||
- ramo bloqueado não conserva `mcp_results`/routing de turno anterior;
|
||||
- nenhuma tool transacional é executada depois de um bloqueio de input;
|
||||
- mensagem pública passa pelos guardrails de saída;
|
||||
|
||||
@@ -22,6 +22,7 @@ Se algo não está funcionando, use **Buscar pelo problema** abaixo.
|
||||
| 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 fala inválida durante um `expected_input` vira `CONTINUAR` em vez de pedir esclarecimento | `semantic_classifier.unmatched_value`, `reprompt`, `contextual_reentry`, COER delegado | [Workflows Transacionais](./03_transaction_workflows_and_state.md) e [Feedback de Guardrails de Entrada](./12_input_guardrail_feedback_and_blocked_turns.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) |
|
||||
@@ -67,9 +68,9 @@ Se algo não está funcionando, use **Buscar pelo problema** abaixo.
|
||||
|
||||
### [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.
|
||||
**O que é:** ciclo transacional multi-turno, estados, confirmação, pausa/retomada, `expected_input`, `semantic_classifier`, `unmatched_value`/`reprompt` e evidência operacional.
|
||||
|
||||
**Use quando:** há loops, confirmações incorretas, retomadas erradas ou operações críticas.
|
||||
**Use quando:** há loops, confirmações incorretas, retomadas erradas, `CONTINUAR`/`contextual_reentry` indevido, `reprompt` ausente ou operações críticas.
|
||||
|
||||
### [04 — MCP, Tools, Policies e Extração de Parâmetros](./04_mcp_integration_tools_and_policies.md)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user