Если вы не используете эти три механизма защиты в своем ИИ-агенте, он уже отправил данные.
Пошаговое руководство: если вы не используете эти три механизма защиты в своем ИИ-агенте, он уже отправил контракты, чеки и готовые блоки кода для команд, применяющих эту схему.
Используйте это как переработанную версию идей из статьи «Если вы не используете эти три механизма защиты в своем ИИ-агенте, он уже отправил ваши секреты поставщику» для операторов: четкие этапы, упорядоченные блоки кода и записи для восстановления, сохраняющиеся при передаче задач. Этап обзора работает лучше всего, если рассматривать его как измеримую основу. Соберите один идеальный пример работы, один случай сбоя и записи для возврата к предыдущему состоянию перед расширением объема работ. Предпочитайте небольшие, тестируемые единицы кода вместо обширных скриптов. Когда какой-то шаг сбивается, причина сбоя должна указывать на конкретную ответственность, а не на запутанную цепочку операций.
Во-первых: что такое промежуточное программное обеспечение и зачем оно существует?
На первом этапе, посвящённом промежуточным компонентам, необходимо определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Дайте названия создаваемым элементам, определите критерии успеха и не допускайте молчаливого частичного завершения работы. Внедрите человеческое утверждение для операций, связанных с тратой денег или изменением производственных данных. Подключение компонентов во время компиляции не гарантирует полноты выполнения бизнес-задач.
Механизм защиты, предотвращающий попадание конфиденциальной информации к модели:
Для защиты этапа обработки необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Рядом с функциональными результатами следует записывать время выполнения и стоимость токенов или запросов. Отображение затрат с самого начала помогает избежать неожиданных расходов при переходе с демо-среды в общедоступные среды. При следующем шаге, представляющем собой код или вызов инструмента, следует отдавать предпочтение структурированным выводам с проверкой схемы перед свободным текстовым описанием.
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,
)
Порог одобрения, предотвращающий тихое удаление:
При работе на этом этапе сначала запишите условия контракта: необходимые входные данные, сигнал о успехе и действия при частичной неудаче. Такой чек-лист обеспечивает прозрачность последующих изменений в коде. Рассматривайте этот этап как контракт между входными данными и проверенными выходными результатами. Укажите названия элементов, определите критерии успеха и запретите тихое частичное выполнение задачи. Выполняйте контрольные точки после дорогостоящих операций. Система возобновления работы не должна снова взимать плату за один и тот же вызов большой языковой модели, когда оператор пытается выполнить следующий этап.
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
)
Два лимита скорости, два разных способа сбоя — оба необходимы
При работе с двухэтапной системой ограничений по скорости сначала запишите контракт: необходимые входные данные, сигнал о успехе и то, что происходит при частичной неудаче. Такой список помогает сохранять честность последующих изменений в коде. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код. Создавайте контрольные точки после дорогостоящих шагов. Механизм возобновления работы не должен снова взимать плату за один и тот же вызов большой языковой модели, когда оператор пытается выполнить более поздний этап. При работе с двухэтапной системой ограничений по скорости сначала запишите контракт: необходимые входные данные, сигнал о успехе и то, что происходит при частичной неудаче. Такой список помогает сохранять честность последующих изменений в коде. Предпочитайте небольшие, тестируемые единицы кода большим скриптам. Когда какой-либо шаг терпит неудачу, причина должна быть связана с одной конкретной функцией, а не с запутанной цепочкой операций.
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: не храните ключи поставщика в репозитории, установите лимит токенов на сессию и сохраняйте отчеты рядом с фикстурами для оценки, чтобы последующие замены моделей можно было сравнивать.
Для этапа 0 по усилению безопасности определите входные данные, ответственного за шаг и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии. Документируйте как успешный, так и восстановительный пути работы. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
Деталь усиления безопасности 0/723: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора вопросов, а не на основе единичных примеров.
При работе над первым этапом записи по усилению безопасности сначала запишите контракт: необходимые входные данные, сигнал успешного выполнения и что происходит при частичной неудаче. Такой чек-лист обеспечивает честность последующих изменений в коде. Рассматривайте этот этап как контракт между входными данными и проверенными выходными данными. Укажите названия элементов, определите критерии успешности и откажитесь от безответственного частичного выполнения задач.
Деталь усиления безопасности 1/723: измерьте время выполнения, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранить изменение на основе фиксированного набора вопросов, а не на основе единичных примеров.
Второй этап усиления безопасности работает наилучшим образом, если рассматривать его как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Храните конфигурацию вне кода приложения. Файлы среды, хранилища секретов и флаги функций должны находиться в одном месте, чтобы операторы могли их проверять, не читая весь код.
Подробности усиления безопасности 2/723: измеряйте время выполнения, класс ошибок и расход токенов для этого этапа, затем принимайте решение о сохранении изменений на основе определенного набора критериев, а не на основе единичных примеров.
Для третьего этапа усиления безопасности необходимо заранее определить входные данные, ответственного за выполнение шага и критерии завершения перед изменением кода. Операторы должны иметь возможность перезапустить шаг с известной точки контроля, не догадываясь о скрытом состоянии системы. Желательно использовать небольшие, тестируемые единицы вместо обширных скриптов. При сбое шага причина должна быть связана с конкретной областью ответственности, а не с запутанной структурой обработки данных.
Подробности усиления безопасности 3/723: измеряйте время выполнения, класс ошибок и расход токенов для данного этапа, затем принимайте решение о сохранении изменений на основе установленного набора критериев, а не на основе устных оценок.
При работе над четвертым этапом инструкции по усилению безопасности сначала запишите условия работы: необходимые входные данные, сигнал о успешном выполнении и действия при частичной неудаче. Такой список поможет сохранять честность при последующих изменениях кода. Рядом с функциональными результатами записывайте время выполнения, стоимость токенов или запросов. Очевидность затрат с самого начала предотвращает неожиданные расходы при переходе с демо-среды в общедоступные среды.
Подробности усиления безопасности 4/723: измерьте время выполнения, класс ошибки и расход токенов для данной инструкции, затем решите, следует ли сохранять изменение на основе определенного набора критериев, а не на основе устных замечаний.
Четвертый этап инструкции по усилению безопасности работает наилучшим образом, когда его рассматривают как измеримую поверхность. Соберите один идеальный пример работы, один случай сбоя и запись о возврате к предыдущему состоянию перед расширением объема работ. Документируйте как успешный путь выполнения, так и путь восстановления. Повторные попытки, проверки человеком и обработка неработающих сообщений являются частью продукта, а не элементами последующей доработки.
Подробности усиления безопасности 5/723: измерьте время работы на стенде, класс ошибки и расход токенов для этой записи, затем решите, следует ли сохранять изменения на основе фиксированного набора вопросов, а не на основе единичных примеров.