OutputParser

model.invoke 返回 AIMessage,业务往往要 str 或 dict。在链尾加 OutputParser 统一「AIMessage → 目标类型」,与 LCEL | 自然衔接;简单场景用 StrOutputParser 即可,复杂 JSON 可试 JsonOutputParser 或改用 structured output。

段末注释OutputParser(输出解析器)= 将模型原始输出转为 str/dict/列表等的 Runnable。


1. 一句话定位

维度 内容
角色 能力层 链尾转换:AIMessage / str → 业务类型
输入 → 输出 多为 AIMessagestrdict
典型调用入口 `prompt
与 LangGraph 节点内可单独 invoke parser

2. 实现逻辑

1
2
3
4
5
6
1. chain = prompt | model | StrOutputParser()
2. chain.invoke({...}) 内部最后一步:
AIMessage(content="hello") → "hello"
3. JsonOutputParser:content 当 JSON 字符串 parse → dict
4. 若 content 含 ```json 围栏,部分 parser 需 PydanticOutputParser 或手动 strip
5. 结构化强约束优先 with_structured_output,parser 作兜底

字段级变形

1
2
3
AIMessage(content='{"a":1}')
→ JsonOutputParser.parse
{"a": 1}

3. 原理说明

3.1 StrOutputParser

StrOutputParser(类)
功能:取 AIMessage.content;若为 list[block] 则拼接文本块。构造无参数。
最小输入:1 条带 content 的 Message;空 content → ""
返回:str

1
2
from langchain_core.output_parsers import StrOutputParser
StrOutputParser().invoke(AIMessage(content="杭州"))

LCEL 最常用链尾。

3.2 JsonOutputParser

JsonOutputParser(类)
功能:对 content 做 json.loads。可选 pydantic_object 再校验。
默认值:无 schema 时返回 dict。
最小维度:content 必须是合法 JSON 对象或数组;非 JSON 抛错。最小对象 {} 可解析。

1
2
3
from langchain_core.output_parsers import JsonOutputParser
JsonOutputParser().invoke(AIMessage(content='{"city":"北京","temp":20}'))
# {'city': '北京', 'temp': 20}

适合 prompt 已强约束「只输出 JSON」且不用厂商 schema API 时。

3.3 PydanticOutputParser

PydanticOutputParser(pydantic_object)(类)
功能:旧式:把 format instructions 注入 prompt,再 parse。pydantic_object 必填,至少 1 个字段。
v1 更推荐 with_structured_output

1
2
3
from langchain_core.output_parsers import PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=Sentiment)
prompt_vars = {"format_instructions": parser.get_format_instructions()}

get_format_instructions()(方法)
返回 str,无参数。最小用法:拼进 prompt 的一个占位符。

3.4 stream 与 parser

流式时 StrOutputParser 可增量 concat chunk。JsonOutputParser 通常需完整 content 再 parse(半截 JSON 会失败)。
最小 stream:至少 1 个 chunk。


4. 最小可运行示例

1
pip install -U langchain-openai
1
2
3
4
5
6
7
8
9
from langchain_core.messages import AIMessage
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser

ai = AIMessage(content='{"city": "北京", "temp": 20}')
print(StrOutputParser().invoke(ai))
# 预期:{"city": "北京", "temp": 20} (整段 content 字符串)

print(JsonOutputParser().invoke(ai))
# 预期:{'city': '北京', 'temp': 20}

LCEL:真实模型先产出文本,再由 parser 取 content 或解析 JSON。

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
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser

model = ChatOpenAI(
model="qwen3.5:9b",
api_key="ollama",
base_url="http://localhost:11434/v1",
temperature=0,
)

str_chain = (
ChatPromptTemplate.from_template("只输出一个城市名,不要标点。问题:{q}")
| model
| StrOutputParser()
)
print(str_chain.invoke({"q": "浙江的省会"}))
# 预期形态:杭州

json_chain = (
ChatPromptTemplate.from_template(
"只输出 JSON,不要 markdown。键 city 与 temp(整数)。问题:{q}"
)
| model
| JsonOutputParser()
)
print(json_chain.invoke({"q": "虚构:杭州今天 22 度"}))
# 预期形态:dict,含 city、temp(数值随模型)

重要配置参数

参数(API 名) 类型 / 默认值 功能说明 作用与影响 参考起点 配置指导
Parser 类型 类,链尾 把 AIMessage 收成 str 或 dict Str 最稳;Json 遇非 JSON 抛错 Str / Json 强 schema 优先 with_structured_output
pydantic_object BaseModel,PydanticOutputParser 必填 旧式:按模型字段 parse 并生成 format instructions 新项目维护成本高 旧式 新代码少用
prompt format 指令 str,注入模板 用文字要求模型只输出 JSON 与 parser 成对才有效;模型仍可能加 markdown 模板内 Json 链必须写「不要 markdown」
temperature model 上 降低自由发挥,提高合法 JSON 率 宜 0 0 在 model.bind 设,不是 parser 上
流式 stream 方法 增量拼接 content 只有 StrOutputParser 适合半包;Json 须等完整 StrOutputParser Json 勿半包 parse
错误处理 应用层 parse 失败时 retry/fallback 并记录 raw 不处理则整链崩 retry / fallback 日志里保留原始 content

5. 易踩坑

  1. JsonOutputParser 遇 markdown 代码块:loads 失败;strip ``` 或换 structured output。
  2. AIMessage.content 为多模态 list:StrOutputParser 行为与纯 str 不同,需查版本文档。
  3. parser 与 prompt 约束不一致:prompt 让「自然语言回答」,parser 却当 JSON parse。

小结

  • StrOutputParser 是 LCEL 默认链尾,取 content 字符串
  • JsonOutputParser 适合轻量 JSON,可靠性低于 with_structured_output
  • Parser 是 Runnable,可 | 进链。
  • 强结构优先模型层 schema,parser 作兼容或兜底。

参考链接

-------------本文结束感谢您的阅读-------------