代码语言

知识点思维导图

29 个知识节点

Prompt Engineering(07) - 结构化输出与格式约束

读完后,你应能完成以下任务:

  • 绘制“Prompt Engineering(07) - 结构化输出与格式约束 / 为什么格式控制这么重要”的关键对象与数据流,解释“内容没问题,但你的程序根本没法用——它要的是 {"情感": "正面", "关键词": ["服务", "价格"]} 这种能直接 json.loads 的东西,结果拿到一段大白话,还得自己写一堆字符串处理去抠。”,并用源码位置、日志或 Trace 标注证据。
  • 为“Prompt Engineering(07) - 结构化输出与格式约束 / 核心思路:说明 + 示例,双管齐下”设计正常与异常输入,验证“明确的格式说明:用文字把你要的格式、字段、类型讲清楚。 -> 一个具体的格式示例:直接给一个长成什么样的样例(这就是第 05 章的 few-shot)。”,输出首个偏差位置与回归测试结果。
  • 实现“Prompt Engineering(07) - 结构化输出与格式约束 / 让它「只输出 JSON,别说废话」的技巧”的最小代码或配置,检验“给纯净示例:示例里就只有 JSON,不带任何多余文字,模型会模仿。 -> 兜底——代码侧别全信:即便如此,模型偶尔仍会加东西。”,输出命令、结果与 Diff,并说明不适用边界。

本章目标:让模型稳定输出 JSON、表格、Markdown 等指定格式,方便你直接复制使用、或让程序解析。


一、为什么格式控制这么重要

你写了个小程序,想让模型帮你把用户评论分析成结构化数据,再存进数据库。你这样问:

分析这条评论的情感和关键词:这家店服务很好,就是有点贵。

模型回你:

这条评论整体偏正面。用户对服务表示满意("服务很好"),但对价格有些不满("有点贵")。
关键词包括:服务、价格。情感倾向为正面偏中性。

内容没问题,但你的程序根本没法用——它要的是 {"情感": "正面", "关键词": ["服务", "价格"]} 这种能直接 json.loads 的东西,结果拿到一段大白话,还得自己写一堆字符串处理去抠。

只要输出要给程序用、要批量处理、要填进表格,你就必须控制格式。 这一章讲的就是怎么让模型「按规矩出牌」。


二、核心思路:说明 + 示例,双管齐下

让格式稳定,靠两件事配合:

  1. 明确的格式说明:用文字把你要的格式、字段、类型讲清楚。
  2. 一个具体的格式示例:直接给一个长成什么样的样例(这就是第 05 章的 few-shot)。

文字说明负责讲规则,示例负责「锁死」长相。 两个一起上,比单用任何一个都稳。

来改造上面的例子:

分析下面这条评论,输出 JSON,包含三个字段:
- sentiment:情感,取值只能是 "正面"/"负面"/"中性" 之一
- keywords:关键词数组,字符串列表
- summary:一句话总结,不超过 20 字

输出格式示例:
{"sentiment": "正面", "keywords": ["质量", "物流"], "summary": "整体满意,物流给力"}

评论:这家店服务很好,就是有点贵。

模型这次会稳定输出:

{"sentiment": "正面", "keywords": ["服务", "价格"], "summary": "服务好但价格偏贵"}

字段、类型、取值范围全都对齐了。


三、让它「只输出 JSON,别说废话」的技巧

模型有个老毛病:爱在 JSON 前后加客套话,比如:

好的,这是您要的 JSON:
```json
{"sentiment": "正面"}
```text
希望对您有帮助!

这些多余文字会让 json.loads 直接报错。怎么治?几招叠加用:

  1. 明确下命令
    只输出 JSON,不要任何解释、前言或结尾文字,不要用 markdown 代码块包裹。
    
  2. 指定第一个字符
    你的回复必须以 { 开头,以 } 结尾。
    
  3. 给纯净示例:示例里就只有 JSON,不带任何多余文字,模型会模仿。
  4. 兜底——代码侧别全信:即便如此,模型偶尔仍会加东西。正确做法是程序里也做一层提取容错(本章 Demo 演示的就是这个),而不是指望提示词 100% 干净。

记住:提示词能把「翻车概率」降到很低,但要彻底稳,得「提示词约束 + 代码侧容错」两头都做。


四、其它常用格式怎么要

4.1 要表格(Markdown)

请用 Markdown 表格输出,包含「城市、人口、特色」三列,不要表格以外的任何文字。

4.2 要固定结构的 Markdown 报告

请按以下结构输出,每部分用二级标题:
## 摘要
(一段话)
## 关键发现
(3 条要点)
## 建议
(2-3 条)

4.3 要 CSV

输出 CSV,第一行为表头:name,age,city。用英文逗号分隔,不要多余空格,不要其它说明文字。

通用心法:你越是把「要什么、不要什么」说死,结果越稳。 尤其要主动声明「不要 XX」(不要解释、不要代码块、不要前言),模型很吃这套。


五、常见翻车与修复

翻车现象 原因 修复方法
JSON 前后多了解释文字 没禁止,或模型习惯性客套 加「只输出 JSON,不要任何其它文字」+ 代码侧提取
\`\`\`json 代码块包裹 模型默认习惯 加「不要用 markdown 代码块包裹」+ 代码侧剥离
JSON 不合法(缺引号、多逗号、中文引号) 模型生成失误 给清晰示例;代码侧 try/except 捕获并重试
字段名/结构每次不一样 没给明确示例 给一个完整的格式示例锁定结构
字段值类型不对(数字变字符串) 没说明类型 在说明里写清每个字段的类型和取值范围
中文标点混进 JSON("" 、) 模型中文语境下手滑 明确要求「所有标点用英文半角」

最关键的一条:对 JSON 这种要程序解析的输出,永远在代码侧再做一层提取和容错。 提示词负责降低翻车率,代码负责兜底,缺一不可。


六、一个可稳定解析的 JSON 提示词范例

把前面所有技巧整合,做一个「从简历文本抽取结构化信息」的完整范例:

你是简历信息抽取助手。从下面的简历文本中抽取信息,严格按要求输出 JSON。

字段要求:
- name:姓名,字符串
- years_experience:工作年限,整数(无法确定填 0)
- skills:技能,字符串数组
- highest_education:最高学历,取值 "高中"/"大专"/"本科"/"硕士"/"博士" 之一

输出要求:
- 只输出一个 JSON 对象,以 { 开头、} 结尾。
- 不要任何解释、前言、结尾文字,不要用代码块包裹。
- 所有标点使用英文半角。

输出示例(仅示意格式):
{"name": "张三", "years_experience": 5, "skills": ["Java", "MySQL"], "highest_education": "本科"}

简历文本:
李四,硕士毕业,从事后端开发 3 年,熟悉 Python、Go 和 Docker。

模型会稳定输出:

{"name": "李四", "years_experience": 3, "skills": ["Python", "Go", "Docker"], "highest_education": "硕士"}

这个范例同时用上了:字段说明(含类型和取值范围)、缺省值规则、明确的「只输出 JSON」约束、纯净示例。这是生产环境里抽取任务的典型写法。


七、常见错误

  1. 只用文字描述格式,不给示例:模型对「长什么样」理解不一,结构容易飘。
  2. 没说「不要多余文字」:模型默认爱加客套话和代码块,把 JSON 包起来。
  3. 字段类型/取值没说清:年限一会儿是数字一会儿是字符串,枚举值五花八门。
  4. 完全指望提示词,代码侧不做容错:偶尔一次格式翻车就让整个程序崩。
  5. 示例里带了多余文字:示例不纯净,模型有样学样也跟着加废话。
  6. JSON 里混了中文标点:没要求英文半角,模型在中文语境下写出全角引号导致解析失败。

八、最佳实践

  • 说明 + 示例双管齐下:文字讲规则,示例锁长相。
  • 把字段定义写死:每个字段的名字、类型、取值范围、缺省值都交代清楚。
  • 主动声明「不要什么」:不要解释、不要前言、不要代码块——模型很听这种话。
  • 示例保持纯净:示例里只放目标格式,不带任何多余文字。
  • 代码侧永远兜底:要程序解析的输出,一定加提取 + try/except 容错,必要时重试。
  • JSON 强制英文半角标点:避免全角符号导致解析失败。

九、本章小结

  • 只要输出要给程序用或批量处理,就必须控制格式。
  • 稳定格式靠两件事:明确的格式说明 + 一个具体示例,双管齐下。
  • 想要纯净 JSON:明确「只输出 JSON、不要多余文字、不要代码块」,并指定以 { 开头。
  • 提示词能大幅降低翻车率,但代码侧的提取与容错是必须的兜底
  • 核心心法:把「要什么、不要什么」说到死,再给个示例锁住——剩下的交给代码兜底。

下一章我们讲迭代与调试——当提示词没达到预期时,怎么科学地一步步把它「改」好,而不是靠玄学瞎试。


十、配套 Demo

提示词工程-demo/07-demo/:一个纯 Python 标准库脚本 parse_demo.py,演示当模型返回「带多余文字的 JSON」时,代码侧如何稳健地提取并解析(含异常处理),直接 python3 parse_demo.py 即可运行。README 里还给出了「能稳定产出可解析 JSON」的提示词写法。

十一、动手实践:demo:代码侧稳健解析模型返回的 JSON

这个 Demo 有一个可直接运行的 Python 脚本,演示第 07 章的核心兜底思想: 别指望提示词 100% 产出干净 JSON,代码侧一定要做提取 + 容错。

11.1 直接运行

python3 parse_demo.py

只用 Python 标准库(json + re),不联网、不装包。

11.2 脚本干了什么

parse_demo.py 内置了 5 段「模型可能返回的、不干净的响应」,逐个演示如何救回来:

样例 模拟的翻车情况 处理结果
1 JSON 前后裹着客套话 ✅ 成功提取
2 \`\`\`json 代码块包裹 ✅ 剥离后成功
3 干净 JSON(理想情况) ✅ 正常解析
4 混了中文全角标点 “”,: ✅ 清洗后成功
5 根本没有 JSON ✅ 优雅报错,不崩溃

核心步骤(见脚本注释):

  1. 剥代码块:正则去掉 \`\`\`json / ``` 围栏。
  2. 定位 JSON:靠花括号计数找出最外层 {...}(比简单截取更稳,能正确处理嵌套)。
  3. 清洗标点:把全角 “”,: 换成半角,救回中文语境下的手滑。
  4. 解析 + 兜底json.loads 包在 try/except 里,失败也返回清晰原因而不是直接崩。

