Головна / Статті

Чому агенти довгострокового планування потребують Harness: як Deep Agents керує станом та контекстом.

Чому агентам з довгим горизонтом потрібні пристрої кріплення: як LangChain Deep Agents бореться з розпадом контексту за допомогою чотирьох основ, проміжного програмного забезпечення, бекендів файлової системи та ізольованих підагентів.

Видавець: REACTAPP.TOP12 хв читання2727 слів

Джерела: The Deep Agents Architecture, Part 1: Understanding the Agent Harness

Найпростіший дизайн агента — це цикл викликів інструментів. Модель читає запит, обирає інструмент, запускає його, читає результат, знову робить вибір та продовжує, поки не припинить викликати інструменти. LangChain відверто говорить про межі такого підходу: такі агенти є „поверхневими“, вони не здатні планувати та діяти у рамках довгих, складних завдань. Це не недолік, притаманний лише одній платформі — це наслідок того, що між моделлю та контекстом, який постійно зростає, нічого не залишається.

Найкращим доказом того, що стеля є структурною, є роботи трьох команд, які ніколи не координувалися. Anthropic досяг цього під час створення Claude Code, OpenAI — за допомогою Deep Research, а Butterfly Effect — настільки сильно, що Manus довелося перебудовувати чотири рази. Усі вони опиралися на чотири однакові компоненти: інструмент планування, делегування завдань підагентам, доступ до файлової системи та детальний запит. Незалежні зусилля різних компаній, які дійшли до однакової архітектури, свідчать про те, що проблема сама вимагала цього, а не особисті уподобання хтось із розробників.

Справжнім механізмом є зіпсований контекст

Хочеться сказати, що тривалі запуски агентів провалюються через заповнення вікна контексту. Але це не є справжнім механізмом.

Модель, яка бере участь у тривалій розмові, приймає гірші рішення, ніж та сама модель під час короткої розмови, навіть якщо більша частина її „вікна“ все ще вільна. Кількість уваги, яку може отримати кожен окремий токен, зменшується зі зростанням кількості сусідніх токенів, а зниження співвідношення сигнал/шум значно погіршує якість результату ще до того, як „вікно“ заповниться. Цей ефект задокументований, а не є анекдотичним: моделі надійно гірше отримують інформацію з середини довгого контексту, віддаючи перевагу токенам, розташованим ближче до початку та кінця.

Це змінює підхід до пошуку рішення. Якби проблемою була обмежена ємність, більше „вікна“ би її вирішило. Насправді проблема полягає у розведенні інформації: модель все ще здатна до роботи, але потрібна їй інформація загублюється серед усього, що було раніше. Це проблема організації інформації, а не її обсягу, і додатковий простір у „вікні“ нічим не допомагає у вирішенні цієї проблеми.

Прогалина, яку не було створено для подолання ні LangChain, ні LangGraph

LangGraph зосереджується на стійкій роботі: контрольні точки, стрімінг, людський огляд та збереження даних між потоками. Його справжнім аналогом є Temporal, а не інші фреймворки агентів. Він забезпечує, щоб агент продовжував працювати після збою, але не каже нічого про те, чи продовжує агент чітко мислити через чотири години. LangChain знаходиться на вищому рівні та надає абстракції: цикл виклику інструментів, структурований контент та проміжне програмне забезпечення для налаштувань. Проте стандартний цикл, створений на основі цих абстракцій, є саме тим поверхневим циклом, про який йшлося раніше. Стійкість та абстракція є реальними та необхідними, проте жодна з них не відповідає на питання про те, чи залишається робочий контекст моделі чистим.

Це можна перевірити за тим, як під’єднані елементи. Оголошені залежності Deep Agents — це langchain, langchain-core, langchain-anthropic, langchain-google-genai та langsmith. LangGraph у цьому списку немає. Він присутній лише тому, що LangChain від нього залежить. Структура є суворо вкладеною: Deep Agents — над LangChain, який, у свою чергу, — над LangGraph, а не три окремі компоненти, додані разом. Ні на рівні виконання, ні на рівні фреймворку ніколи не існувало контролю за чистотою контексту, оскільки шар, який мав би цим керувати, розташований вище обох.

