使用LCEL构建一个简单的LLM应用

使用LCEL构建一个简单的LLM应用 #

https://python.langchain.com/docs/tutorials/llm_chain/

在这个快速入门中,我们将向您展示如何使用LangChain构建一个简单的LLM应用。这个应用将把文本从英语翻译成另一种语言。这是一个相对简单的LLM应用——它只是一个单一的LLM调用加上一些提示。尽管如此,这是开始使用LangChain的一个很好的方式——许多功能只需要一些提示和一个LLM调用就可以构建!

阅读完本教程后,您将对以下内容有一个高层次的概览:

让我们开始吧!

设置 #

Jupyter Notebook #

本指南(以及文档中的大多数其他指南)使用Jupyter Notebook,并假设读者也是如此。Jupyter Notebook非常适合学习如何使用LLM系统,因为在操作过程中可能会出现问题(意外输出、API故障等),在交互环境中进行指导是一种更好地理解这些内容的方式。

本教程和其他教程在Jupyter Notebook中运行可能是最方便的。请参见此处获取安装说明。

安装 #

1pip install langchain

有关更多详细信息,请参阅安装指南

LangSmith #

用LangChain构建的许多应用程序会包含多个步骤,涉及多次LLM调用。随着这些应用变得越来越复杂,能够检查你的链或代理内部究竟发生了什么变得至关重要。实现这一点的最佳方式是使用LangSmith

在上面的链接注册后,请确保设置你的环境变量以开始记录跟踪:

1export LANGCHAIN_TRACING_V2="true"
2export LANGCHAIN_API_KEY="..."

或者,如果在notebook中,你可以这样设置它们:

1import getpass
2import os
3
4os.environ["LANGCHAIN_TRACING_V2"] = "true"
5os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

注意

LangSmith对个人开发者用户每月有5000次免费追踪额度

os.environ["LANGCHAIN_TRACING_V2"] = "false"可关闭追踪

环境变量设置 #

创建.env文件:

1OPENAI_API_KEY=xxx
2OPENAI_BASE_URL=https://api.openai.com/v1
3MODEL_NAME=gpt-4o-mini

加载环境变量:

1from dotenv import load_dotenv
2assert load_dotenv()

使用语言模型 #

首先,让我们学习如何单独使用语言模型。LangChain支持许多不同的语言模型,这里使用OpenAI。

1import os
2MODEL_NAME = os.environ.get("MODEL_NAME")
3from langchain_openai import ChatOpenAI
4model = ChatOpenAI(model=MODEL_NAME)

首先,我们直接使用模型。ChatModels是LangChain “Runnables”的实例,这意味着它们提供了一个标准接口用于交互。为了简单地调用模型,我们可以将消息列表传递给.invoke方法。

1from langchain_core.messages import  SystemMessage, HumanMessage
2messages = [
3    SystemMessage(content="Translate the following from English into Italian"),
4    HumanMessage(content="hi!"),
5]
6model.invoke(messages)

API Reference: HumanMessage | SystemMessage

1AIMessage(content='Ciao!', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 3, 'prompt_tokens': 20, 'total_tokens': 23, 'completion_tokens_details': None}, 'model_name': 'gpt-4o-mini', 'system_fingerprint': 'fp_878413d04d', 'finish_reason': 'stop', 'logprobs': None}, id='run-c4994bc8-2158-422c-bfc9-16002947e80c-0', usage_metadata={'input_tokens': 20, 'output_tokens': 3, 'total_tokens': 23})

如果我们启用了LangSmith,我们可以看到此运行已记录到LangSmith,并可以查看LangSmith 追踪。

输出解析器(OutputParsers) #

注意到,模型的响应是一个 AIMessage。这包含一个字符串响应以及关于响应的其他元数据。我们通常只想处理字符串响应。我们可以通过使用一个简单的输出解析器来提取这个响应。

首先,我们导入简单输出解析器。

1from langchain_core.output_parsers import  StrOutputParser
2parser = StrOutputParser()

API Reference: StrOutputParser

一种使用方法是单独使用它。例如,我们可以保存语言模型调用的结果,然后将其传递给解析器。

1result = model.invoke(messages)
2parser.invoke(result)
1'Ciao!'

如果我们现在查看 LangSmith,可以看到这个链条有两个步骤:首先调用语言模型,然后将结果传递给输出解析器。我们可以看到LangSmith的追踪记录。

提示模板(Prompt Templates) #

目前,我们直接将消息列表传递给语言模型。这个消息列表来自哪里呢?通常,它是由用户输入和应用逻辑的组合构建而成的。这种应用逻辑通常会将原始用户输入转换为准备传递给语言模型的消息列表。常见的转换包括添加系统消息或使用用户输入格式化模板。

PromptTemplates 是 LangChain 中的一个概念,旨在帮助进行这种转换。它们接收原始用户输入并返回准备好传递给语言模型的数据(提示)。

让我们在这里创建一个 PromptTemplate。它将接收两个用户变量:

  • language: 要翻译成的语言
  • text: 要翻译的文本
1from langchain_core.prompts import ChatPromptTemplate

API Reference: ChatPromptTemplate

首先,让我们创建一个字符串,用于格式化为系统消息:

