many chore
This commit is contained in:
FallenYing
2023-08-06 22:46:43 +08:00
parent 97d86551e9
commit 1ea114cd6c
10 changed files with 242 additions and 235 deletions

View File

@@ -1,4 +1,4 @@
# LLM Agent之结构化输出
# LLM Agent 之结构化输出
author:Marlene
@@ -6,33 +6,33 @@ author:Marlene
## 引言
自去年年底以来GPT的迅速发展诞生了一系列大模型。出现了更新、更大、更强的GPT-4。OpenAI不断推出GPT-4ChatGPT Plugins代码解释器Function calling,图片处理等等。7月的WAIC上笔者也有幸见到了国内一众企业相继展示自家的大模型。在这段时间里LLM从最初的PE工程走向智能体交互。而笔者从最开始考虑LLM能不能多人协作思考”一个专家完成所有任务好还是很多人分工完成好“到各种论文层出不穷到如今火热的LLM Agent开发模式。可以说如果你从大学里随便问某个人都知道GPT甚至大部分都用过。
自去年年底以来GPT 的迅速发展诞生了一系列大模型。出现了更新、更大、更强的 GPT-4。OpenAI 不断推出 GPT-4ChatGPT Plugins代码解释器Function calling图片处理等等。7 月的 WAIC 笔者也有幸见到了国内一众企业相继展示自家的大模型。在这段时间里LLM 从最初的 PE 工程走向智能体交互。而笔者从最开始考虑 LLM 能不能多人协作,思考”一个专家完成所有任务好还是很多人分工完成好“,到各种论文层出不穷,到如今火热的 LLM Agent 开发模式。可以说,如果你从大学里随便问某个人都知道 GPT甚至大部分都用过。
好了前言少叙。进入正题。众所周知Agent 基本= LLM大型语言模型+ 记忆 + 规划技能 + 工具使用。
想要使用工具让GPT掌握如何使用工具常见的方法是告知GPT工具通常是一个可以调用的函数的参数让GPT生成这些参数即可。那么如何让GPT可靠的生成这些规定的参数呢换一种说法如何让GPT输出结构化的数据信息呢
想要使用工具,让 GPT 掌握如何使用工具,常见的方法是告知 GPT 工具(通常是一个可以调用的函数)的参数,让 GPT 生成这些参数即可。那么如何让 GPT 可靠的生成这些规定的参数呢?换一种说法,如何让 GPT 输出结构化的数据信息呢?
## 原理及相关框架
现如今大部分的结构化输出工具的原理都是告诉GPT要输出一个怎么样的结构即可。没错~当然,为什么会出现这么多开发工具都用来解决这个问题,明明是一个简单的原理呢?
现如今大部分的结构化输出工具的原理都是:告诉 GPT 要输出一个怎么样的结构即可。没错~当然,为什么会出现这么多开发工具都用来解决这个问题,明明是一个简单的原理呢?
```
```txt
1. 通过 prompt 告知 LLM 我们所需要的返回格式,并进行生成。
2. 通过一些规则来检查返回结果,如果不符合格式,生成相关错误信息。
3. 将上一次的生成内容和检查的错误信息告知 LLM进行下一次的修正生成。
4. 重复 2-3 步骤,直到生成的内容完全符合我们的要求。
```
首先关于怎样描述这样一个结构的prompt模板众口难调。有些人认为结构就应该用自然语言描述这样足够简单上手难度足够低方便快速迭代开发。有些人认为结构描述JSON Schema不就够了有些人觉得YAML也可以。有些人觉得上面这些对于我的需求还是够不着啊于是自己造了一个伪代码描述。
首先,关于怎样描述这样一个结构的 prompt 模板众口难调。有些人认为结构就应该用自然语言描述这样足够简单上手难度足够低方便快速迭代开发。有些人认为结构描述JSON Schema 不就够了?有些人觉得 YAML 也可以。有些人觉得上面这些对于我的需求还是够不着啊,于是自己造了一个伪代码描述。
其次,自动处理修正机制也可以做很多文章。还有许多对性能和开销的优化。
下文就是关于一众框架的简单分析。希望会对选择困难症的你有所帮助。
### **guardrails**
guardrails这个项目就是将上述的步骤做了进一步的抽象与封装提供更加 high level 的配置与 API 来完成整个过程。
guardrails 这个项目,就是将上述的步骤做了进一步的抽象与封装,提供更加 high level 的配置与 API 来完成整个过程。
优点:
1. 定义了一套RAIL spec
1. 定义了一套 RAIL spec
2. 更聚焦于错误信息
```markdown
@@ -78,7 +78,7 @@ Given the following doctor's notes about a patient, please extract a dictionary
</rail>
```
可以看到guardrails定义了一套类似xml的语言用于结构化输出又结合了自然语言的prompt。虽然比起常见的模板语言要更加“繁琐”但可以包含的内容也可以更加完善。比如可以提供字段的描述信息检查规范一定程度上也能帮助 LLM 更好地理解需求,生成预期的结果。
可以看到guardrails 定义了一套类似 xml 的语言用于结构化输出,又结合了自然语言的 prompt。虽然比起常见的模板语言要更加“繁琐”但可以包含的内容也可以更加完善。比如可以提供字段的描述信息检查规范一定程度上也能帮助 LLM 更好地理解需求,生成预期的结果。
```markdown
I was given the following JSON response, which had problems due to incorrect values.
@@ -127,11 +127,11 @@ define bot inform capabilities
"I am an AI assistant which helps answer questions based on a given knowledge base. For this interaction, I can answer question based on the job report published by US Bureau of Labor Statistics."
```
从代码可以看出其结合了python和自然语言方便相似度检索。
从代码可以看出其结合了 python 和自然语言,方便相似度检索。
其整体的运作流程如下:
1. 根据用户输入识别用户意图。在这一步,系统会将用户的输入在 flow 定义的各种用户回复文本中做相似性查找也就是上面文件中“What can you do?”这一连串内容。这些检索到的预设用户意图内容,结合其它信息如对话样例,最近聊天记录等,形成整体的 prompt发给 LLM 来生成回复。最终再从回复中提取用户意图。
2. 根据意图,判断下一步操作动作。这一步有两种做法,一是当前的状态能够匹配上预定义的 flow。例如用户就是提了一个 bot 能力的问题那么就会匹配上面定义的user ask capabilities下一步动作自然就是bot inform capabilities。如果没有匹配上就要由 LLM 自己来决定下一步动作,这时候也会跟生成用户意图一样,对于 flow 定义做一个相似性查找,将相关信息发给 LLM 来做生成。
2. 根据意图,判断下一步操作动作。这一步有两种做法,一是当前的状态能够匹配上预定义的 flow。例如用户就是提了一个 bot 能力的问题,那么就会匹配上面定义的 user ask capabilities下一步动作自然就是 bot inform capabilities。如果没有匹配上就要由 LLM 自己来决定下一步动作,这时候也会跟生成用户意图一样,对于 flow 定义做一个相似性查找,将相关信息发给 LLM 来做生成。
3. 生成 bot 回复。如果上一步生成的 bot 回复意图已经有明确定义了(例如上面的 bot 能力的回复),那么就直接用预定义的回复内容来回复用户。如果没有,就跟生成用户意图一样,做意图的相似性查找,将相关信息给 LLM 来生成回复。注意到很多动态的问题例如 QA 场景,是很难预先定义好回复内容的,这里也支持对接知识库,同样是做 vector search 之后,将相关 context 信息发给 LLM 来生成具体回复。
### guidance
@@ -174,7 +174,7 @@ program(description="A quick and nimble fighter.", valid_weapons=valid_weapons)
1. 生成的 json 结构是保证合法且可控的,不会出现语法错误或者缺失/错误字段等。
2. 通过 LLM 生成的 token 数量减少了,理论上可以提升生成速度。
除了prompt模板它还提供了
除了 prompt 模板,它还提供了:
- 支持 hidden block例如 LLM 的一些推理过程可能并不需要暴露给最终用户,就可以灵活利用这个特性来生成一些中间结果。
- Generation caching自动把已经生成过的结果缓存起来提升速度。
@@ -186,7 +186,7 @@ program(description="A quick and nimble fighter.", valid_weapons=valid_weapons)
### lmql
在 guidance 的基础上lmql这个项目进一步把“prompt 模板”这个概念推进到了一种新的编程语言。从官网能看到给出的一系列示例。语法结构看起来有点像 SQL但函数与缩进都是 Python 的风格。
在 guidance 的基础上lmql 这个项目进一步把“prompt 模板”这个概念推进到了一种新的编程语言。从官网能看到给出的一系列示例。语法结构看起来有点像 SQL但函数与缩进都是 Python 的风格。
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7B92E71406-7249-4345-894C-AC646F47D05A%7D.png)
从支持的功能来看,相比 guidance 毫不逊色。例如各种限制条件,代码调用,各种 caching 加速,工具集成等基本都具备。这个框架的格式化输出是其次,其各种可控的输出及语言本身或许更值得关注。
@@ -194,17 +194,17 @@ program(description="A quick and nimble fighter.", valid_weapons=valid_weapons)
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)
其本质原理是把interface之类的ts代码作为prompt模板。因此它不仅可以对输出结果进行ts校验甚至能够输入注释描述不可谓非常方便js开发者。不过近日typechat爆火很多开发者企图尝试将typechat移植到python笔者认为这是缘木求鱼因为其校验本身依赖的是ts。笔者在开发过程中将typechat融合到自己的库中效果不错。但是它本身自带的prompt和笔者输入的prompt还是存在冲突还是需要扣扣源码。
其本质原理是把 interface 之类的 ts 代码作为 prompt 模板。因此它不仅可以对输出结果进行 ts 校验,甚至能够输入注释描述,不可谓非常方便 js 开发者。不过,近日 typechat 爆火,很多开发者企图尝试将 typechat 移植到 python笔者认为这是缘木求鱼因为其校验本身依赖的是 ts。笔者在开发过程中 typechat 融合到自己的库中,效果不错。但是它本身自带的 prompt 和笔者输入的 prompt 还是存在冲突,还是需要扣扣源码。
### Langchain
如果你关注了过去几个月中人工智能的爆炸式发展,那你大概率听说过 LangChain。简单来说LangChain 是一个 Python 和 JavaScript 库,由 Harrison Chase 开发,用于连接 OpenAI 的 GPT API后续已扩展到更多模型以生成人工智能文本。
langchain具有特别多的结构化输出工具。例如使用yaml定义Schema输出结构化JSON。使用zodSchema定义Schema输出结构化JSON。使用FunctionParameters定义Schema输出结构化JSON。
langchain 具有特别多的结构化输出工具。例如使用 yaml 定义 Schema输出结构化 JSON。使用 zodSchema 定义 Schema输出结构化 JSON。使用 FunctionParameters 定义 Schema输出结构化 JSON。
但是笔者这里不打算介绍langchain。究其原因是笔者被langchain折磨不堪。明明可以几行代码写清楚的东西langchain可以各种封装花了好几十行才写出来。更何况笔者是用ts开发开发时甚至偷不了任何懒甚至其文档丝毫不友好。这几天《机器之心》发布文章表示放弃langchain。要想让 LangChain 做笔者想让它做的事就必须花大力气破解它这将造成大量的技术负担。因为使用人工智能本身就需要花费足够的脑力。LangChain 是为数不多的在大多数常用情况下都会增加开销的软件之一。所以笔者建议非必要不使用langchain。
但是笔者这里不打算介绍 langchain。究其原因是笔者被 langchain 折磨不堪。明明可以几行代码写清楚的东西langchain 可以各种封装,花了好几十行才写出来。更何况,笔者是用 ts 开发,开发时甚至偷不了任何懒,甚至其文档丝毫不友好。这几天,《机器之心》发布文章表示放弃 langchain。要想让 LangChain 做笔者想让它做的事就必须花大力气破解它这将造成大量的技术负担。因为使用人工智能本身就需要花费足够的脑力。LangChain 是为数不多的在大多数常用情况下都会增加开销的软件之一。所以笔者建议非必要,不使用 langchain。
## LLM对于结构化信息的理解
## LLM 对于结构化信息的理解
LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级应用中非常关键的问题,上面分享的这些项目都是在这方面做了很多探索,也有很多值得借鉴的地方。总体思路上来说,主要是:
@@ -216,24 +216,24 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
即使我们不直接使用上述的项目做开发,也可以从中学习到很多有用的思路。当然也非常期待这个领域出现更多有意思的想法与研究,以及 prompt 与编程语言结合能否碰撞出更多的火花。
同时笔者认为自动处理机制、自己设计的编程语言等等内容随着时间发展一定会层出不穷不断迭代更新。笔者抛去这些时效性较弱的内容从描述信息和位置信息两方面思考peompt模板该如何设计当然只是浅浅的抛砖引玉一下。
同时笔者认为自动处理机制、自己设计的编程语言等等内容,随着时间发展,一定会层出不穷,不断迭代更新。笔者抛去这些时效性较弱的内容,从描述信息和位置信息两方面思考 peompt 模板该如何设计,当然只是浅浅的抛砖引玉一下。
### 描述信息
到底哪种方式更容易于LLM去理解我们不谈框架的设计只考虑prompt的设计。上述框架关于这方面有一些参考例如有些直接拿json作为prompt模板有些拿xml作为prompt模板有些拿自己设计的语言作为prompt有些拿自然语言作为prompt模板。时至今日选用哪种最适合LLM去理解格式化的信息输出格式化的内容完全没有盖棺定论。甚至时至今日格式化输出问题还是没有得到可靠稳定的解决要不然笔者肯定不会介绍这么多框架实践了。
到底哪种方式更容易于 LLM 去理解?我们不谈框架的设计,只考虑 prompt 的设计。上述框架关于这方面有一些参考,例如有些直接拿 json 作为 prompt 模板,有些拿 xml 作为 prompt 模板,有些拿自己设计的语言作为 prompt有些拿自然语言作为 prompt 模板。时至今日,选用哪种最适合 LLM 去理解格式化的信息,输出格式化的内容完全没有盖棺定论。甚至时至今日,格式化输出问题还是没有得到可靠稳定的解决,要不然笔者肯定不会介绍这么多框架实践了。
笔者认为不管哪种方式都可以从两个方面考量更简单更结构。如果想要在开发的时候更简单或者在使用时更简单选择md、yaml方式描述结构化信息更合适。如果想要更结构化的方式选择json、xml、ts输出都能更有结构甚至之后做结构校验都更方便。
笔者认为不管哪种方式,都可以从两个方面考量:更简单,更结构。如果想要在开发的时候更简单,或者在使用时更简单,选择 md、yaml 方式描述结构化信息更合适。如果想要更结构化的方式,选择 json、xml、ts输出都能更有结构甚至之后做结构校验都更方便。
想要LLM结构化输出更加稳定和理想笔者认为选择prompt模板时必须考虑每个字段是否有足够的辅助信息。例如xml描述时每个标签都有一个描述属性描述这个标签时什么意思。
想要 LLM 结构化输出更加稳定和理想,笔者认为选择 prompt 模板时必须考虑每个字段是否有足够的辅助信息。例如 xml 描述时,每个标签都有一个描述属性描述这个标签时什么意思。
#### 额外引申
笔者之前在开发LLM应用时也曾思考类似的问题。笔者需要将多模态的数据进行结构化的标注方便LLM去理解。但是标注成什么样却是一个很大的难题。笔者选择的是JSON。但是关于里面许多内容的标注。笔者在众多方案中徘徊。在细节处深挖如何设计一种既简单又能表示各种结构复杂关系还能够节约token的方案及其的难。
> 关于后续如何解决请容笔者卖个关子sai~
笔者之前在开发 LLM 应用时,也曾思考类似的问题。笔者需要将多模态的数据进行结构化的标注,方便 LLM 去理解。但是标注成什么样却是一个很大的难题。笔者选择的是 JSON。但是关于里面许多内容的标注。笔者在众多方案中徘徊。在细节处深挖如何设计一种既简单又能表示各种结构复杂关系还能够节约 token 的方案及其的难。
> 关于后续如何解决,请容笔者卖个关子 sai~
### 位置信息
是否有人注意到llm对于关键信息在prompt中的位置会对结果产生影响呢在设计 prompt 方面,人们通常建议为语言模型提供详尽的任务描述和背景信息。近期的一些语言模型有能力输入较长的上下文,但它究竟能多好地利用更长的上下文?这一点却相对少有人知。近日,有学者研究发现如果上下文太长,语言模型会更关注其中的前后部分,中间部分却几乎被略过不看,导致模型难以找到放在输入上下文中部的相关信息。下文部分是该论文一些核心内容:
是否有人注意到 llm 对于关键信息在 prompt 中的位置会对结果产生影响呢?在设计 prompt 方面,人们通常建议为语言模型提供详尽的任务描述和背景信息。近期的一些语言模型有能力输入较长的上下文,但它究竟能多好地利用更长的上下文?这一点却相对少有人知。近日,有学者研究发现如果上下文太长,语言模型会更关注其中的前后部分,中间部分却几乎被略过不看,导致模型难以找到放在输入上下文中部的相关信息。下文部分是该论文一些核心内容:
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7B59E03114-A066-4394-B1F0-B09357F76B39%7D.png)
这是由其本身训练和结构设计有关的,但却对于我们开发有着莫大的帮助和指导意义。
![](https://marlene-1254110372.cos.ap-shanghai.myqcloud.com/blog/%7B9EA47A4E-3EF3-4800-99F4-109EE713746B%7D.png)
@@ -243,18 +243,19 @@ LLM 的可控性、稳定性、事实性、安全性等问题是推进企业级
## 题外话
之前妙鸭相机突然爆火。其只需9.9即可生成同款数字分身效果拔群。但是很多人发现其生成的内容极其容易造成肖像权侵犯这显然是有问题的。更有甚至的是用户发现妙鸭相机的用户协议存在问题。根据该应用最初版本的用户服务协议用户需授权妙鸭相机在全世界包括元宇宙等虚拟空间范围内享有永久的、不可撤销的、可转让的、可转授权的、免费的和非独家的许可使得妙鸭相机可以任何形式、任何媒体或技术无论现在已知或以后开发使用用户的内容。对于上述内容妙鸭相机称系“为了使我方能够提供、确保和改进本服务包括但不限于使用AI生成内容作为再训练数据等”。
之前,妙鸭相机突然爆火。其只需 9.9 即可生成同款数字分身,效果拔群。但是很多人发现,其生成的内容极其容易造成肖像权侵犯,这显然是有问题的。更有甚至的是,用户发现妙鸭相机的用户协议存在问题。根据该应用最初版本的用户服务协议,用户需授权妙鸭相机在全世界(包括元宇宙等虚拟空间)范围内享有永久的、不可撤销的、可转让的、可转授权的、免费的和非独家的许可,使得妙鸭相机可以任何形式、任何媒体或技术(无论现在已知或以后开发)使用用户的内容。对于上述内容,妙鸭相机称系“为了使我方能够提供、确保和改进本服务(包括但不限于使用 AI 生成内容作为再训练数据等)”。
一句话理解,就是你的肖像它随便用,与你无关。
这不禁让我联想到一部非常发人深省的剧作《黑镜》。它的第六季第一集讲述的同样是隐私的问题。该集中主人公的生活隐私由于同意了用户协议被无时无刻搜集。然后当天晚上就发现流媒体电视上居然出现了跟她同名的电视剧内容与它当天的生活一模一样台词甚至更加夸张。于是她的不方便公之于众的生活变得一塌涂地但她甚至没有办法打官司因为肯定会输。更令人深省的是电视剧的主人公是AI生成的视频其肖像确是根据现实存在的明星生成的。那位明星也无法对她的肖像有任何权利。这样一个荒诞的故事但是仔细想想却又非常可能发生。
这不禁让我联想到一部非常发人深省的剧作:《黑镜》。它的第六季第一集讲述的同样是隐私的问题。该集中,主人公的生活隐私由于同意了用户协议,被无时无刻搜集。然后当天晚上就发现流媒体电视上居然出现了跟她同名的电视剧,内容与它当天的生活一模一样,台词甚至更加夸张。于是她的不方便公之于众的生活变得一塌涂地,但她甚至没有办法打官司,因为肯定会输。更令人深省的是,电视剧的主人公是 AI 生成的视频,其肖像确是根据现实存在的明星生成的。那位明星也无法对她的肖像有任何权利。这样一个荒诞的故事,但是仔细想想,却又非常可能发生。
如今的社会出现了各种大模型。大模型的发展必定需要大数据的支撑。企业为了盈利必定会想方设法的搜集数据然后肆意使用转卖。而很多用户对此不自知更有甚至是非常乐意。例如抖音、B站当你对其交互时你希望它推荐更适合你的视频它也在搜集你的数据这是明知且主动的。
如今的社会出现了各种大模型。大模型的发展必定需要大数据的支撑。企业为了盈利必定会想方设法的搜集数据然后肆意使用转卖。而很多用户对此不自知更有甚至是非常乐意。例如抖音、B 站,当你对其交互时,你希望它推荐更适合你的视频,它也在搜集你的数据,这是明知且主动的。
隐私的掠夺是无声的。你认为你的一下点击是没啥价值的隐私数据殊不知这正中了资本家的下怀。几年前我也是这样的。高中的大门出现了闸机可以刷脸进校园。我当时以为这需要像手机解锁一样需要扫描人脸ID。结果发现我可以直接进去闸机上甚至会出现我的照片。我仔细看了看发现是我入学的证件照。原来一张照片就能刷脸进校园。原来就连学校也可以不经同学同意将照片用作其他用途。那更何况其他的呢。
隐私的掠夺是无声的。你认为你的一下点击是没啥价值的隐私数据,殊不知这正中了资本家的下怀。几年前,我也是这样的。高中的大门出现了闸机,可以刷脸进校园。我当时以为这需要像手机解锁一样需要扫描人脸 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/>