LangChain大模型应用开发:多模态输入与自定义输出

embedded/2025/2/24 21:37:00/

介绍

大家好,博主又来给大家分享知识了。今天给大家分享的内容是使用LangChain进行大模型应用开发中的多模态输入与自定义输出。

LangChain中的多模态数据输入是指将多种不同形式的数据作为输入提供给基于语言模型的应用程序或系统,以丰富交互内容和提升模型处理能力,让应用能够处理和理解更广泛的信息类型,从而更好地满足用户多样化的需求。

LangChain自定义输出指的是开发者依据具体应用场景和业务需求,对基于LangChain构建的大模型应用输出结果的形式、内容、风格等进行个性化定制的能力。在一些需要数据规整呈现的场景下,我们可以让LangChain输出特定格式的结构化数据,比如JSONXML、YAML等。

好了,我们直接进入正题。

多模态数据输入

这里我们演示如何将多模态输入直接传递给模型。我们目前期望所有输入都以与OpenAI期望的格式相同的格式传递。对于支持多模态输入的其他模型提供者,我们在类中添加了逻辑以转换为预期格式。

在这个演示中,我们让大模型帮助我们描述下面这张图片。

获取Base64编码的图片信息

其中,最常支持的传入图片的方式是将其作为字节字符串传入。这种方式适用于大多数模型集成。

完整代码

python"># 从langchain_core.messages模块导入HumanMessage类,用于创建人类发送的消息
from langchain_core.messages import HumanMessage
# 从langchain_openai模块导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI
# 导入base64模块,用于对图片数据进行Base64编码
import base64
# 导入httpx库,用于发送HTTP请求获取图片
import httpx# 初始化一个ChatOpenAI实例,使用gpt-4o模型
model = ChatOpenAI(model="gpt-4o")# 定义图片的URL地址
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"# 通过httpx库发送请求获取图片内容,并使用base64对其进行编码,最后解码为字符串
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")# 创建一个HumanMessage实例,包含文本请求和Base64编码的图片信息
message = HumanMessage(content=[{"type": "text", "text": "用中文描述这张图片中的天气"},{"type": "image_url","image_url": {"url": f"data:image/jpeg;base64,{image_data}"},},],
)# 调用模型处理消息并获取响应
response = model.invoke([message])# 打印模型对图片天气描述的响应内容
print(response.content)

运行结果

python">这张图片中的天气晴朗,碧蓝的天空中点缀着几朵薄薄的白云。太阳光线充足,明媚的阳光洒在绿色的草地和木质步道上,显得格外清新和温暖。整体感觉空气清新,风和日丽,是一个非常舒适宜人的天气。进程已结束,退出代码为 0

获取URL原始图片信息

我们可以在“image_url”类型的内容模块中直接提供图像URL。但是,前提是:我们使用的模型供应商必须支持此功能

完整代码

python"># 从langchain_core.messages模块导入HumanMessage类,用于创建人类发送的消息
from langchain_core.messages import HumanMessage
# 从langchain_openai模块导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化一个ChatOpenAI实例,使用gpt-4o模型
model = ChatOpenAI(model="gpt-4o")# 定义图片的URL地址
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"# 通过httpx库发送请求获取图片内容,并使用base64对其进行编码,最后解码为字符串
image_data = base64.b64encode(httpx.get(image_url).content).decode("utf-8")# 创建一个HumanMessage实例,包含文本请求和原始图片URL信息
message = HumanMessage(content=[{"type": "text", "text": "用中文描述这张图片中的天气"},{"type": "image_url", "image_url": {"url": image_url}},],
)# 调用模型处理消息并获取响应
response = model.invoke([message])# 打印模型对图片天气描述的响应内容
print(response.content)

运行结果

python">这张图片中的天气非常晴朗。天空中有一些轻薄的白云,主要以蓝色为主,显得天特别的高远。阳光明媚,照在绿色的草地上,使整个景象显得非常明亮和清新。整体感觉温暖且令人愉悦,适合外出活动。进程已结束,退出代码为 0

对比多张图片信息

我们还可以传入多张图片并可以让大模型帮我们进行对比。

完整代码

