[大模型冷知识]详解 Langchain 中的with_structured_output方法, 从 Langchain 框架一窥大模型的结构化输出的常见策略.
看到这个标题的朋友也许会觉得很奇怪, 一个方法有什么好解读的, 不是很简单的事情吗?看下参数有那些, 知道怎么用不就行了吗?还真不是, 生成结构化的输出是在通过 API 调用大模型处理任务时最普遍的一个能力诉求.模型结构化输出的能力即可以方便解析模型输出, 也能方便函数函数调用,允许模型带有 FunctionCall 的能力. 同时模型稳定的结构化输出还有助于提升 Agent 系统的稳定性, 减少
前言:
看到这个标题的朋友也许会觉得很奇怪, 一个方法有什么好解读的, 不是很简单的事情吗? 看下参数有那些, 知道怎么用不就行了吗?
还真不是, 生成结构化的输出是在通过 API 调用大模型处理任务时最普遍的一个能力诉求.模型结构化输出的能力即可以方便解析模型输出, 也能方便函数函数调用,允许模型带有 FunctionCall 的能力. 同时模型稳定的结构化输出还有助于提升 Agent 系统的稳定性, 减少结果解析带来的问题.
Langchain 中帮我们很好的抽象封装了对大模型结构化输出的策略, 使得我们不再关注各种大模型输出结果的解析细节, 从而专注于Agent 工作流的编排上. 但其实各家大模型针对结构化输出的能力是不同的, 支持的力度也不同, 有的模型原生自带结构化输出能力, 允许通过调用 API 的参数来指定结果的样式, 而有的模型原生不支持, 那么就得需要你在Prompt 中去指定输出结果,比如以 JSON 格式响应等. 所以本文就想针对这样的一个如何让大模型结构化输出的小点切入, 看 Langchain 框架中的with_structured_output背后的实现和设计思想.
with_structured_output 方法
Langchain 中提供了一种非常方便的让开发者去配置大模型的输出结果样式的方法, 就是 with_structured_output, 通过简单该方法, 就能够方便的去拿到json 结构的输出, 这对业务落地过程中, 为解析大模型的结果带来了便利. 那我们就看下with_structured_output的作用机制吧.
with_structured_output方法签名
def with_structured_output(
self,
schema: _DictOrPydanticClass | None = None,
*,
method: Literal["function_calling", "json_mode", "json_schema"] = "json_schema",
include_raw: bool = False,
strict: bool | None = None,
**kwargs: Any,
) -> Runnable[LanguageModelInput, _DictOrPydantic]:
with_structured_output本质还是一个模型包装器, 实现了将模型结果格式化成了指定的 schema, 在调用with_structured_output中必要重要的参数有两个: schema和method
-
[schema]
schema定义了输出的结构, 支持四种方式, 包括 1). OpenAI 原生格式OpenAI tool schema2).标准的JSON Schema3).python 的类型字段TypedDict以及 4).Pydantic模型类, 最后一种带有字段验证的能力, 即模型生成的值会被 Pydantic 类验证, 而其他的三种方式都是输出一个 dict, 内容不会被验证. -
[method] - 生成方法(默认:
"json_schema"), 这里是引导模型生成预设schema的策略方法,- 最最简单的策略是什么? Prompt 工程, 在提示词中指定要返回结果是 json 结构定义,但Prompt 工程的引导模型的结果是不稳定的, 所以通常需要叠加其他策略, 比如模型重试或自反馈, 即让模型自己根据报错信息重新调整输出的样式, 或者引入其他的 json 修复工具进行二次验证和修复. 总之这种策略虽然简单, 适用面也是最广的, 只要是文本生成模型就支持该策略, 但不可靠, 当下已经过时了.
- 第二种策略就是
函数调用策略, 通过工具调用来实现结构化的输出, 其实就是将结果输出伪装成工具调用, 然后从模型返回的 toolcall 信息中解析结果, 这种策略适用于所有支持工具的模型. 这其实是一种取巧的策略. - 第三种就是
JSON Schema策略, 这其实指的是模型原生支持以结构化方式响应用户的能力, 在调用模型时, 可以直接在Response Format等参数中指定json 定义, 就可以保证模型输出完全符合你定义的 schema, 无需复杂的 Prompt 工程技巧引导结果的格式, 无需重试或者额外验证. 但这种策略在使用前需要确定原生模型是否支持.
2/3 两种策略都能很好的支持模型一次就输出符合schema 定义的结果, 从而让系统更加的稳定可靠, 减少结果解析的错误处理和数据验证的复杂性. 通常优先采用, 而第一种则是作为兜底档案,在调用非常古老的模型或者小型不支持 ToolCall 以及结构化输出的模型上使用.
以上在 Langchain 中当然都会支持, 即通过
method来指定, 相对应的取值为json_mode/function_calling/json_schema,分别对应以上三种生成策略.
策略对比:
| 方法 | 原理 | 特点 | 适配范围 |
|---|---|---|---|
| json_schema | 使用 OpenAI 的 Structured Output | 输出保证完全匹配 schema,无需在 prompt 中指定格式 | 需模型原生能力支持, 如GPT-4o |
| function_calling | 使用 OpenAI 的 Tool-calling | 通过工具调用返回结构化数据,无需在 prompt 中指定格式. | 所有支持工具调用的模型 |
| json_mode | 使用 OpenAI 的 JSON mode | 需要在 prompt 中手动指定格式 | 支持所有模型 |
- 其他参数
include_raw: 设置返回值的处理方式, 是否包含原始的模型响应, 默认是false,即不包含, 在这种情况下, 如果 schema 是 Pydantic 类, 那么就返回 Pydantic 实例, 其他情况返回是一个 dict(也就是合法的 json); 如果是true, 则输出包含原始模型响应的 dict. 包含 key : [raw,parsed,parsing_error]'raw':BaseMessage- 原始 LLM 响应'parsed':如果有解析错误则为None,否则类型取决于上述 schema'parsing_error':BaseException | None- 解析错误(如果有)
结构化输出的工作流程

未完待续…
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)