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)
相关推荐
我才是银古1 小时前
构建 Java GIS 工具库:从碎片化 API 到统一抽象的设计实践
java·gis·geotools·gdal·esri
敲代码的嘎仔1 小时前
实习日志day6--实习日志day6--title命名规范化&businessType纠正&补充缺失的@Log注解&报警与通信模块补充&产出阶段总结文档
java·开发语言·人工智能·git·python·实习·大二
编程(变成)小辣鸡2 小时前
Spring事务失效场景
java·后端·spring
极客先躯3 小时前
高级java每日一道面试题-2026年03月30日-实战篇[Docker]-如何监控容器的网络流量?
java·运维·docker·容器·prometheus·高级面试
tachibana23 小时前
hot100 翻转二叉树(226)
java·数据结构·算法·leetcode
brave_zhao3 小时前
nginx的进程架构
java·学习·nginx
兰令水3 小时前
leecodecode【面试150】【2026.7.9打卡-java版本】
java·数据结构·leetcode·面试·职场和发展
禾高网络3 小时前
互联网医院|AI 互联网医院成品开发系统
java·大数据·人工智能·小程序
shepherd1113 小时前
一次把 Spring MVC 文件上传参数“查没了”的排查:multipart、Filter 与 request body 的连环坑
java·spring boot·后端
lbb 小魔仙3 小时前
MuMu 模拟器 6.0 硬核测评:这次升级确实不一样
java·开发语言·模拟器·mumu·硬核测评