Практычныя прытамулі: Карэкцыя багоў неадначнай пераўтварэння дадзеных у цыклах агента ШІ
Практычныя нарады: Как вылечыць багі ненадзеянай пераўтворэння дадзеных у AI-агентах: контракты, перакананні та спецыяльныя месца для коду для команд, якія викорыстоўваюць гэты патэрн.
Наступныя прыміткі паказваюць практычны падход да рашэння задачы «Устранэння недэтэрміністычных багоў пад час перарабаткі дадзеных у цыклах AI-агента». Акцэнт ставіцца на кантракты, пераконтроўваннія і месца для вставкі коду, а не на мотывацыйныя аспекты. Калі працуеце на стадзіі агляду, спачатку запісайце кантракт: неабходныя вхідныя даны, сігнал успеху і тое, што выканаецца у разы частковага невялікога бага. Такі список дапамагае залишыцца чыстасна ў практычных змяненах коду. Запісвайце час выканання і вартасць токеноў або запытак праза функцыйнае рэзультат. Відразувыя даны пра вартасці запобегаюць неспакоўным рашчыткам, калі процес пераходзіць з дэмаверсіі ў спяльныя сераўы.
Баг, прычым не імя
Багі, які з’являюцца на пачатку етапу, найэфектыўнейша адносна ў тым случае, калі іх розглядаць як вимерную паверхню. Зафіксавайце адна «золатая» транскрыпцыю, адин прыклад неудачы і запіс пра відкатанне раней, чым расширваце обсяг работы. Зберагаюце настройкі пазырочна ад коду прыемліка. Файлы сераўнавання, хранільнікі секрэтных данных і флагі функцый крануцца ў аднам месцы, якое аператары можаць пераглядаць без неабяжнай чытанняў усіх дадзеных. Зберагаюце стан графа ў простам і типаваным формате. Вкладаныя блокі дадзеных маскуюць інфармацыю пра тое, який вузел запісаў які поле, і спакоююць продажчэй работу пасля перерываў.
# ❌ What I almost wrote — LLM call INSIDE the workflow.
@workflow.defn
class SourcingWorkflow:
@workflow.run
async def run(self, brief: SourcingBriefInput) -> SourcingResult:
suppliers = await workflow.execute_activity(research_activity, brief)
scored = await workflow.execute_activity(score_activity, suppliers)
# The LLM call — right here, in the workflow. THIS IS THE BUG.
# If worker dies here, replay will re-call the LLM and mutate state/history.
response = await llm_client.complete(
messages=build_decide_prompt(scored),
temperature=0.0,
)
selected = parse_llm_decision(response.content, scored)
approval = await workflow.wait_condition(...)
# ...create PO, initiate payment
# ✅ The fix — LLM call moved into an activity.
@activity.defn
async def decide_activity(scored: list[dict], brief: SourcingBriefInput) -> dict:
"""The LLM call lives here — in the activity, not the workflow."""
from app.agentmesh.llm import get_llm_client
client = get_llm_client()
response = await client.complete(
messages=build_decide_prompt(scored),
temperature=0.0,
)
selected, rationale = parse_llm_decision(response.content, scored)
return {"selected_supplier": selected, "decision_reason": rationale}
@workflow.defn
class SourcingWorkflow:
@workflow.run
async def run(self, brief: SourcingBriefInput) -> SourcingResult:
suppliers = await workflow.execute_activity(research_activity, brief)
scored = await workflow.execute_activity(score_activity, suppliers)
# The LLM call is NOWHERE in the workflow.
# The activity result is recorded. On replay, it's injected.
decision = await workflow.execute_activity(
decide_activity,
args=(scored, brief),
)
Закон: павторнае відтворэнне должна даць тую ж історыю
Закон адміністрування працюе наяўнасць краща, калі яго розглядаць як вимерную паверхню. Запісаце адна ідеальная версія, адзін прыклад неудачы і запіс пра вярнэнне да поперадняе стану перш чым расширваць масштабы. Дакументаваце як шлях успеху, так і шлях вяснавання проблемы. Перапрыбуткі, людзкія контрольныя пункты і обработка некоректных поведань ўскладнень є частью самага продукту, а не пасляднім дапрацоўкам. Зберагаце стан графа ў простым і типаваным формате. Вкладзеныя блокі маскуюць інфармацыю пра тое, який вузел запісаў канкрэтны поле, і спакоююць продовжэнне роботы пасля перерываў.
Пахілення: што выходзіць, калі LLM ўключаны ў процес работы
Этап выявлення наражання на рызык працюе найэфектыўней, калі яго спрыяваць як мерыемую плошчу. Зафіксавайце адны ідеальны прыклад, адзін кейс неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Валідзіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выходзіць, прычына неудачы павінна вказываць на адную адпаведальнасць, а не на заплутаны ланцюг задач. Задаўце ліміты на колькість токенав за раунд і за сесію. Інструменты з агентным падходам агрэсіўна расширваюць контекст; строгі ліміты запобегаюць таму, каб дэманстрацыі ператварыліся на неспакоючыя рахункі. Этап выявлення наражання на рызык працюе найэфектыўней, калі яго спрыяваць як мерыемую плошчу. Зафіксавайце адны ідеальны прыклад, адзін кейс неудачы і запіс пра вярнэнне да пачатковага стану перш чым расширваць масштабы. Запісвайце час выканання і вартасьць токенав або запытак праза функцыйнае рэзультат. Відкрытая інформацыя пра вартасьці з самага пачатку запобегае неспакоючым рахункам, калі процес пераходзіць з дэманстрацыі ў спяльныя сераўеры.
Чаму “temperature=0.0” не захаіщае вас
Для стадіі «Why temperature 0 0» неабяжна прадзеўдзіць вводныя даны, абавесцеліваць адпаведальнага за крок і задаць критэрыя завершэння пры перадзмене коду. Аперацыйныя працавнікі павінны магчымае перазапускаць крок з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба захаваць праз аддзел ад коду прыкладнення. Файлы сераўіса, хранільнікі секрэтных данных і флагі функцыйяў павінны знаходзіцца ў адном месцы, якое працавнікі можуць пераглядаць, не чытаючы весь ланцуг задач. Пры выконанні дзеянь, якія коштуюць грошы або зменяюць даны ў працэсе, неабяжна ўключыць людскія апраўданні. Падключэння на этапе компіляцыі не ўзроўнавалася з повнасцю бізнес-процэсаў.
Граніца: актывацыя являе сабою мембрану недэтэрмінізма
Для вялікага этапу дзеяння, перад зменайом коду, неабходна ясная дэфініцыя вхідных даных, адпаведальнага за шаг і крэтарыяў выходу. Аператары должны магчымае перадзеяць шаг з вядомай точкі контролю, не спрабоўваючы здагадвацца пра схованы стан. Неабходна аддзеяваць як шлях успеху, так і шлях вярнення. Перапрыбуткі, людзкія пераказы і обработка некоректных паведамленняў ёсць часткай продукту, а не пасляднім дапрацоўкам. Неабходна людзкая аправара для тых крокоў, якія выкарыстоўваюць грошы або зменяюць даны праўдзівай роботы. Кампіляцыйныя наладкі не ўзроўнаваліся з повнасцю бізнес-функцыяў.
Код: як гэта насправды выглядае ў AgentMesh
Для коду данага этапу, перад тым як зменіць код, неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здогадвацца пра схованы стан. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выканаецца, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны процес. Неабяжна ўключыць людзкія пераказы для тых крокоў, якія ведуць да витрачання грошаў або змены данных у прыемнай сістэме. Компіляцыйныя налаштаванні не є гарантыяю цэліснасці бізнес-процесаў. Для коду данага этапу, перад тым як зменіць код, неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аператары должны магчымае перайсці на выкананне кроку з вядомага пункта контролю, не спрабоўваючы здагадвацца пра схованы стан. Запісвайце час выканання, а таксу токенаў аб запытавань разам з функцыйнальнымі рэзультатамі. Відразувыя даны пра вартасць запобегаюць неспакойным рахункам, калі процес пераходзіць з дэмовай сістэмы ў спяльныя сераўеры.
Temporal Workflow (deterministic — replayed)
└── Activity: run_graph_until_interrupt (non-deterministic — recorded once)
└── LangGraph StateGraph
└── decide_node (async function)
└── get_llm_client().complete() ← the LLM call
Рабочы процес — чыстая оркестрацыя (workflow.py)
Калі працуеце над стадзіяй чыстай оркестрацыі рабочага процесу, спачатку запісайте умовы: неабяжлівыя даннэ, сигнал успеху і тое, што выканаецца у разы ў частковай нявыполненасці. Такі список контроля дапамагае залічваць змяны коду чыста. Храніце настройкі паза кодам прыемліка. Файлы сераўіса, базы секрэтных даных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куда аператары можу працаваць без неабяжлівага чытання всей структуры. Ставьце контрольныя пункты пасля дорогіх крокаў. Функцыя вярнення роботы не должна занова ставіць плата за той самы вызов LLM, калі аператар перапрыяўляе роботу да наступнага вузла.
@workflow.defn
class SourcingWorkflow:
@workflow.run
async def run(self, brief: SourcingBriefInput) -> SourcingResult:
# ↓ This is the boundary. The activity runs once. Result is recorded.
graph_result = await workflow.execute_activity(run_graph_until_interrupt, brief, ...)
# Wait for human signal — a Temporal primitive, not an LLM call.
# On replay, the signal is injected from history.
await workflow.wait_condition(lambda: self._approval_received, timeout=timedelta(hours=24))
# ↓ Another boundary. Resume activity runs once. Result is recorded.
resume_result = await workflow.execute_activity(resume_graph, self._approval_data, ...)
# ↓ Side effects — each is its own activity with its own retry policy.
po_result = await workflow.execute_activity(create_po_activity, args=(...), ...)
Актывацыя — дзе жыве недэтермінізм (activity.py)
Калі працуеце над заданнем, дзе паказаны этапы, спачатку запісайце умовы выканання: неабяжлівыя даны, сігнал успеху і тое, што выходзіць пад частыя неудачы. Такі список пераконтроўкі дапамагае заліцвачыць змяны ў кодзе.
@activity.defn
async def run_graph_until_interrupt(brief: SourcingBriefInput) -> dict:
graph = build_sourcing_graph(checkpointer=await get_checkpointer())
config = {"configurable": {"thread_id": activity.info().workflow_id}}
# ↓ Everything inside this call is non-deterministic. It runs ONCE.
# The result dict is recorded in the event history. On replay, it's injected.
final_state = await graph.ainvoke({"brief": brief, "suppliers": [], "attempts": 0, ...}, config)
return {"paused": True, "selected_supplier": selected, "suppliers": final_state.get("suppliers", [])}
Вузел графа — там, дзе фактычна запускаецца LLM (graph.py)
Калі працуеце з вузлам «The graph node where stage», спачатку запісайце умовы викорыстоўвання: неабходныя даны, сігнал успеху і тое, што выходзіць па частковай нявыполненасці. Такі список дапамагае залічыцца з пазнейшымі змянамі ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыполненасці павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Зберагаеце у кэшы стабільныя інструкцыі системы та схемы інструментавання. Перадзесланне ідэнтычных даных — частая прычына зайвых витрацоў. Калі працуеце з вузлам «The graph node where stage», спачатку запісайце умовы викорыстоўвання: неабходныя даны, сігнал успеху і тое, што выходзіць па частковай нявыполненасці. Такі список дапамагае залічыцца з пазнейшымі змянамі ў кодзе. Запісвайце час выконання та вартасьць токеноў чы апыткаў па боку функцыйнальных рэзультатаў. Відразувая візуабілізацыя вартасцей запобегае неспакойным рахункам, калі процес пераходзіць з дэмаверсіі ў спяльныя сераўысы.
async def decide_node(state: AgentState) -> dict:
scored = state.get("scored_suppliers", [])
messages = build_decide_prompt(brief.item, brief.quantity, brief.budget, scored, past_decisions)
# ↓ THE LLM CALL. This is the non-determinism that must never be in the workflow.
response = await get_llm_client().complete(messages=messages, temperature=0.0, max_tokens=1000)
selected, rationale = parse_llm_decision(response.content, scored)
return {"selected_supplier": selected, "decision_reason": rationale, "cost_incurred": response.cost_usd} # ↓ THE LLM CALL. This is the non-determinism that must never be in the workflow.
response = await get_llm_client().complete(messages=messages, temperature=0.0, max_tokens=1000)
Калі межы станавяцца размытымі
Календарныя параметры працуюць наўсёх краща, калі іх спрыяваць як вимерную паверхню. Запісаўце адна «золатая» транскрыпцыя, адзін прыклад неудачы і запіс пра вярнэнне да поперадньага стану пры розшырэнні масштаба. Зберагачце настройкі праза код аплікацыі. Файлы сяродавішча, хранільнікі секрэтных дадзеных і флагі функций павінны знаходзіцца ў адном месцы, куды аператары можаць аудытаваць, не чытаючы весь граф. Зберагачце стан графа у простам і типаваным формате. Вкладныя блокі маскуюць, який вузел запісаў канкрэтны поле, і спакоююць продажчыку пасля перарываў.
Temporal event history LangGraph checkpoint (Postgres)
└── ActivityCompleted(result) └── graph state at interrupt()
paused: True node: "approve"
selected: SupplierB selected: SupplierB
suppliers: [A, B, C] suppliers: [A, B, C]
Шаблон ізоляцыі — адныя тэльфаваннія ўсюды
Шаблон ізоляцыі на той жа этап працюе найэфектывней, калі яго розглядаць як вимерную паверхню. Запісаце адны ідеальны прыклад, адну справу з бягам і прыметку па вярнэнню да пачатковага стану пры расшырэнні масштаба. Дакументавайце як шлях успеху, так і шлях вярнэння. Перапрыбуткі, людзкія контраліны і обработка некоректных паведамленняў ёсць часткай продукту, а не пасляднім дапрацоўкам. Храніце стан графа ў простым і типаванам формате. Вкладзеныя блокі маскуюць, який вузел запісаў канкрэтны поле, і спакоююць працу пасля перарываў.
Той жа абмежэнняе ў іншых стеках агентаў
Той жа абмежэння на стадзіі працуе лепш, калі яе спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач. Рэзультаты роботы графа павінны быць простымі та з адначытаемымі дадзеннямі. Вярнутыя структуры дадзеных маскуюць інфармацыю пра тое, каней вузел запісаў канкрэтны поле, і спаказваюць роботу пасля перарываў. Той жа абмежэння на стадзіі працуе лепш, калі яго спрыяваць як меравальную плошчу. Зберагачыце адны ідеальны прыклад роботы, адзін прыклад неудачы і запіс пра вярнэнне да пачатковага стану перад расшырэнням масштаба. Запісвайце часы виконання та косты токеноў або запытак праза функцыйнае рэзультаты. Відкрытасць костаў з самага пачатку запобегае неспакойным рашчыткам, калі процес пераходзіць з дэмаверсіі ў спяльныя среды.
Косць: што вы пасвячаеце за дэтэрмінізм
Для таго, каб вы зналі цэну сваёй задачы, пярэд зменым коду неабходна ясная ваказка пра вхідныя даны, адміністратара крока і критэрыя завершэння. Аператары должны магчымаць перзапуск крока з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба знаходзіць за межамі коду прыемлікі. Файлы сераўнавання, хранільнікі секрэтных данных і флагі функцыйяў должны быць у аднам месца, якое аператары можаць пераглядаць, не чытаяўшы весь ланцуг задач. Прызначайце людскія апраўды для рэлей, якія витрачаюць грошы або зменяюць даны у працэйнай сістэме. Падключэння пад час компіляцыі не ўзроўнаўваецца з повнай адпаведнасцю бізнес-процэсам.
Адлічны случай 1: Дзейнасці, якія трываюць дуго, і проблема «серца»
Для крайньего случая 1 з вялым виконанням етапа неабяжна прадзецьваць вхідныя даны, адпаведнага адпаведальнага за етап і крэтыяры завершэння пры перадзеўці коду. Аперацыйныя працавнікі павінны магчымае перазваляць етап з вядомай точкі контролю, не падозрываючы прыхованы стан. Неабяжна задокументаваць як шлях успеху, так і шлях вярнення да нормальнага стану. Перапрыбуткі, людзкія пераказы і обробка некоректных паведамленняў є часткай продукту, а не элементамі пазнейшага дапрацоўвання. Неабяжна застосаваць людзкую апраўдку для тых ситуацыяй, дзе відбываецца выдатак грошэй або зміняюцыся даны для працы продукту. Працэс кампілявання не є адпаведніком пачынковай готовасці продукту для викорыстоўвання.
@activity.defn
async def run_graph_until_interrupt(brief: SourcingBriefInput) -> dict:
# Long-running: graph may run 5+ minutes with multiple LLM calls
for node in graph.stream(initial_state, config):
activity.heartbeat() # ← "I'm alive, don't timeout me"
# ... process node output
Крайній случай 2: Перадача токенав LLM праз Temporal
Для стадіі стрімінгу Edge case 2 неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтырыя завершэння пры зміне коду. Аперацыйныя працавнікі должны магчымае перайскаць крок з вядомага пункта контролю без неабяжнай адгадвання схованага стану. Лепш выбіраць маленькія, тэставаныя елементы замест большых скрыптов. Калі крок не выйшаў, прычына неудачы должна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны процес. Калі наступны крок — це код або вызов інструмента, лепш выбіраць структураваныя выходныя даны з пераканальваннем схэмы замест вольнага формата тэксту. Для стадіі стрімінгу Edge case 2 неабяжна ўзначыць вхідныя даны, адпаведальнага за крок і крэтырыя завершэння пры зміне коду. Аперацыйныя працавнікі должны магчымае перайскаць крок з вядомага пункта контролю без неабяжнай адгадвання схованага стану. Запісваць час выконання і кост токеноў або запытаў разам з функцыйнальнымі рэзультатамі. Відразувая візуабілізацыя костаў запобегае неспакойным рахункам, калі процес пераходзіць з дэмавай версіі ў спяльныя сераўы.
Экстремальны ўзлокаленасці 3: Палітыкі павторных спроб адзінакоў — не всі адзінаковыя задачы павінны вестися адной і той жа спосабам
Калі працуеце над стадзіяй адзінакоў Экстремальны ўзлокаленасці 3, спачатку запісайте умовы ўзаўмадзейнасці: неабходныя даны, сигнал пра успех і тое, што выходзіць на частковай нявыполненасці. Такі список контроля дапамагае залічыць пазнейшыя змены ў кодзе. Зберагаюце настройкі праза код аплікацыі. Файлы сяродавішча, хранільнікі секрэтных дадзеных і флагі функций павінны знаходзіцца ў адном месцы, куда аператары можу пераглядаць без неабяжнай чытанняў усіх элементаў. Ствараюце контрольныя пункты пасля дорогіх крокаў. Система вярнення не павінна зноў ставіць плату за той самы вызов LLM, калі аператар павторна працуе з пазнейшым вузлом.
# Side effect — strict, non-retryable. Idempotency key handles safety.
po_result = await workflow.execute_activity(
create_po_activity,
args=(supplier, item, quantity, price),
retry_policy=workflow.RetryPolicy(
initial_interval=timedelta(seconds=1),
maximum_attempts=1, # ← don't retry. Idempotency key prevents duplicates.
non_retryable_error_types=["DuplicatePOError"],
),
)
# Verification — aggressive retry, but with backoff for eventual consistency
po_verification = await workflow.execute_activity(
verify_po_exists,
args=(po_result["po_id"],),
retry_policy=workflow.RetryPolicy(
initial_interval=timedelta(seconds=2), # ← give the DB time to sync
maximum_attempts=5,
),
)
Ментальная модэль
Калі працюеце над стадзіяй «Ментальная модель», спачатку запісайце контракт: неабяжлівыя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі список пераконтроўвае чыстасць пазнейшых змян у кодзе. Дакументавайце як шлях успеху, так і шлях вяснавання. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў ёсць часткаю продукту, а не пазнейшым дапрацоўкам. Зберагайце у кэшы стабільныя інструкцыі системы і схемы інструментаў. Перадача ідэнтычных прамулкіў — частая прычына зношэння ресурсаў.
Што будзе ў наступным апускі
Калі працуеце на стадыі «Што прыходзіць», спачатку запісайце умовы кантракту: неабяжлівыя даны, сигнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список пераканальвае заставаць пазнейшыя змены коду адпаведнымі. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыполнення павінна вказваць на адзіну адпаведную абяспекту, а не на заплутаны ланцюг задач. Зробіце пераканальванне пасля дорогіх крокаў. Система не павінна зноў вырахоўваць адплату за той самы вызов LLM, калі аператар праканае пазнейшы вузел. Калі працуеце на стадыі «Што прыходзіць», спачатку запісайце умовы кантракту: неабяжлівыя даны, сигнал успеху і тое, што выканаецца у разе частковага нявыполнення. Такі список пераканальвае заставаць пазнейшыя змены коду адпаведнымі. Запісвайце час выканання і кост токеноў або запытаў праза функцыйнае рэзультат. Відкрытыя даны пра косцы з’являюцца раніше, таму не будзе неспадзянак у вырахунках, калі процес пераходзіць з дэмаверсіі ў спяльныя сераўы.
Апавяданні
Этап апеляцыйй працюе найкраща, калі яго спрыяваць як меравальную плошчу. Зберагучы адны ідеальны прыклад, адну справу з бягам і запіс пра возврат да пачатковага стану, перш чым расширваць масштабы. Храніце конфігурацыю параду ў коде прыкладнага програма. Файлы сераўіса, сховішчы секрэтных даных і флагі функцыйяў должны знаходзіцца ў аднам месцы, куды аператары можаць адбавляць контроль, не чытаючы весь граф. Храніце стан графа у простам і типаваным формате. Вярнутыя блокі дадзеных маскуюць інфармацыю пра тое, канферны вузел запісаў канкрэтны поле, і спакойваюць продаж чынення пасля перарываў.
Чэк-ліст для эксплуатацыі
Для этапа чэк-ліста для эксплуатацыі неабходна прадзефінаваць вхідныя даны, адпаведальную особу за кожны крок і крэтырыя завершэння перад змінайом кода. Аператары должны магчымае перзапускаць крок з вядомай точкі контролю, не падозрываючы пра схованы стан.
Спрыявайце этапу як даговор між вхіднымі данымі і перакананымі выходнымі рэзультатамі. Даўайце назвы артыфактам, прадзефінавайце крэтырыя успеху і адмовляйцеся ад тых варыянтаў, калі завершэнне адбываецца часткова без паведамлення.
Неабяжна людская апраўка для тых элементаў, які выкорыстоўваюць грошы або зменяюць даны пра вырабніцтва. Падключэнне ў час компілявання не абавязкова значыць повнайшую падтрымку бізнес-процэсаў.
Напісце кароткі посібнік: як роцыяваць кантрольныя клучы, як спрачыслаць чергу, як анулюваць пярэдніе змены.
Зазначайце час выканання задач і кост токенаў або запытаў разам з рэзультатамі ўжывання. Відразлівае відображэнне костаў з’являецца прычыной адсутнасці неспакою, калі сістэма пераходзіць з дамовай версіі ў спадзяльныя сераўы.
Неабяжна людская апраўка для тых элементаў, які выкорыстоўваюць грошы або зменяюць даны пра вырабніцтва. Падключэнне ў час компілявання не абавязкова значыць повнайшую падтрымку бізнес-процэсаў.
Перад пераводам сістэмы на вышэйшую версію заморозьце існуючыя версіі, зафіксуйце критычныя моменты працы сістэмы і паказваце крокі для анулявання змэн. У спадзяльных сераўых неабходны ліміты на частоту запытаў, пераканання ў правільнасці належнасці ресурсаў і чысткая відпаведальнасць за роцыяванне кантрольных клучаў. Валіце простую надзейнасць працы сістэмы над красавіцкімі, але разовымі дамовымі прыкладамі.
Запіска параграфу 11b06b04feeb: не трэба кантрацеўваць ключы прадаўцаў у репазітарыі, задаць максімальную кантэйнернасць токена на кожную сесію, а таксама зберагчы транскрыпціі празаўседле з фікстурамі для ацэнкі, каб пазнейшыя замены моделей заставаліся пораўнанневымі.
Калі працуеце над стадзіяй 0 запіскі пра зміцнэнне, спачатку запісайце контракт: неабходныя вхідныя даны, сігнал успеху і тое, што выходзіць у разе частковага нявыпання. Такі чэк-ліст дапамагае заставаць пазнейшыя змены коду чыстымі. Дакументавайце як шлях успеху, так і шлях вяснавання. Перапрыбуткі, людзкія контралі і обработка некоректных паведамленняў ёсць часткаю продукту, а не пазнейшым дапрацоўкам.
Дзеянне пра зміцнэнне 0/898: вы мерыце час выканання, класію адзінакоў і выкарыстоўванне токенаў для гэтай запіскі, а пасля выявляеце, чы хацеце заставіць змену на адной падставе фіксаванага набора запытанняў, а не на адной падставе індывідуальных спазыроў.
Этап 1 практыкы зміцнення працюе найэфективней, калі яго розглядаць як вимерную паверхню. Зафіксавце адны ідеальны прыклад роботы, адну справу з бягамі та прыметкі па варыянты адвярнення пры розширэнні масштаба. Разглядзайце гэты этап як кантракт межа вхіднымі даннымі та пераканаленымі выходнымі рэзультатамі. Даўце назвы артыфактам, задаце критэрыя успеху та адмовіцеся ад безсловеснага частковага завершэння.
Дзеянне зміцнення 1/898: вимеравайце час выканання, класы каштоўкаў та витрату токенав для гэтай прыметкі, а пасля, на аднойчынку з фіксаваным наборам пытанняў, а не на аднойчынку з пераказамі, выберайце, чы рашыцца застаўіць змяну.
Для другага этапа практыкы зміцнення неабяжна пазначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння пры зміне коду. Аператары должны магчымаць перзапуск кроку з вядомай точкі контролю, не падозрываючы прыхованы стан. Конфігурацыю трэба залічыць пазначкай ад коду прыемліка. Файлы сераўнавання, хранальнікі секрэтных данных і флагі функцыйяў должны знаходзіцца ў аднам месцы, якое аператары можаць пераглядаць, не чытаяўшы весь код.
Дзялейчык практыкі зміцнення 2/898: вы мераваеце час выканання, класы каштоўкаў і витрату токенав для гэтай практыкі, а потым выявляеце, чы рашацься застаўіць змяну на адной пазначкай фіксаванага набора пытанняў, а не на адной лічбе.
Калі працуеце над 3-й стадзіяю практыкы забезпечэння безпекі, спачатку запісайце умовы кантракта: неабяжлівыя данні, сігнал успеху і тое, што выходзіць на падзею частковага нявыпання. Такі список контроля дапамагае заліцвачыць пазнейшыя змены ў кодзе. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісь крок не выйшае, прычына нявыпання павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач.
Дзеянне 3/898 практыкы забезпечэння безпекі: замерайце час выканання, класы каштоўкаў і витраты токенав для гэтай практыкі, а потым вырашайце, чы робіць змены на адной основе фіксаванага набору пытанняў, а не на адной лячбе.
3-я стадзія практыкы забезпечэння безпекі працуе лепей, калі яе спрыяваць як меравальную плошчу. Запісайце адны ідеальны прыклад работы, адзін кейс нявыпання і прыказку па адкатаванні, перш чым расширваць масштаб. Запісвайце часы выканання і вартасць токенав або запыткаў разам з функцыйнальнымі рэзультатамі. Відкрытая інформацыя пра вартасці запобегае неспакойным рашчыткам, калі працэс пераходзіць з дэмаверыяна на спакульнаныя сераўсы.
Дзеянне паўжчання 4/898: звярніце увагу на час выканання, клас памылакі і колькасць викорыстоўваных токенаў для гэтага зьведнення, а пасля, на аднойчыне з фіксаваным наборам пытанняў, а не на асобістых спазырэннях, выявіце, чы хацяце застаўіць змены.
Для 5-го этапу паўжчання неабходна перад змянай коду чытко визначыць вхідныя даны, адпаведальнага за крок і критэрыя завершэння. Аперацыйныя працавнікі должны магчымае перадзьвяжыць выкананне кроку з вядомай точкі контролю, не падозрываючы прыхованы стан. Неабходна адначасова задокументаваць шлях успеху і шлях вяснавання проблем. Практыка падзьяздоў, людскія перакрыцця і обробка неканэктываў яе ўжо часть продукту, а не элемент пазнейшай дапрацоўкі.
Дзеянне паўжчання 5/898: звярніце увагу на час выканання, клас памылакі і колькасць викорыстоўваных токенаў для гэтага зьведнення, а пасля, на аднойчыне з фіксаваным наборам пытанняў, а не на асобістых спазырэннях, выявіце, чы хацяце застаўіць змены.
Этап 0 пры практыкаванні заходаў з абароны працюе наякша, калі яго розглядаць як вимерную паверхню. Зберыце адна «золатая» версія коду, адны прыклад неудачы і запіс пра можлівасць вярнуцься да пачатковага стану, прычым расшырюючы сферу дзеяння. Запісвайце часы выканання і вартасць токенаў або запытак пад функцыйнальнымі рэзултатамі. Відразы вартасцей з самага пачатку запобегае неспакоўным рахункам, калі процес пераходзіць з дэмаверсіі ў спяльныя сераўы.
Дакладнасць пры практыкаванні заходаў 0/917: звярніце увагу на час выканання, класы каштоўкаў і витраты токенаў для гэтага пункту, а потым вырашыце, чы хацяце застаўіць змены, спакоюючыся на апранаванай сэтцы пытанняў, а не на індывідуальных спазырэннях.
Для этапа 1 пры практыкаванні заходаў з абароны спачатку задайце вхідные даны, адпаведальнага за крок і критэрыяы завершэння, прычым змінюючы код. Аператары должны магчымае пераўстаць выкананне крока з вядомага пункта контролю, не спадзяючыся на схованы стан. Запісвайце як «успешны» так і «восстанавліваючы» шляхі. Перапрыбуткі, людзкія контрольны пункты і обработка некоректных запытак ўжо є частью продукту, а не чымсь, што дадаецца пазней.
Дзеянні паўжасткі 1/917: звярніце увагу на час выканання, клас памылак і колькасць викорыстоўваных токенав для гэтага зьязку, а пасля, на аднойчынай базе фіксаванага набору пытанняў, а не на індывідуальных прыкладах, выявіце, чы хацяце застаўіць гэтыя змены.