Агент с delegated tools (Supervisor → 2 специализированных агента)

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Агент с delegated tools (Supervisor → 2 специализированных агента)

1. Цель задачи

Спроектировать и реализовать агентную систему с одним супервизором (Supervisor) и двумя специализированными агентами, каждый из которых владеет определённым набором инструментов. Supervisor получает сложную задачу, разбивает её на подзадачи и делегирует выполнение подходящему агенту. Цель: на практике освоить паттерн «оркестратор+воркеры», понять, как управлять контекстом и распределять вызовы LLM между агентами.

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


2. Исходные данные

Что нужноОткуда взять
Python 3.11+Установить из официального дистрибутива
LLM API (OpenAI / Anthropic / локальная модель)API-ключ (OpenAI), либо запустить Ollama с моделями (например, llama3)
Фреймворк для агентов (LangGraph / CrewAI / Autogen)pip install langgraph, pip install crewai, или аналоги
Инструменты для специализированных агентовНабор: веб-поиск (Mock/заглушка), калькулятор, преобразование текста, работа с файлами – см. ниже

Если нет реального инструмента — симулируем:

  1. Для веб-поиска: создать класс MockWebSearch с фиксированными ответами по заданным запросам.
  2. Для API вызовов (погода, курсы валют): написать заглушки, возвращающие заранее заготовленные JSON-объекты.
  3. Для доступа к файлам: использовать tempfile и создать иерархию тестовых файлов во временной папке.

3. Технологический стек

КомпонентИнструментыНазначение
Язык программированияPython 3.11+Реализация всей системы
Управление диалогамиLangGraph (граф состояний)Построение графа агентов и состояния
LLMOpenAI GPT-4o / Anthropic Claude 3.5 Sonnet / Ollama llama3Генерация ответов, принятие решений
Инструменты агентовduckduckgo_search, wolframalpha, yfinance, requestsФактические инструменты (или моки)
Хранение состоянияСловарь Python / langgraph.graph.StateСохранение истории вызовов и контекста
Логированиеlogging (INFO для трейсинга)Отладка и анализ
Тестированиеpytest + unittest.mockПроверка логики делегирования

4. Этапы выполнения

Этап 1: Проектирование архитектуры и выбор доменной области (1–2 ч)

Действия

  1. Выбрать предметную область, например:

    • «Финансовый ассистент» (агент A получает рыночные данные, агент B делает анализ и отчёт).
    • «Путеводитель» (агент A ищет достопримечательности, агент B – маршруты и бронирование).
    • «Научный ревью» (агент A ищет статьи, агент B пишет аннотацию).
  2. Определить два специализированных агента

    • Агент Alpha — отвечает за сбор информации (инструменты: web search, API погоды/финансов, чтение файлов).
    • Агент Beta — отвечает за обработку и генерацию (инструменты: калькулятор, перевод, форматирование, запись в файл).
  3. Спроектировать граф состояний в LangGraph:

    • Узлы supervisor_node, agent_alpha_node, agent_beta_node, human_node (если нужна обратная связь).
    • Рёбра Supervisor → Alpha (если запрос на сбор данных), Supervisor → Beta (если запрос на обработку), Alpha → Supervisor, Beta → Supervisor.
    • Состояние messages (список сообщений), task_plan (план, сгенерированный supervisor), results (собранные данные).
  4. Нарисовать диаграмму (в текстовом виде или в Mermaid):

    graph TD
        A[Supervisor] -->|delegate search| B[Alpha Agent]
        A -->|delegate compute| C[Beta Agent]
        B --> A
        C --> A
        A -->|final answer| D[User]
    

Ожидаемый результат этапа Описание архитектуры, выбор доменной области, структура графа в виде кода на LangGraph.

Этап 2: Реализация специализированных агентов и их инструментов (2–3 ч)

Действия

  1. Создать классы инструментов

    • web_search(query: str) -> str — мок, возвращает фиктивные результаты.
    • read_file(path: str) -> str — читает локальный файл.
    • calculator(expression: str) -> float — использует eval с безопасным окружением (или numexpr).
    • translate(text: str, target_lang: str) -> str — мок (пишет [переведено: {text} -> {lang}]).
  2. Реализовать агента Alpha

    • Функция agent_alpha_node(state: State) -> State:
      • Принимает задачу от supervisor.
      • Вызывает подходящий инструмент (по ключевым словам).
      • Возвращает результат в состояние.
    • Использовать @tool из LangChain, если используем langgraph с привязкой инструментов.

    Пример кода:

    from langchain_core.tools import tool
    
    @tool
    def web_search(query: str) -> str:
        """Поиск информации по запросу."""
        return f"Mock result for '{query}': some relevant data."
    
    agent_alpha = create_openai_functions_agent(llm, [web_search, read_file])
    
  3. Реализовать агента Beta

    • Аналогично, но с инструментами: calculator, translate, write_file.
    • write_file(path, content) — записывает в файл и возвращает подтверждение.
  4. Протестировать каждого агента изолированно — передать простой запрос и убедиться, что инструмент вызывается корректно.

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

Этап 3: Реализация Supervisor-агента с логикой делегирования (2–3 ч)

