Галоўная / Артыкулы

Струменевыя адказы ў LangGraph: 3 практычныя патэрны

Струменевыя адказы ў LangGraph: тры патэрны для токенаў, абнаўленняў вузлоў і ўласных падзей, каб карыстальнікі бачылі працу агента адразу.

Выдавец: REACTAPP.TOP16 хв чытання3658 слоў

Крыніцы: Streaming Responses in LangGraph: 3 Practical Patterns Every Agent Developer Should Know

У гэтым карыце парадоксальным чынам перакладзены ўсі элементы з англійскай на беларускую мову: «Гэты практычны карыце перакладзе шлях ад сыр'ёў да рабочай сістэмы для: Стрымаванне адпаведзяў у LangGraph: 3 практычныя мадэлі, якія кожны распрацоўшчык агента павінен знаты. Акцэнт ставіцца на крокі, якія можна выконваць, чыстае перакананне і код, які можна проста дадзіць у рэпазітарый без неабясненых падозрэнняў. У этапы агульнага відзору неабходна практычна апісацыя вхідных дадзеных, адпаведальнага за крок і крэатывных крэтарыяў перад якімі-небудзь зменамі ў кодзе. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю без неабясненых падозрэнняў ў схованым стане. Неабходна адзіночна задокументаваць як шлях успеху, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контрольныя пункты і обработка некорэктных паведамленняў ёсць часткай самага продукту, а не якімісь пазнейшымі дапрацоўкамі.»

Чаму стрымаванне мае большое значэнне, чым думаюць людзі

Калі працуеце над этапам «Чаму стрымінг мае большое значэнне», спачатку запісайце умовы: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі спіс контроля дапамагае заліцвачваць будучыя змены коду. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшоў, прычына нявыпання павінна вказываць на адну адпаведальнасць, а не на заплутаны ланцужок задач. Зробіце перапактаванне пасля дорогіх крокаў. Програма не павінна зноў сцягваць плата за той самы вызов LLM, калі аператар праканае пазнейшы вузел.

Прыклад, з якім мы працуем

Калі працуеце над стадзіяй «Прыклад, які мы ствараем», спачатку запісайце угоду: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі спіс пераконтроўкаў дапамагае заліцвачыць пазнейшыя змены ў кодзе. Спрыймайце гэтую стадзію як угоду межа данымі і перакананымі выходамі. Дайце назву рэзультатам, задацьце перакананні успеху і адмовіцеся ад тыхоўскага частковага завершэння. Зробіце пераконтроўку пасля дорогіх крокаў. Програма не должна занова выклікаць той самы калл LLM, калі аператар прабуе зноў запрацаваць з пазнейшым вузлам.

import asyncio
import operator
from typing import Annotated, TypedDict
from dotenv import load_dotenv
from langchain_core.messages import BaseMessage, HumanMessage
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, StateGraph

load_dotenv()

# --- 1. STATE & GRAPH ---
class State(TypedDict):
    messages: Annotated[list[BaseMessage], operator.add]

llm = ChatOpenAI(model="gpt-4o-mini", streaming=True)

def chatbot_node(state: State) -> dict:
    return {"messages": [llm.invoke(state["messages"])]}

def dummy_node(state: State) -> State:
    return state

builder = StateGraph(State)
builder.add_node("chatbot", chatbot_node)
builder.add_node("dummy", dummy_node)
builder.add_edge(START, "chatbot")
builder.add_edge("chatbot", "dummy")
builder.add_edge("dummy", END)
graph = builder.compile()

# --- 2A. stream_mode="updates" — one event per node ---
print("=== Method 1: stream_mode='updates' ===")
for event in graph.stream(
    {
        "messages": [HumanMessage("List 3 benefits of LangGraph in one line each")],
    },
    stream_mode="updates",
):
    for node_name, output in event.items():
        print(f"  [{node_name}] {output['messages']}")

# --- 2B. stream_mode="values" — full state after each node ---
print("\n=== Method 2: stream_mode='values' ===")
for snapshot in graph.stream(
    {
        "messages": [HumanMessage("Say hello in 3 languages")],
    },
    stream_mode="values",
):
    print(f"  State has {len(snapshot['messages'])} message(s) now")
    print(snapshot["messages"])

