一次性写出完美的提示词是很少见的。多数情况下,初次尝试的提示词生成的输出虽然接近,但总有些不足,可能缺少细节、信息编造、格式错误,或者未能严格遵守指令。迭代式提示词优化是一个系统性的流程,它通过分析这些不足,并对提示词进行有针对性的调整,来逐步提升大型语言模型(LLM)的输出质量和可靠性。这更像是一种有条不紊的实验,而非奇迹。这个流程通常遵循一个循环:生成输出,根据要求进行评估,找出具体问题,提出一项旨在修正问题的提示词修改设想,修改提示词,然后再次测试。这个循环会重复进行,直到输出持续满足您应用的预期标准。提示词优化循环采用结构化的方法对高效优化很重要。同时修改提示词的太多方面,会让人难以弄清是哪个改动带来了性能的提升或下降。因此,应采纳一个侧重于逐步调整的循环:分析输出: 使用一个或多个代表性输入运行当前提示词。仔细检查大型语言模型的响应。它是否满足所有要求?哪里不符?具体说明:是过于冗长?格式不正确?是否误解了某个特定指令?是否存在事实错误?提出设想: 根据已发现的问题,提出一个具体的理由,说明提示词为何可能引起该问题。例如,“‘总结文本’这条指令过于模糊,导致输出内容过长。”然后,就某个具体的修改形成设想:“添加‘将文本总结为50字以内’的限制,会生成更短的摘要。”修改提示词: 根据您的设想,对提示词实施一项有针对性的修改。抵制一次性调整多个元素的冲动。这种隔离有助于将结果直接归因于该项改动。测试与评估: 执行修改后的提示词,最好使用之前产生缺陷输出的相同输入。将新响应与旧响应以及您的预期结果进行比较。该改动是否产生了预期效果?是否引入了任何新问题?迭代:如果修改成功,且没有出现新问题,您可以保留该改动,然后继续处理其他问题,从第1步重新开始循环。如果修改改善了输出,但未能完全解决问题,您可能需要进一步完善该修改(例如,将“50字”改为“3句话”)。如果修改没有效果或使情况变糟,请放弃它(这时跟踪提示词版本就很重要了,我们将在后面讨论),并提出一个新的设想(第2步)。这个系统性的循环将提示词工程从猜测转变为一种更具科学性的观察、设想验证和优化流程。digraph RefinementCycle { rankdir=LR; node [shape=box, style=rounded, fontname="sans-serif", color="#495057", fontcolor="#495057"]; edge [color="#868e96"]; splines=true; new_rank=true; "分析\n输出" -> "提出\n设想" -> "修改\n提示词" -> "测试与\n评估" -> "迭代\n(保留/完善/放弃)" -> "分析\n输出" [label=" 重复循环 ", fontname="sans-serif", fontsize=10, fontcolor="#495057", color="#adb5bd"]; }一个典型的提示词迭代优化循环。常见优化策略在“修改提示词”这一步,可以运用几种方法:提高清晰度和具体性: 模糊的指令通常导致含糊不清或不理想的输出。使用更清晰的语言、更强的动词和明确的限制来重新措辞指令。初始: “解释这个原理。”优化后: “用简单的话语解释光合作用的原理,适合高中生阅读。将解释限制在三个段落内。”添加示例(少样本提示): 如果模型仅凭指令(零样本)难以处理任务格式或风格,可在提示词中提供一个或多个高质量示例。仔细选择与您预期输入类型所需输出结构和内容紧密相似的示例。这会使用大型语言模型的上下文学习能力。调整格式提示: 有时,对提示词结构进行的细微调整可以指导模型。尝试使用Markdown(如标题#、列表* -)、XML标签(<example>、</example>)、JSON片段或不同的分隔符(###)来区分指令、上下文、输入数据和预期输出格式。明确说明限制(否定限制): 告诉模型不要做什么。这对于防止常见失败情况会非常有效。示例: “总结以下文本。不要包含任何个人观点或解释。不要以‘本文讨论…’之类的短语开头。”角色提示调整: 如果您正在使用角色提示(例如分配一个“您是一个乐于助人的助手”这样的人格),并且结果不太对劲,请尝试完善角色的描述,使其更具体地符合预期行为或专业知识。任务分解: 如果一项任务对于单个提示词而言过于复杂,请考虑将其分解为更小、按顺序进行的子任务。每个子任务可以有自己优化的提示词,并可能将一个步骤的输出作为下一个步骤的输入。这符合在后面关于大型语言模型框架章节中讨论的“链”的思路。参数调整: 虽然本节侧重于提示词内容,但请记住,temperature或top_p等生成参数(在第1章讨论过)会与您的提示词互相作用。如果一个优化的提示词生成的输出过于可预测或过于随机,尝试调整这些参数可以是一种补充的优化步骤。不过,在严重依赖参数调整之前,请先尝试稳定提示词内容。系统性实验与记录高效优化依赖于严谨性:隔离修改: 如前所述,每次迭代只修改提示词的一个方面。如果您既修改了指令,又添加了示例,还调整了温度,您将无法知道是哪个改动导致了观察到的任何改进或下降。使用测试集: 不要仅依赖单个输入进行测试。准备一套小而多样化的测试用例,涵盖典型情况、潜在的极端情况以及先前导致失败的输入。评估此测试集上的性能,可以增加您对优化后的提示词可靠性的信心。记录版本: 记录您的提示词变体及其性能。简单的文本文件、电子表格或专用的版本控制系统(如Git,后面会讲到)都是不可或缺的。这使得您可以轻松比较版本,如果某个改动被证明有害,可以回溯到之前可用的提示词,并记录特定修改背后的原因。优化场景示例我们来看一个简单的例子。假设您需要一个大型语言模型从客户反馈邮件中提取具体信息,并将其格式化为JSON。输入邮件: “你好客服,我的订单#12345收货时损坏了。屏幕裂了。我想让你们寄一个替换品到我的存档地址。我的账号邮箱是user@example.com。谢谢,Alex。”初始提示词(尝试1):Extract the order number, issue, desired resolution, and customer email from the following text. Format as JSON. Text: "{email_text}"输出(尝试1):{ "order": "12345", "problem": "arrived damaged, screen cracked", "resolution": "replacement", "customer": "user@example.com" }分析(尝试1): 它运行得相当好,但键名(“order”、“problem”、“resolution”、“customer”)过于通用。我们希望使用更具体的键名。设想: 在提示词中明确定义带有目标键名的所需JSON结构,将能更好地指导模型。修改后的提示词(尝试2):Extract the following information from the customer email and format it as a JSON object with the keys "orderId", "reportedIssue", "requestedAction", and "customerEmail". Desired JSON format: { "orderId": "...", "reportedIssue": "...", "requestedAction": "...", "customerEmail": "..." } Email Text: "{email_text}"输出(尝试2):{ "orderId": "12345", "reportedIssue": "arrived damaged. The screen is cracked.", "requestedAction": "replacement sent", "customerEmail": "user@example.com" }分析(尝试2): 效果好很多。键名符合要求。reportedIssue更完整,requestedAction也稍微更具描述性。对于需要特定字段名称的下游处理来说,这个版本更可靠。“这个简单的例子表明,识别一个具体不足(通用键名)如何引出一个设想(明确的结构定义)以及一个有针对性的修改,从而带来可衡量的输出改进。优化通常涉及更多循环并处理更复杂的问题,但其基本原理保持不变:分析、设想、修改、测试,然后重复。”