Deep Agents у LangChain: планування, підагенти та банківський шлюз
Як deepagents використовують планування, систему файлів та підагентів у циклі інструментів, чим вони відрізняються від ReAct, та як розподіляти інструменти між агентами різних доменів через шлюз.
Джерела: Beyond Simple Agents: Engineering DeepAgents for Enterprise with LangChain
Багато команд можуть залучити агента, який працює на ноутбуці. Набагато менше з них можуть підтримувати такого агента у робочому стані, і саме в цій прогалині знаходить своє застосування концепція глибоких агентів. Це не просто модний термін — це відповідь на конкретну обмеженість: звичайний цикл виклику інструментів перестає ефективно працювати, коли завдання стає довгим, багатоетапним або складним.
Обмеження простого циклу
Найпростіший агент — це LLM, який працює в циклі та викликає інструменти. Такий агент зазвичай є поверхневим, тобто не може планувати роботу над тривалими завданнями чи виконувати складні, багатоетапні обов’язки. Він добре справляється з одним запитанням, але стикається з труднощами при роботі з чимось більшим.
Продукти на кшталт Deep Research, Manus та Claude Code подолали цю проблему завдяки чотирьом елементам: інструменту планування, підагентам, файловій системі та детальному запиту. Проєкт deepagents виник у результаті спроби зрозуміти, що робить Claude Code настільки універсальним, та розвинути цю можливість ще більше. У LangChain такі агенти називаються „глибокими агентами“, оскільки вони можуть планувати складну роботу та виконувати її протягом тривалого часу. Фактично це шлях LangChain до автономних агентів у стилі Claude Code, які можуть виконувати справжні багатокрокові завдання, а не лише одноразові запитання.
deepagents — це автономна бібліотека, створена на основі базових елементів агентів LangChain та запущена в середовищі LangGraph, яке забезпечує надійну роботу, підтримку стрімінгу та участь людини у процесі. Хорошим описом є «засіб керування агентом»: це той самий цикл виклику інструментів, що й у інших фреймворках, але доповнений додатковими вбудованими інструментами та функціями.
Чотири складові
Планування. Вбудований інструмент write_todos дозволяє агенту розділяти велику задачу на окремі кроки, відстежувати прогрес та коригувати план у міру надходження нової інформації.
Система файлів для контексту. Інструменти на кшталт ls, read_file, write_file та edit_file дозволяють агенту зберігати об’ємний контекст у пам’яті чи на диску, щоб вікно контексту не переповнювалося та можна було обробляти результати будь-якого розміру від інструментів. Старіші повідомлення автоматично узагальнюються, коли розмова стає довгою.
Підагенти. Вбудований інструмент завдань створює спеціалізованих підагентів із ізольованим контекстом. Основний агент залишається чистим, тоді як допоміжний агент зосереджується на окремому підзавданні.
Довгі системні запити. Запити, створені на основі Claude Code, є довгими та містять велику кількість інструкцій щодо використання інструментів, а також приклади дій у конкретних ситуаціях. Без них ці агенти були б значно менш здатними. Запити все одно мають велике значення.
Його місце в стеку LangChain
Існує три шари, кожен з яких ґрунтується на тому, що знаходиться нижче. LangGraph — це середовище виконання агентів, придатне для поєднання робочих процесів та агентів. LangChain — це фреймворк для агентів, який дозволяє використовувати основний цикл, а також створювати запити та інструменти з нуля. Deep Agents — це інструментарій для автономних агентів, які працюють протягом тривалого часу та отримують переваги від вбудованого планування, файлової системи та подібних додаткових функцій. Цей інструментарій побудований на абстракції агентів від LangChain, яка, у свою чергу, ґрунтується на LangGraph.
Приклад з банківської сфери
Уявіть банк, який надає п’ять інструментів для роботи з конкретною сферою: пошук банкоматів за поштовим індексом, перелік спеціалістів з інвестицій у певному місті, отримання інформації про компанії з інвестиційного портфеля банку, надання деталей про плани виходу на пенсію та пошук філій у різних регіонах. Кожен з цих інструментів ефективно виконує одне конкретне завдання. Проблеми виникають, коли користувач просить щось, що потребує використання кількох з них одночасно:
Чи можете ви навести список центрів АТМ банку XYZ разом із компаніями з його інвестиційного портфеля, а також вказати адреси його інвестиційних спеціалістів у Чикаго?
Щоб відповісти на це запитання, потрібно розпізнати кілька намірів у одному запиті, вибрати та координувати відповідні інструменти, зберігати контекст у різних даних та об’єднати результати в одну послідовну відповідь. Архітектури, створені для одноетапних або лінійних процесів, часто тут зазнають невдач. Саме для таких ситуацій і створені складні агенти.
Послідовність дій виглядає так.
- Планування. Основний оркестратор читає складне запитання та використовує
write_todos, щоб розділити його на три завдання: отримати інформацію про центри АТМ, компанії з портфеля та спеціалістів у Чикаго.
get_atm_centers(zipcode=...), get_trusted_portfolio_companies() та get_investment_officers(city="Chicago").Простий агент для виклику інструментів міг би обробити всі три завдання по черзі в межах одного контексту. Він міг би забути попередні результати, втратити контроль над тим, на яке запитання відповідає, або досягти ліміту контексту. Глибокий агент тримає ці завдання окремо та відстежує прогрес за списком завдань, тож навіть якщо один виклик зазнає невдачі або повертає часткові дані, координатор знає, на якому етапі знаходиться процес.
Кількість елементів конфігурації невелика:
from deepagents import create_deep_agent
agent = create_deep_agent(
tools=[
get_atm_centers, # your ATM tool
get_investment_officers, # your officers tool
get_portfolio_companies, # your portfolio tool
get_retirement_plans, # your retirement tool
get_bank_locations, # your locations tool
],
system_prompt="You are XYZ Bank's AI assistant. Always answer completely and cite sources."
)
result = agent.invoke({"messages": [{"role": "user", "content": "Can you give me a list of ATM centers for XYZ bank and also list the name of companies XYZ has in its investment portfolio? Also can you give me the location of XYZ investment agents in Chicago?"}]})
Агент вирішує, які інструменти викликати, у якому порядку та як поєднати отримані результати. Вам не потрібно самостійно писати логіку маршрутизації, і саме в цьому полягає справжня цінність цього інструментарію.
ReAct проти складних агентів у разі відсутності інструменту
Візьмемо той самий запит та додамо четверте питання, на яке немає відповідного інструменту: список опцій кредитних карток для студентів. Ось як кожен з підходів справляється з цим завданням.
Глибокий агент перевіряє свій реєстр інструментів та створює список завдань перед тим, як діяти, тож спочатку бачить, що немає інструментів для роботи з кредитними картками. Він запускає підагентів для трьох завдань, які виконуються паралельно та завершуються успішно, позначає пункт про кредитну картку як „жоден інструмент недоступний“ та повертає одну синтезовану відповідь. Ця відповідь повністю відповідає на всі три запитання та чітко повідомляє користувачеві, що жоден інструмент для кредитних карток не налаштований та що його може знадобитися додати. Нічого не ламається, а частковий успіх повідомляється чітко.
ReAct, скорочення від Reasoning plus Acting, дотримується суворого циклу „Мислення, Дія, Спостереження“ крок за кроком без попереднього плану. Це призводить до трьох проблем:
- Він працює послідовно: спочатку банкомати, потім портфель, а потім співробітники. Проблема з кредитними картками з’являється лише наприкінці, після того, як усе інше вже виконано.
ReAct підходить для коротких, чітко визначених завдань, де відомо про існування кожного інструменту. Deep agents призначені для складнішого реального світу, де запитання є складними, інструменти можуть бути відсутніми, але все одно потрібно отримати якомога більше користі з того, що є.
Питання дизайну: один агент із усіма інструментами?
Чи означає це, що нам слід створювати багато інструментів та робити їх усі доступними через одного агента? Ні. Один агент, який має 50 чи більше інструментів, є антипатерном. Кращою структурою є ієрархія агентів. Уявіть собі агента, чия конфігурація містить сотні інструментів — від пошуку в Інтернеті та електронної пошти до бронювання рейсів та запуску ракет, — із вказівкою „розібратися самостійно“. Це може спрацювати іноді, але час від часу він вирішує проблеми, пов’язані з запізненою доставкою, бронюючи рейс, сплачуючи податки та замовляючи піцу. Ніхто цього не хоче.
Власність на домен
Керівною засадою є те, що кожен доменний агент володіє невеликою, цілісною групою інструментів — ідеально від трьох до п’яти — з однієї бізнес-галузі. Агент-шлюз ніколи не торкається інструментів. Він лише читає намір користувача, направляє його до відповідного доменного агента та об’єднує отримані відповіді. Це та сама сепарація функцій, яку використовують у мікросервісах.
У випадку банківської сфери природний розподіл є таким:
- Агент філії та банкомату з функціями
get_atm_centersтаget_bank_locations, який відповідає за фізичну присутність: поштові індекси, міста, години роботи. - Агент з інвестиціями з функціями
get_portfolio,get_officersтаget_retirement_plans, який займається управлінням грошима, включаючи фінансові регуляції, сертифікацію співробітників та типи планів. - Агент з продуктами з функцією
get_credit_cards(якщо вона існує), а також з функціями для кредитів та ощадних рахунків, який відповідає за каталог продуктів. Якщо певний інструмент відсутній, лише цей агент повідомляє про цей пробіл, а інші продовжують працювати без змін.
Код відображає саме таку структуру:
from deepagents import create_deep_agent
# Each domain agent is self-contained
branch_agent = create_deep_agent(
tools=[get_atm_centers, get_bank_locations],
system_prompt="You are the Branch & ATM specialist for XYZ Bank..."
)
investments_agent = create_deep_agent(
tools=[get_portfolio, get_officers, get_retirement_plans],
system_prompt="You are the Investments specialist for XYZ Bank..."
)
products_agent = create_deep_agent(
tools=[get_credit_cards], # sparse now, grows over time
system_prompt="You are the Products specialist for XYZ Bank..."
)
# Gateway knows nothing about tools — only about agents
gateway = create_deep_agent(
tools=[
branch_agent.as_tool(name="branch_atm_agent"),
investments_agent.as_tool(name="investments_agent"),
products_agent.as_tool(name="products_agent"),
],
system_prompt="""You are the XYZ Bank assistant gateway.
Parse the user's intent, delegate to the right domain agent(s),
and synthesize a unified response. Never answer directly — always route."""
)
Чому це масштабується
Коли банк додає нові функції, шлюз та інші агенти домену залишаються незмінними. Ви можете додати інструмент до відповідного агента домену або створити нового, наприклад для кредитів чи боротьби з шахрайством, та зареєструвати його у шлюзі. Будь-які зміни обмежуються одним доменом.
Уявіть собі „ліс“ інструментів. Агент, який має 30 інструментів, не розуміє контексту домену та може викликати функцію get_retirement_plans, відповідаючи на запитання про години роботи банкоматів, просто тому, що обидва пункти належать до сфери його діяльності. Агенти домену уникають цього, надаючи кожному з них чітку ідентичність через системні підказки та набір інструментів. Агент, який знає, хто він такий, приймає більш точні рішення у своїй сфері компетенції.
Корисний тест: якщо ви сперечаєтесь про те, чи належить інструмент агенту A чи агенту B, цей інструмент або робить занадто багато і його потрібно розділити, або вам потрібна третя сфера діяльності. Межа між ними має бути настільки очевидною, як і розуміння того, чи питання належить керівнику відділу чи інвестиційному консультанту.
Відкриті питання
Залишаються два питання: чи сильно залежать «глибокі» агенти від вибору основної моделі, та чи можна створити повне рішення «від початку до кінця» з їх використанням. Відповідь на друге питання — так, і наступним логічним кроком є практична реалізація цього банківського сценарію.