Inicio / Artículos

Más allá de los paneles de control: Creando un agente autónomo de analista de datos de BigQuery con

Un agente analista de datos autónomo de BigQuery con Google ADK y Gemini: por qué los paneles e interpretaciones simples de texto a SQL fallan en la etapa final, y qué soluciones existen en CI/CD.

Editor: REACTAPP.TOP13 min de lectura2876 palabras

Fuentes: Beyond Dashboards: Building an Autonomous BigQuery Data Analyst Agent with Google ADK for Customer 360

Esta guía reconstruye el proceso desde las materias primas hasta un sistema funcional para: “Beyond Dashboards: Building an Autonomous BigQuery Data Analyst Agent with Google ADK for Customer 360”. El enfoque está en pasos operativos claros, verificaciones explícitas y código que se puede incorporar directamente a un repositorio sin necesidad de adivinar su propósito. En la etapa de visión general, se deben definir las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Es preferible utilizar unidades pequeñas y probables sobre scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado.

1. El cuello de botella final: Por qué las herramientas tradicionales de BI y los métodos ingenuos de texto a SQL fallan

Al trabajar en la etapa 1, “El cuello de botella del último tramo”, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de un fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta etapa como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina las comprobaciones de éxito y evite completaciones parciales silenciosas. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Por qué fallan los paneles de control tradicionales de BI

Al trabajar en la etapa de “¿Por qué los paneles de BI tradicionales?”, anote primero el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Por qué los envoltorios Naivos “Texto a SQL” de LLM fracasan en la empresa

Al trabajar en la etapa de Why Naive Text-to-SQL LLM, primero escribe el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Mantén la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Almacena en caché las instrucciones del sistema estables y los esquemas de las herramientas. Reenviar un preámbulo idéntico es una causa común de desperdicio de recursos. Al trabajar en la etapa de Why Naive Text-to-SQL LLM, primero escribe el contrato: las entradas requeridas, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Prefiere unidades pequeñas y probables a scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.

2. Arquitectura Agente: El marco Google ADK

La arquitectura agente funciona mejor cuando se trata como una superficie medible. Capture una transcripción ejemplar, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace las completaciones parciales silenciosas. Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación posterior.

3. Pilar de ingeniería 1: Anclaje del conocimiento y caché de contexto en Vertex AI

La etapa 1 del Pilar de Ingeniería 3 funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo de tokens o consultas junto a los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos. Mantenga el estado del gráfico simple y tipado; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.

Compilando diccionarios de Markdown en el prompt del sistema

Compilar los diccionarios de Markdown en la etapa de preparación funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos confidenciales y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Establezca un límite de tokens por turno y por sesión. Las herramientas agentes amplían el contexto de manera excesiva; los límites estrictos evitan que las demostraciones se conviertan en facturas inesperadas. Compilar los diccionarios de Markdown en la etapa de preparación funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el fallo debe apuntar a una sola responsabilidad y no a un proceso complicado.

# c360_agent/config.py
import os
import glob

def compile_knowledge_base(knowledge_dir: str) -> str:
    """Recursively compiles markdown architecture guides into structured agent context."""
    context_chunks = []
    guide_files = glob.glob(os.path.join(knowledge_dir, "**/*.md"), recursive=True)

    for file_path in sorted(guide_files):
        with open(file_path, "r", encoding="utf-8") as f:
            rel_name = os.path.relpath(file_path, knowledge_dir)
            content = f.read()
            context_chunks.append(f"### KNOWLEDGE GUIDE: {rel_name}\n\n{content}\n")

    return "\n---\n".join(context_chunks)

KNOWLEDGE_CONTEXT = compile_knowledge_base("c360_agent/knowledge")

