[智能体-174]:LangChain 输出格式化 完整方案
核心分为原生解析、输出解析器 (Output Parser)、Prompt 约束、结构化返回四大类,适配不同场景(字符串、JSON、列表、对象、枚举),基于 LangChain 最新版本(0.1+)演示。
一、前置依赖
bash
运行
pip install langchain langchain-openai python-dotenv二、基础:Prompt指令约束(最简单,无代码解析)
直接在提示词要求固定格式,适合简单场景,纯文本约束,不需要根据大模型的输出自动调用函数。
示例 1:固定文本格式 / 列表
python
运行
from langchain_openai import ChatOpenAI from dotenv import load_dotenv import os load_dotenv() llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0) prompt = """ 请总结以下内容,严格按照格式输出: 1. 标题:xxx 2. 核心要点: - 要点1 - 要点2 内容:人工智能发展趋势 """ res = llm.invoke(prompt) print(res.content)示例 2:强制 JSON 格式(纯 Prompt 约束)
python
运行
prompt = """ 提取以下人物信息,**只返回标准JSON**,不要额外解释、不要markdown: 字段:name(姓名), age(年龄), hobby(爱好) 内容:小明,22岁,喜欢编程和阅读 """ res = llm.invoke(prompt) print(res.content)三、标准 OutputParser 输出解析器(官方推荐)
LangChain 内置多种解析器,自动校验 + 格式化输出,防乱格式、自动报错。
1. StrOutputParser 纯字符串(默认)
仅包装原始输出,链式调用常用:
python
运行
from langchain_core.output_parsers import StrOutputParser parser = StrOutputParser() chain = llm | parser res = chain.invoke("介绍Python") print(type(res), res) # 字符串类型2. JsonOutputParser 解析 JSON(最常用)
自动解析 LLM 输出的 JSON字符串为 Python 字典,自动容错。
python
运行
from langchain_core.output_parsers import JsonOutputParser from langchain_core.prompts import ChatPromptTemplate # 1. 定义解析器 parser = JsonOutputParser() # 2. 构造提示词,注入格式要求 prompt = ChatPromptTemplate.from_messages([ ("system", "提取用户信息,输出JSON格式。{format_instructions}"), ("human", "姓名:张三,职业:工程师,城市:上海") ]).partial(format_instructions=parser.get_format_instructions()) # 3. 构建链路 chain = prompt | llm | parser # 4. 调用,直接得到字典 result = chain.invoke({}) print(type(result)) # <class 'dict'> print(result["姓名"], result["职业"])3. PydanticOutputParser结构化对象(强类型、字段校验)
基于Pydantic定义数据模型,强制字段、类型、规则,适合生产级结构化输出。
步骤 1:定义 Pydantic 模型
python
运行
from pydantic import BaseModel, Field from langchain_core.output_parsers import PydanticOutputParser # 定义数据结构 class UserInfo(BaseModel): name: str = Field(description="用户姓名") age: int = Field(description="用户年龄,数字类型") city: str = Field(description="所在城市") # 初始化解析器 parser = PydanticOutputParser(pydantic_object=UserInfo)步骤 2:拼接 Prompt + 调用
python
运行
prompt = ChatPromptTemplate.from_messages([ ("system", "解析用户信息,严格按照指定格式输出。{format_instructions}"), ("human", "小李,25岁,定居北京") ]).partial(format_instructions=parser.get_format_instructions()) chain = prompt | llm | parser # 返回 Pydantic 对象,直接点属性取值 user: UserInfo = chain.invoke({}) print(user.name, user.age, user.city) # 转字典 print(user.model_dump())4. CommaSeparatedListOutputParser 逗号分隔列表
自动把a,b,c格式转为 Python 列表:
python
运行
from langchain_core.output_parsers import CommaSeparatedListOutputParser parser = CommaSeparatedListOutputParser() prompt = ChatPromptTemplate.from_messages([ ("system", "列出3个编程语言,用英文逗号分隔。{format_instructions}"), ("human", "需求:编程语言") ]).partial(format_instructions=parser.get_format_instructions()) chain = prompt | llm | parser res = chain.invoke({}) print(res) # ['Python', 'Java', 'Go']四、进阶:自定义解析器 + 处理异常
1. 捕获解析失败(LLM 输出不规范兜底)
LLM 偶尔输出多余文本,导致 JSON 解析报错,增加异常捕获:
python
运行
from langchain_core.output_parsers import JsonOutputParser from langchain_core.exceptions import OutputParserException parser = JsonOutputParser() chain = llm | parser try: res = chain.invoke("xxx") except OutputParserException as e: print("解析失败,原始输出:", e.llm_output) # 兜底手动清洗字符串再解析2. 自定义 OutputParser
继承BaseOutputParser实现个性化逻辑:
python
运行
from langchain_core.output_parsers import BaseOutputParser from typing import Any class CustomParser(BaseOutputParser[str]): def parse(self, text: str) -> str: # 自定义清洗逻辑:去除markdown、空格 return text.replace("```", "").strip() parser = CustomParser() chain = llm | parser res = chain.invoke("用一句话介绍LangChain") print(res)五、LCEL 链式组合(工程常用写法)
统一格式链路,复用解析逻辑:
python
运行
from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import JsonOutputParser prompt = ChatPromptTemplate.from_template(""" 分析以下评论情绪,输出JSON: 字段:sentiment(positive/negative/neutral), reason(原因) 评论:{comment} {format_instructions} """) parser = JsonOutputParser() # 完整链路 chain = prompt.partial(format_instructions=parser.get_format_instructions()) | llm | parser # 调用 data = chain.invoke({"comment": "这个工具很好用,效率提升很多"}) print(data)六、关键技巧 & 避坑
必加
temperature=0,格式化场景建议关闭随机性,llm = ChatOpenAI(temperature=0),大幅降低格式错乱概率。禁止多余内容:Prompt 里明确:
只输出结果,不要解释、不要markdown、不要多余文字。嵌套 JSON / 复杂结构:优先用
PydanticOutputParser,支持嵌套 Model,天然支持复杂对象。多轮对话格式化:解析器全局复用,只需要保证每一轮 Prompt 都携带格式指令。
旧版本 LangChain 兼容老版本:用
from langchain.output_parsers import xxx,新版本统一迁移到langchain_core.output_parsers。
七、选型速查表
| 场景 | 推荐解析器 |
|---|---|
| 纯文本输出 | StrOutputParser |
| 字典 / 简单 JSON | JsonOutputParser |
| 强类型、字段校验、复杂结构 | PydanticOutputParser |
| 逗号分隔数组 | CommaSeparatedListOutputParser |
| 特殊清洗规则 | 自定义 BaseOutputParser |
