Галоўная / Артыкулы / Практычныя прытамулкі: ваш АІ-агент не ўжо такі розумны. Як стварыць такога, які будзе

Практычныя прытамулкі: ваш АІ-агент не ўжо такі розумны. Як стварыць такога, які будзе

Практычныя прыказкі: ваш АІ-агент не ўжо такі розумны. Як стварыць такога, які будзе выкарыстоўваць кантракты, пераказы і спецыяльныя слоты для коду для команд, якія викорыстоўваюць гэты патэрн.

3392 слоў

Існавайце гэта як перапрацоўаны варыянт ідэй з статті «Ваш AI-агент не ўмны. Як стварыць той, який справды думае» для працавіка-оператара: чыткія етапы, аранжаваныя блакі з кодам і прыметкі для відновлення, якія застаюцца пасля перадачы задання.

Змест

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

Чаму большасць AI-агентаў — це проста розкішныя ланцюгі запитоў

Этап «Чаму» большасць AI-агентаў працюе найэфектывней, калі яго спрыяваць як мерыемую паверхню. Запісаце адна ідеальная транскрыпцыю, адзін прыклад неудачы і прыметку па адвярненню роботы, прычым расшырваючы масштабы. Спрыявайце гэты этап як кантракт межа вхіднымі дадзеннямі і паверыжанымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху і адмовіцеся ад тыхоўскага частковага завершэння. Задзеце бюджет токенаў на кожны раунд і на кожную сесію. Інструменты агентаў агрэсывна расшырваюць контекст; строгія ліміты не дазволяюць дэмам ператварыцца на неспакоўныя рахункі.

Проблема з фразай «Проста выкорыстоўваць ReAct»

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

Архітектура: чатыры вузлы, адна петля

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

START --> Planner --> Executor <--> Replanner --> Reporter --> END

Управлінне станам: канэк гэтага всьога

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

import operator
from typing import Annotated, TypedDict

from pydantic import BaseModel, Field

class StrategyState(TypedDict, total=False):
    """Global state that flows through the LangGraph nodes."""
    query: str
    plan: list[dict]
    scratchpad: Annotated[list[dict], operator.add]
    current_step: int
    final_report: str
    replan_count: int

Структураваныя схемы выходных дадзеных: PlanStep і Plan

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

AVAILABLE_TOOLS_TEXT = """
- get_metrics(ticker, metric?): Return stock metrics. 'metric' is optional
  (P/E, EPS, Revenue, Market Cap, Sector).
- search_news(ticker): Return recent news headlines for a ticker.
- compare_metrics(tickers: list, metric): Compare one metric across
  multiple tickers.
"""

class PlanStep(BaseModel):
    """A single executable step inside an analysis plan."""
    step_id: int = Field(description="Sequential step number")
    tool: str = Field(
        description=f"Tool to use. Must be one of:\n{AVAILABLE_TOOLS_TEXT}"
    )
    args: dict = Field(description="Arguments for the tool call")
    purpose: str = Field(description="Why this step is needed")

class Plan(BaseModel):
    """The full plan generated by the planner node."""
    goal: str = Field(description="The overall analysis goal")
    steps: list[PlanStep] = Field(
        description="Ordered list of steps to execute"
    )
class ReplanDecision(BaseModel):
    """Output of the replanner node."""

reasoning: str = Field(
        description="Analysis of current progress and findings"
    )
    should_replan: bool = Field(
        description="Whether the plan needs modification"
    )
    updated_steps: list[PlanStep] = Field(
        default_factory=list,
        description="Remaining steps if replan is needed. Empty if no changes.",
    )

Сістэма інструментаў: тры інструмента, адна база дадзенаў

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

The ToolRegistry

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

from langchain_core.tools import BaseTool
from typing import Iterable, Mapping, Any

