Inicio / Artículos

De prototipo a producción con Agents CLI: Un agente para la aprobación de gastos

Construir un andamio, probar, evaluar e implementar un agente ADK en Cloud Run mediante Agents CLI, abordando en el proceso el seguimiento de actividades, el registro en BigQuery, las extensiones CI/CD y RAG.

Editor: REACTAPP.TOP12 min de lectura2799 palabras

Fuentes: Building AI Agents in 30 Minutes from Prototype to Production

Cualquiera que haya intentado enviar un agente de IA recientemente conoce este patrón. Durante el desarrollo se comporta bien: responde preguntas, utiliza las herramientas adecuadas y toma decisiones razonables. Luego alguien pregunta cuándo podrá ponerse en producción, y los días se pierden en procesos de Docker, autenticación, observabilidad e implementación.

El código del agente tardó unas pocas horas. La infraestructura necesaria para él está tomando semanas.

A continuación se explica paso a paso cómo crear e implementar un agente de tipo producción con Agents CLI, una herramienta de código abierto diseñada para simplificar ese proceso de implementación. El ejemplo es un agente de aprobación de gastos que incluye reglas empresariales, evaluaciones y una implementación en la nube; según la promoción de esta herramienta, todo esto tarda aproximadamente media hora en total. Considere esa cifra como el mejor escenario en una cuenta ya preparada.

La brecha de implementación

Crear un agente con el Agent Development Kit (ADK), LangChain o LlamaIndex es bastante sencillo. Pero ahí donde realmente comienza el trabajo es al ponerlo en producción. Un agente para entornos de producción suele necesitar todo lo siguiente.

Desarrollo local

  • el código del agente, que es la parte importante
  • una configuración de pruebas local
  • datos de prueba o stubs de API

Pruebas y evaluación

  • definiciones de casos de prueba
  • métricas y criterios de puntuación
  • una configuración con un LLM como evaluador
  • un conjunto de pruebas de regresión

Infraestructura para producción

  • una imagen de contenedor
  • configuración de despliegue en la nube para servicios como Cloud Run o Kubernetes
  • autenticación y autorización
  • gestión de secretos
  • un pipeline CI/CD