# --- 2C. astream_events — token-by-token (async) ---
async def token_stream():
    print("\n=== Method 3: Token-by-token streaming ===")
    print("🤖 Bot: ", end="", flush=True)
    async for event in graph.astream_events(
        {
            "messages": [HumanMessage("Count from 1 to 5 slowly, one per line")],
        },
        version="v2",
    ):
        if event["event"] == "on_chat_model_stream":
            chunk = event["data"]["chunk"].content
            if chunk:
                print(chunk, end="", flush=True)
    print()

asyncio.run(token_stream())

Крок 1: Спачатку з’ясавайце дызайн стану

Калі працуеце над першым крокам «З’ясаваць стадыю», спачатку запішыце умовы вікорыстання: неабяжлівыя даны, сігнал успеху і тое, што выходзіць на падзею частковага невыпання. Такі спіс контролю дапамагае заліцвачыць пазнейшыя змены ў кодзе. Запісвайце час выканання і кост токена або запіту праза функцыональныя рэзультаты. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя сераўы. Зробіце контрольную пазнаку пасля дорогіх крокаў. Сістэма вярнення не павінна знову ставіць плату за той самы вызов LLM, калі аператар перапрыяўляе працу да наступнага элемента. Калі працуеце над першым крокам «З’ясаваць стадыю», спачатку запішыце умовы вікорыстання: неабяжлівыя даны, сігнал успеху і тое, што выходзіць на падзею частковага невыпання. Такі спіс контролю дапамагае заліцвачыць пазнейшыя змены ў кодзе. Аддзекументаваць трэба як шлях успеху, так і шлях вярнення да нормы. Перапрыяўленні, людзкі контроль і обработка некорэктных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

class State(TypedDict):
    messages: Annotated[list[BaseMessage], operator.add]
{"messages": [some_new_message]}

Чаму гэта важна для стрымінгу

Падход «Чаму гэта важна для стрымінгу» работае найкрашча, калі яго розглядаць як вімерную структуру. Запісаўце адна ідэальная версія, адзін прыклад неудачы і прыметкі па поверненню да попярэдня стану пры розшырэнні масштаба. Валіце вароты на маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшаў, прычына неудачы павінна вказываць на адную адповядальнасць, а не на заплутаны ланцужок задач. Рэзультаты працы графа трэба зберагаць у простай, тыпаванай форме. Вярнутыя структуры маскуюць інфармацыю пра тое, які вузел запісаў кожны поле, і спакоююць продовжэнне працы пасля перэрываў.

Крок 2: Сам граф спецыяльна просты

Этап «2. Граф» працюе найкрашча, калі яго розглядаць як вімерную паверхню. Зафіксавце адна ідэальная транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расшырваць масштабы. Разглядзіце гэты этап як кантракт межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Дайце назвы артыфактам, задаце крытэрыі успеху і не падзейвайце частковае завершэнне без адказу. Храніце стан графа у простам і тыпаваным фармаце. Вкладзеныя блокі маскуюць інфармацыю пра тое, які вузел запісаў канкрэтны поле, і спакоююць працу пасля перарываў.

chatbot_node

Этап chatbotnode працюе найкрашча, калі яго спрыяваць як меркавую плошчу. Зафіксавце адны ідэальны прымер працы, адну справу з бягамі і прыметку па адварцыю перш чым расшырваце сферу дзейнасці. Запісвайце часы выканання і вартась токенав або запытак праз адныя з рэзультатамі функцыональнасці. Відразлівае паказанне вартасей з самага пачатку запобегае неспакоўным рахункам, калі працэс пераходзіць з дэмавай версіі ў спяльныя сераўеры. Храніце стан графа ў простам і тыпаваным фармаце. Вярнутыя структуры дакументаў маскуюць інфармацыю пра тое, калькі вузел запісаў калькі поль, і спакшваюць продовжэнне працы пасля перарываў. Этап chatbotnode працюе найкрашча, калі яго спрыяваць як меркавую плошчу. Зафіксавце адны ідэальны прымер працы, адну справу з бягамі і прыметку па адварцыю перш чым расшырваце сферу дзейнасці. Дакументавайце як успешны, так і вярнучыся парадкі працы. Перапрыбуткі, людзкія контралі і обработка нераспакаваных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

