Akemi

Langchain模块ModelIO组件输出解析器output parsers

2025/12/02

为什么需要输出解析器,因为调用大模型返回的内容并非给人看的,而是需要以特定的格式输出给其他的应用进行解析

解析器类型 输入示例 输出 适用场景
CommaSeparatedListOutputParser “苹果,香蕉,橙子” ['苹果', '香蕉', '橙子'] 简单列表提取
PydanticOutputParser {"name": "苹果", "color": "红"} Fruit(name='苹果', color='红') 结构化对象
StructuredOutputParser “名称:苹果\n颜色:红” {'名称': '苹果', '颜色': '红'} 键值对数据
JSONOutputParser {"items": ["苹果", "香蕉"]} {'items': ['苹果', '香蕉']} JSON格式数据

格式化输出-定义输出格式json

在输入的时候通过prompt template进行输入:定义输出格式:字段与类型

llm在返回结果的时候,会通过输出分析器进行验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from langchain.prompts import PromptTemplate,ChatMessagePromptTemplate,HumanMessagePromptTemplate,SystemMessagePromptTemplate
from langchain_deepseek import ChatDeepSeek
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel,Field,validator
from typing import List
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat",streaming=True)

# 定义所需数据结构
class Joke(BaseModel):
setup: str = Field(description="提出一个问题")
punchline: str = Field(description="回答,生成一个笑话")

# 将Joke这个类赋给输出解析器
parser = PydanticOutputParser(pydantic_object=Joke)

#
prompt = PromptTemplate(
template="回应用户查询。\n{format_instructions}\n{query}\n",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()}
)

# 构建一个查询,输入query变量
formatted_prompt = prompt.format_prompt(query="说一个笑话")
response = llm.invoke(formatted_prompt)

print(response.content)

# {
# "setup": "为什么程序员总是分不清万圣节和圣诞节?",
# "punchline": "因为 Oct 31 等于 Dec 25。"
# }

格式化输出-定义输出类型list

通过get_format_instructions指令在prompt阶段定义输出格式为list,并且定义输出分析器为CommaSeparatedListOutputParser

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from langchain.output_parsers import CommaSeparatedListOutputParser
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from dotenv import load_dotenv

load_dotenv()
llm = ChatDeepSeek(model="deepseek-chat")

# 创建一个列表输出解析器
output_parser = CommaSeparatedListOutputParser()
format_instructions = output_parser.get_format_instructions()

# 提示模板,并定义应该如何输出结果(引用format_instructions
prompt = PromptTemplate(
template="列出五种{subject}。\n{format_instructions}",
input_variables=["subject"],
partial_variables={"format_instructions": format_instructions}
)

formatted_prompt = prompt.format(subject="水果")

print(output_parser.parse(llm.invoke(formatted_prompt).content))

# ['苹果', '香蕉', '橙子', '草莓', '葡萄']

自动修复解析器auto-fixing parser

outputfixing parser是特殊的输出解析器。如果原始的解析器无法解析输入的字符串,就会使用一个语言模型来修复输入的字符串,使其能够被原始解析器解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from langchain.prompts import PromptTemplate
from langchain_deepseek import ChatDeepSeek
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel,Field
from typing import List
from dotenv import load_dotenv
from langchain.output_parsers import OutputFixingParser

load_dotenv()

class Actor(BaseModel):
name: str = Field(description="演员名称"),
film_name: List[str] = Field(description="主演过的电影列表")

# 创建一个输出解析器,用于解析actor
parser = PydanticOutputParser(pydantic_object=Actor)

# 定义一个错误格式化的字符串
misformatted = '{"name": "甄子丹", "film_name": ["叶问","龙虎门"]}'

fix_formatted = OutputFixingParser.from_llm(parser=parser,llm=ChatDeepSeek(model="deepseek-chat"))

print(fix_formatted.parse(misformatted))

# name='甄子丹' film_name=['叶问', '龙虎门']
CATALOG
  1. 1. 格式化输出-定义输出格式json
  2. 2. 格式化输出-定义输出类型list
  3. 3. 自动修复解析器auto-fixing parser