(15-1)langchain模型I/O与数据增强:模型I/O基础

LangChain的模型I/O模块和数据增强功能为开发者提供了强大的工具,以便更有效地与语言模型交互,并扩展模型的能力以适应各种应用场景。在本章的内容中,将详细讲解LangChain中模型I/O模块和数据增强的知识,为读者步入后面知识的学习打下基础。

3.1  模型I/O基础

LangChain的模型I/O模块是其核心组成部分之一,它负责标准化和简化与各种语言模型的交互过程。模型I/O模块包括输入、模型和输出三个主要部分,使得开发者能够更加高效地构建和部署基于语言模型的应用程序。

3.1.1  模型I/O模块介绍

LangChain的模型I/O模块是一个强大的工具集,负责处理与语言模型相关的所有输入和输出任务,它使得与各种语言模型的交互变得简单而高效。模型I/O模块的主要组成和功能介绍如下所示。

1. 输入格式化(Input Formatting)

在与语言模型交互时,输入数据通常需要被格式化为模型能够理解的结构。模型I/O模块提供了多种工具来帮助开发者创建和格式化输入数据。提示模板(Prompt Templates)定义了如何将用户输入和附加的上下文信息组合成一个完整的提示,这个提示将被发送给语言模型。提示模板可以包含变量、示例和指令,以帮助模型更好地理解和回应请求。

2. 模型调用(Model Invocation)

模型I/O模块封装了与不同语言模型服务的交互,使得开发者可以通过统一的接口调用各种模型。

  1. LLMs(Large Language Models):是用于文本生成的模型,它们接受一个文本字符串作为输入,并返回一个文本字符串作为输出。
  2. Chat Models:这些模型专门为了处理对话而设计,它们接受一个聊天消息列表作为输入,并返回一个聊天消息作为输出。

3. 输出解析(Output Parsing)

当语言模型返回结果时,输出通常需要被解析和转换成更加结构化的形式,以便后续的处理和分析。输出解析器(Output Parsers)负责将模型的原始输出转换为结构化数据。例如,可以将文本输出解析为JSON对象、列表或其他有用的数据结构。

4. 数据增强(Data Augmentation)

数据增强是LangChain中的一个高级特性,它允许开发者利用模型以外的数据来增强应用程序的功能。

  1. 数据加载和转换:LangChain提供了工具来加载和转换各种数据源,如文档、数据库和互联网数据,以便它们可以被语言模型使用。
  2. 向量化和嵌入:通过将文本数据转换为向量表示,LangChain可以利用嵌入模型来增强语言模型的理解和生成能力。

5. 组合和链式操作(Composition and Chaining)

LangChain的模型I/O模块支持将不同的组件组合在一起,创建复杂的数据处理流程。通过LCEL(LangChain表达式语言(LCEL)),开发者可以使用管道符号(|)来连接提示模板、模型调用和输出解析器,创建一个数据处理的链。

总的来说,LangChain的模型I/O模块为开发者提供了一套完整的工具,以便更容易地与语言模型进行交互,处理输入和输出数据,并构建强大的基于语言模型的应用程序。

3.1.2  字符串提示模版:PromptTemplate

PromptTemplate 是 LangChain 中用于创建和格式化提示的一个关键组件,是一个预定义的模板,可以根据特定的任务和上下文动态生成用于语言模型的输入提示。通过使用PromptTemplate,开发者可以轻松地将用户输入和其他相关信息插入到提示中,从而生成适合特定语言模型的格式化文本。

PromptTemplate的主要特点如下所示。

  1. 动态格式化:PromptTemplate 允许开发者定义包含变量的模板字符串,并在运行时插入具体的值。这些变量可以是用户输入、上下文信息或其他动态数据。
  2. 灵活性:模板可以包含任意数量的变量,甚至可以没有变量。这为不同的使用场景提供了极大的灵活性。
  3. 易于使用:PromptTemplate 使用 Python 的 str.format 语法进行格式化,这是一种广泛熟悉的字符串格式化方法。
  4. 模型无关性:LangChain 努力创建与特定模型无关的模板,使得相同的模板可以在不同的语言模型之间重用。

例如下面是一个使用PromptTemplate来创建字符串提示模板的例子,假设想要构建一个提示,其目的是让语言模型生成一个关于特定主题的有趣故事。

