Главная / Статьи / Один агент с хорошим контекстом лучше роя: почему передачи ломают мультиагентный код

Один агент с хорошим контекстом лучше роя: почему передачи ломают мультиагентный код

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

1015 слов

Семь агентов, одна удалённая функция

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

+ def limit(req):            agents/a2.py
+ def rate_limit(req):       agents/a3.py
+ def check_limit(r):        agents/a4.py
+ def limiter(request):      agents/a5.py
+ def apply_limit(req):      agents/a6.py
+ def limit(req):            agents/a7.py
- def limit(req):            agents/a7.py  (removed a2's copy)

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

Если вы когда-нибудь рисовали прямоугольники с подписями Planner, Coder, Reviewer и Tester и чувствовали лёгкое удовлетворение от того, что проектируете что-то серьёзное, это про вас.

Арифметика, которой нет на слайдах

Возьмём агента, который прав в 95 процентах случаев, а это действительно хороший агент. Соедините пятерых в цепочку и посмотрите, что будет. Цикл выполняется за четыре секунды:

p = 0.95
for n in range(1, 6):
    print(n, round(p**n, 2))
1 0.95
2 0.9
3 0.86
4 0.81
5 0.77

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

Ломается на передаче

Это дольше всего не бросалось в глаза. Агент, глубоко погружённый в задачу, несёт огромный объём невысказанного состояния. Он знает, что middleware авторизации держится на изоленте, что тесты завышают покрытие и что очевидное исправление уже пробовали и оно всё сломало.

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

FIVE AGENTS

  [A1] --msg--> [A2] --msg--> [A3] --msg--> [A4]
   |             |             |             |
  full          ~300          ~300          ~300
  context       tokens        tokens        tokens
   |             |             |             |
  knows         guesses       guesses       guesses

ONE AGENT
   retrieval ---+
   memory    ---+---> [ AGENT ] ---> output
   tools     ---+         ^  |
   compaction---+         |  |
                          +--+
                     one head, one state,
                     nothing lost in transit

Лучшие аргументы за мультиагентность

Противоположная точка зрения сильна, поэтому выслушаем её как следует. Во-первых, специализация работает: на конкретной задаче агент с узким промптом обходит универсала. Во-вторых, окна контекста конечны, а пять окон дают в пять раз больше места. В-третьих, свежий контекст — единственный ревьюер, которому можно доверять. Агент, потративший шестьдесят тысяч токенов на то, чтобы убедить себя в каком-то дизайне, плохо подходит для его оценки. Наконец, исследовательские системы, которые одновременно перекапывают много источников, действительно обходят однопоточные, и этот выигрыш измерен, а не разрекламирован.

Так что распараллеливание не умерло. Просто его применяют не в том измерении.

Чтение распараллеливается, запись — нет

Считать агентов — неправильный критерий. Важно другое: принимают ли подзадачи решения, которые должны быть согласованы между собой. Чтение делится почти бесплатно, будь то сорок источников, сотня файлов или шесть утверждений на проверку, потому что никто ничего не фиксирует и нет общего состояния, которое можно разорвать.

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

hits = par([find(q) for q in qs])   # reads fan out
patch = run(req, ctx + hits)        # writes go through one head

Коротко: чтение распараллеливайте, запись пропускайте через одно место. Всё правило помещается на салфетке.

Скучная часть и есть настоящая работа

Главное здесь не «один агент», а хороший контекст, и это нудная, нефотогеничная работа:

  • поиск, который находит нужные четыре файла, а не топ-20 по косинусному сходству
  • сжатие контекста, которое выдерживает долгую сессию
  • память, которая хранит, почему подход отвергли, а не что было набрано
  • вывод инструментов, оформленный так, чтобы один вызов не съедал пол-окна

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

Попробуйте завтра

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