Разговорная парадигма AutoGen
AutoGen смотрит на мультиагентную систему под особым углом: всё взаимодействие — это обмен сообщениями. Агент получает сообщение, что-то с ним делает (зовёт LLM, выполняет код, спрашивает человека) и отправляет ответное сообщение собеседнику. Координация выражается не графом и не вызовами функций, а диалогом — естественной для людей метафорой.
Это отличает AutoGen от LangGraph из модуля 03. Там мы строили граф: узлы, рёбра, общее состояние. Здесь — беседу: участники, сообщения, реплики по очереди. Оба подхода решают одну задачу (оркестрация агентов), но мыслят по-разному: LangGraph — «поток управления как структура», AutoGen — «координация как разговор».
У AutoGen непростая история. Классический API (ConversableAgent, initiate_chat) живёт в пакете pyautogen и в форке AG2. Microsoft параллельно выпустила переписанную архитектуру AutoGen 0.4 (autogen-agentchat) с асинхронным ядром. Концепции — агенты-собеседники, обмен сообщениями — общие для всех версий. Мы изучаем именно их на классическом, наиболее документированном API; перенести идеи на новую версию несложно.
ConversableAgent — универсальный агент
ConversableAgent — базовый класс всех агентов AutoGen. «Conversable» = «способный к разговору»: у него есть имя, поведение (системный промпт + конфиг LLM) и методы, чтобы слать и принимать сообщения. Почти все остальные агенты (AssistantAgent, UserProxyAgent — следующий урок) — это ConversableAgent с предустановленными настройками.
from autogen import ConversableAgent
llm_config = {"model": "gpt-4o-mini", "api_key": "sk-..."} # конфиг модели
agent = ConversableAgent(
name="assistant", # имя — адрес в разговоре
system_message="Ты вежливый помощник.", # роль/поведение (как роль в промпте)
llm_config=llm_config, # какой моделью думать
human_input_mode="NEVER", # не спрашивать человека
)
Ключевые параметры:
name— уникальное имя; по нему агента адресуют в разговоре.system_message— системный промпт: кто этот агент и как себя ведёт (привет уроку про роли из модуля 01).llm_config— конфигурация LLM (модель, ключ, параметры). Если поставитьFalse— агент не использует LLM (например, чисто исполнитель кода или прокси человека).human_input_mode— спрашивать ли человека:"NEVER"(автономно),"ALWAYS"(каждый ход),"TERMINATE"(только перед завершением).
Как агенты обмениваются сообщениями
Сообщение в AutoGen — это знакомый по модулю 01 формат {"role": ..., "content": ...}. Разговор — это растущий список таких сообщений, общий для собеседников. У агента есть низкоуровневые методы send / receive и метод generate_reply, который по истории формирует ответ.
Важная деталь: роль (user/assistant) в сообщении — относительная. С точки зрения каждого агента собеседник — это «user», а его собственные ответы — «assistant». AutoGen сам ведёт эту перспективу для каждого участника, тебе об этом думать обычно не нужно.
initiate_chat: запуск диалога
Вручную дёргать send/receive не нужно — есть initiate_chat. Один агент инициирует разговор с другим, передаёт стартовое сообщение, и AutoGen прокручивает обмен репликами автоматически, пока не сработает условие остановки.
from autogen import ConversableAgent
llm_config = {"model": "gpt-4o-mini", "api_key": "sk-..."}
# Два специализированных агента (разные system_message — разные роли)
comedian = ConversableAgent(
name="comedian",
system_message="Ты комик. Шути коротко и по делу.",
llm_config=llm_config, human_input_mode="NEVER",
)
critic = ConversableAgent(
name="critic",
system_message="Ты критик юмора. Оцени шутку одним предложением.",
llm_config=llm_config, human_input_mode="NEVER",
)
# critic запускает разговор с comedian
result = critic.initiate_chat(
comedian,
message="Пошути про программистов.",
max_turns=2, # ограничиваем число обменов
)
print(result.summary) # итог беседы
Что произошло: critic отправил стартовое сообщение, comedian ответил шуткой, critic её оценил — и на этом max_turns=2 остановил беседу. Никаких рёбер и состояния — просто два агента поговорили. initiate_chat вернул объект с историей и summary разговора.
Без ограничения два LLM-агента могут «вежливо беседовать» бесконечно — каждый отвечает на ответ другого. Всегда задавай max_turns и/или условие завершения (is_termination_msg, ниже). Это прямой аналог recursion_limit из LangGraph: страховка от вечного цикла, только здесь цикл — это диалог.
Как разговор завершается
У беседы должно быть условие выхода. AutoGen даёт несколько механизмов остановки:
max_turns— жёсткий лимит числа обменов репликами. Самый простой предохранитель.is_termination_msg— функция-предикат: если сообщение ей подходит (например, содержит «TERMINATE»), разговор завершается. Так агент сам сигналит «я закончил».max_consecutive_auto_reply— сколько автоответов подряд агент даёт без участия человека.
agent = ConversableAgent(
name="solver",
system_message="Реши задачу. Когда закончишь — ответь словом TERMINATE.",
llm_config=llm_config,
human_input_mode="NEVER",
# разговор остановится, как только в сообщении встретится TERMINATE
is_termination_msg=lambda m: "TERMINATE" in (m.get("content") or ""),
)
Как и в Reflection/циклах из модуля 03, надёжнее всего два условия выхода: осмысленное (is_termination_msg — агент сам решил, что готово) и аварийное (max_turns — на случай, если он не остановится). Первое отвечает за нормальный сценарий, второе — за защиту от зацикливания.
Откуда берётся ответ
Когда агент получает сообщение, он не обязательно идёт в LLM. У ConversableAgent есть цепочка генераторов ответа (reply functions), которые пробуются по порядку: проверить условие завершения → выполнить код, если он есть в сообщении → спросить человека (если режим требует) → и только потом сгенерировать ответ через LLM. Первый сработавший генератор и даёт ответ.
Это делает ConversableAgent гибким: один и тот же класс может быть «думающим» агентом (LLM), «исполнителем» (запуск кода без LLM) или «прокси человека» — всё определяется конфигом и набором reply-функций. Регистрировать свои генераторы можно через register_reply, но на старте хватает встроенного поведения.
Типичные ошибки
Без max_turns или is_termination_msg два агента могут беседовать бесконечно, сжигая токены. Всегда задавай условие остановки.
Если завершение завязано на слово TERMINATE, но в system_message не сказано его писать — агент его не напишет, и разговор не остановится. Условие остановки и промпт должны быть согласованы.
Имя — это адрес в разговоре. Два агента с одинаковым name создают путаницу в маршрутизации сообщений. Имена должны быть уникальными.
Агенту-исполнителю кода или прокси человека LLM не нужен — ставь llm_config=False. Иначе он будет лишний раз дёргать модель (и тратить токены) там, где должен просто выполнить действие.
Шпаргалка
from autogen import ConversableAgent
# ИДЕЯ: мультиагент = разговор; агенты обмениваются сообщениями
# Создание агента
agent = ConversableAgent(
name="assistant", # адрес в разговоре (уникальный!)
system_message="Ты ...", # роль/поведение
llm_config={"model": "...", "api_key": "..."}, # или False — без LLM
human_input_mode="NEVER", # NEVER | ALWAYS | TERMINATE
is_termination_msg=lambda m: "TERMINATE" in (m.get("content") or ""),
)
# Запуск диалога: один агент инициирует разговор с другим
result = a.initiate_chat(b, message="...", max_turns=2)
result.summary # итог беседы
# Остановка:
# max_turns — жёсткий лимит обменов (предохранитель)
# is_termination_msg — агент сам сигналит "готово" (логика)
# max_consecutive_auto_reply — автоответов подряд без человека
# Сообщение = {"role": "user"|"assistant", "content": "..."}
# роль ОТНОСИТЕЛЬНА: собеседник = user, свои ответы = assistant
# Правила:
# • ВСЕГДА условие остановки (предохранитель + логика)
# • уникальные имена агентов
# • нет LLM у агента → llm_config=False
# • TERMINATE в условии ⇒ упомяни его в system_message
Практическое задание
Собери первый разговор агентов:
Задание: диалог двух ConversableAgent
- Установи
pyautogen(или AG2), настройllm_configсо своей моделью и ключом. - Создай двух агентов с разными ролями через
system_message— например, «учитель» и «ученик»: ученик задаёт вопросы, учитель отвечает. - Запусти диалог через
initiate_chatсmax_turns=3. Выведиresult.summaryи посмотри полную историю. - Поменяй
human_input_modeна"ALWAYS"у одного агента и поучаствуй в разговоре вручную. Чем отличается поведение? - Добавь завершение по
is_termination_msg(словоTERMINATE) и не забудь упомянуть это в системном промпте. Проверь, что разговор останавливается «по смыслу», а не только по лимиту. - Со звёздочкой: сделай третьего агента-«критика» и устрой беседу так, чтобы после ответа учителя критик его оценивал (пока без GroupChat — просто цепочкой initiate_chat).
Что дальше
Ты освоил базовый кирпичик AutoGen — агента-собеседника. Дальше — два самых ходовых вида ConversableAgent и классический паттерн их связки: AssistantAgent (думает) и UserProxyAgent (исполняет/представляет человека).