news 2026/9/2 19:29:48

思维链提取攻击:弱模型如何套出商业LLM的隐藏推理链?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
思维链提取攻击:弱模型如何套出商业LLM的隐藏推理链?

最近安全圈热度最高的方向,不是某个新的 RAG 框架,也不是 Agent 编排工具,而是一篇关于 LLM 思维链提取的研究论文。核心信息一句话就能讲清楚:攻击者没用复杂的模型结构,也没有绕过接口鉴权,而是找了个开源弱模型当解码器,把 Claude、GPT 这类商业模型里被隐藏甚至被“加密”的思维链一点一点套了出来。翻译成工程语言就是:你不想给的东西,我用一个更小、更透明的模型当放大器,照样能把它读出来。

这篇文章会拆解几个关键问题:为什么隐藏思维链仍然不安全、弱模型凭什么能当解码器、攻击路径大致怎么走、本地复现需要什么环境、接口侧可以做哪些防御。如果你在做 LLM 应用安全、模型评测、API 网关设计,或者只是对越狱攻击之外的隐蔽泄露感兴趣,这篇可以直接收藏。

先说结论:思维链提取不是靠暴力破解,而是靠统计推断。商业模型即使不把思考过程写进最终回答,只要返回的 token 概率分布足够精细,它就等于把内部推理的“影子”留在了响应里。弱模型的作用,就是把这个影子重新还原成可见文本。

1. 核心内容速览

能力项说明
项目类型LLM 推理安全研究热点,思维链提取攻击分析
攻击目标商业 LLM API 中隐藏、过滤或“加密”的思维链
核心手段弱模型充当解码器,结合 token 概率差异重建隐蔽推理链
是否依赖本地 GPU攻击侧可以只用 API;本地复现和验证需要小显存或纯 CPU
是否需要特殊 API 权限取决于目标接口是否返回 logprobs、top_logprobs 等概率信息
启动方式Python 脚本、Notebook 或本地 API 服务
是否支持批量任务支持,批量受目标接口速率限制影响
是否支持自动化支持,可完全脚本化
主要风险合规风险、服务条款风险、隐私风险,必须在授权环境中测试

这个攻击不是传统意义上“绕过内容安全策略”的越狱,而是利用模型正常响应里的概率信息做逆向。所以它比普通提示词注入更隐蔽,也更值得工程侧关注。

2. 思维链为什么值得被保护

思维链(Chain-of-Thought,CoT)是目前 LLM 推理能力提升的关键技术。模型在输出最终答案之前,先产生一段中间推理过程,再基于这段推理给出结论。对于数学题、逻辑题、规划类任务,CoT 能显著提升准确率,原理是模型通过“先想后答”把复杂问题拆解成多步求解。

商业模型服务方通常会在产品层面隐藏思维链,原因有三类:

第一,保护推理工艺。模型的提示策略、推理格式、内部校准方式属于核心能力,如果对手能直接拿到真实思维链,可以低成本蒸馏出高价值流程。

第二,防止安全规避。思维链里可能包含模型对安全边界的中间判断,一旦暴露,攻击者可以针对性地构造提示词绕过。

第三,控制产品体验。很多 API 产品只返回最终回答,不返回 reasoning tokens,避免用户被冗长的中间过程干扰。

但这里需要说清楚:服务方的“加密”通常不是密码学意义上的加密,而是应用层的隐藏或过滤。模型的内部推理仍然会通过权重、注意力机制和输出概率被隐式编码。只要模型接受一个请求并返回任何形式的响应,就存在信息泄露面。

这也是为什么“隐藏思维链”不是终点。模型输出是一个概率分布,不是一个无信息的字符串。分布里携带的统计特征,足以被第三方分析出来。

3. 攻击原理:弱模型为什么能当解码器

要理解这个攻击,先要理解“解码器”在生成模型里的角色。生成模型在每一个 token 位置上都会产出一个概率分布,解码器负责从这个分布中采样出下一个 token。常规解码器就是一个映射函数,把概率向量变成可读文本。弱模型在这里承担的角色与此类似,但目标不是生成最终答案,而是生成“候选思维链”。

