Спецыялісты-агенты, маршрутазначальнік ключоў і функцыя перарыву(): Кансультант LangGraph
Задумайце асистента LangGraph з двума спецыялістамі, які будзе выкарыстоўваць дэтэрміністычны маршрутазер, спяльны стан, які застаецца пасля перадачы, а також чэкпоінт для людзя, створаны на аднойчыных перерывах і командах.
Крыніцы: Building Multi-Agent AI Systems with LangGraph: A Fitness & Nutrition Coach Example
Адзін запрос для асистэнта, які должен пакрыць два нясвязаныя направленні, зазвычай пакрывае іх оба слабка. У гэтым артыкуле замест таго ствараецца маленькая система LangGraph у вобразе трэнера па фізычныяй рухлівасці і аджыменне: два спецыялісты-агента, дэтерміністычны маршрутызатор, які выбирае, хто будзе адказваць, адна спяльная становішча, якая перадае абмежэння праз перадачу заданняў, і чалавечы контрольны пункт, які зупіняе роботу системы пасля кожнага адказу. У канцы вы зразумеете, як працюе кожны элемент, чаму система мае такі формат і як можна перадаць той самы формат для будзь-яго пары спецыялістаў.
Сцэнарый і тэставая розмова
Целевы продукт — асистэнт у дапаможным прыстрые для фізычных вправ, які дапамагае як у трэнаваннях, так і ў дыете. Дизайн пераканаліваецца за дапамогою трывалай розмовы з троха крокаў: запит пра план трэнавання, дапыт пра ўжоў і абмежэння ў дыете, якія мусяць зменіць рэкамендацыі па ўжоў:
Scenario: A fitness app wants an assistant that helps with workouts and nutrition.
Test conversation flow (3 turns):
"Build muscle, lose fat — suggest a workout plan"
"What should I eat to support this workout plan?"
"I'm vegetarian, adjust the meal suggestion"
Кожна з рашынакоў дизайна мае на мету забезпечыць правільную і прагнозавальную роботу эўх трох парадоў.
Чаму стандартны чат-бот не падходзіць
Якщо запытаць чат-бота загальнага назначэння пра план трэнавань і адпоўнае яму дыятэчнае правілле, адпаведныя адказы зачаста бываюць поверхневымі. Модель прабуея обработаць усе аспекты ў рамках аднаго запиту, таму парады становяцца нечысткімі, а дыятэчныя нюансы трыццаюць. Гэтыя слабасі вынікаюць з таго, што трое разныя вакуфанцыяі давляць на адной і той жа запыт адразу:
- Раз'едначэнне домэнаў. Планаванне трэнавань і планаванне харчування — гэта разныя сферы экспертызы, і парады з адной сферы не должны прасачвацца ў іншую чы суперсечыцца з яя.
- Зберагчэнне контексту між парадамі. Умовы, згаданыя раней, напрыклад травма колена, упамінаная трох паўтарэнняў тыму, все ўсё должны вплываць на план трэнавань чы харчування, які ствараецца пазней.
Уместо таго, каб адна прыказка виканала тры заведамення, такая архітектура дае кожнай вимозе свой саўстанак: спецыялістаў для раздзелення домэнаў, спяльны стан для контексту і чалавечы вузел для нагляду.
Пяць основных элементаў
Система складаецца з пяці частак, кожная з якіх мае адну вялічыну адпаведальнасці:
- Кансалтант па трэнуваннях: агент, які адпаведзяў за практыкі трэнування, планаванне трэнувань і ўсілякія змены ў звязку з травамі.
- Кансалтант па харчаванні: агент, які адпаведзяў за планы ўжывання ўжоў, макронутрыенты і діетычныя обмежэння, такія як вегетарыянская, веганская діета чысто діеты, вызваныя алергіяй.
- Рутэр: лёгкі элемент прынятнага рашэння, який аналізуе пасляпэўныя запыткі корыстніка і выбирае, який саветчык будзе адпавядаць далей.
- Людзкі вузол: цэлесапраўедзена пауза, калі граф чакае на адпаведь чалавека замест таго, каб генераваць ўсё больш выходных дадзенаў.
- Спакушаны стацус: адна автарытатывная запись дыялогу да гэтага момента, а таксама інфармацыя пра тое, який саветчык адпавядаў последнім.
Это іерархічны, або оркестрацыйны, патэран. Коордынатор делегуе задачі спецыялізаваным падагентам замест таго, каб аднолькі агент намагаўся выпалняць усе ролі адразу.
Правілло, якое робіць перадачы прыведамымі
Адзін структурны правілы робіць весь дизайн надзеяным: кансалер ніколі не перадае кантроль безпасова другаму кансалеру. Кожны выхідны данны агента праходзіць через чалавечы вузол, а потым через рутэра. Таму два агенты ніколі не можаць таямна перадаваць кантроль аднам другаму, і кожны пераход яе ўсё час можна бачыць і перарваць.
Як паведамленне пераходзіць через граф
Следавайце за адзінам паведамленням пользователя. Яно спачатку падае на чалавечы вузел і перадаецца рутэру, які чытае тэкст паведамлення; якщо сам тэкст недастычны, рутэр абяцоўваецца з полем last_active_agent у спяльнам стане, каб выбраць між Кансалтантом з трэнаванняў і Кансалтантом з аджымення. Выбраны кансалтант можа вызваць свой інструмент, пасля чаго вяртае кантроль чалавечаму вузелу, які зноў настаіць і чакае на наступнае паведамлення. Такім чынам цикл завжды складаецца з чалавечага вузла, рутэру, кансалтанта, неабяцованага інструмента і знову чалавечага вузла.
Модэль: LLM з адкрытымі вагамі на Groq
Оба кансалтанты выкарыстоўваюць модэль з адкрытымі вагамі openai/gpt-oss-120b, якая працюе на Groq і налаштаваная з temperature=0:
- Чаму саме гэтая модэль: у яй є надзейныя можлівасці вызывання внутршных інструментаў, ад карыстоўвання якімі залежыць цей інструментам-адрасаваны працэс.
Нічыя частка графа не залежыць конкрэтна ад Groq. Будзе працаваць любой чат-модель, якай падтрымляе вызовы інструментаў, напрыклад Google Gemini або Anthropic Claude, праз заданне відпаведнага ключа API (такога як GEMINI_API_KEY або ANTHROPIC_API_KEY) і нацэніцуе рэйпер моделі на гэтага прадастальніка. Доступнасць модэляў на хоставаных платформах зміняецца з часам, таму павінны быць перакананы ў ідэнтыфікаторы модэляў на адпаведнасць сучаснаму каталогу прадастальніка.
Спадзяльны стан: дзе насправды знаходзіцца памяць
Кожны вузел чытае і запісвае данні ў адны об’ект стану з паказаным типам MultiAgentState, які мае два поля:
messages: цэлы ход размовы, які успадковуецца зMessagesStateLangGraph, і які таксама забезпечвае функцыю для дадавання новых прывітанняў уместо замены вялікага списку.
last_active_agent: значэнне ставіцца як "workout_advisor" або "nutrition_advisor"; раутэр выкарыстоўвае яго тады, калі не можа визначыць, да якога домэна належыць запит на дадатковую інфармацыю, напрыклад "tell me more".Самэ гэты стан ўскладнюе ситуацыю, калі абмежэння, зазначанае ў пяршым кроцы, застаецца чынным у наступных кроках, нават якщо адпаведны адказ генеруе іншы вузол. Модэлю нічога не падсумовваецца і не пераз’ясняецца. Кожны кансультант проста отрымае той самы список накопіленаў messages кожны раз, калі ён працуе, а чэкпойнтар зберагае стан між крокамі той самай розмовы.
Ключоўны выбор у дизайне — гэта тое, што памяць є цэнтралізаваная, а не прызначаная для кожнага агента. Якбы кожны кансультант зберагаў свою сабэйскую історыю, кансультант з питанняў харчування ніколі не даведаўся бы пра цялі, якія корыстувач задаў кансультанту з трэніраў.
Адвайзару — адзін вузкі інструмент
Кожны агент можа выкорыстоўваць толькі адзін інструмент, і гэты інструмент належыць да яго сферы. У гэтым варыянте інструменты базуюцца на правілах і падбіраюць ключавыя слова, што робіць ўзоракі працы прагнозаванымі і лёгкімі да дэманстрацыі. У реальных умовах іх можна заменіць на справжні API для аналізу фізычных якостей чы ўжывання паўз, або дазволіць модэлю самаму ствараць адпаведныя адказы. Паколькі рэшта графа залежыць толькі ад інтэрфейсу інструмента, замена реалізацыі не выклікае іншых змян.
Кожны адвайзар — у сваёй сферы
Адзін спецыяльны інструмент недастаткова, каб агент заставаліся на тэме; модэль таксама павінна знати, на шта яй не трэба адказваць. Таму кожны системны запрос встановляе чыстаю межу:
- Адвайзару па трэніровкам даўнацца наказ не даваць порады па ўжыванні ежу чы паўз, таму што граф будзе направляць такія запросы адвайзару па паўзах.
Прычына гэтага заключаецца у тым, што модель сама сябе не керуе. Адказы на праблемы, якія стаюцься на межах адпаведнасці, змушваюць кожнага агента даклэўвацца правілам, а не імпровізаваць па заходзе свайго кваліфікацыя, і саме граф, а не LLM, чыста якраз прымечвае кожнае рашэння па кераванні.
Маршрутазатор, пабудаваны на ключовых словах, а не на ўтрыманні іншаго LLM
Калі кансалтанты маюць такія абмежэння, маршрутазатору проста трэба выбраць наступнага спікера, і ён гэта рабіць за дапамою простага падабрання ключовых слов:
- Словы такія як gym, reps, cardio або muscle направляюцца да Кансалтанта па трэнаваннях.
- Словы такія як diet, food, eat, protein або vegetarian направляюцца да Кансалтанта па шчытанні жывёначэння.
- Усе, што не падае під атрыбуты жаднага зі спісаў, пераходзіць да таго саветніка, які зберагаецца ў
last_active_agent.
Дэтерміністычны маршрутызацыя ўсё можна працаваць і легка тэставаць: аднойчы надслаўленая паведамленне завжды вядзе да таго ж наступнага этапу, і можна працаваць з рутэрам у формате юніт-тэстаў без вызыву моделі. Аднак такой падход мае недзеяльнасць — спісы ключоўых словаў не включаюць сынанімы, і паведамленне, якое адначасна стосуецца двух тэм (напрыклад, пытанне пра ўжоў до трэнування), вымагае явная правілы для выбору маршруту. Калі формулювання стае занадта разнарадзенымі для викорыстоўвання ключоўых словаў, простая класыфікацыя ёсць разумным апградам, але гэта падрыхтавляе частку той працяглівасці.
Участка чалавека з перерывам і камандай
Сама важная рашынка падчорагу не ў рутэры, а ў «людзкім» вузле. Пасля кожнага крока саветчыка граф спецыяльна зупіняецца. Ён не прыпускае наступныя запитанні корыстувальца і не продовжвае генераванне. Две прымітывы LangGraph рэалізуюць гэтае зупіненне:
interrupt(...)зупіняе выконанне працэзу самэ там, дзе ён вызваны, і вяртае контроль вызываючаму, а таксама любую значэнне, якое вы яму перадалі.Command(resume=...)продовжвае зупінены граф, перадаючы даны, якія ввёў чалавек, як значэнне зворотнага выхаду вызовуinterruptу там самым вузле.
Інтарупцыямі керуецца за дапамою контрольных пунктав: граф должен зберагаць свой стан у момент зупінення, каб пазней могаць яго продовжыць, і самэ таму скомпільаваны граф патрэбуе контрольнага пунктава і ID аддзіны.
Для асистента з фітнесу та харчавання такая пауза — гэта не проста зручна функцыя інтэрфейсу. Це момент, калі корыстнік можа дадаць інформацыю, важную для безпекі, такую як травма, алергія чыў вакульна обмежэння, прычым перад тым, як продавацца далей розмова, а не пасля таго, як система вже дала пораду, якая гэта не берае ў расчыт.
Этапы трохі розмовы
Этап 1: пачатак розмовы
Корыстнік называе два цялей — адбудова мускулатуры та схудненне, і прасіць пра план трэнуванняў. Кожная новая розмова завжды пачынаецца з Адвайзера з трэнуванняў. Ён берае параметры «мускулатура» та «жыль», запускае свой інструмент і вяртае структураваны план — напрыклад, чатырохдзённы план трэнуванняў верхней/нижней часткі тэла з 8-12 павтарэнняў у 3-4 падходы, які спалюе тры дні на трэнуваннях сілы і два дні на кардіо.
Этап 2: пераход да пытанняў харчавання
Далей корыстнік хочаць ведаць, які продукты можу падтрымаць гэты план. Чалавечы вузол перадае запрос, маршрутызатор падбірае опцыю „есть“, і выкананне пераходзіць да Кансалтанта з пытанняў пра жывленне. Ён вяртае ўтыковы план на дзень, які складаеся з прыблізна 2 500 ккал, спрыважаны на белкі з малой колькасцю жыру і складныя вуглеводы, з перакушанням кожныя тры-чатыры гадзіны.
Этап 3: застосаванне абмежэння з спяльнага стану
У канцы корыстнік паведамляе, што ён вегетарыянін, і просіць скоректавацію практыкі харчування, адзін раз дадаўшы прыклад закускі. Паведамленне зноў прайшоў да Кансалтанта з пытаннямі харчування, і тут дзеўа механізмы падтрымлілі адпаведную дзеянне: слова „вегетарыянін“ сама по сабе ёсць ключоўым словам у сфере харчування, а last_active_agent яшчэ і далей вказуе на харчування, таму нават болей нечыстае запитанне на кшталт „скоректавацыя практыкі харчування, адзін раз дадаўшы прыклад закускі“ апошнюючы прайсць у той жа направленні. Кансалтант зноў прачытаў усю історію запитаў, як і раней адпаведзеў на цель, заданую ў першы раз, дадаў умову вегетарыянства і створыў план харчування без мяса для нараджэння мышц, створаны з тофу, паніра і сочнаваў, а таксама з закускамі на кшталт едамамэ і чашак з хуммусам. Нікому не было трэба падтверджваць цель, калі ў стане вже была яна заданая.
Гэты крок ўособліва падкресляе перавагу цэнтрызаванага дзяржавнага апарату. Адказ генеруецца іншым вузлом, чым той, які выйшаў на пачатковую мету, пры тым у гэтага вузла є цэлы контекст.
Складанне машыны станоў
За структурой рэзультатам являецца невялікая графіка станоў з трыма вузламі (двума саветчыкамі і людскім вузлом) плюс маршрутазыграч, які выступае у ролі умовай логіки межы ўсіма імі, а таксама адна фіксаваная точка входу:
- Кожны новы поток пачынаецца у саветчыка з аспекта трэнуванняў. Гэта стандартнае рашэнне адпавядае продукту: люди, якія запускаюць додатак для фітнесу, зазвычай спачатку запытаюць пра трэнуванняя, а ўжо пасля — пра ўжыць.
- Пасля першага адказу людскі вузел і маршрутазыграч адлучаюць кожны наступны крок.
MemorySaver, і кожная розмова адзначаецца thread_id. Калі вызывач знова викорыстоўвае той самы thread_id, граф автаматычна вярнюе паведамленні і last_active_agent; вызывач ніколі не практыкуе історыю занова.MemorySaver зберагае аптэчныя точкі ў памяці процеса, што ідеальна для ноутбука, але всё губіцца пасля перзапуску. Версія, якая выкорыстоўваецца у практыцы, должна викорыстоўваць стойкую аптэчную точку, падтрымваную базай дадзеных.
Полная рабочая реалізацыя доступна як супаняючы ўжоўнік. Па іншым способам структуравання крокаў маршрутызацыі та затверджэння адзірніце пяць патэранаў LangGraph, якіе раскрываюць маршрутызацыю, розпад на часткі, крітыку та затверджэння.
Павторны выкарыстоўкі патэрана за межамі фізычных трэнуванняў
Ніч гэтага ня є спецыфічным для трэнуванняў чы перакусаў. Тыя ж тры элементы — спецыялісты-агенты, маршрутызатор, керованы спяльным станам, і людскі пункт контролю, які выкарыстоўвае функцыі перарыву та продажвачэння, падходзяць для будзь-каго системы, якая мае:
- больш чым адну разлічную сферу экспертызы, якая можа знадобіцца пад час размовы,
Якщо заменіць двух кансалтантаў на іншую пару экспертаў у данай галіне, форма графа застаецца тая ж. Зменяюцься толькі інструменты, запиты і ключавыя слова для направлення.
Прынцыпы дзяржання
- Оркестрацыя заместо моналітных структураў. Іспользуйце граф, каб стварыць адзеленыя каналы экспертызы, заместо таго, каб пакладацца на аднаго агента для выканання всіх задач.
- Цэнтрызаванне стану. Адны
MultiAgentState, які зберагаецца за дапамогою чэкпойнтара, яўляецца тым, што робіць перадачу задач без працягоў і памагае зберагчы всі абмежэння.
interrupt(), каб людзі моглі участваваць у ключовыя моменты.Галоўныя выводы
- Раздзеліце работу па домэнах і даўце права на прыняття рашэння па маршрутах дэтэрміністычной логіцы графа, а не самой модэлі.
- Зберагаеце адну спяльную історыю
messagesплюсlast_active_agent, каб абмежэння, установленыя раней, вплывалі на адпаведзі, якія пазней даўае іншы агент. - Вважайце
interrupt()іCommand(resume=...)механізмамі, якія дазволяюць чалавеку дадаць правілы безпекі ў перадчасе наступнай адпаведзі, і памятайце, што для цього патрэбны чекпойнтар і ID аддзеўкі. - Зберагаеце інструменты ў вузкім формате за стабільным інтэрфейсам, каб логіка, апаратная на правілах, пазней маглась стаць сапраўдным API або повнамасштабным расыяванням модэлі без змены графа.
- Спадчыяй спосаб прыняць гэты шаблон — выбраць двух чытка адзначаных спецялістаў і стварыць цэлысны рабочы граф; топалогія застаецца незменнай, а падказкі і інструменты — гэта тыя часткі, якія можна прыстосаваць.