def chatbot_node(state: State) -> dict:
    return {"messages": [llm.invoke(state["messages"])]}

dummy_node

Для этапы dummynode неабяжна прадзеўкаваць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры перадзеўкве коду. Аператары должны магчымаць паўтарнае запусканне крока з вядомага пункту контролю, не прыпускаючы стану, які застаўся непазнаваным. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выконваецца, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны працэс. Неабяжна ўключыць людзкія пераказы для тых крокоў, якія выкарыстоўваюць грошы або зменяюць даны ў працэсе віробніцтва. Компіляцыйныя налашчэння не ўзначаюць павнае выкананне бізнес-функцый.

def dummy_node(state: State) -> State:
    return state
START → chatbot → dummy → END

Метод 1: stream_mode="updates"

Для этапы апдэтаў рэжыму стрымаў Метад 1 неабходна пазначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння прычыні змены коду. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Спрыяйце цій этапы як даговору межаў вхідных даных і перакананых выходных рэзультатаў. Даць назвы артыфактам, пазначыць крэтыяры успеху і не прымаць тыхню частковую завершанасць. Заставіць людзкія апраўленні для тых крокаў, якія вітрачаюць грошы або зменяюць даны для працы. Компіляцыйныя налашчэнні не ўзроўнаўцяюцься з пачатковай цэласнасцю бізнес-процэсаў.

for event in graph.stream(..., stream_mode="updates"):

Што гэта робіць

У стадыі «Што я роблю» неабяжна праймеры вхідных дадзеных, адміністратара крока і крэтэрыяў завершэння пры перадзеіснаванні коду. Аператары должны магчымае запускаваць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выканання і кост токенаў або запытаў разам з функцыйнальнымі рэзултатамі. Відразы костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмовай асяроддзя ў спакульную. Заставіце людзкую апраўдку для тых крокаў, якія вітрачаюць грошы або зменяюць даныя ў працэсе. Працэс складання коду не ўзроўнаважваеся з повнасцю бізнес-функцый. У стадыі «Што я роблю» неабяжна праймеры вхідных дадзеных, адміністратара крока і крэтэрыяў завершэння пры перадзеіснаванні коду. Аператары должны магчымае запускаваць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Дакументавайце як «шчаслівы» шлях, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контрольныя пункты і обработка некорэктных запытаў ёсць часткай продукту, а не пасляднім дапрацоўкам.

{
    "chatbot": {
        "messages": [...]
    }
}
{
    "dummy": {
        "messages": [...]
    }
}

Чаму гэты рэжым ўжыткавы

Кал працуеце над этапам «Чаму гэты рэжым ўжыткавы», спачатку запісайце умовы вікорыстання: неабяжныя даны, сігнал успеху і тое, што выходзіць на падчасныя аберанцы. Такі чарт дапамагае залічваць пазнейшыя змены ў кодзе чыста. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Кал якісь крок не выходзіць, аберанца должна вказваць на конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Зробіце перапактаванне пасля дорогіх крокаў. Програма не должна занова ставіць плату за той самы вызов LLM, калі аператар праказвае пазнейшы вузел.

Найлепшыя сцэнарыі вікорыстання

Калі працюеце над стадзіяй «Найлепшыя варыянты выкарыстання», спачатку запісайце контракт: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі спіс перакладоў заходзіць пазнейшыя змены коду чыстымі. Спрыятлівайце гэтай стадзіяй як контракту межа данымі і перакананымі выходамі. Дайце назву артыфактам, задаць тэсты на успех і не прымайце часткова завершэнне без паведамлення. Зробіце пераконтроль пасля дорогіх крокаў. Сістэма вярнення не павінна зноў ставіць плату за той самы вызов LLM, калі аператар прабуе зноў выконаць пазнейшы вузел.

Прыклад з рэальнага жыцця