Теза: проблема стану, а не проблема міркування

Складна робота, щодо певної конкретної та чітко визначеної категорії складності, є проблемою управління станом, а не проблемою міркування.

Існує простий спосіб визначити, якого типу проблема стоїть перед завданням. Уявіть собі кваліфікованого колегу, який щогодини втрачає всю пам’ять. Якщо цей колега не справляється з роботою, то проблема полягала у відстеженні стану справ, і нотатки, делегування обов’язків та система, створена з урахуванням втрати пам’яті, допоможуть її вирішити. Якщо ж людина, яка постійно тримала всю проблему у своїй голові, все одно буде мати труднощі, нотатки нічого не допоможуть, адже складність полягала у самому міркуванні.

Кожен механізм, який додає пристрій керування — чи то файлова система для перенесення навантаження, підагенти для ізоляції чи інструмент планування для відстеження прогресу — розглядає випадок амнезії. Жоден з них не робить жоден окремий крок міркування розумнішим. Тому управління станом не є конкуруючим поясненням міркувань. Це основа, яка дозволяє міркуванням розвиватися протягом багатьох кроків та не скидатися з кожним з них. Модель, яка правильно міркує на кожному кроці, все одно може зазнати невдачі у завданні з двомастами кроками, якщо на 150-му кроці неможливо побачити, що було вирішено на 12-му кроці. Міркування не були неправильними. У них просто не було континуїтету для роботи.

Цієї основи самої по собі недостатньо, і вдача, ніби вона є, послабить решту аргументації. Утримання невдалої стратегії, коли правильна, повна історія є на очах, — це суцільна помилка міркування, і бездоганне керування станом її не виправляє. Так само модель, чия власна переказування подій відрізняється від того, що насправді сталося, має проблеми з міркуванням навіть тоді, коли справжні записи залишаються цілими та доступними. Справедлива версія твердження виглядає так: щодо недоліків, на які спрямовані ці інструменти, тобто роботи, які псуються через те, що вони існують довше, ніж один чистий контекст, керування станом є основним засобом, тоді як якість міркувань — це складніша частина, до якої опорні структури не можуть дістатися. У наступних розділах описано, що створили три команди для використання цього засобу.

Чотири стовпи з багатьма елементами

Що таке Deep Agents

Deep Agents постачається як відкритий Python-пакет під ліцензією MIT, встановлюється за допомогою pip та наразі має версію 0.7.5. Навколо нього існує версія на TypeScript, термінальний CLI під назвою deepagents-code та хостована, керована версія, яка все ще знаходиться у приватному бета-тестуванні. Це не конкурент LangChain та LangGraph. Як уже зазначалося, він безпосередньо залежить від LangChain та отримує доступ до LangGraph лише через нього. Виклик функції create_deep_agent() призводить до виконання функції create_agent() у LangChain, яка створює граф LangGraph, тож будь-яка стійкість агента успадковується від того, що передає LangChain.

Чотири основи та технології, що лежать під ними

За словами LangChain, чотири елементи роблять агента «глибоким»: інструмент планування, делегування завдань підагентам, доступ до файлової системи та детальний запит. Гаррісон Чейз запропонував цю концепцію, помітивши схожість у Claude Code, Deep Research та Manus. Як ментальна модель вона добре функціонує, адже ці чотири категорії справді визначають різницю між поверхневим циклом та агентом, здатним виконати складне завдання до кінця.

Чотири — це початковий опис, а не остаточний план. Функція create_deep_agent() об’єднує кожну з цих можливостей із все більшим набором проміжних засобів, які можна вільно комбінувати. Цей список включає файли, підагентів, функції узагальнення, корекцію викликів інструментів, різні варіанти кешування запитів, пов’язані з конкретними постачальниками, пам’ять, навички та схвалення людини, а також будь-який користувацький шар, створений розробником. Основні елементи визначають, що може робити агент. Стек проміжних засобів — це спосіб, яким насправді створюються ці здібності, і він постійно змінюється.

