面向开发者的提示工程
type
Post
status
Published
summary
之前写过《面向使用者的提示工程》,主要是面向普通用户,在日常使用大语言模型聊天或对话的时候应该如何书写提示词,来改善大模型输出的效果。而本篇主要是面向开发者,介绍在开发 RAG 类基于大模型的应用时应该如何优化和改善提示词,针对特定任务构造能充分发挥大模型能力的 Prompt 的技巧
slug
llms-prompt-for-developer
date
Mar 18, 2024
tags
LLMs
Prompt
提示词
大语言模型
category
大语言模型
password
icon
URL
Property
Apr 12, 2024 11:44 AM
一、导读
之前写过《面向使用者的提示工程》,主要是面向普通用户,在日常使用大语言模型聊天或对话的时候应该如何书写提示词,来改善大模型输出的效果。而本篇主要是面向开发者,介绍在开发 RAG 类基于大模型的应用时应该如何优化和改善提示词,针对特定任务构造能充分发挥大模型能力的 Prompt 的技巧
整理自:
二、提示原则
2.1、原则一:编写清晰、具体的指令
2.1.1、使用分隔符清晰地表示输入的不同部分
作用:
- 将不同的部分进行分割,避免混淆
- 避免词注入(用户输入的文本可能与预设的 prompt 冲突,可能导致可以直接通过输入操控语言模型、或者干扰模型而得出较差的效果)
示例:
2.1.2、寻求结构化的输出
有时候我们需要语言模型给我们一些结构化的输出,如JSON、HTML等,而不仅仅是连续的文本。
示例
2.1.3、要求模型检查是否满足条件
如果任务包含不一定能满足的假设(条件),我们可以告诉模型先检查这些假设。
示例
2.1.4、提供少量示例
给模型一两个已完成的样例,让模型了解我们的要求和期望的输出样式
示例
2.2、原则二:给模型时间去思考
如果让语言模型匆忙给出结论,其结果很可能不准确。例如,若要语言模型推断一本书的主题,仅提供简单的书名和一句简介是不足够的。
应通过 Prompt 指引语言模型进行深入思考。可以要求其先列出对问题的各种看法,说明推理依据,然后再得出最终结论。在 Prompt 中添加逐步推理的要求,能让语言模型投入更多时间逻辑思维,输出结果也将更可靠准确。
2.2.1、指定完成任务所需的步骤
示例
2.2.2、指导模型在下结论之前找出一个自己的解法
还可以通过明确指导语言模型进行自主思考,来获得更好的效果。
假设我们要语言模型判断一个数学问题的解答是否正确,可以在 Prompt 中先要求语言模型自己尝试解决这个问题,思考出自己的解法,然后再与提供的解答进行对比,判断正确性。这种先让语言模型自主思考的方式,能帮助它更深入理解问题,做出更准确的判断。
示例
大语言模型可能会产生幻觉问题(自行构造出似是而非的细节),由于幻觉信息往往令人无法辨别真伪,开发者必须警惕并尽量避免它的产生。
可以先让语言模型直接引用文本中的原句,然后再进行解答。这可以追踪信息来源,降低虚假内容的风险。
三、迭代优化
以下是一些常见的问题可供参考
- 生成文本太长
- 优化:使用最多50个词
- 问题:精度不会很准,但是接近预设长度,需要多次尝试
- 细节处理错误:细节信息错误,侧重角度不对等
- 请对三个反引号之间的评论文本进行概括,最多30个字,并且侧重在快递服务上。
- 请对三个反引号之间的评论文本进行概括,最多30个词汇,并且侧重在产品价格和质量上。
- 指定输出格式
- 优化:在描述之后,包括一个表格,提供产品的尺寸。表格应该有两列。第一列包括尺寸的名称。第二列只包括英寸的测量值。
四、任务类型
使用上面提到的优化迭代方法进行不断的优化和迭代;
4.1、文本概括
示例:单一文本概括
多条文本概括
for 循环、整合品论、分布式
4.2、推断
示例:情感分类
示例:信息提取
示例:信息提取和情感分析
示例:推断主题
示例:推断主题并判断
4.3、文本转换
示例:文本翻译
示例:识别语种
示例:写作语气与风格调整
示例:文件格式转换
示例:拼写及语法纠正
示例:综合案例
4.4、 文本扩展
示例:定制客户邮件
根据客户的评价和其中的情感倾向,使用大语言模型针对性地生成回复邮件。
4.5、聊天对话
像 ChatGPT 这样的聊天模型实际上是组装成以一系列消息作为输入,并返回一个模型生成的消息作为输出的。
示例:设置角色
示例:构建构建上下文
示例:订餐机器人
五、最佳实践
5.1、使用 CO-STAR 框架构建提示

