Conferir nota fiscal contra o pedido sem deixar o modelo decidir Checking invoices against purchase orders without letting the model decide
Conferir nota contra pedido toma tempo e um erro pode virar pagamento indevido. Construí um piloto para separar duas tarefas: a IA extrai campos de documentos sem estrutura; regras conferem valores e decidem quando pedir revisão humana. O teste usa apenas notas sintéticas, então ainda não demonstra desempenho numa operação real. Checking invoices against orders takes time, and an error can lead to an improper payment. I built a pilot that separates two tasks: AI extracts fields from unstructured documents; rules check values and decide when human review is needed. The test uses only synthetic invoices, so it does not yet demonstrate performance in a real operation.
Palavras sublinhadas têm uma explicação rápida. Toque nelas. Underlined words have a quick explanation. Tap them.
Nota em XML vai por regra, sem modelo. Nota em PDF ou escaneada é lida por um modelo de linguagem (Gemini), que devolve os campos num formato fixo. O código confere essa leitura e compara com o pedido. Quando há divergência, um agente escreve ao comprador o porquê, consultando o pedido e o histórico do fornecedor. An XML invoice goes through rules, no model. A PDF or scanned invoice is read by a language model (Gemini), which returns the fields in a fixed format. Code checks that reading and compares it with the order. When there's a discrepancy, an agent writes to the buyer explaining why, looking up the order and the supplier's history.
Pagar errado não volta, então quem aprova ou barra é o código, nunca o modelo. O modelo entra só onde a regra não alcança, que é ler um documento sem estrutura. E o formato certo não garante o número certo: por isso toda leitura passa por contas que não precisam de gabarito, como quantidade vezes preço, soma dos itens e dígito verificador do CNPJ. A wrong payment doesn't come back, so code approves or blocks, never the model. The model only steps in where rules can't reach, which is reading an unstructured document. And the right format doesn't guarantee the right number, so every reading goes through checks that need no answer key: quantity times price, sum of items, and the CNPJ check digit.
Python com FastAPI expõe a conferência como API. O n8n recebe a nota por webhook, chama a API e separa em três filas: automático, comprador ou revisor. O agente que explica a divergência usa LangChain e só tem ferramentas de leitura, sem nenhuma que aprove ou altere a nota. Tudo sobe em Docker, com dados 100% sintéticos. Python with FastAPI exposes the check as an API. n8n receives the invoice through a webhook, calls the API and routes it to one of three queues: automatic, buyer or reviewer. The agent that explains the discrepancy uses LangChain and only has read tools, none that approve or change the invoice. Everything runs in Docker, with 100% synthetic data.
Em 10 notas escaneadas, o modelo leu certo 134 de 155 campos (86%), e nenhuma nota que devia ser barrada foi aprovada: 0 de 10, com margem que vai até 28%, porque a amostra é pequena. Num lote de 10 notas pelo fluxo completo, 5 passaram sem ninguém tocar, e só 1 das 5 que chegaram a uma pessoa foi por erro de leitura do modelo. Em 10 ataques escondidos no texto do fornecedor, o agente não mudou nenhuma decisão e não obedeceu nenhum. On 10 scanned invoices, the model read 134 of 155 fields correctly (86%), and no invoice that should have been blocked was approved: 0 of 10, with a margin that goes up to 28% because the sample is small. In a batch of 10 invoices through the full flow, 5 went through with no one touching them, and only 1 of the 5 that reached a person was due to a model reading error. Across 10 attacks hidden in the supplier text, the agent changed no decision and obeyed none.
O número que importa aqui não é o acerto por campo. Com 86% dos campos certos, nenhuma decisão perigosa passou, porque os erros caíram no texto e a regra depende dos números. O custo apareceu em outro lugar: metade das escaneadas foi para revisão sem precisar. Antes de trocar por um modelo maior, o degrau mais barato é pedir o XML ao fornecedor. Os números vêm de 10 notas por condição e um único layout de nota, então servem para comparar caminhos, não para prometer acerto em produção. The number that matters here isn't per-field accuracy. With 86% of fields right, no dangerous decision got through, because the errors landed in text and the rule depends on numbers. The cost showed up elsewhere: half of the scanned invoices went to review without needing it. Before switching to a bigger model, the cheapest step is asking the supplier for the XML. The numbers come from 10 invoices per condition and a single invoice layout, so they're for comparing approaches, not for promising accuracy in production.