LangChain是一个开源框架,旨在使用诸如GPT、LLaMA、Mistral等语言模型轻松构建应用程序。
LangChain最强大的功能之一是其对高级提示工程的支持。提示工程是指设计和优化提示,以从语言模型中获得最准确和相关的回复。
在这篇文章中,我们将介绍提示的基础知识,以及Langchain如何利用提示、提示模板、内存、代理和链条。对于这些核心概念,我们将在Python中提供几个代码示例,以便在本教程结束时,您能够轻松地使用LangChain框架构建自己的应用程序。
想知道如何使用LangChain和GPT来创建一个简单的AI代理吗?请查看我们的GPT和LangChain AI代码教程:
什么是Prompt工程?
作者提供的图片
我们有一份完整的指南,涵盖了提示工程,但作为一个快速复习,它是创建能够有效与生成式AI模型进行通信的文本输入的实践。这些以自然语言编写的提示指定了我们希望AI执行的任务。
它们的形式可以多种多样,从简单的问题,比如要求解释一个数学定理,到更具创意的请求,比如写一首关于特定主题的诗歌。
在即时工程中,关键不仅在于你问什么,还在于你如何问。这可能包括选择合适的措辞,设定特定的语气或风格,提供必要的背景信息,甚至定义AI的角色,比如要求它以某种语言的母语者的身份回答。
在某些情况下,提示还可以包含示例,以指导人工智能的学习过程。这种技术被称为少样本学习,对于复杂任务尤其有效。
当处理生成图像或音频的模型时,提示通常会详细描述所需的输出,从主题和风格到最终产品的构图和情绪。提示工程的艺术在于调整这些元素,以引导人工智能产生所期望的结果。
提示的基础知识
作者提供的图片
提示是提供给大型语言模型(LLM)的输入,以引发所需的响应。设计良好的提示对于从LLM获得有用的输出至关重要。提示工程的目标是精心构建提示,以获得准确、相关和有帮助的LLM响应。
一个好的提示通常包含以下四个组成部分:
- 指示 – 告诉模型要做什么,如何使用提供的信息,如何处理查询,并构建输出。
- 示例输入 – 提供示例输入,以向模型演示预期的内容。
- 示例输出 – 提供相应的示例输出。
- 查询 – 您希望模型处理的实际输入。
除了查询之外,其他内容都是可选的,但可能会显著影响响应的质量,特别是提供给LLM的指示,用于指导任务和预期响应。
示例演示了给定示例输入的期望输出格式。
查询是向LLM提出的问题或请求。
构建有效的提示涉及根据所解决的问题创造性地结合这些元素。
LangChain提示
LangChain提供了各种类和函数来帮助构建和处理提示,使得管理涉及语言模型的复杂任务更加容易。
Langchain通过`PromptTemplate`对象为即时工程提供一流的支持。
提示模板作为构建语言模型查询的结构化指南。
这些模板通常包括指令、一些示例输入(少样本示例)以及适用于特定任务的定制问题和背景。
LangChain的目标是设计与各种语言模型兼容的模板,提高在不同模型之间传输模板的便捷性。
简而言之,您可以使用PromptTemplate
类来创建一个字符串提示的模板。
from langchain.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template(
"告诉我一个关于{content}的{adjective}笑话。"
)
prompt_template.format(adjective="悲伤的", content="数据科学家")
输出:
‘
>>> “告诉我一个关于数据科学家的悲伤笑话。”
‘
不需要有一个变量。即使没有任何变量,您也可以使用这个类创建一个提示。
from langchain.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("告诉我一个笑话")
prompt_template.format()
输出:
>>> ‘告诉我一个笑话’
如果你正在构建一个聊天应用程序,在每次用户发送新消息时都需要保存并发送消息历史记录给LLM,那该怎么办?手动完成这个过程非常耗时。
对于支持的聊天模型,您可以使用ChatPromptTemplate
代替:
from langchain.prompts import ChatPromptTemplate
chat_template = ChatPromptTemplate.from_messages(
[
("system", "你是一个有用的AI机器人。你的名字是{name}。"),
("human", "你好,你好吗?"),
("ai", "我很好,谢谢!"),
("human", "{user_input}"),
]
)
messages = chat_template.format_messages(name="Bob", user_input="你叫什么名字?")
print(messages)
输出:
>>> [SystemMessage(content=’你是一个有帮助的AI机器人。你的名字是Bob。’),
‘
>>> HumanMessage(content=’你好,你好吗?’),
>>> AIMessage(content=”我过得很好,谢谢!”),
‘
>>> HumanMessage(content=’你叫什么名字?’)]
‘
所以你一定在想,为什么我们需要PromptTemplates
?为什么我们不能直接将字符串提示传递给LLM?以下是使用LangChain的PromptTemplate
的一些好理由:
- 提示模板是可重复使用的,允许您创建一次提示并在多种情况下使用,例如在不重写提示的情况下总结不同的文章。
- 它们将提示的格式与实际模型调用分离,使代码更模块化,并允许对模板或模型进行独立更新。
- 使用模板可以提高代码的可读性,因为它们将复杂逻辑封装在更简单、更清晰、有命名的变量格式中。
- 使用提示模板可以更轻松地进行维护,因为只需在一个中心位置进行提示逻辑的更改,而不是在每个单独的提示中进行更改。
LangChain记忆
在涉及聊天的语言模型应用中,系统记住过去的对话非常重要。
就像在普通聊天中一样,系统应该能够回顾之前说过的内容。
简单来说,这意味着系统可以看到一些先前的消息。但更先进的系统将记住更多细节,比如不同主题的事实以及它们之间的联系。
这种记住过去聊天记录的能力被称为“记忆”。LangChain帮助为这些聊天系统添加记忆功能。
LangChain中的一个内存有两个主要功能:
- 在将查询发送给LLM之前,系统会从内存中读取数据,以增强用户输入的初始提示。
- 一旦LLM返回响应,系统会将其写入内存以供将来的交互使用,然后将最终输出返回给用户。
LangChain中的内存(图片来源)
要在LangChain中使用Memory
功能,您可以使用ConversationBufferMemory
类。
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(return_messages=True)
memory.chat_memory.add_user_message("hi!")
memory.chat_memory.add_ai_message("what's up?")
memory.chat_memory.add_user_message("how are you doing?")
memory.chat_memory.add_ai_message("I am fine, thank you and you?")
# 检查变量历史记录
memory.load_memory_variables({})
输出:
>>> {‘history’: [HumanMessage(content=’hi!’),
‘
>>> AIMessage(content=”怎么了?”),
>>> HumanMessage(content=’你好吗?’),
>>> AIMessage(content=’我很好,谢谢你,你呢?’)]}
它返回一个字典,默认情况下键是history
。这个键指向一个消息列表,这些消息可以是来自人类的(HumanMessage
),也可以是来自LLM的(AIMessage
)。
LangChain 链
对于简单的任务,使用单个 LLM(大型语言模型)效果很好。然而,对于更复杂的任务,通常需要链式多个步骤和/或模型。
在LangChain中,使用Chains
的传统方式是通过Chain
接口。
较新且推荐的方法是LangChain表达式语言(LCEL)。虽然LCEL更适用于新项目,但Chain方法仍然有用且受支持。
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
model = ChatOpenAI(openai_api_key = “...”)
prompt = ChatPromptTemplate.from_messages(
[
(
"system",
"您是一位专业的数据科学家和机器学习工程师,能够提供专业的知识并准确地回答问题。",
),
("human", "{question}"),
]
)
runnable = prompt | model | StrOutputParser()
for chunk in runnable.stream({"question": "机器学习和深度学习有什么不同之处?"}):
print(chunk, end="", flush=True)
输出:
>>> 机器学习和深度学习是人工智能(AI)的子领域,涉及训练模型根据数据进行预测或决策。虽然两者之间存在重叠,但它们……
创建runnable
的方式对于Python来说并不是很标准,但是这个|
是一个管道操作符。Prompt | model | StrOutputParser()
的意思是Prompt
通过model
传递,然后将其输出传递给StrOutputParser()
。链中的每个部分都以某种方式转换数据。
想要了解更多关于使用LangChain构建的有趣用例和应用程序吗?请查看我们的工程和数据应用用例博客。
LangChain代理
代理的基本概念是利用语言模型来选择一系列的动作。
与链式不同,其中一系列动作是预先确定并嵌入在代码中,代理使用语言模型作为决策工具来识别适当的动作及其顺序。
在LangChain的Agents
中有三个关键概念:
- 工具:LLM可用工具的描述
- 用户输入:任务的高级目标
- 中间步骤:为了实现用户输入而先前执行的任何(动作,工具输出)对
工具代表代理可以激活的功能。工具设计的两个关键方面包括:
- 确保代理人能够使用适当的工具。
- 以最大化对代理人有用的方式定义这些工具。
对于各种常规活动,代理人需要一系列相互关联的工具。为了解决这个问题,LangChain引入了工具包的概念。LangChain提供了广泛的工具包供您开始使用。
要了解更多关于Agents的信息,请查看这个官方LangChain指南。
来源:本博客中的一些示例是使用官方的LangChain文档生成的。
结论
通过提供一种结构化的设计提示方法,LangChain不仅简化了与不同语言模型交互的过程,还最大限度地提高了其输出的效率和相关性。LangChain中的PromptTemplate
和Memory
等功能展示了在提示工程中灵活性和精确性的深思熟虑的整合,适用于从简单查询到复杂对话环境的各种任务。
LangChain的Chains
和Agents
中的高级功能进一步提升了使用LangChain构建应用程序的潜力,只需几行代码即可选择任何底层的LLM进行开发,而可供选择的选项有很多。
无论是简单的任务还是复杂的应用,LangChain对于提示工程的方法都非常简单、清晰且易于采用。
想要了解更多吗?请查看DataCamp上如何使用LangChain构建LLM应用程序的第一部分。
‘