Главная / Статьи

Поддержка клиентов с участием пяти агентов на базе Gemini 3.1 и ADK: сортировка задач, поиск информации, выполнение действий, контроль качества и координация работы агентов.

Создание системы поддержки клиентов с участием нескольких агентов с использованием Google ADK и Gemini 3.1: передача задач в ручном режиме, циклы коррекции качества, Agent Engine или Cloud Run, сессии и затраты.

Издатель: REACTAPP.TOP19 мин чтения4349 слов

Источники: Building a Multi-Agent AI System with Gemini 3 and Google Cloud: From Single Agent to Orchestrated Intelligence

Представьте себе заказ, в котором возникли проблемы. Клиент пишет, что пришел неверный товар, просит возврат денег и также хочет, чтобы правильный товар был отправлен в тот же день. За этим одним предложением стоят три задачи: проверка заказа, обработка возврата и срочная доставка замены. Каждая из них требует своих данных, собственных правил и конкретных действий. Одинокий бот поддержки с одним большим запросом может справиться с простым вопросом, но начинает терпеть неудачи, когда несколько задач переплетаются между собой. В таких случаях он работает медленнее, становится более уязвимым к сбоям и склонен к ошибкам.

Решением является многокомпонентный подход: несколько специалистов, каждый из которых отвечает за определенный этап рабочего процесса, при этом оркестратор координирует их действия. Далее приводится пример реализации такого подхода на Google Cloud с использованием моделей Gemini 3.1 и инструментария Google Agent Development Kit (ADK). В нем объясняется, как определить четкие функции для каждого агента, как оркестратор направляет задачи, делегирует их и собирает результаты, как агенты передают друг другу информацию, и, что не менее важно, когда лучше использовать одного агента.

Что происходит при использовании одного большого запроса

Представьте себе агента поддержки, который начинал с простых задач и постепенно приобретал новые возможности: поиск информации в базе знаний, более мягкий тон общения с недовольными клиентами, возможность самопроверки. Объем его системного запроса превышает 3 000 токенов, и каждое новое добавление мешает уже существующим функциям. Появляются четыре проблемы:

  • Утечка ресурсов ограничений. Правила возврата начинают применяться к вопросам, не связанным с возвратами, поэтому простой запрос о продукте получает ответ с логикой возврата.
  • Размытие внимания. Внимание модели ограничено. Когда оно распределяется между десятками инструкций, большинство из которых не связаны с текущим запросом, каждой из них уделяется меньше внимания.
  • Невозможность отладки. Когда ответ неверен, неясно, какая из множества инструкций стала причиной этого.
  • Один путь для всего. Каждый запрос проходит через одну и ту же обработку независимо от своей сложности.

Разделение задач позволяет каждой модели использовать весь свой бюджет внимания для решения конкретной задачи. Она думает только о политике возврата при обработке запросов на возврат и только о тоне при проверке черновика.

ADK разработан именно на основе этой идеи. Его механизм AutoFlow управляет передачей задач между специалистами: когда у оркестратора есть подагенты, ADK добавляет инструмент transfer_to_agent() и записывает описания всех доступных специалистов в его контекст. Таким образом оркестратор знает, кто входит в его команду и чем каждый из участников способен помочь.

Структура системы

