English translation is not available yet. Showing Russian content.

Как вы передаёте контекст между несколькими агентами (multi-agent system)?

Краткий тезис

В multi-agent системах контекст — это cache|общая память, состояние диалога или данные, которые агенты читают и обновляют. Основные механизмы передачи: shared state через message bus (Redis, RabbitMQ), global memory (общая БД), иерархическая координация (supervisor-agent) и встроенные механизмы фреймворков (AutoGen, LangGraph). LangGraph предлагает элегантное решение — единый State объект, доступный всем узлам графа, что упрощает управление контекстом и гарантирует согласованность.


1. Зачем нужна передача контекста между агентами

В multi-agent system несколько автономных агентов решают общую задачу. Каждый агент может отвечать за свою подзадачу (опрос базы данных, call|вызов API, логическое рассуждение). Чтобы результат одного агента был доступен другому, требуется механизм обмена информацией — контекстом. Контекст включает:

  • Историю диалога (предыдущие сообщения, решения);
  • Промежуточные результаты (данные, извлечённые из документов, ответы API);
  • Состояние задачи (какие шаги выполнены, какие ещё предстоят);
  • Пользовательские параметры (ID сессии, язык, настройки).

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


2. Shared state / Message bus (Redis, RabbitMQ)

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

Популярные реализации:

  • Redisin-memory key-value store с поддержкой pub/sub. Быстрый, но не гарантирует доставку сообщений при сбоях.
  • RabbitMQ — полноценный брокер сообщений с очередями, подтверждениями и гарантиями доставки.

Пример архитектуры:

  • Агент А обрабатывает запрос, кладёт результат в Redis по ключу session:123:extracted_data.
  • Агент Б подписан на событие data_ready и при получении читает extracted_data из Redis.
  • Агент Б дополняет контекст и пишет в session:123:final_answer.

Плюсы:

  • Слабая связанность — агенты не знают друг о друге;
  • Масштабируемость — можно легко добавить новых агентов.

Минусы:

  • Высокая латентность (сеть, сериализация);
  • Необходимость управления конкурентным доступом (блокировки, транзакции);
  • Сложность отладки распределённого состояния.

3. Global memory — общая база данных

В этом подходе все агенты используют единую БД (реляционную или векторную) для чтения и записи контекста. Обычно это PostgreSQL или MongoDB для структурированных данных, или FAISS + SQLite для семантической памяти.

Схема таблицы:

CREATE TABLE agent_context (
    session_id TEXT,
    agent_name TEXT,
    step INTEGER,
    key TEXT,
    value JSONB,
    timestamp TIMESTAMPTZ
);

Каждый агент пишет записи с временной меткой, а последующий агент читает последние значения по session_id.

Плюсы:

  • Простота — стандартные инструменты и запросы;
  • Долговременное хранение (контекст сохраняется между запусками).

Минусы:

  • Узкое место — БД может стать бутылочным горлышком;
  • Необходимость очистки устаревших данных;
  • Нет встроенной подписки на изменения (приходится полагаться на polling).

4. Иерархическое управление (supervisor-agent)

В этой архитектуре есть агент-супервайзер, который координирует работу подчинённых агентов. Супервайзер:

  1. Принимает запрос пользователя.
  2. Разбивает задачу на подзадачи.
  3. Последовательно или параллельно вызывает воркеров, передавая им необходимый контекст.
  4. Собирает результаты в единый ответ.

Передача контекста происходит явно: супервайзер формирует контекстный пакет (например, словарь Python) и передаёт его каждому воркеру. Воркер может дополнить пакет и вернуть обратно.

Фреймворки: Microsoft AutoGen поддерживает это через UserProxyAgent и AssistantAgent, где супервайзер играет роль диспетчера.

Плюсы:

  • Централизованное управление — легко контролировать порядок и ошибки;
  • Нет проблем с консистентностью, потому что один владелец состояния.

Минусы:

  • Супервайзер — единая точка отказа;
  • При большом числе агентов супервайзер может стать узким местом.

5. AutoGen — встроенная передача сообщений

AutoGen от Microsoft — фреймворк для построения multi-agent приложений. Ключевой механизм — сообщения: агенты общаются друг с другом, отправляя и принимая объекты Message.

Пример кода:

from autogen import AssistantAgent, UserProxyAgent, config_list_from_json

config_list = config_list_from_json("OAI_CONFIG_LIST")

assistant = AssistantAgent(name="assistant", llm_config={"config_list": config_list})
user_proxy = UserProxyAgent(name="user_proxy", human_input_mode="ALWAYS")

# Запуск диалога — контекст передаётся через историю сообщений
user_proxy.initiate_chat(assistant, message="Какая средняя температура на Марсе?")

