About the project
Qué construí
Un agente de IA que concilia una factura contra su orden de compra —lee ambos documentos a partir de una foto, y te dice si coinciden— corriendo 100% en mi propia máquina, sin mandar nada a ninguna nube.
Cómo funciona
- Subís una imagen de la factura y una de la orden de compra.
- Un modelo multimodal chico (SmolVLM2, 500M parámetros, vía
@qvac/sdk) lee cada documento por separado. - En vez de pedirle "devolveme JSON" en texto libre, fuerzo al modelo a llamar a una herramienta con un esquema fijo (Zod). Si no la llama, o los datos no cumplen el esquema, lo trato como fallo de lectura — nunca como excusa para inventar un número.
- La comparación entre los dos documentos (proveedor, número de orden de compra referenciada, moneda, monto total con 1% de tolerancia, ítems) la hace código determinístico plano, no el modelo. El modelo lee; el veredicto lo calcula JS auditable.
- El mismo modelo redacta una explicación en un párrafo, pero a partir de la lista de discrepancias que el código ya calculó — no tiene permiso de inventar comparaciones nuevas.
- Si algún campo salió con confianza baja o no se pudo leer, se marca explícitamente en pantalla en vez de ocultarlo.
Arquitectura
- `/engine`: servidor Node local que carga el modelo y hace toda la inferencia con
@qvac/sdk. Esto es lo único que tiene que correr en la máquina del usuario. - `/web`: interfaz estática (HTML/CSS/JS sin build), deployable en Vercel. No hace ningún cómputo de IA — solo le habla a
localhost:8787, donde vive el motor.
Separé el proyecto así a propósito: la consigna exige que toda la inferencia corra en el dispositivo del usuario, y @qvac/sdk solo corre nativo sobre Node/Bare/Expo (no existe versión de navegador). Esta arquitectura me deja tener una interfaz prolija sin romper esa regla.
Capacidades de QVAC usadas
- Multimodal completion (
completion()conattachments) para leer las imágenes. - Tool calling como mecanismo de salida estructurada confiable, con validación Zod.
- Modelo:
SMOLVLM2_500M_MULTIMODAL_Q8_0+MMPROJ_SMOLVLM2_500M_MULTIMODAL_Q8_0.
Qué no hice (y por qué)
- OCR dedicado: elegí ir directo con el VLM para tener menos modelos que cargar y una demo más rápida.
- Soporte de PDF: por ahora solo acepto imágenes, porque no confirmé que
completion()acepte PDF directamente enattachments.
Hacki