Como funciona "Sugerir via IA" (pirâmide C1→C2→C3)
A sugestão de mapping roda em 3 camadas: heurística instantânea, embeddings semânticos com cache, e LLM só pros campos ambíguos. Reduz latência -70% e custo -75% em mappings grandes (SAP OData 300+ fields).
A pirâmide em 3 camadas
Quando você clica em Sugerir via IA, o backend roda 3 camadas em sequência:
Camada 1 — Heurística determinística (instantânea, $0)
Resolve matches óbvios sem chamar IA:
- Match exato literal (
SalesOrder→SalesOrder) - Match normalizado (
sales_order→SalesOrder) - Match por sufixo nav (
to_Item.OrderedQuantity→OrderedQuantity) - Levenshtein curto (typos de até 2 caracteres em nomes ≥4 chars)
Resolve tipicamente 25% dos campos em <50ms.
Camada 2 — Embeddings semânticos (Voyage voyage-code-3)
Vetoriza cada campo (nome + descrição) num espaço numérico de 1024 dimensões e calcula similaridade do cosseno. Aceita matches ≥0.86 de confiança.
- Otimizado pra identifiers técnicos (SAP OData, EDIFACT, NF-e, X12)
- Cache permanente em
ai_embeddings_cache— depois da primeira execução, vetor é gratuito - Multilingual: campos com descrições em PT/EN/ES cruzam idiomas sem perda
Resolve tipicamente 50% adicionais em ~2s.
Camada 3 — LLM (Anthropic Sonnet 4.6)
Só os ambíguos residuais chegam aqui. Como o volume caiu de 100% pra ~25%, o LLM termina mais rápido e custa menos.
Progresso na UI
A barra mostra cada camada conforme termina:
- "Etapa 1: regras exatas (76/302)..."
- "Etapa 2: similaridade semântica (+148)..."
- "Etapa 3: IA pros ambíguos (78 restantes)..."
- "Concluído em ~10s"
O que NÃO muda
- Campos editados manualmente (
destination_fieldpreenchido sem marcaai_suggested) NUNCA são sobrescritos. Frontend filtra ANTES de mandar. - Resultado é IDÊNTICO independente do idioma logado — input vem do catálogo, não da UI traduzida.
- Fallback 1:1 só atua se a pirâmide inteira falhar.
Telemetria
Cada execução loga em
ai_usage_events (visível em /admin/costs):
pyramid.heuristic_resolved/embedding_resolved/llm_resolved/unmappedelapsed_ms_heuristic/elapsed_ms_embedding/elapsed_ms_llmvoyage_cache_hits/voyage_cache_missesllm_cache_read_tokens/llm_cache_creation_tokens
Atualização (jun/2026): compilador determinístico é o caminho primário
Desde jun/2026, o "Sugerir IA" é resolvido primeiro pelo compilador determinístico: campos de origem e destino anotados com a MESMA semântica (conceito) são casados e o fio EDI (slot, qualifier, formato, cardinalidade) é montado lendo a spec (XSD/EDMX) do catálogo — sem palpite. A pirâmide C1→C2→C3 descrita acima vira o fallback pra campos sem anotação/regra. A IA também anota campos novos → conceito (auto-concept), e a partir daí o compilador gera sempre.
Histórico de versões
- V4.5
Codex audit 30/05 (follow-up #387/#392): o contextFingerprint do cache de sugestão usava syn:${synonyms.total} (apenas o COUNT). Editar um synonym in-place ou delete-um+add-um mantém o count igual → cache de sugestão servia o resultado antigo (filter_lookup / matches cross-standard desatualizados). Fix: SynonymsIndex ganha campo fingerprint = hash sha256 de conteúdo de TODOS os synonyms ativos (ordenado por id; inclui source/dest_format, patterns, is_regex, confidence, concept keys). suggest-mapping passa a usar syn:${synonyms.fingerprint}. Qualquer edição/add/delete muda o hash → cache invalida corretamente. A troca do formato da key (syn:N → syn:hash) auto-invalida as entradas antigas (recompute único, sem bump de CACHE_VERSION). Mesma filosofia do sample:${hash} já presente. Helper puro synonymsFingerprint() exportado. +5 tests (estável a reordenação; edit in-place e delete+add com count igual mudam o hash). 2369 tests verdes.
5/30/2026 · updated
- V4.4
Auditoria Codex 30/05 — 4 fixes na pirâmide + mapping. [P1] apply-mapping passa a pular is_ignored=true (não só transform=ignore) — regra duplicada marcada pelo dedup não executa mais no runtime (fixture Carrefour tinha 6). [P1] toggle-mapping-status persiste field_mappings mutado (dedup is_ignored + _needs_review) na ativação — antes gravava só status e descartava o dedup do strict validator. [P2] cache da pirâmide (suggest-mapping) inclui sample payload (hash) + synonyms (count) no contextFingerprint — antes 1ª execução sem sample cacheava sem filter_lookup e mensagens reais pegavam stale. [P2] progress legado mapeia os 4 stages da pirâmide (heuristic/semantic/intelligence/qualifier) — antes travava no stage 1 (cinematic loader já estava correto). +1 test (is_ignored skip). 2362 tests.
5/29/2026 · updated
- V4.3.5
[BACKFILL 30/05 — sessão 28/05 não foi consolidada no dia, reconstruída do git] Pirâmide de sugestão "forte" (PRs #363-#370). #364 mega-PR: threshold 0.75 + reciprocity 5 + topK 15 + prefix_canonical, refator 4 camadas (heuristic/semantic/intelligence/qualifier), P0 hardening (bloquear ativação com path fora catálogo, role guard partner, needs_review<0.6). #366 FASE 1+2+3: required gap-domínio (3 INVOIC conditional) + 7 concepts. #368 D1-D5: catálogo X12_850 (30+ segments, novo) + UI /admin/synonyms + fix chunk LLM + regenerate. #369 synonyms cross-standard 12→72. #370 G1+G2 dedup destinos + regenerate aplica strict validator. #363 categorização required_kind EDIFACT. Versão entre V4.3 (26/05) e V4.4 (29/05).
5/28/2026 · updated
- V4.3
Quando a IA gera uma sugestão que é dropada pelo histórico do tenant (par removido ≥2× e nunca aceito), o operador agora vê: (1) banner topo do mapping editor com resumo "N fontes com sugestões dropadas", (2) badge âmbar inline na linha do source não-mapeado, (3) click no badge abre popover com lista dos destinos dropados + counts, (4) botão "Reinserir como rule" adiciona a rule ao state — salvar marca como aceito e desbloqueia o par permanentemente. Funciona simétrico em ambas as views (source/destination).
5/26/2026 · updated
- V4.2
K do agregado cross-tenant comum (PR G-D) virou parametrizável via env COMMON_MAPPINGS_MIN_TENANTS (default 3, floor 2). Em base grande dá pra subir pra K=5 conservador; em homologação K=2 pra testar; K=999 desliga sem deploy. Log do K efetivo aparece no runtime sempre que há resultado.
5/26/2026 · updated
- V4.1
Épico G / PR G-F (último do épico): a IA passa a analisar os campos agrupados por estrutura (cada segmento/loop — LIN, NAD, to_Item — junto com seus filhos) em vez de em blocos de tamanho fixo. Com o loop inteiro visível de uma vez, a inferência entre campos do mesmo grupo melhora (ex: quantidade + unidade + preço da mesma linha). Encerra o Épico G (qualidade da sugestão de mapping): cache + required-first, aprendizado por cliente, exemplos reais + conversões por tipo, defaults comuns entre clientes, qualifier-aware (filter_lookup) e agora chunking semântico.
5/26/2026 · updated
- V4.0
Épico G / PR G-E: a IA agora resolve mapeamentos que dependem de qualifier sozinha. Em EDIFACT/X12/IDoc e arrays SAP, muitas vezes só UM elemento de uma lista deve alimentar um campo (ex: dentre vários PricingElement, o ConditionType=PR00 é o preço bruto que vira o amount da linha da fatura). A pirâmide passa a sugerir o transform filter_lookup com a condição já montada, inferindo o valor do qualifier dos exemplos reais (V3.8). Como isso quase sempre mexe em valor financeiro, a regra vem marcada para revisão — o operador confirma o qualifier antes de ativar. Quando a IA não consegue identificar o discriminador, mantém direct (nunca cria regra quebrada).
5/26/2026 · updated
- V3.9
Épico G / PR G-D: defaults comuns entre clientes (privacy-safe). Quando um par de formatos já é usado por vários clientes, a pirâmide aproveita os mapeamentos mais comuns como ponto de partida para um cliente novo (cold-start) — só pares usados por pelo menos 3 clientes distintos entram (k-anonimato), e apenas nomes de campo, nunca dados ou identidade de ninguém. O aprendizado do próprio cliente (V3.7) sempre tem prioridade sobre o default comum. Documentado em compliance/llm-data-handling.
5/26/2026 · updated
- V3.8
Épico G / PR G-C: a pirâmide passa a usar VALORES REAIS do payload do cliente como contexto. (1) Amostra até 2 valores reais por campo (do histórico de mensagens do mapping), truncados e REDIGIDOS (CPF/CNPJ/email/telefone/IBAN/cartão), e mostra ao modelo como dica — melhora a inferência de formato e de regra de conversão (ex: vê /Date(...)/ e sugere date_format; vê texto longo indo pra campo curto e sugere truncate). (2) Detecção de transform agora também roda local (sem enviar dado ao modelo) a partir dos mesmos exemplos + comparação de tipos/comprimento. Privacidade: máx 2 valores por campo, truncados a 40 chars, redigidos; documentado em compliance/llm-data-handling.
5/26/2026 · updated
- V3.7
Épico G / PR G-B: a pirâmide agora APRENDE com o uso real de cada cliente, sem ninguém editar prompt. (1) Mapeamentos que o cliente aceitou/refinou ≥2× para o mesmo par de formatos viram "examples provados" e passam a ser preferidos pela IA. (2) Mapeamentos que o cliente removeu ≥2× (e nunca aceitou) entram numa lista de bloqueio — a IA para de sugeri-los (reforçado no prompt e por um filtro pós-processamento). Tudo isolado por cliente (tenant). Resultado: quanto mais o cliente usa, mais a IA acerta de primeira e menos repete erros já corrigidos. Coerente com o cache de sugestões (o aprendizado invalida o cache quando muda).
5/26/2026 · updated
- V3.6
Épico G / PR G-A: (1) Cache de sugestões por par-catálogo (mapping_suggestions_cache) — quando o mesmo par source↔destino + conjunto de campos + modelo já foi sugerido, a 2ª chamada vem do cache: resposta instantânea e custo LLM zero. Invalida sozinho quando o catálogo muda. (2) Required-first: campos OBRIGATÓRIOS do destino agora são priorizados pela IA — sinalizados [REQUIRED] no prompt + garantidos no candidate set (top-K) com teto pra não inflar catálogos com muitos obrigatórios. Telemetria de cobertura de obrigatórios no /admin/costs. Resultado: pirâmide mais rápida em retries e maior acerto nos campos que travam a integração.
5/26/2026 · updated
- V3.5
Wizard admin NÃO cria mais message_type stub. Salva default_source_format + default_destination_format na integration; DeriveMappingDialog usa pra pré-preencher form. resolve-conflict não bumpa version (alinha com save-mapping). 250 envelope fields marcados autoFilled em 10 catálogos EDIFACT — IA não sugere rule pra esses.
5/25/2026 · updated
- 1.6
Sessão 24/05: Toast 422 + botão Forçar publish (#256) + Cobertura desc + breadcrumb nested (#257). Destrava bug "não deixa publicar" silencioso + UX clarity nos cards e tree.
5/24/2026 · updated
- 1.5
downgradeHeaderToNested determinístico: pra cada rule to_X[*].field, se catalog tem to_Item[*].to_X[*].field equivalente, migra automaticamente. Aplicado em postProcess junto com applyArraySyntax. Resolve SAP V2 header-collection vazia silenciosa.
5/22/2026 · updated
- 1.4
canonicalSourcePath prioriza loopPath (V3 catalog) quando cardinality=many. injectWildcardOnAllNavs recursivo substitui regex 1-nv. Cobre paths nested 2+ níveis sem perder [*]. mapping-editor anchor click usa loopPath. UI Bug A: rules transform=ignore+ai_suggested escondidas, filtro "rejected" dedicado.
5/22/2026 · updated
- V3.4
DTO de catalog fields agora propaga os 6 campos V3 (qualifiedName/loopPath/loopRoot/cardinality/segmentPath/compositePath). View estruturada destino/source funciona corretamente em mappings com catálogo qualificado.
5/21/2026 · updated
- V3.3
IA prefere LOOP quando source é ARRAY. Prompt reforçado + filtro pós-LLM com heurística semântica source loopRoot → dest loopRoot. Fallback LIN. Flag _needs_review quando múltiplos candidatos competem.
5/21/2026 · updated
- V3.1
Fix raiz alucinação IA na criação de mapping. /api/edi-hub/suggest-format agora consulta o catálogo do banco (catalog_user_messages) antes de cair no fallback IA — mensagens SAP OData populadas via teste de conexão usam os fields REAIS do SAP em vez de a IA inventar 284 fields plausíveis. Bonus: /api/edi-hub/create-message-type valida payload contra catálogo DB antes da pirâmide LLM, com telemetria de contaminação.
5/21/2026 · updated
- V3.2
Source cardinality auto-correct na pirâmide LLM. Quando catálogo marca um source field como cardinality=many (loops, ex: to_Item.X), o sistema agora força automaticamente o loopPath canônico (to_Item[*].X) — antes a IA emitia o nome plano e o save rejeitava com violação de cardinalidade. Auto-cleanup paralelo em save-mapping cobre mappings criados antes do fix raiz.
5/21/2026 · updated
- V3.0
IA gerador emite destination_field qualificado direto do catálogo V3 (loopPath/qualifiedName em vez de name plano). Auto-correção V3 upgrade legacy → qualified.
5/21/2026 · updated
- 2.3.0
SEMANTIC_THRESHOLD 0.86 → 0.78 pra cross-standard ODATA↔EDIFACT — cosine ficava em 0.70-0.82 e LLM cobria gap a 100× o custo (#102). Voyage payment method ativo (vide FT-AI-COSTS).
5/19/2026 · updated
- 2.2.0
Sessão 15/05 tarde: 10 PRs em cadeia. Bug crítico LLM (max_tokens=3000 truncava JSON em chunks 60 sources × ~150 tokens/objeto = 9k output). Fix #13: 8000 + parser strip markdown fence. + 4 bugs qualidade SAP→EDI (#14): transforms inválidos alinhados com enum real, [*] auto-injetado em nav refs, CONSTANT VALUES section no few-shot pra BEG.BEG01, isSapSandboxUrl supprime sap-client header em URLs api.sap.com. + UX (#15-#17): barra de progresso por estágio, label da próxima camada em vez da que terminou, unificação Sem destino + Ignorados. + Observabilidade (#11-#12): embedding_error, llm_error, raw_text_sample, parsed_count, with_dest_count em metadata.
5/15/2026 · updated
- 2.1.0
Probe SAP cursor field (#164) + overlay DB no route (PR #6) + cursor field do $metadata real no wizard + editor (#160) + SSE pra destino genérico (PR #6). Cobre 100% do Bug #1 do relatório original.
5/15/2026 · updated
- 2.0.0
Pirâmide IA C1→C2→C3: (C1) heurística determinística com exact+normalize+suffix_nav+Levenshtein; (C2) embeddings Voyage voyage-code-3 (1024 dims) com cache permanente em ai_embeddings_cache + greedy assignment; (C3) LLM Sonnet 4.6 só nos ambíguos com cap paralelismo=4 + max_tokens=3000. SSE streaming start→layer(3)→done. Frontend filtra manuais antes do POST. -70% latência / -75% custo / preserva edits manuais.
5/15/2026 · updated
- 1.0.0
IA de sugestão de mapping com chunking (60 source fields/chunk), atalho 1:1 quando sourceFormat===destinationFormat, fallback non-destrutivo que preserva destination_field existente. Resolve prompt-size errors em catálogos grandes (302+ source × 696+ dest) e elimina destruição de mapeamentos válidos quando IA falha.
5/8/2026 · new