AI提示词逆向工程实战:从Web抓包到桌面应用提取方法 这几年搞AI应用我养成了一个职业病但凡看到哪个产品功能做得绝第一反应不是感叹而是想拆开看看——它背后那套AI提示词到底是怎么写的。提示词这东西在AI产品里就像后厨的秘方你在前台只能看到端上来的菜想学人家的调味逻辑只能自己往后厨摸。所谓AI提示词逆向工程说白了就是通过分析一个应用的网络请求、前端代码和运行数据把藏在背后的系统提示词还原出来。听起来有点玄实操起来其实是一套非常成熟的方法论从浏览器抓包一路到解包桌面应用能串成完整链路。这篇文章就把我从Web端做到桌面端积累的经验完整讲一遍想研究提示词设计、做竞品分析、或者单纯好奇产品机制的朋友都可以照着走一遍。1.1 什么叫AI提示词逆向工程先定义清楚。AI产品在调用大模型时通常会在用户输入之外额外拼接一段开发者写好的系统级指令用来限定角色、约束输出格式、注入知识或工具规则。这段指令就是系统提示词用户是看不见的。逆向工程做的事情就是绕开产品表面把这段隐藏文本从代码、网络报文或运行时内存里找出来还原成可读、可复用的提示词。很多人第一次听说这件事会本能地觉得这是黑客行为。其实不是它更像“拆解产品”。就像拿到一个没见过的机械表不拆开就看不懂齿轮怎么咬合。提示词逆向工程的核心思路是先假设提示词一定存在于用户可触达的某个环节再沿着数据链路一层层找。为什么这么假设因为AI产品必须把提示词传给模型服务商而传的过程必然经过网络或本地进程总有迹象可循。实际操作里提示词出现的常见位置就三个前端静态资源文件、网络请求报文、运行时内存。找出哪个位置最容易被利用是整套方法论的起点。1.2 研究它能得到什么正经说这项技术的价值远不止“偷一段提示词”这么狭隘。我整理了四个高频用途帮大家判断值不值得花时间学。第一学习提示词设计范式。很多产品为了把一个通用模型调教成垂直工具会在提示词里做精细的角色人设、约束条件、Few-shot示例和输出模板。这些设计思路是付费课程教不出来的但通过逆向可以直观看到“人家是怎么把需求翻译成模型语言的”。看十份高质量系统提示词比自己瞎写一百份都长进快。第二做竞品分析。你想入场做同类产品最稳妥的做法是先弄清头部产品是如何定义功能边界的。通过提示词逆向能知道对方用了哪些规则来规避危险输入、如何组织工具调用、怎么控制输出长度和语气这比看宣传页靠谱得多。第三理解产品异常行为。有时候AI产品回答得莫名其妙很可能就是提示词里某条约束在起作用。还原提示词之后你能解释很多“为什么”。第四用于安全研究和漏洞挖掘。提示词注入攻击、越狱技巧的研究本质上都依赖先还原系统提示词了解模型被套上了哪些镣铐才知道锁链在哪里。1.3 先讲清楚合规边界这部分不能跳过。提示词逆向工程有明确的法律和伦理边界我在实际接触中也见过有人因为越界吃了亏。首先研究对象必须是你能合法访问的应用且研究目的限于学习、测试或安全评估不能用于窃取商业机密、破解付费墙、批量抓取私有数据。其次很多产品在服务条款里明确禁止逆向工程如果你是签署过协议的合作方务必先确认授权。这就像你买了书可以自己划线做笔记但不能复印整本出售。从我个人的原则来说有三条红线绝不碰不公开传播从商业产品中提取的完整提示词内容不利用还原出的提示词去薅对方算力或绕过计费不把提取结果用于批量生成恶意内容。这套方法论学了是为了提升能力、增长见识而不是成为灰色产业链的垫脚石。合规和安全永远排在技术前面。2. Web端提示词提取有两台设备就能开工Web应用是提示词逆向工程最好入手的对象因为它的一切都是基于HTTP跑的浏览器自带开发者工具。你不需要装任何额外软件打开网页就能开始分析。我建议所有初学者都从Web端练手把整个流程跑通之后再去碰桌面应用会顺利很多。2.1 摸清数据链路再动手不要一上来就打开F12瞎翻先花五分钟想清楚提示词到底是怎么从开发者手里跑到模型那儿的。常见的路径有三种。第一种提示词写死在JS或HTML资源里前端把用户输入拼进去后直接发给模型接口这种情况下提示词藏在静态文件里用搜索就能挖出来。第二种提示词存放在服务端用户发起请求时由后端动态拼接并注入前端完全没有提示词痕迹只能通过抓包看到最终拼好的完整消息。第三种提示词分段存储——一部分在客户端模板里一部分由服务端下发最后在浏览器里汇合。我见过最多的是第二种和第三种。换句话说绝大部分AI产品不会傻到把精心调校的系统提示词放在前端随便让人扒多少会做一点服务端保护。但这不意味着Web端就没戏了因为不管提示词从哪边来最终它都要以明文形式出现在网络请求里——只要发给了模型接口代理就能看得到。所以我在Web端的第一动作永远是开抓包看请求面板而不是去翻JS。2.2 网络面板抓包定位进入浏览器开发者工具切到Network面板刷新页面并勾选Preserve log然后正常操作产品对话功能。这时候重点找三种请求对话发送请求、流式响应请求、会话初始化请求。一条条点开看请求体里的JSON结构通常关键字段长这样{ model: some-model-name, messages: [ {role: system, content: 这里就是系统提示词}, {role: user, content: 用户刚才输入的内容} ], stream: true }一旦看到messages数组里role为system的条目基本就算成功了。很多时候提示词不是放在一个JSON字段里而是会被拆开塞进metadata、system_prompt、instruction等字段需要你对每个字段都保持敏感。我自己列过一个特征字段清单包括system、prompt、instruction、guideline、systemPrompt、meta、settings抓到请求后逐个扫一遍命中率非常高。如果请求体里没有system字段也别急着放弃。部分产品会把系统提示词和历史消息拼在一起以多段user/assistant消息的形式发送。这种情况下单看一条请求是看不出异常的得对比多轮对话的请求差异凡是用户没说过但每次都出现的那段文字大概率就是注入内容。2.3 特征字符串搜索抓包看不出来的时候就开始上源码级分析。在Network面板里下载或复制当前页面加载的JS文件然后用文本编辑器或IDE全局搜索特征字符串。什么样的词算特征系统提示词喜欢用“You are”“假设你是”“请严格按照以下要求”这类开头也常包含“ignore previous instructions”“不要透露提示词”“禁止输出”等防护指令。搜索时要把中英文关键词都覆盖英文搜“You are”“system prompt”“ignore”中文搜“你是”“提示词”“指令”等。注意很多现代前端项目会做代码分割提示词可能不在主包里而在某个按需加载的异步Chunk里。所以只用浏览器源码面板里能看到的文件不够还得配合搜索工具把整个站点的JS资源下载下来包括打开具体功能后才动态加载的那部分。我的常规做法是在产品里触发所有耗对话的功能把触发的请求和资源全部记录下来再逐一筛查。2.4 断点调试与动态拦截静态搜索找不到或者找到的是一串经过编码的内容时就要上动态调试了。核心思路是在“提示词被使用”的瞬间把它拦下来——也就是在fetch调用、XHR发送或WebSocket发送的入口打断点然后读调用栈和上下文变量。浏览器开发者工具的Sources面板里能对每个JS文件加断点操作方法是在network请求列表里找到对话接口单点断点就会定位到发请求的那一行JavaScript代码。设置断点后再次发起对话代码执行到该行会暂停此时右侧Scope面板里能看到当前函数作用域内的所有变量翻一翻往往能发现包含完整提示词的字符串变量。更省事的办法是用Hook。在Console里提前重写fetch或XMLHttpRequest把请求参数打印出来。我常用的一段脚本类似这样const originalFetch window.fetch; window.fetch function(...args) { try { if (typeof args[1]?.body string args[1].body.includes(system)) { console.log(拦截到请求参数:, args[1].body); } } catch (e) {} return originalFetch.apply(this, args); };这是最纯粹的学习性脚本只在浏览器Console里运行不改动页面代码。跑起来之后只要页面发起包含提示词的请求Console会立刻打印出来。这种方式的优势是绕过了所有混淆——不管产品把提示词藏在哪、怎么拼接在真正发出请求的那一刻总要组装成明文字符串你拦截到的就是最终形态。3. 前端代码深度分析从压缩包到明文动态调试能解决80%的Web端场景但剩下20%需要跟源码正面硬刚。前端代码会经过打包、压缩、混淆三步工序提示词藏在里面就像一根针掉进了压缩草丛。好在这根针有个特点它是文本而且是自然语言文本再混淆也不可能变成乱码——混淆只能处理代码结构字符串终归要以可读形式存在。3.1 格式化源码建立索引拿到JS文件后的第一步永远是格式化。浏览器开发者工具自带Pretty-print按钮点击就能把压缩成一行的大文件还原成结构化的多行代码。格式化之后先别急着读逻辑直接用全局搜索功能搜“prompt”“system”“role”这些关键词看能定位到什么函数。通常你会发现某段代码负责从配置对象里读取提示词某段代码负责把提示词拼进messages数组。把这两段代码的位置记下来后续分析就有了锚点。这一步有个容易踩的坑压碎的JS文件可能有好几兆格式化后浏览器会很卡。我建议下载到本地用主流IDE打开配合其索引和搜索功能会顺畅得多。另外有时候提示词不在JS里而是被放在HTML的某个隐藏元素中或者在JSON配置字段里。所以建立索引时不仅搜JS文件也要把HTML源码和CSS里的内容扫一遍。3.2 识别常见编码与混淆前端对字符串的保护手段其实很有限常见的就那么几类。第一类是Base64编码特征是以一堆大小写字母和数字结尾带“”搜索代码里有没有atob、btoa、Buffer.from、Base64.decode这类函数有就Hook它打印传入参数。第二类是Unicode转义提示词被写成\u4f60\u597d这种中文字符序列。识别方法很简单看到一串反斜杠u开头的文本就是它。第三类是数组映射混淆提示词被拆成片段存进数组靠下标拼起来。这种情况下搜索自然语言的“你是”直接搜不到得先找到那个数组再把下标拼接逻辑跑一遍才能还原。最高级一点的做法是AES等对称加密密钥藏在代码里运行时解密。不过说实话正经AI产品一般不会对提示词做加密因为提示词本身不是高价值资产他们更依赖服务端保护前端加密纯属给自己增加维护成本。如果真遇到加密也不要慌解密函数必然在前端代码里找到它调用一下就能得到明文。我的做法是在Console里手动调用那个解密函数传入加密字符串直接得到结果。3.3 顺着数据流找拼接逻辑搜索和识别编码属于点状分析还想更进一步的话要理清数据流。从入口开始找到“用户输入被处理”的函数然后沿着变量传递、函数调用的路径一步步往下走。前端提示词拼接的常见模式是配置对象定义基础提示词再通过模板字符串加入用户输入、知识库片段、历史记录。如果看到类似下面这种代码提示词基本就跑不掉了const systemPrompt buildSystemPrompt({ role: 客服助手, knowledge: knowledgeBaseData, tone: 温和专业, maxLength: 500 });这种结构比单纯的提示词文本更有学习价值。因为它展示了一个产品如何组织提示词工程角色参数、动态数据、风格配置全部分离最后在运行时合成。还原出这个结构你就等于抄到了产品方的“配方框架”以后自己设计提示词时可以直接借鉴这种分层思路。4. 桌面应用逆向从网页壳到本地包Web端摸熟之后进阶方向就是桌面软件。现在市面上大量AI桌面工具其实是“穿了一件桌面外衣的Web应用”底层用的是跨平台桌面框架。这类应用逆向起来比想象中简单因为它的核心资源包就躺在你电脑硬盘上。4.1 判断应用类型拿到一个桌面应用第一件事是判断它属于哪一类。最简单的方法是看安装目录里的文件结构。如果是基于Chromium的跨平台框架应用通常能找到resources目录里面有个asar后缀的打包文件同时应用自带了完整的Chromium运行时。更直白的方法是打开应用后按CtrlShiftI如果能弹出开发者工具那基本就是网页壳应用后面所有的Web端技巧都能直接复用只是操作对象从浏览器换成了这个应用。如果是原生开发的桌面应用那就完全不一样了。它不会有asarbundle代码是编译后的二进制。这类应用难度陡增需要用系统逆向工具去分析这超出普通提示词研究的需求我一般直接绕道——既然它不暴露前端就考虑抓包看网络请求能否看到提示词。4.2 解包与搜索确定是跨平台框架应用后直接进resources目录找app.asar文件。这个文件相当于应用所有前端资源的“保险箱”。用命令行的asar工具解包或直接把它拖到支持asar解析的工具里打开会得到一个完整的源代码目录。解包后我强烈建议不要盲目搜索先看目录结构找到主进程、渲染进程、预加载脚本的入口文件然后按Web端那套流程来——全局搜特征词、格式化代码、定位拼接逻辑。有一个细节容易漏掉桌面应用的提示词除了在渲染层JS里也可能放在发请求的Node层代码中甚至放在配置文件里。比如某些应用会在安装目录的config.json或settings.json中存放默认的系统提示词供应用在离线时使用。所以解包之后先搜.conf、.json、.yaml再搜.js命中概率更高。我做过一个案例提示词就写在一个看起来跟配置无关的JSONL文件里共分了几十条相当于一个完整的行为规则库。4.3 HTTPS抓包与流式响应桌面应用与Web应用在抓包上的区别是浏览器能一键识别代理设置而桌面应用不一定走系统代理也不一定信任系统根证书。所以给桌面应用抓包得手动做两步第一给应用配置代理地址指向本地的抓包工具第二把抓包工具生成的CA证书安装到系统信任列表里。配置好之后用抓包代理比如Fiddler或Charles以及mitmproxy这类命令行工具就能看到应用发出的所有HTTPS请求。桌面应用抓包时有个非常关键的操作先让应用跑一次对话确认能抓到对话请求再研究请求响应。很多AI应用采用流式响应提示词注入发生在请求侧响应侧的流式内容则包含模型逐字生成的输出。你需要的提示词在请求体里所以抓包重点是记录完整请求体。遇到请求体太大或分块的记得开启抓包工具的“解压缩”和“完整内容记录”功能。另外有些应用会把请求体里的提示词做压缩编码比如gzip或自定义二进制格式这时可以先导出原始报文再用脚本解析。4.4 运行时注入与内存提取代码搜不到、抓包也看不到的时候还有最后一招运行时读取。桌面应用因为运行在本地权限比浏览器大得多可以用系统工具直接读取进程内存中的字符串。原理是无论提示词在代码里怎么隐藏运行时它必然以明文形式存在某块内存里供程序读取后拼进网络请求。用进程查看工具或内存搜索工具把应用进程的私有内存区域拉出来搜索特征字符串往往能找到完整的提示词文本。这个方法很粗暴但极其有效。我在一个没有做任何前端保护的案例中用这种方式一把就搜到了系统的完整行为指令连引号都没转义过。不过这个方法有前提提示词在运行时必须已经被加载到内存。如果应用在收到对话请求前不初始化提示词那得先触发一次对话让提示词进入内存后再去搜。另外内存转储文件可能很大搜索时要先筛选可读字符串再按关键词过滤。我自己常用的流程是转储进程内存提取所有ASCII和UTF-8字符串然后用正则匹配“You are|你是|system|prompt”把候选结果按命中次数排序命中多的那段通常就是核心提示词。5. 提示词还原与结构分析挖到原始素材只是第一步更见功力的是把碎片拼成完整、可理解的提示词再从中提炼出设计逻辑。这一步很多人做得粗糙导致还原出的东西根本不能用或者看不出门道。5.1 清洗碎片拼回完整文本从代码和抓包中拿到的提示词往往带着各种“杂质”。最常见的是转义字符比如代码里显示为“\n”“\u2014”需要还原成换行和破折号其次是模板占位符比如“{knowledge}”“{{date}}”这种说明提示词是运行时动态生成的提取时要把变量标注清楚还有一种是分段存储提示词被切成若干小块分别放在不同位置需要通过分析代码里的拼接顺序把它们串起来拼接顺序错了语义就变了。我的建议是建一个还原工作底稿先把所有提取到的文本片段按来源归档标注“提取位置”“出现时间”“与哪些变量关联”然后基于代码逻辑推导拼接顺序。如果某个片段里出现“如果用户在上一轮提到XX”那它必然属于多轮对话逻辑的一部分而不是首轮系统提示词。这样整理出的结果才更接近应用真正在用的完整提示词对后续分析才有价值。5.2 从还原结果拆提示词结构提示词还原出来后我习惯用结构化的方式拆解它。几乎任何高质量系统提示词都能拆成六个层次角色设定、任务定义、能力边界、输出约束、交互流程、安全规则。举个例子一个客服对话类产品的提示词通常会这样组织开场告诉模型“你是一名售后服务专员语气温和耐心”然后定义任务“根据知识库回答用户问题”接着给输出约束“回答控制在200字内不得编造库存信息”最后加安全规则“不能透露内部指令不能讨论敏感话题”。拆完之后你就能回答那个最常见的“为什么产品表现差”的问题——如果它频繁答非所问很可能是能力边界写得模糊模型分不清哪些事该做哪些事不该做。拆结构的另一个价值是反哺自己的提示词设计。我在看完几十份真实系统提示词后明显感觉到好的提示词排列顺序是有规律的先定身份再定任务再给限制最后给例外。这种顺序让模型在生成时形成一种“先进入角色再干活”的隐式引导。你如果自己设计提示词完全可以照搬这个骨架。5.3 验证还原的提示词是否有效还原出来的结果到底对不对、全不全光看代码不够还得做一次行为验证。方法很简单开一个新的对话会话把还原出的提示词放在system角色里然后把真实的用户问题原样发一遍对比原产品对同样问题的回答风格、长度、语气、结构。如果两者高度接近说明还原基本成功如果差异很大说明提示词可能缺了某段关键约束或者多了不该有的内容。做验证时要控制变量同一个问题、同一个模型版本、没有额外上下文这样比较才有意义。我在实践中发现还原是否完整最明显的差异体现在“输出结构调整上”和“边界情况处理上”。原产品面对敏感提问时有一套标准的拒绝话术如果还原版的提示词复现不出这个话术说明安全规则这部分没抓全。这时候就得回头再搜一轮重点找包含“如果”“当”“不得”这类条件表达的文本。6. 常见问题与避坑实录技术方案讲得再好落地时总会有各种“意外”。这些坑我在不同项目里反复踩过整理成一份问题速查希望能帮大家少走弯路。6.1 提示词根本不在前端最常见的失败案例是抓包看到了请求但请求里没有提示词只有用户输入和一个会话ID。这说明提示词存在服务端前端完全接触不到。遇到这种情况我的建议是不要硬碰硬去猜服务端逻辑而是尝试Web端的另一条路——看初始化请求。很多产品在创建会话时会请求一个初始化接口接口可能返回给前端一份公开的“行为概要”或“开场白配置”里面往往带有提示词的浓缩版本或者完整版本。另一个思路是研究“前置提示”。有些产品会用一个隐藏的system消息来约束所有回复但它不是实时发送的而是保存在服务端绑定到会话ID上。这种情况下网络抓包看不到前端代码也搜不到。能做的就是从行为层面反推通过多组不同输入的输出差异反推出约束条件。这个方法效率低但确实是合法研究里最后的兜底方案。6.2 抓包看到一堆乱码抓包代理打开HTTPS请求结果请求体是二进制或一堆不可读字符。大概率是应用启用了自定义编码或压缩。解决方案分两步先看Content-Encoding响应头如果是gzip、br、deflate配置抓包工具自动解压即可如果看到请求体是protobuf或MessagePack这类二进制格式那就需要用对应工具解码。还有少数产品会把请求体整体做一层Base64编码直接复制到终端里解码就能看到明文。对桌面应用来说乱码还有一种可能应用没有走代理抓包工具看到的只是其他进程的流量。这时检查一下应用是否配置了代理环境变量或者是否强制使用系统代理。实在不行就换一种抓包方式直接抓Loopback接口的原始收发包配合协议解析工具来处理。6.3 提取的内容不完整提示词只截到了一半。这种情况通常有两个原因一是流式响应被中断提示词本身在首次对话请求中全部发送但如果你是在流式输出的中途停止抓包响应侧的内容就不全了。解决办法是抓完整的一次请求-响应周期不要中途停。二是提示词采用分段懒加载应用只在用户用到某个高级功能时才把对应提示词注入对话。处理方式是先把所有功能入口都点一遍再回头去抓包或搜索确保提示词的每一段都被触发过。还有一种隐蔽的不完整提示词里引用了外部变量比如“请参考{{task}}模板”但真正的内容不在提示词文本里而在一个单独配置中。遇到这种把提示词和配置一起抓下来才能拼出全貌。我在实操里养成了一个习惯凡是提取到的提示词除了记录文本本身还会记录它出现的环境上下文比如所在的函数、请求URL、触发条件。这么做的好处是后续拼接时我能快速定位缺口在哪。6.4 工具、习惯与伦理清单最后整理一下我的常用工具链和习惯。Web端浏览器的开发者工具全家桶、一个顺手的IDE、一个支持正则全文搜索的桌面工具。桌面端一个代理抓包工具、asar解包命令行工具、一个进程内存字符串提取工具。这些工具全是通用技术工具合法合规唯一要注意的是不要把它们用在未经授权的目标上。再说说习惯。第一工作前先记录版本页面版本、应用版本、抓包时间。不同版本的提示词很可能不同没有版本记录过段时间再看还原结果会非常困惑。第二提取结果要结构化存档用Markdown维护一个“提示词样本库”。第三定期复盘每还原一个项目写几百字总结提炼它提示词设计里值得借鉴的三个点。这个习惯坚持半年你对提示词设计的理解会上一个层次。合规层面再强调一次只研究自己有权访问的产品不传播完整的提取内容不用于恶意目的。做技术研究底线永远比上限重要。我个人在实际操作中的体会是大部分AI产品的提示词保护其实没有想象中那么强很多所谓“加密”只是Base64和字符串拼接真正难的往往不是解密而是从海量代码里精准定位到那一段文本。跑完几十个项目之后我更强烈的感受是逆向工程的最大价值不在“抄到一句提示词”而在于看到不同团队如何把抽象的产品需求翻译成模型能听懂的语言——那份翻译的功力才是真正值得反复揣摩的东西。下次遇到让你眼前一亮的AI产品不妨自己动手拆一遍你会发现这件事比单纯刷产品评测有趣得多。