Галоўная / Артыкулы / Якщо вы не викорыстоўваете гэтыя тры захаванні у сваём AI-агенте, ён вялікай шансою вже выправіўся.

Якщо вы не викорыстоўваете гэтыя тры захаванні у сваём AI-агенте, ён вялікай шансою вже выправіўся.

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

2254 слоў

Існуець перапісва ідэй з артыкула “Якщо вы не викорыстоўваете гэтыя тры механізмы захавання ў сваём AI-агенте, ён вже апрацаваў вашы секрэты для прадаўца” для аператароў: чыстыя этапы, арганізаваныя блакі коду і прыметкі з восстанавлення, якія застаюцца пасля перадачы. Этап “Агульны відзор” найэфектывней працюе, калі яго розглядаць як вимерную плошчу. Запісаўце адна ідеальная транскрыпцыя, адзін прыклад неудачы і прыметкі з вярнення да пачатковага стану, прычаму расшырюваць масштабы пазней. Валіце маленькія, тэставаныя елементы замест большых скрыптов. Калі якісьця кроку не выходзіць, прычына неудачы павінна вказываць на адну конкрэтную адпаведальнасць, а не на заплутаны ланцюг задач.

Перша частка: Чым є мідлвэр і чаму яны існуюць?

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

Захоўнік, який ловіць секрэты пры ўсуненні іх да моделі:

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

PIIMiddleware

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

from langchain.agents.middleware import PIIMiddleware

PIIMiddleware(
    "email",
    strategy="redact",            # replaces match with [REDACTED_EMAIL]
    apply_to_input=True,          # scans what you type
    apply_to_tool_results=True,   # scans what tools return - never skip this
)
import re
API_KEY_PATTERN = r"(?:sk-|ghp_|AKIA)[a-zA-Z0-9]{20,48}"
# sk-   → OpenAI and Anthropic keys
# ghp_  → GitHub personal access tokens
# AKIA  → AWS access key IDs
PIIMiddleware(
    "api_key",
    detector=API_KEY_PATTERN,
    strategy="redact",
    apply_to_input=True,
    apply_to_tool_results=True,
)

Шлюз затверджэння, які спяшае безшумныя выдаленні:

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

HumanInTheLoopMiddleware

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

from langchain.agents.middleware import HumanInTheLoopMiddleware
from langgraph.checkpoint.sqlite import SqliteSaver

# The checkpointer is not optional. Without it, resume is impossible.
with SqliteSaver.from_conn_string("./review_agent.db") as checkpointer:
    agent = create_agent(
        model="anthropic:claude-sonnet-4-20250514",
        tools=[read_file, list_directory, write_file, search_codebase],
        middleware=[
            HumanInTheLoopMiddleware(
                interrupt_on={
                    "write_file": True,       # always pause before writing
                    "read_file": False,        # reading is safe - no pause needed
                    "list_directory": False,
                    "search_codebase": False,
                }
            ),
        ],
        checkpointer=checkpointer,            # saved to SQLite, persists across restarts
    )
# First call — agent hits the interrupt at write_file and pauses
result = agent.invoke(
    {"messages": [{"role": "user", "content": "Review and fix the config files"}]},
    config={"configurable": {"thread_id": "session-001"}}
    # thread_id ties the saved state to this specific session
)


# result.interrupted == True
# result.pending_tool_call == {"name": "write_file", "args": {"path": "src/config.py", ...}}
# You show this to the user and wait for approval
# User approves - resume the same thread
final_result = agent.invoke(
    Command(resume=True),
    config={"configurable": {"thread_id": "session-001"}}
    # same thread_id - loads state from the checkpointer and picks up where it stopped
)

Два ліміты шырокаспектнасці, два разныя спосабы адказоў — вам патрэбны оба

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

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

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

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

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

from langchain.agents.middleware import ModelCallLimitMiddleware, ToolCallLimitMiddleware

ModelCallLimitMiddleware(
    max_calls=30,
    on_limit="raise",   # raises MaxCallsExceeded - catch this in your application
)
ToolCallLimitMiddleware(
    max_calls=60,
    on_limit="raise",
)

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

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

