jueves 10 / 07 / 2025

タイラーRetourner

Bazza

Bazza es una plataforma para restaurantes: pedidos desde el celular, un POS, mesas, inventario, caja. En algún punto de la construcción 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

La forma habitual de hacer que un agente «conozca tu app» es describir la app en el prompt de sistema. Después inventa un id de producto y escribe 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
]
sesiónconstruidas alrededorllamamismo caminouna tarjeta, no una filachat · vozservidorElysia · Better AuthagenteADK · Geminiservicioslos del propio panelherramientassesión adentro
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, zona horaria. El modelo nunca pasa un id de local, porque no hay parámetro de id de local que equivocar. Y las herramientas llaman a los mismos servicios que llama el dashboard, así que no hay una segunda versión de la verdad que mantener en sincronía.

Una regla encima: nunca 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 agrega un producto. Llama a propose_product, el dashboard muestra una tarjeta de vista previa con los campos y el porqué de cada uno, y recién después de que aceptas corre create_product. El perfil del negocio funciona igual.

Un error dicho con seguridad se vuelve una tarjeta que descartas, en vez de una fila que tienes que buscar y borrar. Al modelo se le permite equivocarse donde equivocarse sale barato. Y cuando le falta un valor lo pide, tipado: un monto pide un monto, una elección se muestra como opciones.

El ritual del cierre de caja

Dices «cierra la caja». 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 que lo cuentes si dices que hay una diferencia. Esa es la prueba a la que vuelvo siempre: el camino por defecto tiene cero preguntas, y una pregunta aparece 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, un dashboard con Vite.