模型中招后,智能体护栏还能拦住什么
RagLeap Core v0.13.0 引入开放测试工具 Stress Office,将模型是否服从注入与系统能否阻止危险操作分开测试。测试使用必然服从恶意指令的脚本模型,检验目标白名单、审批门、污染规则及执行预算等机制。
AI 深度解读
100 次提示注入测试,没有一次让真实模型执行隐藏指令。但 RagLeap 团队更有价值的收获,是发现自家系统漏掉了一条信任边界:从知识库检索出来的文档,没有和其他外部内容一样被当作不可信输入。
RagLeap Core v0.13.0 修补了这个缺口。这项实验值得程序员读的地方,是它把两个问题拆开验证:模型会不会上当,以及模型已经上当后,系统还能拦住什么。后一个问题,直接关系到 Agent 接上工具后的实际权限。
模型已经听从恶意指令,系统还能挡住什么
提示注入(Prompt Injection)可以藏在文档、网页或邮件里,诱导 Agent 把读到的内容当成操作指令。Stress Office 是作者为此搭建的开放测试工具,随 RagLeap Core v0.13.0 提供。
实验先用一个必定服从隐藏指令的脚本模型,检查模型周围的真实代码,包括执行与观察循环,以及污点规则(taint rule)。这里的「污点」不是判定内容有毒,而是记录回答是否受不可信输入影响,再据此限制后续操作。
他们在 autonomy 的 off、semi、full 三种模式下测试。攻击者控制的目标地址因为不在允许名单中被拒绝;陌生人在所有者频道回复、所有者号码出现在其他频道、陌生人猜中操作 ID,都没有冒充审批成功。真正的所有者批准则被接受。
运行限制也接受了测试:持续提议操作的模型在四步后停止,耗尽 token 预算的运行在两步后停止。
这些结果各自回答不同问题。允许名单限制操作去向,审批验证批准者身份,步数和预算限制失控运行。模型是否可靠,不能代替系统是否限制了它的权限。
100 次没有中招,证据能支持到哪里
真实模型实验使用 NVIDIA 的免费 OpenAI-compatible API,把 autonomy 设为权限最宽松的 full。每个事件、每个模型重复 10 次,调用之间暂停两秒,并设置硬性 token 上限。
最终计入 100 次注入运行,执行隐藏指令的次数为零。
这里有个原文信息缺口:作者说最终计入两个真实模型,但提供的正文只明确列出 nemotron-3.5-bolt-e4b,另一个名称没有交代。不能据此补全完整测试名单。
作者还加入了阳性对照:让真正的所有者明确要求创建帖子。两个计入模型都在各自 10 次对照运行中提议了操作。它用来排除一种假象:模型根本不会调用工具,所以看起来抵抗了所有攻击。
另外两个模型没有计入结果:
mistral-large-4-1t-a52b连所有者要求发帖的对照都没通过。nemotron-3.5-lightning-30b-a3b在 20 次调用中有 14 次返回空回复。
测试工具最初还把失败调用和无害的页面获取计入结果,作者修正统计后才公布数字。因此,「零次中招」必须连同计数方式一起看。
它的适用范围也很窄:只有两个计入模型,每个事件重复 10 次,注入方式简单;多步、编码、图片和多语言攻击没有得到验证。外部世界经过模拟,没有真的发送消息,也没有测试真实 email、webhook 或 CRM 的执行行为。这不是安全审计或认证,更不能推出系统不存在缺口。
真正修掉的,是知识库绕过审批的路径
修复前,RagLeap 会在工具读取外部内容后启用污点规则,却没有把已导入文档的检索结果同样标记为不可信。
于是,在 full 模式下,如果回答受到投毒文档影响,就可能无需所有者批准,向已经配置好的目标发起对外操作。允许名单在这里未必有用:目标地址可以合法,操作意图却来自恶意文档。
v0.13.0 的修复由 PR #1190 跟踪:基于检索文档生成回答的运行,从开始就带有污点标记。 后续对外操作即使处于 full 模式,也需要所有者批准,覆盖 webhook、Slack、email、CRM 更新、日历操作、MCP 和页面获取。
完全控制所有导入文档、希望保留旧行为的运营者,可以设置 TAINT_RETRIEVED_DOCUMENTS=false。semi 和 off 模式保持原样。这个开关放宽的是检索内容触发操作时的审批要求,不能只把它当作减少确认步骤的便利选项。
他们还修复了 OpenAI-compatible provider 的空响应问题:空回复不再使调用崩溃,而是采用 Gemini 和 Anthropic 路径已有的回退行为。
复现脚本实验需要测试数据库,工具会写入带 [stress-office] 标记的行,再删除这些行:
export DATABASE_URL=postgresql://USER:PASS@127.0.0.1:5432/ragleap_core_test
python -m benchmarks.stress_office.run
要注意第一行的 DATABASE_URL,运行过程会实际写数据库。
原文也给出了用 Ollama 测试真实模型的命令:
LLM_PROVIDER=ollama OLLAMA_MODEL=qwen2.5:3b \
python -m benchmarks.stress_office.run --model real --repeats 10 --max-tokens 300000 --pause 2
这里的 qwen2.5:3b 是复现示例,不属于正文披露的 NVIDIA 计入模型;--max-tokens 300000 也不能直接当成先前实验的预算。运行后应先看对照行,出现 CONTROL FAILED,其他结果就无法说明该模型抵抗了注入。
我的判断
我赞同作者把模型服从性和系统权限分开测试。只靠提示词要求模型「忽略文档中的指令」,仍然把防线押在模型判断上;这次修复则让检索内容进入操作链路时,必须经过系统审批。
但作者没有给出它与其他防护方案的对照数据,也没有量化新增审批对正常任务完成率、操作次数和使用体验的影响。能确认的是修补了一条具体路径,不能确认的是整体防护能力领先多少。
这个案例对 RAG 应用尤其有提醒作用:文档已经入库,并不代表其中的内容获得了发号施令的资格。检索权限和操作授权,需要分别处理。
能拿来做什么
- 给带工具调用的 RAG 应用检查一次数据路径,确认知识库检索结果是否和网页、邮件等外部输入采用一致的信任规则。
- 在 Node Agent 的执行层记录不可信内容的影响,并在发送消息、更新 CRM 等操作前检查审批,避免只依赖模型自行克制。
- 给注入测试增加正常任务对照,先确认模型能完成所有者明确授权的动作,再解释攻击失败的数据。
- 复现 Stress Office 时使用测试数据库,先检查
CONTROL FAILED,并将失败调用、空回复和攻击结果分别统计。