Калі працуеце над стадзіяй прыклада з рэальнага свету, спачатку запісайце умовы вікорыстання: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі спіс контролю дапамагае заставіць пазнейшыя змены коду быць чыстымі. Запісвайце час выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відразлівасць костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя асяроддзя. Зробіце контрольную пазнаку пасля дорогіх крокаў. Функцыя адновлення не должна зноў нараховваць косты той самай вызову LLM, калі аператар прабуюць зноў запрацаваць пазнейшы вузел. Калі працуеце над стадзіяй прыклада з рэальнага свету, спачатку запісайце умовы вікорыстання: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі спіс контролю дапамагае заставіць пазнейшыя змены коду быць чыстымі. Дакументавайце як шлях успеху, так і шлях адновлення разам. Прабавы, людзкія контрольныя пункты і обработка некорэктных паведамленняў ёсць часткай продукту, а не пазнейшым дапрацоўкам.

Метод 2: stream_mode="values"

Значэнні параметра streammode у методзе 2 працуюць наякша, калі іх розглядаць як вімерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адын прыклад неудачы і прыметку па вярнэнню да пачатковага стану пры расшырэнні масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выходзіць, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Рэзервавайце стан графа ў простам і тыпізаваным фармаце. Вкладаныя структуры маскуюць інфармацыю пра тое, які вузел запісаў канкрэтны поле, і спакойваюць працу пасля перэрываў.

for snapshot in graph.stream(..., stream_mode="values"):

Што ён робіць

Этап «Што ён робіць» працюе найэфектывней, калі яго розглядаць як вімерную паверхню. Зафіксавце адны ідэальны прыклад працы, адны прыклад неудачы і запіс пра вярнэнне да пачатковага стану, перш чым расшырваць сферу дзеяння. Разглядвайце этап як кантракт межа вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце крытэрыя успеху і не падзеўляйцеся частым, непূরным выкананнем задачы. Храніце стан графа ў простам і тыпаваным фармаце. Вкладзеныя блокі маскуюць інфармацыю пра тое, які вузел запісаў канкрэтны поле, і спакойваюць працу пасля перарываў.

print(f"  State has {len(snapshot['messages'])} message(s) now")
print(snapshot["messages"])

Чаму гэта важна

Этап «Чаму гэта важна» працюе найкрашча, калі яго розглядаць як параметр, які можна змерыць. Зафіксавайце адны ідэальны прымер працы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расшырваць масштабы. Запісвайце час выканання задач і кост токеноў або запытаў разам з рэзультатамі функцыйнасці. Відразлівае паказанне костаў з самага пачатку запобегае неспакойным рахункам, калі працэс пераходзіць з дэмавайшанняў у спяльныя асяроддзя. Храніце стан графа ў простам і тыпаваным фармаце. Вярнутыя структуры даных маскуюць інфармацыю пра тое, які вузел запісаў кожны поле, і спакшваюць продовжэнне працы пасля перарываў. Этап «Чаму гэта важна» працюе найкрашча, калі яго розглядаць як параметр, які можна змерыць. Зафіксавайце адны ідэальны прымер працы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расшырваць масштабы. Дакументавайце як шлях успеху, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контрольны пункты і обработка некорэктных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

Найлепшыя варыянты выкарыстоўвання

Для этапы найкрашчых варыянтаў выкарыстання неабходна прадзефінаваць вхідныя даны, адпаведальную особу за крок і крэтыяры завершэння пры зміне коду. Аперацыйныя працавнікі должны магчыма ўвайсці крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптаў. Калі крок не выконваецца, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны працэс. Неабходна людская апраўда для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны ў працэсе. Компіляцыйныя налашчэння не ўзроўнаўцуюцься з повнай адпаведальнасцю ў бізнесе.

Прыклад з рэальнага жыцця

Для этапы рэальнага прыкладу неабяжна прадзеўліць вхідныя даны, адпаведальнага за крок і крэтарыя выходу пры перадзеўлівцы коду. Аператары должны магчымае запускаць крок з вядомай точкі контролю, не падозрываючы схованы стан. Спрыяйце гэтай этапы як кантракту межа вхіднымі данымі і падтвердзенымі выходамі. Даўце назвы артыфактам, прадзеўліць перакананні ў успеху і адмовіцеся ад тыхнага частковага завершэння без паведамлення. Заставьце людзкія апраўданні для тых крокаў, якія вітрачаюць грошы або зменяюць даны праўдзівай працы. Кампіляцыйныя наладкі не ўзроўнаваліся з пачытальнасцю бізнес-процэсу.

Метод 3: astream_events() для стрымування токен за токенам

Для астрым-заходаў методу 3 для этапы неабходна пазначыць вхідныя даны, адпаведальнага за крок і крэтыяры выходу пры перадзеі коду. Аператары должны магчыма было перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выканання і кост токенаў або запытаў разам з функцыйнальнымі рэзультатамі. Відразлівае паказанне костаў запобегае неспадзяваным рахункам, калі траекторыя пераходзіць з дэмаверсіі ў спадзеленыя сераўысы. Калі наступны крок — гэта код або вызов інструмента, валідаванне структураваных выходных дадзенняў за дапамою схемы лепша, чым вільная проза. Для астрым-заходаў методу 3 для этапы неабходна пазначыць вхідныя даны, адпаведальнага за крок і крэтыяры выходу пры перадзеі коду. Аператары должны магчыма было перзапускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Дакументавайце як шлях успеху, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контрольныя пункты і обработка некорэктных дадзенняў ёсць часткай продукту, а не пасляднім дапрацоўкам.

async for event in graph.astream_events(..., version="v2"):
if event["event"] == "on_chat_model_stream":
chunk = event["data"]["chunk"].content

Што гэта рабіць

Калі працуеце над этапам «Што гэта рабіць», спачатку запісайце умовы кантракту: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць пад частковыя неудачы. Такі спіс контроля дапамагае заліцвачыць змяны ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшоў, неудача павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Зробіце перапактаванне пасля дорогіх крокаў. Програма не павінна знову сцягваць плата за той самы вызов LLM, калі аператар праказвае познейшы вузел.

Чаму гэта важна

Калі працюеце над этапам «Чаму гэта важна», спачатку запісайце угоду: неабяжлівыя даныя, сігнал успеху і тое, што выходзіць у разе частковага невыпання. Такі спіс пераконтролюе чыстасць пазнейшых змян у кодзе. Спрэцьвуйце да гэтага этапу як да угоды межа данымі і перакананымі выходамі. Дайце назвы элементам, задаце правіла пераканання успеху і не падзейцеся частковым завершэнням без паведамлення. Зробіце пераконтроль пасля дорогіх крокаў. Сістэма вярнення не павінна зноў выклікаць той самы календар LLM, калі аператар прабуе зноў запрацаваць з пазнейшым вузлам.

Чаму astream_events() ў рэжыме асінхроннасці

Калі працуеце над стадзіяй «Чаму astreamevents ў рэжыме async», спачатку запісайце угоду: неабяжныя вхідныя даны, сігнал успеху і тое, што выходзіць у разе частковага невыпання. Такі спіс контроля дапамагае заліцвачыць пазнейшыя змены коду. Запісвайце час выканання і вартасьць токена або запыту праза функцыйнальныя рэзултаты. Відразувая вартасьці запобегае неспакоўным рахункам, калі працэс пераходзіць з дэмаверсіі ў спяльныя асяроддзя. Зробіце контрольную пазнаку пасля дорогіх крокаў. Функцыя вярнення не павінна знову стаўляць рахунак за той самы вызов LLM, калі аператар перапрыяўляе пазнейшы вузел. Калі працуеце над стадзіяй «Чаму astreamevents ў рэжыме async», спачатку запісайце угоду: неабяжныя вхідныя даны, сігнал успеху і тое, што выходзіць у разе частковага невыпання. Такі спіс контроля дапамагае заліцвачыць пазнейшыя змены коду. Дакументавайце як «вдалы» шлях, так і шлях вярнення да нормальнасьці. Перапрыяўленні, людзкі контроль і обработка некорэктных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

asyncio.run(token_stream())

Розумэнне фільтра западзеў

Этап розумэння фільтра западзеў працуе наякша, калі яго спрыятарабатваць як меравальную плошчу. Зберыце адна ідэальная транскрыпцыю, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перш чым расшырваць сферу дзеяння. Валіце малыя, тэставальныя елементы замест большых скрыптов. Калі якісьць крок не выйшае, прычына неудачы павінна вказваць на адную адпаведальнасць, а не на заплутаны ланцуг дзеяння. Рэжым графа павінен застацца простым і з адначыным тыпам дадзеных. Вярнутыя блокі маскуюць інфармацыю пра тое, які вузел запісаў канкрэтны поле, і спакойваюць працу пасля перарываў.

