在上一节中学会了用|符号将组件串联起来。但是当你尝试构建一个多步推理的链比如先让 AI 起个名字再让 AI 根据这个名字写首诗时你可能会遇到一个令人头大的报错ValueError: Invalid input type class langchain_core.messages.ai.AIMessage. Must be a PromptValue, str, or list of BaseMessages.为什么明明组件都是Runnable连在一起却报错了今天我们就来揭秘这个“类型陷阱”并介绍 LangChain 中的关键组件 ——StrOutputParser。 问题复现为什么model | model会报错让我们先看一段看似合理但实际会崩溃的代码。假设我们想让模型做两件事第一步根据姓氏和性别起个名字。第二步根据这个名字写一句祝福语。fromlangchain_core.promptsimportPromptTemplatefromlangchain_community.chat_models.tongyiimportChatTongyi modelChatTongyi(modelqwen-plus)promptPromptTemplate.from_template(我的邻居姓{lastname}, 刚生了{gender}请起名仅告诉我名字无需其他内容)# ❌ 错误写法直接将两个模型串联chainprompt|model|model reschain.invoke({lastname:王,gender:男})print(res.content) 报错分析运行上述代码你会得到类似这样的错误ValueError: Invalid input type class langchain_core.messages.ai.AIMessage...原因解析第一个model的输出ChatModel 的invoke方法返回的是一个AIMessage对象包含 content, response_metadata 等属性。第二个model的输入ChatModel 的invoke方法不接受AIMessage对象作为直接输入它只接受str(字符串)PromptValue(提示词值对象)List[BaseMessage](消息列表)结论第一个模型的输出类型AIMessage与第二个模型的输入要求str/PromptValue不匹配。就像你想把方形积木塞进圆形的孔里当然会报错。️ 解决方案StrOutputParser为了解决类型不匹配的问题我们需要在两个模型中间加一个“转换器”。这个转换器负责把AIMessage对象“剥壳”提取出里面的纯文本字符串 (str)。这就是StrOutputParser的作用。✅ 什么是 StrOutputParser功能它是 LangChain 内置的最简单的输出解析器。它的唯一工作就是接收AIMessage返回message.content即纯字符串。身份它也是Runnable的子类所以可以完美地加入链中。地位它是连接“模型输出”和“需要字符串输入的下游组件”之间的桥梁。 修正后的代码fromlangchain_core.output_parsersimportStrOutputParserfromlangchain_community.chat_models.tongyiimportChatTongyifromlangchain_core.promptsimportPromptTemplate# 1. 实例化解析器parserStrOutputParser()modelChatTongyi(modelqwen-plus)promptPromptTemplate.from_template(我的邻居姓{lastname}, 刚生了{gender}请起名仅告诉我名字无需其他内容)# ✅ 正确写法在两个模型之间加入 parser# 数据流向# Dict - Prompt - AIMessage - [Parser] - String - Model - AIMessagechainprompt|model|parser|model reschain.invoke({lastname:王,gender:男})print( 最终结果)print(res.content)⚙️ 内部流转过程详解当我们调用chain.invoke(...)时数据经历了以下变身Input:{lastname: 王, gender: 男}↓(PromptTemplate 处理)Step 1 Output:AIMessage(content王浩然)--这里是对象↓(StrOutputParser 处理)Parser Output:王浩然--变成了字符串↓(第二个 Model 接收字符串)Step 2 Output:AIMessage(content祝王浩然小朋友健康快乐成长)正是因为有了parser这一步“类型转换”第二个模型才能顺利接收到它想要的字符串输入。 进阶思考为什么模型不直接返回字符串你可能会问“LangChain 为什么要设计得这么麻烦让模型直接返回字符串不就省事了吗”这是一个很好的架构设计问题。AIMessage对象不仅仅包含文本它还包含元数据Token 消耗量、延迟时间、模型版本。结构化信息在某些高级用法中可能包含工具调用请求Tool Calls。角色标识明确标记这是 AI 说的话区分于 Human 或 System。保留这些元数据对于调试、计费和构建复杂的 Agent 系统至关重要。StrOutputParser给了开发者选择权如果你只需要文本就加上它如果你需要完整信息就不加。 总结本节课我们解决了链式调用中的核心痛点类型 mismatch 问题理解了ChatModel输出AIMessage但不能直接作为下一个ChatModel输入的原因。StrOutputParser 的作用学会了使用它作为“适配器”将AIMessage转换为str。多步推理链构建掌握了Prompt | Model | Parser | Model的标准范式这是构建 Agent 自主规划、多轮反思等高级功能的基础。现在你的链条已经可以无限延长了只要记得在需要“纯文本”的地方插上StrOutputParser这个插头即可。
【第三周】RAG与Agent实战19:StrOutputParser字符串输出解析器
在上一节中学会了用|符号将组件串联起来。但是当你尝试构建一个多步推理的链比如先让 AI 起个名字再让 AI 根据这个名字写首诗时你可能会遇到一个令人头大的报错ValueError: Invalid input type class langchain_core.messages.ai.AIMessage. Must be a PromptValue, str, or list of BaseMessages.为什么明明组件都是Runnable连在一起却报错了今天我们就来揭秘这个“类型陷阱”并介绍 LangChain 中的关键组件 ——StrOutputParser。 问题复现为什么model | model会报错让我们先看一段看似合理但实际会崩溃的代码。假设我们想让模型做两件事第一步根据姓氏和性别起个名字。第二步根据这个名字写一句祝福语。fromlangchain_core.promptsimportPromptTemplatefromlangchain_community.chat_models.tongyiimportChatTongyi modelChatTongyi(modelqwen-plus)promptPromptTemplate.from_template(我的邻居姓{lastname}, 刚生了{gender}请起名仅告诉我名字无需其他内容)# ❌ 错误写法直接将两个模型串联chainprompt|model|model reschain.invoke({lastname:王,gender:男})print(res.content) 报错分析运行上述代码你会得到类似这样的错误ValueError: Invalid input type class langchain_core.messages.ai.AIMessage...原因解析第一个model的输出ChatModel 的invoke方法返回的是一个AIMessage对象包含 content, response_metadata 等属性。第二个model的输入ChatModel 的invoke方法不接受AIMessage对象作为直接输入它只接受str(字符串)PromptValue(提示词值对象)List[BaseMessage](消息列表)结论第一个模型的输出类型AIMessage与第二个模型的输入要求str/PromptValue不匹配。就像你想把方形积木塞进圆形的孔里当然会报错。️ 解决方案StrOutputParser为了解决类型不匹配的问题我们需要在两个模型中间加一个“转换器”。这个转换器负责把AIMessage对象“剥壳”提取出里面的纯文本字符串 (str)。这就是StrOutputParser的作用。✅ 什么是 StrOutputParser功能它是 LangChain 内置的最简单的输出解析器。它的唯一工作就是接收AIMessage返回message.content即纯字符串。身份它也是Runnable的子类所以可以完美地加入链中。地位它是连接“模型输出”和“需要字符串输入的下游组件”之间的桥梁。 修正后的代码fromlangchain_core.output_parsersimportStrOutputParserfromlangchain_community.chat_models.tongyiimportChatTongyifromlangchain_core.promptsimportPromptTemplate# 1. 实例化解析器parserStrOutputParser()modelChatTongyi(modelqwen-plus)promptPromptTemplate.from_template(我的邻居姓{lastname}, 刚生了{gender}请起名仅告诉我名字无需其他内容)# ✅ 正确写法在两个模型之间加入 parser# 数据流向# Dict - Prompt - AIMessage - [Parser] - String - Model - AIMessagechainprompt|model|parser|model reschain.invoke({lastname:王,gender:男})print( 最终结果)print(res.content)⚙️ 内部流转过程详解当我们调用chain.invoke(...)时数据经历了以下变身Input:{lastname: 王, gender: 男}↓(PromptTemplate 处理)Step 1 Output:AIMessage(content王浩然)--这里是对象↓(StrOutputParser 处理)Parser Output:王浩然--变成了字符串↓(第二个 Model 接收字符串)Step 2 Output:AIMessage(content祝王浩然小朋友健康快乐成长)正是因为有了parser这一步“类型转换”第二个模型才能顺利接收到它想要的字符串输入。 进阶思考为什么模型不直接返回字符串你可能会问“LangChain 为什么要设计得这么麻烦让模型直接返回字符串不就省事了吗”这是一个很好的架构设计问题。AIMessage对象不仅仅包含文本它还包含元数据Token 消耗量、延迟时间、模型版本。结构化信息在某些高级用法中可能包含工具调用请求Tool Calls。角色标识明确标记这是 AI 说的话区分于 Human 或 System。保留这些元数据对于调试、计费和构建复杂的 Agent 系统至关重要。StrOutputParser给了开发者选择权如果你只需要文本就加上它如果你需要完整信息就不加。 总结本节课我们解决了链式调用中的核心痛点类型 mismatch 问题理解了ChatModel输出AIMessage但不能直接作为下一个ChatModel输入的原因。StrOutputParser 的作用学会了使用它作为“适配器”将AIMessage转换为str。多步推理链构建掌握了Prompt | Model | Parser | Model的标准范式这是构建 Agent 自主规划、多轮反思等高级功能的基础。现在你的链条已经可以无限延长了只要记得在需要“纯文本”的地方插上StrOutputParser这个插头即可。