LangChain之解析器核心组件.2026年新版讲解,超详细

在上一节的 Chain 讲解中,只用了最简单的 StrOutputParser,它仅仅是把 AI 的回复从 AIMessage 对象变成了 str 字符串。这一节,我们将深入这个核心组件。


LangChain之解析器核心组件.

第一部分:OutputParser ------ 让模型"听话"地输出数据

OutputParser 主要做两件事:

  1. 立规矩(Format Instructions):自动生成一段提示词,告诉模型:"你必须给我输出 JSON,字段要是这样这样......"。
  2. 做翻译(Parse):把模型生成的文本(String),转换成程序可用的数据结构(Dict, List, Object)。
1. JsonOutputParser (最常用的解析器)

这是目前最实用的解析器。它能把模型的输出直接转成 Python 的 Dictionary(字典)

场景:你需要从一段文本中提取具体的字段(如:人名、年龄、职业)。

代码实战:

我们需要借助 Pydantic 来定义数据结构(虽然 JsonOutputParser 可以不用 Pydantic,但配合使用是最规范的)。

python 复制代码
from pydantic import BaseModel, Field
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
# 1. 定义数据"图纸" (使用原生 Pydantic)
class PersonInfo(BaseModel):
    name: str = Field(description="人物的姓名")
    age: int = Field(description="人物的年龄,必须是数字")
    skills: list[str] = Field(description="人物掌握的技能列表")


# 2. 实例化解析器
parser = JsonOutputParser(pydantic_object=PersonInfo)

# 3. 构造 Prompt 模板 (必须挖一个坑留给格式指令)
prompt = ChatPromptTemplate.from_template(
    "请从下面的文本中提取人物信息。\n\n文本:{text}\n\n{format_instructions}"
)

# 4. 初始化模型
model = ChatOpenAI(
    model="arcee-ai/trinity-large-preview:free",
    # model="Pro/zai-org/GLM-4.7",
)

# 5. 组装链 (Chain)
chain = prompt | model | parser

# 6. 运行链
# 注意:我们要把 parser.get_format_instructions() 动态传给 Prompt
text_input = "小李今年28岁了,他是个全栈工程师,平时精通Python、Java,周末还喜欢去冲浪。"
result = chain.invoke({
    "text": text_input,
    "format_instructions": parser.get_format_instructions()  # 自动生成长篇的JSON要求指令
})
print(type(result))  
print(result)
# <class 'dict'>
# {'name': '小李', 'age': 28, 'skills': ['Python', 'Java']}

原理解析:

如果你不加 format_instructions,模型可能会回一句:"好的,这是提取的信息:..."。

解析器收到这句话就会报错,因为它只要纯 JSON。
所以,解析器的核心不仅仅是"解析",更重要的是"提示(Prompting)"。

2. PydanticOutputParser (更严格的校验)

它和上面的 JsonOutputParser 很像,但更严格。如果模型输出的 JSON 缺字段或者类型不对(比如年龄输成了字符串 "eighteen"),它会抛出错误,甚至可以触发"自动修复机制"(Auto-fixing Parser,这是更高级的话题)。

适用场景 :金融、医疗等对数据格式要求极高的场景。
用法与上面基本一致,区别在于 invoke 后的返回值是 Person 类的对象,而不是 dict。

3. CommaSeparatedListOutputParser (简单的列表)

如果你只需要一个简单的列表,不需要复杂的 JSON。

代码实战:

python 复制代码
from langchain_core.output_parsers import CommaSeparatedListOutputParser

parser = CommaSeparatedListOutputParser()
prompt = ChatPromptTemplate.from_template(
    "列出5个{subject}的名称。\n{format_instructions}"
)

chain = prompt | ChatOpenAI() | parser

result = chain.invoke({
    "subject": "水果",
    "format_instructions": parser.get_format_instructions()
})
# 结果直接就是一个 Python List
# ['苹果', '香蕉', '橙子', '葡萄', '西瓜']

第二部分:RunnableLambda ------ 把"自定义函数"变成链的一环

在 LCEL 链中,我们不仅可以放 LangChain 的组件,还可以放任何 Python 函数

这让你可以在链的中间做数据清洗、逻辑判断、或者简单的计算。

LangChain 提供了一个包装器叫 RunnableLambda,它可以把普通函数变成"可链式调用"的组件。

1. 基础用法:数据清洗

假设模型输出的 JSON 里,名字全是小写,你想把它转换成大写。

代码实战:

python 复制代码
from langchain_core.runnables import RunnableLambda

# 普通 Python 函数
def uppercase_name(data):
    # 假设 data 是上一步解析出来的字典 {'name': 'john', ...}
    data['name'] = data['name'].upper()
    return data

# 在链中使用 (LCEL 会自动把函数识别为 RunnableLambda,也可以显式包裹)
chain = prompt | model | parser | RunnableLambda(uppercase_name)
2. 进阶用法:分支逻辑与调试

有时候你想看看链运行到一半时,数据长什么样。你可以写一个"打印函数"插进去。

python 复制代码
def inspect_data(x):
    print(f"【中间监控】当前数据: {x}")
    return x # 必须返回 x,否则链就断了

chain = prompt | model | RunnableLambda(inspect_data) | parser

第三部分 打造"智能数据分析链"