if event["event"] == "on_chat_model_stream":
chunk = event["data"]["chunk"].content

3 рэжыму стрымавання на простай англійскай мове

Этап 3 «Рэжымы стрымінгу» працюе наяўна, калі яго спрыяваць як мерыемую паверхню. Запісаце адна «золатая» транскрыпцыя, адын прыклад неудачы і прыметку па вярнэнню да пачатковага стану пры расшырэнні масштаба. Спрыявайце гэты этап як кантракт межа вхіднымі дадзеннямі і перакананымі выхіднымі рэзультатамі. Даўце назвы артыфактам, задаце крытэрыя успеху і не падзеўляйцеся частым, некомплектным выкананнем задачы. Храніце стан графа ў простам і тыпаваным фармаце. Вкладзеныя блокі маскуюць інфармацыю пра тое, які вузел запісаў які поле, і спакшуюць возз'яданне пасля перарываў.

updates

Этап апдэйтаў працюе наякша, калі яго спрыяваць як мерыемую паверхню. Зберагуце адны ідэальны прыклад працы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Запісвайце часы выканання і вартасць токенаў або запытак па боку ад рэзультатаў функцыяналізму. Відразлівае паказанне вартасцей з’являецца рана, таму не будзе неспакою з рахункамі, калі працэс перэйдзе з дэма-серавера ў спяльныя асяроддзя. Храніце стан графа ў простам і тыпаваным фармаце. Вярнутыя блокі маскуюць інфармацыю пра тое, які вузел запісаў канкрэтны поле, і спакшваюць продовжэнне працы пасля перарываў. Этап апдэйтаў працюе наякша, калі яго спрыяваць як мерыемую паверхню. Зберагуце адны ідэальны прыклад працы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Дакументавайце як шлях успеху, так і шлях вяснавання проблем. Перапрыбуткі, людзкія контралі і обработка некорэктных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

values

На стадыі вылічэння значэнняяў неабходна прадзефінаваць вхідныя даны, адпаведальную особу за крок і крытэрыя завершэння пры перадзмене коду. Аперацыйныя працавнікі должны магчымае рэалізаваць павторную експансію крока з вядомай точкі контролю, не прабуючы спадарожваць схованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест амаль неканчатых скрыптав. Калі крок не выконваецца, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцужок задач. Неабходна людская апраўда для тых крокав, якія выкарыстоўваюць грошы або зміняюць даны ў працэсе віробніцтва. Компіляцыйныя налашчэння не ёсць гарантыяй полнай адпрацоўкі бізнес-процэса.

astream_events

Для этапы astreamevents неабяжна прадзеўкаваць вхідныя даны, абавесцелювальніка крока і крэтыяры завершэння пры перадзеўкаванні коду. Аператары павінны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы схованы стан. Спрацавваць з гэтай стадыяй як з кантрактом межаў вхідных дадзеных і паверыганых выходных. Даць назву артыфактам, прадзеўкаваць крэтыяры успеху і адмовіцца ад бяспечнага частковага завершэння. Заставіць людзкую апраўдку для тых крокаў, якія выкарыстоўваюць грошы або зміняюць даны праўай працы. Кампіляцыйныя наладкі не ўзроўнаваліся з пачытальной завершанасцю задачы.

Какі рэжым стрымування вам трэба выбраць?

Для выбору рэжыма стрымінгу неабяцкова ўзначыць вхідныя даны, адпаведальнага за крок і крэтыры завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выканання і вартасць токена або запыту разам з функцыйнальнымі рэзултатамі. Відразы вартасці з самага пачатку запобегае неспакоўным рахункам, калі працэс пераходзіць з дэмовай асяроддзя ў спакульную. Заставіце людзкую апраўку для тых крокаў, якія вітрачаюць грошы або зменяюць даны ў працэсе. Працэс складання коду не ўзначае повнайсткіўнасці продукту з точка зору бізнеса. Для выбору рэжыма стрымінгу неабяцкова ўзначыць вхідныя даны, адпаведальнага за крок і крэтыры завершэння пры змяне коду. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Дакументавайце як шлях успеху, так і шлях вярнення да нормы. Перапрыбуткі, людзкія контрольныя пункты і обработка некорэктных паведамленняў ёсць часткай продукту, а не елементамі, якія дадаюцца пазней.

