跳至主要内容

使用 LCEL 构建简单的 LLM 应用程序

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

阅读本教程后,你将对以下内容有高级概述:

让我们深入了解!

设置

安装

要安装 LangChain,请运行

yarn add langchain

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

LangSmith

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

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

export LANGCHAIN_TRACING_V2="true"
export LANGCHAIN_API_KEY="..."

# Reduce tracing latency if you are not in a serverless environment
# export LANGCHAIN_CALLBACKS_BACKGROUND=true

使用语言模型

首先,让我们学习如何单独使用语言模型。LangChain 支持许多不同的语言模型,你可以互换使用 - 在下面选择你要使用的模型!

选择你的聊天模型

安装依赖项

yarn add @langchain/openai 

添加环境变量

OPENAI_API_KEY=your-api-key

实例化模型

import { ChatOpenAI } from "@langchain/openai";

const model = new ChatOpenAI({ model: "gpt-4" });

首先,让我们直接使用模型。ChatModel 是 LangChain “Runnable” 的实例,这意味着它们公开了与之交互的标准接口。要简单地调用模型,我们可以将消息列表传递给 .invoke 方法。

import { HumanMessage, SystemMessage } from "@langchain/core/messages";

const messages = [
new SystemMessage("Translate the following from English into Italian"),
new HumanMessage("hi!"),
];

await model.invoke(messages);
AIMessage {
lc_serializable: true,
lc_kwargs: {
content: "ciao!",
tool_calls: [],
invalid_tool_calls: [],
additional_kwargs: { function_call: undefined, tool_calls: undefined },
response_metadata: {}
},
lc_namespace: [ "langchain_core", "messages" ],
content: "ciao!",
name: undefined,
additional_kwargs: { function_call: undefined, tool_calls: undefined },
response_metadata: {
tokenUsage: { completionTokens: 3, promptTokens: 20, totalTokens: 23 },
finish_reason: "stop"
},
tool_calls: [],
invalid_tool_calls: []
}

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

输出解析器

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

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

import { StringOutputParser } from "@langchain/core/output_parsers";

const parser = new StringOutputParser();

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

const result = await model.invoke(messages);
await parser.invoke(result);
"ciao!"

使用 LCEL 将组件链接在一起

我们也可以将模型“链接”到输出解析器。 这意味着这个输出解析器将使用模型的输出进行调用。 此链将采用语言模型的输入类型(字符串或消息列表),并返回输出解析器的输出类型(字符串)。

我们可以使用.pipe()方法创建链。.pipe()方法在 LangChain 中用于将两个元素组合在一起。

const chain = model.pipe(parser);
await chain.invoke(messages);
"Ciao!"

这是一个使用LangChain 表达式语言 (LCEL) 将 LangChain 模块链接在一起的简单示例。 此方法有几个好处,包括优化的流式处理和跟踪支持。

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

提示模板

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

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

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

  • language:将文本翻译成的语言
  • text:要翻译的文本
import { ChatPromptTemplate } from "@langchain/core/prompts";

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

const systemTemplate = "Translate the following into {language}:";

接下来,我们可以创建 PromptTemplate。 这将是systemTemplate以及用于放置文本的更简单模板的组合

const promptTemplate = ChatPromptTemplate.fromMessages([
["system", systemTemplate],
["user", "{text}"],
]);

此提示模板的输入是一个字典。 我们可以单独玩弄这个提示模板,看看它本身会做什么

const result = await promptTemplate.invoke({ language: "italian", text: "hi" });

result;
ChatPromptValue {
lc_serializable: true,
lc_kwargs: {
messages: [
SystemMessage {
lc_serializable: true,
lc_kwargs: {
content: "Translate the following into italian:",
additional_kwargs: {},
response_metadata: {}
},
lc_namespace: [ "langchain_core", "messages" ],
content: "Translate the following into italian:",
name: undefined,
additional_kwargs: {},
response_metadata: {}
},
HumanMessage {
lc_serializable: true,
lc_kwargs: { content: "hi", additional_kwargs: {}, response_metadata: {} },
lc_namespace: [ "langchain_core", "messages" ],
content: "hi",
name: undefined,
additional_kwargs: {},
response_metadata: {}
}
]
},
lc_namespace: [ "langchain_core", "prompt_values" ],
messages: [
SystemMessage {
lc_serializable: true,
lc_kwargs: {
content: "Translate the following into italian:",
additional_kwargs: {},
response_metadata: {}
},
lc_namespace: [ "langchain_core", "messages" ],
content: "Translate the following into italian:",
name: undefined,
additional_kwargs: {},
response_metadata: {}
},
HumanMessage {
lc_serializable: true,
lc_kwargs: { content: "hi", additional_kwargs: {}, response_metadata: {} },
lc_namespace: [ "langchain_core", "messages" ],
content: "hi",
name: undefined,
additional_kwargs: {},
response_metadata: {}
}
]
}

我们可以看到它返回一个ChatPromptValue,它包含两条消息。 如果我们想直接访问消息,我们应该做

result.toChatMessages();
[
SystemMessage {
lc_serializable: true,
lc_kwargs: {
content: "Translate the following into italian:",
additional_kwargs: {},
response_metadata: {}
},
lc_namespace: [ "langchain_core", "messages" ],
content: "Translate the following into italian:",
name: undefined,
additional_kwargs: {},
response_metadata: {}
},
HumanMessage {
lc_serializable: true,
lc_kwargs: { content: "hi", additional_kwargs: {}, response_metadata: {} },
lc_namespace: [ "langchain_core", "messages" ],
content: "hi",
name: undefined,
additional_kwargs: {},
response_metadata: {}
}
]

现在我们可以将其与上面的模型和输出解析器结合起来。 这将把所有三个组件链接在一起。

const chain = promptTemplate.pipe(model).pipe(parser);
await chain.invoke({ language: "italian", text: "hi" });
"ciao"

如果我们看一下 LangSmith 跟踪,我们可以看到所有三个组件都出现在LangSmith 跟踪

结论

就是这样! 在本教程中,您学习了如何创建第一个简单的 LLM 应用程序。 您已经了解了如何使用语言模型、如何解析其输出、如何创建提示模板、如何使用 LCEL 将它们链接在一起,以及如何使用 LangSmith 获得对创建的链条的出色可观察性。

这仅仅触及了您成为一名熟练的 AI 工程师需要学习的内容的表面。 幸运的是,我们还有很多其他资源!

有关 LangChain 核心概念的更多阅读,我们提供了详细的概念指南

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

以及 LangSmith 文档


此页面是否有用?


您也可以留下详细的反馈 在 GitHub 上.