llm.with_structured_output

llm.with_structured_output 是 LangChain 中一个非常强大且便捷的方法,用于强制大模型输出符合特定格式的数据(如 JSON、Pydantic 对象),而不是返回普通的文本字符串。

1. 核心原理

该方法会在底层通过以下两种方式之一工作(取决于模型支持情况):

  1. Function Calling (工具调用):这是最推荐的方式。模型不会直接输出文本,而是调用一个定义好的函数,参数就是你要的结构化数据。LangChain 会自动解析这个函数调用并返回对象。
  2. JSON Mode:如果模型不支持工具调用,LangChain 会尝试在 System Prompt 中强制模型输出 JSON 格式,然后用正则或解析器提取。

2. 基础用法:使用 Pydantic 模型 (推荐)

这是最常用、最健壮的方式。利用 Pydantic 进行数据校验,能确保类型正确(例如金额必须是 float,日期必须是 datetime)。

步骤:

  1. 定义一个继承自 BaseModel 的类,并使用 Field 描述每个字段。
  2. 调用 llm.with_structured_output(Schema)

代码示例:

复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI  # 假设你用的是 Qwen,可以用 ChatOpenAI 兼容接口
from pydantic import BaseModel, Field

# 1. 定义输出的数据结构
class BidderInfo(BaseModel):
    """投标人信息提取"""
    company_name: str = Field(description="中标公司的全称")
    winning_amount: float = Field(description="中标金额,单位为万元")
    contact_person: str = Field(description="联系人姓名", default="未知")
    
# 2. 初始化模型(这里以 Qwen 为例,通过 vLLM/OpenAI 兼容接口调用)
llm = ChatOpenAI(
    base_url="http://localhost:8000/v1", # 你的 vLLM 地址
    model="qwen-32b-instruct",
    temperature=0
)

# 3. 使用 with_structured_output 包装模型
# 这里的 structured_llm 现在的输出类型就是 BidderInfo 对象,而不是 str
structured_llm = llm.with_structured_output(BidderInfo)

# 4. 构建提示词并调用
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个专业的招投标信息提取助手。请从用户输入的文本中提取关键信息。"),
    ("user", "{input}")
])

chain = prompt | structured_llm

# 模拟一段标书文本
text = """
根据中标公告显示,XX科技有限公司于今日成功中标该项目。
中标金额为 450.5 万元。
项目负责人为张三。
"""

# 5. 调用链
result = chain.invoke({"input": text})

# 6. 查看结果(此时 result 已经是一个对象,不是字符串)
print(f"类型: {type(result)}")
print(f"公司名: {result.company_name}")
print(f"金额: {result.winning_amount}")
print(f"JSON输出: {result.model_dump_json()}") # 可以直接转成 JSON 字符串存库

3. 进阶用法:处理复杂结构 (嵌套与列表)

在招投标场景中,往往需要提取一个列表(例如:评分表中的多条明细,或多个产品清单)。Pydantic 完美支持嵌套。

代码示例:提取评分细则列表

复制代码
from typing import List, Literal
from pydantic import BaseModel, Field

# 定义单个评分项的结构
class ScoreItem(BaseModel):
    category: Literal["技术分", "商务分", "价格分"] = Field(description="评分大类")
    factor: str = Field(description="评审因素,如:实施方案")
    standard: str = Field(description="评审标准描述")
    max_score: float = Field(description="该项最高分值")

# 定义整个评分表的结构
class EvaluationStandard(BaseModel):
    """评分标准表"""
    total_score: float = Field(description="总分")
    items: List[ScoreItem] = Field(description="评分细则列表")

# 包装模型
structured_llm = llm.with_structured_output(EvaluationStandard)

# 调用
text = "本项目总分100分。技术分占40分,其中实施方案20分,人员资质20分。商务分30分...(此处省略)"
result = structured_llm.invoke(text)

# 遍历列表
for item in result.items:
    print(f"{item.factor}: {item.max_score}分")

4. 常用参数与技巧

llm.with_structured_output 除了传入 Schema 类,还支持一些参数:

  • name: 给这个工具起个名字(主要用于 Agent 场景,让模型知道什么时候调用它)。

  • description: 描述这个工具的用途(主要用于 Agent)。

  • include_raw : 布尔值。如果设为 True,返回结果中会包含原始的 raw_output(模型的原始响应)和 parsed_output(解析后的对象)。这对于调试解析失败的情况非常有用。

    structured_llm = llm.with_structured_output(BidderInfo, include_raw=True)
    response = structured_llm.invoke(...)
    print(response['raw']) # 模型生成的原始文本或工具调用参数
    print(response['parsed']) # 解析成功的 Pydantic 对象

注意事项

  1. 模型能力要求with_structured_output 依赖于模型 Function Calling (Tool Use) 的能力。
    • Qwen: Qwen-2.5, Qwen-2, Qwen-1.5 系列均支持 Function Calling。
    • 如果使用 vLLM 部署,请确保 vLLM 版本较新,并且开启了对应的支持(通常默认开启 OpenAI 兼容协议即可)。
  2. 描述非常重要 :在 Field(description="...") 中写的描述越清晰,模型提取的准确率越高。特别是对于金额,最好注明单位(如"单位:元")。
  3. 容错处理 :如果模型完全无法提取(例如文本中根本没相关信息),Pydantic 可能会报错或生成空字段。在代码中要做好 try-except 或默认值处理。
相关推荐
神云瑟瑟1 小时前
看langchain理解python中的链式调用
python·langchain·链式调用
稳稳C94 小时前
04|Langgraph | 从入门到实战 | 进阶篇 | 流式传输
python·ai·langchain·agent·langgraph
linmoo19865 小时前
Langchain4j 系列之二十二 - Embedding Models
人工智能·langchain·embedding·嵌入模型·langchain4j
敏叔V5876 小时前
LangChain × LlamaIndex:解锁复杂AI工作流与自定义工具集成的终极指南
人工智能·langchain
人工干智能8 小时前
LangChain的提示模板template中的{tool_names}和{agent_scratchpad}
langchain·llm
San30.10 小时前
LangChain 第二课:拒绝“废话”,用 Zod 强制 AI 输出标准 JSON
人工智能·langchain·json
敏叔V58711 小时前
AI应用开发框架对比:LangChain vs. Semantic Kernel vs. DSPy 深度解析
人工智能·驱动开发·langchain
weixin_462446231 天前
使用 Chainlit +langchain+ LangGraph + MCP + Ollama 构建可视化 AI 工具 Agent(完整实战)
人工智能·langchain·agent·ai聊天·mcp server
南_山无梅落1 天前
create_deep_agent vs create_agent 的区别
人工智能·langchain·deepagent
红鼻子时代1 天前
第9篇:Middleware中间件
langchain·middleware中间件