85 lines
7.7 KiB
Markdown
85 lines
7.7 KiB
Markdown
# Seleção individual de decisões: modelo atual ou JEV
|
||
|
||
Implementação opt-in para o projeto do ZIP de 03/11/2026. O padrão continua sendo `current`; nenhum modelo foi ativado e nenhuma chave foi incluída.
|
||
|
||
## Configuração
|
||
|
||
Copie as variáveis de `.env.jev.example` para o `.env` utilizado pelo processo. Se usar contêiner/Kubernetes, passe as variáveis também para o ambiente do processo e guarde a chave no mecanismo de secrets do ambiente. Reinicie o serviço após alterar a configuração. Substitua os arquivos de código e refaça o build/redeploy caso o framework esteja instalado em pacote ou imagem; reiniciar sem atualizar o pacote instalado não aplica mudanças de código.
|
||
|
||
Exemplo: ativar somente continuidade e intenção, mantendo o restante atual:
|
||
|
||
```dotenv
|
||
DECISION_PROVIDER=current
|
||
DECISION_ROUTE_CONTINUITY_PROVIDER=jev
|
||
DECISION_ROUTER_PROVIDER=jev
|
||
AI_GATEWAY_API_KEY=<sua chave>
|
||
JEV_MODEL=typesafe-ai/jev
|
||
DECISION_FALLBACK_TO_CURRENT=true
|
||
JEV_MIN_CONFIDENCE=0.7
|
||
DECISION_ROUTE_CONTINUITY_MIN_CONFIDENCE=0.90
|
||
```
|
||
|
||
A variável individual prevalece sobre `DECISION_PROVIDER`. Uma variável individual ausente herda o padrão global. Como o exemplo define todas como `current`, mudar somente a variável global não altera os pontos explicitamente definidos. Os valores válidos são `current` e `jev`.
|
||
|
||
A seleção não habilita funcionalidades desativadas: `ENABLE_LLM_ROUTER`, `ENABLE_ROUTE_STICKINESS`, configuração de semantic classifiers e configuração dos guardrails/judges continuam controlando se cada ponto é executado. Para não tornar `current` incompatível, não foram alteradas as regras determinísticas nem os controles de execução.
|
||
|
||
## Pontos disponíveis
|
||
|
||
Cada sufixo abaixo corresponde a `DECISION_<SUFIXO>_PROVIDER`:
|
||
|
||
| Sufixo | Função |
|
||
|---|---|
|
||
| ROUTE_CONTINUITY | CONTINUE, ROUTE, HUMAN_HANDOFF, END_SESSION; inclui sondagem de controles globais que usa o mesmo classificador |
|
||
| ROUTER | Intenção semântica; agente, domínio e ferramentas derivados do catálogo local |
|
||
| WORKFLOW_EXPECTED_INPUT | Opção permitida para retomada de workflow; opção sem correspondência não retoma |
|
||
| WORKFLOW_REENTRY | REENTER ou RESUME |
|
||
| TRANSACTION_CONFIRMATION | Confirmação semântica, usando as opções configuradas; parser explícito permanece |
|
||
| TRANSACTION_PARAMETER_RELEVANCE | RELEVANT ou NOT_RELEVANT |
|
||
| TRANSACTION_INTENT_SHIFT | CONTINUE, REPLACE, SHIFT ou ABANDON e intenção de destino |
|
||
| MULTI_INTENT | Intenção de cada objetivo extraído, com preservação de ordem e trechos literais |
|
||
| TRANSACTION_PARAMETER_RECONCILIATION | resolved, preserve, clear ou unresolved por parâmetro |
|
||
| GLOBAL_SUPERVISOR | Backend permitido no registro do supervisor global |
|
||
| PROCESSING_INTERRUPTION | Regenerar resposta de voz ou repetir |
|
||
| GUARDRAIL_GUARDRAIL / GUARDRAIL_GRL | Guardrails LLM genéricos com os perfis padrão; perfis personalizados usam GUARDRAIL_<PERFIL> |
|
||
| GUARDRAIL_PINJ, COER, TOX, REVPREC, AOFERTA, OOS, FRASEOLOGIA, RAGSEC, DLEX_IN, DLEX_OUT | Cada tarefa calibrada tem sua própria variável GUARDRAIL_<TAREFA> |
|
||
| JUDGE_CSI, JUDGE_VCTN, JUDGE_ALUC, JUDGE_RQLT | Cada tarefa de judge calibrado, como padrão de grupo |
|
||
| JUDGE_<NOME> | Judge genérico, usando seu `name`; o padrão é JUDGE_LLM_JUDGE |
|
||
|
||
Um judge calibrado também aceita `DECISION_JUDGE_<NOME_CONFIGURADO>_PROVIDER`, que prevalece sobre o grupo da tarefa (por exemplo `DECISION_JUDGE_GROUNDEDNESS_PROVIDER` prevalece sobre `DECISION_JUDGE_ALUC_PROVIDER`). Rechecagens de guardrail aceitam o nome completo do componente, por exemplo `DECISION_GUARDRAIL_DLEX_OUT_PROTOCOL_AUTHORIZATION_RECHECK_PROVIDER`, prevalecendo sobre `DECISION_GUARDRAIL_DLEX_OUT_PROVIDER`.
|
||
|
||
Caracteres diferentes de letras/números são convertidos em `_`, com nome em maiúsculas. O mesmo ponto pode definir `DECISION_<SUFIXO>_MIN_CONFIDENCE`; esse valor é independente dos limites já existentes no componente. Os limites existentes continuam sendo aplicados depois da integração.
|
||
|
||
## O que é híbrido
|
||
|
||
- Multi-intenção: o modelo atual extrai os objetivos e seus trechos, mantendo a ordem. O JEV escolhe a intenção de cada objetivo. Não há geração de trechos pelo JEV; trechos não literais são rejeitados. Isso pode custar mais que uma chamada atual isolada, por ser uma etapa adicional.
|
||
- Reconciliação: o modelo atual extrai candidatos e proveniência. JEV decide o tratamento de cada campo. A decisão não inventa valores e não substitui validação de negócio.
|
||
- Geração final, extração livre, resumos, RAG rewrite/compression, TOXOUT e FALLBACK de texto seguem no provedor atual. Autorização, alçadas, idempotência, pré-validação de negócio e execução seguem nas implementações existentes.
|
||
- Guardrail LLM genérico no JEV avalia se o texto original pode passar sem alteração. Se precisar de sanitização, deve bloquear; o JEV não fornece `sanitized_text` ou instruções textuais de reescrita. Reescritas já separadas no fluxo continuam generativas.
|
||
- Judges JEV não inventam rótulos ou justificativas de prosa: o retorno contém os campos necessários à decisão e motivo técnico fixo. RQLT/CSI usam score 0–10; judge genérico converte para 0–1. Os limites precisam de calibração antes de produção.
|
||
|
||
## Transporte, falhas e observabilidade
|
||
|
||
O cliente usa `POST https://ai-gateway.vercel.sh/v1/decisions` com `typesafe-ai/jev`, API key em `Authorization`, timeout de 15 segundos por padrão e perguntas choice/predicate/score. Usa a biblioteca padrão do Python; não adiciona dependências de produção. A chamada bloqueante roda em thread para não bloquear o event loop.
|
||
|
||
Respostas incompletas, tipos incompatíveis, opções não declaradas, números inválidos, confiança abaixo do limite e erros de transporte acionam o provedor atual uma vez quando `DECISION_FALLBACK_TO_CURRENT=true`. Sem fallback, a exceção chega ao tratamento de falha já existente do componente; isso não redefine automaticamente cada política fail-open/fail-closed. Confiança ausente em choice/score é zero e aciona fallback no limite padrão. Para predicates usa-se a probabilidade do resultado selecionado. Para várias perguntas usa-se o mínimo das confianças.
|
||
|
||
O custo de uma chamada JEV seguida de fallback inclui ambas as etapas. Respostas recebidas são contabilizadas no repositório de uso e no evento `decision.jev` quando o provedor original oferece esses recursos, mesmo quando a validação rejeita a resposta. Logs registram ponto, modelo, duração, uso e falha/fallback, sem imprimir prompts, chave ou corpo de erro HTTP. Não há geração Langfuse de chat para chamadas JEV; a integração publica evento de decisão.
|
||
|
||
## Validação
|
||
|
||
Teste isolado, sem dependências do projeto ou API real:
|
||
|
||
```sh
|
||
python3 tests/test_jev_transport_standalone.py
|
||
```
|
||
|
||
Testes adicionais de integração em ambiente com dependências instaladas:
|
||
|
||
```sh
|
||
PYTHONPATH=libs/agent_framework/src python -m pytest tests/test_jev_decisions.py tests/test_expected_input_semantic_classifier.py tests/unit/test_semantic_route_stickiness.py
|
||
```
|
||
|
||
O teste isolado cobre contratos, seleção, precedência de configuração, fallback, erros, confiança, transporte e análise sintática dos módulos. Resultado local: 17 testes isolados passaram, incluindo execução dos corpos reais de continuidade, roteamento, reconciliação e judge calibrado com transporte simulado. A suíte completa não foi executada: as dependências do projeto não estavam disponíveis e a tentativa de instalação não conseguiu obtê-las. A suíte completa e a qualidade/latência do modelo real precisam ser verificadas no ambiente de execução. Não foi feita chamada real ao JEV.
|
||
|
||
Fontes de protocolo consultadas: https://vercel.com/docs/ai-gateway/sdks-and-apis/openai-decisions e https://vercel.com/ai-gateway/models/jev.
|