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

167 天前
 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
}
4679 次点击
所在节点    问与答
33 条回复
TheWalkingDead
166 天前
@shampoo 你这真的是钻牛角尖,此地无银三百两。
mekingname
166 天前
@lqw3030 JSON 不能嵌套太深,否则可能拿到的结果跟预期不一致。
wuyiccc
166 天前
用的 langchain 的 output parser
macaodoll
166 天前
国产的如果涉及到某些敏感词直接不按提示来的,用外面的没这个问题
leehaoze98
166 天前
模型本身支持限定输出为格式为 application/json 这种的效果最好,本身就是微调在模型内的。
通过 Prompt 的方式约束,直接在 Prompt 内举出一个返回的示例效果是最好的,比如:

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

以下是一个输出示例
leehaoze98
166 天前
不小心发出去了,续楼上:

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

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

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

只能是多种策略一起用,完全指望模型,代价高不稳定
lqw3030
166 天前
@Cyron 晚些试了下,不知道是否是我调用的 API 问题,我参照文内编辑了 prompt ,整体输出质量是提高了,但是还是会出现类似```json 这样的 markdonw 头,好在简单的 substring 可以处理
cheng6563
166 天前
问题是语言模型你不让他滔滔不绝说一堆的话,他的智力会有不少限制。
yangyaofei
166 天前
用 CFG 去控制, 比如 Guidance 和 OutLines 这种项目
RRRoger
166 天前
https://mp.weixin.qq.com/s/gMdQBlTdvGbhzi_NL3HGXQ
大语言模型下的 JSON 数据格式交互
zhangwugui
166 天前
那返回 json 的话,还能流式输出么
Cyron
165 天前
@lqw3030 #27 是的文本补全只能自己处理,如果想要 100%可用的 JSON 就用大模型的 JSON Mode ,参考 https://platform.openai.com/docs/guides/text-generation/json-mode
Ironpan
163 天前
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, 然后正则解析.

希望有所帮助.

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

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

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

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

© 2021 V2EX