Guia essencial para garantir estabilidade ao adotar APIs de linguagem natural em produção (Microsoft Developer Community)
(techcommunity.microsoft.com)Princípios centrais
- Ao construir uma API de linguagem natural em produção, é essencial separar semantic parsing e execution
- O LLM deve ser usado apenas para converter linguagem natural em solicitações estruturadas canônicas (
canonical structured requests) - A linguagem natural deve ser tratada apenas como entrada, e não como contrato de API (a linguagem é frágil)
Problemas de usar linguagem natural diretamente
- Comportamento não determinístico (
nondeterministic behavior) - Lógica de negócio baseada em prompt → difícil de depurar e reproduzir
- Contrato de API implícito → pequenas mudanças alteram o funcionamento
- Ocorrência de falhas silenciosas (
silent failures), deixando o sistema vulnerável
Arquitetura: separação em duas camadas
1. Semantic Parse API (linguagem natural → transformação em estrutura)
- Aceita entrada de texto do usuário
- Extrai
intenteentitiescom LLM - Preenche um schema predefinido
- Quando faltar informação, faz perguntas de esclarecimento (
clarification) (não executar lógica de negócio) - Atua como um compilador (ex.: “blue backpack but cheaper” → {intent: “recommend_similar”, reference_product_id: “blue_backpack_123”, price_bias: -0.8})
2. Structured Execution API (estrutura → execução)
- Aceita apenas entrada estruturada
- Determinística, versionada e testável
- Não processa linguagem natural, atuando como backend estável
Elemento principal: Canonical Schemas
- Contratos por
intentdefinidos em código (campos obrigatórios/opcionais, intervalos de valores, regras de validação) - Absorvem variações da linguagem natural → garantem saída consistente
- Funcionam como a espinha dorsal do contrato da API
Schema Completion (Clarification)
- Quando faltar informação, retorna
needs_clarification(campos ausentes, pergunta direcionada, estado atual) - Gerencia memória com objeto de estado (a API é
stateless) - O cliente mantém a conversa enviando o estado → ao completar, executa
canonical_request
Orquestração: uso do LangGraph
- Modelagem de workflow estruturado (
intentclassification → extração deentities→ merge de schema → validação → roteamento para conclusão/clarification) - Decisões baseadas em código; o LLM apenas sugere
- Transições de estado claras, observabilidade e tentativas seguras de retry
Proteções: Confidence Gates
- Exigir
confidence scorena saída do LLM - Se ficar abaixo do limite, bloquear a execução e pedir esclarecimento (ex.: “the bag” ambíguo → baixa confiança → pergunta adicional)
- Evita interpretação silenciosa incorreta
Normalização: Lightweight Ontologies
- Baseadas em código (intenções permitidas, mapeamento de sinônimos, validação entre campos)
- Valores sugeridos pelo LLM → normalizados por código (ex.: “cheaper” →
price_bias: -0.7) - Em caso de inconsistência lógica, pedir esclarecimento (ex.: pergunta de prioridade entre barato + alta qualidade)
Considerações de desempenho
- Latência: classificação de
intent~40ms, extração deentities~200ms, validação 1ms → total de 250300ms - Aceitável em UX de chat, e mais barato do que o custo dos erros
Principais lições (Key Takeaways)
- Linguagem não é contrato de API; converta para estrutura
- O servidor deve ser dono da conclusão do schema
- Use LLM apenas para discovery e extraction, não para execução
- Segurança e determinismo vêm em primeiro lugar
- Baseado na experiência real de construção de sistemas com Azure OpenAI + LangGraph
Ainda não há comentários.