CO-STAR是结构化的Prompt模版六大要素的首字母缩写,即:
- (C) Context 上下文:为任务提供背景信息 通过为大语言模型(LLM)提供详细的背景信息,可以帮助它精确理解讨论的具体场景,确保提供的反馈具有相关性。
- (O) Objective 目标:明确你要求大语言模型完成的任务 清晰地界定任务目标,可以使大语言模型更专注地调整其回应,以实现这一具体目标。
- (S) Style 风格:明确你期望的写作风格 你可以指定一个特定的著名人物或某个行业专家的写作风格,如商业分析师或 CEO。这将指导大语言模型以一种符合你需求的方式和词汇选择进行回应。
- (T) Tone 语气:设置回应的情感调 设定适当的语气,确保大语言模型的回应能够与预期的情感或情绪背景相协调。可能的语气包括正式、幽默、富有同情心等。
- (A) Audience 受众:识别目标受众 针对特定受众定制大语言模型的回应,无论是领域内的专家、初学者还是儿童,都能确保内容在特定上下文中适当且容易理解。
- (R) Response响应:规定输出的格式 确定输出格式是为了确保大语言模型按照你的具体需求进行输出,便于执行下游任务。常见的格式包括列表、JSON 格式的数据、专业报告等。对于大部分需要程序化处理大语言模型输出的应用来说,JSON 格式是理想的选择。
场景:假设你是一名社交媒体经理,你需要帮助起草一篇 Facebook 帖子来宣传你公司的新产品。
基于CO-STAR框架的prompt:
5.2、使用分隔符给Prompt分段
善于利用分隔符,帮助大模型更好的理解提示内容。Prompt内容越复杂,分隔符的作用就越重要。分隔符可以自己设计,但不应与标点符号等相同,容易发生歧义,常见的分隔符可以是###、===、<<<>>>等。同时,也可以使用xml标签来分隔Prompt。
一个运用分隔符的示例:
该例子使用 ### 进行分段,并使用大写“EXAMPLE CONVERSATIONS”对话和“EXAMPLE OUTPUTS”以进行区分。Prompt最前面描述已经指出要分类的对话会使用 <<<CONVERSATIONS>>> 分隔,这些对话随后在提示的底部提供给 LLM,虽然没有任何解释性文本,但 LLM 可以理解这是它应该分类的对话,因为存在分隔符 <<< 和 >>>。
5.3、利用 LLM 防护措施创建系统提示
由于大模型记忆能力有限,对于需要重复设置的指令,可以通过OpenAI中的System Prompt设置,这些提示会和User Prompt合并后每次都提交给大模型,从而减少记忆丢失和提示繁琐的问题。一般可以设置以下类别:
- 任务定义: 这样 LLM 在整个聊天过程中始终记得它需要做什么。
- 输出格式: 这样 LLM 将始终记得它应该如何响应。
- 护栏: 这样 LLM 将始终记得它不应该如何响应。护栏指的是 LLM 允许操作的配置边界。比如一些避免提示攻击的一些防御性说明。
5.4、仅使用 LLM 分析数据集
大模型不擅长精确数学计算或复杂、基于规则的任务处理,但大模型擅长识别模式和趋势分析,这种能力源于它们在大量不同数据上的广泛训练,使它们能够识别可能并不那么明显的复杂模式。这使得它们非常适合基于数据集内模式查找的任务,能在更短的时间内产生比使用代码更好的结果。
例如:
- 异常检测:根据一个或多个列值识别偏离规范的异常数据点。
- 聚类:将具有相似特征的数据点分组到各个列中。
- 跨列关系:识别跨列的组合趋势。
- 文本分析(针对基于文本的列):基于主题或情感进行分类。
- 趋势分析(针对具有时间方面的数据集):识别列中跨时间段的模式、季节性变化或趋势。
示例《仅使用LLM分析 Kaggle 数据集 》:
Kaggle真实数据集(https://www.kaggle.com/datasets/imakash3011/customer-personality-analysis),该数据集是为客户个性分析准备,试图细分其客户群,以便更好地了解其客户。
5.4.1、具体操作流程:
1、系统配置及任务指令输入
System Prompt:
User Prompt:
2、GPT回答及用户提供待分析数据

3、GPT 生成分析报告
4、验证 LLM 的分析正确性
5.4.2、技巧总结
1、任务分解:
LLM擅长执行简单的任务,但不太擅长执行复杂的任务。因此,对于像这样的复杂任务,重要的是将任务分解成简单的、逐步的指令,供大型语言模型遵循。
与简单地将整体任务交给 LLM,例如这样的指令“将客户进行分组,然后给出针对每个组的营销策略”相比,通过逐步的指令,LLM 更有可能提供正确的结果。
2、引用LLM每个步骤生成中间输出
当向 LLM 提供每步过程时,将每个步骤的中间输出赋予一个大写的变量名,即 CLUSTERS、CLUSTER_INFORMATION、CLUSTER_NAME、MARKETING_IDEAS 和 RATIONALE。
使用大写字母是为了将这些变量名与给出的指令主体区分开来。这些中间输出稍后可以使用方括号引用为 [VARIABLE_NAME]。
3、格式化 LLM 的响应
在这里, LLM 的响应为 markdown 报告格式。同时,从中间输出中使用变量名来设定报告的结构也非常方便。
4、将任务指令与数据集分离
在第一个Prompt中从未将数据集提供给 LLM。相反,Prompt仅给出了数据集分析的任务说明,并添加了以下内容:
这样做的好处是帮助 LLM 更清晰地理解每个指令,降低遗漏信息的可能性,尤其是在像这样指令较长的复杂任务中。通过首先接收指令,然后再接收指令所针对的数据集,LLM 可以先消化它应该做什么,然后再在提供的数据集上执行它。