当前位置: 首页 > news >正文

LangChain-结构化输出:告别解析困难,让AI返回标准格式

一、问题场景

假设你需要AI返回用户信息:

fromlangchain_openaiimportChatOpenAI model=ChatOpenAI(model="gpt-4o-mini")response=model.invoke("请给我一个用户信息,包含姓名、年龄、职业")print(response.content)

输出可能是:

姓名:张三 年龄:28岁 职业:软件工程师

或者:

张三,28岁,是一名软件工程师

或者:

{"name":"张三","age":28,"job":"软件工程师"}

问题:输出格式不可控,难以程序化处理。

二、输出解析器的作用

输出解析器负责将模型返回的非结构化文本转换为结构化数据:

AI输出(文本) → 解析器 → 结构化数据(对象/JSON)

LangChain提供了多种输出解析器:

解析器用途
StrOutputParser获取纯文本
JsonOutputParser解析JSON
PydanticOutputParser解析为Pydantic对象
CommaSeparatedListOutputParser解析列表

三、StrOutputParser

3.1 基本用法

最简单的解析器,从消息对象中提取文本内容:

fromlangchain_openaiimportChatOpenAIfromlangchain_core.output_parsersimportStrOutputParserfromlangchain_core.promptsimportChatPromptTemplate# 创建组件prompt=ChatPromptTemplate.from_template("讲一个关于{topic}的笑话")model=ChatOpenAI(model="gpt-4o-mini")parser=StrOutputParser()# 组装链chain=prompt|model|parser# 执行result=chain.invoke({"topic":"程序员"})print(result)# 直接是字符串print(type(result))# <class 'str'>

3.2 为什么需要它?

# 不使用解析器response=model.invoke(messages)print(type(response))# <class 'AIMessage'>print(response.content)# 需要手动访问content属性# 使用解析器result=parser.invoke(response)print(type(result))# <class 'str'>,直接是字符串

四、PydanticOutputParser

4.1 定义数据结构

使用Pydantic定义期望的输出结构:

frompydanticimportBaseModel,FieldfromtypingimportListclassUserInfo(BaseModel):"""用户信息模型"""name:str=Field(description="用户姓名")age:int=Field(description="用户年龄")job:str=Field(description="职业")hobbies:List[str]=Field(description="兴趣爱好")

4.2 创建解析器

fromlangchain_core.output_parsersimportPydanticOutputParser parser=PydanticOutputParser(pydantic_object=UserInfo)# 获取格式说明print(parser.get_format_instructions())

输出:

The output should be formatted as a JSON instance that conforms to the JSON schema below. { "name": "用户姓名", "age": "用户年龄", "job": "职业", "hobbies": ["兴趣爱好"] }

4.3 完整示例

fromlangchain_openaiimportChatOpenAIfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.output_parsersimportPydanticOutputParserfrompydanticimportBaseModel,FieldfromtypingimportList# 1. 定义数据模型classUserInfo(BaseModel):name:str=Field(description="用户姓名")age:int=Field(description="用户年龄")job:str=Field(description="职业")hobbies:List[str]=Field(description="兴趣爱好,最多3个")# 2. 创建解析器parser=PydanticOutputParser(pydantic_object=UserInfo)# 3. 创建提示模板(包含格式说明)prompt=ChatPromptTemplate.from_messages([("system","你是一个数据生成助手。\n{format_instructions}"),("human","请生成一个{age}岁左右的用户信息")])# 4. 格式化提示词messages=prompt.format_messages(format_instructions=parser.get_format_instructions(),age=30)# 5. 调用模型model=ChatOpenAI(model="gpt-4o-mini")response=model.invoke(messages)# 6. 解析输出user_info=parser.parse(response.content)print(user_info)print(type(user_info))

输出:

name='张伟'age=30job='产品经理'hobbies=['读书','跑步','摄影']<class'__main__.UserInfo'>

4.4 使用解析后的数据

