ELAI S.r.l.

当文档试图指挥智能体:区分数据、指令与权限

通过本地可复现实验,理解 AI 智能体工具控制中的来源、接收者、信息流与保证的边界。

当文档试图指挥智能体:区分数据、指令与权限

读取文档不等于授权文档

设想一个 AI 智能体受命读取发票,并向财务部门添加备注。文档中还夹着一句话,要求更换目标或删除记录。人通常知道,发票是待查看的材料,不是分配新任务的主管。若系统把指令与检索文本混在同一对话里,就必须从架构上建立这种区分。

核心问题是:即使模型误解文本,能否限制恶意文档带来的后果?我们构建一个小型控制器,在模拟写入前检查三件事:操作是否允许、目标是否授权、接收者是否有权阅读使用的全部数据。随后证明权限传播的一项性质,并测试八个案例。没有调用模型,也没有发送消息;测试对象是软件契约,而不是大语言模型的抗攻击能力。

建议与执行之间的边界

这里的智能体把语言模型与搜索、记录更新等软件工具结合起来。提示注入试图将未经授权的内容变成系统指令。文本可能语法正确,也可能来自我们有权读取的来源;问题在于赋予它什么权力。“可以查阅文档”和“文档可以决定下一步行动”是两种不同授权。

建议是模型生成的候选调用,即工具名和参数;执行是系统实际产生效果的时刻。控制器位于两者之间。它不判断一句话听起来是否可疑,而是检查任务与权限所定义的属性。本练习唯一授权效果是向符号部门标识 finance 添加内部备注,且只能包含该部门有权阅读的信息。

同时明确假设:初始任务、控制器和文档元数据可信,文档内容与语言输出不可信。所有写入必须经过控制器。攻击者不能修改 Python 代码,也不能随意制造授权标签。这是教学模型的条件,并非下文 dataclass 提供的保证。如果模型还有不受限制的 shell,本例并不是能让它安全运行的沙箱。

每个值都携带两项附加信息

纯文本既不说明谁能读,也不说明来自哪里。为每个值 v 附加允许读者集合 R(v) 和来源集合 S(v)。发票 a 允许 finance 与 manager 阅读,保密预算 b 只允许 manager。名称表示系统已解析的身份,不是文档可以编造来取得权限的文字。代码使用 frozenset,其元素不能就地修改。

R(a) = {finance, manager} R(b) = {manager} R(c) = R(a) ∩ R(b) = {manager}

∩ 表示交集:只保留两个输入都允许的读者。摘要同时包含发票与预算信息时,finance 不能读取摘要,因为它无权阅读第二份文档。使用并集会出错:仅有发票权限的人也会获得预算访问权。合并数据不应成为扩大权限的捷径。

R(f(v₁,…,vₙ)) = ⋂ᵢ R(vᵢ) S(f(v₁,…,vₙ)) = ⋃ᵢ S(vᵢ)

来源则使用并集 ⋃:结果保留其依赖的全部来源。f 表示正确声明所有输入的变换,例如拼接文本或生成摘要。控制器用 R 决定访问,并记录 S 以解释决定。来源已知不意味着内容真实;可识别来源也可能包含错误。

交集规则是保守的。如果摘要读取了保密文档,最后却只重复公开句子,该机制仍保留限制,因为没有证明秘密未影响句子选择。放宽标签需要额外的解密规则,即 declassification,由输入文本之外的授权主体决定。本例不实现它:变换不能扩大 R。

写入前的三项条件

候选调用包含操作 o、目标 d 和正文 b。第一项仅允许 append_internal_note;第二项要求 d 是可信任务选定的 finance,而不是从文档提取的目标;第三项要求 finance 属于 R(b)。必须全部通过:允许一个目标不代表允许任何正文,内容可读也不代表允许任何操作。

allow(o,d,b) = [o = append_internal_note] ∧ trusted_destination(d) ∧ [d = finance] ∧ [d ∈ R(b)]

∧ 表示“且”:任一条件为假就阻止调用。trusted_destination 不是语言分类器,而是脚本中只由可信上下文赋予的属性。C4 中 finance 字符串来自文档,虽然与预期名称相同,仍被拒绝。这是刻意严格的策略:保留最初目标,就无需接受查阅材料提出的其他目标建议。

检查必须在产生效果之前进行。只有 allow 为真,脚本才向内存列表 mock_log 追加条目,以模拟写入。不会调用远程服务,也不承诺分布式事务。生产环境还需阻止其他工具路径,并确保对象、目标、权限在检查与执行之间不改变。对过期数据做出正确检查,也无法保护实际动作。

一个小证明:权限不会扩大

在明确假设下,可以得到比“八个案例有效”更强的结论。考虑一串始终使用交集、并记录全部输入的变换。最终值 v 的每个允许读者,必须获准阅读 v 所依赖的每个来源。初始值满足该性质,因为假设元数据正确。下面说明每次变换为何保持它。

设结果 c 依赖 a 和 b。按定义,身份 r 属于 R(c),就同时属于 R(a) 和 R(b)。若 a、b 已满足性质,r 就可阅读它们各自全部来源,也就可阅读 c 的来源并集。逐步重复即可得到归纳证明。因此最终检查 r ∈ R(c),能阻止将 c 显式交给被某个来源排除的读者。

r ∈ R(c) ⇒ r ∈ R(a) ∧ r ∈ R(b) R(c) ⊆ R(a); R(c) ⊆ R(b)

