Теперь представим такую ситуацию: вы спросили агента "мы на прошлой неделе бронировали ресторан, напомни время". А агент умеет смотреть историю чатов только по дням. И в итоге получается что-то вроде этого:
User -- "Мы на прошлой неделе выбирали, куда пойти в НН. Что мы там решили?" --> LLM
LLM -- {
"name": "list_memories",
"arguments": '{"date":"04_15_2025"}'
} --> Agentic Framework
LLM <-- [] -- Agentic Framework
LLM -- {
"name": "list_memories",
"arguments": '{"date":"04_16_2025"}'
} --> Agentic Framework
LLM <-- [
"Write_Blogpost", "Make_Presentation"
] -- Agentic Framework
LLM -- {
"name": "list_memories",
"arguments": '{"date":"04_17_2025"}'
} --> Agentic Framework
LLM <-- [
"Find_NN_Restaurants"
] -- Agentic Framework
LLM -- {
"name": "read_file",
"arguments": '{"path":"04_17_2025/Find_NN_Restaurants.md"}'
} --> Agentic Framework
User <-- "Да, это было 17го! Ты решил сходить в Ель и мы забронировали столик на 21:00" -- LLM
Контекст в данном случае выглядит следующим образом
| assistant |
| tool result |
| tool call |
| tool result |
| tool call |
| tool result |
| tool call |
| user |
| tools definitions |
| system |
Как мы видим, у нас в контексте теперь очень много промежуточной информации. Она нужна, чтобы ответить на вопрос "когда у меня бронь", но в рамках диалога в целом - бесполезна.
Т.е. наш вопрос породил *"подзадачу"* (subtask), выполнять которую желательно в изолированном контексте. Кодинг-агенты часто сталкиваются с такими подзадачами: планирование, запуск тестов, линтеров, ревью - это все мелкие технические шаги, детали которых не так важны в контексте глобальной задачи "ЗАПИЛИ ФИЧУ".
Решение очень простое - пусть подзадачу решает *сабагент*. Т.е. мы просто создаем инструмент, внутри которого будет вызываться другой агент. Пусть он уже дергает инструменты сколько угодно - в основной контекст попадет только финальный результат
from autogen.beta import Agent, config, tools
memory_agent = Agent(
"memory-agent",
config=config.OpenAIConfig("gpt-5"),
tools=[
tools.FilesystemToolkit("./memory"),
]
)
def call_subagent(prompt: str) -> str:
return await memory_agent.ask(prompt)
agent = Agent(
"ag-claw",
config=config.OpenAIConfig("gpt-5"),
tools=[
call_subagent,
# memory_agent.as_tool() - или так
]
)
Теперь вместо одного зашумленного контекста у нас появилось 2 изолированных
| assistant | |
| subagent result | assistant |
| | tool result |
| | tool call |
| | tool result |
| | tool call |
| | tool result |
| | tool call |
| subagent call | user |
| user | |
| subagent tools | memory tools |
| claw prompt | subagent prompt |
Сабагенты - это самый распространенный паттерн мультиагентного взаимодействия сейчас. Потому что самый простой и при этом достаточно эффективный. Про хореографические паттерны поговорим в другой раз. Но концепция всегда одна и та же - если задачу можно разбить на шаги / подзадачи, которые для своего решения не требуют понимания всего контекста - лучше выделить нескольких агентов. Также сабагенты частично решают проблему overtooling (когда у одного агента слишком много инструментов и он сходит с ума).
Тут важно понимать, что
Subagent - это не сервис и не модуль. Это просто подконтекст. У него свой системный промпт, своя история. Но модель чаще всего та же.
В рамках этого подконтекста вы можете решать подзадачи вашего текущего диалога без захламления основного контекста.
#Agents