# 访问属性print(user_info.name)# 张伟print(user_info.age)# 30print(user_info.hobbies)# ['读书', '跑步', '摄影']# 转换为字典user_dict=user_info.model_dump()print(user_dict)# {'name': '张伟', 'age': 30, 'job': '产品经理', 'hobbies': ['读书', '跑步', '摄影']}# 转换为JSONimportjson user_json=user_info.model_dump_json()print(user_json)# {"name":"张伟","age":30,"job":"产品经理","hobbies":["读书","跑步","摄影"]}

五、JsonOutputParser

5.1 基本用法

更简单的JSON输出方式:

fromlangchain_core.output_parsersimportJsonOutputParserfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_openaiimportChatOpenAI# 定义JSON结构schema={"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"},"city":{"type":"string"}}}parser=JsonOutputParser()prompt=ChatPromptTemplate.from_messages([("system","你是一个数据生成助手。\n{format_instructions}"),("human","生成一个来自{city}的用户信息")])model=ChatOpenAI(model="gpt-4o-mini")chain=prompt|model|parser result=chain.invoke({"format_instructions":parser.get_format_instructions(),"city":"北京"})print(result)print(type(result))

输出:

{'name':'李明','age':28,'city':'北京'}<class'dict'>

六、列表解析器

6.1 CommaSeparatedListOutputParser

fromlangchain_core.output_parsersimportCommaSeparatedListOutputParserfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_openaiimportChatOpenAI parser=CommaSeparatedListOutputParser()prompt=ChatPromptTemplate.from_template("列出5种流行的编程语言。\n{format_instructions}")model=ChatOpenAI(model="gpt-4o-mini")chain=prompt|model|parser result=chain.invoke({"format_instructions":parser.get_format_instructions()})print(result)# ['Python', 'JavaScript', 'Java', 'Go', 'Rust']

6.2 自定义分隔符

fromlangchain_core.output_parsersimportListOutputParser parser=ListOutputParser()# 或者继承自定义

七、处理解析错误

7.1 常见错误

fromlangchain_core.output_parsersimportPydanticOutputParserfrompydanticimportBaseModelclassUser(BaseModel):name:strage:intparser=PydanticOutputParser(pydantic_object=User)# 模型可能返回不符合格式的数据invalid_json='{"name": "张三", "age": "不是数字"}'try:user=parser.parse(invalid_json)exceptExceptionase:print(f"解析失败:{e}")

7.2 重试机制

fromlangchain_core.output_parsersimportPydanticOutputParserfromlangchain.output_parsersimportRetryWithErrorOutputParserfrompydanticimportBaseModelclassUser(BaseModel):name:strage:intparser=PydanticOutputParser(pydantic_object=User)# 带重试的解析器retry_parser=RetryWithErrorOutputParser.from_llm(parser=parser,llm=ChatOpenAI(model="gpt-4o-mini"))# 解析失败时会自动让LLM修正try:result=retry_parser.parse_with_prompt(invalid_output,prompt_value)exceptExceptionase:print(f"解析失败:{e}")

八、实战案例:信息提取

fromlangchain_openaiimportChatOpenAIfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.output_parsersimportPydanticOutputParserfrompydanticimportBaseModel,FieldfromtypingimportList# 定义输出模型classPersonInfo(BaseModel):"""人物信息"""name:str=Field(description="姓名")occupation:str=Field(description="职业")company:str=Field(default="",description="公司")achievements:List[str]=Field(default_factory=list,description="成就列表")# 创建解析器和提示parser=PydanticOutputParser(pydantic_object=PersonInfo)prompt=ChatPromptTemplate.from_messages([("system","你是信息提取专家。从文本中提取人物信息。\n{format_instructions}"),("human","{text}")])model=ChatOpenAI(model="gpt-4o-mini")chain=prompt|model|parser# 执行提取text=""" 马斯克是特斯拉CEO,也是SpaceX的创始人。他成功发射了可回收火箭, 推动了电动汽车革命,还在 Neuralink 和 The Boring Company 担任领导职务。 """result=chain.invoke({"format_instructions":parser.get_format_instructions(),"text":text})print(result)

输出:

name='马斯克'occupation='CEO、企业家'company='特斯拉'achievements=['成功发射可回收火箭','推动电动汽车革命','Neuralink创始人','The Boring Company创始人']

九、小结

解析器输入输出适用场景
StrOutputParserAIMessagestr获取纯文本
PydanticOutputParserstrPydantic对象结构化数据
JsonOutputParserstrdictJSON数据
ListOutputParserstrlist列表数据

最佳实践:

  1. 定义清晰的Pydantic模型
  2. 使用Field添加描述
  3. 在提示词中包含格式说明
  4. 处理解析异常

http://www.jsqmd.com/news/475861/

相关文章:

  • AI For Trusted Code|泛联新安:以“AI+可信”构筑智能时代基石
  • MCP客户端同步机制终极手册:涵盖gRPC流控、ETag校验、向量时钟VVC实现——仅限内部技术梯队解密版
  • SecGPT-14B安全能力图谱:覆盖CNVD/CNNVD/NVD三大漏洞库的语义理解
  • BiLSTM锂电池剩余寿命预测,NASA数据集(5号电池训练6号电池测试),MATLAB代码
  • 论文写作入门指南:用快马AI生成你的第一个可复现代码项目
  • 无需代码!用OFA图像语义蕴含模型快速搭建智能图文审核工具
  • 传奇游戏玩法与攻略-复古传奇爆率-传奇职业选择,传奇打BOSS方法
  • 请你明确具体需求,比如对这篇文章进行润色、提取信息、根据已
  • Gemma-3-12b-it效果惊艳集锦:12B参数下媲美云端多模态模型的表现
  • TranslateGemma-12B企业级应用:基于SpringBoot的多语言客服系统集成
  • Spring AI Alibaba 学习记录(记忆功能实现)
  • 使用Kubernetes管理FireRedASR-AED-L集群的最佳实践
  • 比迪丽LoRA模型Matlab仿真接口初探:科研可视化中的艺术化表达
  • 比迪丽SDXL模型多场景落地:电商同人周边、社群配图、创作素材库
  • 提升算法调试效率:基于快马平台快速迭代evomap可视化方案
  • Super Resolution处理结果保存:输出路径与命名规则说明
  • ollama运行Phi-4-mini-reasoning效果实测:在形式化验证、类型推导等硬核场景表现
  • 从Perfetto视角看Audio异常underrun问题的表现
  • [Redis小技巧11]Redis Key 过期策略与内存淘汰机制:深度解析与实战指南
  • 基于龙卷风优化算法(TOC) 的多个无人机协同路径规划(可以自定义无人机数量及起始点)附Matlab代码
  • 2026年知名的防水行程开关厂家推荐:2NC 1NO行程开关/TUV认证行程开关厂家热卖产品推荐(近期) - 品牌宣传支持者
  • 2025年全国行业职业技能竞赛第四届全国数据安全职业技能竞赛暨第四届安防行业职业技能竞赛“美亚柏科杯“数据安全管理员样题
  • 工业数字化提速,边缘计算存储如何减负?天硕工业级固态硬盘给出答案
  • 哪款减肥产品掉秤快还安全?2026 高性价比减脂代餐推荐:懒人“躺瘦”不反弹指南 - 企业推荐官【官方】
  • YOLO12教学演示指南:Gradio界面动态调参+检测效果对比教学
  • Fish-Speech-1.5与Vue.js前端集成:实时语音预览功能实现
  • 网络基础干货|域名/DNS/URL 一篇吃透
  • 提升效率:用快马生成Python脚本自动批量下载推特媒体
  • 纯硬件嵌入式鞭炮声播放系统设计
  • 哪款减肥代餐好用又安全?腰纪线(MetaSlim)全营养代餐,以精准控热+代谢重启,解锁长效减脂 - 企业推荐官【官方】