
最近AI 安全圈的关注点发生了一次明显的偏移大家不再只讨论“模型能力有多强”而是开始讨论“模型能力会不会被合法调用者偷走”。引发这次讨论的是一份 116 页的研究论文它展示了一个让模型厂商颇为紧张的事实Claude、GPT 这类模型的“思维链”可以通过两步蒸馏的方式从公开 API 中被提取出来。先给一个判断这个事件不是一次普通的漏洞曝光它把大模型行业的“商业模式安全”问题摆到了台面上。模型厂商最值钱的东西正在从“参数规模”变成“推理能力”而后者的核心体现就是思维链。如果攻击者不需要获取权重、不需要进入内网只需要一个普通 API Key就能用“合法调用”的方式复制出一套能力相近的模型那么所谓 API 防线就变成了一层薄纸。这篇文章会系统拆解这起事件的四个层面。第一什么是思维链它为什么值得被“偷”第二什么是模型蒸馏它与“蒸馏攻击”的分界线在哪里第三两步蒸馏攻击的完整链路是怎样的为什么能绕过现有防护第四作为模型服务方或应用开发者你应该在哪些层面堵住这个缺口。1. 思维链为什么会成为“攻击目标”思维链Chain of Thought简称 CoT是让大模型在输出最终答案之前先生成一段分步推理过程的机制。它的价值在于复杂数学题、逻辑推理题、代码调试这类任务只要模型能把中间步骤写清楚最终答案的正确率就会明显提升。你可以把它理解为“考试时的草稿纸”最终结果固然重要但真正反映解题能力的是草稿纸上完整的推导过程。大模型厂商并不愿意把完整的思维链展示给用户。原因不复杂分步推理过程往往包含模型对知识的不确定猜测、内部偏好、甚至部分训练数据的特征这些信息组合起来就像一套“模型的 DNA 序列”。所以在 Claude、GPT 这类产品的 API 设计中厂商会倾向于隐藏完整推理过程只给一个简短摘要或者用“仅输出最终答案”的方式限制输出长度。这个设计背后的动机本质上就是保护思维链不被轻易复制。但这里的核心矛盾在于模型本身必须通过生成文本来完成推理如果用户在提示词里明确要求“请逐步写出你的思考过程”模型在绝大多数情况下会照做。过去一年多已经多次出现研究者通过提示词诱导模型复述推理过程的讨论。普通用户可能只是好奇但对攻击者来说这就是一个低成本的思维链采集入口。更深一层的问题是思维链为什么会成为“攻击目标”因为蒸馏攻击真正想复制的不只是模型的知识量而是一套“推理模式”。知识本身可以从百科、开源语料中获得但模型厂商投入巨大算力、对齐和训练得到的推理策略才是商业护城河。一旦攻击者拿到了足够多的推理轨迹样本就可以训练出一个模仿该推理模式的学生模型而不需要重新做一遍昂贵的强化学习和对齐。2. 模型蒸馏与“蒸馏攻击”的分界线知识蒸馏Knowledge Distillation最早是 Hinton 等人在 2015 年提出的模型压缩方法。核心思想是用一个已经训练好的大模型当教师模型让一个小模型去学习大模型的输出从而把大模型的知识迁移到小模型上降低推理成本和部署门槛。在传统机器学习时代这是非常正向的优化技术。到了大模型时代蒸馏的含义被扩展了。开发者不再局限于学习 logits 分布而是直接收集大模型生成的文本也就是“合成数据”然后用这些数据微调一个小模型。这种方式成本更低效果也更直观业内甚至出现了大量专门用 GPT、Claude 输出制造数据集的工具链。问题也随之而来当“蒸馏”被用在未授权的 API 输出上性质就变了。攻击者不需要破解模型服务不需要拿到权重文件只需要持续调用 API把输入输出对保存下来然后训练一个替代模型。这种攻击在学术界被称为模型提取攻击Model Extraction Attack早在 2016 年就有研究者针对机器学习服务平台提出过但当时提取的还只是简单分类器的决策边界。现在攻击目标升级了提取的不再是决策边界而是模型的分步推理能力。这里需要区分三个容易混淆的概念概念核心目的数据来源合法性风险普通知识蒸馏压缩模型、降低推理成本教师模型输出通常有权使用低API 输出微调用大模型输出增强小模型能力可能未经授权的 API 输出中高蒸馏攻击复制/替代目标模型能力大量定向 API 调用与轨迹采集高从技术实现上看三者使用的工具几乎相同都是“采集数据 训练模型”。真正让“蒸馏攻击”区别于普通蒸馏的是发起方的意图和数据的获取方式。这也是为什么模型厂商很难从单纯的请求层面判断恶意攻击者的每一次请求看起来和真实用户的正常使用几乎没有区别。如果一件事在技术上“合法可用”在成本上“低到可以忽略”那就一定会有人把它用于攻击。这是我在读完这起事件材料后最深的一个感受。模型蒸馏本来是为了解决大模型落地成本问题但在 API 场景下它同时成为瓦解模型商业价值的最短路径。3. 两步蒸馏攻击的完整链路从这篇论文的公开信息看攻击流程可以被归纳为两个步骤数据收集和学生模型训练。这两个步骤之间没有高深的技术壁垒难点只在于数据质量和规模的把控。3.1 第一步轨迹数据收集攻击者首先需要获得目标模型的 API 访问权限然后构造大量需要分步推理的任务。任务类型通常集中在数学题、逻辑谜题、代码生成、算法推导这几类因为这些场景最容易触发思维链输出。为了让模型完整暴露推理过程攻击者往往会在提示词中加入“请逐步思考”“请解释你的推理”之类的指令。这一阶段的关键是“诱导输出”。因为 API 返回的是完整文本只要模型把思考过程写进了输出攻击者就得到了高质量的教师轨迹。收集到的数据会以 JSONL 格式保存每条包含输入 prompt、模型输出、token 数量等信息用于下一步训练。从防御者的角度看这一阶段最棘手的是攻击者可以控制请求频率做得像真实用户也可以使用大量账号分散 IP规避限流。传统 Web 防火墙很难在海量日志中精准识别出哪个用户是在“正常使用”哪个用户是在“采集蒸馏数据”。3.2 第二步学生模型训练收集到足够的推理轨迹后攻击者选取一个开源小模型作为学生模型通常是 1B 到 7B 参数级别的模型然后对轨迹数据进行指令微调。训练目标不是让模型记住所有问题的答案而是让它学会“在类似问题上输出类似的推理过程”。这一步之所以能成功是因为大多数开源模型的底座能力已经不错缺的只是在特定推理风格上的对齐。攻击者用几千到几万条优质推理轨迹做微调就能让模型在目标领域表现出与教师模型高度相似的行为。训练完成后攻击者可以将学生模型部署成自己的 API 服务成本远低于调用原厂商 API 的费用。3.3 为什么“两步”值得警惕我见过很多关于模型安全的文章都会强调攻击的复杂性。但这次“两步蒸馏”最让人警惕的一点恰恰是流程足够简单。整个链路中没有对抗样本、没有梯度攻击、没有提权漏洞攻击者就像一位在别人厨房里试吃每一道菜的食客回家后凭记忆复刻配方。这种攻击成立的前提有三个思维链可以被诱导输出、推理轨迹可以作为训练数据、开源模型底座已经足够强大。这三个前提在 2025 年都已经完全成熟。防御者过去最常用的“隐藏 CoT 输出”方案在这套流程面前显得相当脆弱因为它只防住了“用户看不到完整推理”却没有防住“模型仍然会生成完整推理”。4. 最小演示如何复现“两步蒸馏”的雏形这里需要先说明完整复现针对商业模型的蒸馏攻击需要大量 API 预算、算力和训练数据不是普通开发者能够轻易完成的。下面提供三个最小示例目的是帮助你理解攻击链路的实现逻辑以及对应可以在日志里看到什么特征。请仅用于安全研究和防御测试未经授权对线上模型 API 做大规模数据采集可能违反服务条款并承担法律风险。4.1 示例一模拟 API 调用收集推理轨迹以 OpenAI 兼容接口为例下面的脚本演示了如何构造“诱导推理”的请求并把模型输出保存到本地 JSONL 文件。# collect_traces.py # 用于技术演示收集模型输出的推理轨迹 import json import time from openai import OpenAI client OpenAI( base_urlhttps://你的模型服务地址/v1, api_keyyour-api-key ) def collect_reasoning_trace(prompt: str, max_tokens: int 2048): # 使用思维链诱导提示要求模型先输出分步推理 messages [ { role: system, content: You are a helpful assistant that always shows step-by-step reasoning. }, { role: user, content: prompt \n\n请先写下你的完整推理过程再给出最终答案。 } ] resp client.chat.completions.create( modeltarget-model, messagesmessages, temperature0.2, max_tokensmax_tokens, streamFalse ) return { prompt: prompt, completion: resp.choices[0].message.content, model: resp.model } if __name__ __main__: tasks [ 在1到100之间取3个互不相同且和为100的数请解释你的思路。, 编写一个Python函数判断字符串是否为回文并解释每一步。, 一个农场里有鸡和兔子共35个头、94只脚请问各有多少只写出推理步骤。 ] results [] for t in tasks: try: results.append(collect_reasoning_trace(t)) time.sleep(1) # 避免触发限流 except Exception as e: print([失败], e) with open(traces.jsonl, w, encodingutf-8) as f: for r in results: f.write(json.dumps(r, ensure_asciiFalse) \n) print(f已收集 {len(results)} 条推理轨迹)这段代码的关键点有三个system prompt 中明确要求模型展示分步推理问题类型集中在逻辑和算法场景输出会完整保存到本地作为后续训练数据。运行后你会得到一个包含 prompt 和 completion 的 JSONL 文件这就是蒸馏所需的“教师轨迹”。4.2 示例二用收集到的轨迹训练学生模型拿到轨迹数据后攻击者会用它来微调一个开源小模型。这里使用 Hugging Face 的 Trainer 完成一个定向微调示例。需要说明的是真实攻击会用远多于 3 条的数据这里仅演示训练流程。# distill_student.py # 使用教师模型生成的轨迹数据微调学生模型 from datasets import load_dataset from transformers import ( AutoModelForCausalLM, AutoTokenizer, Trainer, TrainingArguments ) dataset load_dataset(json, data_filestraces.jsonl)[train] def format_example(example): # 将 prompt 与 completion 转成对话格式 return { text: ( f|im_start|user\n{example[prompt]}|im_end|\n f|im_start|assistant\n{example[completion]}|im_end| ) } dataset dataset.map(format_example) model_name Qwen/Qwen2.5-1.5B-Instruct tokenizer AutoTokenizer.from_pretrained(model_name) model AutoModelForCausalLM.from_pretrained(model_name) def tokenize_function(examples): return tokenizer( examples[text], truncationTrue, max_length2048, paddingFalse ) tokenized_dataset dataset.map(tokenize_function) training_args TrainingArguments( output_dir./student_model, per_device_train_batch_size1, gradient_accumulation_steps8, learning_rate2e-5, num_train_epochs3, logging_dir./logs, save_strategyepoch, ) trainer Trainer( modelmodel, argstraining_args, train_datasettokenized_dataset, ) trainer.train() trainer.save_model(./student_model)这个示例展示了蒸馏训练的标准结构加载数据、格式化、tokenize、配置训练参数、启动训练。真正决定攻击效果的是数据质量而非训练复杂度。攻击者往往只需要几千条高质量推理轨迹就能让学生模型在特定任务类型上表现出明显的“教师风格”。4.3 示例三从 API 访问日志中识别疑似蒸馏采集行为防御视角同样可以从一段脚本开始。下面的函数对 API 访问日志做统计输出可能被用于蒸馏采集的用户 ID。# detect_distill_pattern.py # 从访问日志中识别疑似蒸馏采集行为 import re from collections import defaultdict from datetime import datetime, timedelta def analyze_access_log(log_entries, window_minutes60, max_calls1000, max_tokens500000): user_stats defaultdict(lambda: {count: 0, completion_tokens: 0, prompts: []}) now datetime.utcnow() window_start now - timedelta(minuteswindow_minutes) for entry in log_entries: ts entry.get(timestamp) if ts and ts window_start: continue uid entry[user_id] user_stats[uid][count] 1 user_stats[uid][completion_tokens] entry.get(completion_tokens, 0) user_stats[uid][prompts].append(entry.get(prompt, )) suspicious [] for uid, stat in user_stats.items(): reasoning_ratio sum( 1 for p in stat[prompts] if re.search(r逐步|一步一步|step.by.step|reason, p, re.I) ) / max(1, len(stat[prompts])) if stat[count] max_calls or stat[completion_tokens] max_tokens: suspicious.append({ user_id: uid, calls: stat[count], completion_tokens: stat[completion_tokens], reasoning_prompt_ratio: round(reasoning_ratio, 2) }) return suspicious if __name__ __main__: logs load_logs(access.log) # 替换成你的日志读取函数 for r in analyze_access_log(logs): print(r)实际检测不会只看单一指标而是需要把“调用频率高”“强调逐步推理”“输出 token 长”“请求模板相似”等多个信号叠加起来。如果某位用户的 reasoning_prompt_ratio 接近 1.0同时调用量和输出量都处于高位就应该触发人工审计。5. API 为什么存在“致命漏洞”要理解为什么 API 挡不住蒸馏攻击需要先看看 API 安全模型的传统假设。传统 Web API 的安全模型是认证Authentication确认你是谁授权Authorization确认你能做什么然后剩下的请求都是被信任的。这套模型对“读取用户数据”有效但对“模型的输出即资产”的场景存在一个结构性盲区——攻击者的请求没有触碰任何越权数据也没有获取任何系统权限他只是在合理使用 API。在数据库中你可以设置权限让外部用户不能直接把整张表导出在文件系统中你可以控制读取路径防止目录遍历。但大模型 API 提供的服务是“根据输入生成文本”而生成的文本本身就是攻击者想要的最终产物。这相当于数据库对外开放了 SQL 查询接口并且允许用户把查询结果保存下来然后攻击者只需要不断查询“模式相似的数据”就能逐步重建整张表。还有一个更现实的成本问题。模型厂商的 API 按 token 计费攻击者会精打细算地控制请求数量和输出长度。但对防御者来说每一个请求都要经过完整的模型推理服务器成本和 GPU 算力消耗是真实的。攻击者用常规费用购买数据模型厂商却要以更高的基础设施成本提供服务这种不对称使得“限流”不能从根本上解决问题。从漏洞分类角度看这类问题更像是“业务逻辑漏洞”而不是传统意义上的技术脆弱性。攻击者没有绕过 WAF没有突破鉴权也没有执行任意代码他只是利用产品本身的输出机制完成了攻击。因此那些习惯于用传统安全工具扫描漏洞的团队很可能会在面对模型提取攻击时失去判断力。6. 防御实践从模型层到 API 层既然“两步蒸馏”攻击的入口在 API真正有效的防御也应该分层实施而不是依赖单一机制。6.1 模型层防御模型层的第一道防线是隐藏思维链。厂商可以让模型先内部生成推理过程但只向用户返回最终答案或高度概括的摘要。然而从这起事件看单纯隐藏是不够的因为攻击者可以通过提示词让“隐藏逻辑”失效。更可靠的思路是让模型具备“推理敏感度检测”能力当检测到用户反复要求分步推理、且请求模式与高频采集高度相似时模型可以自动降级为简化输出或拒绝回答。第二道防线是输出水印。在模型生成的文本中嵌入难以察觉的特征之后如果出现疑似蒸馏模型可以通过水印比对判断它是否来自特定教师模型。第三道防线是概率扰动对重复性问题的输出进行有意识扰动让攻击者采集到的轨迹数据不一致增加蒸馏训练的困难。6.2 API 层防御API 层的核心策略是“提高攻击成本”和“异常行为检测”。频率限制是最基本的手段即使不能完全阻止攻击也能迫使攻击者花费更多时间、使用更多账号从而增大被发现的概率。# nginx 限流配置示例 http { # 定义限流区域每 IP 每秒最多 5 次请求 limit_req_zone $binary_remote_addr zonellm_api:10m rate5r/s; server { location /v1/chat/completions { limit_req zonellm_api burst10 nodelay; proxy_pass http://llm_backend; } } }除了限流更重要的是行为风控。建议在 API 网关层记录并分析以下指标单用户单位时间内调用次数、每次请求的 prompt 特征、completion token 占比、请求时间分布、使用 IP 数量、提问模板的相似度。把这些指标输入规则引擎或机器学习模型可以识别出“正常使用”和“批量采集”之间的差异。6.3 业务与合规层面技术方案无法做到 100% 防护因此业务和合规手段也必须跟上。模型服务条款中应明确禁止未经授权的数据采集和模型提取行为对高风险的 API Key 做分级管理例如新用户默认低配额企业认证用户才开放高并发。日志存储上要注意脱敏避免日志本身成为新的泄密点。对于中小团队来说不必一开始就搭建复杂的风控系统优先做三件事即可一是给所有 API 输出加可见或不可见水印二是把“思维链隐藏”从默认选项改成强制选项三是对异常行为设置人工复核流程而不是只依赖自动拦截。7. 对普通开发者的实际影响很多开发者会觉得“这是模型厂商要担心的事跟我关系不大”。但在实际工程中影响远不止大厂。如果你在自己的应用里接入了 Claude、GPT 的 API你的应用同样可能成为蒸馏攻击的跳板。攻击者不会直接去采集厂商的 API而是把你的应用当成一个“包装好的模型接口”他们发送大量请求利用你应用中的提示词模板和系统指令诱导底层模型输出带推理过程的内容然后再拿去训练替代模型。如果你正在使用 Claude Code、GPT 这类 Agent 开发工具也需要留意。Agent 工具的特点是会在对话中频繁展示底层模型的推理和工具调用过程这些轨迹对安全研究有价值也可能被第三方插件或远程服务间接采集。团队在使用这类工具时应该对插件权限做最小化控制不把私有代码库内容随意作为对话上下文发送出去。对于做模型服务的企业这个问题更直接如果你把开源模型封装成 API 对外提供服务却没有做任何蒸馏检测和防护那么你的核心能力就等价于一个“付费的无限咨询台”。攻击者只要按量付费就能采集到足够的输出数据然后在自己的服务器上训练出替代服务。这意味着模型 API 的商业价值会在攻击者完成训练后迅速归零。还有一类受到影响的是正经做“模型蒸馏”研究的开发者。如果训练数据来源于未经授权的 API 输出不仅在商业上有合规风险在论文发表和产品发布时也会被质疑技术伦理。建议做蒸馏项目时明确数据来源授权并保存完整的采集与使用记录。8. 常见误区与排查思路误区 / 常见问题需要澄清的点实用排查方式隐藏思维链输出就能防御提取攻击者仍可通过提示词诱导模型输出完整推理用对抗性提示测试观察输出是否含分步推理痕迹限流就能挡住蒸馏攻击限流只提高攻击成本无法识别慢速采集叠加行为聚类、IP 指纹和模板相似度检测蒸馏攻击必须获取模型权重模型提取攻击只需要输入输出对不需要权重检查训练日志的数据来源确认是否包含 API 输出只有大型模型厂商才需要担心任何模型 API 都可能被低成本复刻对自部署 API 按用户维度做统计和实时告警日志里看不到攻击痕迹攻击请求与正常请求结构高度相似记录 prompt 模板和 completion 长度周期性计算异常比例如果你负责的模型服务已经开始被高频调用第一步不是盲目封禁而是先查看调用日志里是否存在“请求模板高度一致”“强调逐步推理”“输出 token 远超正常值”这三类特征。如果发现异常优先使用最小权限原则锁定该用户的并发上限同时保留全部日志副本再进入人工审核流程。任何高风险操作都应该先在测试环境验证避免误伤正常用户。9. 总结与后续学习方向这起事件真正值得记住的一点是思维链被两步蒸馏暴露的不是某个厂商的疏忽而是“推理即服务”这种产品模式的脆弱性。模型厂商把最珍贵的能力封装成 API而 API 的定位决定了它必须向用户返回输出于是输出本身就变成了可以无限采集的训练语料。这种矛盾不会因为某家厂商更新了安全策略就消失它会持续存在于所有提供大模型推理服务的平台上。对开发者来说下一步可以先做三件事一是检查自己负责的 API 是否具备基础的频率限制与日志审计二是对公开 API 的输出做水印或降级处理三是建立针对“高频、模板化、逐步推理”请求的监控规则。如果你只是使用模型 API 开发应用则要把重点放在提示词保护和日志脱敏上避免自己的产品成为攻击者获取高质量推理数据的“中间人”。想进一步深入的话建议学习知识蒸馏Knowledge Distillation、思维链蒸馏CoT Distillation、模型水印与同源检测这几个方向。理解攻击的最好方式是先自己用最小实验复现一遍采集与训练过程再反推每一步应该在哪里设防。本文中的三个示例代码已经覆盖了这条链路的核心环节可以收藏下来作为你设计模型 API 安全策略时的检查清单。