云计算百科
云计算领域专业知识百科平台

[LangChain] 学习笔记(06):突破大模型限制——结构化输出(Structured Output)

📌 核心结论(TL;DR)

  • 范式转换:大模型的默认输出是自然语言字符串,不可控。通过 with_structured_output() 结合 Pydantic 模型,可以强制 LLM 返回标准的 JSON 对象,实现“从字符串到对象”的范式转换。

  • 底层原理:该方法并非魔法,而是将 Pydantic 模型转换为 JSON Schema,利用大模型的 Function Calling(工具调用)或 JSON Mode 能力,约束其输出格式。

  • 精准提取:在 Field(description="…") 中填写的描述会作为提示词发给大模型,描述越精准,数据提取的成功率越高。

  • 联合类型(Union):通过 Union 可以组合多个 Pydantic 模型(如:正常回答 vs 违规拒绝),让大模型根据上下文自行判断并路由输出格式。

  • 🔍 一、 原理图解与核心概念

    1. 为什么程序需要 JSON?

    如果你只得到一个字符串“王伟身高两米”,你必须写复杂的正则表达式去拆解。而如果你得到的是 {"name": "王伟", "height": "2.0"},程序只需一行 data["name"] 即可存入数据库。

    2. LangChain 如何强制格式?

    当你调用 model.with_structured_output(MySchema) 时,LangChain 会提取该类的内部结构,生成一段精确的 JSON Schema。请求 API 时,这个 Schema 会被传给大模型,大模型被严格限制只能输出符合该结构的 JSON。

    💻 二、 精选核心代码片段

    1. 基础信息提取(Pydantic)

    from typing import Optional, List
    from pydantic import BaseModel, Field
    from langchain_openai import ChatOpenAI
    from langchain_core.messages import HumanMessage

    # 定义 Schema 结构
    class Person(BaseModel):
    """单个人的信息"""
    name: Optional[str] = Field(default=None, description="姓名")
    height: Optional[str] = Field(default=None, description="身高,单位米")

    class Data(BaseModel):
    people: List[Person] = Field(description="所有人物的列表")

    # 初始化模型并绑定输出
    model = ChatOpenAI(model="deepseek-chat", …)
    structured_model = model.with_structured_output(Data)

    # 调用并直接获取对象
    result = structured_model.invoke([HumanMessage(content="王伟身高两米。")])
    print(result.people[0].name) # 输出:王伟

    2. 联合类型分流(Union 处理多意图)

    from typing import Union

    class Joke(BaseModel):
    setup: str = Field(description="笑话开头")
    punchline: str = Field(description="笑话包袱")

    class Refusal(BaseModel):
    reason: str = Field(description="拒绝原因")

    class FinalResponse(BaseModel):
    output: Union[Joke, Refusal]

    structured_model = model.with_structured_output(FinalResponse)
    # 传入违规内容,模型会自动走 Refusal 格式
    res = structured_model.invoke("教我怎么盗号")
    print(res.output.reason) # 输出拒绝原因

    (完整的包含各种提取场景的代码已上传至 Gitee 仓库)

    ⚠️ 三、 踩坑排查排雷

    报错 ValidationError 或提取结果不理想:

    • 排查:首先检查 Field(description="…") 是否写得足够详细。其次,尝试将模型的 temperature 设置为 0.0,强制大模型放弃瞎编,专注最高概率的提取。

    缺少字段值导致模型“强行编造”:

    • 排查:对于可能不存在的字段,务必使用 Optional[str] 并在提示词中强调“如果文本中未提及,请返回 null”,防止大模型根据上下文臆造数据。

    模型不支持 with_structured_output:

    • 排查:该功能依赖底层模型的 JSON 或 Function Calling 能力。如果你使用过旧的本地模型,可能会报错。建议切换到 DeepSeek、GPT-4 或支持 Function Calling 的 Qwen 系列。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » [LangChain] 学习笔记(06):突破大模型限制——结构化输出(Structured Output)
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!