18. LangChain输出解析器实战:从大模型输出到结构化数据的转化

在实际开发AI应用时,我们常会遇到一个很实际的问题:大模型的输出大多是自然语言文本,但我们搭建的应用程序,往往只能处理字符串、JSON、列表这类结构化数据。两者格式不匹配,就会导致大模型的输出无法直接被应用调用,而LangChain内置的输出解析器,正是为了解决这个痛点而生的。视频看这里《18. 动画讲解 LangChain 解析器!一看就懂》

最基础也最常用的,就是StrOutputParser。它的作用很简单,就是把大模型的输出,直接转换成纯文本字符串------看起来简单,但却是很多AI应用的基础操作,毕竟很多场景下,我们只需要干净的文本输出,无需多余格式。

我们用一个简单的案例来演示,比如让大模型扮演"笑话大王",输出一个笑话,再用StrOutputParser解析结果。具体代码如下,每一步都标注了核心作用,大家可以直接复制实操:

复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 定义提示词模板,指定大模型的角色和用户输入
prompt = ChatPromptTemplate.from_messages(
    [
        {"role": "system", "content": "你是一个笑话大王"},
        {"role": "user", "content": "{new_input}"}
    ]
)
# 传入用户输入,生成完整的提示词
prompt_value = prompt.invoke(
    {
        "new_input": "讲一个笑话"
    }
)
# 调用大模型,获取原始输出
res = llm.invoke(prompt_value, config=config)
# 初始化解析器,解析大模型输出为纯文本
parser = StrOutputParser()
result = parser.invoke(res)
# 打印解析后的结果
print(result)

运行这段代码后,大家会发现,大模型的输出会被解析成一段干净的纯文本,没有任何多余的格式,刚好能满足应用程序对字符串输入的需求。

除了常规的一次性输出,实际开发中我们还常会用到流式输出------比如让大模型的回复像聊天一样逐字显示,提升用户体验。这种情况下,StrOutputParser同样适用,只需要稍微调整代码,就能实现流式解析。

流式输出的处理代码如下,重点在于用stream方法调用大模型,再用解析器的transform方法逐块解析流式数据:

复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 提示词模板和之前一致,指定大模型角色
prompt = ChatPromptTemplate.from_messages(
    [
        {"role": "system", "content": "你是一个笑话大王"},
        {"role": "user", "content": "{input}"}
    ]
)
# 传入用户输入,生成提示词
prompt_value = prompt.invoke(
    {
        "new_input": "讲一个笑话"
    }
)
# 用stream方法调用大模型,获取流式输出
res = llm.stream(prompt_value, config=config)
# 初始化解析器,逐块解析流式数据并打印
parser = StrOutputParser()
for chunk in parser.transform(res):
    print(chunk, end="", flush=True)

这里有个小细节需要注意:print语句里的end=""和flush=True,是为了让解析后的内容逐字连续显示,不会出现换行或卡顿的情况,完美还原流式输出的效果。

其实StrOutputParser的核心价值,就是"做减法"------去掉大模型输出中多余的格式冗余,只保留纯文本内容,让大模型的输出能直接适配应用程序的需求。对于刚接触LangChain的开发者来说,先掌握这个最简单的解析器,再逐步学习更复杂的JSON解析器、列表解析器,就能轻松解决大模型输出与应用程序格式不匹配的问题。