class ToolRegistry:
    """Namespace-aware container for LangChain tools."""
    def __init__(self) -> None:
        self._tools_by_toolset: dict[str, dict[str, BaseTool]] = {}
    def add_tools(self, toolset: str, tools: Iterable[BaseTool]) -> None:
        bucket = self._tools_by_toolset.setdefault(toolset, {})
        bucket.update({t.name: t for t in tools})
    def get_tools(self, toolset: str) -> tuple[BaseTool, ...]:
        return tuple(self._tools_by_toolset.get(toolset, {}).values())
    def invoke(
        self, toolset: str, tool_name: str, tool_args: Mapping[str, Any]
    ) -> Any:
        t = self._tools_by_toolset.get(toolset, {}).get(tool_name)
        if t is None:
            raise ValueError(
                f"Unknown tool '{tool_name}' in toolset '{toolset}'"
            )
        return t.invoke(dict(tool_args))

Узел планавальніка: Думайце пры дзеянні

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

def planner_node(state: StrategyState) -> dict:
    """Create a step-by-step research plan using structured output."""
    planner = model.with_structured_output(Plan)

prompt = PLAN_PROMPT.format(
        available_tools=AVAILABLE_TOOLS_TEXT,
        ticker_choices=ticker_choices_text(),
        metric_choices=metric_choices_text(),
        query=state["query"],
    )
    plan: Plan = planner.invoke(prompt)
    steps = [s.model_dump() for s in plan.steps]
    return {"plan": steps, "current_step": 0}

PLAN_PROMPT: Дзе знаходзяцца правілы

Калі працуеце з фазай «PLANPROMPT Where the Guardrails», спачатку запісацеце кантракт: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага абякання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Храніце канфігурацыю параду ў кодзе прыемлівача. Файлы серавэра, хранальнікі секретных дадзеных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавіць аудыт без неабяжлівага чытання всей структуры. Кэшавайце стабільныя інструкцыі системы і схемы інструментаў. Перадзесланне ідэнтычных прамаўляючых частак — частая прычына зношэння ресурсаў.

PLAN_PROMPT = """\
You are a financial research planner. Given a user's analysis request,
create a step-by-step research plan using the available tools.

Available tools:
{available_tools}
Rules:
- Use only the tools listed above.
- Every plan step must be executable with one of those tools.
- When a tool accepts 'ticker' or 'tickers', use only these exact values:
  {ticker_choices}
- When a tool accepts 'metric', use one of these exact values:
  {metric_choices}
- There are no other tools available. Final synthesis is handled separately.
Create an efficient plan. Group related lookups. Aim for 4-8 steps.
User request: {query}"""

Узел выканання: па шагу

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

MAX_STEPS = 12  # Safety limit on total steps

def executor_node(state: StrategyState) -> dict:
    """Execute the next pending step from the plan."""
    plan = state.get("plan", [])
    current_step = state.get("current_step", 0)
    if current_step >= len(plan):
        return {}
    if current_step >= MAX_STEPS:
        return {"current_step": len(plan)}
    step = plan[current_step]
    tool_name = step["tool"]
    tool_args = step["args"]
    try:
        result = str(
            TOOL_REGISTRY.invoke(
                AgentName.EXECUTOR.value, tool_name, tool_args
            )
        )
        status = "Error" if result.startswith("Error:") else "Success"
    except Exception as exc:
        result = f"Error: {exc}"
        status = "Error"
    entry = {
        "step": current_step + 1,
        "tool": tool_name,
        "args": tool_args,
        "result": result,
        "status": status,
    }
    return {
        "scratchpad": [entry],
        "current_step": current_step + 1,
    }

The Replanner Node: Дзе відбываецца самакорэкцыя

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

MAX_REPLANS = 2  # Prevent infinite replanning

