大家是如何限制 LLM 输出格式为 JSON

2024-06-02 10:34:48 +08:00
 lqw3030
{
    "usage": {
        "prompt_tokens": 185,
        "completion_tokens": 304,
        "total_tokens": 489
    },
    "created": 1717295221,
    "model": "GLM-4",
    "id": "123",
    "error": null,
    "choices": [
        {
            "finish_reason": "stop",
            "index": 0,
            "message": {
                "role": "assistant",
                "content": "根据您提供的信息,我为您做了以下规划:\n\n```json\n{\n  \"planDays\": [\n    {\n      \"dayPlanOrder\": 0,\n      \"dayStations\": [\n        {\n          \"stationName\": \"腾格里沙漠\",\n          \"stationOrder\": 0,\n          \"stationDescription\": \"中国第四大沙漠,体验沙漠探险和沙丘摩托\",\n          \"stationTag\": \"探险,自然景观\",\n          \"stationActivity\": \"沙漠徒步,骑骆驼,沙丘摩托\",\n          \"timeUsed\": 120\n        },\n        {\n          \"stationName\": \"贺兰山\",\n          \"stationOrder\": 1,\n          \"stationDescription\": \"阿拉善著名景点,参观贺兰山岩画\",\n          \"stationTag\": \"历史,文化,自然景观\",\n          \"stationActivity\": \"参观岩画,登山\",\n          \"timeUsed\": 90\n        },\n        {\n          \"stationName\": \"巴丹吉林沙漠\",\n          \"stationOrder\": 2,\n          \"stationDescription\": \"中国第三大沙漠,欣赏沙漠日落\",\n          \"stationTag\": \"自然景观\",\n          \"stationActivity\": \"欣赏日落\",\n          \"timeUsed\": 60\n        }\n      ]\n    }\n  ]\n}\n```\n\n 这个行程涵盖了阿拉善的主要景点,您可以根据个人兴趣选择参加的活动。如果选择自驾出行,可以在景点附近寻找停车场。祝您在阿拉善度过愉快的一天!",
                "name": null,
                "tool_call_id": null,
                "tool_calls": null
            },
            "delta": null
        }
    ],
    "task_id": null,
    "request_id": null,
    "task_status": null
}
6868 次点击
所在节点    问与答
33 条回复
mekingname
2024-06-02 10:41:04 +08:00
我使用 tool calling 来实现。

定义一个函数,接受 n 个参数,这些参数就是你的 json 里面对应的各个字段。然后让大模型通过 tool calling 去调用这个函数就可以了。在函数里面拿到这些参数,就是你需要的已经格式化以后的数据。
lqw3030
2024-06-02 10:44:55 +08:00
@mekingname tool/funcation call 有碰到过非期望响应的情况不
yinmin
2024-06-02 10:45:55 +08:00
调用 api 时,可以是多组对话,因此,你加几组“一问一答”到 message 里,给 gpt 做参考,而不是写在一条信息里
maolon
2024-06-02 10:48:54 +08:00
可能无关: gpt 可以指定 return as json object ,以及比较好奇楼上的 tool calling 能否解决嵌套字段问题?
mumbler
2024-06-02 11:32:44 +08:00
指令跟随能力还是不够好,我用 gemini ,可以设置"response_mime_type": "application/json",几乎没遇到过加料的情况
june4
2024-06-02 11:36:00 +08:00
就象楼上说的,给几个例子基本不可能出意外。
yorhaha123
2024-06-02 11:38:35 +08:00
直接用正则表达式提取了
yushi17
2024-06-02 11:56:55 +08:00
没有必要让大模型输出纯粹的 json 。你只要从里面找到 json 然后 parse 出来就行了。
yushi17
2024-06-02 11:58:09 +08:00
可以参考 TypeChat: https://github.com/microsoft/TypeChat 就是我说的这个思路。
izzy27
2024-06-02 12:24:29 +08:00
langchain 的 json parser
m0unta1n886
2024-06-02 13:44:19 +08:00
有个 github 项目专门处理这个问题的。
codehz
2024-06-02 13:45:09 +08:00
有些模型是自带这个的,不是我打广告,但是 minimax 那家是真的有,最关键是还能限制 json 格式,用一个类似 json schema 的语法
(虽然实际用下来 bug 不少,尤其是和 array 类型配合,还是和模型本身的基础能力有关系。。。)
akira
2024-06-02 13:46:08 +08:00
gpt 的话,有参数可以限制输出格式
devliu1
2024-06-02 14:22:07 +08:00
gpt 可以直接指定
lqw3030
2024-06-02 14:24:59 +08:00
@m0unta1n886 https://github.com/RealAlexandreAI/json-repair 这个吗,我现在的做法是直接读取第一个{和最后一个},想说从语言模型本身出发解决这个问题
lqw3030
2024-06-02 14:27:09 +08:00
@yinmin 我去尝试下,先前的 prompt 模板都是参照 https://baoyu.io/translations/prompt-engineering/how-i-won-singapores-gpt-4-prompt-engineering-competition 里面建议的思路写的,我觉得你说的这个是个好主意👍
lqw3030
2024-06-02 14:29:07 +08:00
@maolon funcation 确实 function call 就是复杂的结构不好指定
lqw3030
2024-06-02 14:35:27 +08:00
@mumbler 我觉得可以这么指是最好得了,受限于调用环境,用的都是国内厂商的模型
Cyron
2024-06-02 14:47:48 +08:00
之前做了几个试验性项目,用 dsl 约束+json_mode 效果稳定,写了个总结
《 LLM 生成 Json 结构化数据的几种方案》 https://juejin.cn/post/7325429835387404307
shampoo
2024-06-02 16:43:35 +08:00
题外话,做程序要讲究思维严谨、语义清晰:
“限制输出格式为 JSON”这句话有歧义,应该改为“指定输出格式为 JSON 。”

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1046076

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX