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

Першы агент на LangGraph: практычны гід для пачаткоўцаў

Першы агент на LangGraph для пачаткоўцаў: навошта агенты, што LangGraph дадае да LangChain, налада праекта і пакрокавая зборка.

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

Крыніцы: Building Your First LangGraph Agent: A Practical Beginner’s Guide

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

Чаму агенты маюць значэнне

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

User question → LLM → Answer
User question → Retrieve context → LLM → Answer
User question → Agent decides what to do → Calls tools → Updates state → Produces answer

Што такое LangGraph?

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

Настройка праекта

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

pip install langgraph langchain langchain-openai langchain-community python-dotenv pydantic
pip install jupyter notebook ipython
OPENAI_API_KEY=your_api_key_here
import os
import json
from typing import Optional, List

from dotenv import load_dotenv
from pydantic import BaseModel

from langgraph.graph import StateGraph, START, END
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage
from langchain.tools import tool
load_dotenv()
llm = init_chat_model("openai:gpt-4o-mini")

Шаг 1: Адактувація стану агента

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

class PlayerState(BaseModel):
    question: str
    selected_tools: Optional[List[str]] = None

    name: Optional[str] = None
    club: Optional[str] = None
    country: Optional[str] = None
    number: Optional[int] = None
    rating: Optional[int] = None

    goals: Optional[List[int]] = None
    minutes_played: Optional[List[int]] = None

    summary: Optional[str] = None

Шаг 2: Стварэнне інструментаў

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

Інструмент 1: Зялезь інформацыю пра гэймера

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

@tool
def fetch_player_information_tool(name: str):
    """
    Returns the football club and country of a player.
    """
    data = {
        "Haaland": {
            "club": "Manchester City",
            "country": "Norway"
        },
        "Kane": {
            "club": "Bayern Munich",
            "country": "England"
        },
        "Lautaro": {
            "club": "Inter Milan",
            "country": "Argentina"
        },
        "Ronaldo": {
            "club": "Al-Nassr",
            "country": "Portugal"
        }
    }

    return data.get(name, {
        "club": "unknown",
        "country": "unknown"
    })
def fetch_player_information(state: PlayerState):
    return fetch_player_information_tool.invoke({
        "name": state.name
    })

Інструмент 2: Зялучэнне номера джэрсі

Для этапы Tool 2 Fetch Jersey неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтыяры завершэння пры зміне коду. Аперацыйныя працавнікі должны магчымае запускаць крок з вядомай точкі контролю, не падозрываючы схованы стан. Конфігурацыю трэба залічыць пазначкай ад коду прыемніка. Файлы сераўіса, хранільнікі секрэтных даных і флагі функцыйяў должны знаходзіцца ў аднам месцы, якое працавнікі можуць пераглядаць, не чытаючы весь ланцуг задач. Автэнтыфікацыя павінна выконвацца на шлюзе, а пераправенне прав на выкарыстоўвання — у рэжыме апрацоўкі дадзеных. Толькі токэн-носіцель не ёсць межай адпаведнае часткі сістэмы.

@tool
def fetch_player_jersey_number_tool(name: str):
    """
    Returns the jersey number of a football player.
    """
    data = {
        "Haaland": 9,
        "Kane": 9,
        "Lautaro": 10,
        "Ronaldo": 7
    }

    return {
        "number": data.get(name, 0)
    }
def fetch_player_jersey_number(state: PlayerState):
    return fetch_player_jersey_number_tool.invoke({
        "name": state.name
    })

Tool 3: Fetch Player Rating

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

@tool
def fetch_player_rating_tool(name: str):
    """
    Returns the player's football video game rating.
    """
    data = {
        "Haaland": 92,
        "Kane": 89,
        "Lautaro": 88,
        "Ronaldo": 90
    }

    return {
        "rating": data.get(name, 0)
    }
def fetch_player_rating(state: PlayerState):
    return fetch_player_rating_tool.invoke({
        "name": state.name
    })

Крок 3: Дадаць вузлы адзысквання дадзеных

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

Адзыяванне цэлей

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

def retrieve_goals(state: PlayerState):
    data = {
        "Haaland": [25, 40, 28, 33, 36],
        "Kane": [33, 37, 41, 38, 29],
        "Lautaro": [19, 25, 27, 24, 25],
        "Ronaldo": [27, 32, 28, 30, 36]
    }

    return {
        "goals": data.get(state.name, [0])
    }

Адзыяванне колькасці празыграных хвілін

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

def retrieve_minutes_played(state: PlayerState):
    data = {
        "Haaland": [2108, 3102, 3156, 2617, 2758],
        "Kane": [2924, 2850, 3133, 2784, 2680],
        "Lautaro": [2445, 2498, 2519, 2773],
        "Ronaldo": [3001, 2560, 2804, 2487, 2771]
    }

    return {
        "minutes_played": data.get(state.name, [0])
    }

Шаг 4: Выявленне імені гэймера

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

