ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

提示词工程实战:从单轮提示到多轮上下文管理的系统方法

提示词工程实战:从单轮提示到多轮上下文管理的系统方法 提示词工程这件事很多人第一次接触时都会有一个误解以为它是在学某种“咒语”只要背下几个模板就能让模型乖乖听话。实际用下来你会发现真正决定输出质量的往往不是那句提示词写得多花哨而是你有没有把模型当成一个“理解力很强但完全不了解你背景的新同事”来沟通。我见过太多人拿着同一套模板反复套结果换一个任务就翻车然后得出结论说“模型不行”。问题多半出在沟通方式上而不是模型本身。这篇文章想聊的就是怎么跟模型说话它才听得懂。我会从提示词工程的本质讲起拆解为什么有些提示词有效、有些无效然后给出可以直接抄作业的结构化写法、参数控制思路、常见翻车场景的排查方法以及从单轮提示到多轮上下文管理的进阶路径。不管你是刚上手大模型的新手还是已经写过几百条提示词但总觉得输出不稳定的老手应该都能从里面找到能直接用的东西。1. 提示词工程到底在解决什么问题1.1 模型不是读心术它只对你写出来的字负责很多人对模型有一个隐藏预期我大概说个意思它应该能猜到我要什么。这个预期在人类沟通里成立因为人有常识、有场景感知、有共享背景。但模型没有。它看到的只有你输入的那串文本以及它在训练阶段学到的大量语言规律。你没写出来的东西它只能靠概率去猜猜对了是运气猜错了是常态。举个很典型的例子。你写“帮我写个总结”模型会给你一段总结但总结什么、给谁看、多长、什么语气、要不要分点它全靠默认值。默认值不一定符合你的需求于是你觉得它“不懂我”。但如果你写“把下面这段会议记录总结成给部门负责人看的周报300字以内分三块进展、风险、下周计划语气正式但不啰嗦”输出质量会立刻上一个台阶。差别不在于模型变聪明了而在于你把它需要的信息补齐了。所以提示词工程的第一性原理很简单把模型完成任务所必需的上下文、目标、约束、格式尽可能无歧义地写进输入里。它不是玄学而是一种信息传递的优化。1.2 提示词、上下文工程、Agent 技能三者不是一回事热词里经常把“提示词工程”“上下文工程”“Skill Agent”混在一起谈其实它们关注的层面不同。提示词工程关注的是“这一次输入怎么写”上下文工程关注的是“整个对话窗口里放什么、按什么顺序放、什么时候清理”而 Agent 技能关注的是“模型如何调用外部工具、如何分步骤完成一个复杂任务”。打个比方。提示词工程像是你给同事写一张便签说清楚这件事怎么做上下文工程像是你整理整个工作台把相关的资料、历史记录、当前任务按优先级摆好Agent 技能则是给同事配了一套工具箱让他能自己查资料、跑脚本、调接口。三者是叠加关系不是替代关系。你提示词写得再好如果上下文里塞了一堆无关内容模型照样会被干扰你上下文管理得再干净如果单条指令本身含糊输出也不会稳定。理解这个分层能帮你判断问题出在哪一层。输出跑偏了先看单条提示词是否清晰如果单条没问题但多轮之后越来越乱那就是上下文管理的问题如果任务本身需要多步骤、需要外部数据那才轮到 Agent 技能上场。1.3 为什么同一个提示词换个模型就失效这是很多人踩过的坑。你在某个模型上调好了一条提示词效果很好换到另一个模型上输出风格、格式遵循度、指令理解能力全变了。原因在于不同模型的训练数据、对齐策略、指令微调方式都不一样。有的模型对格式指令特别敏感你说“用 JSON 输出”它就老老实实输出 JSON有的模型更偏向自然语言你要求 JSON 它可能给你一段带解释的伪 JSON。这意味着提示词工程不是一次性的工作而是需要针对目标模型做适配。适配的方法也不复杂先用一条基础提示词测试模型对指令的遵循程度再根据它的表现调整措辞的强度。比如对遵循度高的模型你可以写得简洁对遵循度低的模型你需要把关键约束重复强调甚至给出示例。这个适配过程本质上是在摸清这个模型的“脾气”。2. 让模型听懂话的四个信息层2.1 角色层给它一个明确的身份定位角色设定是提示词里最容易被滥用也最容易被低估的部分。滥用是因为很多人不管什么任务都加一句“你是一个资深专家”但这句话本身不携带任何有效信息对输出几乎没有影响。低估是因为真正有效的角色设定能显著改变模型调用知识的倾向和表达风格。有效的角色设定要具体到领域和视角。比如“你是一个有十年经验的财务分析师擅长从报表里发现异常”就比“你是一个专家”有用得多因为它限定了知识范围财务、经验水平十年、核心能力发现异常。模型在生成时会倾向于调用与财务分析相关的表达模式和推理路径输出的专业度会明显不同。但要注意角色设定不是万能的。如果任务本身是纯格式转换比如把一段文字翻译成英文角色设定的作用就很有限。角色层真正发挥作用的地方是那些需要特定知识背景、特定表达风格、特定判断标准的任务。判断标准很简单如果换一个角色你期望的输出会明显不同那角色设定就值得写如果换不换都一样那就别浪费字数。2.2 任务层把“做什么”拆到不能再拆任务描述是提示词的核心也是最容易写得含糊的地方。很多人写任务时用的是“帮我优化一下”“帮我看看有没有问题”这种模糊动词模型只能靠猜。正确的做法是把任务拆解成具体的动作和对象。比如“优化这段代码”可以拆成“找出这段代码里的性能瓶颈按影响程度排序对每个瓶颈给出修改后的代码和预期提升”。这样模型就知道它要做的是识别、排序、改写三件事而不是笼统地“优化”。拆得越细输出的可控性越高。这里有个实用技巧用动词开头描述每一步。识别、提取、比较、排序、改写、生成、验证这些动词本身就携带了明确的操作含义。当你把任务写成一系列动词短语时模型更容易按步骤执行而不是把所有要求揉成一团。2.3 约束层告诉它什么不能做比告诉它做什么更重要约束是提示词里最容易被忽略的部分。大多数人只写“要什么”不写“不要什么”。但模型在生成时如果没有明确约束它会倾向于选择最常见、最通用的表达而这些表达往往不是你要的。约束可以分几类。长度约束不超过 200 字或者至少三段。格式约束用 Markdown 表格或者纯文本不分点。内容约束不要出现专业术语或者必须引用原文。风格约束不要用感叹号或者保持中性语气。这些约束写进去之后输出的稳定性会大幅提升。一个常见的误区是约束写得太多太碎导致模型顾此失彼。约束不是越多越好而是要抓关键。通常一次任务里三到五条核心约束就够了再多反而会让模型在约束之间做取舍时出错。优先写那些“不满足就完全不能用”的约束次要的可以放到后续轮次里补充。2.4 示例层一个例子胜过十句描述当任务比较复杂或者输出格式有特定要求时给示例是最有效的手段。示例的作用是让模型直接看到“输入长什么样、输出长什么样”从而模仿这个映射关系。这比用文字描述格式要精确得多。示例的写法有讲究。一个示例适合格式明确、变化不多的任务比如固定字段的抽取。多个示例适合需要覆盖不同情况的任务比如分类任务里每个类别给一个例子。示例要尽量覆盖边界情况否则模型遇到边界输入时还是会跑偏。但示例也不是越多越好。示例太多会占用大量上下文空间而且如果示例之间有矛盾模型会困惑。一般来说两到三个高质量示例就能覆盖大多数场景。示例的质量比数量重要一个精心设计的示例比五个随手写的示例有用得多。3. 结构化提示词的实操写法3.1 用分隔符把不同信息块切开当提示词里包含多种信息时比如指令、背景资料、示例、待处理内容如果不加区分地堆在一起模型很容易混淆哪部分是要求、哪部分是素材。用分隔符把信息块切开是最简单也最有效的办法。常用的分隔符有三引号、XML 标签、Markdown 标题、横线等。选择哪种不重要重要的是前后一致且视觉上明显。比如用三引号包住待处理的文本用 XML 标签包住示例用 Markdown 标题区分不同章节。这样模型在解析时能清楚知道每一块的边界。一个实际的对比例子。不加分隔符时你写“把下面这段话翻译成英文这段话是今天天气不错适合出门散步”模型可能会把“这段话是”也当成待翻译内容。加上分隔符后“把以下三引号内的内容翻译成英文今天天气不错适合出门散步”边界就清晰了。这个细节看起来小但在处理长文本时边界清晰与否直接决定输出质量。3.2 把输出格式写成模板而不是描述要求模型输出特定格式时直接给模板比用文字描述有效得多。文字描述容易有歧义模板则是精确的。比如你要模型输出一个包含姓名、职位、部门的 JSON不要写“请输出 JSON 格式包含姓名、职位、部门三个字段”而是直接写{ name: , position: , department: }然后说“按上面的模板填充”。模型看到模板后会直接往里填内容格式错误率大幅降低。这个方法在处理批量数据抽取、结构化信息整理时特别有用。模板的另一个好处是你可以通过留空字段来控制模型必须输出哪些内容。如果某个字段你不需要直接从模板里删掉模型就不会多输出。这比写“不要输出某某字段”要可靠因为否定指令有时候会被模型忽略。3.3 用“先思考再回答”提升推理质量对于需要推理的任务比如数学题、逻辑分析、多条件判断直接让模型给答案它可能会跳步或者出错。让模型先写出推理过程再给结论准确率会明显提升。这个技巧通常叫“思维链”但本质上就是要求模型把中间步骤显式写出来。写法很简单在提示词里加一句“先一步步分析最后给出结论”或者给一个示例展示“分析过程 最终答案”的结构。模型在生成时会先输出推理步骤这些步骤本身会约束后续的结论减少跳跃性错误。但要注意思维链不是所有任务都需要。对于简单的信息抽取、格式转换加思维链反而会让输出变啰嗦。判断标准是如果任务需要多步推理、需要综合多个条件、容易在中间步骤出错那就加如果任务是直接的映射关系那就别加。3.4 参数控制温度、Top-p 与输出长度的实际影响除了提示词本身模型的生成参数也会影响输出。最常调的是温度temperature和 Top-p。温度控制随机性温度越低输出越确定、越保守温度越高输出越多样、越有创意。Top-p 控制候选词的累积概率范围值越小候选越少输出越集中。实际使用中需要准确、稳定的任务把温度调低比如信息抽取、代码生成、格式转换温度设在 0 到 0.3 之间比较合适。需要创意、多样的任务把温度调高比如文案生成、头脑风暴温度设在 0.7 到 1.0 之间。Top-p 一般保持默认或者设在 0.9 左右不需要频繁调整。输出长度限制也很关键。如果任务需要完整的长文长度上限设得太低会导致输出被截断出现“已达到输出 token 上限”的提示。这时候要么提高上限要么把任务拆成多轮。反过来如果任务只需要简短回答长度上限设得太高模型可能会啰嗦。根据任务预期长度来设是比较稳妥的做法。4. 那些让提示词失效的常见坑4.1 指令冲突模型在矛盾要求之间随机选择指令冲突是提示词失效最常见的原因但很多人意识不到自己写了冲突的指令。比如“请详细分析控制在 100 字以内”详细和 100 字以内本身就是矛盾的模型只能二选一结果就是有时候详细但超长有时候简短但没内容。类似的冲突还有“用专业术语解释让小白也能看懂”“保持简洁覆盖所有要点”“严格按模板输出同时灵活调整”。这些要求单独看都合理放在一起就互相打架。模型遇到冲突时不会告诉你“你的要求矛盾了”而是默默选一个它认为更重要的执行于是输出就不稳定。排查方法很简单写完提示词后逐条检查约束之间是否有互斥。如果有就明确优先级比如“优先保证不超过 100 字在字数范围内尽量详细”。把优先级写清楚模型就知道该怎么取舍了。4.2 信息过载上下文塞太多反而降低质量很多人觉得给模型的信息越多越好于是把一堆背景资料、历史对话、相关文档全塞进上下文。结果模型被无关信息干扰抓不住重点输出质量反而下降。这就是信息过载。模型处理上下文时并不是所有内容都同等重要。如果上下文里大部分是无关内容模型在生成时会被这些内容影响可能跑题或者混淆。尤其是在长对话里早期的无关内容会持续占用注意力导致后期输出越来越偏。解决办法是主动管理上下文。每一轮对话前想清楚哪些信息是当前任务必需的哪些可以删掉。对于长文档先做摘要或者分段处理而不是整篇塞进去。对于多轮对话定期清理与当前任务无关的历史。上下文干净输出才稳定。4.3 否定指令的陷阱说“不要”它偏偏要做否定指令在提示词里经常失效。你写“不要用专业术语”模型可能还是会用你写“不要分点”它可能还是给你列了一二三四。原因是模型在理解否定时需要先激活被否定的概念再抑制它这个抑制过程不如直接指令可靠。更稳的做法是用正面指令替代否定指令。不说“不要用专业术语”而说“用日常口语表达”不说“不要分点”而说“写成连贯的段落”。正面指令告诉模型该做什么模型直接执行不需要先激活再抑制遵循度更高。如果确实需要否定可以配合示例。比如给一个“错误示例”和一个“正确示例”让模型看到区别。示例比单纯的否定指令有效得多因为模型可以直接模仿正确示例的模式。4.4 格式漂移多轮之后输出越来越随意多轮对话里第一轮输出格式很规范第二轮开始有点变化第三轮就完全跑偏了。这是格式漂移原因是模型在每一轮生成时会参考前面的对话内容如果前面的输出格式逐渐松动后面的输出会跟着松动。解决办法是在每一轮的关键指令里重复格式要求而不是只在第一轮说一次。虽然这样会增加一些字数但能有效防止漂移。另一个办法是在每轮输入里附上格式模板让模型每轮都看到标准格式。对于格式要求严格的任务这两个方法配合使用效果比较稳。5. 从单轮提示到多轮上下文管理5.1 单轮提示的边界在哪里单轮提示适合任务明确、信息量适中、不需要迭代的场景。比如翻译一段文字、抽取一组字段、生成一个固定格式的回复。这些任务一次输入就能完成不需要多轮交互。但单轮提示有边界。当任务需要多步推理、需要根据中间结果调整、需要处理超出上下文长度的内容时单轮就力不从心了。硬要用单轮做结果就是提示词越写越长约束越堆越多模型反而更容易出错。判断是否需要多轮的标准是任务是否可以分解成有依赖关系的子任务。如果可以那就用多轮每一步聚焦一个子任务输出质量会比一次性全塞进去高很多。比如写一篇长文可以先让模型列大纲确认大纲后再逐段生成最后整合。这比一次性要求“写一篇 5000 字文章”要可控得多。5.2 多轮对话里的上下文压缩技巧多轮对话最大的问题是上下文会越来越长最终超出模型的处理上限或者因为太长导致模型注意力分散。上下文压缩就是解决这个问题的。压缩的方法有几种。摘要法把前面的对话内容总结成简短摘要替换掉原始对话。关键信息提取法只保留与当前任务相关的关键信息其余删掉。分段处理法把长任务拆成多个独立会话每个会话处理一段最后合并结果。摘要法最常用但要注意摘要本身也可能丢失细节。对于需要精确引用的内容比如代码、数据、原文不要摘要直接保留。对于讨论过程、中间结论可以摘要。压缩的目标是保留“完成任务必需的信息”而不是保留所有信息。5.3 把复杂任务拆成提示词链提示词链是把一个复杂任务拆成多个提示词每个提示词负责一个步骤前一步的输出作为后一步的输入。这种方法在处理复杂任务时特别有效因为每一步都可以单独优化出错也容易定位。比如做一个竞品分析可以拆成第一步提取竞品的基本信息第二步分析各竞品的优劣势第三步对比并给出建议。每一步的提示词都聚焦一个子任务输出质量比一次性要求“做个竞品分析”高得多。提示词链的关键是步骤之间的接口要清晰。前一步的输出格式要适合后一步的输入否则中间需要人工整理。设计时可以先想清楚每一步的输入输出再写具体的提示词。这样整条链跑起来才顺畅。6. 提示词工程的迭代与验证方法6.1 建立自己的提示词测试集提示词不是写完就完事的需要测试和迭代。但很多人测试时只用一两个例子结果提示词在这两个例子上表现好换个输入就翻车。要真正验证提示词的质量需要建立一个测试集。测试集不需要很大但要有代表性。通常包含典型输入最常见的情况、边界输入极端或特殊的情况、干扰输入包含无关信息或格式不规范的情况。每类准备三到五个例子总共十几个就够用了。用这个测试集跑一遍看提示词在各种情况下的表现比凭感觉判断可靠得多。测试集建好之后每次修改提示词都跑一遍对比修改前后的表现。这样能清楚知道修改是改善了还是恶化了避免凭感觉改来改去。6.2 用对比实验找出有效改动提示词优化最怕的是“改了很多但不知道哪个改动起了作用”。解决办法是做对比实验每次只改一个变量看输出变化。比如这次只改角色设定下次只改格式约束这样能清楚知道每个改动的影响。对比实验不需要很正式但要有记录。把每次的提示词版本、测试结果、改动原因记下来积累一段时间后你会对自己的任务类型形成一套有效的提示词模式。这比每次从零开始写要高效得多。记录的时候重点记“什么改动导致了什么变化”。比如“把温度从 0.7 降到 0.2输出稳定性明显提升但多样性下降”。这些经验积累起来就是你自己的提示词工程方法论。6.3 什么时候该放弃调提示词换方案提示词工程有边界。有些问题不是提示词能解决的硬调只会浪费时间。比如模型本身不具备某项知识你怎么写提示词它都答不对比如任务需要实时数据模型没有联网能力就给不出准确答案比如任务需要精确计算模型的计算能力有限提示词再优化也保证不了准确率。遇到这些情况正确的做法是换方案。知识不足就补充知识库或者用检索增强需要实时数据就接外部数据源需要精确计算就调用计算工具。提示词工程是工具箱里的一件工具不是万能钥匙。知道它的边界比把它用到极致更重要。判断标准是如果你已经尝试了多种提示词写法输出质量都没有实质提升而且问题出在模型能力而非沟通方式上那就该考虑换方案了。继续调提示词边际收益会越来越低。7. 一些实战中攒下来的经验角色设定别写“资深专家”这种空话写具体领域和具体能力比如“擅长从用户评论里识别情绪倾向”模型才知道该调用哪部分知识。约束条件控制在三到五条优先写“不满足就不能用”的次要的放到后续轮次补充。约束太多模型会顾此失彼。需要精确格式时直接给模板别用文字描述。模板里留空的字段就是模型必须输出的删掉的字段模型就不会输出。多轮对话里每轮都重复关键格式要求别指望模型记住第一轮的指令。格式漂移是常态重复是解药。测试提示词时准备一个包含典型、边界、干扰三类输入的测试集比凭感觉判断可靠得多。每次改动只改一个变量记录改动和结果积累自己的方法论。温度参数按任务类型调准确类任务调低创意类任务调高。输出长度按预期设别设太低导致截断也别设太高导致啰嗦。否定指令尽量换成正面指令说“用口语表达”比说“不要用术语”有效。确实需要否定时配合正反示例。上下文要主动管理无关内容定期清理长文档先摘要再处理。上下文干净输出才稳定。提示词工程有边界模型能力不足、需要实时数据、需要精确计算的任务换方案比硬调提示词更有效。知道边界在哪比把提示词用到极致更重要。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进