从一个“多轮对话拼接”说起
先明确一个前提:对话模板拼接漏洞是近两年论文里反复出现的推理服务侧注入面。它的成因不在于模型本身被越狱,而在于服务端组装 messages 的方式——把历史、重试、重试失败重试、摘要、工具结果,一层层 plaintext 拼接进同一条上下文时,信任边界没有画清楚。
我在之前几篇文章讨论过流式工具调用、Agent沙箱和上下文压缩。对话模板拼接漏洞与这几件事有重叠,但它更底层:它恰好位于 web 框架和推理引擎之间,很多团队认为它不重要,两个都没碰过该职责边界。
漏洞是怎么被“拼”出来的
三个必需的要素。第一,服务端负责拼 messages,而不是每个 turn 都拿客户端传进来的完整 messages 原样转发。现实中几乎一半的对话产品属于前一种——为了做滑动窗口、摘要压缩、失败掉早于 N 轮的东西,不得不自己管理 history。
第二,拼接中混用不同角色之间的边界标记。典型的错误写法:
// 错误示例 let prompt = "You are a helpful assistant.\n"; for (
类似遗漏边界、忘记转义历史内容,就容易被历史内容反噬。历史上容易被用户注入的一轮 assistant-turn,下一次请求就变成模板里受信任的片段。
预填充这一类特殊拼接
另一条常见路径是故意把“assistant”预填充进最后一轮。Security 论文里提到,Gemini、Claude、Kimi K2 等模型在合法场景(例如强制 JSON 开头、控制思考语气)普遍使用该能力。各家推理平台对预填充的处理完全不同:Claude 走 assistant-turn 预填充,而 GPT-5.6 Luna 的 API 会拒绝超过约 50 token 的逐字子串拼接——双方在 security 层面的处理差异,与模型能力如 Haiku 4.5、Opus 4.8、Gemini Robotics ER-1.6 往往关系不大;分水岭正在于这一层。
权限与会话串线的交汇
AGENT-2026-001 到 010 那类清单,在通用报告里把模板注入列为高危条目。对话模板拼接一旦失败,后果最小是一轮 shell 历史泄露,严重则是对话窗口越权。拼接入口必须拿到会话 id、操作者 id 这类信息,但它与实际 access token 一旦相连,任何对模板注入的攻击就不再只是“让模型多说两句”,而是构造一条横向挪移。
工程上的三个取舍
取舍一:拼接交给谁。 客户端传 messages、服务端原样转发,拼接错误的风险低、可以维护模板;但客户端能改写 assistant 内容。反过来,客户端只是纯数据,拼接和服务侧负责,可以让长度治理容易做、但入口不能容忍一个没有 session 更新的 turn。我倾向后者——但要额外加固 role 标记和各角色的边界归属。
取舍二:每轮重建还是增量传递。 全量重建相当于每轮以拼接模板为基准重新组装 messages,可审计、能重放,开销主要在 token 和拼装;增量传递即 KV/request 参数做收敛,省前缀、也省拼接代码量,但一旦上一轮有一处异常渲染(或者 tool trace 发生),问题会静默传到后面每一轮。我的做法是全量 message 重建,引擎侧 warm 前缀留作可回退的冷启动入口,别把一份推理历史里可复用的参数也当作缓存的一部分透明化。
取舍三:工具结果、thinking 块、摘要能不能拆、放在哪。 这三者最容易打破角色消息结构。团队常见的处理有两个极端——一把塞进 data 或 system 里省事;或者把摘要放到独立 context 但显式区分 assistant-vs-runtime。前者在日志里混为一体,后者的模型组合反而更稳。我看对输入安全的验证优先使用后者做灰度。
推理轨迹可能带有隐藏推理内容,摘要不忠实会让一层摘要与一层 history 混在一起后出现拼接段越权。
容易被忽视的点
拼接之后还要看产出,输入 tokenizer 逐字校验和回复、输出前缀校验同样要建在 content 上,而不是只校验 content-disposition。论文里还提到 Anthropic 自己的摘摘率:Claude 泄漏历史的 ~1/5,历史被有选择地暴露、多进到模板里——到那时,模板拼接漏洞测试真正命中检测的概率已经取决于模型厂商的自我保护强度和平台版本号。
通用建议如果硬要理出可操作短名单:把 messages 存储去敏和 拼接边界上同时做 。
大多数拼接漏洞是版本迭代出的脚手架没有演化成约束流程。漏洞能长期存在,往往不是新增团队借 OSS 快速叠出来、调试完就上。定位 root cause 时定期看下发出去的 prompt byte 串和某一条 messages 装配代码的覆盖检测,往往能快速看清是不是手管理不清边界——最后一种做法频繁出现:正常拼接被切成“短字符串”再拼回去,而在这段代码停留的那一公里内仍没有人会记得。
转载请注明出处: 皮哈皮阿
本文的链接地址: https://blog.phpat.com/ai-frontier/663.html
微信或手机浏览器扫一扫,随时随地随心阅读与分享
-
多智能体不是银弹:编排、通信与成本取舍
我们试过让五个 Agent 开会,结果它们花了二十分钟争论谁该先说话,最后交上来的方案还不如一个单 Agent 加两个工具。多智能体不是不能做,是很多团队做早了。
2026/10/18
-
AI 浏览器用了一个月,我还是回到了地址栏
我试着把 AI 浏览器当主力用了一个月。模型不差,功能也不少,但最后让我放弃的是一件很朴素的事:地址栏比对话框更快、更确定。AI 浏览器到底卡在哪?
2026/10/20
-
个人 Agent 与常驻智能体:长期记忆、主动性与隐私边界
我让一个常驻 Agent 帮我盯快递。包裹签收三天后,它还在提醒我“预计今天送达”。长期记忆、主动性和隐私边界,决定了个人 Agent 是助手还是负担。
2026/10/20
-
世界模型被吹了两年,真正难的不是生成视频
看世界模型的演示视频,很容易产生“就差一点”的错觉。可一旦你试图在里面做一个动作,问题就全暴露了。生成一段像世界的视频,和拥有一个能交互的世界,是两件难度完全不同的事。
2026/10/20
-
思维链压缩到 20%,还能保住数学推理的准确率吗
把推理模型的思维链砍到原来的 20%,多数压缩方法会崩,但 Extra-CoT 在 MATH-500 上还保住了近半准确率。拆一下它怎么用公式原子性和分层奖励,以及这些结果在别的任务上不一定成立。
2026/10/22
-
前缀缓存命中率:字节对齐与工程取舍
从 QwenPaw 的命中率议题、Reasonix 的前缀分区,到 vLLM 的缓存感知路由,拆开前缀缓存失效的真实触发器,并讨论冻结前缀之后要执行换来的工程代价。
2026/10/24
京公网安备11011402053654 
@muffin:链接已更新,分类图像功能...
AI网址导航模版图标库更换指南
作者大大,图标库邀请链接失效了,麻烦更新...
AI网址导航模版图标库更换指南
太好看了,快点更新!
友情链接
@戴墨镜的刘备:哈喽,路过点赞。
vue.js组件之手写签名板vue-signature-simple
太好看了,快点更新!太棒了!👍真的很赞!
vue.js组件之手写签名板vue-signature-simple
你写得非常清晰明了,让我很容易理解你的观...
Emlog插件RSS订阅器发布