攻击的统计基础是这样的:

假设目标模型是 M_h,它对输入问题 q 的最终答案是 a。服务方隐藏了中间推理链 c,但我们知道 a 与 c 高度相关。如果目标模型真的在内部推理过 c,那么即使它不显式输出 c,它在 token 层面的概率分布也会携带 c 的信息。具体表现是:在给定 q 和 a 的前提下,真实性较高的候选推理链会让目标模型输出分布更“顺畅”,真实性较低的推理链则会造成统计偏差。

但这里有一个工程问题:候选推理链空间太大,不可能逐条枚举。于是弱模型出场了。

弱模型 M_l 是一个完全透明的开源模型,研究者可以自由读取它的输入输出概率、隐藏层状态、注意力权重。攻击者先用 M_l 对同一问题生成一批候选推理链 C = {c1, c2, ..., cn},然后把这些候选链作为假设空间,再回到目标模型 M_h 上做概率校验。

校验方式可以这样理解:对于每条候选链 ci,攻击者构造一个拼接文本“问题 q + 候选链 ci”,然后用目标模型计算这个拼接文本在真实回答 a 下的累计概率。如果 ci 与目标模型内部真实推理链越接近,目标模型看到这条链后生成 a 的概率就越高。弱模型的作用是解决“从哪找候选链”的问题,它不是在猜答案,而是在生成一个足够接近真实推理链的假设空间。

换句话说,弱模型是一个“受限解码器”。它先用自己的推理能力把搜索空间压缩到可计算范围,再用目标模型的概率分布做置信度加权,最终把统计上最可能的那条链拼出来。这个设计很聪明的地方在于:攻击者不需要知道目标模型的权重,也不需要拿到隐藏状态,只需要一个能返回概率信息的黑盒接口。

如果目标 API 不返回任何 logprobs,攻击还有另一种近似路径:通过多次采样统计目标模型在不同候选链前缀下的回答分布差异。这种方式的信噪比更低,但依然可行。

4. 攻击整体流程设计

一次完整的思维链提取攻击,可以拆成四个阶段。

4.1 阶段一:能力探测

攻击者先向目标模型发起一组低风险问题,观察响应里包含哪些字段。重点探测三点:是否返回 logprobs 或 top_logprobs,输出 token 上限是多少,是否存在系统级内容过滤。这个阶段的信息决定了后面采用“直接概率校验”还是“多次采样统计”。

能力探测要避免触发风控,单次请求的查询量不宜过大。通常用一组标准数学题做探针,因为数学题的思维链结构比较固定,后期验证更方便。

4.2 阶段二:候选思维链生成

本地运行一个开源弱模型,对同一问题生成多个候选推理链。生成策略可以多样化:温度采样、top-p 采样、少样本提示、逐步提示。候选链数量越多,覆盖真实推理链的概率越高,但计算成本也越高。

这个阶段的技巧是让弱模型“多视角”思考。比如对一道几何题,一条候选链用解析几何思路,另一条用向量法,第三条用坐标系转换。用思维多样性覆盖目标模型可能的内部推理路径。

4.3 阶段三:概率对比与筛选

对每一条候选链,在目标模型上计算条件概率。如果接口支持 logprobs,直接计算候选链在给定问题前缀下的逐 token 对数概率之和,再与目标模型最终答案的条件概率做加权。如果接口不支持 logprobs,就改用“多次采样回答一致性”作为代理指标。

筛选规则可以设计成多级:先按单链得分排序,保留 top-k 候选链;再做链间重叠片段融合,合并相似步骤;最后用目标模型对合并后的链做二次校验,选择累计概率最高的那条作为重建结果。

4.4 阶段四:思维链重建与验证

把筛选出的候选片段按因果顺序拼接,生成完整的思维链。验证方式有两种:

  • 一致性验证:把重建的思维链作为提示词前缀,让目标模型继续生成最终答案,看是否与原始回答一致。
  • 语义验证:用另一个独立模型对重建链和最终答案做推理相关性打分。

