ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

提示词工程五大核心要素:从任务指令到输出格式的实战指南

提示词工程五大核心要素:从任务指令到输出格式的实战指南 提示词工程这个词这两年出现的频率越来越高但真正动手写过几十上百条提示词之后你会发现大部分教程讲的都是角色设定任务描述输出格式这种三层结构照着写出来的提示词跑个demo还行一旦放到真实业务里就各种翻车。我自己从最早写GPT-3的completion提示词到后来折腾ChatGPT的系统提示词再到现在给各种Agent框架配prompt踩过的坑比写过的提示词还多。这篇文章不打算给你一个万能模板而是把提示词工程拆成五个真正决定效果的要素每个要素都配上可以直接跑的代码示例让你看完就能动手改自己的提示词。1. 先搞清楚提示词工程到底在解决什么问题很多人把提示词工程理解成怎么跟AI说话这个理解不能说错但太浅了。提示词工程的本质是在不修改模型参数的前提下通过输入文本的设计来约束模型的输出空间。这句话听起来有点绕翻译成人话就是模型本身是个概率机器你给的每一个词都在影响它下一步往哪个方向走提示词工程就是想办法让这个方向尽可能落在你想要的区域里。1.1 为什么同一个模型换个问法效果差这么多大语言模型的工作原理是根据上文预测下一个token。你输入的提示词就是上文模型会根据这个上文计算下一个词的概率分布。提示词里多一个限定词、换一个句式、调整一下信息的排列顺序都会改变这个概率分布。举个我实际遇到的例子。我需要模型从一段用户反馈里提取产品问题最早的提示词是提取以下文本中的问题结果模型经常把用户的情感表达也当成问题提取出来比如这个功能太烂了它会提取成功能烂但我要的是具体的功能缺陷描述。后来我把提示词改成从以下用户反馈中提取具体的产品功能缺陷忽略用户的情感评价和主观感受提取准确率立刻上了一个台阶。差别就在于我通过提示词把问题这个词的语义空间收窄了排除了情感评价这个分支。1.2 提示词工程的边界在哪里这里必须说清楚一个事提示词工程不是万能的。它解决的是模型有能力做但不知道你要它怎么做的问题解决不了模型根本没这个能力的问题。比如你让一个纯文本模型去识别图片里的文字提示词写得再漂亮也没用。我一般用这个标准来判断该不该用提示词工程来解决如果换一个表达方式模型偶尔能给出正确结果那说明模型有这个能力提示词工程可以把它稳定下来如果无论怎么换说法模型都做不对那可能需要微调或者换模型别在提示词上死磕。提示判断一个任务是否适合用提示词工程解决先手动试五种以上不同的问法如果至少有一种能碰到正确答案那这个任务就值得优化提示词。2. 要素一任务指令的精确度决定输出下限任务指令是提示词里最核心的部分它告诉模型你要做什么。但精确这两个字说起来容易做起来难。我见过太多提示词写的是帮我分析一下这段文本这种指令的问题在于分析这个词太宽泛了模型可以给你做情感分析、主题分析、结构分析、词频分析它选哪个完全看运气。2.1 动词选择用具体动作替代抽象概念写任务指令的第一个原则是用具体动词替代抽象动词。下面这张表是我自己总结的常见抽象动词和对应的具体替代方案抽象动词问题具体替代方案分析范围太广不知道分析什么维度提取、分类、对比、统计、判断处理完全不知道要做什么操作翻译、改写、摘要、格式化、纠错优化优化目标不明确缩短到X字、改成正式语气、去除重复生成生成什么、什么格式、什么风格都不清楚按以下模板生成、生成X个选项、生成JSON格式这个表看起来简单但实际写提示词的时候特别管用。我现在的习惯是写完任务指令后把里面的动词圈出来问自己这个动词有没有歧义如果有就换成更具体的。2.2 用代码示例看指令精确度的实际影响下面用Python写一个对比示例同一个任务用模糊指令和精确指令分别调用你可以直接跑一下看效果差异import openai client openai.OpenAI(api_keyyour-api-key, base_urlyour-base-url) text 这款耳机的音质确实不错低音很饱满但是戴了半小时耳朵就开始疼了。 而且蓝牙连接偶尔会断特别是在人多的地方。续航倒是挺满意的能用一整天。 # 模糊指令 vague_prompt f帮我分析一下这段文本{text} # 精确指令 precise_prompt f从以下用户反馈中提取产品优缺点按以下要求输出 1. 优点和缺点分开列出 2. 每条不超过15个字 3. 只提取产品功能相关的评价忽略物流、客服等非产品因素 4. 输出格式为JSON{{pros: [], cons: []}} 用户反馈{text} def call_model(prompt): response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: prompt}], temperature0 ) return response.choices[0].message.content print( 模糊指令输出 ) print(call_model(vague_prompt)) print(\n 精确指令输出 ) print(call_model(precise_prompt))跑完你会发现模糊指令的输出可能是一大段文字格式每次都不一样而且可能把物流慢这种非产品因素也混进去。精确指令的输出则是结构化的JSON可以直接被下游程序消费。这就是指令精确度带来的差异。2.3 约束条件的写法把不要什么说清楚除了告诉模型要做什么还要告诉它不要做什么。这一点很多人会忽略。模型在生成内容的时候如果没有明确的排除条件它会倾向于把所有相关信息都塞进去导致输出冗余。我常用的约束条件写法有这么几类范围约束只考虑X不考虑Y。比如只提取产品功能相关的问题不考虑价格和物流长度约束每条不超过X字总共不超过X条。这个对控制输出长度特别有效格式约束必须输出JSON/XML/Markdown表格。格式约束越具体后续解析越省事风格约束用正式/口语/技术文档的语气。这个在做内容生成时很关键排除约束不要出现X、不要使用Y。比如不要使用总之、综上所述这类总结词注意约束条件不是越多越好。我试过在一个提示词里塞了十几条约束结果模型顾此失彼反而把核心任务做砸了。一般控制在5条以内比较稳妥超过的话考虑拆成多步调用。3. 要素二上下文信息的组织方式影响输出上限任务指令决定了模型做什么上下文信息决定了模型基于什么做。同样的指令给不同的上下文输出质量可能天差地别。但上下文不是越多越好关键是怎么组织。3.1 上下文的三层结构背景、示例、数据我把提示词里的上下文信息分成三层背景信息是告诉模型这个任务的业务场景是什么。比如你是一个电商平台的客服质检系统需要判断客服回复是否合规。背景信息不需要很长一两句话点明场景就行但它能帮模型激活相关的知识区域。示例信息就是少样本提示few-shot给模型看几个输入输出的例子。这是提升输出稳定性的利器后面会专门讲。数据信息是这次任务实际要处理的内容。数据信息的位置很关键我一般放在提示词的最后紧挨着输出指令。因为模型对靠近末尾的内容注意力更集中。3.2 信息排列顺序的实测对比我做过一个简单的对比实验同样的背景、示例、数据只改变排列顺序看输出质量的变化。任务是根据用户评论判断情感倾向并提取关键词。排列方式A背景→数据→示例→输出指令 排列方式B背景→示例→数据→输出指令 排列方式C示例→背景→输出指令→数据实测下来方式B的准确率最高方式C最差。原因也不难理解示例放在数据前面模型可以先从示例里学到模式再应用到数据上数据放在最后紧挨着输出指令模型处理完数据立刻就要输出注意力最集中。方式C把数据放在最后但输出指令在数据前面模型可能还没看完数据就开始生成输出了。这个实验样本不大但和我后来在多个任务上的观察是一致的。所以我现在写提示词的默认结构就是背景→示例→数据→输出指令。3.3 用分隔符把不同信息块隔开当提示词里包含多种信息时一定要用明确的分隔符把它们隔开否则模型可能把示例数据当成真实数据来处理。常用的分隔符有三引号、XML标签、Markdown标题等。prompt 你是一个情感分析助手。 ## 示例 输入这个产品质量很好物流也快 输出{sentiment: positive, keywords: [产品质量, 物流]} 输入用了三天就坏了客服还不理人 输出{sentiment: negative, keywords: [质量, 客服]} ## 待分析数据 输入{user_input} ## 输出要求 严格按照示例的JSON格式输出不要添加任何额外说明。 用##标题做分隔的好处是模型对Markdown结构很敏感能清楚区分不同区块。XML标签比如example、data效果也不错特别是在Claude系列模型上。三引号适合包裹大段文本数据。4. 要素三少样本提示的示例选择比数量更重要少样本提示Few-shot Prompting是提示词工程里性价比最高的技巧之一。给模型看几个例子它就能模仿例子的模式来处理新输入。但很多人用少样本提示的时候有个误区觉得例子越多越好其实不是。4.1 示例数量的边际效应我做过一组测试同一个分类任务分别给0、1、3、5、10个示例看准确率变化示例数量准确率备注072%零样本模型靠自己的理解181%提升明显模型有了模仿对象389%提升放缓但仍有收益591%接近饱和1091%基本没有额外提升还增加了token消耗从1到3的提升最大3到5还有一点5以上基本就饱和了。所以我的建议是3到5个示例是性价比最高的区间。当然这个数字不是绝对的任务越复杂、输出格式越特殊需要的示例可能越多但一般不超过8个。4.2 示例的多样性比数量关键比数量更重要的是示例的多样性。如果你的5个示例都是同一种情况模型学到的模式就很窄遇到稍微不同的输入就懵了。选示例的时候我一般遵循这几个原则覆盖不同类别如果是分类任务每个类别至少一个示例包含边界情况那些容易混淆的、模棱两可的情况要放进去难度递进从简单到复杂排列让模型看到处理难例的方式格式一致所有示例的输入输出格式必须完全一致不能有的用JSON有的用纯文本4.3 示例的输入输出格式设计示例的格式设计有个技巧输出格式要和你期望模型输出的格式完全一致。如果你希望模型输出JSON示例的输出就必须是JSON不能是情感是正面的这种自然语言描述。few_shot_prompt 判断以下评论的情感倾向并提取关键词。 示例1 输入屏幕清晰度很高看视频很爽 输出{sentiment: positive, keywords: [屏幕, 清晰度]} 示例2 输入电池续航太差了半天就没电 输出{sentiment: negative, keywords: [电池, 续航]} 示例3 输入价格还行但是做工一般般 输出{sentiment: neutral, keywords: [价格, 做工]} 现在处理 输入{new_input} 输出注意示例3这是一个中性情感的边界情况价格满意但做工不满意整体情感偏中性。这种边界示例能帮模型学会处理模棱两可的情况。提示示例里的输出不要有错别字或格式错误模型会忠实模仿你给的格式包括错误。我踩过这个坑示例里JSON少了个引号结果模型输出也经常少引号。5. 要素四思维链的触发方式决定复杂推理的成败思维链Chain of Thought是让模型在给出最终答案之前先展示推理过程的技术。对于需要多步推理的任务思维链能显著提升准确率。但思维链不是简单加一句让我们一步步思考就完事了触发方式很讲究。5.1 零样本思维链和少样本思维链的区别零样本思维链就是在提示词末尾加一句请一步步思考或者Lets think step by step。这种方式实现简单对很多任务都有效但效果不稳定。少样本思维链是在示例里展示推理过程让模型模仿这种推理方式。比如cot_prompt 判断以下数学应用题的计算结果是否正确。 示例 题目小明有5个苹果吃了2个又买了3个现在有几个 计算过程5 - 2 33 3 6 答案6个 判断正确 题目一箱牛奶有12盒喝了3盒又买了2箱现在有几盒 计算过程12 - 3 92箱 24盒9 24 33 答案33盒 判断正确 现在判断 题目{question} 计算过程{process} 答案{answer} 判断少样本思维链的效果通常比零样本好因为模型不仅知道要推理还知道按什么格式推理。但代价是提示词更长token消耗更多。5.2 思维链的触发词选择触发词的选择也有讲究。我测试过几种常见的触发词触发词效果适用场景让我们一步步思考通用性好大多数推理任务请展示你的推理过程输出更详细需要检查推理步骤的场景先分析再回答简洁简单推理任务逐步分析并给出理由输出最长需要详细解释的场景实测下来让我们一步步思考的通用性最好但输出可能比较简短。请展示你的推理过程会让模型输出更详细的步骤适合需要人工检查推理链的场景。5.3 思维链的隐藏与展示在实际产品里思维链内容要不要展示给用户是个需要权衡的问题。展示的好处是用户能看到推理过程增加信任感坏处是输出变长而且推理过程可能有错反而让用户困惑。我的做法是内部用思维链提升准确率但最终输出只给结果。实现方式是在提示词里要求模型先输出推理过程然后用分隔符隔开最后输出结果程序解析的时候只取结果部分。prompt 请先逐步分析然后给出最终答案。 分析过程和最终答案之间用---分隔。 问题{question} 分析 response call_model(prompt) # 解析时只取分隔符后面的内容 final_answer response.split(---)[-1].strip()这样既利用了思维链提升准确率又保证了最终输出的简洁。6. 要素五输出格式的约束精度影响下游可用性提示词工程的最终产出是要被使用的。如果是给人看格式要求可以宽松一些如果是给程序解析格式必须严格约束。我见过太多项目在提示词上花了很多功夫结果因为输出格式不稳定下游解析天天报错。6.1 结构化输出的三种约束方式方式一自然语言描述格式。就是用文字说明你要什么格式比如请输出JSON格式包含name和age两个字段。这种方式最灵活但模型有时候会加一些额外的解释文字导致JSON解析失败。方式二提供格式模板。给模型一个具体的模板让它填充。比如prompt 提取以下文本中的个人信息严格按照模板输出 模板 姓名[姓名] 年龄[年龄] 职业[职业] 文本{text} 这种方式比自然语言描述稳定但模型仍可能在模板外添加内容。方式三使用API的结构化输出功能。现在很多模型API支持JSON mode或者function calling可以从底层保证输出格式。比如OpenAI的response_format参数response client.chat.completions.create( modelgpt-4o, messages[{role: user, content: prompt}], response_format{type: json_object} )这种方式最可靠但需要API支持而且模型必须理解JSON格式。我一般优先用这种方式不行再退回模板方式。6.2 格式约束的常见坑坑一JSON里的中文引号。模型有时候会输出中文引号而不是英文引号导致JSON解析失败。解决办法是在提示词里明确说使用英文引号。坑二多余的解释文字。模型经常在JSON前后加一句好的以下是提取结果。解决办法是在提示词里加一句直接输出JSON不要添加任何解释文字。坑三字段缺失。模型可能漏掉某个字段。解决办法是在提示词里强调所有字段都必须输出没有信息则填null。坑四嵌套结构不稳定。如果要求输出嵌套JSON模型有时候会把嵌套层级搞错。这种情况建议拆成多步调用先提取平铺结构再用代码组装嵌套结构。6.3 输出格式的验证与重试即使提示词写得再好模型偶尔还是会输出格式错误的内容。所以在工程上一定要有格式验证和重试机制。import json def call_with_retry(prompt, max_retries3): for i in range(max_retries): response call_model(prompt) try: # 尝试解析JSON # 先清理可能的markdown代码块标记 cleaned response.strip() if cleaned.startswith(json): cleaned cleaned[7:] if cleaned.endswith(): cleaned cleaned[:-3] result json.loads(cleaned.strip()) return result except json.JSONDecodeError: if i max_retries - 1: # 重试时在提示词里加上错误信息 prompt prompt f\n\n上次输出格式错误请确保输出合法的JSON。 else: raise ValueError(f重试{max_retries}次后仍无法解析JSON)这个重试机制在实际项目里救过我很多次。特别是处理批量数据的时候总有几个case模型会抽风有了重试机制就不用人工干预了。7. 把五个要素串起来一个完整的实战案例前面讲了五个要素现在用一个完整的案例把它们串起来。任务是从电商评论中提取产品问题并分类输出结构化数据供后续分析。7.1 完整提示词的设计过程先明确任务输入是一条用户评论输出是产品问题列表每个问题包含问题描述和问题类别。第一步写任务指令。不能写分析评论要写从评论中提取产品功能相关的问题并按类别分类。第二步准备上下文。背景是电商平台的产品评论分析系统示例准备3个覆盖质量、功能、外观三个类别。第三步设计示例。每个示例包含输入评论和输出JSON输出格式要统一。第四步加入思维链。对于复杂的评论让模型先判断哪些是产品问题再进行分类。第五步约束输出格式。用JSON格式明确字段名和字段类型。完整的提示词如下system_prompt 你是一个电商平台的产品评论分析系统。 你的任务是从用户评论中提取产品功能相关的问题并进行分类。 问题类别定义 - quality质量问题如破损、材质差 - function功能问题如无法连接、操作复杂 - appearance外观问题如颜色偏差、做工粗糙 - durability耐用性问题如用几天就坏 请先分析评论中哪些内容属于产品问题然后对每个问题进行分类。 示例1 输入耳机音质不错但是戴久了耳朵疼而且蓝牙经常断连 分析提到两个产品问题一是佩戴舒适度属于appearance二是蓝牙连接属于function 输出{issues: [{desc: 戴久了耳朵疼, category: appearance}, {desc: 蓝牙经常断连, category: function}]} 示例2 输入用了不到一周屏幕就出现坏点质量太差了 分析屏幕坏点属于质量问题 输出{issues: [{desc: 屏幕出现坏点, category: quality}]} 示例3 输入外观挺好看的就是电池不太行半天就要充电 分析电池续航问题属于function 输出{issues: [{desc: 电池续航差, category: function}]} 现在处理以下评论严格按照示例的JSON格式输出不要添加任何解释文字 输入{comment} 输出7.2 效果验证与迭代这个提示词上线后我拿100条真实评论做了测试准确率大概在85%左右。主要错误集中在两类一是把非产品问题比如物流慢也提取进来了二是类别判断错误把耐用性问题归到了质量问题。针对第一个问题我在提示词里加了一句只提取产品本身的问题忽略物流、客服、价格等非产品因素。针对第二个问题我在类别定义里加了更具体的例子比如durability下面加了用几天就坏、寿命短。改完之后准确率提升到了92%左右。这个迭代过程说明提示词工程不是一次写完就完事的需要根据实际bad case不断调整。7.3 工程化落地的注意事项最后说几个工程化落地的经验温度参数设置。提取类任务建议temperature设为0或接近0保证输出稳定。生成类任务可以适当调高增加多样性。批量处理的分批策略。如果要处理大量数据不要一次性发太多请求注意API的速率限制。我一般用并发控制同时发5到10个请求根据API响应调整。日志记录。每次调用的输入、输出、token消耗都要记录方便排查问题和优化成本。特别是提示词迭代的时候没有日志根本不知道改之前和改之后差在哪。版本管理。提示词要像代码一样做版本管理。我一般用git管理提示词文件每次修改都提交commit message写清楚改了什么、为什么改。成本控制。提示词越长token消耗越大。少样本示例虽然有效但每个示例都要消耗token。如果调用量很大要考虑示例数量和成本之间的平衡。我一般会算一下每个示例带来的准确率提升和token成本增加的比例选择性价比最高的示例数量。注意提示词工程不是一劳永逸的事。模型版本更新、业务场景变化、数据分布漂移都会导致原本好用的提示词效果下降。建议定期用测试集跑一下监控准确率变化。这套方法论我在多个项目里用过从简单的文本分类到复杂的多步推理基本都能覆盖。核心思路就是把模糊的需求拆成精确的指令用示例锚定输出模式用思维链处理复杂推理用格式约束保证下游可用。每个要素单独看都不复杂但组合起来能解决大部分提示词效果不稳定的问题。
返回列表