Вместо одного запроса центральный оркестратор управляет группой специализированных подагентов. Модели не обязаны быть идентичными. Самый сильный аналитик используется там, где важны принятие решений (оркестрация и проверка качества), а самый быстрый и дешевый — там, где важна скорость (триаж):

  • Оркестратор: планирует и распределяет задачи. Gemini 3.1 Pro. Его инструментами являются специализированные агенты.
  • Агент для триажа: анализирует настроение и намерения пользователя и направляет запрос. Gemini 3.1 Flash-Lite с использованием классификаторов NLP.
  • Агент исследования: собирает факты и контекст. Gemini 3.1 Flash с функциями поиска Vertex и API CRM.
  • Агент действий: выполняет операции, такие как возвраты средств и обновления. Gemini 3.1 Flash с API для управления заказами и оплатами.
  • Агент контроля качества: проверяет точность фактов и соответствие правилам. Gemini 3.1 Pro с базой знаний о правилах.
  • Gemini 2.5 Flash по-прежнему остается хорошим инструментом для сценариев с одним агентом. Однако когда при принятии решений важна качество логических рассуждений, модели серии Gemini 3.1 (доступные с начала 2026 года) более подходят, особенно для ролей оркестратора и контроля качества.

    Используемые компоненты Google Cloud:

    • Модели Gemini 3.1 в качестве ядра для логических рассуждений, настроенные под использование инструментов.
    • Agent Development Kit в качестве фреймворка для управления передачей задач через AutoFlow.
    • Vertex AI Agent Engine — управляемая среда выполнения для развертывания и масштабирования агентов.
    • Firestore — общее хранилище состояния сессии, где агенты читают и записывают информацию о разговоре.
    • Vertex AI Vector Search — инструмент для поиска в базе знаний.

    Настройка ADK

    ADK предоставляет необходимую структуру, включая механизм передачи задач, позволяющий одному агенту эффективно передать вызов другому. Установка выполняется одной строкой:

    pip install google-adk google-generativeai google-cloud-firestore pydantic
    

    Pydantic упоминается явно потому, что ADK использует его для схем ввода и вывода данных агентов, а указание его названия обеспечивает совместимость версий.

    Структура проекта следует тщательно спланировать с самого начала. Многоагентные системы чаще всего выходят из строя из-за несоответствий: один агент отправляет значение refund_id в виде целого числа, тогда как другой ожидает строку. Плоская структура с общими схемами предотвращает появление подобных ошибок:

    support_agents/
    ├── main.py              # Entry point for Cloud Run
    ├── common/
    │   ├── __init__.py
    │   └── schemas.py       # Shared Pydantic models (the "handshake")
    ├── agents/
    │   ├── __init__.py
    │   ├── orchestrator.py
    │   ├── triage.py
    │   ├── research.py
    │   ├── action.py
    │   └── qa.py
    └── config.py            # Environment & project IDs
    

    Больница — это уместная аналогия. Руководитель процесса — это медсестра, отвечающая за триаж, исследовательский агент — лаборант, а исполнительный агент — хирург. Никто из них не общается с пациентом одновременно. Они читают и обновляют медицинскую карту пациента, которая здесь представлена в виде Firestore, а schemas.py — это формат карты, на котором все согласны.

    Агент триажа

    Триаж выполняет функции диспетчерской службы управления воздушным движением. Он сам ничего не решает, а лишь обеспечивает, чтобы каждая заявка попадала к соответствующему специалисту с правильным приоритетом.

    Передача необработанных строк между агентами может привести к ошибкам. Строгая схема Pydantic гарантирует, что руководитель процесса получает проверенный объект на языке Python и ему никогда не придется парсить свободный текст. Сначала идет схема:

    # common/schemas.py
    from pydantic import BaseModel, Field
    
    class TriageResult(BaseModel):
        intents: list[str] = Field(description="List of detected customer goals")
        urgency: str = Field(pattern="^(low|medium|high|critical)quot;)
        sentiment: str = Field(description="Current emotional state of the user")
        required_agents: list[str] = Field(
            description="List of sub-agents needed (research, action, etc.)"
        )
    

    Затем агент, который его генерирует:

    # agents/triage.py
    from google.adk.agents import LlmAgent
    from common.schemas import TriageResult
    
    triage_agent = LlmAgent(
        name="triage_agent",
        model="gemini-3.1-flash-lite",  # Fast and cheap for classification
        instruction="""You are a triage specialist. Analyze the customer's
        message and categorize it accurately.
    
        Urgency rules:
        - critical: Active outages or safety threats
        - high: Frustrated users or financial issues > $100
        - medium: Standard requests needing action
        - low: General info/feedback
    
        You must NOT attempt to solve the problem. Only classify it.""",
        output_schema=TriageResult,  # Force structured JSON output
        output_key="triage_data"
    )
    

    В этом определении важны четыре фактора дизайна:

    • Одна задача. Агент никогда не отвечает на вопросы и не выполняет действий, он только классифицирует. Это позволяет сохранять краткость запроса и высокую точность.
    • Структурированный вывод. output_schema обеспечивает использование корректного JSON, соответствующего структуре TriageResult, а ADK автоматически проверяет его с помощью Pydantic.
    • Несколько намерений одновременно. Поскольку intents представляет собой список строк, сообщение с просьбой обновить адрес и проверить последний счет обрабатывается успешно, в то время как классификатор с одним меткой справиться с этим не сможет.
    • Передача состояния. output_key="triage_data" сохраняет результат в состоянии сессии, так что оркестратор может прочитать его по адресу session.state['triage_data'].

    Исследовательский агент

    Агент исследования — это следователь. Он собирает необработанные данные из Firestore и системы обработки запросов, затем преобразует их в структурированный краткий отчет для агента действий. Схема этого отчета представляет собой контракт между этими двумя ролями:

    # common/schemas.py (add to existing file)
    
    class ResearchBrief(BaseModel):
        order_status: str = Field(description="Current order state")
        customer_tier: str = Field(description="e.g. Gold, Standard")
        applicable_policy: str = Field(description="Relevant policy text")
        can_refund: bool = Field(description="Whether a refund is allowed")
        reasoning: str = Field(description="Why this conclusion was reached")
    

    Далее идут его инструменты и определение агента:

    # agents/research.py
    from google.adk.agents import LlmAgent
    from google.cloud import firestore
    from common.schemas import ResearchBrief
    
    db = firestore.Client()
    
    def lookup_order(order_id: str) -> dict:
        """Fetch real-time shipping status and line items for an order ID."""
        doc = db.collection('orders').document(order_id).get()
        if doc.exists:
            return doc.to_dict()
        return {"error": f"Order {order_id} not found"}
    
    def lookup_customer(customer_id: str) -> dict:
        """Retrieve customer profile, tier, and interaction history."""
        doc = db.collection('customers').document(customer_id).get()
        if doc.exists:
            return doc.to_dict()
        return {"error": f"Customer {customer_id} not found"}
    
    def search_knowledge_base(query: str) -> list:
        """Search product docs and company policies via RAG pipeline."""
        # Uses the RAG pipeline from our previous article
        from rag_pipeline import pipeline
        result = pipeline.query(query, top_k=5)
        return result['sources']
    
    research_agent = LlmAgent(
        name="research_agent",
        model="gemini-3.1-flash",
        instruction="""You are a research specialist.
        1. Extract identifiers (Order ID, Customer ID) from the triage data.
        2. Use tools to gather order history and relevant company policies.
        3. If policy info is missing, use search_knowledge_base.
    
        CRITICAL: Do not answer the customer. Output a formal ResearchBrief.""",
        tools=[lookup_order, lookup_customer, search_knowledge_base],
        output_schema=ResearchBrief,
        output_key="research_brief"
    )
    

    Состояние передаётся без дополнительного кода. Когда запускается агент исследования, ADK вставляет в его контекст данные triage_data из предыдущего шага, поэтому агент уже знает, что ему необходимо искать запись с номером 12345, так как система триажа определила соответствующую цель. Каждый агент строит свою работу на основе результатов предыдущего, и ничего не выполняется дважды. Небольшой совет для производственной среды: ADK автоматически оборачивает обычные функции в объекты FunctionTool, но явное оборачивание с использованием from google.adk.tools import FunctionTool обеспечивает более точный отслеживание задержек и логирование использования токенов в Vertex AI Agent Engine.

    Агент действий

    Только этот специалист имеет право на запись в бизнес-API. Поскольку он выполняет операции с высокой степенью риска, для него устанавливаются строгие схемы и чёткие ограничения. Сначала определяется схема вывода:

    # common/schemas.py (add to existing file)
    
    class ActionSummary(BaseModel):
        actions_taken: list[str] = Field(description="List of actions executed")
        refund_id: str | None = Field(default=None, description="Refund ID if issued")
        escalated: bool = Field(default=False)
        escalation_reason: str | None = Field(default=None)
    

    Затем сам агент, который требует подтверждения от человека для операций с высокой стоимостью:

    # agents/action.py
    from google.adk.agents import LlmAgent
    from google.adk.tools import FunctionTool
    from common.schemas import ResearchBrief, ActionSummary
    
    def process_refund(order_id: str, amount: float, reason: str) -> dict:
        """Process a financial refund. Required: valid order_id and amount."""
        # In production: call your payment API
        return {
            "status": "processed",
            "refund_id": f"REF-{order_id}",
            "amount": amount
        }
    
    def create_replacement_order(
        order_id: str,
        item_id: str,
        shipping_speed: str
    ) -> dict:
        """Create a replacement order with specified shipping speed."""
        # In production: call your order management API
        return {
            "status": "created",
            "new_order_id": f"REPL-{order_id}",
            "estimated_delivery": "2 business days"
        }
    
    def escalate_to_human(reason: str, priority: str) -> dict:
        """Escalate to a human agent with full context."""
        return {
            "status": "escalated",
            "queue": "priority" if priority == "high" else "standard"
        }
    
    # Wrap refund tool with human confirmation for high-value transactions
    refund_tool = FunctionTool(
        func=process_refund,
        require_confirmation=True  # Pauses for human approval before executing
    )
    
    action_agent = LlmAgent(
        name="action_agent",
        model="gemini-3.1-flash",
        instruction="""You are an action specialist.
        Review the 'research_brief' in the session state.
    
        CRITICAL RULES:
        1. Only refund if 'can_refund' is True in the research brief
        2. If amount > $500, you MUST use escalate_to_human
        3. You must call tools for every action — do not just tell the user
           it happened
        4. If information is missing from the brief, escalate""",
        tools=[refund_tool, create_replacement_order, escalate_to_human],
        input_schema=ResearchBrief,   # Only sees research data, not raw chat
        output_schema=ActionSummary,
        output_key="action_result"
    )
    

    Два параметра обеспечивают основную часть безопасности. Параметр require_confirmation необходим, поскольку в производственных системах агент редко может осуществить возврат средств исключительно на основе полученных указаний. Механизм подтверждения через инструменты ADK приостанавливает выполнение до тех пор, пока человек не даст разрешение, и оркестратор видит статус «в ожидании», который можно перенаправить на панель управления сотрудников. Параметр input_schema важен, так как без него агент видит всю историю переписки, включая устаревшие сообщения. Ограничение ввода данными из формата ResearchBrief предотвращает попадание устаревшей информации и помогает принимать решения на основе самых свежих данных.

    Следует также отметить, что параметр escalate_to_human представляет собой целенаправленное бизнес-правило, а не состояние сбоя. Оркестратор может точно узнать, почему агент остановил работу, и переслать заявку человеку вместе с полным описанием исследования.

    Агент QA

    QA — это последний этап проверки. Помимо анализа формулировок, он сравнивает действия агента с требованиями исследовательского задания, чтобы убедиться, что действия соответствуют знаниям.

    Эта функция работает на Gemini 3.1 Pro, поскольку ей необходимо запоминать весь контекст разговора и выявлять тонкие противоречия, в задачах, где версия Pro постоянно превосходит Flash. ADK также позволяет ей использовать режим размышлений для более глубокого самоанализа перед одобрением ответа. Схема проверки:

    # common/schemas.py (add to existing file)
    
    class QAReview(BaseModel):
        is_approved: bool = Field(description="True if the response meets all criteria")
        feedback: str = Field(description="Specific corrections if not approved")
        final_text: str = Field(description="The customer-facing message")
    

    А конфигурация агента:

    # agents/qa.py
    from google.adk.agents import LlmAgent
    from google.adk.planners import BuiltInPlanner
    from google.genai.types import ThinkingConfig
    from common.schemas import QAReview
    
    qa_agent = LlmAgent(
        name="qa_agent",
        model="gemini-3.1-pro",
        instruction="""You are a senior QA auditor. Compare the 'action_result'
        against the 'research_brief' in the session state.
    
        CRITICAL CHECKS:
        1. Did the Action Agent refund the EXACT amount listed in the brief?
        2. Does the response cite the policy found during research?
        3. Is the tone empathetic but professional?
        4. Are ALL intents from the triage classification addressed?
        5. No unauthorized promises, discounts, or policy exceptions
    
        If any check fails, set is_approved to False with specific feedback.""",
        output_schema=QAReview,
        output_key="qa_review",
        # MEDIUM for routine QA; switch to HIGH for edge cases or audits
        planner=BuiltInPlanner(
            thinking_config=ThinkingConfig(thinking_level="MEDIUM")
        )
    )
    

    Отклонение не прерывает процесс. Когда значение qa_review.is_approved равно ложному, оркестратор считывает поле feedback и направляет запрос обратно агенту, ответственному за действия или исследования, с конкретными исправлениями. Именно этот цикл корректировок отличает производственного агента от демонстрационного скрипта. Он ограничен двумя циклами ревизии, после чего дело передается человеку.

    Оркестратор

    Оркестратор ни не проводит исследований, ни не выполняет действий. Он управляет состоянием и обеспечивает, чтобы специалисты работали в разумном порядке. Исходя из списка sub_agents, система AutoFlow от ADK добавляет инструмент transfer_to_agent(), и ЯЗЫК больших моделей оркестратора выбирает следующего специалиста на основе своих инструкций и текущего состояния сессии:

    # agents/orchestrator.py
    from google.adk.agents import LlmAgent
    from agents.triage import triage_agent
    from agents.research import research_agent
    from agents.action import action_agent
    from agents.qa import qa_agent
    
    orchestrator = LlmAgent(
        name="support_orchestrator",
        model="gemini-3.1-pro",  # Best reasoning for delegation decisions
        instruction="""You are the lead coordinator of a customer support team.
        Use the following specialists in order:
        1. triage_agent: to classify the intent and urgency
        2. research_agent: to gather order data and relevant policies
        3. action_agent: to execute the required operations
        4. qa_agent: to verify the final response
    
        Special cases:
        - If triage classifies as 'critical': bypass the chain and escalate
        - If QA returns is_approved=False: re-route to the responsible agent
          with the feedback (maximum 2 revision cycles, then escalate)
        - If any agent fails: escalate to human with full context
    
        You must never respond to the customer directly.
        Always route through the specialist pipeline.""",
        sub_agents=[triage_agent, research_agent, action_agent, qa_agent]
    )
    

    Запуск

    ADK выполняет агентов с помощью Runner, который призывает к временной остановке выполнения в момент вызова агентом инструмента, а затем возобновляет его работу после возврата результата:

    # main.py
    from google.adk.runners import Runner
    from google.adk.sessions import InMemorySessionService
    from agents.orchestrator import orchestrator
    
    APP_NAME = "customer_support"
    USER_ID = "system"
    
    # For production, replace with a Firestore-backed session service
    session_service = InMemorySessionService()
    
    runner = Runner(
        agent=orchestrator,
        app_name=APP_NAME,
        session_service=session_service
    )
    
    async def handle_customer_message(customer_id: str, message: str):
        """
        Entry point for customer messages.
        """
        session_id = f"support-{customer_id}"
    
        # Ensure session exists
        session = await session_service.get_session(
            app_name=APP_NAME, user_id=USER_ID, session_id=session_id
        )
        if not session:
            session = await session_service.create_session(
                app_name=APP_NAME, user_id=USER_ID, session_id=session_id
            )
    
        # run_async yields events as agents execute
        final_response = None
        async for event in runner.run_async(
            user_id=USER_ID,
            session_id=session_id,
            new_message=message
        ):
            if event.is_final_response():
                final_response = event
    
        return {
            "response": final_response.content.parts[0].text if final_response else None,
            "session_id": session_id
        }
    

    Почему бы не связаться с агентами напрямую? Runner контролирует весь процесс: он сохраняет сессии, отслеживает активных агентов, обрабатывает вызовы инструментов и фиксирует каждый шаг. Поскольку каждый агент записывает свой результат под output_key, Runner гарантирует наличие необходимых данных, когда им нуждается исполняющий агент, без необходимости вручную писать дополнительный код. Прозрачность работы также обеспечивается автоматически: каждый вызов агента, использование инструмента и передача данных фиксируются как события, что помогает решать проблемы с отладкой. Если что-то идет не так, записи показывают, какой агент принял ту или иную решение и почему.

    Способы развертывания

    Существует два способа развертывания. Vertex AI Agent Engine предлагает управляемую среду выполнения, в которой практически не требуется никакого технического обслуживания, в то время как Cloud Run предоставляет полный контроль над контейнером.

    Agent Engine

    Этот вариант требует минимального ухода и рекомендуется для большинства сред, основанных на ADK. Необходимо установить две переменные:

    PROJECT_ID=your-project-id
    LOCATION_ID=us-central1
    

    Затем разверните с помощью одной команды:

    adk deploy agent_engine \
      --project=$PROJECT_ID \
      --region=$LOCATION_ID \
      --display_name="Customer Support Team" \
      support_agents
    

    Agent Engine обеспечивает масштабирование, сохранение сессий и логирование с учётом действий агентов. Не требуется Dockerfile, код для управления сессиями и специальная инфраструктура.

    Cloud Run

    Выбирайте этот вариант, когда необходимы собственные системные библиотеки, определённая сетевая инфраструктура, такая как VPC Service Controls, или компоненты, отличные от ADK. В примере вместо Flask используется Quart. Синтаксис практически идентичен, но Quart поддерживает async/await встроенно, что позволяет избежать антипаттерна asyncio.run(), при котором для каждого запроса создаётся новый цикл событий:

    # server.py
    from quart import Quart, request, jsonify
    from main import handle_customer_message
    
    app = Quart(__name__)
    
    @app.route("/support", methods=["POST"])
    async def support():
        data = await request.get_json()
        # No asyncio.run needed — Quart handles the event loop
        result = await handle_customer_message(
            data["customer_id"],
            data["message"]
        )
        return jsonify(result)
    
    @app.route("/health", methods=["GET"])
    async def health():
        return jsonify({"status": "healthy"})
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", port=8080)
    

    Определение контейнера:

    # Dockerfile
    FROM python:3.11-slim
    
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install --no-cache-dir -r requirements.txt
    
    COPY . .
    EXPOSE 8080
    
    CMD ["python", "server.py"]
    

    А команда развертывания:

    gcloud run deploy support-agents \
      --source . \
      --region us-central1 \
      --memory 4Gi \
      --cpu 2 \
      --allow-unauthenticated
    

    Короче говоря, Cloud Run требует средних усилий на настройку (Dockerfile и API), нуждается в ручном управлении состоянием с помощью Firestore или Redis, записывает логи в стандартный Cloud Logging и подходит для кастомных временных сред и фреймворков. Agent Engine работает по одному команду, имеет встроенные сессии, генерирует трейсы специфичные для агента и подходит для агентов ADK, которым необходима быстрая масштабируемость.

    Сохранение состояния разговоров

    В примере оркестратора использовался InMemorySessionService, который подходит для тестирования, но теряет всё при перезапуске процесса. В продакшене требуется надежный сервис. ADK предлагает два таких решения.

    С Agent Engine управление сессиями осуществляется автоматически через сервис сессий Vertex AI:

    # config.py
    from google.adk.sessions import VertexAiSessionService
    
    session_service = VertexAiSessionService(
        project="your-project-id",
        location="us-central1",
        agent_engine_id="your-agent-engine-id"  # From adk deploy output
    )
    

    Agent Engine также обобщает длинные истории данных и сам очищает их, поэтому код Firestore не требуется.

    Для Cloud Run сервис DatabaseSessionService работает с базами данных PostgreSQL или SQLite:

    # config.py
    from google.adk.sessions import DatabaseSessionService
    
    # PostgreSQL for production
    session_service = DatabaseSessionService(
        db_url="postgresql+asyncpg://user:pass@host:5432/agents"
    )
    
    # Or SQLite for development
    session_service = DatabaseSessionService(
        db_url="sqlite+aiosqlite:///sessions.db"
    )
    

    Он создаёт свои таблицы при первом запуске. Переместив его в Runner, состояние сессии сохраняется после перезагрузки.

    Как состояние передаётся между агентами

    Не требуется ручного вызова функций get() и set(). output_key каждого агента автоматически записывает данные в состояние сессии, а последующие агенты читают их оттуда:

    triage_agent (output_key="triage_data")
        ↓ writes to session.state["triage_data"]
    research_agent (reads triage_data, output_key="research_brief")
        ↓ writes to session.state["research_brief"]
    action_agent (input_schema=ResearchBrief, output_key="action_result")
        ↓ writes to session.state["action_result"]
    qa_agent (reads action_result + research_brief, output_key="qa_review")
    

    Runner сохраняет весь этот состояние в любом настроенном бэкенде — будь то Firestore, PostgreSQL или Agent Engine.

    Три привычки помогают поддерживать здоровую память:

    • Кратко излагайте. Храните сжатые результаты вместо необработанных ответов API, иначе окно контекста заполнится лишними данными.
    • Устанавливайте срок действия сессий. Сессии должны иметь срок жизни от 24 до 48 часов, что позволяет сохранять базу данных компактной и безопасной.
    • Защищайте персональные данные. Необработанные персональные данные, такие как номера удостоверений личности или пароли, не должны храниться в общем состоянии; их следует маскировать перед записью в сессию.

    Когда один агент всё ещё лучший вариант

    Многократный использование агентов не всегда превосходит одиночный вариант. Практический способ принятия решения:

    • Простой FAQ или проверка статуса: один агент. Минимальная задержка и стоимость, не требуется сложного анализа.
    • Обогащение данных с помощью трех–пяти поисков: один агент. Один вызов большой языковой модели достаточен для базового использования инструментов.
    • Регулируемые рабочие процессы: многократный агент. Изоляция позволяет разделять логику действий от ввода пользователя, что снижает риск внедрения вредоносных запросов.
    • Неоднозначное направление действий: многократный агент. Специализированный агент для сортировки задач, занимающийся определением намерений пользователя, снижает количество ошибок.
    • Действия высокой стоимости свыше 500 долларов: многократный агент. Позволяет провести двойную проверку с помощью агента контроля качества перед вызовом любого API.
    • Требования к аудиту: многократный агент. Ввод и вывод каждого агента записываются отдельно.

    Ориентир: когда объем вводных данных для одного агента приближается к 3 000 токенам — это момент, когда начинаются проблемы с ограничениями и размытием внимания агента, — или когда разным этапам рабочего процесса требуются разные инструменты, наступает время его разделения.

    Распространенные ловушки

    • Агент, умеющий всё. Производительность снижается, когда один агент использует десять и более инструментов, поскольку модели тратят время на выбор инструмента вместо того, чтобы понимать запрос. Разделяйте агентов по функциям: агент, нуждающийся в инструментах для возврата средств, доставки и юридической помощи, превращается в трех специалистов.
    • Чрезмерно большой контекст. Если каждый агент видит всю историю чата из десяти сообщений, затраты на токены резко возрастают. Сокращайте объем данных, чтобы процесс сортировки передавал только выявленную цель, а не всю переписку.
  • Бесконечная передача заданий. Агент A отправляет задание агенту B, тот в свою очередь возвращает его A, при этом токены тратятся по кругу. Необходимо установить максимальное количество циклов передачи заданий; два цикла до обращения к человеку являются подходящим значением.
  • Нечеткие границы ответственности. Два агента берут на себя одно и то же задание или задание оказывается между ними. Необходимо четко определить контракты input_schema и output_schema без перекрытия обязанностей.
  • Игнорирование задержек. В последовательной схеме добавляется 4–6 секунд, тогда как у одного агента этот показатель составляет 1–2 секунды. Механизм ParallelAgent ADK распределяет работу между несколькими агентами, что позволяет сократить общую задержку на 30–40% за счет одновременного выполнения исследований и проверок соответствия.
  • Чего ожидать

    Многоагентные системы идут на увеличение задержек ради надежности при выполнении сложных задач. Опубликованные тесты и опыт отрасли подтверждают следующие преимущества:

    • Точность при выполнении сложных задач. Разбиение многоэтапных проблем на конкретные подзадачи обычно дает лучшие результаты, чем использование монолитных запросов; в документации ADK указано, что показатели завершения задач выше, когда у агентов четко определены функции.
    • Контролируемые сбои. Если один компонент выходит из строя, ущерб ограничивается только этим агентом и не портит всего ответа.
    • Возможность аудита. Отдельные логи для каждого агента облегчают отладку и контроль соответствия требованиям.

    Есть и свои недостатки:

    • Задержки. Обработка задачи с участием пяти агентов занимает примерно от 3 до 8 секунд, тогда как для одного агента — от 1 до 2 секунд. Основным барьером являются последовательные вызовы.
  • Расходы на API. Пять агентов (оркестратор и четыре специалиста) стоят примерно в четыре-пять раз дороже одного агента за запрос, хотя использование комбинации моделей помогает сдерживать затраты. Сортировка запросов с использованием Flash-Lite обходится в 0,25 доллара за миллион токенов входных данных, а версия Pro по цене 2 доллара за миллион предназначена для оркестрации и проверки качества; в сумме совокупные затраты за одну интеракцию остаются ниже одного цента.
  • Токены для обработки информации. Режим расширенной обработки в версии Pro (thinking_level="HIGH") может увеличить количество токенов примерно на 20 тысяч, за что взимается плата по ставке 12 долларов за миллион токенов выходных данных. Следовательно, одна сложная проверка качества обходится примерно в 0,24 доллара только на обработку информации. Используйте режим HIGH лишь при необходимости, поскольку для большинства проверок достаточен режим MEDIUM.
  • Сложность задачи. При сложных рабочих процессах требуется контролировать больше параметров, что оправдывает дополнительные затраты, но для простых задач это избыточно.
  • Примерный месячный счет для 100 000 сложных запросов:

    • Маршрутизация через Orchestrator в Gemini 3.1 Pro: примерно 80 долларов
    • Обработка запросов с использованием Flash-Lite: примерно 20 долларов
    • Исследования с использованием Flash: примерно 40 долларов
    • Работа с данными в режиме Flash: примерно 40 долларов
    • Проверка качества с использованием режима MEDIUM в версии Pro: примерно 100 долларов
    • Cloud Run с 2 vCPU и 2 GiB памяти: примерно 120 долларов
    • Сессии PostgreSQL: примерно 30 долларов
    • Векторный поиск в режиме совместного использования с одним агентом: примерно 100 долларов
    • Итого: примерно 530 долларов в месяц

    Фактически ключевым фактором снижения затрат является смешивание моделей. Только около 30% запросов (с использованием Orchestrator и для проверки качества) обходятся по цене версии Pro, в то время как остальные обрабатываются с использованием Flash или Flash-Lite по цене, в восемь-пятьдесят раз ниже за токен. Стоимость одной сложной интеракции составляет примерно половину цента. Эти цифры основаны на публикуемых тарифах Google Cloud; реальные счета меняются в зависимости от сложности запросов, уровня обработки информации и глубины взаимодействия с агентом.

    Порядок внедрения

    Разумная последовательность заключается в том, чтобы начать с одного агента, настроить его логику, обеспечить её данными с помощью механизмов поиска, а разделять его на специалистов — только тогда, когда промпт системы становится слишком длинным или задачи слишком разнообразными, чтобы одна модель могла их надёжно обрабатывать. Каждый слой строится на основе предыдущего.

    Момент использования микросервисов для агентов

    Дизайн с несколькими агентами не делает ИИ более сложным. Он делает сложные рабочие процессы предсказуемыми, подобно тому как микросервисы заменили монолит: один промпт превращается в распределённый набор компонентов, каждый из которых выполняет свою функцию. Просить одного агента одновременно сортировать информацию, проводить исследования, действовать и проверять результаты — это как просить одного человека быть одновременно рецепционистом, ведущим аналитиком, техником и аудитором. Это сработает в компании из одного человека, но провалится в крупном предприятии.

    Если предоставить каждому агенту четко определенную задачу, специализированные инструменты и общий слой памяти, результат будет точным — ведь конкретные указания снижают отклонения при выполнении несвязанных задач; систему легко отладить, поскольку проблемы конкретного специалиста становятся видимыми; к тому же это дешево — запуск пяти агентов на Gemini 3.1 стоит примерно половины цента за каждое сложное взаимодействие, что значительно меньше времени, затрачиваемого человеческим агентом.

    Эта конструкция также имеет потенциал для дальнейшего развития. Благодаря протоколу Agent-to-Agent (A2A), открытому стандарту, управляемому Linux Foundation, подобная система в будущем сможет вступать в общение с агентами, работающими у поставщиков или партнеров — например, агент службы поддержки может напрямую общаться с агентом транспортной компании для решения проблемы с потерянным грузом без участия человека.

    На данный момент совет прост: сначала создайте одного агента, а затем разделяйте его функции, когда запросы становятся слишком длинными или задачи — слишком разнообразными.