python"># 从langchain_core.messages模块导入HumanMessage类,用于创建人类发送的消息
from langchain_core.messages import HumanMessage
# 从langchain_openai模块导入ChatOpenAI类,用于调用 OpenAI 的聊天模型
from langchain_openai import ChatOpenAI# 初始化一个ChatOpenAI实例,使用gpt-4o模型
model = ChatOpenAI(model="gpt-4o")# 定义图片的URL地址
image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"# 创建一个HumanMessage实例,询问两张相同图片是否一样,并附带两张图片的URL
message = HumanMessage(content=[{"type": "text", "text": "这两张图片是一样的吗?"},{"type": "image_url", "image_url": {"url": image_url}},{"type": "image_url", "image_url": {"url": image_url}},],
)# 调用模型处理消息并获取响应
response = model.invoke([message])# 打印模型对两张图片是否相同的响应内容
print(response.content)

运行结果

python">是的,这两张图片是一样的。它们显示了同一个风景场景,都是在一片绿色的草地上,有一条木板路延伸至远处,天空中有少许云彩。从图像内容、颜色和细节上看,它们是完全相同的。进程已结束,退出代码为 0

工具调用

一些多模态模型也支持工具调用功能。要使用此类模型调用工具,只需以通常的方式将工具绑定到它们,然后使用所需类型的内容块(例如,包含图像数据)调用模型。

我们自定义一个名为weather_tool的工具函数,接收一个表示天气状况的参数,参数类型只能是指定的几种天气情况。然后我们利用LangChain库,结合OpenAIgpt-4o模型,实现对两张图片中天气状况的分析描述功能。

完整代码