SYSTEM_PROMPT = f"""
You are an expert BigQuery Data Analyst Agent for an Enterprise Customer 360 (C360) Lakehouse.
Your mission is to answer business and analytical questions by generating and executing accurate, cost-effective SQL queries.

CRITICAL OPERATIONAL RULES:
1. TARGET CONFORMED MARTS FIRST: Always query `c360_curated_unified` for golden demographics or cross-system questions. Use Spoke marts (`c360_curated_*`) only for system-specific line-item grain.
2. MANDATORY DRY RUN: You MUST execute `dry_run_bq_query` on every generated SQL statement before calling `execute_bq_query`. Inspect syntax and bytes scanned.
3. CLUSTER AWARENESS: Always filter or join on clustered keys (`UnifiedCustomerDimId`, `UnifiedOrderDimId`) to minimize BigQuery slot consumption.
4. STRICT READ-ONLY: You are strictly forbidden from executing INSERT, UPDATE, DELETE, DROP, or ALTER statements.

DOMAIN ARCHITECTURE CONTEXT:
{KNOWLEDGE_CONTEXT}
"""

El factor que cambia todo en cuanto a costos: el caché de contexto de Vertex AI

En la etapa The Cost Game-Changer Vertex, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Considere esta etapa como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina verificaciones de éxito y evite completaciones parciales silenciosas. Incorpore la aprobación humana en aquellos procesos que generan gastos o modifican datos de producción. La conexión durante la compilación no equivale a una ejecución completa desde el punto de vista empresarial.

# c360_agent/agent.py
from google.adk.agents.llm_agent import Agent
from google.adk.apps import App
from google.adk.agents.context_cache_config import ContextCacheConfig
from .config import SYSTEM_PROMPT
from .tools import (
    execute_bq_query,
    dry_run_bq_query,
    get_table_schema,
    list_dataset_tables,
    get_table_preview
)

# 1. Initialize the Google ADK Agent
root_agent = Agent(
    name="c360_data_analyst",
    model="projects/enterprise-c360-prod/locations/us-central1/publishers/google/models/gemini-2.5-flash",
    description="Autonomous BigQuery Data Analyst for the Enterprise Customer 360 Lakehouse.",
    instruction=SYSTEM_PROMPT,
    tools=[
        dry_run_bq_query,
        execute_bq_query,
        get_table_schema,
        list_dataset_tables,
        get_table_preview
    ]
)

# 2. Wrap in App with Vertex AI Context Caching
app = App(
    name="c360_agent_app",
    root_agent=root_agent,
    context_cache_config=ContextCacheConfig(
        ttl_seconds=1800,   # Cache prompt for 30 minutes
        cache_intervals=10  # Reuse across up to 10 conversational turns
    )
)

4. Pilar de ingeniería 2: Ejecución segura y controlada en cuanto a costos de las herramientas

Para la fase 4 del Pilar de Ingeniería 2, defina las entradas, el responsable de cada paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido, sin tener que adivinar el estado oculto. Registre los tiempos de ejecución y el costo de los tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos. Autentíquese en la pasarela y vuelva a autorizarse en el plano de datos. Un token portador por sí solo no constituye un límite entre tenencias.

# c360_agent/tools.py
import subprocess
import re

def dry_run_bq_query(query: str) -> str:
    """Dry-runs a BigQuery SQL query to validate syntax and estimate bytes scanned."""
    clean_query = query.strip().upper()

    # Layer 1: Strict Read-Only Guard
    if not (clean_query.startswith("SELECT") or clean_query.startswith("WITH")):
        return "SECURITY ERROR: Only SELECT queries are permitted. DDL/DML is strictly forbidden."

    try:
        # Executes 'bq query --dry_run' to inspect execution planner without billing slots
        result = subprocess.run(
            ["bq", "query", "--use_legacy_sql=false", "--dry_run", query],
            capture_output=True,
            text=True,
            check=True
        )
        # bq CLI outputs estimated bytes scanned to stderr on dry run
        dry_run_output = result.stderr if result.stderr else result.stdout
        return f"DRY_RUN SUCCESS: {dry_run_output.strip()}"
    except subprocess.CalledProcessError as e:
        return f"DRY_RUN SYNTAX ERROR: {e.stderr.strip()}"