Действия

  1. Написать системный промпт для supervisor

    Ты – руководитель команды из двух агентов: Alpha (сбор информации) и Beta (обработка/создание).
    Проанализируй запрос пользователя, разбей на подзадачи и для каждой реши, какой агент должен её выполнить.
    Отвечай в строгом формате JSON:
    {
        "next_agent": "Alpha" | "Beta",
        "task": "детальное описание задачи для агента",
        "context": "контекст, который нужно передать агенту"
    }
    Если задача завершена, ответь {"next_agent": "FINISH", "final_answer": "..."}.
    
  2. Реализовать узел supervisor_node

    • Вызывать LLM с системным промптом и историей сообщений.
    • Парсить JSON-ответ, записывать в состояние: state["next_agent"] и state["pending_tasks"].
  3. Реализовать роутинг (логику, какой узел выполнить следующим):

    • В графе после supervisor проверяем state["next_agent"]:
      • если "Alpha" → переходим к agent_alpha_node.
      • если "Beta" → переходим к agent_beta_node.
      • если "FINISH" → выводим финальный ответ и завершаем диалог.
  4. Добавить цикл После каждого специализированного агента возвращаем управление supervisor, чтобы он мог продолжить или завершить.

  5. Обработать ошибки десериализации (если LLM вернула невалидный JSON) — повторить запрос с инструкцией исправить.

Ожидаемый результат этапа Полный граф, по которому проходит запрос: supervisor → Alpha → supervisor → Beta → supervisor → ответ.

Этап 4: Интеграция, тестирование и демонстрация (1–2 ч)

Действия

  1. Написать несколько тестовых сценариев (минимум 3):

    • Сценарий 1: «Найди последние новости по теме X и переведи их на испанский». Требует Alpha (поиск) → Beta (перевод).
    • Сценарий 2: «Посчитай сумму 1234 + 5678, а затем результат запиши в файл results.txt». Требует Beta (калькулятор + запись).
    • Сценарий 3: «Подготовь отчёт: найди данные о погоде в Лондоне и сформируй краткое резюме». Alpha (поиск) → Beta (генерация текста).
  2. Запустить систему в интерактивном режиме (цикл while с вводом пользователя).

  3. Вывести трейс вызовов инструментов и решений supervisor (используя логирование).

  4. Убедиться, что сложная задача действительно решается (все подзадачи выполняются последовательно).

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

Этап 5: Документирование и оформление (0.5–1 ч)

Действия

  1. Написать README.md с инструкцией по запуску, примером использования и описанием архитектуры.
  2. Приложить диаграмму графа (Mermaid) в README.
  3. Добавить файл requirements.txt / pyproject.toml.

Ожидаемый результат этапа Готовый репозиторий, понятный новому разработчику.


5. Критерии приемки (Definition of Done)

  • Система запускается одной командой (например, python main.py) и принимает запросы через консоль.
  • Supervisor корректно разбивает сложный запрос на подзадачи.
  • Каждый агент вызывает свои инструменты и возвращает результат supervisor.
  • Supervisor передаёт контекст (предыдущие результаты) следующему агенту.
  • Поток управления соответствует спроектированному графу (логируется).
  • Реализованы минимум два разных инструмента у каждого агента.
  • Система успешно проходит все три тестовых сценария.
  • Код покрыт юнит-тестами (pytest) на уровне инструментов и логики делегирования.
  • Добавлена обработка ошибок: невалидный JSON от LLM, недоступность инструмента, пустой ответ агента.

6. Ожидаемый результат

  • Основной файл main.py – точка входа с графом LangGraph и циклом диалога.
  • Дополнительные файлы
    • agents.py – реализация агентов Alpha и Beta.
    • tools.py – все инструменты (реальные или моки).
    • state.py – определение состояния графа.
    • prompts.py – системные промпты.
    • test_agents.py – тесты.
    • README.md с документацией.
  • Содержимое полноценная multi-agent система, демонстрирующая паттерн delegated tools.

7. Возможные сложности и их решение

СложностьРешение
LLM не соблюдает формат JSON в ответе supervisorДобавить few-shot примеры в промпт, а при ошибке парсинга переспрашивать (retry до 3 раз)
Бесконечный цикл: supervisor постоянно передаёт задачу одному агентуВвести счётчик итераций (max_delegations), после которого принудительно завершать
Агент не распознаёт, какой инструмент использоватьУточнить описание инструмента в @tool и добавить fallback-запрос к LLM
Моки не дают реалистичного поведенияНаписать моки с динамической генерацией на основе шаблонов, чтобы тесты были разнообразны
Путаница в состоянии (результаты теряются)Чётко определить ключи в State (collected_data, processed_data, pending_tasks)

8. Бюджет времени (оценка)

ЭтапВремя
1. Проектирование архитектуры1.5 ч
2. Реализация инструментов и агентов2.5 ч
3. Реализация Supervisor2.5 ч
4. Интеграция, тестирование2 ч
5. Документирование0.5 ч
Итого9 ч

Примечание Для первого раза рекомендуется заложить 2–3 дополнительных часа на отладку и исправление ошибок, характерных для multi-agent систем.


9. Связанные вопросы из базы знаний

ВопросТема
101Архитектура RAG-системы с несколькими индексами
205Использование LangGraph для пошаговых цепочек
310Паттерн “Orchestrator-Workers” в AI-системах
412Динамическое добавление инструментов в агент
508Управление контекстом в long-running агентах
623Валидация JSON-ответов от LLM (structured output)
734Обработка ошибок в графах LangGraph (fallback)
845Тестирование моков инструментов в агентных системах
889Деплой multi-agent приложений в Docker

10. Чек-лист самопроверки

  • Я разделил обязанности агентов так, чтобы каждый отвечал за один тип действий (сбор vs обработка).
  • Supervisor всегда анализирует запрос перед делегированием, а не просто передаёт всё первому агенту.
  • В коде реализована защита от зацикливания (максимум 5 делегирований).
  • Я написал минимум один end-to-end тест, который проходит от запроса до финального ответа.
  • README содержит пример запуска и один реальный кейс использования.