GPT提示工程
GPT最佳实践六个策略
拆解复杂任务

《GPT最佳实践 - 提升Prompt效果的六个策略》 (opens in a new tab)中,我们介绍了OpenAI官方发布的"GPT 最佳实践"指南的六个策略,其中第三个策略是“将复杂的任务拆分为更简单的子任务”。

就像在软件工程中将复杂系统分解为一组模块化组件一样,在提交给GPT模型的任务中也是如此。复杂任务往往比简单任务出错率更高。此外,复杂任务通常可以重新定义为一系列简单任务的工作流程,其中前置任务的输出作为后续任务的输入。

具体方法:

  • 使用意图分类来识别与用户查询最相关的指令
  • 对于需要很长会话的对话应用,总结或过滤之前的对话
  • 分段总结长文档,并递归构建成完整摘要

使用意图分类来识别与用户查询最相关的指令

对于需要大量独立指令集来处理不同情况的任务,首先对查询类型进行分类并使用该分类来确定需要哪些指令可能会更好。这可以通过定义与处理给定类别中的任务相关的固定类别和硬编码指令来实现。该过程也可以递归地应用,将任务分解为一系列阶段。这种方法的优点是每个查询仅包含执行任务下一阶段所需的指令,与使用单个查询执行整个任务相比,这可以降低错误率。这还可以降低成本,因为更多的提示(large prompts)运行成本也会更高。(这段描述比较抽象,结合下面的例子来理解会清楚很多)

示例1

例如,对于一个客户服务查询系统,可以按照以下方式进行更好的查询分类。

SYSTEM Prompt:

我们将向您提供客户服务查询,并将每个查询分为一级分类和二级分类。  
请你以JSON格式回答问题,并且JSON包含以下字段:一级和二级。  
示例回答:{"一级":"一般查询","二级":"定价"}

一级分类:计费、技术支持、账户管理或一般查询。

计费二级分类:
- 取消订阅或升级
- 添加付款方式
- 收费说明
- 对收费提出异议

技术支持二级分类:
- 故障排除
- 设备兼容性
- 软件更新

账户管理二级分类:
- 密码重置
- 更新个人信息
- 关闭账户
- 账户安全

一般查询二级分类:
- 产品信息
- 定价
- 反馈
- 人工交流

我们提几个问题,进行客户服务查询:

针对我们提出的4个问题,GPT对意图的识别都是正确的,效果很棒。

这种实现思路,非常适合用来实现智能客服,以及指令类型的应用系统。

USER
我需要让我的互联网再次工作起来。
ASSISTANT
{"一级":"技术支持","二级":"故障排除"}

USER
我忘记密码了
ASSISTANT
{"一级":"账户管理","二级":"密码重置"}

USER
我的软件兼容性有问题
ASSISTANT
{"一级":"技术支持","二级":"设备兼容性"}

USER
软件版本太旧了
ASSISTANT
{"一级":"技术支持","二级":"软件更新"}

示例2

根据客户查询的分类,可以向 GPT 模型提供一组更具体的指令来处理后续的步骤。例如,假设客户需要“故障排除”方面的帮助。

SYSTEM Prompt:

你将收到需要技术支持故障排查的客户服务咨询。请按照以下步骤帮助用户:

- 请他们检查所有进出路由器的电缆是否已连接。请注意,电缆随着时间的推移可能会变得松动,这是很常见的。
- 如果所有的电缆都已连接,但问题仍然存在,请询问他们使用的路由器型号是什么。
- 现在你将指导他们如何重启设备:
-- 如果型号是 MTD-327J,请建议他们按下红色按钮并保持5秒,然后等待5分钟后再测试连接的状态。
-- 如果型号是 MTD-327S,请建议他们拔下电源插头并重新插入,然后等待5分钟后再测试连接的状态。
- 如果客户在重启设备并等待5分钟后,问题仍然存在,请通过输出 {"IT support requested"} 将他们转接到IT支持服务。
- 如果用户开始提问与此话题无关的问题,那么请确认他们是否希望结束当前关于故障排除的聊天,并根据以下方案对他们的请求进行分类:


将客户的每个查询分为一级分类和二级分类。  
请你以JSON格式回答问题,并且JSON包含以下字段:一级和二级。  
示例回答:{"一级":"一般查询","二级":"定价"}

一级分类:计费、技术支持、账户管理或一般查询。

计费二级分类:
- 取消订阅或升级
- 添加付款方式
- 收费说明
- 对收费提出异议

技术支持二级分类:
- 故障排除
- 设备兼容性
- 软件更新

