同样是让大语言模型做一件事,有人输入“帮我总结一下这篇文章”,得到的是一段流水账加两处事实错误;有人输入“你是一位资深产品经理,请基于以下原文输出三句话结论、两个关键论据、一个待核实假设,原文没有的信息明确写‘未提及’”,得到的是一份可以直接抄进周报的结果。明明用的是同一个模型、同一份上下文,差距却大到像两个产品,这就是提示词工程在日常中最直观的体现。
这篇算是大语言模型系列里的第三篇,今天我们专门聊提示词工程。它不是什么高深算法,而是在不重新训练模型的前提下,通过设计输入、组织上下文、约束输出,把模型的真实能力“挤”出来的方法体系。适合正在用大模型写代码、做内容、跑数据流程的同学,也适合刚接触大模型、想摆脱“一问就错”的普通用户。我会从底层原理讲到高频模板,再到上下文工程和 Agent 的边界,最后附上我踩过的坑和排查清单,尽量让你看完就能直接动手改自己的提示词。
1. 提示词工程到底在“工程”什么
很多人以为提示词工程只是“把话问细一点”,其实不是。它是一套围绕模型行为做设计的工程方法:定义角色、拆解任务、管理上下文、控制输出格式、设计示例,甚至包括对不同模型的提示词适配。本质上,你在和模型共写一段“条件化生成”的剧本。
1.1 大语言模型的本质决定了提示词的价值
大语言模型本质上是一个超大的“概率接龙器”。给定前面的一串 token,它不断预测下一个最可能的 token,然后接上、再预测。换句话说,模型输出的每一个字,都受到“此前所有字”的约束。提示词就是这段“此前文字”里我们人为控制的部分,它决定了模型进入哪种语言分布、行为模式和知识提取方向。
这个特点决定了两个结论:第一,提示词不是可有可无的修饰,而是模型推理时的条件输入,直接影响概率分布;第二,提示词是一种“域外控制手段”——你不需要动模型权重,却能显著改变输出倾向。相比微调,提示词的边际成本几乎为零,在算力受限、训练数据不可控的生产环境里,优化提示词往往比重新训练划算得多,这也是提示词工程能成为独立技能的根本原因。
不过也要说清楚,提示词不是“魔法咒语”。它能约束模型的表达路径,但无法让模型知道它从未见过的知识。有时候你提示词写得再完美,模型还是会基于错误的内部记忆给出看似合理的答案。理解这条边界,才不会把提示词工程神话化。
1.2 提示词工程能解决的四个具体问题
我在实际项目里用提示词工程解决过四类高频问题。第一类是输出结构性差:模型回答一大段,你需要的是表格、JSON、关键字段,结果必须手动二次处理。第二类是内容不稳定:同一个问题问两次,结论能反着说,温度没有调但输出就是飘。第三类是信息遗漏:让它做总结,它漏掉你真正关心的指标,却把次要内容写了一大段。第四类是角色能力弱化:你让它扮演专业顾问,它回答得却像百度百科。
这四个问题互相关联,但根子不同。结构性差是缺少输出约束,不稳定性是缺少示例与边界,信息遗漏是任务拆解不够,角色弱化是上下文和角色设定没有形成合力。提示词工程就是围绕这四点做“定向改造”。我的经验是,先记录你被无效输出浪费的时间,再逐条对照这四类问题去改提示词,比直接套模板有效得多,因为生产环境里的问题永远是具体场景里的问题。
2. 写提示词前,先理解模型怎么“读”你的话
想写好提示词,不能只记模板,还要明白模型在“读”什么。它读的是 token 序列,不是你的意图;它依赖的是上下文窗口里的所有字符,不只是你最后那句指令。
2.1 Token、上下文窗口和概率生成
先说 token。大语言模型不会按字处理文本,而是把文本切成 token,一个 token 可能是半个中文词、一个英文单词或一个标点。模型的所有注意力机制、概率计算都在 token 上进行。这意味着提示词越冗长、越啰嗦,占用上下文越多,模型需要聚焦的关键信息就越容易被稀释。
再说上下文窗口。不同模型支持 4K、32K、128K 甚至更长的上下文,但它只是一个“可以装多少字符”的容器,并不代表模型能充分利用其中所有信息。在很多长文本任务里,模型对中后段内容的注意力会衰减,实验发现哪怕上下文窗口够大,把关键指令放在最开头和最末尾通常更有效,中间部分容易成为“注意力黑洞”。
概率生成决定了模型对参数的敏感性。temperature 越高,越容易选到低概率 token,输出更有“创造性”;temperature 越低,越偏向高概率 token,输出更稳定。提示词工程通常建议把 temperature 设在 0 到 0.3 之间,尤其是代码生成、数据处理、JSON 输出这类任务。这不是玄学,而是直接用参数约束概率分布,让模型少走“创造弯路”。
2.2 角色、任务、上下文、格式:四要素拆解
我写提示词时习惯按四个要素拆解,这也是一套能覆盖大多数场景的底层公式。
第一个要素是角色设定。不是简单说“你是专家”,而要给出行为边界和价值观。例如“你是一位生产环境优先的后端工程师,给出的代码要考虑异常处理、日志和可维护性”。这样模型就被限制在一个更具体的知识分布里,回答会明显偏向实践而不是教科书。
第二个要素是任务描述。尽量用动词开头,明确你的交付物是什么。写“生成一段Python代码”不如写“生成一个读取CSV文件并统计每列缺失率的Python函数,要求处理空文件情况”。任务越具体,模型越不需要自己“猜”。
第三个要素是上下文与背景信息。这是很多人容易漏掉的。模型不知道你的表结构、你的业务口径、你的用户画像,除非你给它。上下文越完整,输出越贴合真实需求。我会习惯把相关资料、历史对话、字段说明直接粘贴进提示词。
第四个要素是输出格式约束。你可以要求输出 Markdown、JSON、代码块,也可以要求“先给结论、再给原因”,或者规定一个表格的列名。这个要素决定了模型输出的可用度。四要素之间是乘法关系,缺一个效果都会打折扣。
3. 高频实战:场景化提示词模板与参数调优
理论讲多了容易飘,直接进入实战。我挑三个最高频的场景:内容生成、代码生成、结构化输出。每个场景我都会给一套可以直接改改就用的提示词模板,并解释为什么这么写。
3.1 内容生成与润色:从“能写”到“写好”
内容生成最忌空泛。模型写出来的东西之所以像“塑料感”,是因为你没有给它风格锚点、结构锚点和禁止项。我自己常用的一套模板是:
角色:你是一位有10年经验的行业编辑,擅长把复杂问题讲得通俗但不失真。 任务:请把下面的原始内容改写成一篇面向产品经理的说明文。 结构要求:先给核心结论,再写三个分论点,每个分论点配一个生活化类比;总字数控制在500字以内。 风格要求:语气直接,不要官方套话,少用“赋能”这类词。 禁止事项:不要增加原文没有的数据结论。 原始内容:……这套模板的核心是把“好文章”拆成可执行的子标准。很多人只告诉模型“写得好一点”,模型无法理解什么是“好一点”。当我给出结构、字数、措辞、禁用词这些硬约束,输出质量明显上升。参数上我会把 temperature 调到 0.5 左右,既保留一点语言多样性,又不至于跑偏。
同一个模板也适合产品文案、通知、周报。只需要改角色和风格描述即可。比如写周报时,我加一句“每项工作用一句话说明结果、量化数据优先”,模型就会主动去挖数字,而不是写“推进了XX项目”。
3.2 代码生成:规则设定与AI写代码
“AI写代码+规则设定+提示词工程”是很多开发者的黄金组合。但如果你只是说“帮我写一个按钮”,模型大概率会给你一个孤立 HTML 片段,既没有样式变量,也没有事件处理。问题的根源是规则没有进入提示词。
我在用大模型生成代码时,会把项目约束前置,形成一个“编码规则包”:
语言与框架:Python 3.11 + FastAPI 工程规范:函数必须有类型注解;关键路径必须有异常处理;日志使用 logging,不允许 print 目标:提供一个 POST /api/parse 接口,接收 JSON,返回提取的字段列表 边界条件:输入为空、字段缺失、类型错误时分别返回 400 和错误信息 测试要求:附带两个 pytest 用例,覆盖正常输入和异常输入这组提示词的效果远好于“帮我写个接口”。原因很简单:模型在预测下一段代码时,条件分布中包含了你的工程规范,它就更倾向生成符合规范的代码。你实际上是在用提示词扮演“技术评审”,让模型在生成阶段就把规范内化。
代码调试也一样。不要直接甩报错信息让模型“修复”,而是给它三段内容:出错的代码段、完整报错信息、你怀疑的可能原因。再让它先用文字解释错误根因,最后给出修改方案。很多模型在“先解释再写代码”的模式下正确率更高,因为解释过程激活了推理相关的 token 分布。
3.3 结构化输出:从自由文本到稳定JSON
用大模型做数据提取时,最头疼的是输出不稳定。今天给你 JSON,明天给你 Markdown,后天给你一段带解释的文字。解决这个问题不能只靠“请输出JSON”,还要给 schema 和反例。
我的标准做法是:
从以下用户评论中提取情感倾向、提及的问题类别、紧急程度。 输出格式:严格JSON,不要输出任何解释文字。 JSON Schema: { "sentiment": "positive|negative|neutral", "problem_categories": ["string"], "emergency_level": 1-5 } 如果某字段无法提取,使用 null,不要编造。 用户评论:……关键细节有两个:一是给字段枚举值,二是明确“无法提取时用 null”。这能显著降低模型的“脑补概率”。另外一个非常有效的小技巧是给一个期望输出示例,哪怕示例和当前输入无关。比如加上“示例:{"sentiment":"negative","problem_categories":["物流"],"emergency_level":4}”,模型会把生成结果拉回同一形状。
参数上,temperature 必须设到 0,top_p 也可以降到 0.8。我在生产环境里还会做一层“输出校验”,用代码解析 JSON,解析失败就重试一次,并把上次失败的原因加入提示词。这不是提示词工程本身能完全解决的问题,但和提示词配合,能把成功率从 80% 拉到 98%。
4. 进阶话题:上下文工程、System Prompt 与 Agent
基础的提示词模板只能在单次对话里起作用。当你要构建真正可用的 AI 应用时,就需要把视角从“单条提示词”上升到“上下文工程”和“多轮交互体系”。
4.1 从提示词工程到上下文工程
很多人把提示词工程和上下文工程混为一谈。我理解的区别是:提示词工程解决的是“单次请求里如何措辞、设定角色、组织指令”;上下文工程解决的是“在多次调用中,把哪些内容放进上下文窗口、以什么顺序放、放多少、何时摘要和裁剪”。
举个例子。做一个基于内部知识库的问答机器人,你不是只写一句“你是客服助手”就够了。你要决定用户问题之外要不要附带检索到的知识片段、历史对话保留几轮、系统指令占多少字符、知识片段和问题谁先谁后。这些都属于上下文工程。一个典型配置可能是:前置 System Prompt(约500字符) + 检索知识片段(约1500字符) + 当前问题(约200字符) + 历史摘要(约300字符)。
顺序上,我会把最关键的内容放在最前和最后。模型对前后内容的注意力更强,中间塞太多知识片段反而可能被忽略。迭代的经验是:每轮把历史和旧知识做摘要,避免上下文窗口被垃圾撑满。上下文工程本质上是“用有限的窗口做信息优先级管理”,比单纯优化一句话更要紧。
4.2 System Prompt、Skill 与 Agent 到底有什么不同
连我自己也见过很多讨论把 System Prompt、Skill、Agent 混着说,但它们根本不是同一维度的东西。
System Prompt 是给模型设定的“开机配置”,在会话开始时注入,规定模型身份、处理原则、输出偏好、安全边界。它影响所有后续消息,所以适合放稳定、可复用的规则。例如“你是一个物流客服,必须基于给定订单信息回答,不猜测,不承诺赔偿金额”。
Skill 则是面向某一类任务的“可复用能力包”,通常包含一组指令、示例、工具定义、输出模板。模型可以根据用户意图选择或加载某个 Skill,比如“代码审查 Skill”“周报生成 Skill”。Skill 更像一个外挂工具箱,只是挂载点依然在提示词和工具描述里。
Agent 则更进一步,它不只是用提示词约束回答,而是组合模型、工具调用、记忆、规划,自主拆解任务并执行。Agent 里可能有多个 System Prompt、多个 Skill、多次模型调用。简单说,System Prompt 是“底线人设”,Skill 是“技能库”,Agent 是“带目标、会调工具的完整执行者”。
在实践里,不要为了“用 Agent”而用 Agent。很多场景只需要一个稳定的 System Prompt 加一个 Skill 就够了。一旦任务涉及多步骤、需要实时工具反馈,才值得引入 Agent。把简单任务复杂化,反而容易失控。
4.3 多模态与本地部署场景:提示词工程的边界
这几年视觉大语言模型很火,能看图、读文档、识别截图。但一个经常被忽视的事实是:很多多模态模型并不是真正“看懂”了图,而是借着语言先验在“猜答案”,尤其是当图像信息模糊时,模型会倾向于从周边文本中找答案。这个特性决定了在多模态任务里,提示词要更像“给这位只能靠蒙的同学出题”:把图像里需要关注的位置、要提取的字段、不能凭空猜测的范围全部写清楚,而不是简单说“看看这张图有什么”。
本地部署大语言模型的场景里,提示词工程反而更关键。本地模型参数量小或因为量化精度导致表达能力受限,它对模糊指令的容错率远低于商业大模型。同一个提示词,在线模型可能能猜中你意图,本地小模型可能直接跑偏。这时候我会把提示词里的“隐含常识”尽量显式化,比如把“信息缺失时写未知”换成“如果原文没有出现金额数字,禁止推断金额,直接输出null”,小模型的表现会立刻改善。
另外,本地部署时还要注意上下文长度更紧张。因为显存有限,窗口越长、生成越慢。提示词设计要考虑“每句话都用来控制行为”,尽量避免大段无关历史。我自己在本地模型上测试时,会给提示词增加一个“去掉前后置寒暄”的规范,既省 token 又降低干扰。
5. 产物不稳定的排查实录与避坑清单
就算是提示词老手,也免不了遇到模型“发神经”。与其一篇篇翻文档,不如把常见问题定位和修复模板整理成清单,直接对照使用。
5.1 五个常见问题定位清单
我在调试提示词时,习惯先对照下面这张表,而不是盲目改措辞:
| 现象 | 可能原因 | 优先排查方向 |
|---|---|---|
| 输出结构混乱 | 缺少格式约束或格式约束被长文本稀释 | 把格式要求放到提示词末尾,并给出 JSON 示例 |
| 同一问题答案反复横跳 | temperature 过高或边界条件不清 | 调低 temperature 到 0.3 以下,补充不猜测的规则 |
| 任务漏项 | 指令句子太多,模型注意力偏移 | 用编号列表拆分子任务,并在输出前增加“自检清单” |
| 角色失效 | 角色定义被用户消息覆盖 | 把角色放回 System Prompt,同时在每个回复后给角色召回指令 |
| 幻觉频率高 | 模型把内部记忆当事实 | 明确“仅根据给定资料回答”,并要求引用原文片段 |
这张表不是万能药,但它能帮你把模糊问题翻译成可操作项。比如漏项问题,不是模型不听话,而是你的提示词里塞了太多并列任务,注意力被均摊。拆成编号列表后,模型更容易逐个完成。
还有一个容易被忽略的坑是“否定词过多”。人类善于处理“不要写、不要出现、不要用”,但模型对否定结构的注意力不如对肯定结构敏感。与其写“不要输出多余解释”,不如写“只输出JSON,不包含任何JSON之外的字符”。后者是正面约束,模型更容易遵守。
5.2 一次“翻车”提示词的重构复盘
之前我做一个客服工单分类,最初的提示词是:“帮我判断这个工单是不是紧急,紧急的话给个原因。”模型的输出五花八门,有输出“这个工单很紧急,因为客户很生气”的,也有输出长段解释的,完全没法自动化。
我后来做了一次重构。第一,定义“紧急”的标准,而不是让模型自己理解。例如“紧急定义为:存在客户数据丢失、服务完全不可用、有明确经济损失或安全风险,其他情况一律非紧急”。第二,输出格式改为 JSON,要求返回 is_emergency、reason、risk_level。第三,加一个示例。第四,把 temperature 调成 0。
重构后,同一批工单的分类一致率大幅提升,而且理由也落到实处。这件事让我意识到:提示词工程的本质,是把隐性判断显式化。你越能把自己的业务逻辑写清楚,模型给你的结果就越可控。
5.3 我的六个实测心得
第一,永远别指望模型一次回答完全正确,把“重新生成”和“要求修正”当成流程的一部分。第二,重要的提示词要用代码管理起来,写版本号、变更记录,否则你根本不知道哪版效果好。第三,模型更新后一定要回归测试提示词,同一个提示词在 GPT-4、Claude、开源模型的输出差异可能非常大。第四,尽量保留少量典型输入作为“提示词测试集”,每次调整后用同一批用例跑,对比输出质量。第五,不要在提示词里放用户的任何隐私数据,避免合规风险。第六,提示词越长不一定越好,很多场景里一句话加一个示例的效果,超过一段长篇大论。
6. 最后再分享几点个人经验
写提示词这件事,和写代码有一点很像:需要从“能用”迭代到“好用”,再迭代到“可复用”。我个人的习惯是每个新场景先手写一版粗糙提示词,跑三轮,看输出,再改成模板;模板里用{{变量}}占位,后续全部走程序编排,不再手打。
另外,我强烈建议你在团队里建一个“提示词库”。不用高大上,一个共享目录就行,里面按内容生成、代码、数据提取、客服问答分好类。每个模板旁边写一句“为什么这么写”,以及“在哪些模型上验证过”。这个库的价值会随着时间积累越来越大,因为模型在变、工具在变,但好的提示词设计思路是稳定资产。
如果你已经在用 Agent 或本地部署大模型,不妨从这份清单开始做一次“提示词审计”:把系统里所有写死的提示词翻出来,按照角色、任务、上下文、格式四要素逐项检查,再对照第五章的常见问题表做一轮修复。经手的项目多了以后你会发现,提示词工程不是玄学,而是一门需要耐心打磨的技术。真正决定输出上限的,始终是你对任务的理解深度。