def replanner_node(state: StrategyState) -> dict:
    """Review progress and optionally modify the remaining plan."""
    plan = state.get("plan", [])
    current_step = state.get("current_step", 0)
    replan_count = state.get("replan_count", 0)
    scratchpad = state.get("scratchpad", [])
    remaining = plan[current_step:]
    if len(remaining) = MAX_REPLANS:
        return {}
    scratchpad_text = "\n".join(
        f"Step {e['step']}: {format_tool_call(e['tool'], e['args'])} "
        f"-> [{e['status']}] {e['result'][:150]}..."
        for e in scratchpad
    )
    remaining_text = "\n".join(
        f"Step {s['step_id']}: {format_tool_call(s['tool'], s['args'])} "
        f"- {s['purpose']}"
        for s in remaining
    )
    replanner = model.with_structured_output(ReplanDecision)
    prompt = REPLAN_PROMPT.format(
        goal=state["query"],
        scratchpad=scratchpad_text,
        remaining_steps=remaining_text,
    )
    decision: ReplanDecision = replanner.invoke(prompt)
    if decision.should_replan and decision.updated_steps:
        new_steps = plan[:current_step] + [
            s.model_dump() for s in decision.updated_steps
        ]
        return {"plan": new_steps, "replan_count": replan_count + 1}
    return {"replan_count": replan_count + 1}

REPLAN_PROMPT

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

REPLAN_PROMPT = """\
You are a financial research planner reviewing progress on a research task.

Original goal: {goal}
Completed steps and findings so far:
{scratchpad}
Remaining steps in the plan:
{remaining_steps}
Based on the findings so far, should the remaining plan change?
If an expected tool failed or revealed something unexpected, add a step
to investigate.
If a step is now redundant, remove it.
Use only the available executable tools already shown in the plan.
Do not add recommendation, summary, or report-writing steps."""

Складанне графа: LangGraph

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

from langgraph.graph import StateGraph, END
from enum import Enum

class AgentName(Enum):
    PLANNER = "planner"
    EXECUTOR = "executor"
    REPLANNER = "replanner"
    REPORT = "report"

def build_graph():
    """Build and compile the LangGraph planning-agent workflow."""
    workflow = StateGraph(StrategyState)
    workflow.add_node(AgentName.PLANNER.value, planner_node)
    workflow.add_node(AgentName.EXECUTOR.value, executor_node)
    workflow.add_node(AgentName.REPLANNER.value, replanner_node)
    workflow.add_node(AgentName.REPORT.value, report_node)
    workflow.set_entry_point(AgentName.PLANNER.value)
    workflow.add_edge(AgentName.PLANNER.value, AgentName.EXECUTOR.value)
    workflow.add_edge(AgentName.EXECUTOR.value, AgentName.REPLANNER.value)
    workflow.add_conditional_edges(
        AgentName.REPLANNER.value,
        should_continue_execution,
        {
            AgentName.EXECUTOR.value: AgentName.EXECUTOR.value,
            AgentName.REPORT.value: AgentName.REPORT.value,
        },
    )
    workflow.add_edge(AgentName.REPORT.value, END)
    return workflow.compile()

def should_continue_execution(state: StrategyState) -> str:
    """Return the next node name after re-planning."""
    if state.get("current_step", 0) >= len(state.get("plan", [])):
        return AgentName.REPORT.value
    return AgentName.EXECUTOR.value

Прыклад рэальнай екзекуцыі: адстаўленне за аднам запитам

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

{
  "metric": "P/E",
  "values": {
    "NVDA": 58.3,
    "AMD": 102.5
  }
}

Куды далей

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

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

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

Давайце продовжыць развівацца разам

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

Пашанованне ад нашага заснавальніка

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

Чэк-ліст для эксплуатацыі

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

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

Пауза пасля дорогіх крокаў. Продакцыя не должна знова выкліквати той самы календар LLM, калі аператар праказвае пазнейшы вузел.

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

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

Пауза пасля дорогіх крокаў. Продакцыя не должна знова выкліквати той самы календар LLM, калі аператар праказвае пазнейшы вузел.

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

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