Структурно необхідними є лише дві частини стеку, і це має більше значення, ніж будь-яка кількість. FilesystemMiddleware є обов’язковим, оскільки він забезпечує дотримання правил дозволів, які контролюють доступ до файлів, що, за словами коментаря у вихідному коді, є гарантією безпеки. SubAgentMiddleware є обов’язковим, тому що саме його використовує інструмент task. Його відсутність спричиняє помилку та не призводить до тихого погіршення функціоналу. Усе інше є необов’язковим та компілюється лише за запитом.

Усі, хто зараз працює з цим інструментом, повинні знати, що дві з початкових чотирьох категорій стали опційними. Починаючи з версії v0.7.0, інструмент планування (write_todos) більше не є частиною стандартного набору, а базове запитання системи постачається порожнім, згідно з повідомленням про видалення. Для відновлення кожного з цих елементів потрібна одна рядок конфігурації. Простий виклик create_deep_agent() надає доступ до файлів та можливість делегування завдань підагентам без додаткових налаштувань, а планування та детальне запитання надаються лише за запитом.

Профілі використання — рівень налаштувань, якого немає у новіших моделях

Під середовищем проміжного програмування знаходиться окремий механізм налаштувань під назвою профіль harness. Профіль додає додатковий текст запиту системи та видаляє певні інструменти, вибрані за конкретним рядком моделі, який передається агенту. Не плутайте його з ProviderProfile, який визначає спосіб створення об’єкта моделі. HarnessProfile формує поведінку після його створення.

Для пошуку необхідний точний зареєстрований ключ provider:model; у разі його відсутності використовується запис для всього провайдера як альтернатива. За замовчуванням існують профілі для родини Codex від OpenAI та для трьох поколінь Claude: Haiku 4.5, Sonnet 4.6 та Opus 4.7. Профіль Sonnet 4.6 — це не просто загальні поради щодо формулювання запитів; він настільки точно дотримується офіційних рекомендацій Anthropic, що про це прямо зазначено в коментарях до коду. Крім того, у ньому навмисно відсутні попередження, спрямовані на Opus, щодо надмірної активності та використання багатьох підагентів, оскільки вони вважалися нерелевантними для Sonnet.

Модель, випущена на одне покоління після зареєстрованих, нічого не отримує. При перевірці за допомогою резолвера claude-sonnet-5, anthropic:claude-sonnet-5 та просто anthropic кожен з них не повертає жодного профілю. Оскільки немає точного збігу, а також немає загальнообов’язкової записі в Anthropic для використання як альтернативи (існують лише профілі, прив’язані до окремих версій), ніщо не підходить. Це невдача залишається абсолютно непомітною. Згідно з власною документацією резолвера, єдиною записом у журналі є примітка для дебагування, яка формується, коли використовується альтернатива на рівні постачальника. Якщо обидві пошуки провалюються, жоден запис у журналі не створюється.

Агент, побудований на найновішій моделі зі швидко розвиваючоїся серії, отримує точно таку ж налаштуваність, як агент, побудований на моделі, про яку фреймворк ніколи не чув, тобто жодних налаштувань, причому немає жодних ознак того, що саме це сталося.

Як це працює

Одна абстракція під усім

Увесь цей мідлвейр ґрунтується на єдиному механізмі, який належить до LangChain, а не до Deep Agents. LangChain 1.0 додав можливість виконання коду під час початку чи завершення виконання, до та після кожного виклику моделі, а також під час кожного виклику інструменту, що дозволяє одному агенту з петлею підтримувати досить різні конфігурації. Функції before-hooks виконуються у порядку їх реєстрації, а after-hooks — у зворотному порядку, що відповідає способу, яким веб-фреймворки використовують свої мідлвейри. Функція wrapping hook може спробувати виконати виклик знову, надати його з кешу чи повністю перервати його. Налаштування supervisor, сусплі, петлі рефлексії та deep agents усі є однією петлею з різними приєднаними функціями, а create_deep_agent() — це просто один з можливих варіантів їх вибору.

