微信扫码
添加专属顾问
我要投稿
掌握LLM生成完美JSON格式输出的实用技巧。核心内容:1. LLM在生成特定格式输出中的应用与挑战2. 通过调整概率分布约束LLM输出格式3. 利用开源项目定义JSON语法规则的实际案例
如果你经常用LLM来完成一些任务,比如写代码、生成结构化数据或者调用API,你可能已经听说过类似json_mode
或者“函数调用”这样的功能。这些功能其实解决了一个很核心的问题:让LLM生成的内容完全按照我们想要的格式输出。
硅基流动的API除了DeepSeek,其他模型全部都支持JSON格式返回,大家可以去试试。
我们都知道现在LLM生成内容的过程都是基于概率模型的,一步一步地生成每一个token。而每个token的选择其实是通过一个概率分布决定的,也就是说,下一个token是根据上下文“猜”出来的。
这个过程确实是非常灵活的,因为它允许LLM生成各种各样的文本。不过,这种灵活性也带来了一个问题:如果我们要的是某种特定格式的输出,比如JSON,那该怎么办呢?
除了直接让LLM自由生成外,我们也可以通过一些技术手段来约束它的行为。今天我们重点聊聊一种非常实用的技术——通过人为干预概率分布,强制LLM生成符合特定语法的内容。
也就是我们可以把那些不符合目标格式的token的概率设置为0,从而确保LLM在生成内容时不会偏离我们设定的规则。这种方法在实践中已经被广泛使用了,比如json_mode
、结构化输出(structured output)以及函数调用(function calling)等。
GitHub上的开源项目llama.cpp
,它就提供了一个名为grammars/json.gbnf
的文件( https://github.com/ggml-org/llama.cpp/blob/master/grammars/json.gbnf ),专门用来定义JSON语法的规则。
root ::= object
value ::= object | array | string | number | ("true" | "false" | "null") ws
object ::=
"{" ws (
string ":" ws value
("," ws string ":" ws value)*
)? "}" ws
array ::=
"[" ws (
value
("," ws value)*
)? "]" ws
string ::=
"\"" (
[^"\\\x7F\x00-\x1F] |
"\\" (["\\bfnrt] | "u" [0-9a-fA-F]{4}) # escapes
)* "\"" ws
number ::= ("-"? ([0-9] | [1-9] [0-9]{0,15})) ("." [0-9]+)? ([eE] [-+]? [0-9] [1-9]{0,15})? ws
# Optional space: by convention, applied in this grammar after literal chars when allowed
ws ::= | "" | "\n" [ \t]{0,20}
通过这种方式,LLM在生成JSON格式的响应时,可以严格遵守这些语法规则,而不会出现任何偏差。
像 LangChain 这样提供 GBNF 支持的框架,也是通过 llama.cpp 实现的
或者你想用自己自定义的JSON结构的话,可以参考下面的写法:
from llama_cpp import Llama, LlamaGrammar
# Define your GBNF grammar
grammar_string = r"""
root ::= "{" pair ("," pair)* "}"
pair ::= string ":" list
list ::= "[" value ("," value)* "]"
value ::= string | number
string ::= "\"" [a-zA-Z0-9_]+ "\""
number ::= [0-9]+
"""
# Create a LlamaGrammar object
my_grammar = LlamaGrammar.from_string(grammar_string)
# Initialize Llama model
llm = Llama(model_path="C:/Users/sride/PycharmProjects/gbnf_implemen/llama-2-7b.Q4_K_S.gguf")
# Generate constrained output
prompt = "Give me list of fruits"
output = llm(prompt, max_tokens=100, temperature=0.7, grammar=my_grammar)
print(output['choices'][0]['text'])
希望这篇文章能帮到你!如果你对这个话题感兴趣,欢迎留言讨论哦~
- END -53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费场景POC验证,效果验证后签署服务协议。零风险落地应用大模型,已交付160+中大型企业
2025-03-31
常见的 AI 模型格式
2025-03-31
MetaGPT打造的OpenManus和MGX,实现:一个人即一个软件团队,实操效果太炸裂
2025-03-31
Dify 开源DeepResearch工作流实现本地和Web混合搜索并探索工作流图的正确解析方法(一)
2025-03-31
搭建本地个人知识库?有这个开源工具就够了
2025-03-31
智谱干了件好事儿,免费不限量,这是国内首个正经给用户使用的通用智能体
2025-03-31
Memobase:用户长期记忆系统开源!让AI真正"记住"每个用户的秘密武器
2025-03-31
开源嵌入式项目:轻松上手ESP32打造你的专属AI语音助手
2025-03-31
手把手教你在NAS上部署NextChat,打造你的私人ChatGPT网页应用,支持多种模型!
2025-01-01
2024-07-25
2025-01-21
2024-05-06
2024-09-20
2024-07-20
2024-06-12
2024-07-11
2024-08-13
2024-12-26
2025-03-31
2025-03-25
2025-03-25
2025-03-24
2025-03-22
2025-03-19
2025-03-17
2025-03-17