python"># 导入Literal类型,用于定义一个只能取特定值的类型
from typing import Literal
# 导入HumanMessage类,用于创建人类发送的消息对象
from langchain_core.messages import HumanMessage
# 导入ChatOpenAI类,用于与OpenAI的聊天模型进行交互
from langchain_openai import ChatOpenAI
# 导入tool装饰器,用于将函数转换为工具
from langchain_core.tools import tool# 使用tool装饰器将weather_tool函数转换为一个工具
@tool
# 定义一个名为weather_tool的工具函数,接收一个表示天气状况的参数,参数类型只能是指定的几种天气情况
def weather_tool(weather: Literal["晴朗的", "多云的", "多雨的", "下雪的"]) -> None:"""Describe the weather"""  # 函数的文档字符串,用于描述函数的功能是描述天气pass  # 函数体为空,暂时不做具体操作# 初始化一个ChatOpenAI对象,使用gpt-4o模型
model = ChatOpenAI(model="gpt-4o")# 将模型与工具绑定,使得模型在运行时可以调用weather_tool工具
model_with_tools = model.bind_tools([weather_tool])# 定义第一张图片的URL
image_url_1 = "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Gfp-wisconsin-madison-the-nature-boardwalk.jpg/2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"# 定义第二张图片的URL
image_url_2 = "https://upload.wikimedia.org/wikipedia/commons/thumb/9/92/Morning_in_China_Snow_Town.jpg/1280px-Morning_in_China_Snow_Town.jpg"# 创建一个人类消息对象
message = HumanMessage(content=[  # 消息内容是一个列表,包含文本和图片URL信息{"type": "text", "text": "用中文描述两张图片中的天气"},  # 文本内容,指示模型要完成的任务{"type": "image_url", "image_url": {"url": image_url_1}},  # 第一张图片的URL信息{"type": "image_url", "image_url": {"url": image_url_2}},  # 第二张图片的URL信息],
)# 调用绑定了工具的模型,传入人类消息,得到模型的响应
response = model_with_tools.invoke([message])# 打印模型响应中调用工具的相关信息
print(response.tool_calls)

运行结果

python">[{'name': 'weather_tool', 'args': {'weather': '晴朗的'}, 'id': 'call_cgXu6gngXss6RpgcLamxqB8R', 'type': 'tool_call'}, {'name': 'weather_tool', 'args': {'weather': '下雪的'}, 'id': 'call_aU3xRKwucotSpu2FinamfnHq', 'type': 'tool_call'}]进程已结束,退出代码为 0

从上面的运行结果我们可以看到,当大模型响应完成后我们再去调用自定义工具,输出结果会按照我们自定义工具的参数格式及类型返回。

自定义格式输出

LangChain中,自定义格式输出是指按照特定需求对模型生成的结果进行格式化处理,以满足实际应用的多样化需求。这一功能非常实用,因为语言模型的输出往往是通用的文本形式,而实际使用中可能需要将其转换为特定的数据结构、字符串格式或其他应用程序易于处理的形式。

解析JSON格式输出

虽然一些模型提供商支持内置的方法返回结构化输出,但并非所有都支持。我们可以使用输出解析器来帮助用户通过提示指定任意的JSON模式,查询符合该模式的模型输出,最后将该模式解析为 JSON

请记住,大模型不是完美无缺的,存在着数据、准确性、可靠性等方面的风险和不确定性,在使用时需要谨慎,我们必须使用具有足够容量的大语言模型,具备更强的语言理解和生成能力,以及更好的逻辑和结构化输出能力。

JsonOutputParser是一个内置选项,用于提示并解析JSON输出。虽然它在功能上类似于 PydanticOutputParser,但它还支持流式返回部分JSON对象。

下面,我们将演示如何将其与Pydantic一起使用以方便地声明预期模式。

完整代码

python"># 从langchain_core库中导入JsonOutputParser类,用于将模型输出解析为JSON格式
from langchain_core.output_parsers import JsonOutputParser
# 从langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从pydantic库中导入BaseModel和Field类,用于定义数据模型和字段描述
from pydantic import BaseModel, Field
# 从langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-3.5-turbo模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 定义一个名为Joke的类,继承自BaseModel,用于表示笑话的数据结构
class Joke(BaseModel):# 定义setup字段,类型为字符串,描述为设置笑话的问题setup: str = Field(description="设置笑话的问题")# 定义punchline字段,类型为字符串,描述为解决笑话的答案punchline: str = Field(description="解决笑话的答案")# 定义一个字符串变量,作为向语言模型请求笑话的查询语句
joke_query = "请给我讲个编程的笑话。"# 创建JsonOutputParser实例,指定pydantic对象为Joke类,用于解析符合Joke结构的JSON输出
json_output_parser = JsonOutputParser(pydantic_object=Joke)# 创建PromptTemplate实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": json_output_parser.get_format_instructions()},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model | json_output_parser# 调用处理链,传入查询语句,得到处理结果
result = chain.invoke({"query": joke_query})# 打印最终处理得到的结果
print(result)

运行结果

python">{'setup': '为什么计算机工程师喜欢使用黑色背景的代码编辑器?', 'punchline': '因为黑色背景让BUG无处藏。'}进程已结束,退出代码为 0

在上述代码PromptTemplate中的partial_variables属性,我们添加format_instructions变量,然后通过get_format_instructions()方法赋值,这个方法会生成一段指导语言模型按照特定JSON格式输出的指令文本。

我们也可以将format_instructions设置为自定义的值。

自定义提示格式代码演示

python">custom_instructions = '请用中文来回答。输出应格式化为符合以下JSON模式的JSON实例。例如,对于模式{"properties": {"foo": {"title": "Foo", "description": "字符串列表", "type": "array", "items": {"type": "string"}}}, "required": ["foo"]},对象 {"foo": ["bar", "baz"]}是该模式的格式良好实例。对象{"properties": {"foo": ["bar", "baz"]}}不是格式良好的。'prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": custom_instructions},
)

请大家自行去测试并查看与之前有什么不同😊。

流式处理

如上所述,JsonOutputParserPydanticOutputParser之间的一个关键区别是JsonOutputParser输出解析器支持流式处理部分块。我们演示一下:

流出输出完整代码

python"># 从langchain_core库中导入JsonOutputParser类,用于将模型输出解析为JSON格式
from langchain_core.output_parsers import JsonOutputParser
# 从 langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从 pydantic库中导入BaseModel和Field类,用于定义数据模型和字段描述
from pydantic import BaseModel, Field
# 从 langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-3.5-turbo模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 定义一个名为Joke的类,继承自BaseModel,用于表示笑话的数据结构
class Joke(BaseModel):# 定义setup字段,类型为字符串,描述为设置笑话的问题setup: str = Field(description="设置笑话的问题")# 定义punchline字段,类型为字符串,描述为解决笑话的答案punchline: str = Field(description="解决笑话的答案")# 定义一个字符串变量,作为向语言模型请求笑话的查询语句
joke_query = "请给我讲个编程的笑话。"# 创建JsonOutputParser实例,指定pydantic对象为Joke类,用于解析符合 Joke 结构的 JSON 输出
json_output_parser = JsonOutputParser(pydantic_object=Joke)# 创建 PromptTemplate 实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": json_output_parser.get_format_instructions()},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model | json_output_parser# 每次从生成器中获取的元素chain_stream是语言模型逐步生成的部分结果
for chain_stream in chain.stream({"query": joke_query}):# 打印每次从生成器中获取的部分结果,方便查看模型逐步生成输出的过程print(chain_stream)