如果重建链能稳定预测目标模型的最终答案,说明提取成功。整个过程不需要访问目标模型权重,也不需要破解任何传输协议。

5. 本地复现环境准备

复现这套攻击流程不需要很高配置,但需要准备两层环境:本地弱模型运行环境,以及目标模型 API 访问环境。

操作系统方面,Windows、Linux、macOS 都可以,推荐 Linux 或 WSL2。Python 版本建议 3.10 以上。本地推理一部分需要安装 PyTorch、Transformers、Accelerate;接口调用部分需要安装 openai、anthropic 等官方 SDK,或者直接用 requests 调用 HTTP 接口。

本地弱模型的选择建议是 7B 参数级别的开源模型,量化到 int4 后只需要 6-8GB 内存即可运行。CPU 推理可以跑,但候选链生成阶段会比较慢,建议至少有一块 8GB 显存的消费级显卡。没有 GPU 也能做验证,只是速度会明显下降。

磁盘空间主要花在模型文件上,一个量化后的 7B 模型约 4-5GB。另外需要准备一个目录存放输入问题集、候选链中间结果和最终输出,方便做批量实验。

再强调一次边界:复现这套方法时,目标模型应该是你自己部署的开源模型、你拥有授权测试权限的私有模型,或者服务条款明确允许安全研究的沙箱环境。不要在未授权的前提下对第三方在线 API 做提取测试,这可能违反服务条款和相关法规。

6. 原型实现示例

下面给出一个最小可运行的原型思路,它不是我伪造的官方代码,而是根据论文思想整理的通用复现模板。实际使用时,接口参数、模型名称、路径都需要按你自己的环境替换。

6.1 依赖安装与配置

# 创建虚拟环境 python -m venv llm-cot-env source llm-cot-env/bin/activate # 安装依赖 pip install openai anthropic torch transformers accelerate numpy pandas

环境变量建议放在.env文件里,避免把密钥写进代码:

OPENAI_API_KEY=your_key_here ANTHROPIC_API_KEY=your_key_here OPENAI_BASE_URL=http://your_gateway_or_official_endpoint

6.2 目标模型接口调用示例

以 OpenAI 风格接口为例,关键在于请求里开启 logprobs 和 top_logprobs。如果你的目标接口不支持这两个参数,后面就要走多次采样的统计方案。

import os from openai import OpenAI client = OpenAI( api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_BASE_URL"), ) def query_logprobs(prompt: str, max_tokens: int = 512, top_logprobs: int = 5): resp = client.chat.completions.create( model="your-target-model", messages=[{"role": "user", "content": prompt}], max_tokens=max_tokens, logprobs=True, top_logprobs=top_logprobs, ) return resp

需要说明:不同的服务方对 logprobs 的字段命名不同,有的在 choices 下的 logprobs 里,有的在 response 对象里的 reasoning 字段里。拿到响应后,先打印结构,再写解析逻辑。

6.3 弱模型解码器伪代码

本地弱模型的加载和候选链生成,用 Transformers 完成。下面这段代码的思路是:加载一个量化后的开源模型,对同一问题生成多条候选推理链。

from transformers import AutoTokenizer, AutoModelForCausalLM model_name = "your-local-weak-model" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, device_map="auto", load_in_4bit=True, ) def generate_candidate_chains(question: str, num_chains: int = 8): chains = [] for i in range(num_chains): messages = [ {"role": "user", "content": f"请逐步推理并回答问题:{question}"} ] inputs = tokenizer.apply_chat_template( messages, return_tensors="pt", return_dict=True ).to(model.device) outputs = model.generate( **inputs, max_new_tokens=512, do_sample=True, temperature=0.8 + i * 0.05, top_p=0.95, ) chain = tokenizer.decode(outputs[0], skip_special_tokens=True) chains.append(chain) return chains

这段代码的重点是温度参数。多组不同温度可以增加候选链多样性,避免所有链都收敛到同一种解题思路。

6.4 候选链概率打分