实例3-1生成一个关于特定主题的有趣故事(源码路径:codes\3\PromptTemplate.py

在本实例中,使用PromptTemplate来动态插入用户指定的主题和一些额外的上下文信息。

from langchain.prompts import PromptTemplate

# 定义一个包含变量的模板字符串
template_string = "Once upon a time in a land far, far away, there was a magical {noun} named {name}. This {noun} had the unique ability to {ability}. One day, {name} decided to go on an adventure to {location}."

# 创建 PromptTemplate 实例
prompt_template = PromptTemplate.from_template(template_string)

# 准备要插入模板中的变量值
noun = "unicorn"
name = "Sparkle"
ability = "transform into a rainbow"
location = "the enchanted forest"

# 使用 format 方法将变量插入模板中
story_prompt = prompt_template.format(noun=noun, name=name, ability=ability, location=location)

# 输出格式化后的提示
print(story_prompt)

在上述代码中,首先定义了一个包含几个占位符(变量)的模板字符串。然后,使用PromptTemplate.from_template方法创建了一个PromptTemplate实例。最后,通过调用format方法并传递相应的变量值来生成一个完整的、格式化后的提示,现在可以使用这个提示请求语言模型生成一个故事。

执行后会输出:

Once upon a time in a land far, far away, there was a magical unicorn named Sparkle. This unicorn had the unique ability to transform into a rainbow. One day, Sparkle decided to go on an adventure to the enchanted forest.

3.1.3  聊天模版:ChatPromptTemplate

ChatPromptTemplate 是 LangChain 中专门用于构建聊天模型输入的模板。与 PromptTemplate 不同,ChatPromptTemplate 用于创建一系列聊天消息,这些消息通常代表不同的角色,如系统、用户或 AI 助手,并用于构建多轮对话的场景。

通常来说,每个聊天消息都包含内容信息和角色信息,这使得聊天模型能够理解对话的上下文和流程。ChatPromptTemplate 非常适合用于构建需要对话历史或特定对话结构的场景,例如下面是一个使用 ChatPromptTemplate 的例子,这个例子展示了创建一个包含系统、用户和 AI 助手消息的聊天模板,并且模拟了一个关于未来预测的对话场景。在这个场景中,系统角色提供了对话的上下文和引导,用户角色提出了问题,而 AI 助手角色则给出了预测和建议。

实例3-2:中文版的Q&A问答系统(源码路径:codes\3\ChatPromptTemplate.py

实例文件ChatPromptTemplate.py的具体实现代码如下所示。

from langchain.prompts import ChatPromptTemplate

# 创建一个ChatPromptTemplate实例,定义一个中文的聊天模版
chat_template = ChatPromptTemplate.from_messages([
    ("system", "欢迎使用未来预测AI助手。我将为您预测未来!"),
    ("human", "哇,听起来太棒了!你能告诉我关于我的爱情生活吗?"),
    ("ai", "当然!让我来看看水晶球……"),
    ("system", "我看到您在不久的将来会有一次浪漫的邂逅。您将在咖啡店里遇到一位特别的人!"),
    ("human", "太令人兴奋了!我的职业呢?"),
    ("ai", "让我再次凝视水晶球……"),
    ("system", "您的职业发展势头良好!预计很快会有晋升或新的工作机会到来。"),
    ("human", "太棒了!那我的健康呢?"),
    ("ai", "再次凝视水晶球……"),
    ("system", "您的健康状况看起来不错,但请记得优先考虑自我保健,定期运动。"),
    ("human", "非常感谢您的见解!"),
    ("ai", "不客气!如果您有更多问题,请随时问。")
])

# 使用format_messages方法生成聊天消息列表
formatted_messages = chat_template.format_messages()

# 打印填充后的聊天消息列表
for message in formatted_messages:
    print(message)

对上述代码的具体说明如下所示:

  1. 首先,从 langchain.prompts 模块中导入 ChatPromptTemplate 类。
  2. 使用 ChatPromptTemplate.from_messages 静态方法创建一个 ChatPromptTemplate 实例。这个方法接受一个消息列表,列表中的每个元素都是一个元组,包含角色名称(如 "system"、"human"、"ai")和对应的消息内容。
  3. 在创建的聊天模板中定义了一系列的对话消息,模拟了一个用户与 AI 助手之间的互动。
  4. 调用 format_messages 方法生成聊天消息列表,这个方法不需要额外的参数,它将根据模板中定义的消息生成一个 Message 对象列表。
  5. 最后,通过for循环打印输出每个消息对象的内容,执行后会输出:
content='欢迎使用未来预测AI助手。我将为您预测未来!'
content='哇,听起来太棒了!你能告诉我关于我的爱情生活吗?'
content='当然!让我来看看水晶球……'
content='我看到您在不久的将来会有一次浪漫的邂逅。您将在咖啡店里遇到一位特别的人!'
content='太令人兴奋了!我的职业呢?'
content='让我再次凝视水晶球……'
content='您的职业发展势头良好!预计很快会有晋升或新的工作机会到来。'
content='太棒了!那我的健康呢?'
content='再次凝视水晶球……'
content='您的健康状况看起来不错,但请记得优先考虑自我保健,定期运动。'
content='非常感谢您的见解!'
content='不客气!如果您有更多问题,请随时问。'

3.1.4  特殊模版类型:MessagesPlaceholder

MessagesPlaceholder是LangChain中一种特殊的模板类型,用于在聊天模板中插入一系列消息。可以在模板中灵活地指定消息的角色和内容,而无需提前确定这些消息的数量或角色。具体来说,MessagesPlaceholder可以用于以下两种情况:

  1. 不确定消息的数量或角色:当在设计聊天模板时,可能无法确定具体的消息数量或每条消息的角色。MessagesPlaceholder允许你在模板中定义占位符,稍后在实际生成消息时填充具体的消息内容和角色。
  2. 插入一系列消息:有时希望在聊天模板中插入一系列连续的消息,而不是单独定义每条消息。MessagesPlaceholder可以让你在模板中指定一组消息,并在生成消息时插入这些消息。

在使用MessagesPlaceholder时,需要在模板中指定一个变量名称,表示这个占位符。在生成消息时,可以通过填充这个变量来指定具体的消息内容和角色。例如下面是一个使用MessagesPlaceholder的例子,

实例3-3使用MessagesPlaceholder(源码路径:codes\3\MessagesPlaceholder.py

本实例展示了在LangChain中使用ChatPromptTemplate和MessagesPlaceholder来创建和管理聊天对话的过程,使得构建聊天机器人的交互变得更加灵活和方便。实例文件MessagesPlaceholder.py的具体实现代码如下所示。

from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

# 创建一个包含MessagesPlaceholder的聊天模板
chat_template = ChatPromptTemplate.from_messages([
    ("system", "欢迎使用我们的聊天机器人!让我们开始聊天吧。"),
    MessagesPlaceholder(variable_name="user_messages"),
    ("system", "感谢您和我聊天!")
])

# 填充消息内容和角色
user_messages = [
    ("human", "你好!"),
    ("ai", "您好!我可以为您提供什么帮助?"),
    ("human", "我有一个关于您产品的问题。"),
    ("ai", "当然,我在这里为您提供帮助。您想了解什么?")
]

# 使用format_messages方法生成聊天消息列表
formatted_messages = chat_template.format_messages(user_messages=user_messages)

# 打印填充后的聊天消息列表
for message in formatted_messages:
    print(message)

在上述代码中,使用ChatPromptTemplate和MessagesPlaceholder构建了一个包含用户和系统(AI助手)之间交互的聊天模板。具体实现流程如下所示。

  1. 首先,从langchain.prompts模块导入ChatPromptTemplate和MessagesPlaceholder。
  2. 使用ChatPromptTemplate.from_messages方法创建了一个聊天模板,其中包含两条系统消息和一个MessagesPlaceholder。MessagesPlaceholder用于在聊天模板中预留一个位置,稍后将用实际的用户消息填充。
  3. 定义了一个名为user_messages的列表,其中包含了用户(human)和AI助手(ai)之间的交互消息。在这个列表中,每个消息都是一个元组,包含消息的角色(human或ai)和消息内容。
  4. 调用chat_template.format_messages方法,并传入user_messages作为参数。这个方法将MessagesPlaceholder替换为user_messages中的实际消息,并生成一个完整的聊天消息列表。
  5. 最后,通过for循环打印输出每个消息的内容,执行后会输出:
content='欢迎使用我们的聊天机器人!让我们开始聊天吧。'
content='你好!'
content='您好!我可以为您提供什么帮助?'
content='我有一个关于您产品的问题。'
content='当然,我在这里为您提供帮助。您想了解什么?'
content='感谢您和我聊天!'

3.1.5  LCEL表达式语言

LCEL(LangChain Expression Language)是LangChain中的表达式语言,用于描述和操作LangChain中的各种对象。其中,PromptTemplate和ChatPromptTemplate实现了Runnable接口,是LCEL的基本构建块。

PromptTemplate接受一个字典(包含提示变量)作为输入,并返回一个StringPromptValue对象。而ChatPromptTemplate接受一个字典作为输入,并返回一个ChatPromptValue对象。

LCEL支持调用invoke、ainvoke、stream、astream、batch、abatch和astream_log等的一系列操作。通过这些操作,用户可以对PromptTemplate和ChatPromptTemplate进行调用、批处理、流处理等操作,实现灵活的控制和处理。请看下面的例子,演示了使用LCEL调用和处理PromptTemplate和ChatPromptTemplate的过程。

实例3-4使用LCEL调用和处理模版(源码路径:codes\3\Lcel.py

本实例的功能是使用LangChain的模板系统来构建和处理不同类型的提示,以及将它们转换为字符串或消息列表,以便在应用程序中使用。通过这种方式,开发者可以轻松地创建复杂的提示和聊天场景,以提高应用程序的交互性和用户体验。实例文件Lcel.py的具体实现代码如下所示。

from langchain.prompts import PromptTemplate, ChatPromptTemplate
from langchain_core.messages import SystemMessage
from langchain_core.prompts import HumanMessagePromptTemplate

# 创建一个PromptTemplate实例
prompt_template = PromptTemplate.from_template("Tell me a {adjective} joke about {content}.")

# 使用invoke方法调用PromptTemplate
prompt_val = prompt_template.invoke({"adjective": "funny", "content": "chickens"})

# 将结果转换为字符串
print(prompt_val.to_string())
# 输出: 'Tell me a funny joke about chickens.'

# 将结果转换为消息列表
print(prompt_val.to_messages())
# 输出: [HumanMessage(content='Tell me a funny joke about chickens.')]

# 创建一个ChatPromptTemplate实例
chat_template = ChatPromptTemplate.from_messages([
    SystemMessage(content="You are a helpful assistant that re-writes the user's text to sound more upbeat."),
    HumanMessagePromptTemplate.from_template("{text}"),
])

# 使用invoke方法调用ChatPromptTemplate
chat_val = chat_template.invoke({"text": "i dont like eating tasty things."})

# 将结果转换为消息列表
print(chat_val.to_messages())

# 将结果转换为字符串
print(chat_val.to_string())

上述代码的实现流程如下所示:

  1. 首先,从LangChain的相关模块中导入所需的类:PromptTemplate、ChatPromptTemplate、SystemMessage和HumanMessagePromptTemplate。
  2. 创建一个PromptTemplate实例,这个模板用于生成一个关于特定内容和形容词的笑话。在这个例子中,模板字符串包含两个变量:{adjective}和{content}。
  3. 使用invoke方法调用PromptTemplate实例,传入一个包含adjective和content变量值的字典。这个方法返回一个StringPromptValue对象。
  4. 将StringPromptValue对象转换为字符串,并打印输出。这将输出格式化后的提示:'Tell me a funny joke about chickens.'。
  5. 将StringPromptValue对象转换为消息列表,并打印输出。这将输出一个包含单个HumanMessage对象的列表,其中content属性为格式化后的提示。
  6. 创建一个ChatPromptTemplate实例,这个模板包含一个SystemMessage和一个HumanMessagePromptTemplate。SystemMessage是一个预定义的系统消息,而HumanMessagePromptTemplate是一个用于生成用户消息的模板。
  7. 使用invoke方法调用ChatPromptTemplate实例,传入一个包含text变量值的字典。这个方法返回一个ChatPromptValue对象。
  8. 将ChatPromptValue对象转换为消息列表,并打印输出。这将输出一个包含SystemMessage和根据HumanMessagePromptTemplate生成的HumanMessage对象的列表。
  9. 将ChatPromptValue对象转换为字符串,并打印输出。这将输出一个格式化后的聊天对话,其中包含系统消息和用户消息:
Tell me a funny joke about chickens.
[HumanMessage(content='Tell me a funny joke about chickens.')]
[SystemMessage(content="You are a helpful assistant that re-writes the user's text to sound more upbeat."), HumanMessage(content='i dont like eating tasty things.')]
System: You are a helpful assistant that re-writes the user's text to sound more upbeat.
Human: i dont like eating tasty things.

未完待续

  • 17
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值