Langchain.js 教程一:快速入门
LangChain 让您轻松构建完全自定义的智能体和基于 LLM 的应用程序。只需不到 10 行代码,即可连接到千问、DeepSeek、Kimi、 OpenAI、Anthropic、Google 等平台 LangChain 提供预构建的智能体架构和模型集成,帮助您快速上手,并将 LLM 无缝集成到您的智能体和应用程序中。当前最新的版本是 V1.2.13。
1. 安装与说明
LangChain 是使用 TypeScript 编写的,可以在以下环境中使用:
- Node.js (ESM 和 CommonJS) - 18.x, 19.x, 20.x
- 明确不保证支持: Node.js 16,如果仍旧希望在 16版本运行,也可以参考官方文档安装
fetch
要开始使用 LangChain,请使用以下命令安装:
bash
npm install langchain @langchain/core
# Requires Node.js 20+
安装完毕后使用以下命令查看安装版本:
npm list langchain
如果是LangChain的0.0.52之前的版本,需要更新导入以使用新的路径结构,如果你的是新版本则忽略。如果你参考的是之前老版本的教程,可能这些导包路径在之后的版本中更新了,新版导包参考如下:
javascript
import { OpenAI } from "langchain/llms/openai";
适用于下列6个模块的所有导入,这些模块已分割为每个集成的子模块。组合模块已被弃用,在 Node.js 之外不起作用,并将在将来的版本中删除。
- 如果您使用的是
langchain/llms,请参见 LLMs 以获取更新后的导入路径。 - 如果您使用的是
langchain/chat_models,请参见 Chat Models 以获取更新后的导入路径。 - 如果您使用的是
langchain/embeddings,请参见 Embeddings 以获取更新后的导入路径。 - 如果您使用的是
langchain/vectorstores,请参见 Vector Stores 以获取更新后的导入路径。 - 如果您使用的是
langchain/document_loaders,请参见 Document Loaders 以获取更新后的导入路径。 - 如果您使用的是
langchain/retrievers,请参见 Retrievers 以获取更新后的导入路径。
其他模块不受此更改影响,您可以继续从同一路径导入它们。
此外,还有一些模块也需要进行重大更改:
import { Calculator } from "langchain/tools";现已移至import { Calculator } from "langchain/tools/calculator";import { loadLLM } from "langchain/llms";现已移至import { loadLLM } from "langchain/llms/load";import { loadAgent } from "langchain/agents";现已移至import { loadAgent } from "langchain/agents/load";import { loadPrompt } from "langchain/prompts";现已移至import { loadPrompt } from "langchain/prompts/load";import { loadChain } from "langchain/chains";现已移至import { loadChain } from "langchain/chains/load";
LangChain 提供与数百个 LLM 和其他数千个集成的集成。这些集成以独立提供商软件包的形式存在。一般大模型厂商都兼容 openai 的接口规范。
bash
# Installing the OpenAI integration
npm install @langchain/openai
目前为止,我们搞定了环境,接下来创建一个聊天模型快速上手!
2. 快速入门
本节介绍如何使用聊天模型入门。首先我们选择一个开放大模型,国内可以选择千问,DeepSeek 、智谱或者 Kimi的大模型 API 接口。通过访问相关模型官网获取到请求接口与API_KEY(密钥)。本文以千问大模型为例快速构建一个聊天模型。
语言学习模型(LLM)是功能强大的AI工具,能够像人类一样理解和生成文本。它们用途广泛,无需针对每项任务进行专门训练,即可撰写内容、翻译语言、撰写摘要和回答问题。下面主要会学习几点:
- 非流式调用大模型
- 流式调用大模型
- 批量调用大模型
- Zod 结构化输出
- 获取模型回答置信度
2.1 创建项目
在一个空白项目目录下执行如下命令:
bash
npm install @langchain/openai
在这个项目根目录下创建.env文件,并填入千问大模型的API_KEY(密钥)作为项目的环境变量,如下
ini
QWEN_API_KEY=sk-e85d75869a433333333333333333
package.json中添加 type为module:
perl
{
"type": "module",
"dependencies": {
"@langchain/core": "^1.1.32",
"@langchain/openai": "^1.2.13",
"dotenv": "^17.3.1",
"langchain": "^1.2.32"
}
}
2.2 创建大模型对象
导入如下依赖包:
javascript
import dotenv from "dotenv" // 加载环境变量中的模型 API 密钥
import { ChatOpenAI } from "@langchain/openai" // 使用 OpenAi 接口规范
创建大模型对象,下面注释掉的参数一般不需要配置:
php
dotenv.config() // 读取项目 .env 中的环境变量
const llm = new ChatOpenAI({
model: "qwen-plus",
apiKey: process.env.QWEN_API_KEY,
temperature: 0.7,
streamUsage: false, // 是否开启流式返回,默认 false
// maxTokens: 1000, // 最大Tokens
// maxRetries: 6 , // 最大重试次数,
// timeout: undefined, // 超时时间
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1"
}
})
2.3 非流式调用
php
// aiMsg 是一个 AIMessage 实例,包含了模型的回复内容及其调用 Token 统计信息
const aiMsg = await llm.invoke([
{
role: "system",
content: "你是一个智能助手,你会根据用户的问题回答用户的问题,直接回答不知道.",
},
{
role: "user",
content: "世界上最高的山峰是哪座?"
},
])
console.log(aiMsg)
console.log(aiMsg.content)
上面是手动构造一个问答json喂给模型,其实可以使用 OpenAI 提供的接口,如下:
javascript
import { HumanMessage, AIMessage, SystemMessage } from "langchain";
const conversation = [
new SystemMessage("你是一个智能助手,你会根据用户的问题回答用户的问题,直接回答不知道."),
new HumanMessage("世界上最高的山峰是哪座?"),
new AIMessage("xxxx"), // AI 上次响应的消息
];
const aiMsg = await model.invoke(conversation);
大模型返回的aiMsg是一个 AIMessage 实例,包含了模型的回复内容及其调用 Token 统计信息,如下面的内容:
json
AIMessage {
"id": "chatcmpl-ff7226a5-dc79-949f-8776-1dc8685bc1f6",
// content 是重点,也就是大模型对问题的回答内容
"content": "世界上最高的山峰是珠穆朗玛峰(Mount Everest),海拔高度为8848.86米(2020年中国和尼泊尔联合测量的最新官方数据)。它位于中国与尼泊尔边境的喜马拉雅山脉中段。",
"additional_kwargs": {},
"response_metadata": {
"tokenUsage": { // token 使用量
"promptTokens": 38,
"completionTokens": 58,
"totalTokens": 96
},
"finish_reason": "stop",
"model_provider": "openai",
"model_name": "qwen-plus"
},
"tool_calls": [],
"invalid_tool_calls": [],
"usage_metadata": { // token 消耗信息
"output_tokens": 58,
"input_tokens": 38,
"total_tokens": 96,
"input_token_details": {
"cache_read": 0
},
"output_token_details": {}
}
}
如果对用户提供收费服务,一般用usage_metadata来计算用户大模型的调用次数(调用量)。
yaml
console.log(aiMsgForMetadata.usage_metadata);
// 输出:{ input_tokens: 28, output_tokens: 5, total_tokens: 33 }
2.3 流式调用
大多数模型都能在生成输出内容的同时进行流式传输。通过逐步显示输出,流式传输显著提升了用户体验,尤其是在处理较长的响应时。调用stream()返回一个迭代器它会在生成过程中实时输出数据块。您可以使用循环来实时处理每个数据块,只需要调用如下的命令:
ini
const stream = await llm.stream("世界上最高的山峰是哪座?简单回答!");
for await (const chunk of stream) {
console.log(chunk.text)
}
let full = null;
for await (const chunk of stream) {
full = full ? full.concat(chunk) : chunk;
console.log(full.text);
}
console.log(full.contentBlocks);
最后我们只需要实时将 full刷新到 UI 上就能看到流式输出结果。
2.4 批量调用
同样也可以对大模型批量调用,提高调用效率:
javascript
const responses = await llm.batch([
"Why do parrots have colorful feathers?",
"How do airplanes fly?",
"What is quantum computing?",
"Why do parrots have colorful feathers?",
"How do airplanes fly?",
"What is quantum computing?",
], {
maxConcurrency: 5, // 控制最大并行调用次数
});
for (const response of responses) {
console.log(response);
}
2.5 结构化输出
模型可以按照给定的模式提供响应。这有助于确保输出易于解析,并可用于后续处理。LangChain 支持多种模式类型和方法来强制输出结构化数据。
zod schema是定义输出模式的首选方法。请注意,如果提供了 zod schema,模型输出还会使用 zod 的解析方法根据该 schema 进行验证。zod 也可以 json 嵌套。
css
import * as z from "zod";
const Movie = z.object({
title: z.string().describe("The title of the movie"),
year: z.number().describe("The year the movie was released"),
director: z.string().describe("The director of the movie"),
rating: z.number().describe("The movie's rating out of 10"),
});
const modelWithStructure = llm.withStructuredOutput(Movie);
const json = await modelWithStructure.invoke("提供关于泰坦尼克号电影的评价 JSON 信息!");
console.log(json);
// 输出:{ title: '泰坦尼克号', year: 1997, director: '詹姆斯·卡梅隆', rating: 9.2 }
arduino
// 如果需要包含原始数据:用于includeRaw: true同时获取解析后的格式化输出和原始数据。
const modelWithStructure = llm.withStructuredOutput(Movie, { includeRaw: true });
const raw_parsed_json = await modelWithStructure.invoke("提供关于泰坦尼克号电影的评价 JSON 信息!");
console.log(json);
// 输出
// {
// raw: AIMessage { ... },
// parsed: { title: "Inception", ... }
// }
2.6 模型回答置信度
logprobs某些模型可以通过在初始化模型时设置参数来配置,从而返回模型响应给定token可能性的标记级日志概率(只能标记生成 token 的概率,并不是对整句话生成的概率,没啥用,还不如每次输出时要模型给自己的回答打一个置信度分来的准确。):
ini
const model = new ChatOpenAI({
...
logprobs: true,
});
const responseMessage = await model.invoke("Why do parrots talk?");
responseMessage.response_metadata.logprobs.content.slice(0, 5);
下一章节我们详细来介绍:至关重要的 Messages 大模型消息。