Caso real de Dribba en CityXerpa: tickets de soporte que tardaban 4 horas en resolverse hoy se cierran en 8 segundos. Sin alucinaciones, con función tool sobre BigQuery, razonamiento de Claude y un servicio Go sobre Cloud Run que orquesta todo.
No es magia. Es ingeniería de datos clásica con la pieza correcta de IA encima. Aquí está cómo lo hicimos, qué medimos y qué haríamos distinto hoy.
4 h → 8 s
Tiempo medio de resolución de tickets recurrentes
≈70%
Tickets resueltos por el agente sin escalado humano
120 k+
Usuarios activos servidos por la SuperApp
4 sem
De cero a producción con 2 ingenieros senior
El problema real
CityXerpa tenía toda la información en BigQuery: estado de servicios públicos, transacciones, horarios, tarifas, datos de transporte, alertas. El problema no era de datos. Era de acceso: el equipo de soporte tardaba minutos por consulta y los usuarios horas en obtener una respuesta clara.
La trampa habitual aquí es montar un RAG genérico sobre la documentación interna y descubrir, dos meses después, que el LLM alucina porque la pregunta real no está en un PDF, sino en una tabla con millones de filas.
La solución correcta no es vectorizar BigQuery. Es darle al LLM la capacidad de consultar BigQuery directamente mediante function calling, validando los resultados antes de generar la respuesta. RAG queda para los datos que de verdad son texto sin estructura.
Stack
Sin frameworks pesados, sin abstracciones de moda. Un orquestador, un razonador y un data warehouse — conectados con función tool y observabilidad real.
Orquestación
Servicio Go (chi / echo) desplegado en Cloud Run con autoscaling 0→N. Concurrencia con goroutines para fan-out a Claude y BigQuery en paralelo. Retries con backoff exponencial, circuit breaker y context propagation listos. p99 estable bajo carga, footprint <30 MB por instancia.
Cuándo escalar: Cloud Run cubre desde 0 hasta millones de requests/día sin tocar nada. Si necesitas workflows complejos con estado durable de horas/días (reintentos a una semana, sagas), migra ese path crítico a Temporal.
Razonamiento + tool use
Mejor disciplina de function calling que GPT-4o en queries de larga horizontalidad. Prompt caching nativo (-90% coste en system prompts repetidos). Latencia p50 más estable a alto throughput.
Cuándo escalar: Sonnet 4.x para el 80% de queries. Haiku para clasificación rápida y rate-limited paths. Opus solo para razonamiento multi-paso complejo.
Capa de datos
Datos estructurados a escala con SQL puro. Partitioning + clustering hace que la mayoría de queries devuelvan en <1 s. BI Engine para queries calientes.
Cuándo escalar: Para datos no estructurados (PDFs, FAQs, conocimiento textual) añadir una capa vectorial — BigQuery VECTOR_SEARCH si ya estás dentro, pgvector si no.
Caso real
120 000+ usuarios activos. Una app que cubre transporte, servicios públicos, comercio local, alertas y trámites — y un equipo de soporte humano que no escalaba al ritmo del producto.
Antes
4 h
Tiempo medio para resolver un ticket de soporte recurrente. La info estaba en BigQuery, pero atravesaba a un humano que copiaba/pegaba la query.
Después
8 s
El agente clasifica la consulta, llama al tool correcto contra BigQuery, valida el resultado y devuelve respuesta verificable. Cita la query SQL ejecutada para auditoría interna.
Cuándo escala
≈30%
De los tickets necesitan humano (casos legales, decisiones que no son datos puros, edge cases). El agente prepara el contexto antes de pasar el caso.
Cómo se construyó
Roadmap de mejoras
Diez mejoras concretas sobre el stack actual de CityXerpa. Cada una con coste, esfuerzo y métrica esperable. Sin maximalismo: solo lo que mueve la aguja.
El system prompt con el esquema de BigQuery, las reglas de negocio de CityXerpa y los ejemplos few-shot pesa varios miles de tokens. Activando prompt caching de Anthropic, esa parte se cobra al 10% del precio en cada llamada subsecuente dentro de la ventana de 5 minutos.
Esfuerzo estimado: 1 día
Un clasificador inicial con Claude Haiku decide si la query es trivial (FAQ tipo “¿cuándo abre el ayuntamiento?”), media (lookup en BigQuery con un solo join) o compleja (razonamiento multi-paso). Cada bucket usa un modelo distinto. La mayoría de tickets son triviales.
Esfuerzo estimado: 3 días
Las queries más repetidas a BigQuery (estado de servicios públicos, horarios, tarifas) se materializan como vistas refrescadas cada N minutos. El agente las consulta como tabla, no recalcula. Caching estructural sin Redis.
Esfuerzo estimado: 1 semana
El 30% de tickets que hoy escalan a humano son por información que vive en PDFs, manuales y artículos de soporte — no en BigQuery. Añadir una capa con embeddings (BigQuery VECTOR_SEARCH si quieres mantener el stack, pgvector si no) permite que el agente cite documentación con función tool dedicada.
Esfuerzo estimado: 2 semanas
Un dataset de 200–500 queries reales etiquetadas. Cada deploy del prompt o del modelo se prueba contra el dataset antes de salir a producción. Detecta degradaciones por cambios de modelo (ej: nueva versión de Claude más cauta) o de prompt antes de que las vea el usuario.
Esfuerzo estimado: 1 semana
Streaming de tokens desde Anthropic propagado al cliente vía Server-Sent Events. En Go, context.Context viaja desde el handler HTTP hasta la llamada a Anthropic — si el cliente cierra la conexión, cancela la inferencia y libera tokens facturables. Para queries que necesitan tool use antes de generar, microcopy explícito (“Consultando BigQuery…”) en vez de spinner ciego.
Esfuerzo estimado: 1 semana
Forzar respuestas JSON con schema en cada llamada con tool use, deserializar a struct Go con tags y fallar rápido con retry si la validación falla. El compilador Go captura el 80% de errores de schema antes de que lleguen a producción — superior a parsing dinámico con Zod en runtime.
Esfuerzo estimado: 3 días
Cada request del agente como un trace OpenTelemetry desde el handler Go: span por llamada a Claude, span por query a BigQuery, atributos con tokens consumidos, modelo usado y bytes scaneados. Exportado a Cloud Trace o Datadog. Una query de soporte tiene un coste medible — sin esto, no sabes si optimizar el prompt o el SQL.
Esfuerzo estimado: 1 semana
Para cargas con picos (campañas, eventos), separar el path síncrono (respuesta inmediata) del path asíncrono (notificaciones, embeddings, indexado). Pub/Sub como cola, workers Go con pool de goroutines acotado por semaphore — saturación controlada, sin tirar el servicio principal.
Esfuerzo estimado: 1 semana
Cuando el agente necesite ejecutar workflows que duran minutos u horas (escalado humano con SLA, reintentos diferidos, transacciones distribuidas con compensación), migrar ese path a Temporal. El SDK Go es maduro y se integra nativo con el servicio actual sin reescritura.
Esfuerzo estimado: 2–3 semanas (cuando aplique)
Otros casos de uso
Si tu empresa tiene datos en BigQuery (o Snowflake, Redshift, ClickHouse) y un equipo que pierde horas extrayendo respuestas en lenguaje natural, este patrón aplica.
El equipo no técnico pregunta en lenguaje natural y el agente devuelve la query SQL ejecutada, el resultado y el gráfico. Sustituye a los analistas para preguntas repetitivas.
Agentes que combinan reglas de negocio con datos de competencia y demanda histórica en BigQuery para sugerir precios en tiempo real.
El agente cruza señales del data warehouse, contextualiza la sospecha y abre o cierra el caso con justificación legible. Reduce ruido en los equipos de risk.
Resúmenes semanales o mensuales que combinan datos estructurados (KPIs en BigQuery) con narrativa generada por el LLM. Citan las queries que justifican cada cifra.
Agente sobre la base de conocimiento de RRHH y operaciones. Onboarding de empleados, dudas sobre vacaciones, gastos o políticas internas sin saturar el helpdesk.
El agente compara registros entre sistemas, identifica discrepancias y propone resoluciones. Para finance, ops y compliance.
FAQ técnica
Solo en parte. RAG clásico usa una base vectorial (embeddings) para recuperar texto relevante antes de pasarlo al LLM. Aquí la fuente principal es BigQuery con SQL — el LLM razona y llama a function tools que ejecutan queries. Es Tool-Augmented Generation con datos estructurados. Cuando hace falta texto no estructurado (PDFs, manuales) añadimos una capa vectorial al lado, no en lugar de.
Porque la mayoría de las queries de soporte de una SuperApp como CityXerpa son contra datos estructurados (estado de servicios, horarios, transacciones, tarifas), no contra texto. Para eso, una vector DB es la herramienta equivocada — añade complejidad y no aporta. Cuando hay texto sin estructura (FAQs largos, manuales, regulación), entonces sí: capa vectorial específica para ese subconjunto.
Tres razones prácticas: (1) Function calling más disciplinado y predecible — Claude rara vez inventa parámetros que no existen; (2) Prompt caching nativo desde Sonnet 3.5 que hace que los system prompts grandes sean baratos; (3) Latencia p50/p99 más estable bajo carga. Para clasificación rápida, Haiku gana en coste/latencia. En proyectos donde el cliente ya está en GCP, Gemini Flash es razonable como segundo modelo en routing.
Go nos da en producción tres cosas que ni Python ni n8n entregan al mismo coste: (1) latencia p99 estable bajo carga sin GIL ni runtime warmup; (2) concurrencia nativa con goroutines para fan-out paralelo entre Claude y BigQuery sin frameworks asíncronos pesados; (3) binario único de <30 MB que arranca en <100 ms en Cloud Run, lo que hace el escalado 0→N transparente. Python encaja para prototipado y notebooks; n8n para flujos visuales que el equipo de ops va a tocar. Para un servicio en path crítico de cliente con SLA real, Go es el default razonable.
Tres palancas: (1) Prompt caching de Anthropic, que reduce el coste del system prompt en 90% dentro de la ventana de 5 min; (2) Model routing — Haiku para clasificación, Sonnet para la mayoría, Opus solo para razonamiento complejo; (3) Materialized views en BigQuery que evitan llamadas repetidas para queries comunes. En CityXerpa, estas tres palancas combinadas reducen el coste medio por ticket por debajo de 0,01 €.
Sí, con matices. El servicio Go y BigQuery se despliegan en la VPC del cliente (servicio Go en GKE privado o Cloud Run con VPC Service Controls; BigQuery via VPC Service Controls también). Para Claude, Anthropic ofrece el modelo via AWS Bedrock o Google Vertex AI, ambos con VPC peering — los datos no salen de tu cloud. Para clientes con restricción total (banca, defensa), usamos un LLM auto-alojado (Llama 3.1 70B sobre vLLM en GKE) como fallback, asumiendo que la calidad cae un escalón respecto a Claude Sonnet.
Para un agente focalizado sobre un dominio acotado (un tipo de tickets, un set de tablas BigQuery), de 4 a 8 semanas con dos ingenieros senior. El cuello de botella nunca es el código — es definir bien el alcance, conseguir acceso a los datos, y montar el dataset de evaluación con queries reales. El primer mes el ROI todavía no está claro; a partir del segundo, suele ser obvio.
Un agente bien definido con BigQuery + Claude + servicio Go en Cloud Run y un dominio acotado parte de 35.000–50.000 € en desarrollo. Si requiere capa vectorial añadida, integraciones con sistemas legacy o eval pipeline maduro, sube a 60.000–90.000 €. Soporte y evolución mensual desde 3.500 €/mes según volumen y SLA.
¿Tienes datos en BigQuery y un caso parecido?
Nos cuentas el caso, nos enseñas el esquema y te decimos si tiene sentido un agente, qué stack encaja y qué coste tiene a tu volumen real. Si no encaja, lo sabes en la misma llamada.
Equipo 100% senior in-house en Barcelona y Andorra · Respuesta en 24 h