🎯 课程主题
JSON Schema 是 LangChain 支持的第三种结构化输出格式,需要手动拼接 JSON Schema 字符串来定义结构,但因其繁琐易错,实际开发中不推荐使用。
📝 核心知识点
1. JSON Schema 的定义方式
- 概念说明:按照 JSON Schema 规范,通过拼接 JSON 字符串来定义数据结构,包括字段类型(
type)、描述(description)、必填项(required)等。 - 关键细节:
- 需要定义
title(相当于类名)、description(结构描述)、type: "object"(表示 JSON 对象) properties中逐一列出字段及其类型和描述required数组列出必填字段(类似 TypedDict 中的...语义)description可写中文,但 JSON Schema 的 key 必须使用英文
- 需要定义
2. 四种格式的推荐优先级
- 概念说明:在实际开发中,结构化输出格式的选择优先级为:Pydantic > TypedDict > JSON Schema(@dataclass 亦不推荐)。
- 关键细节:
- Pydantic:首推,类类型输出,强校验
- TypedDict:次选,适合简单字典结构
- JSON Schema:繁琐、容易出错、不推荐
- @dataclass:亦不如 TypedDict 推荐
3. method 参数说明
- 概念说明:
with_structured_output()中可传入method参数指定结构化输出方式,其可用性依赖于模型供应商和 LangChain 适配器的实现。 - 关键细节:
- 默认值:
method="function_calling"(不传时的默认行为) - 使用 JSON Schema 时需显式指定:
method="json_schema" - 部分模型(如 DeepSeek)不支持某些 method
- 默认值:
4. 嵌套 JSON Schema
- 概念说明:JSON Schema 同样支持嵌套结构,如电影信息中嵌套演员列表。
- 关键细节:
- 演员字段类型设为
"array",items 再嵌套"object" - 嵌套越深,JSON Schema 字符串越复杂,越容易写错
- 复杂的嵌套场景强烈建议用 TypedDict 替代
- 演员字段类型设为
🏗️ 架构与工作流
- 手动编写 JSON Schema 字典/字符串
- 通过
model.with_structured_output(json_schema, method="json_schema")绑定 - 调用
invoke()传入自然语言获取结构化结果 - 输出结果为
dict类型
💻 代码实战
# 定义 JSON Schema 结构(基本版)
json_schema = {
"title": "Movie",
"description": "电影信息结构",
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "电影名称",
},
"year": {
"type": "integer",
"description": "上映年份",
},
"director": {
"type": "string",
"description": "导演",
},
"rating": {
"type": "number",
"description": "评分",
},
},
"required": ["title", "year", "director", "rating"],
}
# 嵌套版本(含演员列表)
json_schema_nested = {
"title": "MovieInfo",
"description": "包含演员的电影信息",
"type": "object",
"properties": {
"title": {"type": "string", "description": "电影名称"},
"year": {"type": "integer", "description": "上映年份"},
"director": {"type": "string", "description": "导演"},
"rating": {"type": "number", "description": "评分"},
"actors": {
"type": "array",
"description": "演员列表",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "演员名字"},
"role": {"type": "string", "description": "饰演角色"},
},
},
},
},
"required": ["title", "year", "director", "rating", "actors"],
}
# 绑定并调用
structured_model = model.with_structured_output(json_schema, method="json_schema")
response = structured_model.invoke("给我介绍一下盗梦空间")
print(response) # dict 类型
print(type(response)) # <class 'dict'>
⚠️ 常见问题与避坑指南
- JSON Schema 手写极易出错:结构复杂时,花括号、逗号、引号嵌套很容易写出语法错误,建议用 TypedDict 替代。
- 字段名必须英文:JSON Schema 的 key 只能使用英文,但
description字段支持中文。 - method 参数必须匹配:使用 JSON Schema 时必须传
method="json_schema",否则默认走function_calling模式。 - 部分模型不支持 json_schema 模式:如 DeepSeek 等模型可能不兼容该 method。
💡 个人总结与延伸
JSON Schema 方式仅作了解即可,实际开发中几乎不需要手写。对于 dict 类型的结构化输出,TypedDict 提供了等价的声明能力和更好的开发体验。JSON Schema 的价值更多体现在跨语言/跨系统的数据格式约定中,而非 LangChain 应用开发。