May 24, 2024
CO-STAR 框架构建提示语结构
有效的提示结构对于从 LLM 获得最佳回复至关重要。CO-STAR 框架是新加坡政府科技部数据科学与人工智能团队的心血结晶,是构建提示的模板。考虑到了影响法律硕士回答的有效性和相关性的所有关键方面,从而使回答更加优化。
具体如下,
(C)背景:提供任务的背景信息,这有助于 LLM 了解正在讨论的具体情景,确保其答复具有相关性。
(O)目标:确定你希望 LLM 执行的任务是什么。明确你的目标有助于 LLM 将其回答的重点放在实现这一特定目标上。
(S)风格:指明你希望 LLM使用的写作风格。可以是某个名人的写作风格,也可以是某个行业的某个专家,如商业分析专家或首席执行官。这将引导法律硕士以符合您需求的方式和用词做出回应。
(T)语气:确定回复的态度。这可确保 LLM 的回复与所需的情感或情绪背景产生共鸣。例如,正式、幽默、感同身受等。
(A)受众:确定回应的对象。根据受众(如某一领域的专家、初学者、儿童等)量身定制法 LLM的回复,确保其在所需的语境中是恰当和可以理解的。
(R)回答:提供回复格式。确保 LLM 以下游任务所需的准确格式输出。例如,列表、JSON、专业报告等。对于大多数以编程方式处理 LLM 响应以进行下游操作的 LLM 应用程序来说,理想的输出格式是 JSON。
使用分隔符将提示分段
分隔符是一种特殊的标记,可帮助 LLM 区分提示语的哪些部分应被视为一个单元。这一点很重要,因为整个提示信息是作为一长串标记符到达 LLM 的。分隔符通过对提示语的特定部分进行区别对待,为这一语序提供了结构。
值得注意的是,对于简单的任务,分隔符可能不会影响 LLM 的回复质量。但是,任务越复杂,使用分隔符进行分段对 LLM 回答的影响就越大。
使用 LLM Guardrails 创建系统提示
在开始学习之前,需要注意的是本节只与具有系统提示功能的 LLM 相关,而本文的其他章节则与任何 LLM 相关。具有此功能的最著名 LLM 当然是 ChatGPT,我们将使用 ChatGPT 作为本节的示例。
- 围绕系统提示的术语。
首先,让我们来理清术语:关于 ChatGPT,有大量资源几乎可以互换使用这三个术语:"系统提示"、"系统消息 "和 "自定义指令"。这让很多人感到困惑,以至于 OpenAI 发布了一篇文章来解释这些术语。以下是其摘要:
"系统提示 "和 "系统消息"是通过聊天完成 API 以编程方式与 ChatGPT 进行交互时使用的术语。
另一方面,"自定义指令 "是通过 https://chat.openai.com/ 用户界面与 ChatGPT 交互时使用的术语。
不过总的来说,这三个术语指的是同一件事,所以不要被术语混淆了!今后,本节将使用 "系统提示 "一词。现在,让我们进入正题!
- 什么是系统提示?
系统提示是一种附加提示,您可以在其中提供有关 LLM 行为方式的指令。系统提示被认为是额外的,因为它不属于对 LLM 的 "正常 "提示(即用户提示)。
在聊天中,每次您提供新提示时,系统提示都会像过滤器一样,让 LLM 在回复您的新提示前自动应用。这意味着 LLM 在聊天中的每次回复都会考虑到系统提示。
- 何时使用系统提示?
您首先想到的问题可能是:既然我也可以在与 LLM 进一步交谈之前,在新聊天的第一次提示中提供说明,为什么还要在系统提示中提供说明呢?
答案是,因为 LLM 的对话内存是有限的。在后一种情况下,随着对话的进行,LLM 很可能会 "忘记 "您为聊天提供的第一条提示,从而使这些指令过时。
另一方面,如果在系统提示中提供了指令,那么这些系统提示指令就会与聊天中的每个新提示一起被自动考虑。这可以确保 LLM 在聊天过程中继续接收这些指令,无论聊天时间变得多长。
即,在整个聊天过程中使用系统提示提供您希望 LLM 在回复时记住的指令。
例如,系统提示可能是这样的
您将使用此文本回答问题:[插入文本]。
您将以这种格式回复一个 JSON 对象:{"问题":"答案"}。
如果文本中没有足够的信息来回答问题,请不要编造信息,并将答案填写为 "NA"。
您只能回答与[插入范围]相关的问题。切勿回答任何与年龄、性别和宗教信仰等人口统计信息相关的问题。
- 系统提示应包括哪些内容?
- 任务定义,LLM 就能在整个聊天过程中始终记住要做什么。
- 输出格式,LLM 始终记住应该如何回复。
- 防护栏, LLM 就能始终记住它应该如何不回应,指的是 LLM 允许在其中运行的配置边界。
通常包括以下几类,
举例如下,
You will answer questions using this text: [insert text].
- “正常”的聊天提示又是什么呢?
现在可能会想:看起来系统提示中已经提供了很多信息。那我应该在聊天的 "正常 "提示(即用户提示)中写些什么呢?
系统提示概述了当前的一般任务。在上面的系统提示示例中,任务被定义为只使用特定文本回答问题,并且 LLM 被指示以 {"问题":"答案"}。
系统提示应给出总体任务指令,而每个用户提示应提供您希望使用的任务执行的具体细节。
提示工程示例
- 将复杂的任务分解成简单的步骤
- 参考每个步骤的中间输出
- 编写LLM答复的格式
- 将指令与数据集分开
System Prompt: I want you to act as a data scientist to analyze datasets. Do not make up information that is not in the dataset. For each analysis I ask for, provide me with the exact and definitive answer and do not provide me with code or instructions to do the analysis on other platforms. Prompt: # CONTEXT # I sell wine. I have a dataset of information on my customers: [year of birth, marital status, income, number of children, days since last purchase, amount spent]. ############# # OBJECTIVE # I want you use the dataset to cluster my customers into groups and then give me ideas on how to target my marketing efforts towards each group. Use this step-by-step process and do not use code: 1. CLUSTERS: Use the columns of the dataset to cluster the rows of the dataset, such that customers within the same cluster have similar column values while customers in different clusters have distinctly different column values. Ensure that each row only belongs to 1 cluster. For each cluster found, 2. CLUSTER_INFORMATION: Describe the cluster in terms of the dataset columns. 3. CLUSTER_NAME: Interpret [CLUSTER_INFORMATION] to obtain a short name for the customer group in this cluster. 4. MARKETING_IDEAS: Generate ideas to market my product to this customer group. 5. RATIONALE: Explain why [MARKETING_IDEAS] is relevant and effective for this customer group. ############# # STYLE # Business analytics report ############# # TONE # Professional, technical ############# # AUDIENCE # My business partners. Convince them that your marketing strategy is well thought-out and fully backed by data. ############# # RESPONSE: MARKDOWN REPORT # <For each cluster in [CLUSTERS]> — Customer Group: [CLUSTER_NAME] — Profile: [CLUSTER_INFORMATION] — Marketing Ideas: [MARKETING_IDEAS] — Rationale: [RATIONALE] <Annex> Give a table of the list of row numbers belonging to each cluster, in order to back up your analysis. Use these table headers: [[CLUSTER_NAME], List of Rows]. ############# # START ANALYSIS # If you understand, ask me for my dataset.
技巧1:将复杂任务分解成简单步骤
LLM 擅长完成简单的任务,但对复杂的任务却不太擅长。因此,对于像这样的复杂任务,重要的是要将任务分解成简单的步骤说明,让 LLM 遵循。这样做的目的是让LLM了解您自己在执行任务时会采取的步骤。
比如如下例子,
- 聚类:使用数据集的列对数据集的行进行聚类,使同一聚类中的客户具有相似的列值,而不同聚类中的客户具有明显不同的列值。确保每一行只属于一个聚类。对于找到的每个聚类
- CLUSTER_INFORMATION:根据数据集列描述聚类。
- CLUSTER_NAME:解释 [CLUSTER_INFORMATION] 以获得该群集中客户群的简短名称
- marketing_ideas:产生向该客户群推销我的产品的想法。
- RATIONALE: 解释为什么 [MARKETING_IDEAS] 与该客户群相关且有效。
技巧 2:引用每一步的中间产出
在向 LLM 提供分步流程时,我们会给每个步骤的中间输出一个大写的 VARIABLE_NAME,即 CLUSTERS、CLUSTER_INFORMATION、CLUSTER_NAME、MARKETING_IDEAS 和 RATIONALE。
使用大写字母是为了将这些变量名与给出的指令正文区分开来。以后可以用方括号[VARIABLE_NAME]来引用这些中间输出。
技巧 3:规范 LLM 回复的格式
在这里,我们要求使用 markdown 报告格式,以美化 LLM 的响应。在这里,中间输出中的变量名又派上了用场,可以决定报告的结构。
# RESPONSE: MARKDOWN REPORT #
<For each cluster in [CLUSTERS]>
— Customer Group: [CLUSTER_NAME]
— Profile: [CLUSTER_INFORMATION]
— Marketing Ideas: [MARKETING_IDEAS]
— Rationale: [RATIONALE]
<Annex>
Give a table of the list of row numbers belonging to each cluster, in order to back up your analysis. Use these table headers: [[CLUSTER_NAME], List of Rows].
技巧 4:将任务指令与数据集分开
您会注意到,在第一个提示中,我们从未将数据集交给 LLM。相反,提示中只给出了数据集分析的任务说明,并将其添加到了底部:
# START ANALYSIS #
If you understand, ask me for my dataset.
但为什么要将说明与数据集分开呢?
这样做可以帮助 LLM 保持对每条指令的清晰理解,降低遗漏信息的可能性,尤其是像本任务这样指令较长的复杂任务。您可能遇到过这样的情况,即 LLM "不小心遗忘 "了您作为较长提示的一部分给出的某个指令
例如,如果您要求给出 100 字的回复,而 LLM 给您的回复是一个较长的段落。通过先接收指令,再接收指令所针对的数据集,LLM 可以先消化它应该做的事情,然后再对接下来提供的数据集执行指令。
不过请注意,只有聊天 LLM 才能实现指令和数据集的分离,因为聊天 LLM 会保留会话记忆,而完成 LLM 则不会。