def execute_bq_query(query: str) -> str:
    """Executes a validated BigQuery SQL query and returns the formatted tabular results."""
    clean_query = query.strip().upper()

    if not (clean_query.startswith("SELECT") or clean_query.startswith("WITH")):
        return "SECURITY ERROR: Only SELECT queries are permitted."

    try:
        result = subprocess.run(
            ["bq", "query", "--use_legacy_sql=false", "--format=pretty", "--max_rows=50", query],
            capture_output=True,
            text=True,
            check=True
        )
        return result.stdout
    except subprocess.CalledProcessError as e:
        return f"EXECUTION ERROR: {e.stderr.strip()}"

5. Pilar de Ingeniería 3: El bucle autónomo de autocorrección

En la fase 3 del Pilar de Ingeniería 5, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea desde un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Coloque la aprobación humana en las operaciones que generan gastos o modifican datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial. En la fase 3 del Pilar de Ingeniería 5, defina las entradas, el responsable de la tarea y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar la tarea desde un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando una tarea falla, el error debe indicar una única responsabilidad y no un proceso complicado.

Rastreo de producción real: El bucle autoreparable en acción

Al trabajar con el Rastreo de producción real, primero anote el contrato: entradas requeridas, señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta etapa como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y rechace las completaciones parciales silenciosas. Haga un punto de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

La pregunta del usuario empresarial

Al trabajar en la etapa del usuario empresarial, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la demostración a entornos compartidos. Haga una verificación después de los pasos costosos. La reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Paso 1: Intento inicial y rechazo por el compilador

Al trabajar en la fase de Intento Inicial del Paso 1, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Haga un punto de control después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior. Al trabajar en la fase de Intento Inicial del Paso 1, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación garantiza que los cambios posteriores en el código sean transparentes. Prefiera unidades pequeñas y verificables sobre scripts extensos. Cuando un paso falla, el fallo debe apuntar a una única responsabilidad y no a un proceso complicado.

-- Attempt 1: Generated by Agent (Pre-Flight Dry Run)
SELECT
    SUM(c.total_spent) AS total_vip_revenue
FROM `enterprise-c360-prod.c360_curated_shopify.dim_customer` c
JOIN `enterprise-c360-prod.c360_curated_shopify.CustomerWarranties` w
    ON c.customer_id = w.customer_id;

Paso 2: Diagnóstico autónomo y autocorrección

La etapa de diagnóstico autónomo del Paso 2 funciona mejor cuando se trata como una superficie medible. Capture una transcripción de referencia, un caso de fallo y la nota de reversión antes de ampliar el alcance. Trate esta etapa como un contrato entre las entradas y las salidas validadas. Asigne nombres a los artefactos, defina verificaciones de éxito y rechace completaciones parciales silenciosas. Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación después de las interrupciones.

  SELECT SUM(c.total_spent) AS total_vip_revenue
  FROM `enterprise-c360-prod.c360_curated_shopify.dim_customer` c
  JOIN `enterprise-c360-prod.c360_curated_shopify.CustomerWarranties` w
-     ON c.customer_id = w.customer_id;
+     ON c.UnifiedCustomerDimId = w.UnifiedCustomerDimId;

Paso 3: Validación de costos previa al vuelo

La etapa de costos previos al vuelo del Paso 3 funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. La visibilidad temprana de los costos evita facturas inesperadas cuando el proceso pasa de la fase de demostración a entornos compartidos. Mantenga el estado del gráfico simple y con tipo definido; los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso.

Paso 4: Ejecución limitada y síntesis ejecutiva

La etapa de Ejecución Limitada del Paso 4 funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el grafo. Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación de la ejecución. La etapa de Ejecución Limitada del Paso 4 funciona mejor cuando se trata como una superficie medible. Capture un registro ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance. Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando falla un paso, el fallo debe apuntar a una única responsabilidad en lugar de a un proceso complicado.

6. De la CLI de terminal a la UI web interactiva