Файли: два бекенди, дві гарантії

Файли можуть знаходитися у двох місцях, і те, який з них активний, впливає на те, що насправді означає запис даних агентом.

  • StateBackend, який є стандартним варіантом, зберігає файли у каналі стану LangGraph: дані графа з власними правилами об’єднання, а не на диску. Він працює лише під час роботи з живим графом. Те, чи залишаться дані після одного виклику, залежить від наявності як чекпоїнтера, так і стабільного ідентифікатора потоку. Без них кожен виклик починається з порожніх даних, що пояснює, чому простий виклик create_deep_agent() завжди показує порожню робочу директорію.
  • FilesystemBackend здійснює справжнє читання та запис у диск, що приносить як переваги у вигляді надійного зберігання, так і реальні ризики. У його описі чітко зазначено, що він підходить для локальної розробки та процесів CI/CD, але не підходить для систем, доступні користувачам, оскільки агент може читати все, до чого має доступ, включаючи конфіденційну інформацію, і його зміни неможливо скасувати. За замовчуванням virtual_mode=True, доступ обмежується кореневим каталогом, пересування по шляхах заборонене як у вихідному, так і у вирішеному вигляді, а справжні абсолютні шляхи приховані від виводу агента, щоб не розкривати місцезнаходження кореневого каталогу.
  • Одна система дозволів охоплює обидва випадки. Правило поєднує операцію з шаблоном шляху та одним із трьох режимів: дозволити, відмовити чи перервати. Процес видалення ретельно оцінюється з урахуванням правил запису. Рекурсивне видалення відхиляється, якщо будь-яке правило відмови перетинається з чимось під цільовим об’єктом, а не лише з першим правилом, яке підходить, тому раннє широке дозволення не може уповноважити на видалення того, що захищено пізнішим, вужчим правилом.

    Підагенти, ізольовані за принципом проектування

    До підагентів можна отримати доступ так само, як і до будь-якого інструменту. Коли модель викликає task, запускається абсолютно окремий агент, оснащений власною моделлю, інструментами та проміжним програмним забезпеченням. Налаштування його моделі дозволяють використовувати або рядок provider:model, або вже створений об’єкт моделі, тож розміщення підагента на іншому постачальнику, ніж у батьківському агенті, вимагає лише одного рядка конфігурації, а не значних інженерних зусиль.

    Пам’ять не передається автоматично. У специфікації підагента немає поля пам’яті, а логіка передачі дозволів не має відповідника для пам’яті. Ізольований, „чистий“ контекст є навмисним, що означає, що все, що зберігається через пам’ять батьківського агента, залишається невидимим для підагента, якщо тільки йому не нададуть власний проміжний механізм пам’яті.

    Пам’ять є коригованою, а не авторитетною

    Файл пам’яті, після завантаження, не потрапляє безпосередньо до системного запиту. Він надходить у чітко позначеному блоку з інструкціями, доданими фреймворком, які повідомляють моделі, що цей контент є довідковим матеріалом, який може бути застарілим або створеним іншою особою, а не командою, яку потрібно виконувати без заперечень. Це означає нижчий рівень довіри порівняно з системним запитом, що відповідає призначенню: це щось, що агент читає та коригує під час роботи, а не посібник, який розробник пише один раз та очікує, що він матиме повну автономію.

    Деталі масштабування

    Стан розмови залежить від спеціального редюсера під назвою DeltaChannel, створеного так, щоб обсяг зберігання контрольних точок зростав лінійно, O(N), у міру подовження розмови, а не квадратично, O(N²).

    Поведінка на межах

    Перед тим, як вирішити, наскільки сильно використовувати субагентів у продакшені, варто зрозуміти дві умови, які перевіряються в поточному репозиторії.

    Одна помилка — багато наслідків (проблема №694). Якщо кілька підагентів працюють одночасно, а один з них створює виняток, решта також припиняють свою роботу. Операція виконується успішно або невдається як єдине ціле, без можливості ізоляції окремих елементів. Звіт датується січнем 2026 року та є ранньою версією; проблема згодом була вирішена, хоча зміни в коді, які це зробили, не можна знайти ні в коді підагентів, ні в шарі виконання інструментів LangChain. Проте слід враховувати цей факт: будь-яке розподілення незалежних підзавдань слід розглядати як потенційно неповно успішне, доки не буде підтверджено інше на фактично розгорнутій версії.

    Помилки, які надсилаються неправильному користувачеві (#947). Після того, як інструмент повертає помилку, модель зазвичай має спробувати ще раз або внести корективи. Однак у деяких спостережуваних випадках вона зверталася безпосередньо до кінцевого користувача з текстом, призначеним лише для внутрішньої корекції, тож людина бачила повідомлення про помилку, яке зовсім не було адресоване їй. Проблема залишалася нерозв’язаною під час перевірки. У окремому звіті зазначається, що після пізнішого оновлення фреймворку певні винятки інструментів повністю зупиняють агента, замість того щоб надіслати моделі повідомлення для повторної обробки, як це відбувалося у попередніх версіях.

    Два старіші звіти у цій же галузі вже закриті: підагенти, які ігнорують ліміт рекурсії батьківського агента (#1698), та переривання процесу відновлення роботи через рішення про редагування чи відхилення (#554). Виправлення проблеми з лімітом рекурсії також було перевірено на встановленому коді. Вони демонструють, наскільки швидко проблеми в цій сфері зазвичай вирішуються, тому не є підставою для змін у дизайні.

    Практичні альтернативи

    Сьогодні існує три практичні варіанти для створення агента з довгостроковими цілями: Deep Agents, Claude Agent SDK та OpenAI Agents SDK. Кожен з них відображає різний підхід щодо того, що контролює команда та що вона поширює, і жоден з них не є неповною версією інших.

    Одне розрізнення часто плутають більше, ніж будь-яке інше — це різниця між передачею обов’язків та підагентом. Дві з трьох опцій використовують одну й ту саму основну схему, до якої незалежно дістаються дві команди. Третя є справді іншим механізмом.

    Вибір між ними зводиться до двох запитань, а не до ранжування, і жодне з них не має універсальної відповіді. Кожне з них можна відповісти лише з урахуванням реальних обмежень конкретної системи.

    Що варто запам’ятати

    Агенти з довгим горизонтом дії потребують каркасу, оскільки накопичений контекст послаблює сигнал задовго до того, як вікно заповниться. Глибокі агенти створюють такий каркас за чотирьохстовпчастою структурою, підтримуваний змінним набором проміжних засобів, а також файловою системою, підагентами та пам’яттю, кожен з яких має певні гарантії та певні недоліки. Знання цих недоліків — таких як пропуски у профілях новіших моделей, пам’ять, невидима для підагентів, повні або жодні паралельні збої та помилки інструментів, що потрапляють до користувачів — і є тим, що відрізняє свідоме використання цієї рамки від довіри до її стандартних налаштувань.

    Пов’язана література

  • Managed Deep Agents Beta: Спосіб розгортання агентів LangChain через каталоги — функція Managed Deep Agents від LangChain перетворює папку проекту на хостованого агента. Що робить кожен файл, як працює процес розгортання mda та які недоліки версії Beta варто знати.
  • Створення ефективних AI-агентів: архітектурні шаблони та фреймворки — огляд архітектури агентів, від циклів використання інструментів, моделей ReAct та маршрутизаторів до механізмів зберігання даних, захисних правил, людського схвалення та можливостей моніторингу, а також поетапна інструкція зі створення.