跳转至

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 对象 推荐,最稳定的结构化输出

评论