我在之前的文章《模型吐出来的总是一段话,怎么让它乖乖按格式返回?》里讲的是模型这一层的结构化输出,把 schema 绑到模型上,返回的字段就固定了。
Agent 这一层的结构化输出,配的是另一个参数:
create_agent 上的 response_format。
文章的末尾提过这个参数,说有三种选择。
官方文档 Agent 那一节把这几种选择都列了出来,多出来的那一种是默认的 None,表示不启用结构化输出。
四种之间,用的机制不一样,能用的模型也不一样,这篇逐个拆开。
用供应商的原生结构化输出
ProviderStrategy 走的是模型供应商自己的原生结构化输出能力。
原生结构化输出指的是,供应商在 API 这一层就提供了格式约束,模型响应的时候,输出要落在预先定好的规范里。
schema 传给供应商,返回的结果已经过了一道格式关。
前提是模型得支持这项能力,而支持它的只有一部分模型。
OpenAI、Anthropic、Grok 这些是常见的几家,具体名单以各家的接口文档为准。
这些模型如果是通过中转服务去调,原生结构化输出能力未必还能用上。
from langchain.agents import create_agent
from langchain.agents.structured_output import ProviderStrategy
agent = create_agent(
model=model,
tools=[],
response_format=ProviderStrategy(Contact), # 明确要求走供应商的原生结构化输出
)
result = agent.invoke({"messages": [{"role": "user", "content": "..."}]})
result["structured_response"] # 结构化结果落在最终状态的这个键里
借一次工具调用绕过去
模型没有原生结构化输出能力的时候,改用 ToolStrategy,通过工具调用产生结构化数据。
做法是 LangChain 把 schema 转成一个虚拟工具,只有参数,没有实际动作。
这个工具的参数定义,对应着你期望的字段结构。
模型要给最终答案的时候,框架引导它去调这个虚拟工具,参数填进去,符合要求的结构化数据就跟着出来了。
ToolStrategy 不依赖模型的原生结构化输出能力,只要模型支持工具调用就能用,兼容面最广。
生产环境和日常写代码,它更常见。
只传类型,让框架自己挑
还有一种是省掉指定策略这一步,直接把定义好的 schema 类型传给 response_format。
schema 就是你要的字段结构:
有哪些字段、各是什么类型,都写在里面。
LangChain 拿到类型之后,会按模型能力自己选。
模型原生支持结构化输出,就走 ProviderStrategy,不支持就走 ToolStrategy。
选哪种策略,由框架去定,你这边只说清楚要哪些字段。
日常开发里我更推荐这一种,省掉先确认模型有没有原生结构化输出能力这一步。
不做结构化输出
None 是 response_format 的默认值,表示这一次不按结构化格式返回。
Agent 照旧用自然语言回答问题。
四种怎么挑
| 选择 | 核心机制 | 什么时候用它 |
|---|---|---|
ProviderStrategy | 用模型供应商的原生结构化输出 | 模型有原生结构化输出能力,要格式保证最可靠的那条 |
ToolStrategy | 把 schema 转成一次工具调用的参数 | 模型没有原生结构化输出能力,或者需要兼容面最广的方案 |
| 直接给 schema 类型 | LangChain 按模型能力在 ProviderStrategy 和 ToolStrategy 之间选 | 不想先判断模型能力,让框架去挑 |
None | 不启用结构化输出 | 不需要结构化数据,正常对话 |