Update and rename 4.13LLM Agent之结构化输出 to 4.13LLMAgent之结构化输出.md

This commit is contained in:
少轻狂
2023-07-26 14:31:38 +08:00
committed by GitHub
parent 0421fa836c
commit c161c56930

View File

@@ -1,4 +1,10 @@
# 引言
# LLM Agent之结构化输出
author:Marlene
<em>Last revised 2023/07/26</em>
## 引言
自去年年底以来GPT的迅速发展诞生了一系列大模型。出现了更新、更大、更强的GPT-4。OpenAI不断推出GPT-4ChatGPT Plugins代码解释器Function calling,图片处理等等。7月的WAIC上笔者也有幸见到了国内一众企业相继展示自家的大模型。在这段时间里LLM从最初的PE工程走向智能体交互。而笔者从最开始考虑LLM能不能多人协作思考”一个专家完成所有任务好还是很多人分工完成好“到各种论文层出不穷到如今火热的LLM Agent开发模式。可以说如果你从大学里随便问某个人都知道GPT甚至大部分都用过。
@@ -6,7 +12,7 @@
想要使用工具让GPT掌握如何使用工具常见的方法是告知GPT工具通常是一个可以调用的函数的参数让GPT生成这些参数即可。那么如何让GPT可靠的生成这些规定的参数呢换一种说法如何让GPT输出结构化的数据信息呢
# 原理及相关框架
## 原理及相关框架
现如今大部分的结构化输出工具的原理都是告诉GPT要输出一个怎么样的结构即可。没错~当然,为什么会出现这么多开发工具都用来解决这个问题,明明是一个简单的原理呢?
@@ -21,7 +27,7 @@
其次,自动处理修正机制也可以做很多文章。还有许多对性能和开销的优化。
下文就是关于一众框架的简单分析。希望会对选择困难症的你有所帮助。
## **guardrails**
### **guardrails**
guardrails这个项目就是将上述的步骤做了进一步的抽象与封装提供更加 high level 的配置与 API 来完成整个过程。
优点:
@@ -101,7 +107,7 @@ Help me correct the incorrect values based on the given error messages.
后续 LLM 的返回可以仅针对这部分问题的修正,而不需要再重复生成整个 json。生成的新结果会由 guardrails 再自动填写回原来的位置,非常丝滑。除了 json 格式的检查外RAIL spec 中还提供了通过脚本检查的扩展支持,可以用来检查更加复杂的内容,例如 Python 代码是否合法,结果中是否有敏感信息,甚至通过 LLM 再来检查生成的内容是否有害,做结果过滤等。
## **NeMo-Guardrails**
### **NeMo-Guardrails**
来自 Nvidia 的一个同名项目,其目标相比 guardrails 更有野心,想要确保 LLM 应用整体的可信度,无害性以及数据安全性等,而不仅仅只是输出的结构化检查和修复。因此其实现思路上也复杂不少,设计了一种专门的 Colang 语言,来支持更加通用多样的业务流,而不仅仅是生成 -> 检查 -> 修复。不过它的设计都是基于对话做的。实际开发应用可能不太合适。
@@ -128,7 +134,7 @@ define bot inform capabilities
2. 根据意图,判断下一步操作动作。这一步有两种做法,一是当前的状态能够匹配上预定义的 flow。例如用户就是提了一个 bot 能力的问题那么就会匹配上面定义的user ask capabilities下一步动作自然就是bot inform capabilities。如果没有匹配上就要由 LLM 自己来决定下一步动作,这时候也会跟生成用户意图一样,对于 flow 定义做一个相似性查找,将相关信息发给 LLM 来做生成。
3. 生成 bot 回复。如果上一步生成的 bot 回复意图已经有明确定义了(例如上面的 bot 能力的回复),那么就直接用预定义的回复内容来回复用户。如果没有,就跟生成用户意图一样,做意图的相似性查找,将相关信息给 LLM 来生成回复。注意到很多动态的问题例如 QA 场景,是很难预先定义好回复内容的,这里也支持对接知识库,同样是做 vector search 之后,将相关 context 信息发给 LLM 来生成具体回复。
## guidance
### guidance
之前在 guardrails 中的做法是在 prompt 中给出说明和示范,希望 LLM 能够遵循指令来输出。但现实中往往会出现各种问题,例如额外带了一些其它的文字说明,或者生成的 json 格式不正确等,所以需要后续的 ReAsk 来进行修正。LangChain 里也提供了各种 output parser 来帮忙提取回复中的结构化信息部分,但也经常容易运行失败。
@@ -178,19 +184,19 @@ program(description="A quick and nimble fighter.", valid_weapons=valid_weapons)
从项目代码来看还是有比较浓的“research 味道”的,可读性并不好。实际测试结果也比较翻车。
## lmql
### lmql
在 guidance 的基础上lmql这个项目进一步把“prompt 模板”这个概念推进到了一种新的编程语言。从官网能看到给出的一系列示例。语法结构看起来有点像 SQL但函数与缩进都是 Python 的风格。
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7B92E71406-7249-4345-894C-AC646F47D05A%7D.png?q-sign-algorithm=sha1&q-ak=AKIDADgW-17gEbYE8KXI4SJ-K2nFiytVPhWKD-X5eSBblobvDdAR7RKY6w7gB_04DAmk&q-sign-time=1690352350;1690355950&q-key-time=1690352350;1690355950&q-header-list=host&q-url-param-list=ci-process&q-signature=599bcb08fed33a3f9b8837bbda9122ec30f84a7e&x-cos-security-token=vImUXgI9C7vzsrv3ymAMkcEtPyQCcNda5e18e3cceae357cb9f2c6aefb068cbf8BqMypgx5-DNHrViAIgr8Gwpv2s_YChAAcqsbePywl4zwaWRrN4Sn6G3EsrxeO-Br2t3RmsIG_CUz7yNSMst7MKjAZiD8bGbU1F_9KDTNkyGD5shMz19ZW12vbLk2p4XE6YuXTymlad4Q4pTsfg9-ogD73wkge16Ypk9O2jqY1-k65Nf_UW0rLXP4RgweMht5&ci-process=originImage)
从支持的功能来看,相比 guidance 毫不逊色。例如各种限制条件,代码调用,各种 caching 加速,工具集成等基本都具备。这个框架的格式化输出是其次,其各种可控的输出及语言本身或许更值得关注。
## TypeChat
### TypeChat
TypeChat 将 prompt 工程替换为 schema 工程:无需编写非结构化的自然语言 prompt 来描述所需输出的格式,而是编写 TS 类型定义。TypeChat 可以帮助 LLM 以 JSON 的形式响应,并且响应结果非常合理:例如用户要求将这句话「我可以要一份蓝莓松饼和一杯特级拿铁咖啡吗?」转化成 JSON 格式TypeChat 响应结果如下:
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7BECFBBC78-BFE8-45d0-99EF-5E13E30E2A18%7D.png?q-sign-algorithm=sha1&q-ak=AKIDVU4ys39l5t63hNLtyC0ksCxX3kZox5vnG1g0mcLcMCqeOM5TeB1yCKPGhMgkg3rc&q-sign-time=1690352395;1690355995&q-key-time=1690352395;1690355995&q-header-list=host&q-url-param-list=ci-process&q-signature=a9b1d0fc9cd831b9f38a1fb932fbc61a7d7bb507&x-cos-security-token=AM7z4h9zPrm9LtZSTUHjC6sQi7Tl2rGa395e2017ccc68e3db68e4619d2c7d600ElWASYe21NEJMw2S1tmMmFY2ZbL1qHTiASObl9bIDyNcR84QxYYgiQzCBlRKG14m-bkpDFOwQE4NADCWi3-DT7I5xMNNjCN277p4mEcyMZT5cZGeNumhqTrdhFcuvpGwNqUaZqd_FmoaNhoai9cRwbV121qC6JJfDQ1sYxF-3Ix7Ij36vJreXKakxpD6qSws&ci-process=originImage)
其本质原理是把interface之类的ts代码作为prompt模板。因此它不仅可以对输出结果进行ts校验甚至能够输入注释描述不可谓非常方便js开发者。不过近日typechat爆火很多开发者企图尝试将typechat移植到python笔者认为这是缘木求鱼因为其校验本身依赖的是ts。笔者在开发过程中将typechat融合到自己的库中效果不错。但是它本身自带的prompt和笔者输入的prompt还是存在冲突还是需要扣扣源码。
## Langchain
### Langchain
如果你关注了过去几个月中人工智能的爆炸式发展,那你大概率听说过 LangChain。简单来说LangChain 是一个 Python 和 JavaScript 库,由 Harrison Chase 开发,用于连接 OpenAI 的 GPT API后续已扩展到更多模型以生成人工智能文本。
@@ -198,7 +204,7 @@ langchain具有特别多的结构化输出工具。例如使用yaml定义Schema
但是笔者这里不打算介绍langchain。究其原因是笔者被langchain折磨不堪。明明可以几行代码写清楚的东西langchain可以各种封装花了好几十行才写出来。更何况笔者是用ts开发开发时甚至偷不了任何懒甚至其文档丝毫不友好。这几天《机器之心》发布文章表示放弃langchain。要想让 LangChain 做笔者想让它做的事就必须花大力气破解它这将造成大量的技术负担。因为使用人工智能本身就需要花费足够的脑力。LangChain 是为数不多的在大多数常用情况下都会增加开销的软件之一。所以笔者建议非必要不使用langchain。
# LLM对于结构化信息的理解
## LLM对于结构化信息的理解
LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级应用中非常关键的问题,上面分享的这些项目都是在这方面做了很多探索,也有很多值得借鉴的地方。总体思路上来说,主要是:
@@ -212,7 +218,7 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
同时笔者认为自动处理机制、自己设计的编程语言等等内容随着时间发展一定会层出不穷不断迭代更新。笔者抛去这些时效性较弱的内容从描述信息和位置信息两方面思考peompt模板该如何设计当然只是浅浅的抛砖引玉一下。
## 描述信息
### 描述信息
到底哪种方式更容易于LLM去理解我们不谈框架的设计只考虑prompt的设计。上述框架关于这方面有一些参考例如有些直接拿json作为prompt模板有些拿xml作为prompt模板有些拿自己设计的语言作为prompt有些拿自然语言作为prompt模板。时至今日选用哪种最适合LLM去理解格式化的信息输出格式化的内容完全没有盖棺定论。甚至时至今日格式化输出问题还是没有得到可靠稳定的解决要不然笔者肯定不会介绍这么多框架实践了。
@@ -220,12 +226,12 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
想要LLM结构化输出更加稳定和理想笔者认为选择prompt模板时必须考虑每个字段是否有足够的辅助信息。例如xml描述时每个标签都有一个描述属性描述这个标签时什么意思。
### 额外引申
#### 额外引申
笔者之前在开发LLM应用时也曾思考类似的问题。笔者需要将多模态的数据进行结构化的标注方便LLM去理解。但是标注成什么样却是一个很大的难题。笔者选择的是JSON。但是关于里面许多内容的标注。笔者在众多方案中徘徊。在细节处深挖如何设计一种既简单又能表示各种结构复杂关系还能够节约token的方案及其的难。
> 关于后续如何解决请容笔者卖个关子sai~
## 位置信息
### 位置信息
是否有人注意到llm对于关键信息在prompt中的位置会对结果产生影响呢在设计 prompt 方面,人们通常建议为语言模型提供详尽的任务描述和背景信息。近期的一些语言模型有能力输入较长的上下文,但它究竟能多好地利用更长的上下文?这一点却相对少有人知。近日,有学者研究发现如果上下文太长,语言模型会更关注其中的前后部分,中间部分却几乎被略过不看,导致模型难以找到放在输入上下文中部的相关信息。下文部分是该论文一些核心内容:
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7B59E03114-A066-4394-B1F0-B09357F76B39%7D.png?q-sign-algorithm=sha1&q-ak=AKID3Qjrq4B5rrfZJ43bA2-DzVM4VY00o8ezYuxUko6fAqmDLjhoOwotz5XRLv_dbkkg&q-sign-time=1690352192;1690355792&q-key-time=1690352192;1690355792&q-header-list=host&q-url-param-list=ci-process&q-signature=dba160c7dc037dd82da4369aeec5b0cb6dbb3b71&x-cos-security-token=AM7z4h9zPrm9LtZSTUHjC6sQi7Tl2rGa015c924fbce22b15fb653c312f9eacefElWASYe21NEJMw2S1tmMmLXT2LZXr8mDdl1aXw-1VW1HbxRi1g8g0byRr71z6c2nz0SacBqjL1dkPx-5M7JLZ8db9FLvYcS6Bo7ik6qC9OgvdNTuWUvq3ZpJM1eNsQCwQhH7aE-xfKuJFxYjb6djI8RsaSluGxA-Ge-AJdA88Bt6FmPZtB5eAeSMVxy4XJgP&ci-process=originImage)
@@ -235,7 +241,7 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
那么如果真的为其提供这么多 token那会真的有用吗这个问题的答案是由下游任务决定。因为这取决于所添加上下文的边际价值以及模型有效使用长输入上下文的能力。所以如果能有效地对检索文档排序让相关信息与输入上下文的起始处更近或对已排序的列表进行截断处理必要时返回更少的文档那么也许可以提升基于语言模型的阅读器使用检索上下文的能力。
# 题外话
## 题外话
之前妙鸭相机突然爆火。其只需9.9即可生成同款数字分身效果拔群。但是很多人发现其生成的内容极其容易造成肖像权侵犯这显然是有问题的。更有甚至的是用户发现妙鸭相机的用户协议存在问题。根据该应用最初版本的用户服务协议用户需授权妙鸭相机在全世界包括元宇宙等虚拟空间范围内享有永久的、不可撤销的、可转让的、可转授权的、免费的和非独家的许可使得妙鸭相机可以任何形式、任何媒体或技术无论现在已知或以后开发使用用户的内容。对于上述内容妙鸭相机称系“为了使我方能够提供、确保和改进本服务包括但不限于使用AI生成内容作为再训练数据等”。
@@ -248,7 +254,7 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
隐私的掠夺是无声的。你认为你的一下点击是没啥价值的隐私数据殊不知这正中了资本家的下怀。几年前我也是这样的。高中的大门出现了闸机可以刷脸进校园。我当时以为这需要像手机解锁一样需要扫描人脸ID。结果发现我可以直接进去闸机上甚至会出现我的照片。我仔细看了看发现是我入学的证件照。原来一张照片就能刷脸进校园。原来就连学校也可以不经同学同意将照片用作其他用途。那更何况其他的呢。
我想,未来,这样的隐私问题会越来越多。
# 参考
## 参考
<https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650885029&idx=4&sn=ac01576a8957b41529dd3c877d262d5e&chksm=84e48fdbb39306cd8979a4fa7f7da14a9428dc28ccc47880d668ef6293b1a8b7b0964569ec36&mpshare=1&scene=23&srcid=0725w9FPsVnOOzkPGPB7lH8h&sharer_sharetime=1690303766527&sharer_shareid=d2396b329b12f49d34967e2b183540dd#rd>
<https://mp.weixin.qq.com/s/BngY2WgCcpTOlvdyBNJxqA>
<https://microsoft.github.io/TypeChat/>