Галоўная / Артыкулы / Практычныя нарады: Стрімування відповідей у LangGraph: 3 практычныя схемы.

Практычныя нарады: Стрімування відповідей у LangGraph: 3 практычныя схемы.

Практычныя нарады: Стрімування відповідей у LangGraph: 3 практычныя схемы, якія використовуються у контрактах, перевірках та шаблонах коду для команд, які застосовують цю схему.

3658 слоў

У гэтым карыце парадоксальным чынам перакладзены ўсі элементы з англійскай на беларускую мову: «Гэты практычны карыце перакладзе шлях ад сыр'ёў да рабочай системы для: Стрымаванне адпаведзяў у 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)

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

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

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

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

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