Du prototype à la production avec Agents CLI : un agent d’approbation des dépenses
Créez un squelette, testez, évaluez et déployez un agent ADK sur Cloud Run à l’aide d’Agents CLI, en abordant au passage le suivi des activités, l’enregistrement des données dans BigQuery, ainsi que les extensions CI/CD et RAG.
Sources: Building AI Agents in 30 Minutes from Prototype to Production
Tout ceux qui ont tenté de déployer un agent IA récemment connaissent ce schéma. En phase de développement, il se comporte bien : il répond aux questions, utilise les outils appropriés et prend des décisions sensées. Puis quelqu’un demande quand il pourra être mis en production, et des jours s’écoulent dans les processus liés à Docker, à l’authentification, à l’observabilité et aux pipelines de déploiement.
Le code de l’agent n’a nécessité que quelques heures. L’infrastructure qui l’entoure, en revanche, demande des semaines.
Ce qui suit est une présentation pas à pas de la création et du déploiement d’un agent de type production à l’aide d’Agents CLI, un outil open source conçu pour gérer ces tâches de déploiement. L’exemple présenté est un agent d’approbation des dépenses, doté de règles métier, d’évaluations et d’un déploiement dans le cloud ; selon les promesses de l’outil, ce processus prend environ une demi-heure du début à la fin. Considérez cette durée comme un scénario idéal sur un compte préparé.
L’écart de déploiement
Créer un agent à l’aide du Agent Development Kit (ADK), de LangChain ou de LlamaIndex est assez simple. C’est lorsqu’il s’agit de le mettre en production que les défis apparaissent. Un agent destiné à la production nécessite généralement tout ce qui suit.
Développement local
- le code de l’agent, qui constitue la partie intéressante
- une configuration de test locale
- des données fictives ou des stubs d’API
Test et évaluation
- des définitions de cas de test
- des métriques et des critères d’évaluation
- une configuration utilisant un LLM en tant que juge
- un ensemble de tests de régression
Infrastructure de production
- une image de conteneur
- une configuration de déploiement dans le cloud, par exemple pour Cloud Run ou Kubernetes
- l’authentification et l’autorisation
- la gestion des secrets
- un pipeline CI/CD
Observabilité
- le suivi des requêtes
- l’enregistrement des prompts et des réponses
Chaque élément signifie de devoir apprendre un nouvel outil, lire un nouveau ensemble de documents et relier des systèmes distincts. Un assistant de codage peut aider avec la logique des agents, mais il a du mal avec le déploiement car il ne connaît pas les conventions de votre infrastructure, ce qui entraîne des séries de débogage.
Qu’est-ce que Agents CLI ?
Agents CLI est un ensemble d’outils qui offre une seule interface pour l’intégralité du cycle de vie du développement d’agents sur Google Cloud. Il fonctionne en deux modes.
- Mode agent. Vous installez des « compétences » dans un assistant de codage tel que Gemini CLI, Claude Code ou Cursor. Ces compétences enseignent à l’assistant les modèles de déploiement afin qu’il prenne des décisions correctes.
L’idée principale est que, au lieu qu’un assistant devine les conventions de déploiement, il dispose d’un contexte lisible par machine indiquant quand utiliser chaque cible de déploiement, comment structurer les évaluations et quels modèles d’observabilité fonctionnent le mieux.
Exemple : un agent d’approbation des dépenses
Cet agent examine les rapports de dépenses des employés et prend une décision d’approbation conformément à la politique de l’entreprise. Il utilise des modèles Gemini via Vertex AI pour raisonner. Les exigences :
- approuver automatiquement les demandes courantes inférieures à 50 $
- détecter les soumissions dupliquées
- mettre en évidence des schémas inhabituels tels que des dépenses en fin de semaine ou des fournisseurs inconnus
- transférer les cas incertains à des examinateurs humains
Prérequis
Vérifiez que ceux-ci sont installés :
# Required tools
Python 3.11+
uv package manager
Node.js (for skills installation)
Google Cloud SDK (gcloud)
Vous avez également besoin d’un projet Google Cloud avec la facturation activée, que vous pouvez créer dans la console Google Cloud.
Installez l’outil de développement :
uvx google-agents-cli setup
Ensuite, authentifiez-vous auprès de Google Cloud, configurez votre projet et activez les API nécessaires :
# 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
Cela configure l’accès à Vertex AI pour l’agent, qui appellera les modèles Gemini via l’API Vertex AI.
Étape 1 : structurer le projet
Au lieu de créer manuellement des dossiers et des fichiers de configuration, laissez la CLI générer l’ensemble de la structure du projet.
Avec un assistant de codage tel que Gemini CLI, Claude ou Cursor, une simple demande suffit :
Build an expense approval agent using agents-cli.
Auto-approve under $50, flag duplicates, escalate suspicious cases.
Start with a prototype.
L’assistant lit les compétences installées et crée un projet doté de la structure appropriée. La méthode manuelle consiste en trois commandes :
agents-cli create expense-agent --prototype --yes
cd expense-agent
agents-cli install
Le flag --prototype est important. Il génère uniquement le code de l’agent et la structure de test, en omettant les éléments de déploiement tels que Docker, Terraform et CI/CD, qui sont ajoutés par la suite. Le layout généré ressemble à ceci :
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
Étape 2 : écrire la logique métier
Ensuite, implémentez la logique d’approbation dans app/agent.py. Dans ADK, comme dans la plupart des frameworks d’agent, les outils sont des fonctions Python simples. La documentation est essentielle, car le modèle la lit pour déterminer quand et comment appeler chaque outil.
Outil 1 : vérifier l’historique des dépenses.
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"
})
Outil 2 : obtenir la politique de l’entreprise.
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)
Outil 3 : faire appel à un humain.
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}"
})
Ensuite, les outils sont connectés à un agent doté d’instructions claires et de contraintes de sécurité :
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],
)
Examinez attentivement les règles de sécurité indiquées dans les instructions. Même si la politique permettrait d’approuver un repas jusqu’à 50 $, une limite stricte s’applique : l’agent n’approuve jamais automatiquement quoi que ce soit dépassant 50 $ sans vérification humaine. Cela permet d’éviter des erreurs coûteuses.
Étape 3 : tester localement
Démarrez l’environnement de test ADK :
agents-cli playground
Cela ouvre une interface web sur localhost au port 8080. Trois cas couvrent les bases.
Approbation de routine.
Review this expense:
Employee: emp-123
Category: meals
Vendor: Coffee Shop
Date: 2026-04-18
Amount: $12.50
Comportement attendu : l’agent appelle get_company_policy(), constate un seuil de 50 $, appelle check_expense_history(), ne trouve aucune dépense doublée et approuve la demande.
Dépassement du seuil.
Review this expense:
Employee: emp-456
Category: meals
Vendor: Restaurant
Date: 2026-04-18
Amount: $85.00
Comportement attendu : l’agent passe l’affaire en haut de la hiérarchie car le montant dépasse 50 $.
Soumission dupliquée.
Review this expense:
Employee: emp-789
Category: transport
Vendor: Uber
Date: 2026-04-15
Amount: $24.00
Comportement attendu : l’agent trouve la duplication dans l’historique de simulation et en signale l’escalade.
Les tests manuels permettent de valider le scénario idéal. Cependant, une mise en production nécessite une approche plus systématique.
Étape 4 : évaluations structurées
La plupart des développeurs sautent cette étape, ce qui est l’une des principales raisons pour lesquelles les agents échouent en production. Il faut des cas de test avec des critères clairs de réussite ou d’échec. La question n’est pas « Est-ce que cela semble correct ? », mais plutôt « Cela respecte-t-il les politiques établies ? »
Modifiez 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"]
}
]
}
Exécutez l’évaluation :
agents-cli eval run
Résultat d’échantillon :
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 notation est effectuée par un LLM agissant en tant que juge, en se basant sur les critères de notation présents dans eval_config.json. Lorsqu’un cas échoue, on itère sur les instructions de l’agent ou sur sa logique d’outil jusqu’à ce que tous les cas réussissent.
Cet ensemble de démarches constitue la boucle évaluation-correction, essentielle pour des agents fiables en environnement de production. Sans évaluations, on espère simplement que l’agent fonctionne ; avec elles, on en est certain.
Étape 5 : déploiement
L’agent fonctionne et réussit toutes les évaluations, il est donc temps de le déployer. Tout d’abord, ajoutez l’infrastructure nécessaire au déploiement :
agents-cli scaffold enhance --deployment-target cloud_run
Cela génère un Dockerfile, une configuration de déploiement pour Cloud Run et des fichiers Terraform. Ensuite, configurez le projet et effectuez le déploiement :
gcloud config set project YOUR_PROJECT_ID
agents-cli deploy
Attendez-vous à un résultat de ce type :
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
Le temps total indiqué pour que agents-cli create mette en service un service actif est d’environ 30 minutes, bien que votre première exécution dépende de la configuration du compte et des permissions accordées.
Étape 6 : observabilité
Cloud Trace est activé automatiquement, sans aucune configuration requise. Pour tester l’agent déployé :
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"
Ensuite, ouvrez Cloud Trace pour voir :
- les traces complètes des requêtes avec une ventilation par latence
- la durée de chaque appel à l’LLM
- les temps d’exécution des outils
- un chronogramme du début à la fin pour chaque requête
Pour le débogage et l’analyse, activez le journalisation du contenu :
agents-cli infra single-project --project YOUR_PROJECT_ID
Cela prévoit un compte de service pour l’enregistrement, un bucket Cloud Storage pour le stockage des questions et des réponses, un ensemble de données BigQuery pour les analyses, ainsi qu’une mise à jour permettant à l’agent d’enregistrer chaque conversation. Vous pourrez ensuite interroger le comportement en production dans 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;
C’est essentiel pour le débogage. Lorsque quelqu’un demande pourquoi l’agent a élevé le montant d’un repas de 30 dollars, vous interrogez BigQuery pour connaître précisément sa décision et les raisons qui l’ont motivée.
Ce qui distingue cet outil
Quatre choix de conception se détachent.
1. Les compétences en tant que contexte lisible par la machine. Agents CLI offre plus que des commandes : il fournit des compétences qui enseignent à votre assistant de codage comment les utiliser correctement. L’exécution de agents-cli setup installe sept d’entre elles :
google-agents-cli-workflowpour le cycle de vie du développementgoogle-agents-cli-adk-codepour les modèles d’API Python ADKgoogle-agents-cli-scaffoldpour la structure des projetsgoogle-agents-cli-evalpour la méthodologie d’évaluationgoogle-agents-cli-deploypour les cibles de déploiement
google-agents-cli-publish pour l’enregistrement de Gemini Enterprisegoogle-agents-cli-observability pour le suivi et le journalisationL’assistant les consulte lorsque c’est pertinent. Au lieu de deviner, il sait quand choisir Agent Runtime, Cloud Run ou GKE, et il connaît les schémas LLM-as-judge qui fonctionnent, ce qui évite les essais-erreurs avec les métriques d’évaluation.
2. Évaluation par défaut. Chaque projet prédéfini inclut dès le départ une infrastructure d’évaluation : un dossier tests/eval/evalsets/ pour les cas d’évaluation, eval_config.json pour les critères de notation, ainsi qu’une configuration LLM-as-judge. Cela correspond à la réalité, car les agents sans évaluation atteignent rarement le environnement de production, et en faisant de l’évaluation la voie par défaut, les agents sont testés avant leur déploiement.
3. Observabilité par défaut. Cloud Trace est activé automatiquement sur chaque agent déployé. Déboguer un agent en production sans traces est presque impossible. L’enregistrement du contenu et les analyses via BigQuery sont optionnels grâce à agents-cli infra single-project, mais le suivi de base est obligatoire.
4. L’infrastructure gérée pour vous. La logique de l’agent est intéressante. Les configurations Docker, les middleware d’authentification et les fichiers Terraform ne le sont pas. La CLI s’occupe de l’infrastructure afin que vous puissiez consacrer votre temps à rendre l’agent plus intelligent.
Aller plus loin
L’agent de gestion des dépenses répond aux exigences énoncées, mais un déploiement réel nécessite quelques éléments supplémentaires.
Données en temps réel. Remplacez l’historique simulé par une requête vers votre base de données des dépenses :
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. Générer un workflow GitHub Actions pour le staging et la production :
agents-cli infra cicd --runner github-actions
Cela crée un pipeline multi-environnements dans lequel les commits vers main sont déployés sur l’environnement de préparation, tandis que les versions marquées sont déployées en production.
Stockage de session. Ajoutez Cloud SQL pour des sessions persistantes :
agents-cli scaffold enhance --session-type cloud_sql
Systèmes multi-agents. Le modèle adk_a2a permet aux agents spécialisés de coordonner leurs actions, ce qui convient aux workflows complexes tels que la réponse aux incidents ou les migrations de code :
agents-cli create coordinator-agent --agent-type adk_a2a
Génération augmentée par récupération d’informations. Construire un agent à l’aide de la recherche vectorielle :
agents-cli create docs-agent \
--agent-type agentic_rag \
--datastore agent_platform_vector_search
Cela génère du code d’ingestion de données, une intégration de recherche vectorielle ainsi que de la logique de récupération.
Un aperçu des techniques
Chaque technique ciblé une étape du cycle de vie : un squelette avec un indicateur de prototype pour démarrer rapidement, des outils sous forme de fonctions Python documentées, des contraintes de sécurité strictes dans les instructions, des tests en environnement local, des évaluations structurées avec une boucle de correction, une infrastructure générée pour le déploiement, ainsi que du traçage et de l’enregistrement du contenu pour assurer la visibilité. Ensemble, elles forment un parcours allant du prototype à la production.
La leçon principale
L’écart de déploiement est réel. De nombreux projets d’agents stagneront non pas parce que l’agent est de mauvaise qualité, mais parce que son déploiement exige trop de travail d’infrastructure.
Les agents CLI ne résolvent pas tout. Vous avez toujours besoin de prompts bien conçus, d’outils adaptés et de tests approfondis. Ce qu’ils éliminent, c’est le travail fastidieux lié à l’infrastructure qui retient les agents prisonniers dans des environnements de développement. L’objectif est que les workflows d’agents ressemblent à l’exécution de create-react-app et non à l’assemblage manuel d’une infrastructure.