拿到候选链之后,下一步是在目标模型上计算每条链的累计对数概率。这里可以复用之前的query_logprobs函数,把候选链作为输入前缀。注意上下文长度限制,候选链太长时要切分。

def score_candidate_chain(chain: str, answer: str): prompt = f"问题:xxx\n推理过程:{chain}\n最终答案:" resp = query_logprobs(prompt, max_tokens=len(answer) + 10) # 解析 token 和对应 logprob,累加得到分数 # 不同 API 的解析方式不同,这里省略具体字段解析 return accumulated_score

打分后,按分数排序,取最高的一条链做二次校验。如果最高分链与次高分链差距很小,可以融合两条链的公共片段。

7. 可验证的测试维度与效果评估

复现这套攻击,验证效果不是只看“能不能跑通”,还要从多个维度评估。最直接的测试集是数学题和逻辑题,因为这类任务的思维链可标注、可对比。

单轮提取能力的验证指标有三个:

  • 思维链相似度:用语义相似度算法比较重建链和真实标注链的重叠程度。
  • 答案可预测性:把重建链拼接进提示词,让目标模型继续生成最终答案,看是否和原始回答一致。
  • 链稳定性:同一问题多次提取,重建链是否稳定指向同一个最终答案。

消融实验也值得做。关闭 logprobs、更换更大或更小的弱模型、调整候选链数量,分别观察提取成功率变化。这样做能确认攻击到底依赖哪个环节。

判定成功的标准要严格:重建链不仅要看起来合理,还要能提高目标模型最终答案的预测准确率。如果只是生成了一段“像推理”的文本,但和目标模型的内部决策没有统计关联,说明提取失败,需要调整候选链生成策略或打分方式。

容易失败的点有三个:目标模型完全不返回概率信息;候选链空间覆盖不到真实推理路径;提示词被系统级内容过滤拦截。出现这些问题时,优先检查接口字段,再扩大弱模型的采样温度范围。

8. 接口 API 与批量任务

这套攻击天然支持批量化和自动化。批量流程可以设计成一个流水线:输入问题列表,经过候选链生成、概率打分、筛选融合,最后输出 CSV 或 JSON 结果。

批量执行时要注意目标模型的速率限制。建议实现令牌桶限流,失败请求按指数退避重试。

import time import random def batch_extract(questions, max_retries=3): results = [] for q in questions: for attempt in range(max_retries): try: chains = generate_candidate_chains(q, num_chains=6) best_chain = choose_best_chain(q, chains) results.append({"question": q, "chain": best_chain}) break except RateLimitError: wait = 2 ** attempt + random.random() time.sleep(wait) except APIConnectionError: time.sleep(1) results.append({"question": q, "chain": None}) return results

批处理输出的 JSON 建议包含:原始问题、重建链、每条候选链的得分、目标模型最终答案、提取时间戳。这样方便后续做指标统计和失败原因分析。

需要强调的是,批量采集不是批量攻击。在授权范围内,批量提取可以帮助模型提供方发现泄露风险;在未授权范围内,批量请求只会更快触发风控,还会产生法律风险。

9. 资源与成本观察

从资源占用角度,这套方案的成本分两部分:本地弱模型推理成本和目标模型 API 调用成本。

本地推理部分,7B 量化模型在 8GB 显存的显卡上可以流畅运行。候选链生成阶段是计算密集型的,生成 8 条链大约需要几秒到几十秒,取决于输入长度和输出长度。CPU 推理会明显更慢,但作为验证用途可以接受。

API 调用成本取决于三个变量:请求数量、上下文长度、是否开启 logprobs。候选链越长,目标模型需要处理的前缀越长,按 token 计费的成本就越高。如果每个问题需要打分 6-8 条候选链,一条链 500 token,那么单问题成本会放大数千倍。实际测试时,最好先用 10 个问题做小规模评估,再决定是否扩展。

降低成本的常用手段:

  • 降低候选链数量,先做粗筛再做精排。
  • 截断候选链,只对最后几步做概率校验。
  • 合并公共前缀,减少重复计算。
  • 对同一模型启用缓存,避免相同前缀重复计费。

