LangChain structured output 怎样固定工具返回 schema
如果 agent 调用工具后仍然返回一段不稳定的自然语言,问题通常不在“提示词写得不够长”,而在 schema 绑定错了位置。LangChain 里至少有两个边界:工具的输入参数 schema,以及 agent 最终交给业务代码的结构化响应。要固定后者,应把 Pydantic 模型交给 response_format,需要明确走工具调用时使用 ToolStrategy,再从结果的 structured_response 读取。
官方地址:https://docs.langchain.com/
下面用一个订单查询工具作为例子。示例中的指标是用于设计验收的基线,不代表 LangChain 官方性能承诺。
先把两个 schema 边界分开
工具参数描述“模型怎样调用工具”,例如订单号是什么类型;结构化响应描述“agent 最终交给应用的结果”,例如订单状态、是否需要人工处理和解释。只给工具函数写返回类型,并不会自动把整个 agent 的最终输出固定成这个类型。
| 边界 | 绑定位置 | 业务代码读取 |
|---|---|---|
| 工具输入 | 类型注解或 args_schema | 工具函数参数 |
| agent 最终结果 | response_format + Pydantic | state["structured_response"] |

用 Pydantic 把业务结果写成可校验结构
先定义一个足够小的结果模型。字段描述会进入模型可见的 schema,枚举和范围约束则让错误结果有明确的修正方向。
from typing import Literal
from pydantic import BaseModel, Field
class OrderDecision(BaseModel):
"""订单查询后交给业务层的固定结果。"""
order_id: str = Field(description="用户提供的订单号")
status: Literal["pending", "paid", "shipped", "cancelled"]
needs_human: bool = Field(description="是否需要人工跟进")
reason: str = Field(description="给业务人员看的简短原因")
# 约束写在模型中,后续的 agent 不必依赖字符串解析。
print(OrderDecision.model_json_schema()["properties"].keys())
这里的 Literal 限制状态集合,needs_human 明确为布尔值。不要为了“兼容模型”把所有字段都改成字符串,否则结构看似固定,业务层仍要二次猜测。
用 ToolStrategy 固定 agent 的最终响应
当模型支持工具调用、但不一定支持 provider-native structured output 时,显式使用 ToolStrategy 最直观。工具只负责查数据,response_format 负责把 agent 的最终结果收口。
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
def lookup_order(order_id: str) -> str:
"""按订单号查询脱敏后的订单状态。"""
# 示例返回固定文本;真实项目应在这里访问订单服务并处理超时。
return f"订单 {order_id} 已发货,物流单号为 SF123456"
agent = create_agent(
model="openai:gpt-5.5",
tools=[lookup_order],
response_format=ToolStrategy(OrderDecision),
system_prompt=(
"你是订单助手。只能根据工具返回的信息填写 schema,"
"不能补造订单号、状态或物流事实。"
),
)
result = agent.invoke({
"messages": [{
"role": "user",
"content": "查询订单 A-1007 的状态,并告诉我是否需要人工处理。"
}]
})
# 业务层读取结构化对象,而不是解析最后一条自然语言消息。
decision = result["structured_response"]
print(decision.order_id, decision.status, decision.needs_human)
这个组合形成两步约束:模型先按工具定义生成调用参数,工具执行后再按 OrderDecision 生成唯一的结构化响应。若模型或 provider 不支持原生结构化输出,LangChain 会用工具调用策略完成这一步。
让校验失败反馈给模型,而不是静默吞掉
ToolStrategy 默认会处理结构化输出错误。生产代码可以把提示改成业务语言,让重试针对字段约束,而不是无限重复同一个请求。
from langchain.agents import create_agent
from langchain.agents.structured_output import ToolStrategy
agent = create_agent(
model="openai:gpt-5.5",
tools=[lookup_order],
response_format=ToolStrategy(
schema=OrderDecision,
# 只说明如何修正格式,不把业务事实写死在错误提示里。
handle_errors="请重新输出单个 OrderDecision:status 必须是允许的四个值,needs_human 必须是布尔值。",
tool_message_content="订单结果已按固定 schema 整理。",
),
)
# 真实项目应记录重试次数,避免把模型错误变成无上限成本。
result = agent.invoke({
"messages": [{"role": "user", "content": "查询订单 A-1007"}]
})
print(result["structured_response"].model_dump())
如果应用希望所有异常直接抛出,可以把 handle_errors 设为 False;如果只想捕获某一类异常,也可以传入异常类型或自定义处理函数。注意:重试只能修正结构,不会替你验证订单服务返回的事实。

