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)
相关推荐
米码收割机7 小时前
【项目】spring boot+vue3 宠物领养系统(源码+文档)【独一无二】
java·spring boot·宠物
刹那芳华19928 小时前
STMF+ESP-S+MQTT协议连接华为云端(附踩坑记录)
java·struts·华为
就改了13 小时前
Java8 日期处理(详细版)
java·python·算法
麻瓜生活睁不开眼14 小时前
Android16定制SearchLauncher新增投屏Cast桌面快捷图标完整实现
java·launcher·aosp16
ii_best15 小时前
更新!移动端开发软件按键安卓版&手机助手v5.1.0上线!本地AI识别全面解锁,脚本开发再升级
android·人工智能·ios·按键精灵
IT小盘15 小时前
12-Prompt不等于一句话-System-User-Context三层结构
java·windows·prompt
方乐寺村15 小时前
s,使用libpng提升png图片的保存速度。接下来本文将阐述在Android中如何集成libpng,以及在使用过程中遇到的问题和最 ...
android
name好难取诶16 小时前
PHP 静态分析工具实战 PHPStan 和 Psalm 完全指南
android·开发语言·php
都叫我大帅哥16 小时前
Spring Data JPA 查询之道:方法命名与示例查询完全指南
java·后端·spring
Lydia ,16 小时前
安卓基础-线性布局
android