大模型提取结构化JSON——生产级

张开发
2026/4/14 8:16:55 15 分钟阅读

分享文章

大模型提取结构化JSON——生产级
目录输出结构化符合预期的JsonPhase 1: 提示工程约束 (Prompt Engineering)Phase 2: 原生协议控制 (Native Protocol Control)深入浅出:如何用 Function Calling 提取结构化数据第一步:把“提取动作”包装成一个“函数说明 (Schema)”第二步:向大模型发起对话请求第三步:见证奇迹!大模型不再返回普通文本了第四步:在你的代码里直接拿来用总结Phase 3: 解码拦截 - 核心 (Decoding Interception)深入浅出:解码拦截与 Outlines 状态机 (Decoding Interception)一、 大白话原理解析:如何“捂住大模型的嘴”?1. 大模型的“打字机”原理2. FSM (有限状态机) 的介入:随身监工二、 Python 代码实战1.使用 Outlines 库2. OpenAI协议自带校验器三、 为什么解码拦截(Phase 3)是“终极杀器”?优势 1:100% 的语法正确率优势 2:节省 Token 和算力劣势:Phase 4: 解析自愈与重试 (Parsing Self-healing and Retry)总结输出结构化符合预期的Json四个阶段(Phase 1 - Phase 4):Phase 1: 提示工程约束 (Prompt Engineering)大白话:在你提问的时候,明明白白地告诉大模型你要什么格式,并且给它打个样。提供 JSON Schema:把上面 Pydantic 定义的类转换成 JSON 结构说明(Schema)丢给大模型。告诉它:“你必须返回包含 name, age, email 的 JSON,age 必须是数字”。Few-shot 示例 (少样本提示):仅仅说还不够,直接给例子。输入给大模型的 Prompt 示例:提取用户信息。例子1:输入:"我是张三,今年25岁,邮箱是zs@qq.com"输出:{"name": "张三", "age": 25, "email": "zs@qq.com"}例子2:输入:"李四昨天刚满三十,联系方式lisi@gmail.com"输出:{"name": "李四", "age": 30, "email": "lisi@gmail.com"}现在请处理:输入:"老王今年40了,wang@163.com是他的邮箱。"输出:Phase 2: 原生协议控制 (Native Protocol Control)大白话:很多主流大模型(如 OpenAI, Claude, 智谱等)已经在 API 层面提供了强制输出 JSON 的开关,直接把开关打开。JSON Mode:在调用 API 时,直接加上参数response_format={ "type": "json_object" }。这会让大模型在底层偏向于生成合法的 JSON 字符串。Function Calling (工具调用):把你需要的提取动作包装成一个“函数”。大模型不会直接回复文本,而是返回一个调用该函数的指令,里面的参数天然就是结构化好的name,age,email。深入浅出:如何用 Function Calling 提取结构化数据在之前的“四层防御体系”中,我们提到了Phase 2: 原生协议控制里的Function Calling(工具调用)。传统的做法是“求”大模型:“请你输出JSON格式”。 而 Function Calling 的逻辑是“骗”大模型:“我现在有一个系统函数,需要你帮我把参数填满,你去调用它。”为了让你直观理解,我们用 OpenAI 的 API 格式(这也是目前行业的通用标准)来模拟这个场景:提取「姓名」、「年龄」和「邮箱」。第一步:把“提取动作”包装成一个“函数说明 (Schema)”在大模型的世界里,你不需要真的写一个能在它那里运行的函数,你只需要告诉它有这个函数存在,以及这个函数需要什么参数。我们定义一个假想的函数叫save_user_profile(保存用户档案)。在传给大模型的 API 时,我们会带上下面这段 JSON 描述(也就是工具箱/Tools):{ "name": "save_user_profile", "description": "从自然语言文本中提取用户信息,并保存到数据库中。", "parameters": { "type": "object", "properties": { "name": { "type": "string", "description": "用户的姓名,例如:张三、老王" }, "age": { "type": "integer", "description": "用户的年龄,必须是纯数字,例如:40" }, "email": { "type": "string", "description": "用户的电子邮箱地址" } }, "required": ["name", "age", "email"] } }大白话翻译:告诉大模型“我这里有个抽屉叫save_user_profile,里面有三个格子,分别只能放字符串名字、数字年龄、字符串邮箱。你得帮我把格子填满。”第二步:向大模型发起对话请求现在,我们把用户的输入文本,连同刚才的函数说明(Tools)一起扔给大模型。# 伪代码示例 response = client.chat.completions.create( model="gpt-4o", # 或者其他支持工具调用的模型 messages=[ {"role": "user", "content": "老王今年40了,wang@163.com是他的邮箱。"} ], tools=[ { "type": "function", "function": { /* 这里放的就是第一步里的那段 JSON Schema */ } } ], # 强制让大模型必须调用我们提供的函数 tool_choice={"type": "function", "function": {"name": "save_user_profile"}} )

更多文章