LangChain输出解析器
模型默认返回的是一段文本(字符串),但实际开发中我们往往需要结构化的数据,比如 Python 字典、列表、Pydantic 对象等。输出解析器(Output Parser)就是用来完成这个转换的。
1. StrOutputParser
最简单的解析器,将 AIMessage 对象转换为普通字符串,通常都会加上它:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
load_dotenv()
prompt = ChatPromptTemplate.from_messages([
("human", "{question}"),
])
llm = ChatOpenAI(model="gpt-4o-mini")
parser = StrOutputParser()
chain = prompt | llm | parser
result = chain.invoke({"question": "Python 是什么?"})
print(type(result)) # <class 'str'>
print(result) # 直接输出字符串,不是 AIMessage 对象
2. JsonOutputParser
让模型以 JSON 格式返回数据,解析器会自动将其转成 Python 字典:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
load_dotenv()
prompt = ChatPromptTemplate.from_messages([
("system", "你只返回 JSON 格式的数据,不要有其他内容。"),
("human", "提取以下文字中的姓名和年龄:{text}"),
])
llm = ChatOpenAI(model="gpt-4o-mini")
parser = JsonOutputParser()
chain = prompt | llm | parser
result = chain.invoke({"text": "张三今年 25 岁,是一名工程师。"})
print(type(result)) # <class 'dict'>
print(result) # {'name': '张三', 'age': 25}
print(result["name"]) # 张三
3. PydanticOutputParser(推荐)
最强大的解析器,结合 Pydantic 模型自动验证数据类型,并能自动生成格式说明注入到提示词中:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
load_dotenv()
# 定义你期望的数据结构
class Person(BaseModel):
name: str = Field(description="人物姓名")
age: int = Field(description="年龄")
job: str = Field(description="职业")
parser = PydanticOutputParser(pydantic_object=Person)
prompt = ChatPromptTemplate.from_messages([
("system", "从用户提供的文本中提取人物信息。\n{format_instructions}"),
("human", "{text}"),
]).partial(format_instructions=parser.get_format_instructions())
llm = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm | parser
result = chain.invoke({"text": "李明是一位 30 岁的医生。"})
print(type(result)) # <class '__main__.Person'>
print(result.name) # 李明
print(result.age) # 30
print(result.job) # 医生
parser.get_format_instructions() 会自动生成一段格式说明文字注入到提示词,指导模型按照你定义的结构输出。
嵌套结构示例:
from pydantic import BaseModel, Field
from typing import List
class Skill(BaseModel):
name: str = Field(description="技能名称")
level: str = Field(description="熟练程度:入门/熟练/精通")
class Developer(BaseModel):
name: str = Field(description="开发者姓名")
years: int = Field(description="工作年限")
skills: List[Skill] = Field(description="技能列表")
4. CommaSeparatedListOutputParser
将模型输出的逗号分隔文本转换为 Python 列表:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import CommaSeparatedListOutputParser
load_dotenv()
parser = CommaSeparatedListOutputParser()
prompt = ChatPromptTemplate.from_messages([
("human", "列出5种常见的{category},只输出名称,用逗号分隔。"),
])
llm = ChatOpenAI(model="gpt-4o-mini")
chain = prompt | llm | parser
result = chain.invoke({"category": "编程语言"})
print(type(result)) # <class 'list'>
print(result) # ['Python', 'Java', 'JavaScript', 'C++', 'Go']
5. 使用 .with_structured_output()
这是更现代的写法,直接在模型上调用,省去手动添加格式说明的麻烦:
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import BaseModel, Field
from typing import List
load_dotenv()
class Movie(BaseModel):
title: str = Field(description="电影名称")
year: int = Field(description="上映年份")
genre: List[str] = Field(description="类型标签")
llm = ChatOpenAI(model="gpt-4o-mini")
structured_llm = llm.with_structured_output(Movie)
result = structured_llm.invoke("介绍一下电影《流浪地球》")
print(result.title) # 流浪地球
print(result.year) # 2019
print(result.genre) # ['科幻', '灾难', '冒险']
.with_structured_output() 内部使用了 Function Calling 技术,比让模型自己生成 JSON 再解析更稳定。
总结
| 解析器 | 返回类型 | 适用场景 |
|---|---|---|
StrOutputParser |
str |
只需要文本,最常用 |
JsonOutputParser |
dict |
需要字典,但结构不固定 |
PydanticOutputParser |
Pydantic 对象 | 需要验证的结构化数据 |
CommaSeparatedListOutputParser |
list |
简单列表 |
.with_structured_output() |
Pydantic 对象 | 推荐,最稳定的结构化输出 |