def extract_name(state: PlayerState):
    prompt = f"""
You are a football name extraction assistant.

Extract only the surname of the football player mentioned in the question.

Question:
{state.question}

Return only one word.
"""

    response = llm.invoke([
        HumanMessage(content=prompt)
    ]).content.strip()

    return {
        "name": response
    }
Will Erling Haaland win the World Cup with Norway?
{"name": "Haaland"}

5-й крок: Стварэнне вузла планавальніка

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

def planner(state: PlayerState):
    prompt = f"""
You are a football assistant planner.

Available tools:
[
  "fetch_player_jersey_number",
  "fetch_player_information",
  "fetch_player_rating"
]

User question:
{state.question}

Choose which tools are needed to answer the question.

Return only a valid JSON array of tool names.
Example:
["fetch_player_information", "fetch_player_rating"]
"""

    response = llm.invoke([
        HumanMessage(content=prompt)
    ]).content.strip()

    try:
        selected_tools = json.loads(response)
    except Exception:
        selected_tools = []

    return {
        "selected_tools": selected_tools
    }

6-й крок: Напісанне заключнага падсумку

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

def write_summary(state: PlayerState):
    player_data = {
        "name": state.name,
        "club": state.club,
        "country": state.country,
        "number": state.number,
        "rating": state.rating,
        "goals": state.goals,
        "minutes_played": state.minutes_played
    }

    prompt = f"""
You are a football journalist.

Using the data below, write a concise markdown summary about the player.

Player data:
{json.dumps(player_data, indent=4)}

The summary should include:
- Full player name if it can be inferred
- Country with a flag emoji if available
- Club if available
- Jersey number if available
- Rating if available
- Total goals in the last three seasons
- Average minutes per goal over the available data
- A direct answer to the user's question

User question:
{state.question}
"""

    response = llm.invoke([
        HumanMessage(content=prompt)
    ]).content

    return {
        "summary": response
    }

Этап 7: Стварэнне рабочага працэсу LangGraph

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

graph_builder = StateGraph(PlayerState)
graph_builder.add_node("extract_name", extract_name)
graph_builder.add_node("planner", planner)

graph_builder.add_node("fetch_player_jersey_number", fetch_player_jersey_number)
graph_builder.add_node("fetch_player_information", fetch_player_information)
graph_builder.add_node("fetch_player_rating", fetch_player_rating)

graph_builder.add_node("retrieve_goals", retrieve_goals)
graph_builder.add_node("retrieve_minutes_played", retrieve_minutes_played)
graph_builder.add_node("write_summary", write_summary)

Этап 8: Дадаць канцы

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

graph_builder.add_edge(START, "extract_name")
graph_builder.add_edge("extract_name", "planner")
def route_tools(state: PlayerState):
    if state.selected_tools:
        return state.selected_tools

    return ["retrieve_goals"]
graph_builder.add_conditional_edges(
    "planner",
    route_tools,
    {
        "fetch_player_jersey_number": "fetch_player_jersey_number",
        "fetch_player_information": "fetch_player_information",
        "fetch_player_rating": "fetch_player_rating",
        "retrieve_goals": "retrieve_goals"
    }
)
graph_builder.add_edge("fetch_player_jersey_number", "retrieve_goals")
graph_builder.add_edge("fetch_player_information", "retrieve_goals")
graph_builder.add_edge("fetch_player_rating", "retrieve_goals")
graph_builder.add_edge("retrieve_goals", "retrieve_minutes_played")
graph_builder.add_edge("retrieve_minutes_played", "write_summary")
graph_builder.add_edge("write_summary", END)
graph = graph_builder.compile()

Этап 9: Запуск агента

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

result = graph.invoke({
    "question": "Will Haaland be able to win the FIFA World Cup for Norway based on his recent performance?"
})
print(result["summary"])
## Erling Haaland Performance Summary

- **Player:** Erling Haaland
- **Country:** Norway 🇳🇴
- **Club:** Manchester City
- **FIFA-style rating:** 92
- **Recent goals:** 28, 33, and 36 in the last three seasons
- **Total goals in last three seasons:** 97
- **Average minutes per goal:** Around 88 minutes per goal

Haaland’s individual numbers are outstanding. His scoring rate, consistency, and elite rating show that he is one of the most dangerous forwards in world football.

However, winning the FIFA World Cup depends on much more than one player. Norway would need strong squad depth, tactical discipline, defensive quality, and consistent performances throughout the tournament.

So, based on recent performance, Haaland can significantly improve Norway’s chances, but a World Cup title would still be difficult to predict from individual statistics alone.
result

Чаму гэты прыклад мае значэнне

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

Гэта ўсе.

1. Стан

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

2. Іспользованне інструментаў

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

3. Планаванне

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

4. Умовнае маршрутызаванне

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

5. Заканчальныя выводы

Магчымыя паліпшэння

Заканчальныя меркі

Большая спакойна за тое, што чыталі.

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

Чэк-ліст для аператывай