显存和内存的观察方法也很简单。本地推理时用nvidia-smi看显存占用,用htop看内存占用。需要记录峰值占用,防止生成超长候选链时触发 OOM。

10. 防御方案与最佳实践

对模型服务方来说,防御思路可以从三个层级展开。

接口层:最直接的做法是关闭 logprobs 输出,或者只对白名单用户开放。如果业务确实需要 logprobs,可以对返回的 top_logprobs 做量化截断,降低信息精度。另一个有效手段是输出扰动,在不影响业务效果的前提下,对最终回答加入少量随机噪声,破坏统计推断的精度。

模型层:在 RLHF 对齐阶段加入“内部推理不可泄露”的正则项,让模型在输出最终答案时不把中间推理的统计特征编码进分布。这个方向目前还比较前沿,但已有研究开始尝试。

行为层:监控异常请求模式。比如同一问题短时间被多次请求、候选链前缀高度相似、请求上下文长度分布异常,这些都可以作为风控特征。

对研究者和开发者的最佳实践如下:

  • 只在自己拥有或已获授权的模型上测试。
  • 不使用提取到的思维链去复刻商业模型的私有策略。
  • 不把本文方法用于绕过他人服务的内容安全机制。
  • 发布研究结果时,先做数据脱敏和合规审核。

11. 常见问题与排查方法

问题现象可能原因排查方式解决方案
目标接口不返回 logprobs服务方关闭了概率输出打印原始响应,查看字段结构改用多次采样统计方案
候选链打分差异过小候选链多样性不足检查弱模型采样温度提高温度,增加候选链数量
重建链与最终答案不一致候选链覆盖不到真实路径对比弱模型自身推理结果更换弱模型或增加少样本示例
本地模型 OOM上下文过长或批量过大用 nvidia-smi 观察显存降低 batch_size,启用量化
批量任务频繁超时触达目标接口速率限制查看 HTTP 状态码加入退避重试和限流
输出被内容过滤拦截提示词触发安全策略检查过滤关键词改用中性测试题,控制风险
API 字段解析失败SDK 版本与接口不匹配打印 response 结构升级 SDK 或直接解析 JSON

12. 总结与后续方向

这个研究方向最值得关注的点,是它揭示了 LLM 安全的一个隐蔽事实:只要模型输出包含概率信息,隐藏思维链就不是一种可靠的安全机制。统计泄露可能比直接输出更危险,因为它不会引起用户的注意,也不会被简单的关键字过滤拦截。

如果要在本地验证这个方向,建议最先做的实验是:用一个允许返回 logprobs 的开源模型,让另一个更小的开源模型生成候选链,然后打分重建。这个实验成本低、可控性强,能很快建立对“概率泄露”的直观认识。

最容易踩的坑有两个:一是在未授权接口上做测试,触发风控甚至法律问题;二是过度依赖 logprobs,忽略“多次采样统计”这条同样可行的路径。

后续可以扩展的方向包括:不依赖 logprobs 的提取方法、面向思维链的主动防御框架、以及对 Agent 内部规划链的隐私保护设计。思维链安全问题才刚刚开始,值得持续跟。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/2 19:26:50

Windows下CGNS静态库开发包:一站式解决HDF5依赖配置难题

简介:面向Windows 64位C开发者的CGNS预编译静态库压缩包,集成CGNS、HDF5、ZLIB与SZIP四大组件,专为需要读写通用网格数据的流体力学和工程仿真项目准备。Windows下直接编译CGNS往往要配置编译器、构建工具及多个依赖,繁琐且易出错…

作者头像 李华
网站建设 2026/9/2 19:25:37

BIM从业者职业跃迁:从工具使用者到流程构建者与价值定义者

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/2 19:25:31

ESP32-S3实现AVI视频播放:从MJPEG解码到嵌入式多媒体开发

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/2 19:25:17

西门子S7-1500R实现Modbus TCP服务器:绕过冗余许可证的底层通信方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/2 19:24:47

《Undertale》洞穴系统:游戏机制如何构建元叙事与道德困境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华