Ir al contenido
synsema ¿por qué?
← Todos los casos
Caso 4 · Medido el 2026-10-16 · Synsema 0.6.44 · mismos datos y mismo modelo de los dos lados

Qué facturas se pueden pagar sin una persona

Si el modelo extrae bien una factura, ¿alcanza su confianza para pagarla sin revisión?

0 vs 7

de 7 facturas riesgosas atrapadas: la confianza del LLM contra Jev

El LLM leyó bien las 60 facturas, y su propia confianza habría pagado los duplicados. Jev atrapó 7 de 7.

Confianza propia del LLM0 de 7Validación aritmética0 de 7Jev, calibrado (judge)7 de 7
Facturas que necesitaban una persona, atrapadas por cada regla de aprobación7 de 60 necesitaban revisión: 2 duplicados y 5 totales corregidos a mano, todos bien leídos.

El problema

Las áreas de cuentas a pagar ya usan LLM para leer facturas. Con los modelos actuales, leer dejó de ser lo difícil.

Lo difícil es decidir qué se paga sin que nadie lo mire. Un duplicado leído perfecto no se paga, y un total corregido a mano hay que verificarlo.

Qué construimos

  • 60 facturas sintéticas de empresas ficticias, en texto tipo OCR, con sus respuestas correctas. 28 traen dificultades reales: ruido de OCR, fechas ambiguas, moneda extranjera, descuentos, totales corregidos a mano, duplicados.
  • DeepSeek extrae los campos e informa su propia confianza. Una validación aritmética revisa los totales. Jev, un modelo juez calibrado, responde cuatro preguntas sobre el documento y lo extraído en una sola llamada.
  • Lo que no se aprueba espera en approve, la compuerta humana de Synsema, con un enlace de un solo uso enviado por webhook.

Resultados

Reglas de aprobación sobre 60 facturas
ReglaAprueba solasAtrapa las 7 a revisarSe pagarían sin revisarFalsas alarmas
Confianza propia del LLM ≥ 0,960 (100 %)0 de 7las 70
Solo validación aritmética60 (100 %)0 de 7las 70
Jev (≥ 0,85 por campo, ambiguo < 0,5)46 (77 %)7 de 7ninguna7 (todas con ruido de OCR)
La compuerta humana (probada)
PruebaResultado
POST /approvals/{id} con un token falso, como intentaría un agente403, la aprobación sigue esperando
Rechazar el duplicado con su enlace200, decisión registrada
Usar el mismo enlace otra vez404, un solo uso
Correr sin terminal (CI, un agente)se rechaza al instante

El código, lado a lado

Lo habitual
Lo habitual: pedirle al LLM su propia confianzaEl campo de confianza lo escribe el mismo modelo que extrae.
let SYSTEM be "You extract data from invoices (OCR text, it may contain errors such as O for 0, l for 1, S for 5). Reply ONLY with JSON containing: supplier (text, as it appears at the top, in normal capitalization), number (text NNNN-NNNNNNNN), date (YYYY-MM-DD; dates are written day/month/year), currency (ARS or USD), subtotal, discount (0 if none), vat, total (numbers without thousands separators; the valid TOTAL DUE), and confidence: a number from 0 to 1 saying how sure you are that EVERYTHING extracted is correct."
cases/04-invoice-approval/lib/invoices.syn · desde la línea 5
Synsema
Synsema + Jev: cuatro juicios calibrados, una llamadaProbabilidades sobre el documento y lo extraído.
    let j be jev.systemone({"document": f.text, "extracted": remove(e, "confidence")}, {
        "total_ok": {"type": "noul", "instructions": "The extracted total is exactly the valid total due on the document"},
        "date_ok": {"type": "noul", "instructions": "The extracted date (YYYY-MM-DD) is the issue date of the document, read as day/month/year"},
        "supplier_ok": {"type": "noul", "instructions": "The extracted supplier is the company issuing the invoice"},
        "ambiguous": {"type": "noul", "instructions": "The document has contradictory data, hand corrections, is a duplicate, or has reading errors that cast doubt on some value"}})
cases/04-invoice-approval/lib/invoices.syn · desde la línea 31
Synsema: lo dudoso espera a una personaBajo serve, approve nunca se resuelve sola.
agent Approver
    let ok be approve message within 30m
    -- One key per invoice: state_* has no atomic read-modify-write, and several agents decide at once
    state_set(`decision:{fid}`, {"approved": ok, "t": now()})
cases/04-invoice-approval/review.syn · desde la línea 24

Por qué Synsema

  • judge devuelve probabilidades calibradas sobre las que se puede decidir. La confianza que declaró el modelo fue de 0,9 o más en todo, duplicados incluidos.
  • approve es una primitiva del lenguaje. Bajo serve nunca se resuelve sola: queda en cola, una persona recibe un token de un solo uso y se rechaza al vencer el plazo.
  • Un agente no puede fingir una aprobación. No hay camino en el código para que un programa apruebe su propio pago.

Lo que no resuelve

  • Facturas sintéticas en texto. Con PDF o fotos reales, la extracción no va a ser perfecta.
  • El juicio calibrado no reemplaza las reglas de negocio. Una copia de una factura ya pagada sacó 0,47 y pasó a Jev; la atrapó la regla «mismo proveedor y número ya procesados».
  • Los umbrales (0,85 y 0,5) se fijaron antes de medir. Con datos reales, conviene calibrarlos sobre un conjunto aparte.

Reproducirlo

git clone https://github.com/synsema/why-synsema && cd why-synsema
# cases/04-invoice-approval
python cases/04-invoice-approval/data/generate_invoices.py
synsema run cases/04-invoice-approval/process.syn
SYNSEMA_HUMAN_WEBHOOK=http://127.0.0.1:8105/channel SYNSEMA_HUMAN_PUBLIC_URL=http://localhost:8105 \
  synsema serve cases/04-invoice-approval/review.syn            # approval queue on :8105

github.com/synsema/why-synsema/tree/main/cases/04-invoice-approval

Compartir