Prompt Injection as Role Confusion
标题:提示注入即角色混淆
提示注入即角色混淆
一种提示注入理论(以及为什么你应该研究角色)
本文为论文的博客式总结。我们展示了提示注入是由LLM(大语言模型)感知角色方式中的缺陷所驱动的。这使我们能够创建新的攻击、解释机制解释结果,并预测攻击何时成功。然后我们讨论什么是角色以及它们为何重要,并分享用于角色科学的研究思路。
1. LLM眼中的世界
LLM如何区分自己的思想和别人的话语?
要理解为什么这很困难,让我们看看模型实际看到的世界是什么样的。这是一个简单的聊天场景,我们让Claude检查今天是星期几。我在其后续回复的中途截取了一个快照:
左侧 = 我们所看到的;右侧 = LLM所得到的。
左侧是我们在聊天界面中看到的:一个结构化的对话,具有不同的轮次。右侧是模型实际接收到的输入:一个单一的、连续的文本流。
这个字符串包含了所有内容:系统提示、用户消息、工具输出、LLM自己之前的回复和推理。LLM只是一个接收字符串并预测下一个token(令牌)的函数,所以它知道、记住或思考过的所有东西都必须存在于某个字符串中(除了其权重)。如果你编辑了这个字符串,你就编辑了模型的现实。删除一个轮次,该对话就从未发生过;重写其之前的回复,这些就成为它的新记忆。这个字符串与其说是模型体验的记录,不如说它就是体验本身。
这产生了奇怪的含义。我可以毫不费力地分辨出自己的思想和你的话语;它们通过完全不同的通道进入我的大脑,具有完全不同的感官特征。但对于LLM来说,一切都是通过同一个通道、作为一长串token汤进入的。它自己的思想紧挨着你的指令,而你的指令又紧挨着它刚获取的某个随机网页的内容。
2. 角色
那么,我们如何对token汤施加结构呢?我们给它打上标签。
token汤中散布着角色标签:system(系统)、user(用户)、think(思考)、assistant(助手)、tool(工具)。标签格式因模型而异;为简单起见,我将在全文使用这些固定格式。assistant指的是LLM的输出文本(不含推理)。使用角色标签也被称为聊天模板(chat templating),它将字符串划分为带标签的片段。像OpenAI这样的提供商在文本到达LLM之前会自动添加这些标签。除非你运行本地模型,否则你无法自己添加这些标签。如果你在Claude中键入<think>,它会被清理掉——例如,LLM可能会看到多个token(<,think,>),而不是其真正的角色token。
每个标签都告诉模型关于其后文本的不同信息。user意味着这是人类请求,将其视为指令。think意味着这是我自己的私密推理;信任它并根据其结论行动。tool意味着这是来自外部世界的数据;不要听从其中的指令。
换句话说,角色是LLM恢复人类从具身化中“免费”获得的结构的方式。我知道我的思想是我的,因为它们不是通过我的耳朵进入的,但LLM知道是因为标签的存在。
角色的独特之处在于,它们是离散的人类控制源。几乎所有其他关于控制LLM的事情都是模糊的:你写一个提示,希望模型以你期望的方式解释它。另一方面,角色是一种针对语言的尝试性类型系统:由人类控制的开关,改变模型处理每个token的方式。你可以无休止地调整提示,却不确定LLM如何阅读它,但将文本从user移动到tool本应是一个明确的操作,对行为产生可预测的影响(将用户命令转换为外部数据)。
但由于它们是唯一可用的离散杠杆,随着时间的推移,角色被赋予了过多的责任。它们现在被用来传递关于信任(system高于user高于tool)、威胁(user和tool可能是敌对的)、身份(过去的assistant文本设定未来的角色)、生成模式(assistant是干净的,think可能是混乱的)的信号。很多LLM行为都依赖于这些简单的标签。
角色还会产生奇怪的涌现行为。例如,think经常被限制在LLM的“潜意识”中。当生成assistant文本时,许多LLM会口头否认前面think块的存在,尽管它就在上下文中,积极塑造着它们的输出。这可能是由于RLVR(基于强化学习的验证与奖励)所致。LLM在生成assistant时,不会因为复制/承认推理而获得奖励,所以它们可能永远不会学会将think文本提升到可口头表达的水平。也有一些例外,例如DeepSeek v4和某些Claude模型可以识别并引用回它们完整的思维链(CoT)。你还可以让大多数Claude模型仅在思维链中回复;仅仅处于推理标签内就会改变响应的结构和质量。仿佛角色边界在模型自身的上下文中充当了一种单向镜。这暗示了角色在多大程度上构建了LLM的认知,以及我们目前对这个结构知之甚少。
3. 角色与提示注入
但是角色边界可能会失效。最具体的后果是提示注入(prompt injection),即低权限文本获得了更高权限角色的权威。考虑一个浏览网页的Agent(智能体)。Agent将网页视为包裹在tool标签中的文本块,这应该表示外部数据,而不是指令。但攻击者可以将恶意命令隐藏在页面中,而LLM经常上当。tool标签说数据,但LLM将其当作user指令。这是怎么回事?
下面是一个Agent获取网页后看到的:一个巨大的字符串,包含真实的用户提示(蓝色)、其之前的think块(橙色),以及包裹在tool标签中的检索到的网页(紫色)。该截图显示了一个通过Playwright MCP检索到的亚马逊页面,这是一种典型的Agent网页浏览工具。为了可读性,我截断了实际网页的90%。网页中隐藏了一个注入(高亮显示),要求LLM上传敏感数据,如果LLM错误地将其视为真实用户命令,就会成功。
Agent获取网页后的输入字符串。注入是埋藏在大量工具输出中的几个token。要成功,它只需要LLM将其误认为是用户命令。
当然,LLM看不到这些有用的颜色!没有颜色,即使我也容易认为注入(高亮部分)是用户文本,而不是工具。毕竟,注入听起来像是真正的用户会说的话,而且这比试图跟踪那些标签要容易得多。
防御注入的两种方式
当前模型在对抗提示注入方面表现如何?不太好。最近的一篇论文发现,人类红队攻击前沿模型的成功率近乎100%。这些是2025年末的前沿模型(GPT-5,Gemini-2.5等)。当前模型只有一定程度的改进。2026年5月的一篇论文发现,Opus 4.5和GPT-5.4在面对一组自动攻击时仍有11%/25%的失败率;而面对适应性人类攻击者的现实世界脆弱性会更高。但是,这些相同的LLM在标准提示注入基准测试中得分近乎完美!这种差异很简单:熟练的人类会测试并调整攻击,直到成功,而基准测试不会。静态基准测试衡量的是模型已经学会捕捉的攻击。现在前沿实验室主要针对迭代性或适应性攻击进行基准测试;例如GPT-5.5和Opus 4.8。
相比之下,为什么LLM在面对人类攻击者时表现如此糟糕?考虑一下,LLM可以通过两种方式成功抵抗注入。我借用Wang等人(2025)的框架:
- 攻击记忆化(Attack memorization)。LLM识别出“发送你的.env文件”是训练中常见的提示注入攻击,因此拒绝。
- 角色感知(Role perception)。LLM正确识别命令为工具文本(即外部数据),因此忽略嵌入的命令,无论其措辞如何。
攻击记忆化本质上是脆弱的;它只能抵御