middleware=[
    # PIIMiddleware always first — it must see raw, untransformed data
    PIIMiddleware("api_key", detector=API_KEY_PATTERN, strategy="redact",
                  apply_to_input=True, apply_to_tool_results=True),
    PIIMiddleware("email", strategy="redact",
                  apply_to_input=True, apply_to_tool_results=True),

# Limits next - exact position within the group is flexible
    ModelCallLimitMiddleware(max_calls=30, on_limit="raise"),
    ToolCallLimitMiddleware(max_calls=60, on_limit="raise"),
    # Human-in-the-loop last in the safety group
    # (it fires in the after_model hook regardless of list position,
    # but last is a readable convention)
    HumanInTheLoopMiddleware(interrupt_on={"write_file": True}),
]

Аднае ўсё разам: агент для перагляду коду з тымі ж параметрамі безпекі, як у Cursor

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

from langchain.agents import create_agent
from langchain.agents.middleware import (
    PIIMiddleware,
    HumanInTheLoopMiddleware,
    ModelCallLimitMiddleware,
    ToolCallLimitMiddleware,
)
from langgraph.checkpoint.sqlite import SqliteSaver

# Custom pattern for secrets common in codebases
API_KEY_PATTERN = r"(?:sk-|ghp_|AKIA)[a-zA-Z0-9]{20,48}"
# sk-   → OpenAI / Anthropic keys
# ghp_  → GitHub personal access tokens
# AKIA  → AWS access key IDs
with SqliteSaver.from_conn_string("./review_agent.db") as checkpointer:
    agent = create_agent(
        model="anthropic:claude-sonnet-4-20250514",
        tools=[read_file, list_directory, write_file, search_codebase],
        middleware=[
            # 1. Catch secrets before they reach the model - on both surfaces
            PIIMiddleware(
                "api_key",
                detector=API_KEY_PATTERN,
                strategy="redact",
                apply_to_input=True,
                apply_to_tool_results=True,  # this is the one that catches .env reads
            ),
            PIIMiddleware(
                "email",
                strategy="redact",
                apply_to_input=True,
                apply_to_tool_results=True,
            ),
            # 2. Hard resource limits - stops infinite loops and runaway sessions
            ModelCallLimitMiddleware(max_calls=30, on_limit="raise"),
            ToolCallLimitMiddleware(max_calls=60, on_limit="raise"),
            # 3. Approval gate - nothing gets written without your explicit sign-off
            HumanInTheLoopMiddleware(
                interrupt_on={
                    "write_file": True,
                    "read_file": False,
                    "list_directory": False,
                    "search_codebase": False,
                }
            ),
        ],
        checkpointer=checkpointer,  # required for interrupt/resume to work
    )
Agent: I'd like to update src/config.py to fix the circular import.
       Here is what I plan to write:
--- src/config.py ---
       from typing import Optional
       from pydantic import BaseModel
       class Settings(BaseModel):
           debug: bool = False
           database_url: str = "sqlite:///app.db"
       ...
       Approve this change? (yes/no)
User: yes
Agent: Written. Moving to tests/test_config.py next.
The agent cannot touch anything silently. Every write surfaces for review before it happens. Secrets in any file the agent reads are replaced with [REDACTED_API_KEY] before reaching the model — which also means they never appear in the approval prompt you read. What you are reviewing is already clean.

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

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

Запісвайце адно часовы шлях і шлях вярнення ў нормальны стан. Практыкі перапрыбутку, людзкія контралеры і обработка некоректных паведамленняў є часткай продукту, а не чымсь, што дадаецца пазней.

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

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

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

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

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

Прыметка для 8540643b792a: не кладзіце ключы прадаўцаў у репазітарый, задаце верхнюю межу токенав на сесію і зберагачыце транскрыпты празаўсёды з фікстурамі для ацэнкі, каб пазнейшыя замены моделей заставаліся порównанымі.

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

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

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

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

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

Дзялей 2/723 прыцелення на зміцнэнне: вимеравайце час выканання, класію памылак і колькасць викорыстоўваных токенав для гэтага пункту, а потым вырашайце, чы хацяць застаўіць змяну, спынюючыся на апранаванай сэтцы пытанняў, а не на індывідуальных прыкладах.

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

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

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

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

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

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