使用 LCEL 构建简单的 LLM 应用程序
在本快速入门中,我们将向您展示如何使用 LangChain 构建一个简单的 LLM 应用程序。该应用程序将把文本从英语翻译成另一种语言。这是一个相对简单的 LLM 应用程序——它只是一个单一的 LLM 调用加上一些提示。尽管如此,这仍然是开始使用 LangChain 的绝佳方式——许多功能只需要一些提示和一个 LLM 调用即可构建!
阅读完本教程后,您将对以下内容有更深入的了解
使用 语言模型
使用 LangChain 表达式语言 (LCEL) 将组件链接在一起
使用 LangSmith 调试和跟踪您的应用程序
让我们深入探讨!
设置
安装
要安装 LangChain,请运行
- npm
- yarn
- pnpm
npm i langchain @langchain/core
yarn add langchain @langchain/core
pnpm add langchain @langchain/core
有关更多详细信息,请参阅我们的 安装指南。
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 支持许多不同的语言模型,您可以互换使用它们——从下方选择您要使用的模型!
选择您的聊天模型
- OpenAI
- Anthropic
- FireworksAI
- MistralAI
- Groq
- VertexAI
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/openai
yarn add @langchain/openai
pnpm add @langchain/openai
添加环境变量
OPENAI_API_KEY=your-api-key
实例化模型
import { ChatOpenAI } from "@langchain/openai";
const model = new ChatOpenAI({ model: "gpt-4" });
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/anthropic
yarn add @langchain/anthropic
pnpm add @langchain/anthropic
添加环境变量
ANTHROPIC_API_KEY=your-api-key
实例化模型
import { ChatAnthropic } from "@langchain/anthropic";
const model = new ChatAnthropic({
model: "claude-3-5-sonnet-20240620",
temperature: 0
});
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/community
yarn add @langchain/community
pnpm add @langchain/community
添加环境变量
FIREWORKS_API_KEY=your-api-key
实例化模型
import { ChatFireworks } from "@langchain/community/chat_models/fireworks";
const model = new ChatFireworks({
model: "accounts/fireworks/models/llama-v3p1-70b-instruct",
temperature: 0
});
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/mistralai
yarn add @langchain/mistralai
pnpm add @langchain/mistralai
添加环境变量
MISTRAL_API_KEY=your-api-key
实例化模型
import { ChatMistralAI } from "@langchain/mistralai";
const model = new ChatMistralAI({
model: "mistral-large-latest",
temperature: 0
});
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/groq
yarn add @langchain/groq
pnpm add @langchain/groq
添加环境变量
GROQ_API_KEY=your-api-key
实例化模型
import { ChatGroq } from "@langchain/groq";
const model = new ChatGroq({
model: "mixtral-8x7b-32768",
temperature: 0
});
安装依赖项
查看 本节了解有关安装集成包的通用说明.
- npm
- yarn
- pnpm
npm i @langchain/google-vertexai
yarn add @langchain/google-vertexai
pnpm add @langchain/google-vertexai
添加环境变量
GOOGLE_APPLICATION_CREDENTIALS=credentials.json
实例化模型
import { ChatVertexAI } from "@langchain/google-vertexai";
const model = new ChatVertexAI({
model: "gemini-1.5-flash",
temperature: 0
});
首先,让我们直接使用模型。ChatModel
是 LangChain “可运行对象”的实例,这意味着它们公开了一个用于与它们交互的标准接口。要简单地调用模型,我们可以将消息列表传递给 .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 跟踪记录
提示模板
现在我们直接将消息列表传递给语言模型。这个消息列表从哪里来?通常它是由用户输入和应用逻辑组合构建的。应用逻辑通常会获取原始用户输入,并将其转换为可传递给语言模型的消息列表。常见的转换包括添加系统消息或使用用户输入格式化模板。
提示模板是 LangChain 中一个旨在帮助进行这种转换的概念。它们接收原始用户输入并返回可传递给语言模型的数据(提示)。
让我们在这里创建一个提示模板。它将接受两个用户变量:
language
:将文本翻译成的语言text
:要翻译的文本
import { ChatPromptTemplate } from "@langchain/core/prompts";
首先,让我们创建一个字符串,将其格式化为系统消息
const systemTemplate = "Translate the following into {language}:";
接下来,我们可以创建提示模板。它将结合 systemTemplate
和一个用于放置文本的更简单的模板
const promptTemplate = ChatPromptTemplate.fromMessages([
["system", systemTemplate],
["user", "{text}"],
]);
这个提示模板的输入是一个字典。我们可以单独尝试这个提示模板,看看它本身能做什么
const promptValue = await promptTemplate.invoke({
language: "italian",
text: "hi",
});
promptValue;
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
,它包含两条消息。如果我们想直接访问这些消息,可以这样做
promptValue.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 llmChain = promptTemplate.pipe(model).pipe(parser);
await llmChain.invoke({ language: "italian", text: "hi" });
"ciao"
如果我们查看 LangSmith 跟踪记录,可以看到所有三个组件都显示在 LangSmith 跟踪记录 中
结论
就是这样!在本教程中,你学习了如何创建第一个简单的 LLM 应用。你了解了如何使用语言模型、如何解析它们的输出、如何创建提示模板、如何使用 LCEL 将它们链接在一起,以及如何使用 LangSmith 获得对创建的链条的良好可观察性。
这仅仅是成为一名熟练的 AI 工程师所需要学习的内容的冰山一角。幸运的是,我们还有很多其他资源!
有关 LangChain 核心概念的更多信息,请查看详细的 概念指南。
如果你对这些概念有更具体的问题,请查看操作指南的以下部分
以及 LangSmith 文档