【自然语言处理与大模型】LangChainV1.0入门指南:核心组件Structured Output

在LangChain中一些模型提供者通过其 API 原生支持结构化输出(例如 OpenAI、Grok、Gemini)。这是最可靠的方法。当对于不支持原生结构化输出的模型,LangChain 使用工具调用来实现相同的结果。这种方法适用于所有支持工具调用的模型,而大多数现代模型都支持工具调用。下面是LangChain所提供的两种结构化输出的核心策略对比

策略 适用场景 原理
ProviderStrategy 模型原生支持结构化输出(如 OpenAI GPT-4o/GPT-5、Grok) 利用模型 API 的 response_format={ "type": "json_schema" } 等机制,由模型提供商强制约束输出格式
ToolStrategy 其他支持工具调用的模型(如 Claude、Llama 3 via API) 将你的 schema 包装成一个"虚拟工具",模型通过 tool call 返回结构化参数

一、with_structured_output方法让模型能够结构化输出

python 复制代码
from langchain.chat_models import init_chat_model

# 初始化一个支持结构化输出的大语言模型(此处使用 DeepSeek)
# 注意:DeepSeek 官方 API 是否原生支持结构化输出需确认;
# 若不支持,LangChain 会自动回退到 ToolStrategy(工具调用)方式实现结构化输出。
model = init_chat_model("deepseek-chat")

# 自定义结构化输出的数据模式(Schema)
# 使用 Pydantic BaseModel 定义期望的输出结构,字段带描述可显著提升模型理解准确性
from pydantic import BaseModel, Field

class MovieInput(BaseModel):
    """从文本中提取的电影信息结构"""
    name: str = Field(..., description="电影的名字")
    publish: str = Field(..., description="电影上映时间,格式如 '2009' 或 '2009年'")
    director: str = Field(..., description="电影的导演姓名")

# 使用 .with_structured_output() 方法将原始模型包装为结构化输出模型
# 该方法会根据模型能力自动选择最佳实现策略:
#   - 若模型原生支持 JSON Schema(如 GPT-4o),则使用 ProviderStrategy;
#   - 否则,通过工具调用(Tool Calling)模拟结构化输出(ToolStrategy)。
# 包装后的 structured_model.invoke() 将直接返回 MovieInput 类型的实例,而非字符串。
structured_model = model.with_structured_output(MovieInput)

# 输入一段包含电影信息的非结构化文本
text = "《阿凡达》(Avatar, 2009)导演:詹姆斯·卡梅隆。在不远的未来,地球资源枯竭,人类将目光投向4.4光年外的潘多拉星球。一颗蕴藏稀有矿产"难得素"的神秘世界。为开采资源,人类启动"阿凡达计划",通过基因技术创造出可由人类意识操控的纳美人混血躯体。"

# 调用结构化模型,自动从 text 中提取并返回符合 MovieInput 模式的对象
result = structured_model.invoke(text)

# result 是一个 MovieInput 实例,可直接访问属性或转为 JSON
print(result)
# 示例输出:MovieInput(name='阿凡达', publish='2009', director='詹姆斯·卡梅隆')

对于 DeepSeek ,目前其开源模型(如通过 vLLM 部署)通常不原生支持 JSON Schema 输出 ,因此 LangChain 会采用 ToolStrategy ------ 这意味着模型实际是通过"调用一个虚拟工具"来返回结构化参数,效果依然可靠。

二、response_format参数直接让Agent具备结构化输出能力

在 LangChain 1.0 中,最直接、最推荐的方式 让 Agent 具备结构化输出能力,就是在调用 create_agent 时通过 response_format 参数指定你期望的输出结构。

python 复制代码
# 导入核心模块
from langchain.agents import create_agent
from pydantic import BaseModel, Field

# 定义你期望的结构化输出格式
# 使用 Pydantic BaseModel 是最佳实践:支持类型校验、字段描述、嵌套等
class MovieInfo(BaseModel):
    """从文本中提取的电影基本信息"""
    name: str = Field(..., description="电影的中文或英文名称")
    publish_year: str = Field(..., description="电影上映年份,例如 '2009'")
    director: str = Field(..., description="导演全名")

# 创建具备结构化输出能力的智能体
# 关键点:在 create_agent 中直接传入 response_format=MovieInfo
# LangChain 会根据模型能力自动选择 ProviderStrategy 或 ToolStrategy
agent = create_agent(
    model="deepseek-chat",          # 使用 DeepSeek 模型(不支持原生 JSON Schema)
    response_format=MovieInfo       # ← 直接声明期望的输出结构
    # 注意:无需手动导入或指定 ToolStrategy,LangChain 自动处理!
)

# 准备输入文本
text = "《阿凡达》(Avatar, 2009)导演:詹姆斯·卡梅隆。故事发生在潘多拉星球......"