Как передаётся контекст:

  • История диалога хранится в ConversableAgent;
  • Каждое новое сообщение содержит полный контекст предыдущих сообщений (в виде списка);
  • Можно настраивать callback`и для фильтрации или модификации контекста.

Плюсы:

  • Минимум кода — агенты «сами» запоминают историю;
  • Поддержка групп (GroupChat), где агенты делятся контекстом.

Минусы:

  • При длинных диалогах растёт количество токенов (лимитировано моделью);
  • Нет встроенной долговременной памяти — всё в контексте LLM.

6. LangGraph — единый state object

LangGraph от LangChain — библиотека для построения графов агентов. Каждый узел (агент) может читать и модифицировать единый объект состояния (State), который автоматически передаётся между узлами.

Концепция:

  • Определяем схему состояния (например, TypedDict или Pydantic BaseModel);
  • Каждый узел возвращает обновлённое состояние (словарь, который мержится);
  • LangGraph сам следит за потоком данных.

Пример:

from typing import TypedDict, Annotated, Sequence
from langgraph.graph import StateGraph, END

class AgentState(TypedDict):
    messages: Annotated[Sequence[str], "messages"]
    context: dict
    next_agent: str

def agent_a(state: AgentState):
    new_msg = {"role": "agent_a", "content": "Обработал запрос"}
    return {"messages": [new_msg], "context": {"key": "value"}, "next_agent": "agent_b"}

def agent_b(state: AgentState):
    # Используем state["context"] и state["messages"]
    response = f"Получен контекст: {state['context']}"
    return {"messages": [{"content": response}], "next_agent": END}

graph = StateGraph(AgentState)
graph.add_node("agent_a", agent_a)
graph.add_node("agent_b", agent_b)
graph.set_entry_point("agent_a")
graph.add_edge("agent_a", "agent_b")
graph.add_edge("agent_b", END)

app = graph.compile()
result = app.invoke({"messages": [], "context": {}, "next_agent": "agent_a"})

Плюсы:

  • Явное и прозрачное состояние;
  • Легко отлаживать — можно сериализовать state на каждом шаге.

Минусы:

  • Требует чёткого определения схемы;
  • При сложной логике ветвления граф может стать громоздким.

7. Простой подход: глобальный словарь с session_id

Для прототипов или маленьких систем можно использовать in-memory словарь (Python dict), где ключ — session_id, значение — произвольный контекст. Агенты получают этот словарь через глобальную переменную или dependency injection.

Пример:

context_store: dict[str, dict] = {}

class Agent:
    def __init__(self, session_id: str):
        self.session_id = session_id
        self.context = context_store.setdefault(session_id, {})

    def run(self):
        self.context["step1_done"] = True
        return self.context  # можно передать другому агенту

Плюсы:

  • Простота реализации;
  • Не нужны внешние сервисы.

Минусы:

  • Не масштабируется: при нескольких процессах словарь не синхронизирован;
  • Нет устойчивости к сбоям;
  • Подходит только для однопроцессных демо.

8. Сравнительная таблица подходов

ПодходСвязанностьМасштабиру‑ емостьУстойчивостьПростотаСкорость
Message bus (Redis/RabbitMQ)СлабаяВысокаяСредняя (требует персистентности)СредняяСредняя (сеть)
Global DB (PostgreSQL)СредняяВысокая (с шардингом)ВысокаяСредняяНизкая (диск)
Supervisor-agent (иерархия)СильнаяНизкая (supervisor bottleneck)Низкая (single point of failure)ВысокаяВысокая (in‑memory)
AutoGen (сообщения)СредняяСредняя (все в одном процессе)НизкаяВысокаяВысокая
LangGraph (state object)СредняяВысокая (граф независим от процессов)Средняя (состояние в памяти)СредняяВысокая
Глобальный dict in-memoryВысокаяНе масштабируетсяНизкаяОчень высокаяОчень высокая

9. Рекомендации по выбору

  • Прототип / хак: глобальный словарь или минимальный supervisor-agent.
  • Продакшен с несколькими сервисами: message bus (RabbitMQ) + Redis для быстрого доступа.
  • Когда нужна долговременная память: global DB + TTL на записи.
  • Уже используете LangChain: LangGraph — естественный выбор, единый state упрощает отладку.
  • Команда Microsoft-стек: AutoGen с его встроенным менеджментом сообщений.

Важно: в сложных системах комбинируют несколько подходов — например, LangGraph для оркестрации агентов внутри одного процесса, а Redis для обмена между микросервисами.


10. Пет-проект для закрепления

Задача

Построить multi-agent систему «Групповой чат ассистентов»:

  • Агент A: поиск информации в Wikipedia.
  • Агент B: извлечение ключевых фактов.
  • Агент C: генерация ответа пользователю.
  • Контекст (запрос, найденные статьи, факты, финальный ответ) должен передаваться между агентами.

Инструменты

Шаги

  1. Определите State с полями: query, wiki_results, facts, final_answer.
  2. Создайте три узла: search_agent, extract_agent, answer_agent.
  3. Каждый узел принимает state, модифицирует нужные поля и возвращает обновлённый dict.
  4. Соедините узлы последовательно: search → extract → answer.
  5. Реализуйте версию с parallel branching (например, search_agent может вызвать extract_agent несколько раз).
  6. Сравните с реализацией на AutoGen (групповой чат с GroupChat).

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

  • Работающий чат-бот, который отвечает на вопросы, комбинируя поиск и извлечение фактов.
  • Понимание, как LangGraph автоматически передаёт state между узлами, и как AutoGen управляет историей сообщений.
  • Профилирование производительности: сколько времени занимает передача контекста.

11. Связь с другими вопросами

ВопросТемаСвязь
50Архитектура AI-агентовОпределяет базовые компоненты, контекст — ключевая часть архитектуры.
52Оркестровка вызовов инструментовПередача контекста часто происходит при вызове инструментов.
53Память агента (Memory)Долговременная память — частный случай глобального контекста.
55Планирование задач у агентовSupervisor-agent использует контекст для планирования.
60Интеграция RAG и агентовRAG возвращает контекстные документы, которые передаются между агентами.

12. Навигация


Навигация