账户管理二级分类:
- 密码重置
- 更新个人信息
- 关闭账户
- 账户安全

一般查询二级分类:
- 产品信息
- 定价
- 反馈
- 人工交流

相比于第一个例子,本示例的Prompt要复杂许多,换做是人工都不一定能回答得很好,但是GPT的回复却非常的到位。

USER
我需要让我的互联网再次工作起来。
ASSISTANT
我明白你的困扰,让我们一步一步解决这个问题。

首先,你能检查一下连到路由器的电缆是否都已经连接好了吗? 这包括任何进入或离开路由器的电缆。时间长了,电缆可能会松动,这是很正常的。

USER
检查了,已经连接
ASSISTANT
好的,既然所有的电缆都已经连接好了,接下来我们需要了解一下你的路由器是什么型号。

USER
MTD-327S
ASSISTANT
好的,谢谢你提供了路由器的型号。对于MTD-327S这款路由器,我们需要做的是断电重启。

请你按照以下步骤操作:拔下电源插头,然后重新插入,然后等待5分钟后再测试网络连接的状态。

请先试一试,看看这样能不能解决你的问题。

USER
问题依然存在
ASSISTANT
{"IT support requested"}

USER
我忘记设备的密码了
ASSISTANT
{"一级":"账户管理","二级":"密码重置"}

对于需要很长会话的对话应用,总结或过滤之前的对话

由于 GPT 具有固定的上下文长度,因此用户和GPT之间的历史对话内容不能无限期地包含在上下文窗口中。

对于这个问题有多种解决方法,其中一种是对之前的对话进行总结。当输入内容的大小达到预定的阈值长度时,则触发对部分对话内容的总结,同时总结后的会话摘要可以作为系统提示信息的一部分。或者,可以在整个对话的过程中,在后台异步的总结之前的对话。

另一种解决方案,是动态的选择先前会话中与当前查询最相关的对话内容。 这部分请参阅策略“使用基于嵌入的搜索实现高效的知识检索 (opens in a new tab)”。

举一个简单的例子:

例子1:客服聊天机器人
假设一个客服聊天机器人正在与用户讨论复杂的技术问题。
对话很长,涉及多个问题和解决方案。当对话字符达到2000时,系统触发一个机制将前1000个字符的内容总结为200字符的摘要。
这样,新的问题和回答可以继续添加到对话中,而先前对话的重要部分仍然作为摘要保留,可以作为后续对话的参考。

例子2:法律咨询机器人
假设一个法律咨询机器人正在与用户讨论不同的法律问题,涉及合同、知识产权和劳动法等多个主题。
当用户提出一个特定的关于劳动法的问题时,系统可以动态选择先前关于劳动法的对话部分,忽略与合同和知识产权相关的内容。
这样,一方面不会超过上下文的最大长度,同时可以更精确地响应当前的问题,而不被不相关的信息所干扰。

分段总结长文档,并递归构建成完整摘要

由于 GPT 具有固定的上下文长度,因此它不能用于在单次查询中总结长度超过“固定上下文长度减去生成内容的长度”的文本。

要总结一个很长的文档(例如一本书),我们可以使用一系列的查询来总结文档的每个部分。通过将每一个章节的摘要合并在一起并进行总结,可以进一步生成摘要的摘要。 这个处理过程可以递归地进行,直到对整个文档完成总结。如果有必要使用前面章节的信息来理解后面的章节,那么另一个有用的技巧是,在总结书中任何给定部分的内容时,都将前面章节得到的摘要(a running summary,持续摘要)包含进来。OpenAI 在之前的研究中,已经使用了 GPT-3 的变体研究了这种总结书籍的过程的有效性。

举一个简单的例子:

假设一本书籍有三章:

第一章是关于一个男孩的生活。
第二章描述了他的大学生涯。
第三章讲述了他的工作生涯。

如果我们对每章进行摘要:
第一章摘要:男孩在乡村长大。
第二章摘要:男孩在城市的大学学习。
第三章摘要:男孩成为了一名医生。

如果我们用“持续摘要”的方法:
第一章的持续摘要:男孩在乡村长大。
到第二章时的持续摘要:男孩在乡村长大,后来去城市的大学学习。
到第三章时的持续摘要:男孩在乡村长大,后来去城市的大学学习,并最终成为了一名医生。

通过这种持续摘要的方式,提供了一个连续的、不断更新的上下文信息,当后续的章节与前面的章节有紧密的联系时,可以更好的理解最新的章节。

参考

https://platform.openai.com/docs/guides/gpt-best-practices/strategy-split-complex-tasks-into-simpler-subtasks (opens in a new tab)