jueves 10 / 07 / 2025

タイラーRetourner

Bazza

Bazza es una plataforma para restaurantes: pedidos desde el celular, un POS, mesas, inventario y caja. A mitad del camino, el problema interesante dejó de ser las pantallas y pasó a ser el asistente: algo con lo que un encargado pueda hablar un sábado por la noche con las manos ocupadas, y que de verdad cierre la caja.

El contexto no está en el prompt

¿Cómo haces que un agente «conozca tu app»? La forma habitual es describir la app en el prompt de sistema, pero así es como el modelo termina inventando un id de producto y escribiendo en el tenant equivocado.

Acá las herramientas se construyen con la sesión ya adentro:

typescript
const tools = [
  ...createAnalyticsTools(session),
  ...createPosTools(session),
  ...createInventoryTools(session),
  // 19 modules, all the same shape
]
Dices "cierra la caja". Better Auth resuelve quién eres y qué local.

Cada herramienta es un closure sobre la sesión autenticada: organización, local, rol, moneda y zona horaria. El modelo nunca pasa un id de local porque no hay parámetro que pueda equivocar, y como las herramientas llaman a los mismos servicios que llama el dashboard, no hay una segunda versión de la verdad que mantener en sincronía.

Una regla encima: no inventar números. Toda afirmación cuantitativa tiene que salir de una llamada a una herramienta.

Proponer, después crear

Cuando el asistente cree que deberías agregar un producto, no lo agrega de inmediato. Llama a propose_product, el dashboard muestra una tarjeta de vista previa con los campos y la razón detrás de cada uno, y create_product corre recién después de que aceptas. El perfil del negocio funciona igual.

Un error dicho con seguridad se vuelve una tarjeta que descartas, no una fila que tienes que ir a buscar y borrar. El modelo se puede equivocar donde equivocarse sale barato. Y cuando le falta un valor lo pide, tipado: un monto pide un número, y una elección se muestra como opciones.

El ritual del cierre de caja

Dices «cierra la caja». ¿Qué hace? Si hay más de una caja abierta te pregunta cuál, con el monto esperado al lado de cada nombre. Después calcula cuánto debería tener la caja a partir de cada pedido, pago y movimiento del día, y te lo dice.

No te pide contar el efectivo. Solo te pide la cuenta física si dices que hay una diferencia. Esa es la regla a la que vuelvo siempre: cero preguntas en el camino por defecto, y una pregunta solo donde el humano sabe algo que la base de datos no puede saber.

Por dentro

Google ADK, Gemini 2.5 Flash, herramientas como FunctionTool con parámetros de Zod, dentro del mismo servidor Elysia que todo lo demás. Bun y Moon, Postgres, Drizzle, y un dashboard con Vite.