# 调用智能体
# 输入必须是标准消息格式:{"messages": [{"role": "user", "content": "..."}]}
result = agent.invoke({
    "messages": [{"role": "user", "content": text}]
})

# 提取结构化结果
# 所有结构化输出统一存放在 result["structured_response"] 中
movie: MovieInfo = result["structured_response"]

# 打印结果(movie 是 MovieInfo 实例,支持属性访问)
print(f"片名: {movie.name}")
print(f"上映年份: {movie.publish_year}")
print(f"导演: {movie.director}")

# 也可转为字典或 JSON
print(movie.model_dump())  # {'name': '阿凡达', 'publish_year': '2009', 'director': '詹姆斯·卡梅隆'}

当你在 create_agent(..., response_format=YourSchema) 中传入一个 Pydantic 模型(或其它 schema 类型) 时:

LangChain 会自动分析所用模型的能力:

  • 如果模型原生支持结构化输出 ,则使用 ProviderStrategy
  • 否则,自动降级为 ToolStrategy

最终,Agent 的执行结果中会包含一个 structured_response 字段,其值就是你定义的结构化对象实例。

三、Provider Strategy

利用模型原生支持的结构化输出能力,通过 API 层面直接约束模型输出格式(如 JSON Schema),由模型提供商(Provider)保证输出合规。

(1)自动触发使用

直接在实例化创建Agent的时候,传入参数response_format=MovieInput

python 复制代码
from langchain.chat_models import init_chat_model
from pydantic import BaseModel

class User(BaseModel):
    name: str
    age: int

model = init_chat_model("openai:gpt-4o")
structured = model.with_structured_output(User)  # ← 自动使用 ProviderStrategy

四、Tool Strategy

将你的数据结构伪装成一个工具 ,利用模型的 工具调用能力来返回结构化参数。工作原理:

  1. LangChain 将你的 Pydantic 模型转换为一个虚拟工具(例如叫 return_structured_data)。
  2. 请求时附带该工具的定义(含参数 schema)。
  3. 模型如果支持工具调用,会主动调用这个工具,并将提取的数据作为工具参数传回。
  4. LangChain 拦截该工具调用,提取参数并验证,最终返回结构化对象。

(1)显式的去调用

实例化ToolStrategy并传入你自定义的输出格式,就被称为显示的使用。

python 复制代码
# 导入 ToolStrategy:用于在模型不支持原生结构化输出时,
# 通过"工具调用"(Tool Calling)机制模拟结构化输出行为。
from langchain.agents.structured_output import ToolStrategy

# 创建一个具备结构化输出能力的智能体(Agent)
# - model="deepseek-chat":指定使用 DeepSeek 的聊天模型
#   (注意:DeepSeek 目前不支持 OpenAI 风格的原生 JSON Schema 输出,
#    因此必须通过 ToolStrategy 实现结构化提取)
# - response_format=ToolStrategy(MovieInput):
#   显式声明期望的输出结构为 MovieInput 类型,
#   并强制使用工具调用策略来引导模型返回符合该 schema 的参数。
agent = create_agent(
    model="deepseek-chat",
    response_format=ToolStrategy(MovieInput)
)

# 调用智能体,传入用户输入消息
# 格式遵循标准聊天消息结构:列表 of {"role": "...", "content": "..."}
# 此处将待解析的电影文本作为用户消息传入
result = agent.invoke({
    "messages": [{"role": " user ", "content": text}]
})

# 从结果中提取结构化数据
# LangChain 将模型通过工具调用返回的参数自动验证并转换为 MovieInput 实例,
# 存放在 result["structured_response"] 字段中。
# 该对象可直接访问属性(如 .name, .publish),也可调用 .model_dump() 转为字典。
print(result["structured_response"])
相关推荐
Mapmost2 小时前
【高斯泼溅】3DGS城市模型从“硬盘杀手”到“轻盈舞者”?看我们如何实现14倍压缩
前端
AC赳赳老秦2 小时前
农业智能化:DeepSeek赋能土壤与气象数据分析,精准预测病虫害,守护丰收希望
java·前端·mongodb·elasticsearch·html·memcache·deepseek
咖啡の猫2 小时前
TypeScript-webpack
javascript·webpack·typescript
囊中之锥.2 小时前
《HTML 网页构造指南:从基础结构到实用标签》
前端·html
饼饼饼2 小时前
从 0 到 1:前端 CI/CD 实战(第二篇:用Docker 部署 GitLab)
前端·自动化运维
qq_406176142 小时前
JavaScript的同步与异步
前端·网络·tcp/ip·ajax·okhttp
beckyyy2 小时前
ant design vue Table根据数据合并单元格
前端·ant design
小脑虎2 小时前
JavaScript 进阶核心文档(零基础衔接版,通俗易懂 2025最新)
javascript
用户8168694747252 小时前
Commit 阶段的 3 个子阶段与副作用执行全解析
前端·react.js