xyooyx
V2EX  ›  问与答

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

  •  
  •   xyooyx · Jun 2, 2024 · 9496 views
    This topic created in 889 days ago, the information mentioned may be changed or developed.
    • 最近遇到一个问题,无论我用哪家(智谱、moonshot 、DeepSeek...等)都会存在有一定概率回复带引导词,或非完整的 json:
    {
        "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
    }
    
    • 上述 content 字段中期望的理想的是只有纯粹的 json ,但实际字段中多出了“根据您提供的信息,我为您做了以下规划:\n\n```json\n”,并且是 markdown 格式的
    • 尽管我已经在 prompt 中加入了“参照以下格式输出,直接给出规划的结果,不需要添加任何引导性文本,输出的结果符合标准 json 格式{someKey:someValue}”。 想请教下各位是怎么解决的
    Supplement 1  ·  Jun 9, 2025

    以下是spring ai项目中使用的prompt实测能够达到比较高的约束力,给各位朋友提供个思路:

    Your response should be in JSON format.Do not include any explanations, only provide a RFC8259 compliant JSON response following this format without deviation.Do not include markdown code blocks in your response.Remove the ```json markdown from the output.Here is the JSON Schema instance your output must adhere to: ```{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"someString":{"type":"string"}},"additionalProperties":false}```
    
    33 replies  •  2024-06-05 23:02:36 +08:00
    mekingname
    mekingname
    Jun 2, 2024❤️3
    1
    我使用 tool calling 来实现。

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

    ## 输出要求
    你的输出为 JSON 格式的字符串,压缩在一行内,包含两个字段,"KeyA"代表 XX ,"KeyB"代表 XX

    以下是一个输出示例
    leehaoze98
    leehaoze98
    Jun 2, 2024❤️1
    26
    不小心发出去了,续楼上:

    以下是一个输出示例:
    {"KeyA":"ValA","KeyB":"ValB"}

    通过举例子的方法约束吼,只能保证返回的 JSON 大概率是你要求的格式,但是模型还是有概率在 JSON 后追加一些自然语言来进行解释,或者是加入 MarkDown 语法(有些模型就这么调的)。

    这个时候只能是对大模型的返回进行处理,已经有些现成的库,比如 LangChain 的 Parser ,Python 、TS 和 Go 都有一个 JSON Repair 库。

    只能是多种策略一起用,完全指望模型,代价高不稳定
    xyooyx
    xyooyx
    OP
    Jun 2, 2024
    27
    @Cyron 晚些试了下,不知道是否是我调用的 API 问题,我参照文内编辑了 prompt ,整体输出质量是提高了,但是还是会出现类似```json 这样的 markdonw 头,好在简单的 substring 可以处理
    cheng6563
    cheng6563
    Jun 3, 2024
    28
    问题是语言模型你不让他滔滔不绝说一堆的话,他的智力会有不少限制。
    yangyaofei
    yangyaofei
    Jun 3, 2024
    29
    用 CFG 去控制, 比如 Guidance 和 OutLines 这种项目
    RRRoger
    RRRoger
    Jun 3, 2024
    30
    https://mp.weixin.qq.com/s/gMdQBlTdvGbhzi_NL3HGXQ
    大语言模型下的 JSON 数据格式交互
    zhangwugui
    zhangwugui
    Jun 3, 2024
    31
    那返回 json 的话,还能流式输出么
    Cyron
    Cyron
    Jun 3, 2024
    32
    @lqw3030 #27 是的文本补全只能自己处理,如果想要 100%可用的 JSON 就用大模型的 JSON Mode ,参考 https://platform.openai.com/docs/guides/text-generation/json-mode
    Ironpan
    Ironpan
    Jun 5, 2024
    33
    1. function_call/tools 能力
    2. 模型支持直接 mode 为 json 的, 例如 gpt-3.5 好像现在就行了?
    3. prompt: ReAct/Few shot(带几个例子进去)/langextract 里面有个提取结构化数据的核心 prompt 可以去找找, 然后改改
    4. 一些细节:
    4.1 prompt 使用 markdown 格式, 且添加标题, 如果返回的 json 里有注释, 你可以用 markdown 的格式添加注意事项叫它不要输出其他无关的内容, 或者不要加注释.
    4.2 上下文里不一定都是一个 human+ai 的成对消息. 可以是一个 system message + 一个/多个 ai 消息(补充说明) + user 消息. 然后自己看情况调整.
    4.3 我自己使用的时候返回的 json, 一般都是 markdown, 然后正则解析.

    希望有所帮助.
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1588 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 86ms · UTC 07:40 · PVG 15:40 · LAX 23:40 · JFK 02:40
    ♥ Do have faith in what you're doing.