现在我们将 Prompt + Model + JsonParser + 自定义函数 全部串联起来。

任务目标

  1. 用户输入一段混乱的评论。
  2. 模型提取关键信息(情感分数、关键词)。
  3. 解析器转成字典。
  4. 自定义函数判断是否是"差评",并生成自动回复建议。

完整代码(请仔细阅读注释):

python 复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.pydantic_v1 import BaseModel, Field
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnableLambda

# --- 1. 定义数据结构 ---
class ReviewAnalysis(BaseModel):
    sentiment_score: int = Field(description="情感打分,1-10分,10分为最满意")
    keywords: list[str] = Field(description="评论中的关键名词")
    summary: str = Field(description="一句话总结评论内容")

# --- 2. 准备组件 ---
model = ChatOpenAI(model="gpt-3.5-turbo")
parser = JsonOutputParser(pydantic_object=ReviewAnalysis)

prompt = ChatPromptTemplate.from_template(
    """
    你是一个电商评论分析师。请分析以下用户评论。
    
    用户评论: {comment}
    
    {format_instructions}
    """
)

# --- 3. 定义自定义业务逻辑函数 ---
def analyze_priority(analysis_dict):
    """
    接收解析后的字典,增加一个'处理优先级'字段
    """
    score = analysis_dict['sentiment_score']
    if score <= 3:
        analysis_dict['priority'] = "【红色警报】需人工立即介入"
        analysis_dict['reply_strategy'] = "道歉并提供赔偿"
    elif score <= 7:
        analysis_dict['priority'] = "【黄色关注】需跟进"
        analysis_dict['reply_strategy'] = "询问具体细节"
    else:
        analysis_dict['priority'] = "【绿色正常】"
        analysis_dict['reply_strategy'] = "感谢评价"
    print(f"处理优先级:{analysis_dict['priority']},回复策略:{analysis_dict['reply_strategy']}")

    return analysis_dict

# --- 4. 组装终极链 (LCEL) ---
# 流程:输入 -> 提示词 -> 模型 -> 文本转JSON -> 业务逻辑处理
full_chain = (
    prompt 
    | model 
    | parser 
    | RunnableLambda(analyze_priority)
)

# --- 5. 运行测试 ---
bad_review = "这个东西太烂了!快递慢得要死,打开还是坏的,气死我了!"
good_review = "东西不错,物流挺快的,下次还会买。"

print("=== 测试差评 ===")
result1 = full_chain.invoke({
    "comment": bad_review,
    "format_instructions": parser.get_format_instructions()
})
print(result1)

print("\n=== 测试好评 ===")
result2 = full_chain.invoke({
    "comment": good_review,
    "format_instructions": parser.get_format_instructions()
})
print(result2)

输出结果预期:

text 复制代码
=== 测试差评 ===
处理优先级:【红色警报】需人工立即介入,回复策略:道歉并提供赔偿
{'sentiment_score': 1, 'keywords': ['东西', '快递', '坏的'], 'summary': '用户对商品和快递服务极度不满,表示收到的是损坏的产品。', 'priority': '【红色警报】需人工立即介入', 'reply_strategy': '道歉并提供赔偿'}

=== 测试好评 ===
处理优先级:【绿色正常】,回复策略:感谢评价
{'sentiment_score': 8, 'keywords': ['东西', '物流'], 'summary': '用户对商品和物流速度表示满意,表示下次会继续购买。', 'priority': '【绿色正常】', 'reply_strategy': '感谢评价'}

第四部分:总结

在 LangChain 的链中,解析器和自定义函数让你的应用从"聊天玩具"变成了"生产力工具"。

  1. OutputParser :解决了"非结构化文本 →\to→ 结构化数据 "的难题。
    • 记得:format_instructions 是必不可少的,必须传给 Prompt。
  2. RunnableLambda :解决了"AI 逻辑 →\to→ 传统代码逻辑 "的衔接。
    • 任何 Python 函数都可以是链的一部分。

现在的链结构变成了:
Prompt (输入处理) →\to→ Model (大脑) →\to→ Parser (格式化) →\to→ Function (业务处理)

掌握了这一步,你就已经具备了构建复杂数据处理 Pipeline 的能力!

相关推荐
伶俐的猪2 小时前
性能测试以及面试题
python
52Hz1182 小时前
力扣394.字符串解码、739.每日温度、84.柱状图中最大的矩形
python·算法·leetcode
2501_926978332 小时前
概率分形:智能涌现的统一机理
人工智能·经验分享·机器学习·ai写作·agi
编程小白_澄映2 小时前
《机器学习》——KNN算法
人工智能·算法·机器学习
XW01059992 小时前
4-10大公约数和最小公倍数
python·gcd·lcm
Cxiaomu2 小时前
Python 文件解析: Excel / Word / PDF 的解析、处理、预览与下载
python·word·excel
十五年专注C++开发2 小时前
tiny-process-library:一个用 C++ 编写的轻量级、跨平台(支持 Windows、Linux、macOS)的进程管理库
linux·c++·windows·进程管理
啊阿狸不会拉杆2 小时前
《计算机视觉:模型、学习和推理》第 10 章-图模型
人工智能·python·学习·机器学习·计算机视觉·图模型
测试老哥2 小时前
如何使用Postman做接口测试?
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman