От прототипа к производству с Agents CLI: агент для утверждения расходов
Создайте схему, протестируйте, оцените и разверните агента ADK в Cloud Run с использованием Agents CLI, при этом будут рассмотрены функции отслеживания, логирование в BigQuery, интеграция с CI/CD и расширения RAG.
Источники: Building AI Agents in 30 Minutes from Prototype to Production
Любой, кто недавно пытался развернуть ИИ-агента, знает эту закономерность. Во время разработки он ведёт себя так: отвечает на вопросы, вызывает нужные инструменты, принимает разумные решения. Затем кто-то спрашивает, когда он сможет быть введён в эксплуатацию, и дни уходят на настройку Docker, аутентификацию, мониторинг и процессы развертывания.
Над кодом агента потребовалось несколько часов. На настройку инфраструктуры, необходимой для его работы, уходят недели.
Далее приводится пошаговое руководство по созданию и развертыванию агента производственного уровня с помощью Agents CLI — инструментария с открытым исходным кодом, предназначенного для упрощения процесса развертывания. Примером служит агент для утверждения расходов, включающий бизнес-правила, процедуры оценки и развертывание в облаке; согласно описанию инструментария, весь процесс занимает примерно полчаса. Считайте это оптимальным сценарием для хорошо подготовленного аккаунта.
Разрыв в процессе развертывания
Создание агента с помощью Agent Development Kit (ADK), LangChain или LlamaIndex довольно просто. Настоящая сложность возникает при его внедрении в производство. Для работы в продакшене агенту обычно требуется всё следующее.
Локальная разработка
- код агента, который является самой важной частью
- настройки для локальных тестов
- мок-данные или стабы API
Тестирование и оценка
- определение тестовых случаев
- метрики и критерии оценки
- настройка использования больших языковых моделей в качестве судей
- набор тестов на обнаружение регрессий
Инфраструктура производства
- образ контейнера
- настройки развертывания в облаке, например, для Cloud Run или Kubernetes
- механизмы аутентификации и авторизации
- управление секретами
- пайплайн CI/CD
Возможность наблюдения
- отслеживание запросов
- логирование вводимых команд и получаемых ответов
Каждый из этих пунктов означает необходимость освоения нового инструмента, изучения новой документации и объединения отдельных систем. Помощник-программист может помочь с логикой агента, но у него возникают трудности с развертыванием, поскольку он не знает правил вашей инфраструктуры, что приводит к многократной отладке.
Что такое Agents CLI
Agents CLI — это набор инструментов, предоставляющий единый интерфейс для всего цикла разработки агентов в Google Cloud. Он работает в двух режимах.
- Режим агента. Вы устанавливаете «навыки» в помощника-программиста, такого как Gemini CLI, Claude Code или Cursor. Эти навыки обучают помощника шаблонам развертывания, чтобы он принимал правильные решения.
Основная идея заключается в том, что вместо того чтобы помощник угадывал правила развертывания, он получает машинночитаемый контекст о том, когда использовать каждую цель развертывания, как структурировать оценки и какие паттерны наблюдаемости работают лучше всего.
Пример: агент для утверждения расходов
Агент рассматривает отчеты сотрудников о расходах и принимает решение об утверждении в соответствии с корпоративными правилами. Для принятия решений он использует модели Gemini через Vertex AI. Требования:
- автоматически утверждать рутинные заявки на сумму до 50 долларов
- обнаруживать дублирующиеся заявки
- фиксировать необычные паттерны, такие как расходы в выходные или с незнакомыми поставщиками
- передавать неопределенные случаи на рассмотрение человеку
Предварительные требования
Убедитесь, что установлено следующее:
# Required tools
Python 3.11+
uv package manager
Node.js (for skills installation)
Google Cloud SDK (gcloud)
Вам также нужен проект в Google Cloud с включённой оплатой, который можно создать в консоли Google Cloud.
Установите набор инструментов:
uvx google-agents-cli setup
Затем авторизуйтесь в Google Cloud, укажите свой проект и включите необходимые API:
# 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
Это настраивает доступ к Vertex AI для агента, который будет вызывать модели Gemini через API Vertex AI.
Шаг 1: создание структуры проекта
Вместо ручного создания каталогов и файлов конфигурации позвольте CLI сгенерировать полную структуру проекта.
С помощью ассистента для программирования, такого как Gemini CLI, Claude или Cursor, достаточно просто отправить запрос:
Build an expense approval agent using agents-cli.
Auto-approve under $50, flag duplicates, escalate suspicious cases.
Start with a prototype.
Ассистент считывает установленные навыки и создаёт проект с правильной структурой. Вручную это делается с помощью трёх команд:
agents-cli create expense-agent --prototype --yes
cd expense-agent
agents-cli install
Флаг --prototype имеет важное значение. Он генерирует только код агента и структуру тестов, оставляя без внимания элементы развертывания, такие как Docker, Terraform и CI/CD, которые добавляются позже. Полученная структура выглядит следующим образом:
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
Шаг 2: написание бизнес-логики
Далее реализуйте логику утверждения в файле app/agent.py. В ADK, как и в большинстве фреймворков агентов, инструменты представляют собой обычные функции на Python. Документация критически важна, поскольку модель читает её, чтобы определить, когда и как вызывать каждый инструмент.
Инструмент 1: проверка истории расходов.
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"
})
Инструмент 2: получение политики компании.
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)
Инструмент 3: обратитесь к сотруднику-человеку.
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}"
})
Затем инструменты подключаются к агенту с четкими инструкциями и ограничениями по безопасности:
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],
)
Внимательно изучите правила безопасности, указанные в инструкции. Даже если политика позволяет одобрять траты на еду до 50 долларов, существует строгий лимит: агент никогда не будет автоматически одобрять суммы, превышающие 50 долларов, без проверки человеком. Это предотвращает дорогостоящие ошибки.
Шаг 3: тестирование локально
Запустите среду ADK:
agents-cli playground
Он открывает веб-интерфейс на localhost по порту 8080. Три сценария охватывают основные случаи использования.
Стандартное утверждение.
Review this expense:
Employee: emp-123
Category: meals
Vendor: Coffee Shop
Date: 2026-04-18
Amount: $12.50
Ожидаемое поведение: агент вызывает get_company_policy(), видит порог в 50 долларов, вызывает check_expense_history(), не находит дубликатов и одобряет заявку.
Сумма превышает порог.
Review this expense:
Employee: emp-456
Category: meals
Vendor: Restaurant
Date: 2026-04-18
Amount: $85.00
Ожидаемое поведение: агент переводит заявку на более высокий уровень, поскольку сумма превышает 50 долларов.
Подача дублирующейся заявки.
Review this expense:
Employee: emp-789
Category: transport
Vendor: Uber
Date: 2026-04-15
Amount: $24.00
Ожидаемое поведение: агент находит дубликат в искусственной истории и передаёт задачу на более высокий уровень.
Ручные тесты подтверждают корректное функционирование в идеальных условиях. Однако для готовности к эксплуатации требуется более систематический подход.
Шаг 4: структурированные оценки
Большинство разработчиков пропускают этот шаг, и это одна из основных причин сбоев агентов в производственной среде. Необходимы тест-кейсы с чёткими критериями успешного или неудачного выполнения. Вопрос не в том, «кажется ли это правильным?», а в том, «соответствует ли это правилам?»
Измените файл 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"]
}
]
}
Запустите оценку:
agents-cli eval run
Пример вывода:
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
Оценка осуществляется с помощью ЯИ, выступающего в роли судьи, который использует критерии из файла eval_config.json. Когда какой-либо пример теста не проходит, необходимо корректировать инструкции агента или логику используемых инструментов до тех пор, пока все примеры не будут пройдены.
Этот цикл называется циклом оценки и коррекции — ключом к надежным производственным агентам. Без оценок вы просто надеетесь, что агент будет работать корректно, а с их помощью вы можете быть уверены в этом.
Шаг 5: развертывание
Агент работает и проходит все тесты, поэтому пришло время его развернуть. Сначала необходимо добавить инфраструктуру для развертывания:
agents-cli scaffold enhance --deployment-target cloud_run
Это генерирует Dockerfile, конфигурацию развертывания в Cloud Run и файлы Terraform. Затем устанавливается проект и происходит развертывание:
gcloud config set project YOUR_PROJECT_ID
agents-cli deploy
Ожидайте результат примерно в таком виде:
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
Согласно заявлениям, общее время от выполнения команды agents-cli create до запуска сервиса составляет примерно 30 минут, однако время первого запуска у вас будет зависеть от настроек аккаунта и разрешений.
Шаг 6: возможности мониторинга
Функция Cloud Trace включается автоматически без необходимости настройки. Чтобы протестировать развернутый агент:
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"
Затем откройте Cloud Trace, чтобы увидеть:
- полные треки запросов с разбивкой по задержкам
- время выполнения каждого вызова LLM
- время выполнения инструментов
- полную временную шкалу для каждого запроса
Для отладки и анализа включите запись содержимого:
agents-cli infra single-project --project YOUR_PROJECT_ID
Это предусматривает учетную запись сервиса для логирования, контейнер Cloud Storage для хранения входящих и исходящих сообщений, набор данных BigQuery для аналитики, а также механизм обновления, позволяющий агенту записывать каждый диалог. Затем вы можете выполнять запросы к данным о реальном поведении в 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;
Это крайне важно для отладки. Когда кто-то спрашивает, почему агент повысил стоимость обеда до 30 долларов, вы запрашиваете данные в BigQuery и видите точно, что он решил и почему.
Что отличает этот набор инструментов
Выделяются четыре основных аспекта дизайна.
1. Навыки как контекст, понятный машине. Инструменты CLI для агентов предоставляют не только команды. Они включают навыки, которые учат вашего помощника по программированию правильно ими пользоваться. Выполнение команды agents-cli setup устанавливает семь из них:
google-agents-cli-workflow— для жизненного цикла разработкиgoogle-agents-cli-adk-code— для шаблонов API ADK на Pythongoogle-agents-cli-scaffold— для создания структуры проектаgoogle-agents-cli-eval— для методологии оценкиgoogle-agents-cli-deploy— для целей развертывания
google-agents-cli-publish — для регистрации в Gemini Enterprisegoogle-agents-cli-observability — для трейсинга и логгингаПомощник обращается к ним при необходимости. Вместо угадывания он знает, когда выбрать Agent Runtime, Cloud Run или GKE, а также понимает, какие схемы использования LLM в качестве судьи эффективны, поэтому не возникает ситуаций с пробами и ошибками при оценке показателей.
2. Оценка по умолчанию. Каждый проект с шаблоном с самого начала включает инфраструктуру для оценки: папку tests/eval/evalsets/ для тестовых случаев, файл eval_config.json с критериями оценки и настройку использования LLM в качестве судьи. Это отражает реальность, поскольку агенты без процедур оценки редко попадают в производственную среду, а сделав оценку стандартным этапом, можно тестировать агенты перед их развертыванием.
3. Наблюдаемость по умолчанию. Cloud Trace включается автоматически на каждом развернутом агенте. Отладка агента в производственной среде без записей трассировки практически невозможна. Логгинг содержимого и аналитика с помощью BigQuery включаются по желанию через команду agents-cli infra single-project, но базовая трассировка является обязательной.
4. Инфраструктура обрабатывается за вас. Логика агента представляет интерес, но конфигурации Docker, компоненты аутентификации и файлы Terraform — нет. CLI берет на себя управление инфраструктурой, чтобы вы могли сосредоточиться на сделании агента более умным.
Дальнейшее развитие
Агент для учета расходов соответствует указанным требованиям, но для реального развертывания нужны еще некоторые компоненты.
Актуальные данные. Замените симулированную историю на запрос к вашей базе данных расходов:
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. Сгенерируйте рабочий процесс GitHub Actions для стадии тестирования и продакшена:
agents-cli infra cicd --runner github-actions
Он создаёт конвейер с несколькими средами, в котором коммиты в main развертываются в стадионную среду, а релизы с метками — в производственную.
Хранение сессий. Для постоянных сессий добавьте Cloud SQL:
agents-cli scaffold enhance --session-type cloud_sql
Системы с несколькими агентами. Шаблон adk_a2a позволяет специализированным агентам координировать свои действия, что подходит для сложных рабочих процессов, таких как реагирование на инциденты или миграция кода:
agents-cli create coordinator-agent --agent-type adk_a2a
Генерация с усилением на основе поиска. Создайте агента с использованием векторного поиска:
agents-cli create docs-agent \
--agent-type agentic_rag \
--datastore agent_platform_vector_search
Это генерирует код для ввода данных, интеграцию векторного поиска и логику поиска.
Краткое описание техник
Каждая из этих техник ориентирована на определенный этап жизненного цикла: создание основы с флагом прототипа для быстрого старта, инструменты в виде задокументированных функций на Python, строгие ограничения безопасности в инструкциях, тестирование в локальной среде, структурированная оценка с циклом исправлений, генерируемая инфраструктура для развертывания, а также отслеживание и логирование контента для прозрачности. Вместе они образуют путь от прототипа до продакшена.
Вывод
Проблема с развертыванием действительно существует. Многие проекты агентов застаиваются не из-за плохой работы агента, а потому что его развертывание требует слишком много работы по настройке инфраструктуры.
CLI-инструменты для агентов не решают всех проблем. Вам всё равно понадобятся хорошо спроектированные запросы, подходящие инструменты и тщательные тестирования. Они устраняют лишнюю работу с инфраструктурой, из-за которой агенты остаются в средах разработки. Цель состоит в том, чтобы рабочие процессы с агентами казались такими же простыми, как запуск create-react-app, а не похожими на ручную настройку инфраструктуры.