LangChain--06--结构化输出(Structured Output)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


结构化输出(Structured Output)

1、结构化输出概述

2、四种模式的使用

2.1 模式1:Pydantic

2.2 模式2:TypedDict

2.3 模式3:JSON Schema

2.4 模式4:@dataclass

3、关于类型校验

4、获取结构化结果方式

python 复制代码
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os

# 从.env文件中加载环境变量
load_dotenv(override=True)

CLOSEAI_API_KEY = os.getenv("CLOSEAI_API_KEY")
CLOSEAI_BASE_URL = os.getenv("CLOSEAI_BASE_URL")

model = init_chat_model(
    model="gpt-5.4-mini",
    model_provider="openai",
    api_key=CLOSEAI_API_KEY,
    base_url=CLOSEAI_BASE_URL
)
python 复制代码
from pydantic import BaseModel, Field
from rich import print as rprint

class Movie(BaseModel):
    """电影信息"""
    title: str = Field(description="电影标题")
    year: int = Field(description="上映年份")
    director: str = Field(description="导演")
    rating: float = Field(description="评分(10分制)")


structured_model = model.with_structured_output(Movie,include_raw=True)
response = structured_model.invoke("帮我介绍一下星际穿越这个电影")

print(type(response))
rprint(response)   # 输出结果中就会包含原始的AIMessage
python 复制代码
{
    'raw': AIMessage(
        content='{"title":"星际穿越","year":2014,"director":"克里斯托弗·诺兰","rating":8.6}',
        additional_kwargs={
            'parsed': Movie(title='星际穿越', year=2014, director='克里斯托弗·诺兰', rating=8.6),
            'refusal': None
        },
        response_metadata={
            'token_usage': {
                'completion_tokens': 37,
                'prompt_tokens': 170,
                'total_tokens': 207,
                'completion_tokens_details': {
                    'accepted_prediction_tokens': 0,
                    'audio_tokens': 0,
                    'reasoning_tokens': 0,
                    'rejected_prediction_tokens': 0
                },
                'prompt_tokens_details': {'audio_tokens': 0, 'cached_tokens': 0},
                'latency_checkpoint': {
                    'engine_tbt_ms': 5,
                    'engine_ttft_ms': 32,
                    'engine_ttlt_ms': 227,
                    'pre_inference_ms': 89,
                    'service_tbt_ms': 5,
                    'service_ttft_ms': 288,
                    'service_ttlt_ms': 454,
                    'total_duration_ms': 374,
                    'user_visible_ttft_ms': 198
                }
            },
            'model_provider': 'openai',
            'model_name': 'gpt-5.4-mini-2026-03-17',
            'system_fingerprint': None,
            'id': 'chatcmpl-DmFMuztybKYthCS0QtHmLbB6ziI4Z',
            'service_tier': 'default',
            'finish_reason': 'stop',
            'logprobs': None
        },
        id='lc_run--019e8795-992d-7920-a06c-ff6738ca1ff0-0',
        tool_calls=[],
        invalid_tool_calls=[],
        usage_metadata={
            'input_tokens': 170,
            'output_tokens': 37,
            'total_tokens': 207,
            'input_token_details': {'audio': 0, 'cache_read': 0},
            'output_token_details': {'audio': 0, 'reasoning': 0}
        }
    ),
    'parsed': Movie(title='星际穿越', year=2014, director='克里斯托弗·诺兰', rating=8.6),
    'parsing_error': None
}
python 复制代码
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field
from langchain.chat_models import init_chat_model
from dotenv import load_dotenv
import os

# 1. 创建提示词模板
prompt_template = ChatPromptTemplate.from_messages([
    ("system","回答用户问题,必须始终输出一个包含title(电影标题)和year(上映年份)的 JSON 对象"),
    ("human","问题:{question}")
])

# 2. 模型初始化
# 从.env文件中加载环境变量
load_dotenv(override=True)

model = init_chat_model(
    model="gpt-5.4-mini",
    model_provider="openai",
    api_key=os.getenv("CLOSEAI_API_KEY"),
    base_url=os.getenv("CLOSEAI_BASE_URL")
)

# 3. 定义结构
class Movie(BaseModel):
    """电影信息"""
    title: str = Field(description="电影标题")
    year: int = Field(description="上映年份")

# 4. 创建输出解析器
parser = JsonOutputParser(pydantic_object=Movie)

# 5. 创建链
chain = prompt_template | model | parser

# 6. 调用(返回字典)
# response = chain.invoke({"question": "介绍电影《盗梦空间》"})

response = parser.invoke(model.invoke(prompt_template.invoke({"question": "介绍电影《盗梦空间》"})))


print(type(response))
print(response)
相关推荐
疯狂打码的少年13 小时前
【数据库技术】关系模型基本概念(关系/属性/元组/键)
java·服务器·数据库·笔记
Mr数据杨14 小时前
【Codex】用学生入学评估模块建立新生能力画像
android·java·javascript·django·codex·项目开发
2601_9620562314 小时前
Spring Boot 入门 与 无法解析符号 springframework 的解决
java·spring boot·后端
●VON15 小时前
谁小时候不想要一个游戏修改器?我把电脑 Skill 做成了 Android 小助手
android·游戏·电脑
Thomas214315 小时前
Java scala 数组 链表
java·链表·scala
刃神太酷啦15 小时前
Linux 系统 MySQL 完整安装配置教程:从卸载 MariaDB 到优化 my.cnf----《Hello MySQL!》(1)
android·linux·c语言·c++·mysql·leetcode·mariadb
里欧跑得慢15 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
亚历克斯神15 小时前
低代码与 AI 的融合趋势——从可视化搭建到自然语言生成应用
java·spring·微服务
IT毕设实战小研15 小时前
基于安卓的空气质量查询系统
android·大数据·vue.js·爬虫·python·django·课程设计
学长毕业设计15 小时前
基于SpringBoot的瑜伽馆网站的设计与实现(源码+文档+讲解视频)
java·spring boot·后端