真正做过 LLM 开发的都知道,虽然理论上 LLM 可以生成结构化的数据,但是真正生成的时候经常出错。怎么稳定的让 LLM 返回结构化的数据?
LinkedIn 的做法如下:
https://www.linkedin.com/blog/engineering/generative-ai/musings-on-building-a-generative-ai-product
YAML 和 JSON 是两种常用的数据序列化格式,它们各有优势和用途。大多数 LLM 在训练中都使用了 YAML 和 JSON 来进行结构化输出。
LinkedIn 选择了 YAML,因为它比 JSON 更简洁,因此消耗的 Token 更少。
使用 YAML 而不是 JSON
选择 YAML 作为数据交换格式相对于 JSON 的一个主要优势在于它的人类可读性和灵活性,这些特性使得 YAML 在某些方面具有更高的容错率。
以下是几个关键点来解释为什么在某些情况下 YAML 可能比 JSON 更容错:
1、注释支持
YAML 支持在文件中直接添加注释,这有助于开发人员解释或标记代码,增加了代码的可读性和维护性。
这种可注释的特性使得开发者可以在配置文件中留下有用的说明,有助于避免错误的配置和理解配置的意图。
YAML
# 这是一个主机配置项
host: localhost
port: 8080 # 后面可以直接加注释
YAML 除了注释行,还允许在同一行中加注释和在冒号后直接跟值,使得配置更加简洁;
JSON
{
"host": "localhost",
"port": 8080
// 这会导致错误,因为JSON不支持这样的注释
}
对比说明: YAML 允许在文件中直接添加注释,方便开发者记录重要信息或者暂时禁用某个配置项。而JSON格式不支持注释,试图添加注释会导致解析错误。
让LLM生成指定格式内容时,可以给出示例,YAML格式的示例中有注释,更不容易产生歧义。
2、不严格的语法
YAML 不要求所有数据结构元素(如列表和映射)强制使用逗号和括号分隔。
这种灵活性意味着在编写或编辑数据时,遗漏或错误添加分隔符不会立即导致解析错误,从而提高了容错能力。
YAML
animals:
- dog
- cat
- rabbit
JSON
{
"animals": ["dog", "cat", "rabbit"]
}
对比说明: YAML 中列表项前只需要一个短横线和一个空格,没有严格的逗号分隔;而JSON中的数组元素必须使用逗号分隔,漏写或多写逗号都会导致错误。
3、数据类型检测
YAML 自动检测数据类型,如整数、浮点数、字符串等。这意味着不需要显式声明类型,简化了数据的书写和阅读过程。
例如,你不需要用引号包围字符串,除非它包含可能会被解析为其他类型的字符。
YAML
integer: 5
float: 5.0
boolean: true
unquoted_string: hello world
quoted_string: "12345" # 强制作为字符串
text: "He said, \"Hello, how are you?\"" # 有转义字符
YAML 自动推断数据类型,整数和浮点数不需要引号。
在 YAML 中,字符串常常不需要转义字符(除非包含特定的符号),这简化了复杂字符串的表示,减少了因转义错误导致的问题。
unquoted_string
中的文本不需要引号,除非像 quoted_string
那样要强制为字符串类型。
JSON
{
"integer": 5,
"float": 5.0,
"boolean": true,
"unquoted_string": "hello world",
"quoted_string": "12345",
"text": "He said, \"Hello, how are you?\""
}
JSON 中所有的字符串都必须用引号包围,无论内容。布尔值和数值不需要引号,但对于想要表示为字符串的数字,如 quoted_string
,也必须用引号。
4、复杂结构的表示
YAML 通过缩进来表示层级结构,而不是使用大括号和方括号。这种基于缩进的结构通常更易于阅读和编辑,减少了因括号匹配错误导致的问题。
YAML
root:
child1:
child2: value
JSON
{
"root": {
"child1": {
"child2": "value"
}
}
}
对比说明: YAML 使用缩进来表达层级关系,更易读;JSON 使用花括号和逗号,层次复杂时容易出错,尤其是在括号匹配上。
上面这些例子可以看出:YAML在某些方面相对于JSON的高容错性和灵活性。
解决生成的 YAML 也不规范问题
尽管选用了YAML作为LLM结构化数据输出格式,也有成功率的挑战:
LinkedIn 统计:尽管大约 90% 的时间里 LLM 的响应包含了正确格式的参数,但仍有约 10% 的时间 LLM 会出错,常常输出不符合提供的架构,甚至不是有效的 YAML。
虽然这些错误对于人类来说很容易发现,但却会导致解析代码出错。10% 的错误率足够高,不能轻易忽视,针对这个问题,LinkedIn的解决方案是编写了一个内部防御性 YAML 解析器:
1、YAML 解析器
用日志记录常见的 YAML 错误,优化自己的 YAML 解析器,可以解析 LLM 返回的不规范的 YAML;
下面是一个python版本的yaml格式修正代码,可以根据自己实际的yaml错误做优化改进。
import yaml
import re
def preprocess_yaml(yaml_string):
# 修复常见的缩进错误,确保子项至少比父项多两个空格
lines = yaml_string.split('\n')
processed_lines = []
indent_level = 0
for line in lines:
stripped_line = line.lstrip()
current_indent = len(line) - len(stripped_line)
if ':' in stripped_line and stripped_line.endswith(':') and not stripped_line.endswith(': '):
# 为冒号后确保有一个空格
line = line.replace(':', ': ')
if current_indent < indent_level and stripped_line:
# 如果当前缩进小于预期缩进但非空行,则增加缩进
line = ' ' * indent_level + stripped_line
if stripped_line.endswith(':'):
# 如果行以冒号结尾,则增加预期缩进级别
indent_level = current_indent + 2
processed_lines.append(line)
return '\n'.join(processed_lines)
def parse_yaml(yaml_string):
try:
# 预处理 YAML 字符串以修正格式错误
preprocessed_yaml = preprocess_yaml(yaml_string)
# 尝试解析修正后的 YAML 字符串
data = yaml.safe_load(preprocessed_yaml)
print("YAML 解析成功:", data)
except yaml.YAMLError as e:
# 处理 YAML 解析错误
print("YAML 解析错误:", e)
except Exception as e:
# 处理其他可能的异常
print("其他错误:", e)
# 示例用的 YAML 字符串,包含一些格式错误
yaml_example = """
name: John Doe
age: 34
children:
- name: Jane Doe
age: 10
- hobby: reading # 示例的格式错误,应该更多缩进
"""
parse_yaml(yaml_example)
2、修复解析错误的Prompt
如果还是无法解析则将错误信息交给 LLM 修复,并且不断优化提示词,提升 LLM 修复的成功率;
下面是一个修复解析错误的Prompt示例:
"你有一段包含错误的 YAML 文本,其中可能包括不正确的缩进、缺失的冒号、多余的字符或其他语法问题。
请仔细检查以下 YAML 内容,并纠正所有格式错误,使其成为一个有效的 YAML 格式。
请确保所有键值对都正确分隔,并且列表项正确缩进。
完成后,请输出修正后的完整 YAML 文本。
错误的 YAML 内容:
<incorrect_yaml_content>
name: John Doe
age: 34
children:
- name: Jane Doe
age: 10
- hobby: reading # 示例的格式错误,应该更多缩进
</incorrect_yaml_content>
请修复以上内容,并提供一个有效的 YAML 结构。"
你可以根据实际情况,不断迭代优化这个Prompt。
通过上面步骤的努力,LinkedIn 最终结构化数据的错误率从 10% 下降到 0.01%。
总结
在开发过程中,使用LLM生成结构化数据时,经常会出现格式错误。
为了提高生成数据的准确性和稳定性,LinkedIn选择了YAML作为数据序列化格式,主要因为其简洁性和较低的Token消耗。YAML的优点包括较高的人类可读性、灵活性和容错性。它支持在文件中添加注释,不严格要求数据结构元素使用逗号和括号分隔,自动检测数据类型,且通过缩进来表示层级结构,这些特点使其在某些情况下比JSON更容错。
尽管如此,LLM生成的YAML有时仍然存在约10%的错误率。为应对此问题,LinkedIn开发了一个内部防御性YAML解析器,通过记录常见错误、优化解析器和不断调整提示词,将错误率显著降低至0.01%。
如何系统的去学习大模型LLM ?
大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业
?”“谁的饭碗又将不保了?
”等问题热议不断。
事实上,抢你饭碗的不是AI,而是会利用AI的人。
继科大讯飞、阿里、华为
等巨头公司发布AI产品后,很多中小企业也陆续进场!超高年薪,挖掘AI大模型人才! 如今大厂老板们,也更倾向于会AI的人,普通程序员,还有应对的机会吗?
与其焦虑……
不如成为「掌握AI工具的技术人
」,毕竟AI时代,谁先尝试,谁就能占得先机!
但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高。
针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料
分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓
一、LLM大模型经典书籍
AI大模型已经成为了当今科技领域的一大热点,那以下这些大模型书籍就是非常不错的学习资源。
二、640套LLM大模型报告合集
这套包含640份报告的合集,涵盖了大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(几乎涵盖所有行业)
三、LLM大模型系列视频教程
四、LLM大模型开源教程(LLaLA/Meta/chatglm/chatgpt)
LLM大模型学习路线 ↓
阶段1:AI大模型时代的基础理解
-
目标:了解AI大模型的基本概念、发展历程和核心原理。
-
内容:
- L1.1 人工智能简述与大模型起源
- L1.2 大模型与通用人工智能
- L1.3 GPT模型的发展历程
- L1.4 模型工程
- L1.4.1 知识大模型
- L1.4.2 生产大模型
- L1.4.3 模型工程方法论
- L1.4.4 模型工程实践
- L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
-
目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
-
内容:
- L2.1 API接口
- L2.1.1 OpenAI API接口
- L2.1.2 Python接口接入
- L2.1.3 BOT工具类框架
- L2.1.4 代码示例
- L2.2 Prompt框架
- L2.3 流水线工程
- L2.4 总结与展望
阶段3:AI大模型应用架构实践
-
目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
-
内容:
- L3.1 Agent模型框架
- L3.2 MetaGPT
- L3.3 ChatGLM
- L3.4 LLAMA
- L3.5 其他大模型介绍
阶段4:AI大模型私有化部署
-
目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
-
内容:
- L4.1 模型私有化部署概述
- L4.2 模型私有化部署的关键技术
- L4.3 模型私有化部署的实施步骤
- L4.4 模型私有化部署的应用场景
这份 LLM大模型资料
包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