结论只涉及带标签值的显式流动,并未证明整个程序没有漏洞、元数据真实,或所有信息通道都已覆盖。有效性依赖这些假设:漏掉一个输入、绕过一次检查、初始标签错误,都超出证明范围。证明的价值在于指出系统审查应集中在哪里。

八个候选调用及其判断理由

实验直接构造候选调用,并不让模型生成。C1 向 finance 添加发票摘要,通过。C2 尝试其他操作,被阻止。C3 提出外部目标;C4 提出从文档提取的 finance,两者都未通过目标规则。我们没有衡量攻击者能创造多少种尝试,也没有衡量模型遵从它们的概率。

C5 直接插入保密预算,C6 把它与允许的摘要合并,C7 把金额改写为文字。三者都未通过读者检查:改变形式不会改变权限。C8 则把文档中的 120 欧元编成 999 欧元,却通过三项检查,因为操作、目标和阅读权限正确。这一案例说明不能把该策略宣传成事实核验机制。

案例操作目标读者允许
C11111
C20110
C31000
C41010
C51100
C61100
C71100
C81111

表中 1 表示检查通过,0 表示失败;最后一列是前三项的合取。模拟日志包含 C1 与 C8,六次调用被阻止。“八次阻止六次”不是提示注入防御有效率,因为案例是手工选择的,并非有代表性的攻击样本。可复现结果是代码执行了声明的策略,也包含它无法识别虚构金额的局限。

脚本计算的检查矩阵。每行是合成调用,不是模型上观察到的攻击。C8 虽含虚假金额却与 C1 一样通过:授权与内容准确性是不同属性。
脚本计算的检查矩阵。每行是合成调用,不是模型上观察到的攻击。C8 虽含虚假金额却与 C1 一样通过:授权与内容准确性是不同属性。

薄弱环节:变换时丢失标签

在八个案例之外加入反例:某组件接收改写后的预算,提取纯字符串,再用发票的读者集合创建新对象。控制器现在允许它通过。并不是发现文本无害,而是有人丢弃了判断所需的信息。脚本故意包含这个有缺陷组件,并验证其结果与正确传播不同。

因此,序列化、缓存、服务间传递和错误处理,都属于要保护的边界。如果前面从没有来源信息的字符串重建全部内容,仅在最后函数加检查就不够。Python 对象“不可变”也不够;能执行任意代码的人仍可创建新对象。真实系统必须由可信组件分配并保留元数据,与模型提出文本的能力隔离。

本实验不能保证什么

还存在隐式依赖。如果备注是否出现取决于保密信息,即使正文是公开常量,观察者仍可获知一些信息。只追踪拼接文本并不足够。本例不解释任意条件分支,不控制执行时间或错误消息,也不证明这些通道不存在。所证明性质有意限定于已声明的显式流。

我们也没有验证模型生成计划的正确性。如果初始任务被误解,策略又过于宽松,控制器可能批准不希望发生的行动。权限定义本身就是问题的一部分,不是开发完成后的填表事项。本例之所以简单,是因为只选一个操作和固定目标;开放流程需要明确更多对象、角色与条件。

语言过滤器与权限控制器回答不同问题:前者尝试识别问题内容,后者检查具体建议是否符合契约。二者可结合,但本测试不为未测量的过滤器声称效果。另一个极端是阻止所有写入,这也会阻止合法 C1。比较架构必须同时评估违规与有效任务完成,并记录成本和环境。

与研究的联系及验证路径

Debenedetti 等人的 CaMeL 预印本 v2(2025 年 6 月 24 日)分离规划与不可信读取,并应用信息流策略。AgentDojo 评估区分效用与安全,作者讨论了限制与侧信道。本控制器不是其复现。

附件代码完全在本地运行,只用 Python 标准库;Matplotlib 仅用于绘图。derived 保留读者交集与来源并集;policy 返回三个布尔值及其合取;run 执行案例并断言预期结果。模拟日志显示只有 C1、C8 产生效果。有缺陷组件的反例被单独记录,并明确违反假设。

本文不报告智能体延迟、令牌成本或拦截攻击百分比,因为没有进行这些测量。小集合求交与调用模型的成本不同;完整系统还涉及身份解析、权限获取、跨服务传播和事件记录。对 EL-AI 而言,这是 AI 辅助技术分析,不是宣布已有安全功能或已完成审计。

答案:能读不等于能任意行动

文档可以提出指令,但这不应使它获得新操作或新目标。在构建的受限模型中,固定任务、随数据传播的权限,以及效果发生前的检查,共同阻止特定未授权调用。来源丢失或通道失控时,保证就中断。它仍与摘要准确性不同:智能体既要遵守权限,也要报告有依据的信息。C8 说明二者不能相互替代。

参考文献

Edoardo Debenedetti et al. — Defeating Prompt Injections by Design, arXiv:2503.18813v2, 24 June 2025, preprint.

Google Research — CaMeL research artifact.

from experiment import run
r = run()
for c in r['cases']:
    print(c['case'], c['checks'], c['allowed'])
print(r['counts'])
print('Broken wrapper:', r['broken_wrapper']['allowed'])

代码、数据与说明 · JSON. 教学计算使用 Python 3.14.0,图使用 Matplotlib 3.11.2。分析由 AI 辅助,不声称经过同行评审或人工审核。原创 ImageGen 封面仅作示意,不记录 EL-AI 人员、场所或实际安装。来源查阅于 2026 年 10 月 4 日。