三、将复杂任务拆分成简单任务
技巧一:前置分类
对于一些复合任务,即包含多个独立子任务的任务,我们可以先设定固定的分类,将用户的问题分解到某一分类中,在再该分类中进行特定的处理:
🌰 例子 1,假设我们有一个处理客户服务的应用:
【系统消息】
当你拿到客户服务查询时,将每个查询分类到主要类别和次要类别中。以 JSON 格式提供输出,键为:primary 和 secondary。
主要类别:计费、技术支持、账户管理或一般咨询。
计费的次要类别包括:
- 取消订阅或升级
- 添加付款方式
- 解释收费
- 争议收费
技术支持的次要类别包括:
- 故障排除
- 设备兼容性
- 软件更新
账户管理的次要类别包括:
- 重置密码
- 更新个人信息
- 关闭账户
- 账户安全
一般咨询的次要类别包括:
- 产品信息
- 定价信息
- 反馈意见
- 与人工对话
【用户消息】
我需要让我的网络恢复正常
【AI 回复消息】
{
"primary": "技术支持",
"secondary": "故障排除"
}
注意这里我们让大模型去输出特定的文本格式(JSON),是为了方便通过编程处理。
通过前置分类,我们将用户的问题分到了「技术支持」这个分类中,然后在该分类中进行专门的处理。这样做有几个好处:首先,我们将原本复杂的问题拆分成多个简单步骤,使大模型能够更好地专注于每个步骤的输出效果;其次,在每个步骤中,我们可以进行专门的处理和优化;最后,这样做还能节省成本,因为将所有要求的提示词混合在一起会导致整体提示词的长度变长,从而浪费资金。
技巧二:总结概括
一般来说,每个大模型都有固定的上下文窗口长度,大模型的计量单位为 token,假设窗口长度为 4000 个 token(4K) ,大概约 3000 个英文单词 / 2000 个中文字符,如果超出的话会报错,或者直接给你截断掉。
所以当遇到长对话的时候,一种方式是先将之前的对话进行总结概括,也就是压缩信息密度,好处是有效缩短对话长度,缺点是会丢失信息。
总结概括+用户问题需要调用两次大模型,如果是同步的话会拉长用户等待时间,可以考虑异步调用,比如用户提问之后就立即进行总结概括。
另外一种方式是只引用跟当前用户问题相关的对话,可以使用基于向量数据库的搜索方案。
技巧三:对长文档分段总结,再组合成完整总结
如果是对于超大的文档,比如一本书,可以先对每一个章节进行总结概括,然后再对每一章的总结进行合并再总结,最后得到整本书的总结。
如果某一个章节的内容跟前面的章节内容相关,这里有一个技巧可以使用,那就是跑一个后台「总结」的处理程序,这个程序可以总结任意位置的内容,这种高效的方式已经被 OpenAI 验证过。