4种控制LLM大模型输出JSON的方法

在构建人工智能应用时,需将大型语言模型(LLM)输出集成到代码库,JSON是常用数据交换格式,但让LLM输出JSON较困难。文章介绍了使用提示工程,还探讨了约束LLM输出的方法,如使用语法规则、KOR、LM - Format - Enforcer及微调LLM等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSON 是全球使用最广泛的数据交换格式之一,支持我们的所有需求。 在构建人工智能驱动的应用程序时,工程师不可避免地需要将大型语言模型(LLM)的输出集成到他们的代码库中。

通过指示 LLM 使用特定的语法或模式,然后输出应用程序所需的生成结果,我们可以使应用程序的行为更加可预测。 简而言之,JSON 的互操作性使其成为数据交换的首选。

NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包

1、为什么让LLM 输出JSON数据如此困难?

语言模型擅长预测下一个标记并生成文本,但它们在产生文本之外的精确输出方面可能具有挑战性,因为它们并不总是精确地遵循指令

例如:对于 OpenAI,我希望 GPT-3.5-turbo 始终以以下形式响应

(message_type) {message_content}

然而,它可能会以略微不同的方式响应:

  • message_type:message_content
  • message_type:"message_content"
  • (message_type): "message_content"

2、使用提示工程

Please provide the response in the form of a Python list. It should begin with “[“ and end with “]”.

Chatgpt (gpt4) 支持提示系统/用户 (gpt4 api) 将数据格式化为 csv。 通常工作完美。 虽然 gpt4 非常适合制作演示原型,但它相当昂贵,因此本地解决方案将是完美的。

有许多提示工程框架可以限制 json 格式的输出,请参阅此处的一个用于 LLM 输出的严格 JSON 框架。

## simple example provided by the author
res = strict_output(system_prompt = 'You are a classifier',
                    user_prompt = 'It is a beautiful day',
                    output_format = {"Sentiment": "Type of Sentiment",
                                    "Tense": "Type of Tense"})     
print(res)
## output
{'Sentiment': 'Positive', 'Tense': 'Present'}

虽然提示工程对于某些用例可能是有效的,但它有一个局限性—LLM所做的任何内部更改都可能导致意外的输出。 众所周知,这会在生产环境中引起问题,正如在线故事中所见,依赖 ChatGPT API 的 AI 应用程序由于不断的后台更新而失败。

3、约束LLM输出

这一领域已经有大量的创新工作,我有机会探索三个框架,它们都从不同的角度解决了这个问题。 尽管使用不同的方法,但每个框架如何达到相似的结果给我留下了深刻的印象。

  • GRAMMAR — 约束模型输出的语法。 例如,你可以强制模型仅输出 JSON:
  • KOR — 这是一个半成品原型,可以“帮助”你使用LLM从文本中提取结构化数据
  • LM-Format-Enforcer — 强制语言模型的输出格式(JSON Schema、Regex 等)
  • Finetune LLM 模型 — 教导模型根据输入数据输出 JSON

3.1 使用语法规则强制模型仅输出 JSON

在这种方法中,你需要使用 Llama.cpp 来运行模型并创建语法文件。 GBNF (GGML BNF) 是一种用于定义形式语法以约束 llama.cpp 中模型输出的格式。

这是我为基本测试创建的一个简单语法文件:

root ::= answer
answer ::= "{"   ws   "\"id\":"   ws   number   ","   ws   "\"name\":"   ws   string   "}"
answerlist ::= "[]" | "["   ws   answer   (","   ws   answer)*   "]"
string ::= "\""   ([^"]*)   "\""
boolean ::= "true" | "false"
ws ::= [ \t\n]*
number ::= [0-9]+   "."?   [0-9]*
stringlist ::= "["   ws   "]" | "["   ws   string   (","   ws   string)*   ws   "]"
numberlist ::= "["   ws   "]" | "["   ws   string   (","   ws   number)*   ws   "]"

它更难理解,但是,可以从更容易理解的模式定义开始。 如下所示:

interface answer {
    id: number;
    name: string;
}

接下来将模式粘贴到这个在线工具以自动生成语法文件 - 省去很多麻烦。

现在,我们有了一个语法文件并准备好插入 Llama.cpp。 有关在你的计算机上本地运行的设置的更多详细信息,请参阅存储库。

## start with a prompt
 ./main -m ./models/Mistral-7B-Instruct-v0.1-Q8.gguf -n 256 — grammar-file grammars/answer.gbnf -p ‘Q: Name the planets in the solar system? A:’
...................................................................................................
llama_new_context_with_model: n_ctx      = 512
llama_new_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值