Observabilidad

  • rastreo de solicitudes
  • registro de prompts y respuestas
  • Seguimiento y análisis de costos
  • Monitoreo del rendimiento
  • Alertas de errores
  • Cada uno de estos elementos implica aprender otra herramienta, leer otro conjunto de documentación y conectar sistemas separados. Un asistente de programación puede ayudar con la lógica del agente, pero tiene dificultades para el despliegue porque no conoce las convenciones de su infraestructura, lo que genera rondas de depuración.

    Qué es Agents CLI

    Agents CLI es una herramienta que ofrece una única interfaz para todo el ciclo de vida del desarrollo de agentes en Google Cloud. Funciona en dos modos.

    1. Modo agente. Instala “habilidades” en un asistente de programación como Gemini CLI, Claude Code o Cursor. Estas habilidades enseñan al asistente patrones de despliegue para que tome decisiones correctas.
  • Modo manual. Usted mismo ejecuta los comandos de la CLI. Cada comando funciona por separado y no se necesita ningún asistente de IA.
  • La idea central es que, en lugar de que un asistente adivine las convenciones de despliegue, recibe contexto legible por máquina sobre cuándo usar cada destino de despliegue, cómo estructurar las evaluaciones y qué patrones de observabilidad funcionan mejor.

    El ejemplo: un agente de aprobación de gastos

    El agente revisa los informes de gastos de los empleados y decide si aprobarlos según la política de la empresa. Utiliza modelos Gemini a través de Vertex AI para razonar. Los requisitos son:

    • Aprobar automáticamente las solicitudes habituales por debajo de $50
    • Detener las presentaciones duplicadas
    • Marcar como sospechosas las situaciones inusuales, como cargos en fines de semana o proveedores desconocidos
    • Escalar los casos inciertos a revisores humanos
  • Una regla de seguridad estricta: nunca apruebe automáticamente nada que supere los $50
  • Requisitos previos

    Asegúrese de que estén instalados estos elementos:

    # Required tools
    Python 3.11+
    uv package manager
    Node.js (for skills installation)
    Google Cloud SDK (gcloud)
    

    También necesita un proyecto de Google Cloud con la facturación activada, el cual puede crear en la consola de Google Cloud.

    Instale la herramienta:

    uvx google-agents-cli setup
    

    Luego autentíquese con Google Cloud, defina su proyecto y active las API necesarias:

    # Authenticate with Google Cloud
    gcloud auth application-default login
    # Set your project ID
    gcloud config set project YOUR_PROJECT_ID
    # Enable required APIs
    gcloud services enable aiplatform.googleapis.com
    gcloud services enable run.googleapis.com
    gcloud services enable artifactregistry.googleapis.com
    

    Eso configura el acceso a Vertex AI para el agente, el cual llamará a los modelos Gemini a través de la API de Vertex AI.

    Paso 1: estructurar el proyecto

    En lugar de crear directorios y archivos de configuración a mano, permita que la CLI genere la estructura completa del proyecto.

    Con un asistente de programación como Gemini CLI, Claude o Cursor, basta con una instrucción:

    Build an expense approval agent using agents-cli.
    Auto-approve under $50, flag duplicates, escalate suspicious cases.
    Start with a prototype.
    

    El asistente lee las habilidades instaladas y crea un proyecto con la estructura adecuada. La ruta manual consta de tres comandos:

    agents-cli create expense-agent --prototype --yes
    cd expense-agent
    agents-cli install
    

    La bandera --prototype es importante. Genera únicamente el código del agente y la estructura de pruebas, excluyendo los componentes de despliegue como Docker, Terraform y CI/CD, que se añaden posteriormente. El layout generado se ve así:

    expense-agent/
    ├── app/
    │   ├── agent.py          # Agent definition
    │   └── app_utils/        # Telemetry helpers
    ├── tests/
    │   ├── eval/
    │   │   ├── evalsets/     # Test cases for LLM-as-judge
    │   │   └── eval_config.json
    │   ├── integration/
    │   └── unit/
    ├── pyproject.toml        # Dependencies managed by uv
    └── GEMINI.md             # Guidance for coding agents
    

    Paso 2: escribir la lógica de negocio

    A continuación, implemente la lógica de aprobación en app/agent.py. En ADK, al igual que en la mayoría de los frameworks de agentes, las herramientas son funciones simples de Python. La documentación es crucial, ya que el modelo la lee para decidir cuándo y cómo llamar a cada herramienta.

    Herramienta 1: verificar el historial de gastos.

    import json
    from adk.models import Gemini
    from adk.agents import Agent
    
    def check_expense_history(
        employee_id: str,
        vendor: str,
        date: str,
        amount: float
    ) -> str:
        """Check if this expense was already submitted.
        Args:
            employee_id: Employee identifier
            vendor: Vendor name
            date: Expense date (YYYY-MM-DD)
            amount: Expense amount in USD
        Returns:
            JSON string with duplicate check results
        """
        # In production, this would query your expense database
        # Using mock data for demonstration
        mock_history = [
            {"date": "2026-04-15", "vendor": "Coffee Shop", "amount": 8.50},
            {"date": "2026-04-15", "vendor": "Uber", "amount": 24.00},
        ]
        for past in mock_history:
            if (past["vendor"].lower() == vendor.lower() and
                past["date"] == date and
                abs(past["amount"] - amount) < 0.01):
                return json.dumps({
                    "is_duplicate": True,
                    "message": f"Duplicate found: ${amount} at {vendor} on {date}"
                })
        return json.dumps({
            "is_duplicate": False,
            "message": "No duplicate found"
        })
    

    Herramienta 2: obtener la política de la empresa.

    def get_company_policy(category: str) -> str:
        """Retrieve expense policy for a given category.Args:
            category: Expense category (meals, transport, lodging, etc.)
        Returns:
            JSON string with policy rules
        """
        policies = {
            "meals": {"auto_approve_threshold": 50.00},
            "transport": {"auto_approve_threshold": 50.00},
            "lodging": {"auto_approve_threshold": 0.00},  # Always escalate
            "default": {"auto_approve_threshold": 25.00}
        }
        policy = policies.get(category.lower(), policies["default"])
        return json.dumps(policy)
    

    Herramienta 3: solicitar ayuda a un humano.

    def escalate_to_human(
        expense_id: str,
        reason: str,
        context: str
    ) -> str:
        """Route expense to human approval queue.Args:
            expense_id: Unique expense identifier
            reason: Why this needs human review
            context: Additional context for reviewer
        Returns:
            Confirmation message
        """
        # In production, this creates a ticket or notification
        print(f"\n🚨 ESCALATED: {expense_id}")
        print(f"Reason: {reason}\n")
        return json.dumps({
            "status": "escalated",
            "ticket_id": f"REVIEW-{expense_id}"
        })
    

    Luego, las herramientas se conectan a un agente con instrucciones claras y restricciones de seguridad:

    root_agent = Agent(
        name="expense_approval_agent",
        model=Gemini(model="gemini-3.1-pro-preview"),  # Using Vertex AI
        instruction="""You are an expense approval agent. Review expenses and make
        approval decisions based on company policy.
        Process for every expense:
        1. Call get_company_policy() to check the category threshold
        2. Call check_expense_history() to verify no duplicate exists
        3. Make a decision: AUTO_APPROVE, ESCALATE, or REJECT
        Auto-approve only if ALL of these conditions are true:
        - Amount is under the threshold for that category
        - No duplicate found in expense history
        - Expense is from a business day (Monday-Friday)
        - Vendor appears legitimate
        Escalate to human if ANY of these conditions are true:
        - Amount is over the category threshold
        - Duplicate submission detected
        - Weekend expense without clear business justification
        - Uncertain about vendor legitimacy
        - Category is "lodging" (always requires human review)
        Safety rules (NEVER violate these):
        - NEVER auto-approve any expense over $50
        - NEVER approve without checking for duplicates first
        - ALWAYS provide clear reasoning for your decision
        - When in doubt, ESCALATE (false escalation is better than false approval)
        Response format:
        Decision: [AUTO_APPROVE | ESCALATE | REJECT]
        Reasoning: [Clear explanation of why you made this decision]
        Tools called: [Which tools you used]
        """,
        tools=[check_expense_history, get_company_policy, escalate_to_human],
    )
    

    Observe atentamente las reglas de seguridad indicadas en las instrucciones. Incluso si la política permitiría aprobar una comida de hasta 50 dólares, existe un límite estricto: el agente nunca aprueba automáticamente nada que supere los 50 dólares sin revisión humana. Esto evita errores costosos.

    Paso 3: probar localmente

    Inicie el entorno de pruebas ADK:

    agents-cli playground
    

    Abre una interfaz web en el puerto 8080 de localhost. Tres casos cubren los aspectos básicos.

    Aprobación rutinaria.

    Review this expense:
    Employee: emp-123
    Category: meals
    Vendor: Coffee Shop
    Date: 2026-04-18
    Amount: $12.50
    

    Comportamiento esperado: el agente llama a get_company_policy(), ve un umbral de $50, llama a check_expense_history(), no encuentra duplicados y aprueba la solicitud.

    Superando el umbral.

    Review this expense:
    Employee: emp-456
    Category: meals
    Vendor: Restaurant
    Date: 2026-04-18
    Amount: $85.00
    

    Comportamiento esperado: el agente eleva el caso porque la cantidad supera los $50.

    Envío duplicado.

    Review this expense:
    Employee: emp-789
    Category: transport
    Vendor: Uber
    Date: 2026-04-15
    Amount: $24.00
    

    Comportamiento esperado: el agente encuentra la duplicación en el historial de pruebas y procede a escalarla.

    Las pruebas manuales demuestran el flujo correcto, pero la preparación para producción requiere un enfoque más sistemático.

    Paso 4: evaluaciones estructuradas

    La mayoría de los desarrolladores omiten este paso, y es una de las principales causas por las que los agentes fallan en producción. Se necesitan casos de prueba con criterios claros de éxito o fracaso. La pregunta no es “¿esto parece correcto?”, sino “¿cumple con las políticas?”

    Edita tests/eval/evalsets/basic.evalset.json:

    {
      "eval_set_id": "expense_approval_eval",
      "name": "Expense Policy Validation",
      "eval_cases": [
        {
          "eval_id": "routine_approval",
          "conversation": [
            {
              "user_content": {
                "parts": [{
                  "text": "Review: emp-101, meals, Coffee Shop, 2026-04-18, $15.00"
                }]
              }
            }
          ],
          "session_input": {
            "app_name": "app",
            "user_id": "eval_user",
            "state": {}
          },
          "expected_tool_calls": ["get_company_policy", "check_expense_history"],
          "expected_output_keywords": ["approve", "approved"]
        },
        {
          "eval_id": "escalate_over_threshold",
          "conversation": [
            {
              "user_content": {
                "parts": [{
                  "text": "Review: emp-102, meals, Restaurant, 2026-04-18, $85.00"
                }]
              }
            }
          ],
          "session_input": {
            "app_name": "app",
            "user_id": "eval_user",
            "state": {}
          },
          "expected_tool_calls": ["get_company_policy", "escalate_to_human"],
          "expected_output_keywords": ["escalate", "human review"]
        },
        {
          "eval_id": "reject_duplicate",
          "conversation": [
            {
              "user_content": {
                "parts": [{
                  "text": "Review: emp-103, transport, Uber, 2026-04-15, $24.00"
                }]
              }
            }
          ],
          "session_input": {
            "app_name": "app",
            "user_id": "eval_user",
            "state": {}
          },
          "expected_tool_calls": ["check_expense_history"],
          "expected_output_keywords": ["duplicate", "escalate"]
        }
      ]
    }
    

    Ejecuta la evaluación:

    agents-cli eval run
    

    Ejemplo de salida:

    Running expense_approval_eval...
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ✓ routine_approval       policy_compliance: 1.0  safety: 1.0  tool_usage: 1.0
    ✓ escalate_over_threshold   policy_compliance: 1.0  safety: 1.0  tool_usage: 1.0
    ✓ reject_duplicate       policy_compliance: 0.9  safety: 1.0  tool_usage: 0.9
    Overall Pass Rate: 100% (3/3 cases)
    Average Scores: policy_compliance=0.97, safety=1.0, tool_usage=0.97
    

    La puntuación la realiza un LLM que actúa como juez, siguiendo las rúbricas de eval_config.json. Cuando un caso falla, se repiten las instrucciones del agente o la lógica de las herramientas hasta que todos los casos aprueben.

    Ese ciclo es el bucle eval-fix, la clave para contar con agentes fiables en producción. Sin pruebas de evaluación solo se puede esperar que el agente funcione, mientras que con ellas se sabe con certeza.

    Paso 5: despliegue

    El agente funciona y aprueba todas las evaluaciones, por lo que ha llegado el momento de desplegarlo. Primero se debe añadir la infraestructura de despliegue:

    agents-cli scaffold enhance --deployment-target cloud_run
    

    Eso genera un Dockerfile, una configuración de despliegue para Cloud Run y archivos Terraform. Luego se establece el proyecto y se realiza el despliegue:

    gcloud config set project YOUR_PROJECT_ID
    agents-cli deploy
    

    Esperar salida similar a esta:

    Building container image...
    Pushing to us-central1-docker.pkg.dev/your-project/agents/expense-agent...
    Deploying to Cloud Run...
    ✓ Deployment successful!
    Service URL: https://expense-agent-xyz123-uc.a.run.app
    Logs: https://console.cloud.google.com/run/detail/.../logs
    

    El tiempo total estimado desde agents-cli create hasta que el servicio esté operativo es de unos 30 minutos, aunque su primera ejecución dependerá de la configuración de la cuenta y las permisos.

    Paso 6: capacidad de observabilidad

    Cloud Trace se activa automáticamente, sin necesidad de configuración alguna. Para probar el agente desplegado:

    agents-cli run "Review expense: emp-501, transport, Uber, 2026-04-18, $15.00"
    agents-cli run "Review expense: emp-502, meals, Restaurant, 2026-04-18, $95.00"
    agents-cli run "Review expense: emp-503, lodging, Hilton, 2026-04-18, $200.00"
    

    Luego abra Cloud Trace para ver:

    • rastros completos de las solicitudes con un desglose de la latencia
    • la duración de cada llamada al LLM
    • los tiempos de ejecución de las herramientas
    • una línea de tiempo de extremo a extremo para cada solicitud

    Para depurar y analizar, active el registro de contenido:

    agents-cli infra single-project --project YOUR_PROJECT_ID
    

    Eso proporciona una cuenta de servicio para el registro, un bucket de Cloud Storage para almacenar las solicitudes y respuestas, un conjunto de datos de BigQuery para análisis, además de una actualización que permite al agente registrar cada conversación. Luego puedes consultar el comportamiento en producción en BigQuery:

    SELECT
      timestamp,
      JSON_EXTRACT_SCALAR(request_data, '$.user_content.parts[0].text') as request,
      JSON_EXTRACT_SCALAR(response_data, '$.decision') as decision,
      latency_ms
    FROM `your-project.agent_analytics.conversations`
    WHERE service_name = 'expense-agent'
    ORDER BY timestamp DESC
    LIMIT 10;
    

    Esto es vital para la depuración. Cuando alguien pregunta por qué el agente elevó el costo de una comida de 30 dólares, se consulta BigQuery para ver exactamente qué decidió y por qué.

    Qué hace único este conjunto de herramientas

    Hay cuatro decisiones de diseño que destacan.

    1. Habilidades como contexto legible por máquinas. Agents CLI ofrece algo más que comandos: proporciona habilidades que enseñan a tu asistente de programación a utilizarlos correctamente. Al ejecutar agents-cli setup se instalan siete de ellas:

    • google-agents-cli-workflow para el ciclo de vida del desarrollo
    • google-agents-cli-adk-code para los patrones de la API Python de ADK
    • google-agents-cli-scaffold para la estructuración de proyectos
    • google-agents-cli-eval para la metodología de evaluación
    • google-agents-cli-deploy para los destinos de despliegue
  • google-agents-cli-publish para el registro en Gemini Enterprise
  • google-agents-cli-observability para el rastreo y el registro de logs
  • El asistente los consulta cuando es relevante. En lugar de adivinar, sabe cuándo elegir Agent Runtime, Cloud Run o GKE, y conoce qué patrones de LLM como juez funcionan, por lo que no hay pruebas y errores con las métricas de evaluación.

    2. Evaluación por defecto. Cada proyecto estructurado incluye desde el principio infraestructura de evaluación: una carpeta tests/eval/evalsets/ para los casos, eval_config.json para las pautas de calificación y una configuración de LLM como juez. Esto refleja la realidad, ya que los agentes sin evaluación rara vez llegan a producción, y hacer de la evaluación el camino por defecto significa que los agentes se prueban antes del despliegue.

    3. Observabilidad por defecto. Cloud Trace se activa automáticamente en cada agente desplegado. Depurar un agente en producción sin registros de trazado es casi imposible. El registro de contenido y los análisis con BigQuery son opcionales a través de agents-cli infra single-project, pero el rastreo básico es obligatorio.

    4. Infraestructura gestionada por usted. La lógica del agente es interesante; las configuraciones de Docker, el middleware de autenticación y los archivos de Terraform no lo son. La CLI se encarga de la infraestructura para que pueda dedicar tiempo a hacer que el agente sea más inteligente.

    Ir más allá

    El agente de gastos cumple con los requisitos indicados, pero un despliegue real requiere algunos elementos adicionales.

    Datos en tiempo real. Sustituya el historial simulado por una consulta a su base de datos de gastos:

    import psycopg2
    
    def check_expense_history(employee_id, vendor, date, amount):
        conn = psycopg2.connect(DATABASE_URL)
        cursor = conn.cursor()
        cursor.execute("""
            SELECT * FROM expenses
            WHERE employee_id = %s
            AND vendor = %s
            AND date = %s
            AND amount = %s
        """, (employee_id, vendor, date, amount))
        # Process results...
    

    CI/CD. Generar un flujo de trabajo de GitHub Actions para entornos de pruebas y producción:

    agents-cli infra cicd --runner github-actions
    

    Crea un pipeline multientorno en el que los commits a main se despliegan en la fase de preparación y las versiones etiquetadas se despliegan en producción.

    Almacenamiento de sesiones. Agregue Cloud SQL para sesiones persistentes:

    agents-cli scaffold enhance --session-type cloud_sql
    

    Sistemas multiagente. La plantilla adk_a2a permite que los agentes especializados se coordinen, lo cual es adecuado para flujos de trabajo complejos como la respuesta a incidentes o las migraciones de código:

    agents-cli create coordinator-agent --agent-type adk_a2a
    

    Generación mejorada por recuperación de información. Construye un agente con búsqueda vectorial:

    agents-cli create docs-agent \
      --agent-type agentic_rag \
      --datastore agent_platform_vector_search
    

    Eso genera código para la ingesta de datos, integración de búsqueda vectorial y lógica de recuperación.

    Las técnicas en resumen

    Cada técnica aquí se enfoca en una etapa del ciclo de vida: estructuras básicas con una marca de prototipo para comenzar rápidamente, herramientas en forma de funciones Python documentadas, restricciones estrictas de seguridad en las instrucciones, pruebas en entornos locales, evaluaciones estructuradas con un bucle de corrección, infraestructura generada para el despliegue, y seguimiento además de registro de contenido para tener visibilidad. Juntas forman un camino desde el prototipo hasta la producción.

    La conclusión

    La brecha en el despliegue es real. Muchos proyectos de agentes se estancan no porque el agente sea deficiente, sino porque su implementación requiere demasiado trabajo de infraestructura.

    Agents CLI no resuelve todo. Todavía se necesitan prompts bien diseñados, herramientas adecuadas y pruebas exhaustivas. Lo que sí elimina es el trabajo administrativo relacionado con la infraestructura que mantiene a los agentes atrapados en entornos de desarrollo. El objetivo es que los flujos de trabajo de los agentes se sientan como si se estuviera ejecutando create-react-app y no como si se tuviera que armar la infraestructura a mano.