用一组小指标判断 schema 是否真的稳定
可以把验收拆成三项,而不是只看“这次返回成功”。例如对一组包含已发货、待付款和信息不足的固定样例,记录结构通过率、人工兜底率和平均重试次数:
| 指标 | 基线写法 | 目标判断 |
|---|---|---|
| 结构通过率 | 自然语言 + 手写解析 | 应接近全部样例都能通过模型校验 |
| 人工兜底率 | 字段缺失时靠业务猜测 | 只在事实缺失或规则冲突时触发 |
| 平均重试次数 | 默认提示不记录 | 按模型、字段约束和输入类型分组观察 |
不要把“结构通过率提高”直接等同于“答案正确”。schema 只能保证形状、类型和部分范围;订单状态是否真实,仍要由工具服务、权限和业务规则负责。
工具多、模型能力不同的时候怎么选
如果模型供应商原生支持结构化输出,可以直接传 schema 类型,让 LangChain 自动选择 provider strategy;需要兼容更多支持 tool calling 的模型时,显式使用 ToolStrategy。当 agent 同时绑定普通工具和结构化响应时,模型还必须支持两者并用。
最后记住三个边界:
- 工具的返回字符串不是最终 schema;要固定 agent 结果,就配置
response_format。 structured_response是结果读取入口,不能再从自然语言消息中二次正则解析。- 多个结构化结果、字段校验失败和真实业务事实错误是三类问题,应分别记录和处理。
常见问题
只给工具函数加返回类型可以吗? 可以帮助阅读和静态检查,但不能替代 agent 的 response_format。
为什么用了 Pydantic 仍然会重试? Pydantic 负责校验结果;模型第一次生成的字段仍可能越界或缺失,handle_errors 会把错误反馈给模型。
工具本身也需要输入 schema 怎么办? 给工具参数添加类型注解,或使用 args_schema 绑定一个独立的 Pydantic 输入模型;它和最终响应模型可以不同。
vLLM continuous batching 的请求调度观察点
- 上一篇
- vLLM continuous batching 的请求调度观察点
- 下一篇
- OpenAI Responses API 的 tool call 状态怎样串联
-
- 科技周边 · 人工智能 | 1小时前 |
- PyTorch autograd anomaly detection 怎样定位 NaN 梯度
- 248浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- OpenAI Responses API 的 tool call 状态怎样串联
- 253浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- vLLM continuous batching 的请求调度观察点
- 211浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- ONNX Runtime IO Binding 怎样减少 GPU 张量拷贝
- 424浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- PyTorch DataLoader persistent_workers 的进程生命周期
- 435浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- PyTorch DataLoader 如何限制预取批次避免共享内存耗尽
- 265浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Transformers generate 怎样读取每条序列的分数
- 249浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- PyTorch CUDA Graph 怎样固定输入形状复用推理流程
- 471浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Hugging Face Datasets 怎样用 map 批处理并保留列
- 329浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 | 人工智能 ·
- Transformers quantization picker 怎样按硬件选择量化方式
- 120浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- Transformers PEFT adapter 怎样只保存可训练权重
- 422浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- QLoRA 的 nf4 与 double quant 参数配置方法
- 284浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 820次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 811次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 903次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 873次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 695次使用
-
- Python Pydantic v2 实战:TypeAdapter 别在请求里反复造
- 2026-06-03 342浏览
-
- RAG 知识库怎么防提示词注入:外部文档只能当资料,不能当指令
- 2026-07-17 149浏览
-
- AI 工具调用部分成功怎么处理:结果状态、补偿动作与重试边界
- 2026-08-25 460浏览
-
- MCP 工具结果分页怎么设计:游标失效、重复项与增量验收
- 2026-08-25 269浏览
-
- AI 工具调用如何处理超时重试:幂等键、部分结果与人工接管
- 2026-08-27 195浏览

