Agentes de ventas sin cuentas de cabeza — el modelo elige, el código suma

Una distribuidora de productos de limpieza vende por WhatsApp con un agente de ventas nuestro. El agente atiende, arma la cotización en PDF con el catálogo del negocio y deja el lead en el CRM. Funciona bien con lo de todos los días: escalones de precio por volumen, IVA en el granel, envío según la zona.
Hace unos días el equipo cargó una promo: un paquete de 19 piezas a $799. A precio de lista son $948, o sea $149 de ahorro. El agente la ofreció bien. La cotización salió mal.
La promo que no cabía en el cotizador
El cotizador tenía una guarda: el agente puede cambiar el precio de máximo 8 renglones por cotización. La pusimos para que el modelo no se salte el catálogo y empiece a inventar precios renglón por renglón.
Un paquete de 19 piezas con un precio cerrado choca contra esa guarda. El agente hizo lo que haría alguien con prisa: repartió el descuento a mano. Su explicación fue literal «el mechudo a $64 y el resto proporcional». La suma le cuadró a $799, pero:
- el PDF mostraba precios unitarios que no existen en el catálogo;
- el cliente no veía el descuento por ningún lado, sólo un total más bajo;
- en el CRM no quedaba rastro de qué promo se aplicó ni por qué.
El problema de fondo era de diseño. Le pedimos al modelo dos cosas distintas en un mismo paso: decidir qué cobrar (qué productos, qué promo vigente) y hacer la cuenta. Lo primero le sale bien. Lo segundo lo resolvió con aritmética inventada para cuadrar un número.
El modelo decide qué cobrar; el código hace la cuenta
El arreglo fue un campo descuento sobre la cotización entera, con exactamente una de
tres formas y un motivo obligatorio:
Con eso el reparto queda así:
- Cada renglón va a su precio de catálogo, validado como siempre. La guarda de los 8 renglones se queda igual.
- El código resta el descuento al final. Si viene
precio_final, calcula el ahorro contra la suma real de los renglones. Si hay IVA de granel, se calcula sobre lo que de verdad se cobra. - El PDF pinta el desglose: precio normal → «Ahorro por promoción · motivo» → subtotal. El cliente ve los $149 que se ahorra.
- El motivo queda en la nota del CRM junto al folio y el total. Quien audite después sabe qué promo se aplicó y quién la autorizó.
Si el agente manda dos formas a la vez, un porcentaje mayor a 100 o un motivo vacío, el
cotizador rechaza la cotización con un error que el modelo puede leer y corregir. Y la
instrucción de la skill es corta: para un paquete se usa descuento, nunca precios por
renglón, y sólo se aplican promos vigentes o descuentos que autorizó el equipo.
Los identificadores también los pone la plataforma
El mismo día salió un segundo detalle, más chico. El equipo mandó la imagen de la promo por WhatsApp para que el agente la guardara junto con la promo. La imagen llegaba al turno sin un id de archivo, y el agente, para cumplir, inventó uno. La promo quedaba ligada a un archivo que no existía.
Ahora la plataforma registra la foto como archivo antes de que empiece el turno y le pasa al agente su id real. El agente ya no tiene que adivinarlo.
La lección es la misma que con el descuento: los números que importan, sean montos o identificadores, los pone código determinista. El modelo sólo los usa.
Qué hace la comunidad: mandar la cuenta a una herramienta
No somos los únicos en llegar aquí. El tutorial de IBM para conectar herramientas MCP a watsonx Orchestrate lo dice directo: los modelos son buenos para interpretar, planear y adaptarse, pero «no están diseñados para una ejecución precisa o confiable» en muchas tareas, y para esas el agente debe llamar a una herramienta de confianza. Su ejemplo usa un agente de matemáticas que delega los cálculos a tools MCP.
Hay servidores MCP hechos sólo para eso:
- Calculator MCP ofrece aritmética con decimales de precisión configurable (Decimal.js).
- PrecisionCalc MCP está pensado para finanzas: calcula cada valor monetario con el
módulo
decimalde Python, nunca con flotantes, y devuelve la fórmula y los insumos usados junto al resultado. - codecalc va más lejos: un servidor MCP que corre código en 31 lenguajes, hace matemática simbólica exacta y verifica lógica, para que el agente obtenga una respuesta correcta en lugar de una adivinada.
Es una buena señal: la idea de sacar la aritmética del modelo ya es práctica común.
Nuestra postura: la mejor calculadora es el script con tus reglas
Una calculadora genérica resuelve 948 − 149 sin errores. Lo difícil de una cotización
está en las reglas: qué precio aplica en qué escalón, qué productos llevan IVA, cuánto
cuesta el envío a esa zona, qué promo está vigente hoy y cómo se presenta en el PDF.
Ninguna calculadora MCP sabe eso.
Nuestros agentes ya corren código en su propia caja. Por eso su «calculadora» es el script de la skill de cotizar, con el catálogo, los escalones, el IVA, el envío y ahora los descuentos escritos en código. El modelo arma un JSON con qué cobrar; el script valida, calcula, genera el PDF y registra en el CRM. Si algo no cuadra, el script lo rechaza antes de que el cliente lo vea.
En resumen
Un agente de ventas que cotiza necesita separar dos trabajos:
- El modelo decide qué cobrar: productos, cantidades y qué promo vigente aplica.
- El código hace la cuenta con las reglas del negocio: catálogo validado, escalones, IVA, envío y descuentos con motivo obligatorio.
- El documento muestra el desglose y el motivo queda auditado en el CRM.
- Los identificadores los pone la plataforma, nunca el modelo.
Cuando el cotizador no tiene una forma correcta de expresar algo, el modelo improvisa una. Lo que toca es darle esa forma en código.