1system_template = "Translate the following into {language}:"

接下来,我们可以创建 PromptTemplate。这将是system_template和一个更简单的模板的组合,用于放置要翻译的文本。

1prompt_template = ChatPromptTemplate.from_messages(
2    [("system", system_template), ("user", "{text}")]
3)

这个提示模板的输入是一个字典。我们可以单独尝试这个提示模板,看看它的效果。

1result = prompt_template.invoke({"language": "italian", "text": "hi"})
2
3result
1ChatPromptValue(messages=[SystemMessage(content='Translate the following into italian:', additional_kwargs={}, response_metadata={}), HumanMessage(content='hi', additional_kwargs={}, response_metadata={})])

我们可以看到它返回一个ChatPromptValue,其中包含两条消息。如果我们想直接访问这些消息,可以这样做:

1result.to_messages()
1[SystemMessage(content='Translate the following into italian:', additional_kwargs={}, response_metadata={}),
2 HumanMessage(content='hi', additional_kwargs={}, response_metadata={})]

使用 LCEL 连接组件 #

我们现在可以使用管道|运算符将其与上面的模型和输出解析器结合起来:

1chain = prompt_template | model | parser
2chain.invoke({"language": "italian", "text": "hi"})
1'Ciao!'

这是一个使用LangChain表达式语言(LCEL)将LangChain模块串联在一起的简单示例。这种方法有多个优点,包括优化的流式(streaming)处理和追踪(tracing)支持。

如果我们查看LangSmith的追踪记录,可以看到这三个组件都出现在LangSmith的追踪中。

使用 LangServe 提供服务 #

现在我们已经构建了一个应用程序,接下来需要为其提供服务。这就是 LangServe 的作用。LangServe 帮助开发者将 LangChain 链部署为 REST API。您不需要使用 LangServe 来使用 LangChain,但在本指南中,我们将展示如何使用 LangServe 部署您的应用。

虽然本指南的第一部分旨在在 Jupyter Notebook 或脚本中运行,但我们现在将不再使用这些环境。我们将创建一个 Python 文件,并从命令行与之互动。

安装命令为:

1pip install "langserve[all]"

Server #

为了为我们的应用程序创建一个服务器,我们将创建一个 serve.py 文件。这个文件将包含用于提供服务的逻辑,主要包括三部分:

  1. 我们刚刚构建的链的定义
  2. 我们的 FastAPI 应用
  3. 定义一个路由,通过该路由提供链服务,这可以通过 langserve.add_routes 来实现
 1#!/usr/bin/env python
 2from fastapi import FastAPI
 3from langchain_core.prompts import ChatPromptTemplate
 4from langchain_core.output_parsers import StrOutputParser
 5from langchain_openai import ChatOpenAI
 6from langserve import add_routes
 7
 8# 1. Create prompt template
 9system_template = "Translate the following into {language}:"
10prompt_template = ChatPromptTemplate.from_messages([
11    ('system', system_template),
12    ('user', '{text}')
13])
14
15# 2. Create model
16model = ChatOpenAI()
17
18# 3. Create parser
19parser = StrOutputParser()
20
21# 4. Create chain
22chain = prompt_template | model | parser
23
24
25# 4. App definition
26app = FastAPI(
27  title="LangChain Server",
28  version="1.0",
29  description="A simple API server using LangChain's Runnable interfaces",
30)
31
32# 5. Adding chain route
33add_routes(
34    app,
35    chain,
36    path="/chain",
37)
38
39if __name__ == "__main__":
40    import uvicorn
41
42    uvicorn.run(app, host="localhost", port=8000)

就是这样!如果我们执行这个文件:

1python serve.py

我们应该能够在http://localhost:8000看到我们的链被提供服务。

Playground #

每个LangServe服务都配备了一个简单的内置用户界面,用于配置和调用应用程序,支持流式输出并查看中间步骤。访问http://localhost:8000/chain/playground/来试试吧!输入与之前相同的内容 - {"language": "italian", "text": "hi"} - 它应该会像之前一样响应。

Client #

现在让我们设置一个客户端,以便以编程方式与我们的服务交互。我们可以使用 langserve.RemoteRunnable 轻松实现这一点。使用这个,我们可以像在客户端运行一样与提供的链进行交互。

1from langserve import RemoteRunnable
2
3remote_chain = RemoteRunnable("http://localhost:8000/chain/")
4remote_chain.invoke({"language": "italian", "text": "hi"})
1'Ciao'

要了解 LangServe 的更多其他功能,请访问这里

总结 #

就是这样!在本教程中,您学习了如何创建第一个简单的 LLM 应用程序。您了解了如何使用语言模型、解析其输出、创建提示模板、使用 LCEL 进行链式操作、如何通过 LangSmith 获取创建链的良好可观察性,以及如何使用 LangServe 部署它们。

这仅仅是您希望学习以成为熟练 AI 工程师的表面。幸运的是,我们有很多其他资源!

关于 LangChain 核心概念的进一步阅读,我们提供了详细的概念指南。

如果您对这些概念有更具体的问题,可以查看以下操作指南的相关部分:

以及 LangSmith 文档:

© 2024 青蛙小白