Розділ 14. Оркестрація агентів¶
Один агент — це початок. Ми даємо задачу, він читає код, пише, запускає тести і повертається з результатом. Усе, що книжка досі казала про сесію, — це про нього: межа контексту, проксі, норми, контур контролю.
Переважно ми працюємо з декількома агентами. Один розкладає задачу на частини і роздає їх іншим, кожному з власним контекстом, часто паралельно і в окремих гілках. Хтось із них працює п’ять хвилин, хтось — кілька годин без перерви. Результати повертаються, їх зводять докупи, і до вас приходить одне повідомлення: готово.
Агента, який розподіляє роботу і збирає результати, далі я називаю оркестратором, а тих, кому він роздає частини, — субагентами. Слово «оркестрація» інженерія вже знає з Kubernetes, про який ішлося в розділі 13: система, що сама розподіляє і перезапускає сервіси на багатьох машинах. Також цього головного агента можна назвати контролером.
Що змінилося для вас? Кроків стало в кілька разів більше, ніж ви здатні прочитати, і з них ви бачите лише останнє повідомлення. Хто в такій системі тримає ціль?
Розділ 2 відповів би коротко: кожен новий агент додає машинного різноманіття, а ваше лишається тим самим — як у пастуха, якому до однієї отари додали ще дві. Розділ 13 зібрав контур контролю для одного агента; тут контурів кілька — і найцікавіше відбувається між ними.
Копії — ще не система¶
Перше, що хочеться зробити з агентами, — помножити їх. Один агент рев’юває пул-реквест добре, три рев’юватимуть утричі надійніше. Один шукає причину інциденту, п’ятеро знайдуть її вп’ятеро швидше.
Звучить як арифметика, тільки арифметика тут інша.
Три агенти на тій самій моделі, з тим самим системним промптом і тим самим контекстом — це не три перевірки, а одна, виконана тричі. У них та сама статистика, ті самі сліпі зони і та сама внутрішня ціль — правдоподібність, про яку був розділ 6. Помилку, якої не бачить перший, з великою ймовірністю не побачать і двоє інших. Разом вони дадуть не впевненість, а її відчуття: три «погоджено» замість одного.
У системній теорії є правило: сукупність однакових елементів — множина, а не система, хоч скільки їх буде. Систему утворює різниця між елементами, і саме там, де вони взаємодіють. Однакові виконавці на одній справі не додають цілому нових властивостей.
Що ж тоді додає? Різниця. Агент, який пише код, і агент, який його перевіряє, мають відрізнятися там, де це важливо для перевірки: інший контекст — рев’ювер бачить специфікацію і тести, але не бачив міркувань автора; інші критерії; інколи інша модель. Субагенти, що шукають причину інциденту, корисні, коли кожен дивиться у своє джерело: один — у логи додатку, другий — у логи воркерів, третій — у метрики й історію деплоїв. Кожна така відмінність — розрізнення, якого не було в іншого.
Однакових можна використати інакше — як прилад. Запустити ту саму задачу тричі і взяти не найкращу відповідь, а те, що збіглося у всіх трьох: так розділ 12 відділяв рішення від шуму. Але тоді це вже вимірювання, і розбіжність між прогонами показує, де шум.
Ремонт із прорабом¶
Уявимо ремонт квартири.
Електрик, сантехнік, штукатур, плиточник. Кожен — майстер свого: електрик розведе проводку із заплющеними очима, плиточник покладе плитку шов у шов. Кожен працює у своїй кімнаті, своїм інструментом, у свій день. І кожен, якщо спитати, скаже, що зробив добре, — і не збреше.
Закінчення робочого тижня. Штукатур учора вивів стіну в коридорі під фарбу. Сьогодні прийшов електрик і пробив у ній штробу під новий вимикач: перфоратор, пил на пів квартири, свіжа штукатурка шматками на підлозі. Сантехнік вивів трубу точно за своєю схемою — туди, де за кресленням дизайнера стоятиме шафа. Плиточник підняв підлогу у ванній на сантиметр вище, ніж розраховував той, хто замовляв двері, і двері тепер не зачиняються.
Кожен зробив своє, а квартира не готова. Брак живе не в роботі когось із них, а на стиках — там, де робота одного стає основою для роботи іншого.
Хто за це відповідає? Прораб. І добрий прораб не кладе плитку. Він не тримає перфоратор і не стоїть за спиною в електрика: почне — зробить одну кімнату, а решта стоятиме. Він тримає інше.
Креслення — одне на всіх. Висота підлоги, місця розеток, де стоїть шафа: усе записано до того, як перший майстер увійшов у квартиру, і однаково для всіх. Електрик і плиточник можуть ніколи не зустрітися — у них є креслення.
Порядок робіт. Спершу проводка й труби, потім штукатурка, потім плитка — бо кожен наступний шар закриває попередній.
І приймання. На будівництві є документ із промовистою назвою — акт на приховані роботи. Поки проводку не закрили штукатуркою, її приймають: дивляться, міряють, фотографують. Потім стіна гладка, і що всередині, вже не видно. Перевірити, чи йде провід там, де намальовано, можна лише перфоратором. Прораб, який пропустив цей момент, проводки вже не побачить ніколи — тільки вимикачі на стіні.
Креслення, порядок, приймання перед тим, як закрити, і стики, за які не відповідає жоден майстер окремо, — з цього складається робота прораба.
Що видно нагору¶
Прораб не стоїть за спиною в електрика не тому, що лінується: кроки нижнього рівня з рівня вище не видно.
Між рівнями немає прямого зв’язку. Вищий рівень впливає на нижній лише через ціле — через задачу, яку дав, і результат, який прийняв. Оркестратор дає субагентові задачу й отримує результат. Що субагент робив між ними — які файли відкрив, які гіпотези відкинув, що вирішив не перевіряти, — для оркестратора не існує. Для вас, ще на рівень вище, — тим паче.
Можна спробувати пролізти крізь рівень і читати кожен крок кожного агента. Тоді оркестрації немає: є ви і купа кроків, яку ви читаєте самі, — той самий пастух з розділу 2, тільки отар тепер кілька. Оркестрація, де людина стежить за кожним кроком, від одного агента не відрізняється нічим, крім утоми.
Звідси три наслідки.
Перший: для рівня вище субагент — точка. Нагору доходить не робота, а стислий звіт про неї, і з цього звіту видно лише те, що відхилилось і про що домовились повідомити. Що саме має повернутися, задають до старту. Розділ 13 називав це видимим слідом, і тут він потрібен на кожному стику. Субагент, якому не сказали, що повертати, поверне «готово» — найкоротший правдоподібний звіт.
Другий: ви бачите лише власні зв’язки. Ваш зв’язок — з оркестратором. Що оркестратор написав субагентові, що субагент відповів, що два субагенти залишили один одному в спільному файлі — ви не бачили. Розмови агентів між собою для вас так само невидимі, як домовленість електрика зі штукатуром, що «штробу потім затремо».
Третій: кожен рівень коштує. Задачу треба розписати і роздати, результати — зібрати, звести і перевірити на стиках. Кожен проміжний рівень з’їдає частину часу й токенів на цей перерозподіл, і що більше рівнів, то менша частка витраченого доходить до самої справи. Тому агентів має бути стільки, скільки в задачі справді є незалежних частин, і не більше. Оркестратор, який запускає десять субагентів на задачу з трьох частин, додає сім виконавців без власної частини — зате зі стиками до всіх інших.
Проксі від проксі¶
Розділ 6 описав ціль на трьох рівнях: у голові, у полі вводу і в оптимізації системи. Між першим і другим стоїть проксі — формулювання, яке ви написали замість цілі.
В оркестрації поле вводу субагента пишете не ви. Його пише оркестратор: розкладає вашу задачу і для кожної частини формулює свою. Це проксі від проксі. Ви сформулювали ціль, оркестратор переказав її частинами, субагент оптимізує переказ. Якщо у вашому формулюванні було порожнє місце, оркестратор заповнить його правдоподібним — і роздасть це заповнення всім гілкам одразу.
Помилка в системі агентів ходить у два боки. Згори донизу: припущення оркестратора йде в усі гілки, і кожна гілка додає до нього ще своє. Знизу догори: помилка однієї гілки піднімається разом з її результатом і входить у зібране ціле. Що більше гілок і рівнів, то більше місць, де помилка народжується, і довший шлях, який вона проходить без перевірки.
Звідси два правила.
Перше: одна ціль на субагента. Розділ 13 показав, що агент із двома цілями — це дві лінії на один автомат. Задача, яку можна описати лише через «і заодно», — насправді дві задачі. Якщо цілей у системі більше, ніж часу й уваги, щоб довести кожну до кінця, результат не гарантований, хоч би що робили виконавці.
Друге: спільну міру задає рівень вище. Результати двох субагентів можна порівняти і звести лише за мірою, однаковою для обох. Самі субагенти такої міри не мають: кожен міряє себе тим, що йому сказали. Тому критерії приймання пише рівень над ними і не віддає тим, кого ними міряють. Агент, який сам пише собі критерії і сам себе за ними приймає, буде прийнятий завжди.
Що лишається диспетчерові¶
Що ж робить людина, коли кроки робить не вона?
Вона стає диспетчером: не наглядає за кроками, а розподіляє, приймає і зупиняє. Роботи тут не менше, ніж коли ви пишете код самі, просто вона інша, і жоден агент не зробить її замість вас.
Тут діє та сама арифметика, що й у розділі 2. Той, хто організовує систему, мусить бути організований не гірше за неї. Якщо ви не здатні розкласти задачу на частини і назвати, як перевірити кожну, оркестратор теж не здатен — він лише вдаватиме, що здатен.
Диспетчер тримає ціль, спільну міру, норми і точки зупинки — кожну з них до старту.
Ціль. Опис цілі з розділу 6 — до запуску: що хочу отримати і як перевірю. І одне питання перед стартом, яке з одним агентом можна пропустити, а з кількома — ні: чи взагалі можна отримати потрібне з того, що є? Якщо в репозиторії немає тестів на модуль, жоден набір субагентів не скаже, чи міграція його не зламала. До старту це видно за п’ять хвилин, після — коли агенти вже відпрацювали кілька годин.
Спільна міра. Креслення прораба. Критерії приймання, однакові для всіх гілок: контракт між шарами, формат звіту кожного субагента, тест, який має пройти зібраний результат, а не кожна частина окремо. І ще — хто перевіряє стики: кожен субагент перевіряє свою частину, а стики не перевіряє ніхто, поки їх не доручили комусь окремо.
Норми. Нормативна база з розділу 12 — єдине «зрозуміти», яке є в кожного субагента до старту. Субагент не чув вашої розмови з оркестратором годину тому: що в його сесії — те і в грі, і більше нічого. Норма, яка живе лише у вашій розмові, до нього не доходить. А великий колектив без того, що його об’єднує, розпадається на групи, кожна з яких робить своє. Спільний файл норм і є таким клеєм.
Точки зупинки. Акт на приховані роботи. Перед кожним кроком, після якого перевірити вже не вийде, — міграція на продакшн-базі, деплой, лист клієнтові, видалення гілки, — система зупиняється і чекає на людину. І правило за замовчуванням для кожного субагента: якщо не знаєш однозначно, що робити, — не роби, зупинись і поверни питання. Дія навмання збільшує розрив між потрібним і зробленим, зупинка — ні.
Але зупинка коштує часу: питання йде нагору, відповідь — донизу, і поки вона йде, гілка стоїть. Тому зупинок має бути небагато, і стояти вони мають там, де помилка дорожча за чекання.
Ще одне з розділу 13 — пружність. Субагент, який відповідає «так не вийде, і ось чому», цінніший за того, що на будь-яку задачу повертає «зроблено». З одним агентом заперечення ви почуєте самі. У системі агентів його треба передбачити: дати субагентові формат, у якому «ні» — законний результат, а не провал.
А обсяг автономії системи агентів міряють так само, як одного агента в розділі 13: порціями — стільки роботи, скільки система робить за один захід до перевірки, — і зупинками, коли робота повернулась до людини. Тільки рахувати зупинки доводиться на кожній гілці окремо і на стиках окремо.
Сімнадцять тисяч рядків¶
Цю книжку я пишу з агентами, і кожен її розділ — невелика система агентів.
Перша спроба. Розділ 2 писав один агент за один вечір: чернетка, рев’ю, полірування і три схеми — в одній сесії. Монографій, на логіці яких стоїть книжка, він не відкривав — переказував з пам’яті. Рев’ю робив той самий агент, що писав, і текст пройшов його легко: та сама статистика, ті самі сліпі зони. Схеми він намалював одразу, не спитавши, які потрібні. Зовні розділ був готовий, з позначкою «переглянуто й відполіровано».
Наступного дня довелося переписувати секцію, де закономірність із практики була подана як закон збереження. А за наступні тижні я лишив на розділі п’ятдесят дев’ять правок. Агент справлявся з кожним кроком окремо. Бракувало іншої позиції: усе писалося і перевірялося з одного місця.
Друга спроба — цей розділ. Тепер розділ проходить через кількох агентів, і кожен відрізняється від інших там, де це важливо.
Спершу — три агенти-читачі, паралельно, по одному на монографію: разом сімнадцять тисяч рядків розпізнаного російського тексту. У кожного свій контекст — лише його монографія, — і однаковий для всіх формат звіту: закономірність, її суть, дослівні цитати з номерами рядків. Формат і є спільною мірою: цитату з номером рядка можна перевірити за хвилину. Працювали вони від двох до п’яти хвилин. Їхніх кроків не бачив ні я, ні оркестратор — лише конспекти, які лягли у файл і переживуть будь-яку сесію.
Потім — зупинка. Оркестратор склав план розділу з трьома варіантами метафори, сценарію й анти-патерну, і без мого «так» текст не писався. Ремонт із прорабом — мій вибір із трьох.
Далі моє рев’ю, потім агент полірування зі свіжим контекстом та іншою моделлю. Схеми — знову через зупинку. Переклад англійською — окремим агентом і лише після схем, коли текст уже не зміниться: спершу проводка, потім штукатурка.
Помилка з’явилась на стику між оркестратором і читачами.
Розписуючи задачу читачам, оркестратор вклав у неї власне припущення: попросив знайти в монографії, як дефекти передаються від вищих рівнів системи до нижчих. Цього формулювання я не бачив — це була його проксі для субагента. Читач повернув конспект із застереженням на самому початку: у джерелі дефекти передаються навпаки, знизу вгору. Інший читач написав, що слів «делегування» і «координація» в його монографії немає взагалі — нуль збігів, — і подав найближчі механізми окремо, позначивши, що це реконструкція, а не теза автора.
Чому це спрацювало? У читача був інший контекст — сама монографія, а не розмова з оркестратором. І формат вимагав цитат із номерами рядків: правдоподібно переказати те, чого в тексті немає, з номером рядка не вийде. Різниця позицій і слід, який можна перевірити, — і хибна проксі зупинилась на першому ж стику, а не розійшлася по розділу.
Мої кроки в цьому процесі — дві зупинки і рев’ю. Жодного конспекту я цього разу не писав. На рев’ю цього розділу я лишив шістнадцять правок — проти п’ятдесяти дев’яти на розділі 2. Але одна помилка, яку раніше я шукав би в тексті сам, до тексту вже не дійшла.
Комітет із копій¶
Анти-патерн цього розділу виглядає як ретельність.
У команді налаштовано пайплайн із трьох агентів. Перший пише код за тікетом, другий рев’юває пул-реквест, третій читає рев’ю і ставить «погоджено». Та сама модель, той самий системний промпт, той самий контекст: тікет і код. Кожен пул-реквест проходить три перевірки. Люди бачать фінальне «погоджено» і мержать.
Тікет каже: «додати знижку для постійних клієнтів». Перший агент вирішив, що постійний — це три замовлення за рік. Ніде цього не записано — це правдоподібне заповнення порожнього місця. Рев’ювер перевіряє код проти тікета і погоджується: знижка є, тести проходять. Третій бачить, що рев’ювер погодився. Те, що постійний клієнт у цій компанії — це клієнт із підпискою, а не з кількістю замовлень, не знав жоден із трьох: цього не було в контексті жодного.
Скільки розрізнень додали другий і третій агенти? Майже жодного. Рев’ювер з тим самим контекстом і тією самою статистикою бачить у коді те саме, що бачив автор, — і так само не бачить, що «постійний клієнт» ніде не визначено. Третій погоджує рев’ю, яке написала копія автора. Активність висока: три агенти, тисячі токенів, докладні коментарі. А назовні — одне розрізнення, видане тричі, і за ним дві розмови агентів між собою, яких людина не бачила.
Діагноз за законом цього розділу: копії — не система, а перевірка з тієї самої позиції — повтор. Розділ 13 описував практику, що з часом починає працювати сама на себе: багато запусків, та сама якість. Комітет із копій — той самий стан, тільки практика в нього не виродилась, а такою була побудована.
Лікується це не четвертим агентом. Рев’юверові — інший контекст: не лише тікет і код, а й специфікація, норми команди, історія схожих багів і окреме питання «що в тікеті не визначено?». На нього рев’ювер мав би відповісти «що таке постійний клієнт?» — і зупинитись. Третьому агентові — інша міра: наприклад, інтеграційні тести, яких автор не запускав. Якщо іншої міри для нього немає, третій агент не потрібен: той, хто лише погоджує чуже погодження, з’їдає ресурс і нічого не розрізняє.
А «погоджено» перед тим, чого не відкотити, — мерж у головну гілку, деплой, — ставить людина, не агент. І кнопка «Тест» з розділу 13: навмисно підкласти в пул-реквест помилку і перевірити, чи зловить її хоч один із трьох агентів.
Оркестрація масштабується¶
З командою людей відбувається те саме. Тимлід, який читає кожен коміт кожного інженера, робить те саме, що людина, яка читає кожен крок агентів: команда є, а дивиться лише одна людина. І той самий комітет із копій — троє рев’юверів з однаковим досвідом, які погоджують те, чого не розуміє ніхто з них.
Фірма — ще рівень: керівник, до якого доходить лише «усе за планом», бачить відділи так само, як ви бачите субагентів, — точками.
Коли практика справді готова до оркестрації, а коли це спроба перестрибнути стадію, — розмова розділу 15.
У вашому ремеслі¶
Стики є в кожному ремеслі, де роботу ділять на частини.
Текст. Три агенти паралельно пишуть три розділи інструкції. Кожен розділ гарний. Але той самий екран в одному зветься «панель», у другому «дашборд», у третьому «головна». Брак живе на стику. Спільна міра тут — глосарій, написаний до старту. Окремий агент перевіряє лише терміни між розділами.
Аналітика. П’ять субагентів аналізують п’ять джерел даних, оркестратор зводить висновки в звіт. Кожен висновок правдоподібний. Але «активний користувач» у двох джерелах означає різне, і звіт це приховує. Що вважати активним, вирішує той, хто ставив питання. Зупинка — перед тим, як звіт піде замовникові.
Дизайн. Три агенти генерують варіанти макета з того самого брифу. Виходять три версії того самого середнього. Різниця з’являється, коли кожен отримує своє обмеження чи свій референс. Обрати з варіантів може лише той, у кого є критерії. Цього кроку не віддають тим, хто варіанти генерував.
Наостанок — три питання до вашої практики.
— Скільки агентів працює у вашій системі — і чим вони відрізняються один від одного, крім назви в конфігурації?
— Що ваш оркестратор написав субагентам в останньому запуску? Якщо не знаєте — хто перевіряв цю проксі?
— І глибше: який крок у вашому процесі — акт на приховані роботи, після якого перевірити вже не вийде? Хто його приймає?
