LangGraph можа скомпілявацься і працаваць, калі прыняць увагу на неабяжлівы вузел.
Функцыя LangGraph compile() перакантролюе падключэння, а не цэліснасць бізнес-процэсаў. Граф ад пакупкі да рахунку можа быць створаны, якім будзе прыхіліцься вузол, таму неабходна перакантролюваць, чыры выкананы неабходныя крокі.
Крыніцы: The Node That Never Ran: What LangGraph Does Not Check at Compile Time
Працэс LangGraph ад пакупкі да рахунку-фактуры можа завершыцца успехам, пры чым будзе праскочана адна вузел. Такі спосаб неяўнага завершэння горшы за збой: фінансавыя апараты думаюць, што рахунок-фактура існуе, калі граф ніколі не выканаў гэты крок. Прычына — недастатак у тым, што пераканалівае compile(), і два механізма, якія гэта фіксуюць.
Апранае сітуацыі
Кожны вузел выводзіць свае называнне. У спраўнай працы выводзіцца называнне кожной станцыі, і працэс завершваецца. Аднак калі адняць адну грань:
graph.add_edge("create_purchase_order_from_request", "create_an_invoice")
Працэс запускаецца зноў:
Executing: load_purchase_request
Executing: validate_purchase_request_is_approved
Executing: create_purchase_order_from_request
Выкананне зупіняецца пасля стварэння замовлення на пакупку. Радок з рахунком-фактураю ніколі не праказываецца. Канечны статус застаецца проміжным. Няма асаблівасцей. Тыя, хто вызывае працэс, бачаюць нормальны рэзультат, які не адкрывае інформацыю пра відсутны фінансавы запіс.
Што на самай працэ пераканалівае compile()
StateGraph.compile() парабярае, чырвоныя лініі аднасаюць з рэальнымі вузламі, чы ёсць элемент START, і чы ці канечныя точкі чырвоных ліній — вузлы або END. Аднак ён не парабярае, чы кожны вузел ўможлівы да досягнення, чы кожны вузел можа дасягнуць END, або чы кожны вузел выкананы. У навучальных матэрыялах, якія стверджваюць, што парабяранні досягнення ўможлівы, перацінюецца можнасць гэтага API.
Адна прасоць, два спосабы абярэння
- Абануты вузел — зарэўнаваны, але без чырвоной лініі, якая бы да яго прыводзіла; ніколі не выкананы; компіляцыя заўсёды успевае.
- Зламаны шлях да END — адчыненне чырвоной лініі ў серэдзіне графа прыносіць безследны частковы успех з нестандартным статусам.
У обох случаях компіляцыя выглядае як „успешная“.
Чаму двіжак адзвярцаецца пра успех
LangGraph счытае завершаным той параграф, які дасягае вузла без выходных рэштоў — або вяртаецца без выклікання парадоксу. Успех означае «час выканання не зламаўся», а не «усе бізнес-этапы завершаны». Поле статусу ўжываецца за прыметамі програмы, калі толькі гэта не прымусоваеся.
Чаму END недастатнька спецыяльная
END — гэта тэрмінальны знак для рэштоў, якія гэта падтрымваюць. Вузлы, якіе проста зупіняюцца, не выклікаюць автаматычна парадоксу. Без асэрцый ўжыванняя неабходных этапаў, частковыя графы выглядаюць стабільнымі.
Чаму фрэймворк дэлае такі выбар
Аналіз досяжнасці і неабходных вузлаў — гэта проблемы логікі программы. Бібліятэка пераканальвае структурную схему, а потым дазволяе коду продукту задаць, якія вузлы ёсць неабходнымі. Гэта спрыяе швайнаму кампіляванню і ухілу ад суб’екtyваўных бізнес-правіл — але перакладае адпаведальнасць на тэсты.
Як яго з’яўіць
Дадзіце явную пераглядку пасля выканання (альбо на рэвэне графа), якая пераканаецца, што неабяжныя вузлы былі выкананы — за дапамою лямоў стану, хуків абратнага вызову альбо прадыкты завершэння:
def find_detached_nodes(compiled):
g = compiled.get_graph()
sources = {e.source for e in g.edges}
targets = {e.target for e in g.edges}
dead_ends = [n for n in g.nodes if n not in sources and n != "__end__"]
orphans = [n for n in g.nodes if n not in targets and n != "__start__"]
return dead_ends, orphans
Таксама дадзіце тэсты на едыніцы, якія намеравана адчыняюць рэшткі і спадзяваюцца, што захід не будзе працаваць. Апшырэнныя статычныя пераглядкі могу аналізаваць спіс суседства, каб пераканацца у можлівасці даступу з START да кожнага неабяжнага вузла і далей да END.
Вывыкі
compile()≠ павнае выпанаванне бізнес-логікі.- Для фінансавых робочых практык лепш выкарыстоўваць збіі альбо статус жорсткага падзеяння, чым тыхі прыгнуценні.
- Кодавайце неабяжныя вехі ў стане і пераканаецца ў іх наявнасці пры падтверджэнні успеху для сістэм вышэйшага роўня.
- Документавайце гэтыя прынтары для кожнага інжынера, які перэносіць лінейныя інструкцыі у рэальную працу з пераказамі грошаў.
Спраяванне бага да пераказаў грошаў
Працэс адміністрування замовленняў да выдачы рахункоў-фактур ёсць крайне чутлівым. Калі функцыя create_invoice ніколі не выканаецца, сістэмы адзначэння боргаў, экспорт податковых даных і порталы постаўчыкаў пачынаюць працаваць несувязана. Верненне значэння success з параметрам status=purchase_order_created ёсць сімптамам некорэктнай працы прыкладнення: сервісы, якія вызываюць гэтую функцыю, спрыймаюць такія рэзультаты як завершэння працэса. Неабходна супарадаваць статус HTTP/задання з спісам неабходных ідэнтыфікатораў вузлаў, якія зберагліся ў стане прыкладнення.
Мінімальны контракт для неабходных вузлаў
Неабходна падтрымваць значэння state["executed"] у вачынку тыпу set reducer. Кожны вузел дадае свое імя. До момента завершэння (або пасля вызыву функцыі з боку кліента) неабходна пераканацца, што {"load","validate","create_po","create_invoice"} <= executed. Абсэнцыя імен вузлаў выклікае спецыяльную памятку пра помылку IncompleteGraphError, якая можа быць выкорыстана для монітарынгу. Гэта ператварае дазволліваючы статус успеху фрэймворку на серьёзную помылку в межах конкрэтнай сферы прыкладнення.
Статычныя пераконтроўкі суседства ў CI
У тэстах серыязавайце спіс роўнаў графа. Вычысляйце досяжнасьць з точкі START. Збій у CI, якшо неабходны вузол недосяжны або не можа дасягнуць точкі END. Шырые тэсты выяўляюць коментаваныя роўні ў той жа дзень, калі яны адкрываюцца — без патрабавання да тых, каб іх праігноравалі ў рэальных умовах.
Што должна значыць практыка кампілявання ў інструкцыях
Дакументавайце для каманды: «скомпілявана» означае, што схема ў сінтаксічна правільная. «Завершана» означае, што выконаны неабходныя бізнес-вузлы. Інструкцыі, якія плутаюць гэтыя два статусы, воспамінаюць пра інцыдэнт з праігнораваным рахункам. Паруйце дакументацыю з фрагментам коду для відтворэння, каб новыя учаснікі моглі навмесна зламаць просты граф і пабачыць, як запускаюцца західні механізмы.
Связанныя проблемы
- Умовныя роўні, якія можуць направляць трафік нікуды, якшо флаг статусу не заданы.
Спрыяйце топалогіі графа як да даных прыменнення. Атстаюце ў яе перакананне як у схемах — а не як у неабавязковых каментарах.
Аналіз правернага і неправернага запуску
У правернам графе калбэкі або запісы для выведання паказваюць лепт → перакананне → стварэнне PO → стварэнне фактуры → знак завершэння. Аперацыяны, якія паўтараюць логі з кансэптуальнай інструкцыяй, могу пазначыць кожную стадыю. Пасля выдалення рэгулі, знак фактуры ніколі не праказываецца, пры тым як вызывач на Python все равно атрымлеэ дыкшнер. Сістэмы, якія пераканваюцься толькі ў успехе транспортування, запішуць “завершанае” ў інструмент для кэйсоў. Самэ так тыхія прыгнутыя моменты ператвараюцца на фінансавыя інцыдэнты.
Праектаванне энумерацый статусаў, якія не можуць крацаць
Лепшыя статусы тэрміналу — гэта completed, failed_incomplete і failed_exception; яны задаюцца толькі спецыяльным вузлам завершэння пасля таго, як пройдзе неабяжна асэрцыя. Для стрымінгавага інтэрфейсу можа існаваць проміжныя статусы, але API, якія паведамляюць пра працу іншым службам, должны выдаваць толькі статус completed пасля пераканальнага контролю. Статус failed_incomplete трэба супарадаваць з компенсацыйным тыкетам, у яком пераказаны назвы вузлаў, якія не ўжо існуець.
Взаімадзея з прыстроямі контролю стану
Калі прыстрой контролю стану пачынае запуск зноў пасля збою, відсутныя рэглі ўсё равно прыводзяць да таго ж ігноравання. Сховванне дадзеных не стварае рэглаў. Тэсты на продаж запуску должны включаць фіксаты для мутацый топалогіі. Таксама неабяжна версіюваць адзначэнне графа разам з дадзеннямі контролю стану, каб стары контроль стану не быў пераглядзены на несумісной топалогіі без логікі міграцыі.
Навчанне без страху
Інжынеры, які працуюць з мовамі, дзе «компіляцыя значыць правільна», патрабуюць спецыяльнай дамахры: паводзіцца злом у сэндбоксе, стараецца паблікаваць рэзультат, а потым увёлічвае захіст і стараецца паблікаваць прычыну зламу. Одна жывая дамахра захоўвае ад месцаў неабходнасці працаваць з прыпускамі аб безпецы. Прыкрэпіце гэты скрапт дамахры ля README-а рэпазітарыю з процэсамі купавання і выдачы рахункоў.
Спіс пераканальных пунктав пры адгукванні, што граф «закончаны»
- Кожны неабходны бізнес-вузел выказваецца ў
executed. - Умовныя маршрутыцэры маюць весь спектр гілак, укладаючы ў сябе явны шлях зламу.
- Жаданы вузел не выконвае незворачны I/O без ключа ідэмпатэнтнасці, які зберагаецца ў стане.
- Компіляцыя успехоўна завершаецца і тэсты доступнасці таксама успехоўна праходзяць у CI.
- Рэзультаты вызоваў маюць флаг завершэння, чытальны для машыны, аддзельна ад коду HTTP 200.
Калі гэтыя пяць прынцыпа дотрымваны, пропусканыя рахункуць стаюць выяўлімымі дзефектамі, а не тыхімі «успехамі». Гэтае ўсё, што патрэбна прыкладнам Лангграф для эфектывной працы, калі на кону знаходзяцца грошы чыстае сарання — а не проста зелены лог компіляцыі.