流式输出运行结果

python">{}
{'setup': ''}
{'setup': '为'}
{'setup': '为什'}
{'setup': '为什么'}
{'setup': '为什么程序'}
{'setup': '为什么程序员'}
{'setup': '为什么程序员喜'}
{'setup': '为什么程序员喜欢'}
{'setup': '为什么程序员喜欢冷'}
{'setup': '为什么程序员喜欢冷笑'}
{'setup': '为什么程序员喜欢冷笑话'}
{'setup': '为什么程序员喜欢冷笑话?'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': ''}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电脑'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电脑听'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电脑听得'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电脑听得懂'}
{'setup': '为什么程序员喜欢冷笑话?', 'punchline': '因为只有他们的电脑听得懂!'}进程已结束,退出代码为 0

我们也可以在没有Pydantic的情况下使用JsonOutputParser。此时,它会提示模型返回JSON格式的内容,但不会提供基于Pydantic定义的那种精确、详细的模式信息。不过,我们仍可通过在提示中手动说明等方式,为模型提供一些关于输出模式的大致要求。

不使用Pydantic完整代码

python"># 从langchain_core库中导入JsonOutputParser类,用于将模型输出解析为JSON格式
from langchain_core.output_parsers import JsonOutputParser
# 从langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-3.5-turbo模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 定义一个字符串变量,作为向语言模型请求笑话的查询语句
joke_query = "请给我讲个编程的笑话,并用中文来回答"# 创建JsonOutputParser实例,用于解析JSON输出
json_output_parser = JsonOutputParser()# 创建 PromptTemplate 实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": json_output_parser.get_format_instructions()},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model | json_output_parser# 调用处理链,传入查询语句,得到处理结果
result = chain.invoke({"query": joke_query})# 打印最终处理得到的结果
print(result)

 不使用Pydantic运行结果

python">{'response': '为什么程序员总喜欢晒代码?因为他们觉得自己的代码是最美的!'}进程已结束,退出代码为 0

解析XML格式输出

下面我们将演示如何使用XMLOutputParser来提示模型生成XML输出,然后将该输出解析为可用的格式。

标准解析完整代码

python"># 从langchain_core库中导入XMLOutputParser类,用于将模型输出解析为XML格式
from langchain_core.output_parsers import XMLOutputParser
# 从langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-4o模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-4o", temperature=0)# 定义一个字符串变量,作为向语言模型发送需求
actor_query = "请帮我生成Jackie Chan主演的电影作品列表,按照最新的时间降序。请用中文来回答。"# 创建XMLOutputParser实例,用于解析XML输出
xml_output_parser = XMLOutputParser()# 我们将在下面的提示中添加这些指令
custom_instructions = """输出应格式化为XML文件。1. 输出应符合以下标签。2. 如果没有给出标签,请自行创建。3. 记住始终要打开和关闭所有标签。例如,对于标签 ["foo", "bar", "baz"]:1. String "<foo><bar><baz></baz></bar></foo>” 是符合模式的格式良好的实例。2. String "<foo><bar></foo>” 是格式错误的实例。3. String "<foo><tag></tag></foo>” 是格式错误的实例。
"""# 创建PromptTemplate实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": custom_instructions},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model# 调用处理链,传入查询语句,得到处理结果
result = chain.invoke({"query": actor_query})# 打印最终处理得到的结果
print(result.content)

标准解析运行结果

python">```xml
<filmography><actor><name>成龙</name><movies><movie><title>急速追杀</title><release_year>2023</release_year><description>成龙与约翰·塞纳联袂出演的一部动作喜剧电影。</description></movie><movie><title>龙马精神</title><release_year>2023</release_year><description>成龙饰演一名老马术表演演员,电影以马术为主题融合了温情与幽默。</description></movie><movie><title>机器之血</title><release_year>2017</release_year><description>成龙主演的动作科幻电影,讲述一场围绕尖端技术展开的较量。</description></movie><movie><title>英伦对决</title><release_year>2017</release_year><description>成龙饰演一位悲痛欲绝的父亲,为追查女儿遇害的真相而孤军奋战。</description></movie><movie><title>绝地逃亡</title><release_year>2016</release_year><description>成龙与约翰尼·诺克斯维尔合作的一部动作喜剧电影。</description></movie><movie><title>天将雄师</title><release_year>2015</release_year><description>讲述了汉朝时期西域的一位将军保护丝绸之路的故事。</description></movie><movie><title>十二生肖</title><release_year>2012</release_year><description>成龙主演并执导的冒险动作电影,围绕失落的中国国家文物而展开。</description></movie><movie><title>功夫梦</title><release_year>2010</release_year><description>成龙与贾登·史密斯合作的翻拍版本电影,传递了传统武术精神。</description></movie></movies></actor>
</filmography>
```进程已结束,退出代码为 0

我们还可以添加一些标签以根据我们的需求定制输出。我们可以在提示的其他部分中尝试添加自己的格式提示,以增强或替换默认指令。

按标签解析完整代码

python"># 从langchain_core库中导入XMLOutputParser类,用于将模型输出解析为XML格式
from langchain_core.output_parsers import XMLOutputParser
# 从langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-4o模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-4o", temperature=0)# 定义一个字符串变量,作为向语言模型发送需求
actor_query = "请帮我生成Jackie Chan主演的电影作品列表,按照最新的时间降序。请用中文来回答。"# 创建XMLOutputParser实例,用于解析XML输出
xml_output_parser = XMLOutputParser()# 我们将在下面的提示中添加这些指令
custom_instructions = """输出应格式化为XML文件。1. 输出应符合以下标签。2. 如果没有给出标签,请自行创建。3. 记住始终要打开和关闭所有标签。例如,对于标签 ["foo", "bar", "baz"]:1. String "<foo><bar><baz></baz></bar></foo>” 是符合模式的格式良好的实例。2. String "<foo><bar></foo>” 是格式错误的实例。3. String "<foo><tag></tag></foo>” 是格式错误的实例。以下是输出标签:'''['movies', 'actor', 'film', 'name', 'genre']
"""# 创建PromptTemplate实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": custom_instructions},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model# 调用处理链,传入查询语句,得到处理结果
result = chain.invoke({"query": actor_query})# 打印最终处理得到的结果
print(result.content)

按标签解析运行结果

python">```xml
<movies><actor><name>成龙</name></actor><film><name>急先锋</name><genre>动作</genre><year>2020</year></film><film><name>龙牌之谜</name><genre>奇幻, 冒险</genre><year>2019</year></film><film><name>机器之血</name><genre>动作, 科幻</genre><year>2018</year></film><film><name>功夫瑜伽</name><genre>动作, 冒险, 喜剧</genre><year>2017</year></film><film><name>铁道飞虎</name><genre>动作, 冒险, 喜剧</genre><year>2016</year></film><film><name>绝地逃亡</name><genre>动作, 喜剧</genre><year>2016</year></film><film><name>天将雄师</name><genre>动作, 历史, 战争</genre><year>2015</year></film><film><name>警察故事2013</name><genre>动作, 犯罪, 剧情</genre><year>2013</year></film><film><name>十二生肖</name><genre>动作, 冒险, 喜剧</genre><year>2012</year></film>
</movies>
```进程已结束,退出代码为 0

同样的,该解析器支持流式处理部分块。 

流式输出完整代码

python"># 从langchain_core库中导入XMLOutputParser类,用于将模型输出解析为XML格式
from langchain_core.output_parsers import XMLOutputParser
# 从langchain_core库中导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从langchain_openai库中导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 初始化ChatOpenAI模型实例,使用gpt-4o模型,设置temperature=0不考虑随机性
chat_model = ChatOpenAI(model_name="gpt-4o", temperature=0)# 定义一个字符串变量,作为向语言模型发送需求
actor_query = "请帮我生成Jackie Chan主演的电影作品列表,按照最新的时间降序。请用中文来回答。"# 创建XMLOutputParser实例,并按标签解析XML输出
xml_output_parser = XMLOutputParser(tags=['movies', 'actor', 'film', 'name', 'genre'])# 创建PromptTemplate实例,定义提示模板的格式
prompt = PromptTemplate(# 模板字符串,包含回答查询、格式指令和用户查询三部分template="回答用户的查询。\n{format_instructions}\n{query}\n",# 指定输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令插入到模板中partial_variables={"format_instructions": xml_output_parser.get_format_instructions()},
)# 使用管道操作符将提示模板、模型和解析器连接成一个处理链
chain = prompt | chat_model# 每次从生成器中获取的元素chain_stream是语言模型逐步生成的部分结果
for chain_stream in chain.stream({"query": actor_query}):# 打印每次从生成器中获取的部分结果,方便查看模型逐步生成输出的过程print(chain_stream)

流式输出运行结果

python">content='' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='```' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='xml' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='<' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='movies' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='   ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='actor' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='成' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='龙' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='急' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='先锋' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='动作' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=',' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' 冒' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='险' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='龙' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='牌' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='之' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='谜' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='奇' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='幻' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=',' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' 历' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='史' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='机器' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='之' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='血' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='科' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='幻' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=',' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' 动' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='作' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='功' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='夫' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='瑜' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='伽' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='动作' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=',' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' 喜' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='剧' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='铁' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='道' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='飞' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='虎' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='name' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='           ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' <' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='喜' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='剧' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=',' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' 动' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='作' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='genre' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='       ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='film' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='   ' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content=' </' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='actor' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='</' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='movies' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='>\n' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='```' additional_kwargs={} response_metadata={} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'
content='' additional_kwargs={} response_metadata={'finish_reason': 'stop', 'model_name': 'gpt-4o-2024-08-06', 'system_fingerprint': 'fp_b705f0c291'} id='run-d0a803c9-f3bd-4af8-92d3-030addf44842'进程已结束,退出代码为 0

解析YAML格式输出

来自不同提供商的大型语言模型(LLMs)通常根据它们训练的具体数据具有不同的优势。这也意味着有些模型在生成JSON以外的格式输出方面可能更 “优秀” 和可靠。

这个输出解析器允许用户指定任意模式,并查询符合该模式的LLMs输出,使用YAML格式化他们的响应。

我们使用PydanticYamlOutputParser来声明我们的数据模型,并为模型提供更多关于应生成何种类型YAML的上下文信息。

标准解析完整代码

python"># 从langchain导入YamlOutputParser类,用于将输出解析为YAML格式
from langchain.output_parsers import YamlOutputParser
# 从langchain_core导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从pydantic库中导入BaseModel和Field类,用于定义数据模型和字段描述
from pydantic import BaseModel, Field
# 从langchain_openai导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 定义一个名为Joke的数据模型类,继承自BaseModel
class Joke(BaseModel):# 定义setup属性,为字符串类型,用于存储笑话的问题,并添加描述信息setup: str = Field(description="设置笑话的问题")# 定义punchline属性,为字符串类型,用于存储笑话的答案,并添加描述信息punchline: str = Field(description="解答笑话的答案")# 初始化ChatOpenAI模型。
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 创建一个查询,旨在提示语言模型填充数据结构。
joke_query = "请给我将一个关于编程的笑话。用中文来回答。"# 初始化YamlOutputParser解析器,指定要解析成的Pydantic对象为Joke类
yaml_output_parser = YamlOutputParser(pydantic_object=Joke)# 创建一个提示模板,包含回答查询的要求、格式指令和具体查询内容
prompt = PromptTemplate(# 模板内容,包含回答要求、格式指令和查询变量template="回答用户的查询。\n{format_instructions}\n{query}\n",# 定义模板中的输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令注入到模板中partial_variables={"format_instructions": yaml_output_parser.get_format_instructions()},
)# 创建一个链式处理流程,先通过提示模板处理输入,再传入模型进行处理
chain = prompt | chat_model# 打印解析器的格式指令,方便查看
print(yaml_output_parser.get_format_instructions())# 调用链式处理流程,传入查询内容,获取模型的响应
response = chain.invoke({"query": joke_query})# 打印模型响应的内容
print(response.content)

标准解析运行结果

python">The output should be formatted as a YAML instance that conforms to the given JSON schema below.# Examples
## Schema
```
{"title": "Players", "description": "A list of players", "type": "array", "items": {"$ref": "#/definitions/Player"}, "definitions": {"Player": {"title": "Player", "type": "object", "properties": {"name": {"title": "Name", "description": "Player name", "type": "string"}, "avg": {"title": "Avg", "description": "Batting average", "type": "number"}}, "required": ["name", "avg"]}}}
```
## Well formatted instance
```
- name: John Doeavg: 0.3
- name: Jane Maxfieldavg: 1.4
```## Schema
```
{"properties": {"habit": { "description": "A common daily habit", "type": "string" }, "sustainable_alternative": { "description": "An environmentally friendly alternative to the habit", "type": "string"}}, "required": ["habit", "sustainable_alternative"]}
```
## Well formatted instance
```
habit: Using disposable water bottles for daily hydration.
sustainable_alternative: Switch to a reusable water bottle to reduce plastic waste and decrease your environmental footprint.
``` Please follow the standard YAML formatting conventions with an indent of 2 spaces and make sure that the data types adhere strictly to the following JSON schema: 
```
{"properties": {"setup": {"description": "\u8bbe\u7f6e\u7b11\u8bdd\u7684\u95ee\u9898", "title": "Setup", "type": "string"}, "punchline": {"description": "\u89e3\u7b54\u7b11\u8bdd\u7684\u7b54\u6848", "title": "Punchline", "type": "string"}}, "required": ["setup", "punchline"]}
```Make sure to always enclose the YAML output in triple backticks (```). Please do not add anything other than valid YAML output!
```
setup: 为什么程序员总是悲伤?
punchline: 因为他们总是在处理 BUG。
```
setup='为什么程序员总是悲伤?' punchline='因为他们总是在处理 BUG。'进程已结束,退出代码为 0

同样的,该解析器支持流式处理部分块。

流式输出完整代码

python"># 从langchain导入YamlOutputParser类,用于将输出解析为YAML格式
from langchain.output_parsers import YamlOutputParser
# 从langchain_core导入PromptTemplate类,用于创建提示模板
from langchain_core.prompts import PromptTemplate
# 从pydantic库中导入BaseModel和Field类,用于定义数据模型和字段描述
from pydantic import BaseModel, Field
# 从langchain_openai导入ChatOpenAI类,用于调用OpenAI的聊天模型
from langchain_openai import ChatOpenAI# 定义一个名为Joke的数据模型类,继承自BaseModel
class Joke(BaseModel):# 定义setup属性,为字符串类型,用于存储笑话的问题,并添加描述信息setup: str = Field(description="设置笑话的问题")# 定义punchline属性,为字符串类型,用于存储笑话的答案,并添加描述信息punchline: str = Field(description="解答笑话的答案")# 初始化ChatOpenAI模型。
chat_model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)# 创建一个查询,旨在提示语言模型填充数据结构。
joke_query = "请给我将一个关于编程的笑话。用中文来回答。"# 初始化YamlOutputParser解析器,指定要解析成的Pydantic对象为Joke类
yaml_output_parser = YamlOutputParser(pydantic_object=Joke)# 创建一个提示模板,包含回答查询的要求、格式指令和具体查询内容
prompt = PromptTemplate(# 模板内容,包含回答要求、格式指令和查询变量template="回答用户的查询。\n{format_instructions}\n{query}\n",# 定义模板中的输入变量为 queryinput_variables=["query"],# 部分变量,将解析器的格式指令注入到模板中partial_variables={"format_instructions": yaml_output_parser.get_format_instructions()},
)# 创建一个链式处理流程,先通过提示模板处理输入,再传入模型进行处理
chain = prompt | chat_model# 每次从生成器中获取的元素chain_stream是语言模型逐步生成的部分结果
for chain_stream in chain.stream({"query": joke_query}):# 打印每次从生成器中获取的部分结果,方便查看模型逐步生成输出的过程print(chain_stream)

流式输出运行结果

python">content='' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='``' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='`\n' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='setup' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content=':' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content=' ' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='为' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='什' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='么' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='程序' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='员' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='总' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='是' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='选择' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='快' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='餐' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='作' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='为' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='午' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='餐' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='?\n' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='p' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='unch' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='line' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content=':' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content=' 因' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='为' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='他' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='们' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='喜' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='欢' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='用' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='字' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='节' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='填' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='饱' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='自' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='己' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='!' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='\n' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='```' additional_kwargs={} response_metadata={} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'
content='' additional_kwargs={} response_metadata={'finish_reason': 'stop', 'model_name': 'gpt-3.5-turbo', 'system_fingerprint': 'fp_0165350fbb'} id='run-743ce710-3522-416e-acec-c98ffd30c7c5'进程已结束,退出代码为 0

结束

好了,以上就是本次分享的全部内容了。希望大家能掌握与理解今天分享的内容。今天分享的内容代码部分比较多,请大家多在自己的电脑上多去测试与调试,我相信大家肯定会有所收获的!

LangChain作为一个强大的语言模型驱动的应用程序的开源框架,在数据输入和输出方面具备独特优势。

首先,它将文本、图像、音频等多种不同形式的数据,作为输入提供给基于语言模型的应用程序或系统。这种方式极大地丰富了交互内容,提升了模型处理能力,使应用能够处理和理解更广泛的信息类型,从而更好地满足用户多样化的需求。比如在智能客服场景中,用户既可以输入文字咨询,也能发送图片、语音等,模型可综合这些信息做出更准确全面的回复。

并且,开发者能依据具体应用场景和业务需求,对基于LangChain构建的大模型应用输出结果进行个性化定制。涵盖输出结果的形式、内容、风格等多个方面。在需要数据规整呈现的场景下,可让LangChain输出特定格式的结构化数据,如JSONXMLYAML等。比如在数据分析场景中,要求模型以JSON格式输出分析结果,便于后续的数据处理和系统集成;在报告生成场景中,可定制输出风格,使其更符合正式报告的要求。

那么本次分享就到这了。最后,博主还是那句话:请大家多去大胆的尝试和使用,成功总是在不断的失败中试验出来的,敢于尝试就已经成功了一半。如果大家对博主分享的内容感兴趣或有帮助,请点赞和关注。大家的点赞和关注是博主持续分享的动力🤭,博主也希望让更多的人学习到新的知识。


http://www.ppmy.cn/embedded/164899.html

相关文章

C++栈与队列:数据结构的“单行道”与“流水线

C栈与队列&#xff1a;数据结构的“单行道”与“流水线” 开篇小故事&#xff1a;火车站的两条轨道 想象一个火车站有两条特殊轨道&#xff1a; 轨道A&#xff08;栈&#xff09;&#xff1a;火车只能从同一端进出&#xff0c;最后进入的车厢必须先离开。轨道B&#xff08;队…

Win11更新系统c盘爆满处理

1.打开磁盘管理 2.右击c盘选择属性&#xff0c;进行磁盘管理&#xff0c;选择详细信息。 3.选择以前安装的文件删除即可释放c盘空间。

Java 集合:单列集合和双列集合的深度剖析

引言 在 Java 编程中&#xff0c;集合是一个非常重要的概念。它就像是一个容器&#xff0c;能够存储多个数据元素&#xff0c;帮助我们更方便地管理和操作数据。Java 集合框架主要分为单列集合和双列集合两大类&#xff0c;它们各自有着独特的特点和适用场景。接下来&#xff0…

全面汇总windows进程通信(二)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: 信号量(Semaphore)和互斥量(…

ip归属地和手机卡有关系吗?详细探析

在数字化浪潮席卷全球的今天&#xff0c;互联网已成为连接世界的桥梁。IP地址&#xff0c;作为网络世界中每个设备的“身份证”&#xff0c;承载着设备的位置信息和通信功能。而手机卡&#xff0c;则是我们移动设备接入互联网的钥匙&#xff0c;它让随时随地的在线交流成为可能…

【mysql】核心参数,SHOW VARIABLES

核心参数分类解析 SET GLOBAL slow_query_log = ON; 修改参数设置 一、核心参数分类解析 1. 连接和线程配置 max_connections (200):允许的最大并发连接数,超过会拒绝新连接。 wait_timeout (28800秒):非交互式连接的空闲超时时间(默认8小时)。 interactive_timeout (…

Redis数据结构总结-quickList

quickLis 前言什么是quickListquickList结构quickListfill参数 quickListNode数据压缩压缩解压缩 如何控制每个zipList的大小 前言 为什么会出现ziplist&#xff1f;有两个原因促进它的出现&#xff1a; 对于普通的双端列表(linked list)&#xff0c;它有指向前后的两个指针&a…

[特殊字符] Elasticsearch 双剑合璧:HTTP API 与 Java API 实战整合指南

&#x1f680; Elasticsearch 双剑合璧&#xff1a;HTTP API 与 Java API 实战整合指南 一、HTTP API 定义与用途 Elasticsearch 的 HTTP API 是基于 RESTful 接口设计的核心交互方式&#xff0c;支持通过 URL 和 JSON 数据直接操作索引、文档、集群等资源。适用于快速调试、…