Eliminamos nuestro analizador de gastos en lenguaje natural
Nuestro analizador por reglas duró una semana: cuatro frases corrientes pusieron el dinero en la persona equivocada y una regla de rechazo reemplazó toda la pila de guardas.
Eliminamos un analizador que acabábamos de terminar de escribir. El primer intento de Dimesum de analizar gastos en lenguaje natural fue un motor de reglas, y cuatro frases corrientes lo jubilaron: dinner 12-08 400 se leyó como €12, ravioli 600 metió en el reparto a un miembro llamado Ravindra, kirana 500 cobró a un miembro llamado Kiran y refund -483.50 se convirtió en un cargo de €483.50.
Entender una frase es tarea del modelo y de nada más. Lo que reemplazó al motor de reglas es un único peldaño llamado amount_only: un solo número, devuelto únicamente cuando el texto contiene exactamente un candidato de dinero sin ambigüedad, y nunca una afirmación sobre personas. Dos candidatos significan que no hay importe. Una sola regla reemplazó una pila creciente de guardas.
Cuatro frases acabaron con el analizador de reglas
El analizador eliminado cubría todo el conjunto de entidades que especifica nuestro documento de diseño de IA: coincidencia de miembros y apodos, un léxico de exclusión, inferencia del pagador, un léxico de categorías y confianzas por campo ajustadas. Cada uno de los cuatro fallos siguientes tenía una solución obvia. Cada solución era una nueva guarda con su propio punto ciego.
| Lo que escribió el usuario | Lo que hizo el analizador | Por qué ocurrió |
|---|---|---|
dinner 12-08 400 | Leyó el importe como €12 | Un lector ve una fecha y un total. Una regex ve tres números y toma el primero. |
ravioli 600 | Metió en el reparto a un miembro llamado Ravindra | La coincidencia difusa de apodos puntuó un plato contra una persona. |
kirana 500 | Cobró a un miembro llamado Kiran | El mismo comparador, esta vez con el nombre de una tienda. |
refund -483.50 | Registró un cargo de €483.50 | Los dígitos sobrevivieron y el signo no, así que el dinero apuntó en sentido contrario. |
Dos de los cuatro son un mismo error con distinta ropa. La coincidencia difusa no distingue un plato de una persona ni una tienda de una persona, porque a nivel de caracteres ravioli y Ravindra de verdad se parecen. Exige una coincidencia de prefijo más larga y rompes ravi, que es justo el caso para el que existe el comparador.
Cada guarda que añades hace aparecer dos formulaciones más
Un analizador de reglas falla de una forma concreta: responde con seguridad y se equivoca. Un campo en blanco le cuesta al usuario un toque. Un reparto equivocado cuesta la confianza en el libro mayor, y en una app de seguimiento de gastos compartidos el libro mayor es el producto. Las cuatro filas de arriba no son casi aciertos, son errores de dinero.
La cinta sin fin es el verdadero argumento, no ningún defecto aislado. Añade una guarda de fechas y llega el caso del número de pedido. Añade una guarda de número de pedido y llegan los números sueltos, luego las cantidades, luego los números de mesa. La lista de guardas crece y nunca converge, porque el lenguaje natural no tiene un conjunto finito de formulaciones que enumerar.
La entrada en lenguaje natural es una función de IA, y nada en el repositorio de Dimesum encaja con ese patrón. La decisión se tomó el 2026-08-20, anotada junto con los cuatro fallos, para que nadie reconstruya las guardas por accidente.
Lo que se lanzó es un número y un rechazo
amount_only es el peldaño degradado de nuestro documento de diseño de IA implementado al pie de la letra. Ese peldaño dice «el formulario simple con relleno previo del importe mediante regex del lado del cliente», así que el nivel devuelve un importe y nada más: sin descripción, sin categoría, sin pagadores, sin participantes, sin exclusiones. No cuesta nada y no llama a nadie, y por eso las pruebas y CI se ejecutan sobre él.
La ambigüedad es un rechazo, no un desempate
Toda la regla vive en una función, extract_amount_minor. Una cifra vuelve solo cuando el texto contiene exactamente un candidato para ella, así que order 90210 dinner 400 y flat 402 rent 15000 devuelven blanco en lugar de elegir un ganador. Una cifra marcada con moneda cuenta como no ambigua incluso junto a números pelados, y por eso split 3 ways €1,200 sigue leyendo €1,200.
Una cifra negada no es ningún importe en lugar de su valor absoluto. -500, minus 200 y el (500) del contable vuelven todos vacíos, porque el campo es un cargo y conservar los dígitos descartando el signo apunta el dinero en sentido contrario al del texto. Los paréntesis cuentan solo cuando se cierran sobre la propia cifra, así que (500 each) queda como un inciso entre paréntesis.
La moneda decide la aritmética
Las unidades menores son la única representación que toma el dinero en Dimesum, así que el nivel convierte con una tabla de exponentes ISO 4217 en lugar de una multiplicación fija por 100. El yen japonés no tiene subunidad alguna, y ×100 infla un recibo de ¥1,200 cien veces. Una cifra más fina que la unidad más pequeña de la moneda se rechaza en lugar de redondearse, porque redondear un importe que alguien escribió es inventarlo.
Las palabras numéricas indias son parte de escribir una cifra, no de entender una frase. 1.2k, 2 lakh y 500/- se resuelven todas, igual que 1,200. Cualquier cosa por encima del importe máximo del libro mayor vuelve en blanco, así que una cifra mal tecleada deja un campo en blanco en lugar de desbordar un entero más adelante.
| Campo | Analizador de reglas (eliminado) | amount_only (activo) | Nivel con modelo (conectado, sin clave) |
|---|---|---|---|
| Importe | Adivinado a partir de varios números | Una cifra sin ambigüedad, si no en blanco | Leído en contexto |
| Descripción, categoría | Coincidencia por léxico | Siempre nulo | Extraído de la frase |
| Participantes, exclusiones | Coincidencia difusa de nombres | Siempre vacío | Resuelto a ids de miembros reales |
| Pagador | Inferido de la redacción | Siempre vacío | Nombrado, con un importe anulable |
| Confianza general | Ajustada por campo | Fija en 0.3 | Por análisis |
| Prompt informado | No existía ninguno | Nulo, no se leyó ningún prompt | Id y versión del prompt |
El peldaño activo nunca supera el umbral útil de 0.6
Nuestro contrato de análisis abandona un análisis por debajo de 0.6 de confianza general y lleva al usuario al formulario simple. amount_only informa 0.3 en cada respuesta, y la constante es estructural más que ajustada. Un importe solitario no es un análisis, así que el peldaño se queda en la mitad del umbral sea lo que sea que encuentre. Una constante para cada respuesta es lo que lo mantiene ahí: una puntuación por caso es una puntuación que alguien acaba empujando al alza.
El nivel tampoco informa ningún prompt. Tanto prompt_id como prompt_version vuelven nulos, porque el peldaño no leyó ningún prompt. Nombrar uno atribuiría cada resultado de evaluación a una versión de prompt que el nivel nunca vio, y el arnés de evaluación es el único instrumento autorizado a promover un peldaño a sugerencia de un toque, con un 95% de precisión en importe y participantes juntos.
Hay otros dos niveles declarados y ninguno está activo. El nivel cheap-fast tiene un adaptador de Groq para openai/gpt-oss-120b y ninguna clave; el nivel intermedio no tiene adaptador. Seleccionar cualquiera de los dos falla al arrancar en lugar de en la primera petición del usuario, porque un LLM factura por llamada y una dependencia facturable debe fallar cerrada.
Nada se registra automáticamente, así que un blanco cuesta un toque
Un campo en blanco cuesta tan poco solo porque ninguna captura en Dimesum puede escribir dinero. Una captura crea una sugerencia, una persona la confirma, y la confirmación es lo que crea el gasto. La decisión D5 del Brief establece la regla, y .go-arch-lint.yml la aplica: al contexto de ingesta se le niega cualquier dependencia de expense o ledger, así que una captura no puede registrar un diario ni por error. CI falla la importación, lo cual comprobamos añadiendo una.
La captura conserva el texto original haga lo que haga el analizador, y nombra qué campos quedan sin resolver. El cliente resalta esos blancos en lugar de mostrar un borrador inventado, que es la diferencia entre un analizador que no dice nada y uno que adivina. La confirmación deriva su id de gasto del id de la sugerencia, así que un doble toque se repite en lugar de cobrar dos veces.
La regla que vale la pena robar
Cuenta tus guardas, no tus errores. Una lista de guardas que crece cada semana te está diciendo que el trabajo es comprensión, y la comprensión le corresponde a un modelo. Nuestro siguiente paso es ejecutar el conjunto dorado de contracts/parse_expense/eval/ contra un nivel con modelo real, porque nada de esto se convierte en sugerencia de un toque sin ese veredicto.
Preguntas frecuentes
¿Por qué Dimesum eliminó su analizador de gastos basado en reglas?
Dimesum lo eliminó porque cuatro frases corrientes producían errores de dinero y cada guarda que añadíamos hacía aparecer dos formulaciones más. dinner 12-08 400 se leía como €12, ravioli 600 añadía a un miembro llamado Ravindra, kirana 500 cobraba a un miembro llamado Kiran y refund -483.50 se convertía en un cargo de €483.50. Entender una frase es tarea del modelo.
¿Qué devuelve realmente el nivel amount_only?
El nivel amount_only devuelve un número y nada más. Responde con un importe solo cuando el texto contiene exactamente un candidato de dinero sin ambigüedad, y nunca nombra a un participante, un pagador, una descripción ni una categoría. Dos candidatos significan que no hay importe alguno. Todo lo demás del contrato de análisis espera a un nivel con modelo.
¿Por qué amount_only informa una confianza de 0.3 en lugar de una puntuación real?
El 0.3 es estructural, no ajustado. Nuestro contrato de análisis abandona un análisis por debajo de 0.6 y lleva al usuario al formulario simple, y un importe solitario no es un análisis, así que el peldaño se queda en la mitad de ese umbral sea lo que sea que encuentre. Una única constante fija para cada respuesta impide que una puntuación por caso se empuje al alza más tarde.
¿Puede una captura en lenguaje natural escribir en el libro mayor sin una persona?
No. Una captura crea una sugerencia y una persona la confirma, según la decisión D5 del Brief. La regla se aplica en .go-arch-lint.yml, que niega al contexto de ingesta cualquier dependencia de expense o ledger, así que CI falla la importación si una captura llega a tocar un diario. Confirmar es lo que crea el gasto.
¿Qué pasa con el análisis de gastos en lenguaje natural cuando no hay ningún nivel con modelo disponible?
Dimesum degrada a amount_only y muestra campos en blanco. El nivel cheap-fast está conectado a openai/gpt-oss-120b de Groq y se envía sin clave, y el nivel intermedio no tiene adaptador, así que seleccionar cualquiera de los dos falla al arrancar en lugar de en la primera petición del usuario. La captura conserva el texto original de todos modos.
Artículos populares
- Libro mayor de solo anexión para saldos exactos9 min de lectura
- Por qué editar un gasto debe redefinir el reparto9 min de lectura
- Seis errores de dinero en gastos multidivisa10 min de lectura
- Cómo saldar cuentas de grupo en pocas transferencias5 min de lectura
- Dividir la cuenta cuando un plato no se compartió10 min de lectura