首页 / 文章 / 如果你的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,
)

防止无声删除的审批机制:

在处理该审批阶段时,首先需明确合同条款:所需的输入参数、成功标志以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合要求。 将此阶段视为输入与验证后输出之间的契约。为相关成果命名,定义成功判定标准,并杜绝无声的局部完成。 在成本较高的步骤之后设置检查点。当操作员重新尝试后续节点时,恢复流程不应再次调用相同的大型语言模型。

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阶段在被视为可测量的表面时效果最佳。在扩大范围之前,先记录一份理想的运行日志、一个故障案例以及回滚说明。 将配置信息与应用程序代码分开。环境文件、密钥存储和功能标志应集中存放于一处,这样操作人员无需查看整个系统结构即可进行审计。

加固细节2/723:针对该措施需测量耗时、错误类型以及令牌使用情况,然后依据固定的评估标准而非个人经验来判断是否保留该变更。

在实施强化措施的第3阶段,应在修改代码之前明确输入参数、该步骤的负责人以及完成标准。操作人员应能够从已知的检查点重新运行该步骤,而无需猜测隐藏状态。相比冗长的脚本,更应采用小型且可测试的单元。当某一步骤失败时,故障原因应能指向具体的责任主体,而非复杂的流程问题。

强化措施细节3/723:需记录该步骤的运行时间、错误类型以及令牌消耗情况,然后依据固定的评估标准而非主观判断来决定是否保留该变更。

在处理强化措施的第4阶段时,首先写下相关约定:所需的输入参数、成功信号以及部分失败时的处理方式。这样的检查清单能确保后续的代码修改始终符合初始要求。

在功能结果旁记录执行时间以及令牌或查询成本。提前了解这些成本信息,可避免在系统从演示环境过渡到共享环境时出现意外费用。

强化措施细节4/723:为该阶段测量实际执行时间、错误类型以及令牌消耗情况,然后依据固定的评估标准而非个人经验来决定是否保留相关修改。

将强化措施的第5阶段视为可测量的对象来处理效果最佳。在扩大范围之前,先记录一个理想运行案例、一个失败案例以及回滚说明。

应同时记录正常流程和故障恢复流程。重试机制、人工审核环节以及错误处理方式都是产品本身的组成部分,而非后续需要补充的内容。

强化细节 5/723:测量该笔记的运行时间、错误类型以及令牌消耗情况,然后依据固定的问题集而非个人经验来决定是否保留该变更。