快速入门指南
本教程让您快速了解如何使用 LangChain 构建端到端语言模型应用程序。
安装说明
首先,使用以下命令安装 LangChain:
pip install langchain
# or
conda install langchain -c conda-forge
环境设置
使用LangChain通常需要与一个或多个模型提供程序、数据存储、API等进行集成。
在本例中,我们将使用OpenAI的API,因此我们首先需要安装他们的SDK:
pip install openai
然后我们需要在终端中设置环境变量。
export OPENAI_API_KEY="..."
另外,你也可以在 Jupyter 笔记本 (或 Python 脚本) 内部执行这个操作:
import os
os.environ["OPENAI_API_KEY"] = "..."
如果想动态设置API密钥,您可以在初始化OpenAI类时使用openai_api_key参数,例如每个用户的API密钥。
from langchain.llms import OpenAI
llm = OpenAI(openai_api_key="OPENAI_API_KEY")
Building a Language Model Application: LLMs(构建语言模型应用程序:LLMs)
现在,我们已经安装了LangChain并设置了环境,我们可以开始构建我们的语言模型应用程序。
LangChain提供了许多模块,可以用于构建语言模型应用程序。模块可以组合以创建更复杂的应用程序,也可以单独用于简单的应用程序。
LLMs: Get predictions from a language model(LLMs:从语言模型获取预测)
LangChain的最基本构建单元是在某些输入上调用LLM。让我们通过一个简单的示例来了解如何操作。为此,让我们假装正在构建一个基于公司所生产的产品生成公司名称的服务。
为了实现这一点,我们首先需要导入LLM包装器。
from langchain.llms import OpenAI
然后,我们可以用任何参数来初始化包装器。在这个例子中,我们可能希望输出更加随机,因此我们将使用高温度来初始化它。
llm = OpenAI(temperature=0.9)
我们现在可以对一些输入进行调用了!
text = "一个制造彩色袜子的公司的好名字会是什么?"
print(llm(text))
满足的足部乐趣
有关如何在LangChain中使用LLMs的详细信息,请参阅LLM入门指南.
Prompt Templates: Manage prompts for LLMs(提示模版:管理LLM的提示信息)。
调用LLM是个好的第一步,但这只是开始。通常当你在一个应用程序中使用LLM时,你并不会直接把用户输入发送到LLM。相反,你可能会把用户输入构造成提示信息,然后把它发送给LLM。
例如,在之前的例子中,我们传递的文本是硬编码的,要求输入一个制造彩色袜子的公司的名称。在这个想象中的服务中,我们想要做的是只获取用户描述公司所做的事情的输入,然后用那些信息来格式化提示信息。
这在LangChain中很容易实现!首先,让我们定义提示信息模板:
from langchain.prompts import PromptTemplate
prompt = PromptTemplate(
input_variables=["product"],
template="一个制造{product}的公司的好名字是什么?",
)
现在让我们看看这是如何工作的!我们可以调用.format方法进行格式化。
print(prompt.format(product="彩色袜子"))
一个制造{product}的公司的好名字是什么?
Chains: Combine LLMs and prompts in multi-step workflows(链: 逐步工作流程中的 LLM 和提示组合)
目前为止,我们只是单独使用PromptTemplate和LLM基本单元。但是,真正的应用程序不仅仅是一个基本单元,而是它们的组合。
LangChain中的Chain链由链接组成,可以是像LLM或其他链这样的基本单元。
Chains中最核心的类型是LLMChain,它由PromptTemplate和LLM组成。
扩展之前的示例,我们可以构建一个LLMChain,该链接受用户输入,使用PromptTemplate对它进行格式化,然后将格式化的响应传递给LLM。
from langchain.prompts import PromptTemplate
from langchain.llms import OpenAI
llm = OpenAI(temperature=0.9)
prompt = PromptTemplate(
input_variables=["product"],
template="一个制造{product}的公司的好名字是什么??",
)
我们现在可以创建一个非常简单的链,用于接收用户输入,格式化提示并将其发送到LLM:
from langchain.chains import LLMChain
chain = LLMChain(llm=llm, prompt=prompt)
现在我们可以仅指定产品来运行该链!
chain.run("彩色袜子")
# -> '\n\nSocktastic!'
我们来看看!这是第一个Chain——LLM Chain。这是比较简单的Chain链之一,但了解它的工作原理将为您处理更复杂的链做好准备。
Agents: Dynamically Call Chains Based on User Input(Agents代理: 根据用户输入动态调用链)
到目前为止,我们所看到的链都是按照预先确定的顺序运行的。
而代理人不再是如此:它们使用LLM来确定采取哪些操作以及以什么顺序执行这些操作。一个操作可以是使用工具并观察它的输出,或者回到用户
如果使用正确,代理人可以非常强大。在本教程中,我们将向您展示如何通过最简单、最高级别的API轻松使用代理人。
为了加载代理人,您应该了解以下概念:
- Tool: 执行特定职责的函数。这可以是像Google搜索、数据库查询、Python REPL、其他链等等。工具的接口目前是一个期望具有字符串输入和字符串输出的函数.
- LLM: 支持代理人的语言模型.
- Agent: 要使用的代理人。这应该是引用支持代理人类的字符串。因为本笔记本专注于最简单、最高级别的API,所以仅介绍使用标准支持代理人的内容。如果要实现自定义代理,请参阅自定义代理人文档(即将上线)
Agents: 有关支持的代理人及其规格的列表,请参见此处.
Tools: 有关预定义工具及其规格的列表,请参见此处.
对于本示例,您还需要安装SerpAPI Python包。
pip install google-search-results
设置适当的环境变量.
import os
os.environ["SERPAPI_API_KEY"] = "..."
现在我们可以开始了!
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.llms import OpenAI
# 首先,让我们加载我们要用来控制代理的语言模型.
llm = OpenAI(temperature=0)
# 接下来,让我们加载一些需要使用的工具。注意到 `llm-math` 工具使用了一个 LLM,因此我们需要传递一个。.
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 最后,让我们使用工具、语言模型和我们想要使用的代理类型来初始化代理。.
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 现在让我们来测试一下。!
agent.run("旧金山昨天的华氏高温是多少?这个数字的0.023次方是多少?")
> 进入新的AgentExecutor链...
我需要先找到温度,然后使用计算器将其提高到 0.023 次方。
Action: Search
Action Input: "昨天旧金山高温"
Observation: 昨日旧金山气温。昨日最高气温:57华氏度(于下午1:56)昨日最低气温:49华氏度(于凌晨1:56)平均气温:...
Thought: 我现在有了温度,所以我可以使用计算器将其提高到 0.023 次方.
Action: Calculator
Action Input: 57^.023
Observation: Answer: 1.0974509573251117
Thought: 我现在知道最终答案了。
Final Answer: 昨天旧金山的华氏高温, 算出来的 0.023 次方结果为 1.0974509573251117。
> 结束 chain.
Memory: Add State to Chains and Agents(内存:将状态添加到链和代理)
到目前为止,我们经历的所有链和代理都是无状态的。但通常情况下,您可能希望链或代理具有某种“记忆”概念,以便它可以记住有关其先前交互的信息。其中最清晰和简单的示例是设计聊天机器人——您希望它记住先前的消息,以便它可以利用上下文来进行更好的对话。这将是一种“短期记忆”。在更复杂的一面,您可以想象一条链/代理随着时间的推移记住关键信息——这将是一种“长期记忆”的形式。有关后者的更具体的想法,请参见这篇精彩的论文.
LangChain提供几个专门为此而创建的链。本笔记本演示了如何使用其中一个链(ConversationChain
)和两种不同类型的记忆。默认情况下,ConversationChain
具有一种简单的记忆类型,可以记住所有先前的输入/输出,并将它们添加到传递的上下文中。让我们看看如何使用此链(设置verbose=True
,以便我们可以看到提示)。
from langchain import OpenAI, ConversationChain
llm = OpenAI(temperature=0)
conversation = ConversationChain(llm=llm, verbose=True)
output = conversation.predict(input="你好呀!")
print(output)
> Entering new chain...
Prompt after formatting:
下面是一段人类和人工智能之间友好的对话。人工智能健谈并从其语境中提供很多具体细节。如果人工智能不知道问题的答案,它会诚实地说出自己不知道.
Current conversation:
Human: 你好呀!
AI:
> Finished chain.
' 你好,今天怎么样?'
output = conversation.predict(input="我很好!只是在和一个人工智能聊天")
print(output)
> Entering new chain...
Prompt after formatting:
下面是一段人类和人工智能之间友好的对话。人工智能健谈并从其语境中提供很多具体细节。如果人工智能不知道问题的答案,它会诚实地说出自己不知道.
Current conversation:
Human: 你好呀!
AI: 你好,今天怎么样?
Human: 我很好!只是在和一个人工智能聊天.
AI:
> Finished chain.
" 太好了!你想聊点什么?"
Building a Language Model Application: Chat Models(构建语言模型应用程序:聊天模型)
同样地,你可以使用聊天模型而不是LLMs。聊天模型是语言模型的一种变化形式。虽然聊天模型在底层使用的是语言模型,但它们提供的接口略有不同:它们不是暴露一个“文本输入,文本输出”的API,而是暴露一个接口,其中“聊天消息”是输入和输出。
聊天模型的API还比较新,所以我们仍在探索正确的抽象。
Get Message Completions from a Chat Model(从聊天模型中获取消息完成)。
通过向聊天模型传递一个或多个消息,您可以获得聊天完成。响应将是一条消息。LangChain目前支持的消息类型包括AIMessage
、HumanMessage
、SystemMessage
和ChatMessage
——ChatMessage
接受一个任意角色参数。大多数情况下,您只需要处理HumanMessage
、AIMessage
和SystemMessage
。
from langchain.chat_models import ChatOpenAI
from langchain.schema import (
AIMessage,
HumanMessage,
SystemMessage
)
chat = ChatOpenAI(temperature=0)
您可以通过传递单个消息来获得完成。
chat([HumanMessage(content="将这句话从英文翻译成法文. I love programming.")])
# -> AIMessage(content="J'aime programmer.", additional_kwargs={})
您还可以为 OpenAI 的 gpt-3.5-turbo 和 gpt-4 模型传递多条消息。
messages = [
SystemMessage(content="你是一个有帮助的助手,可以将英语翻译成法语。"),
HumanMessage(content="I love programming.")
]
chat(messages)
# -> AIMessage(content="J'aime programmer.", additional_kwargs={})
您可以采用更深入的方式,使用generate
为多个消息集生成补全。这将返回一个LLMResult对象和一个额外的消息参数:
batch_messages = [
[
SystemMessage(content="你是一个有帮助的助手,可以将英语翻译成法语。"),
HumanMessage(content="I love programming.")
],
[
SystemMessage(content="你是一个有用的助手,可以将英语翻译成法语。"),
HumanMessage(content="I love artificial intelligence.")
],
]
result = chat.generate(batch_messages)
result
# -> LLMResult(generations=[[ChatGeneration(text="J'aime programmer.", generation_info=None, message=AIMessage(content="J'aime programmer.", additional_kwargs={}))], [ChatGeneration(text="J'aime l'intelligence artificielle.", generation_info=None, message=AIMessage(content="J'aime l'intelligence artificielle.", additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 57, 'completion_tokens': 20, 'total_tokens': 77}})
您可以从这个LLMResult中恢复诸如tokens使用情况的东西:
result.llm_output['token_usage']
# -> {'prompt_tokens': 57, 'completion_tokens': 20, 'total_tokens': 77}
Chat Prompt Templates(聊天提示模板)
与LLMs类似,您可以使用MessagePromptTemplate
来使用模板。您可以从一个或多个MessagePromptTemplate
构建ChatPromptTemplate
。您可以使用ChatPromptTemplate
的format_prompt
——这将返回PromptValue
,您可以根据需要将其转换为字符串或Message
对象,具体取决于您想要将格式化值作为LLM或聊天模型输入使用。为了方便起见,模板上公开了from_template
方法。如果您使用此模板,它将看起来像:
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
chat = ChatOpenAI(temperature=0)
template = "你是一个有用的助手,可以将{input_language}翻译成{output_language}."
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
# get a chat completion from the formatted messages
chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
# -> AIMessage(content="J'aime programmer.", additional_kwargs={})
Chains with Chat Models(带有聊天模型的链)
上面的部分中讨论的LLMChain
也可以用于聊天模型
from langchain.chat_models import ChatOpenAI
from langchain import LLMChain
from langchain.prompts.chat import (
ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
chat = ChatOpenAI(temperature=0)
template = "您是一个有用的助手,可以将{input_language} 翻译成{output_language}。"
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
human_template = "{text}"
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
chain = LLMChain(llm=chat, prompt=chat_prompt)
chain.run(input_language="English", output_language="French", text="I love programming.")
# -> "J'aime programmer."
Agents with Chat Models(具有聊天模型的代理人)
代理还可以与聊天模型一起使用,您可以使用AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION
作为代理类型来初始化一个代理。
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from langchain.agents import AgentType
from langchain.chat_models import ChatOpenAI
from langchain.llms import OpenAI
# 首先,让我们加载我们要用来控制代理的语言模型。
chat = ChatOpenAI(temperature=0)
# 接下来,让我们加载一些要使用的工具。请注意,“llm-math”工具使用LLM,所以我们需要传递它。
llm = OpenAI(temperature=0)
tools = load_tools(["serpapi", "llm-math"], llm=llm)
# 最后,让我们使用工具、语言模型和我们要使用的代理类型来初始化代理。
agent = initialize_agent(tools, chat, agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
# 现在让我们测试一下!
agent.run("Who is Olivia Wilde's boyfriend? What is his current age raised to the 0.23 power?")
> Entering new AgentExecutor chain...
Thought: I need to use a search engine to find Olivia Wilde's boyfriend and a calculator to raise his age to the 0.23 power.
Action:
{
"action": "Search",
"action_input": "Olivia Wilde boyfriend"
}
Observation: Sudeikis and Wilde's relationship ended in November 2020. Wilde was publicly served with court documents regarding child custody while she was presenting Don't Worry Darling at CinemaCon 2022. In January 2021, Wilde began dating singer Harry Styles after meeting during the filming of Don't Worry Darling.
Thought:I need to use a search engine to find Harry Styles' current age.
Action:
{
"action": "Search",
"action_input": "Harry Styles age"
}
Observation: 29 years
Thought:Now I need to calculate 29 raised to the 0.23 power.
Action:
{
"action": "Calculator",
"action_input": "29^0.23"
}
Observation: Answer: 2.169459462491557
Thought:I now know the final answer.
Final Answer: 2.169459462491557
> Finished chain.
'2.169459462491557'
Memory: Add State to Chains and Agents(内存:向链和代理添加状态)
您可以使用带有聊天模型的链和代理来使用内存。与LLMs的内存不同的主要区别在于,它不是尝试将所有先前消息压缩成一个字符串,而是将它们作为自己独特的内存对象保留。
from langchain.prompts import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate
)
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
prompt = ChatPromptTemplate.from_messages([
SystemMessagePromptTemplate.from_template("The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know."),
MessagesPlaceholder(variable_name="history"),
HumanMessagePromptTemplate.from_template("{input}")
])
llm = ChatOpenAI(temperature=0)
memory = ConversationBufferMemory(return_messages=True)
conversation = ConversationChain(memory=memory, prompt=prompt, llm=llm)
conversation.predict(input="Hi there!")
# -> 'Hello! How can I assist you today?'
conversation.predict(input="I'm doing well! Just having a conversation with an AI.")
# -> "That sounds like fun! I'm happy to chat with you. Is there anything specific you'd like to talk about?"
conversation.predict(input="Tell me about yourself.")
# -> "Sure! I am an AI language model created by OpenAI. I was trained on a large dataset of text from the internet, which allows me to understand and generate human-like language. I can answer questions, provide information, and even have conversations like this one. Is there anything else you'd like to know about me?"