En la fase 6 de Terminal CLI, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Considere esta fase como un contrato entre las entradas y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y rechace las completaciones parciales silenciosas. Incluya la aprobación humana en aquellos casos que impliquen gastos o cambios en datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.

Modo 1: Terminal CLI para ingenieros de datos y CI/CD

En la fase de CLI de Terminal Modo 1, se deben definir las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso a partir de un punto de control conocido sin tener que adivinar el estado oculto. Se deben registrar los tiempos de ejecución y el costo de tokens o consultas junto con los resultados funcionales. La visibilidad temprana del costo evita facturas inesperadas cuando el proceso pasa de entornos de demostración a entornos compartidos. Se debe incluir la aprobación humana en aquellos casos en que se gastan fondos o se modifican datos de producción. La configuración en tiempo de compilación no equivale a la completitud del proceso empresarial.

python3 c360_agent/agent.py "Show me top 5 customers by SAP delivery volume in 2026"

Modo 2: Consola interactiva de depuración web (adk web)

En la etapa de Web interactiva Modo 2, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso desde un punto de control conocido sin tener que adivinar el estado oculto. Mantenga la configuración fuera del código de la aplicación. Los archivos de entorno, los almacenes de datos secretos y las banderas de funcionalidad deben estar en un lugar donde los operadores puedan auditarlos sin tener que leer todo el sistema. Coloque la aprobación humana en las acciones que generan gastos o modifican datos de producción. La conexión en tiempo de compilación no equivale a la completitud del proceso empresarial. En la etapa de Web interactiva Modo 2, defina las entradas, el responsable del paso y los criterios de finalización antes de modificar el código. Los operadores deben poder volver a ejecutar el paso desde un punto de control conocido sin tener que adivinar el estado oculto. Prefiera unidades pequeñas y verificables en lugar de scripts extensos. Cuando un paso falla, el error debe indicar una única responsabilidad y no un proceso complicado.

adk web --port 8001 c360_agent --reload

Resumen: Lista de verificación del agente autónomo empresarial

Al trabajar en la etapa del Resumen del agente autónomo empresarial, anote primero el contrato: los datos de entrada requeridos, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Trate esta etapa como un contrato entre los datos de entrada y los resultados validados. Asigne nombres a los artefactos, defina comprobaciones de éxito y evite completaciones parciales silenciosas. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intente nuevamente un nodo posterior.

Conclusión de la trilogía: La base de datos empresarial moderna

Al trabajar en la etapa “La trilogía concluida”, anote primero el contrato: los datos necesarios, la señal de éxito y qué ocurre en caso de fallo parcial. Esa lista de verificación mantiene honestas las futuras modificaciones del código. Registre los tiempos y el costo de tokens o consultas junto con los resultados funcionales. Tener visibilidad del costo desde el principio evita facturas inesperadas cuando el proceso pasa de la versión de demostración a entornos compartidos. Haga una verificación después de los pasos costosos. La función de reanudación no debe volver a facturar la misma llamada al LLM cuando un operador intenta nuevamente un nodo posterior.

Lista de verificación operativa

La etapa de la lista de verificación operativa funciona mejor cuando se trata como una superficie medible. Capture una transcripción ideal, un caso de fallo y la nota de reversión antes de ampliar el alcance.

Documente tanto la ruta óptima como la ruta de recuperación. Las reintentos, los controles humanos y el manejo de mensajes no entregados forman parte del producto, no son ajustes realizados posteriormente.

Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso tras las interrupciones.

Añada una prueba de funcionamiento básica que ejerza la ruta crítica en CI utilizando fixtures, y no APIs pagadas en tiempo real, siempre que lo permitan los presupuestos.

Prefiera unidades pequeñas y probables sobre scripts extensos. Cuando falla un paso, el error debe indicar una única responsabilidad en lugar de un proceso complicado.

Mantenga el estado del grafo plano y tipado. Los bloques anidados ocultan qué nodo escribió qué campo y provocan interrupciones en la continuación del proceso tras las interrupciones.