配套:能稳定产出可解析 JSON 的提示词写法

代码兜底是「下半场」,提示词约束是「上半场」,两头都做才最稳。下面这个提示词把第 07 章的技巧都用上了,可直接复制:

你是信息抽取助手。从下面的文本中抽取信息,严格按要求输出 JSON。

字段要求:
- sentiment:情感,取值只能是 "正面"/"负面"/"中性" 之一
- keywords:关键词数组,字符串列表
- summary:一句话总结,不超过 20 字

输出要求:
- 只输出一个 JSON 对象,以 { 开头、以 } 结尾。
- 不要任何解释、前言、结尾文字。
- 不要用 markdown 代码块包裹。
- 所有标点使用英文半角。

输出示例(仅示意格式):
{"sentiment": "正面", "keywords": ["质量", "物流"], "summary": "整体满意物流给力"}

文本:
这家店服务很好,就是有点贵。

这套写法做了四件事,正好对应第 07 章:

  • 字段定义写死(名字、类型、取值范围);
  • 明确「只输出 JSON、不要多余文字、不要代码块」;
  • 强制英文半角标点;
  • 给一个纯净示例锁住格式。

11.3 你应该带走的结论

  • 提示词约束能把翻车概率压到很低,但不能保证 100%
  • 所以代码侧的提取 + 容错是必须的,就像本脚本演示的那样。
  • 上半场(提示词)+ 下半场(代码兜底),才是生产环境里稳定拿到结构化数据的正确姿势。

十二、总结

  • 为什么格式控制这么重要:内容没问题,但你的程序根本没法用——它要的是 {"情感": "正面", "关键词": ["服务", "价格"]} 这种能直接 json.loads 的东西,结果拿到一段大白话,还得自己写一堆字符串处理去抠。
  • 核心思路:说明 + 示例,双管齐下:明确的格式说明:用文字把你要的格式、字段、类型讲清楚。 -> 一个具体的格式示例:直接给一个长成什么样的样例(这就是第 05 章的 few-shot)。
  • 让它「只输出 JSON,别说废话」的技巧:明确下命令: -> 指定第一个字符: -> 给纯净示例:示例里就只有 JSON,不带任何多余文字,模型会模仿。 -> 兜底——代码侧别全信:即便如此,模型偶尔仍会加东西。
  • 其它常用格式怎么要:通用心法:你越是把「要什么、不要什么」说死,结果越稳。
  • 常见翻车与修复:| JSON 前后多了解释文字 | 没禁止,或模型习惯性客套 | 加「只输出 JSON,不要任何其它文字」+ 代码侧提取 |
  • 一个可稳定解析的 JSON 提示词范例:这个范例同时用上了:字段说明(含类型和取值范围)、缺省值规则、明确的「只输出 JSON」约束、纯净示例。

学完自测

选择所有正确答案;提交后逐项核对判断依据。

1在“结构化输出与格式约束”中,需要同时满足“为什么格式控制这么重要”与“核心思路:说明 + 示例,双管齐下”。给定正文约束“只要输出要给程序用、要批量处理、要填进表格,你就必须控制格式。”,哪些判断保持了原有处理机制?多选
2“结构化输出与格式约束”出现偏差:“在“结构化输出与格式约束 / 让它「只输出 JSON,别说废话」的技巧”中,即使不满足“正确做法是程序里也做一层提取容错(本章 Demo 演示的就是这个),而不是指望提示词 100% 干净”,结果与副作用仍会保持不变。”已成为实际行为。围绕“让它「只输出 JSON,别说废话」的技巧”与“要 CSV”,哪些判断能定位被改变的职责或边界?多选
3评审“结构化输出与格式约束”方案时,验收条件包含“提示词负责降低翻车率,代码负责兜底,缺一不可。”。关于“常见翻车与修复”与“一个可稳定解析的 JSON 提示词范例”的哪些决策符合正文机制?多选