.

Існуючы updates калі:

Калі працуеце над этапам «Існуючы updates калі», спачатку запішыце умовы: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частковым нявыпаннем. Такі спіс контроля дапамагае заліцвачыць змяны коду. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшоў, прычына нявыпанні павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Зробіце перапактаванне пасля дорогіх крокаў. Функцыя адновлення не павінна зноў выклікаць той самы календар LLM, калі аператар праканае пазнейшы вузел.

Існуючы values калі:

Калі працюеце над раздзелам «Выкарыстоўваць значэнні пад час стадыі», спачатку запісайце кантракт: неабходныя даны, сігнал успеху і тое, што выходзіць пад час частковага нявыпання. Такі спіс пераконтроўкі дапамагае заліцвачыць пазнейшыя змены ў кодзе. Спрыймайце гэтую стадыю як кантракт межа данымі і перакананымі выходамі. Дайце назву рэзультатам, задаце правілы пераканання успеху і не падтрымайце тыхія частковыя завершэння. Зробіце пераконтроўку пасля дорогіх крокаў. Програма для продакцыі не должна занова ставіць плату за той самы вызыв LLM, калі аператар праканае пазнейшы вузел.

Выкарыстоўваць astream_events калі:

Калі працуеце над практыкай «Use astreamevents when stage», спачатку запісаце кантракт: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частковыя неудачы. Такі спіс пераканае ў тым, што пазнейшыя змены коду будуць чыстымі. Запісваюце час выканання і кост токена або запыту разам з функцыйнальнымі рэзултатамі. Відразувая візуабельнае прадставлення костаў запобегае неспакойным рахункам, калі працэс пераходзіць з дэмовай асяроддзя ў спакульнаныя сераўеры. Ствараеце контрольны пункт пасля дорогіх крокаў. Функцыя вярнення не должна зноў нараховваць косты той самай вызову LLM, калі аператар праканае пазнейшы вузел. Калі працуеце над практыкай «Use astreamevents when stage», спачатку запісаце кантракт: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частковыя неудачы. Такі спіс пераканае ў тым, што пазнейшыя змены коду будуць чыстымі. Аддзекументаваеце як «шчаслівы» шлях, так і шлях вярнення да нормальнасці. Праканы, людзкія контрольныя пункты і обработка некорэктных паведамленняў ёсць часткай продукту, а не чымсь, што дадаецца пазней.

Лепшыя ментальныя мадэлі: стрымінг для корыстуначаў проты стрымінга для распрацоўшчыкаў

Этап «Лепшыя ментальныя мадэлі» работае наўздоўж, калі яго спрыяваць як мерыемую плошчу. Запісаўце адну ідэальную транскрыпцыю, адзін прыклад неудачы і прыметку па адвярненню працы перш чым расшырваць масштаб.

Стрымінг для корыстуначаў

Стрымінг для распрацоўшчыкаў

Шаблон для працы, які вам, верагодна, знадобіцца

Пашырэныя памылкі пад час стрымінгу адпаведзей LangGraph

1. Іспользованне стрымінгу токенав, калі на самай працы вам трэбуюць апошнія змены вузлаў

2. Пакладанне надзеі, што values будуць працаваць як стрымінг токенав

3. Забыванне пра тое, што astream_events() ўжо ёсць асінхронным

4. Нефільтрацыя тыпаў запускаемых задач

5. Стварэнне графаў, якія стрымуець, але не выкладаюць значымых станоў

Распраўнай парада: стрымінг становіцься ўсё моцнейшым у багатапакетных графах агентаў

updates

values

astream_events

Невялыя паследнія змены, якія можна адначыць

for event in graph.stream(
    {
        "messages": [HumanMessage("List 3 benefits of LangGraph in one line each")],
    },
    stream_mode="updates",
):
    for node_name, output in event.items():
        print(f"\nNode: {node_name}")
        for message in output["messages"]:
            print(message)

Чаму стрымінг прыдае агентам вялікай спроможнасці

Заключныы вывад

Ўсё большае спакланенне за тое, што вы чыталі.

Калі хочаце застацца на звязку або паблікаваць больш матэрыяла пра сваю работу, мяне можна знайсці тут:

Чэртак аператыўных дзеянняй