使用 LCEL 构建简单的 LLM 应用程序
在本快速入门中,我们将向您展示如何使用 LangChain 构建一个简单的 LLM 应用程序。此应用程序将文本从英语翻译成另一种语言。这是一个相对简单的 LLM 应用程序 - 它只是一个单一的 LLM 调用加上一些提示。尽管如此,这仍然是开始使用 LangChain 的一个好方法 - 许多功能只需一些提示和 LLM 调用即可构建!
阅读本教程后,您将对以下内容有一个高级概述
让我们开始吧!
设置
Jupyter Notebook
本指南(以及文档中的大多数其他指南)使用Jupyter 笔记本,并假设读者也使用它。Jupyter 笔记本非常适合学习如何使用 LLM 系统,因为很多时候事情可能会出错(意外输出、API 故障等),并且在交互式环境中逐步完成指南是更好地理解它们的好方法。
本教程和其他教程可能最方便地在 Jupyter 笔记本中运行。请参阅此处了解安装说明。
安装
要安装 LangChain,请运行
- Pip
- Conda
pip install langchain
conda install langchain -c conda-forge
有关更多详细信息,请参阅我们的安装指南。
LangSmith
您使用 LangChain 构建的许多应用程序都将包含多个步骤,以及对 LLM 调用的多次调用。随着这些应用程序变得越来越复杂,能够检查链或代理内部到底发生了什么变得至关重要。最好的方法是使用LangSmith。
在上面链接中注册后,请确保设置环境变量以开始记录跟踪
export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="..."
或者,如果在笔记本中,您可以使用以下命令设置它们:
import getpass
import os
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()
使用语言模型
首先,让我们学习如何单独使用语言模型。LangChain 支持许多不同的语言模型,您可以互换使用 - 在下面选择您要使用的模型!
- OpenAI
- Anthropic
- Azure
- Cohere
- NVIDIA
- FireworksAI
- Groq
- MistralAI
- TogetherAI
pip install -qU langchain-openai
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4")
pip install -qU langchain-anthropic
import getpass
import os
os.environ["ANTHROPIC_API_KEY"] = getpass.getpass()
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-3-5-sonnet-20240620")
pip install -qU langchain-openai
import getpass
import os
os.environ["AZURE_OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import AzureChatOpenAI
model = AzureChatOpenAI(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
azure_deployment=os.environ["AZURE_OPENAI_DEPLOYMENT_NAME"],
openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
)
pip install -qU langchain-google-vertexai
import getpass
import os
os.environ["GOOGLE_API_KEY"] = getpass.getpass()
from langchain_google_vertexai import ChatVertexAI
model = ChatVertexAI(model="gemini-1.5-flash")
pip install -qU langchain-cohere
import getpass
import os
os.environ["COHERE_API_KEY"] = getpass.getpass()
from langchain_cohere import ChatCohere
model = ChatCohere(model="command-r-plus")
pip install -qU langchain-nvidia-ai-endpoints
import getpass
import os
os.environ["NVIDIA_API_KEY"] = getpass.getpass()
from langchain import ChatNVIDIA
model = ChatNVIDIA(model="meta/llama3-70b-instruct")
pip install -qU langchain-fireworks
import getpass
import os
os.environ["FIREWORKS_API_KEY"] = getpass.getpass()
from langchain_fireworks import ChatFireworks
model = ChatFireworks(model="accounts/fireworks/models/llama-v3p1-70b-instruct")
pip install -qU langchain-groq
import getpass
import os
os.environ["GROQ_API_KEY"] = getpass.getpass()
from langchain_groq import ChatGroq
model = ChatGroq(model="llama3-8b-8192")
pip install -qU langchain-mistralai
import getpass
import os
os.environ["MISTRAL_API_KEY"] = getpass.getpass()
from langchain_mistralai import ChatMistralAI
model = ChatMistralAI(model="mistral-large-latest")
pip install -qU langchain-openai
import getpass
import os
os.environ["TOGETHER_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
base_url="https://api.together.xyz/v1",
api_key=os.environ["TOGETHER_API_KEY"],
model="mistralai/Mixtral-8x7B-Instruct-v0.1",
)
让我们首先直接使用模型。ChatModel
是 LangChain “可运行对象” 的实例,这意味着它们公开了用于与其交互的标准接口。要简单地调用模型,我们可以将消息列表传递给 .invoke
方法。
from langchain_core.messages import HumanMessage, SystemMessage
messages = [
SystemMessage(content="Translate the following from English into Italian"),
HumanMessage(content="hi!"),
]
model.invoke(messages)
AIMessage(content='ciao!', response_metadata={'token_usage': {'completion_tokens': 3, 'prompt_tokens': 20, 'total_tokens': 23}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-fc5d7c88-9615-48ab-a3c7-425232b562c5-0')
如果我们启用了 LangSmith,我们可以看到此运行已记录到 LangSmith,并且可以看到 LangSmith 追踪
输出解析器
请注意,模型的响应是 AIMessage
。它包含一个字符串响应以及有关响应的其他元数据。通常我们可能只想处理字符串响应。我们可以使用简单的输出解析器解析出此响应。
我们首先导入简单的输出解析器。
from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
一种使用方法是单独使用它。例如,我们可以保存语言模型调用的结果,然后将其传递给解析器。
result = model.invoke(messages)
parser.invoke(result)
'Ciao!'
更常见的是,我们可以将模型与这个输出解析器“链接”。这意味着此输出解析器将在每次链中调用。此链采用语言模型的输入类型(字符串或消息列表)并返回输出解析器的输出类型(字符串)。
我们可以使用 |
运算符轻松创建链。|
运算符用于在 LangChain 中组合两个元素。
chain = model | parser
chain.invoke(messages)
'Ciao!'
如果我们现在查看 LangSmith,我们可以看到链有两个步骤:首先调用语言模型,然后将其结果传递给输出解析器。我们可以看到 LangSmith 追踪
提示模板
现在我们正在将消息列表直接传递给语言模型。此消息列表来自哪里?通常,它是由用户输入和应用程序逻辑组合构建的。此应用程序逻辑通常获取原始用户输入并将其转换为准备传递给语言模型的消息列表。常见的转换包括添加系统消息或使用用户输入格式化模板。
PromptTemplates 是 LangChain 中的一个概念,旨在帮助进行此转换。它们接收原始用户输入并返回准备传递到语言模型的数据(提示)。
让我们在这里创建一个 PromptTemplate。它将接收两个用户变量
language
:将文本翻译成的语言text
:要翻译的文本
from langchain_core.prompts import ChatPromptTemplate
首先,让我们创建一个字符串,我们将对其进行格式化以作为系统消息。
system_template = "Translate the following into {language}:"
接下来,我们可以创建 PromptTemplate。这将是 system_template
以及用于放置要翻译的文本的更简单模板的组合。
prompt_template = ChatPromptTemplate.from_messages(
[("system", system_template), ("user", "{text}")]
)
此提示模板的输入是一个字典。我们可以单独试用此提示模板以查看它本身的功能。
result = prompt_template.invoke({"language": "italian", "text": "hi"})
result
ChatPromptValue(messages=[SystemMessage(content='Translate the following into italian:'), HumanMessage(content='hi')])
我们可以看到它返回了一个 ChatPromptValue
,它包含两条消息。如果我们想直接访问这些消息,我们可以这样做
result.to_messages()
[SystemMessage(content='Translate the following into italian:'),
HumanMessage(content='hi')]
使用 LCEL 将组件链接在一起
现在我们可以使用管道 (|
) 运算符将其与上面的模型和输出解析器结合起来。
chain = prompt_template | model | parser
chain.invoke({"language": "italian", "text": "hi"})
'ciao'
这是一个使用 LangChain 表达式语言 (LCEL) 将 LangChain 模块链接在一起的简单示例。这种方法有几个好处,包括优化的流式传输和跟踪支持。
如果我们查看 LangSmith 追踪,我们可以看到所有三个组件都显示在 LangSmith 追踪 中。
使用 LangServe 提供服务
现在我们已经构建了一个应用程序,我们需要提供服务。这就是 LangServe 发挥作用的地方。LangServe 帮助开发人员将 LangChain 链部署为 REST API。您无需使用 LangServe 即可使用 LangChain,但本指南将介绍如何使用 LangServe 部署您的应用程序。
虽然本指南的第一部分旨在在 Jupyter Notebook 或脚本中运行,但我们现在将从中退出。我们将创建一个 Python 文件,然后从命令行与它交互。
使用以下命令安装
pip install "langserve[all]"
服务器
要为我们的应用程序创建服务器,我们将创建一个 serve.py
文件。这将包含我们为提供应用程序服务的逻辑。它包含三件事
- 我们上面构建的链的定义
- 我们的 FastAPI 应用程序
- 提供链的路由的定义,这是使用
langserve.add_routes
完成的。
#!/usr/bin/env python
from fastapi import FastAPI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI
from langserve import add_routes
# 1. Create prompt template
system_template = "Translate the following into {language}:"
prompt_template = ChatPromptTemplate.from_messages([
('system', system_template),
('user', '{text}')
])
# 2. Create model
model = ChatOpenAI()
# 3. Create parser
parser = StrOutputParser()
# 4. Create chain
chain = prompt_template | model | parser
# 4. App definition
app = FastAPI(
title="LangChain Server",
version="1.0",
description="A simple API server using LangChain's Runnable interfaces",
)
# 5. Adding chain route
add_routes(
app,
chain,
path="/chain",
)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="localhost", port=8000)
就是这样!如果我们执行此文件
python serve.py
我们应该看到我们的链在 https://127.0.0.1:8000 上提供服务。
游乐场
每个 LangServe 服务都带有用于配置和调用应用程序的简单 内置 UI,并提供流式输出和对中间步骤的可见性。前往 https://127.0.0.1:8000/chain/playground/ 试用!传入与之前相同的输入 - {"language": "italian", "text": "hi"}
- 它应该像以前一样做出响应。
客户端
现在让我们为以编程方式与我们的服务交互设置一个客户端。我们可以使用 langserve.RemoteRunnable 轻松做到这一点。使用它,我们可以像在客户端运行一样与提供的链进行交互。
from langserve import RemoteRunnable
remote_chain = RemoteRunnable("https://127.0.0.1:8000/chain/")
remote_chain.invoke({"language": "italian", "text": "hi"})
要了解有关 LangServe 的许多其他功能的更多信息,请点击此处。
结论
就是这样!在本教程中,您学习了如何创建第一个简单的 LLM 应用程序。您学习了如何使用语言模型、如何解析其输出、如何创建提示模板、如何使用 LCEL 将它们链接起来、如何使用 LangSmith 获得对创建的链的出色可观察性以及如何使用 LangServe 部署它们。
这仅仅触及了您想要学习成为熟练的 AI 工程师所需知识的表面。幸运的是 - 我们还有很多其他资源!
有关 LangChain 核心概念的进一步阅读,我们提供了详细的 概念指南。
如果您对这些概念有更多具体问题,请查看操作指南的以下部分
以及 LangSmith 文档