外观
结构化输出与业务正确性
1. 解决什么问题
自由文本很难可靠驱动版本保存、问题定位和素材计划。结构化输出让应用明确需要哪些字段,并拒绝缺失或不合规数据。它解决通信契约,不替代教研判断。
2. 原理与必要术语
JSON 负责可解析的表示;JSON Schema 描述对象、类型、必填项与约束;Pydantic 在应用边界验证数据。模型端 strict 约束和服务端验证形成两道检查,但“2+2=5”仍可能是合法字符串。
3. 输入、输出和执行
run_model 为每种结果生成 submit_result 函数 Schema,模型通过参数提交数据。服务端先 JSON 解析,再调用 schema.model_validate,验证通过才交给业务节点。参数错误被回传给模型修复;超过预算抛出 SchemaFailure,不保存伪造教材。
4. 混淆点
schemas.Strict 的实际配置是 extra='forbid',表示拒绝额外字段,不是 Pydantic 全局严格类型模式。某些类型仍可能按默认规则转换。业务若要求拒绝所有转换,应在对应模型上显式配置并补回归测试。
5. 最小示例
在项目 Python 环境运行,观察重复内容 ID 被拒绝:
python
from app.schemas import Lesson
block = {"id":"b1","kind":"lesson","text":"你好","translation":"Hello","answer":""}
try:
Lesson.model_validate({"title":"示例","chapters":[
{"id":"c1","title":"第一章","blocks":[block,block]}],"facts":[],"sources":[]})
except ValueError as error:
print(type(error).__name__)6. 项目中的实现
教材使用 Lesson/Chapter/Block;评审使用 Review/Issue;局部修改使用 Patch/Edit;人工操作使用 Decision。业务检查另在 business_review 进行,因此错误来源可以区分为协议错误与内容错误。
7. 源码与契约
关键位置是 system/app/schemas.py::Lesson.unique_ids、tools.py::strict_schema 和 providers.py::run_model。strict_schema 删除默认值,把对象属性设为必填并禁止额外属性,以匹配当前函数接口的严格模式要求;模型服务是否支持全部约束仍需验证。
8. 设计取舍
稳定 ID 让局部修改不依赖数组位置,增加了模型必须遵守的约束。Schema 越复杂不一定越好,应把跨字段事实关系放进可测试的业务校验。结构错误可修复原调用;业务错误应形成评审报告与新内容版本。
9. 实验与验收
在 system 目录导出与代码一致的 Schema:
bash
docker compose exec api python -m app.cli schemas
curl -s -H "X-API-Key: ${LAB_API_KEY:-}" -H 'Content-Type: application/json' \
-d '{"theme":"校园生活","scenario":"format_error"}' http://127.0.0.1:8000/api/jobs预期演示事件包含 schema_repair,但这个场景是注入畸形 JSON 后继续模板输出,不是实际模型自我修复证据。再用 business_error 创建任务,检查错误进入 Review 并产生修订版本。两条路径必须能分别解释。
10. 故障排查
字段错误先查看 Pydantic 的字段位置;重复 ID 查看全局唯一性;模型只返回正文时检查工具协议。不要用“取第一个花括号”静默截取未知文本,也不要把解析失败吞成空列表,后者会伪装成无问题评审。
11. 面试题与追问
问:Schema 合规为什么还需要评审? Schema 不能证明题目答案、译文和地区适配正确。追问:评审报告也可能错吗? 会,因此报告需要合法块 ID、证据、类别与修订要求,确定规则另行校验。人工仍是最终质量门。
再追问:结构修复是否无限进行? 不会,超过修复预算会失败,业务重试另有上限。
STAR 应用:假设实验场景,R 为应核对的证据
| 对应 | S:情境 | T:目标 | A:行动 | R:验收证据 |
|---|---|---|---|---|
| 主问 | 答案为合法字符串但计算错误 | 区分契约与内容 | Schema通过后执行业务评审 | 报告exercise问题而非JSON解析失败 |
| 追问一 | 模型报告指向不存在的块 | 阻止错误修订 | 核验评审block_id属于当前教材 | 拒绝未知ID,保留失败证据 |
| 追问二 | 模型重复提交畸形参数 | 控制修复成本 | 使用结构修复计数与终止条件 | 耗尽预算后失败,不生成空教材 |
这些是设计讨论的参考表达,实际执行前不能改写为已取得的历史成果。
12. 官方资料与版本
JSON Schema 对象、Pydantic Models、结构化输出。本项目 Pydantic 2.14.2;核验日期 2026-11-03。供应商 Schema 子集与本地业务校验能力不能等同。