前端学AI:基于Node.js的LangChain开发-知识概念

197 阅读10分钟

前端学AI:基于Node.js的LangChain开发-知识概念

本文主要介绍LangChain的简介、核心定位、核心组件、典型应用场景、常见基础API详解和推荐资料。

供自己以后查漏补缺,也欢迎同道朋友交流学习。

引言

最近在学习各种 AI 相关的知识,也研究了下 LangChain,我打算分俩个章节来介绍 LangChain,本章节主要介绍其简介、核心定位、核心组件、典型应用场景、常见基础API详解和推荐资料。

LangChain的简介

LangChain 是一个面向大语言模型(LLMs)应用开发的开源框架,旨在简化语言模型与外部系统、工具及数据的集成,帮助开发者快速构建智能化应用

它不仅支持 Python 生态,还提供了完整的 Node.js 版本,使得 JS/TS 开发者能够无缝接入语言模型的能力。

我个人是前端开发工程师,Python 我也是会的,但还是写 Node.js 更方便,下面都会基于 Node.js 来介绍 LangChain 框架。

核心定位

LangChain 的核心目标是 将语言模型从“对话工具”转变为“生产级应用组件” ,解决以下关键问题:

  • 集成性:将 LLMs 与数据库、API、文档等外部系统连接。
  • 模块化:通过预构建的组件(如提示模板记忆存储工具链)降低开发复杂度。
  • 灵活性:支持自定义扩展,适应从简单问答到复杂业务流程的多种场景。

Node.js版本的特点

  • 全栈能力:可直接在前后端项目中复用代码(如 Next.jsExpress )。
  • 异步高效:基于 JS 的异步非阻塞模型,适合高并发场景。
  • 工具链完善:与主流 Node.js 工具(如 PrismaSupabase)深度集成。

核心组件

LangChain 通过六大核心组件实现功能解耦与复用:

组件功能描述Node.js示例场景
Models对接多种 LLM 服务(如OpenAIAnthropic)或本地模型(如Ollama)。调用ChatOpenAI生成客服对话回复。
Prompts动态生成提示词模板,支持变量插值结构化输出控制。创建商品推荐模板:为{用户兴趣}推荐3个{品类}商品
Memory管理对话或任务的上下文状态短期记忆/长期记忆)。保存用户聊天记录以实现多轮对话连续性
Chains将多个组件串联成工作流(如:文档加载文本分割向量化检索生成答案)。构建自动文档摘要生成链
Agents让模型自主选择工具完成任务(如调用搜索引擎、计算器或数据库)。开发旅行规划助手,自动查询天气、航班和酒店。
Indexes结构化外部数据(文档、数据库),支持高效检索与语义理解。为企业知识库构建问答系统。

典型应用场景

  1. 文档问答系统

    • 流程:加载PDF/Word文档 → 文本分块 → 向量化存储 → 语义检索 → 生成答案。
    • 技术栈TextLoader + RecursiveCharacterTextSplitter + OpenAIEmbeddings + ChromaDB
  2. 智能客服机器人

    • 功能:多轮对话管理、意图识别、自动调用知识库或API。
    • 核心组件BufferMemory(记忆历史对话) + SerpAPI(实时信息查询) + LLMChain(生成自然回复)。
  3. 自动摘要与报告生成

    • 实现:从数据库或网页抓取数据 → 提取关键信息 → 生成结构化摘要(JSON/Markdown)。
    • 工具链CheerioWebBaseLoader(网页抓取) + MapReduceChain(长文本处理) + OutputFixingParser(格式修正)。
  4. 知识图谱构建

    • 步骤:解析非结构化文本 → 实体关系抽取 → 存储到图数据库(如Neo4j)。
    • 关键能力:结合 LLMs 的语义理解与自定义抽取规则。

LangChain的优势

与传统直接调用 LLM API 的方式相比,LangChain 提供了显著优势:

  • 标准化流程:预置最佳实践(如提示工程错误重试),减少重复开发。
  • 可扩展架构:允许替换模型供应商(如从 OpenAI 切换到 Azure OpenAI)而无需重写业务逻辑。
  • 社区支持:活跃的开发者社区持续贡献新工具(如 Discord 集成、PDF解析器)。

Node.js版本的独特价值

  • 全栈开发:前端(React/Vue)与后端(Node.js)共享同一语言,降低学习成本。
  • 性能优化:支持流式响应(Streaming)和边缘计算(如Vercel Edge Functions)。

与其他框架的对比

框架优势局限性适用场景
LangChain功能全面、社区活跃、多语言支持学习曲线较陡复杂 AI 应用开发
LlamaIndex专注于文档检索问答缺乏链式流程和 Agent 支持知识库问答
Semantic Kernel微软生态集成、C#支持Node.js 功能尚未完全对等Azure云服务深度集成
Haystack检索增强生成(RAG)领域领先主要面向 Python,Node.js 支持有限企业级搜索与问答系统

LangChain基础API详解

LangChain 的 API 设计以模块化和链式调用为核心,下面是一些基础 API 的简单介绍:

模型调用(Models)

LangChain 支持三类核心模型接口,满足不同场景需求:

LLMs

基础文本生成模型(如 GPT-3.5 )

  • 核心方法generate() / call()
const model = new OpenAI({ temperature: 0.7 }); 
await model.call("写一首春天的诗"); 
Chat Models

对话式模型(如 GPT-4 )

  • 核心方法predictMessages()
const chat = new ChatOpenAI();
await chat.predictMessages([new HumanMessage("你好!")]);
Embeddings

文本向量化模型(用于语义检索、聚类)

  • 核心方法embedQuery() / embedDocuments()
const embeddings = new OpenAIEmbeddings();
const vec = await embeddings.embedQuery("机器学习");
关键参数说明
  • temperature(0-2):控制生成随机性,值越高结果越多样。
  • maxTokens:限制生成文本的最大长度。
  • streaming:启用流式传输(适合实时聊天场景)。

提示模板(Prompts)

通过模板动态生成提示词,支持结构化输入与输出控制:

基础模板
import { PromptTemplate } from "@langchain/core/prompts";

// 单变量模板
const template = "用{style}风格翻译以下文本:{text}";
const prompt = new PromptTemplate({
  template,
  inputVariables: ["style", "text"], 
});

// 使用示例
const formattedPrompt = await prompt.format({
  style: "文言文",
  text: "Hello world",
});
// 输出:"用文言文风格翻译以下文本:Hello world"
Few-shot模板

嵌入示例提升模型表现:

import { FewShotPromptTemplate } from "langchain/prompts";

const examples = [
  { input: "高兴", output: "欣喜若狂" },
  { input: "悲伤", output: "心如刀绞" }
];

const examplePrompt = new PromptTemplate({
  template: "输入:{input}\n输出:{output}",
  inputVariables: ["input", "output"],
});

const fewShotPrompt = new FewShotPromptTemplate({
  examples,
  examplePrompt,
  suffix: "输入:{adjective}\n输出:", 
  inputVariables: ["adjective"],
});

await fewShotPrompt.format({ adjective: "愤怒" });
/* 输出:
输入:高兴
输出:欣喜若狂

输入:悲伤
输出:心如刀绞

输入:愤怒
输出: 
*/
文件模板加载

从外部文件读取模板:

import { PromptTemplate } from "@langchain/core/prompts";
import fs from "fs";

const template = fs.readFileSync("./prompts/email_template.txt", "utf-8");
const prompt = new PromptTemplate({
  template,
  inputVariables: ["userName", "product"],
});

链式调用(Chains)

通过组合多个组件构建复杂工作流:

LLMChain(基础链)
import { LLMChain } from "langchain/chains";

const chain = new LLMChain({
  llm: new OpenAI(),
  prompt: new PromptTemplate({
    template: "生成关于{topic}的{num}条冷知识", 
    inputVariables: ["topic", "num"]
  }),
});

const res = await chain.call({ topic: "宇宙", num: 3 });
// 输出:模型生成的3条宇宙冷知识
SequentialChain(顺序链)

串联多个链实现分步处理:

import { SequentialChain } from "langchain/chains";

const chain1 = new LLMChain({ ... }); // 生成文章大纲
const chain2 = new LLMChain({ ... }); // 扩展章节内容
const chain3 = new LLMChain({ ... }); // 优化语言风格

const overallChain = new SequentialChain({
  chains: [chain1, chain2, chain3],
  inputVariables: ["title"],
  outputVariables: ["outline", "content", "final"],
});

const result = await overallChain.call({ title: "人工智能的未来" });
TransformChain(转换链)

自定义数据处理逻辑:

import { TransformChain } from "langchain/chains";

const transform = new TransformChain({
  transform: async (inputs) => {
    // 自定义处理逻辑(如文本清洗)
    return { cleaned: inputs.text.replace(/\d+/g, "") };
  },
  inputVariables: ["text"],
  outputVariables: ["cleaned"],
});

文档加载器(Document Loaders)

支持从多种来源加载结构化文档:

  • 本地文件:加载 文本/PDF/Word 文档。
const loader = new TextLoader("example.txt");
const docs = await loader.load();

const loader2 = new PDFLoader("report.pdf");
const docs2 = await loader2.load();

console.log({ docs });
console.log({ docs2 });
  • 网页内容:抓取指定 URLHTML 内容。
const loader = new CheerioWebBaseLoader("https://exampleurl.com");
const docs = await loader.load();
console.log({ docs });
  • 数据库:从 MySQL/MongoDB 读取数据。
import { createClient } from "@supabase/supabase-js";
import { OpenAIEmbeddings } from "@langchain/openai";
import { SupabaseHybridSearch } from "@langchain/community/retrievers/supabase";

// 初始化 Supabase 客户端
const client = createClient(
  process.env.SUPABASE_URL,
  process.env.SUPABASE_PRIVATE_KEY
);

// 创建混合检索器
const retriever = new SupabaseHybridSearch(new OpenAIEmbeddings(), {
  client,
  similarityK: 5,       // 语义搜索返回结果数
  keywordK: 3,           // 关键词搜索返回结果数
  tableName: "documents", // 数据库表名
  similarityQueryName: "match_documents", // 语义搜索函数名
  keywordQueryName: "kw_match_documents", // 关键词搜索函数名
  // 高级参数
  reRanker: (results) => {
    // 自定义结果合并策略(如加权分数)
    return results.sort((a, b) => b.score - a.score);
  }
});
  • 云存储:从 AWS S3/GCS 加载文件。
const loader = new S3Loader({
  bucket: "my-document-bucket-123",
  key: "AccountingOverview.pdf",
  s3Config: {
    region: "us-east-1",
    credentials: {
      accessKeyId: "<YourAccessKeyId>",
      secretAccessKey: "<YourSecretAccessKey>",
    },
  },
  unstructuredAPIURL: "<YourUnstructuredAPIURL>",
  unstructuredAPIKey: "<YourUnstructuredAPIKey>",
});
const docs = await loader.load();
  • 文档分块处理
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";

const splitter = new RecursiveCharacterTextSplitter({
  chunkSize: 500,   // 单块最大字符数
  chunkOverlap: 50, // 块间重叠字符
});

const docs = await loader.load();
const splitDocs = await splitter.splitDocuments(docs);

内存管理(Memory)

管理对话或任务的上下文状态

对话记忆
import { BufferMemory } from "langchain/memory";

const memory = new BufferMemory({
  memoryKey: "chat_history", // 存储对话历史的字段名
});

const chain = new ConversationChain({ 
  llm: new ChatOpenAI(),
  memory 
});

// 连续对话
await chain.call({ input: "你好!" });
await chain.call({ input: "刚才我们聊了什么?" }); // 模型能回忆历史
实体记忆

跟踪特定实体信息:

import { EntityMemory } from "langchain/memory";

const memory = new EntityMemory({
  llm: new OpenAI(),
  entities: ["userName", "preferences"], // 需要跟踪的实体
});

await memory.saveContext(
  { input: "我叫张三,喜欢科幻电影" }, 
  { output: "已记录您的偏好" }
);

const currentEntities = await memory.loadEntities();
// 输出:{ userName: "张三", preferences: "科幻电影" }

输出解析(Output Parsers)

将模型返回的文本转换为结构化数据

基础解析器
import { StringOutputParser } from "@langchain/core/output_parsers";

const chain = prompt.pipe(model).pipe(new StringOutputParser());
const result = await chain.invoke({ topic: "量子计算" });
结构化解析
import { StructuredOutputParser } from "langchain/output_parsers";

// 定义输出Schema
const parser = StructuredOutputParser.fromZodSchema(
  z.object({
    title: z.string().describe("生成的文章标题"),
    keywords: z.array(z.string()).describe("3-5个关键词"),
    content: z.string().describe("不少于500字的内容")
  })
);

const chain = new LLMChain({
  llm: model,
  prompt: new PromptTemplate({
    template: "根据主题{topic}写一篇文章\n{format_instructions}",
    inputVariables: ["topic"],
    partialVariables: { format_instructions: parser.getFormatInstructions() }
  }),
  outputParser: parser
});

const res = await chain.call({ topic: "可再生能源" });
// res 将自动转换为JSON对象:{ title: "...", keywords: [...], content: "..." }

工具与代理(Tools & Agents)

集成外部API扩展模型能力:

预定义工具
import { Calculator, SerpAPI } from "langchain/tools";

const tools = [
  new Calculator(),       // 数学计算
  new SerpAPI(),          // 实时网络搜索
  new WolframAlphaTool(), // 科学计算
];
自定义工具
import { DynamicTool } from "langchain/tools";

const weatherTool = new DynamicTool({
  name: "get_weather",
  description: "查询指定城市的天气",
  func: async (city) => {
    const apiUrl = `https://api.weather.com/${city}`;
    return await fetch(apiUrl).then(res => res.json());
  }
});
代理执行
import { initializeAgentExecutorWithOptions } from "langchain/agents";

const executor = await initializeAgentExecutorWithOptions(
  tools, 
  new ChatOpenAI({ temperature: 0 }), 
  { agentType: "structured-chat-zero-shot-react-description" }
);

const res = await executor.invoke({
  input: "上海当前温度是多少?比纽约高多少摄氏度?"
});
// 模型将自动调用天气查询工具和计算器

检索增强(Retrieval)

结合向量数据库实现知识增强

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { OpenAIEmbeddings } from "@langchain/openai";

// 1. 加载文档并向量化
const vectorStore = await MemoryVectorStore.fromDocuments(
  splitDocs, 
  new OpenAIEmbeddings()
);

// 2. 语义检索
const results = await vectorStore.similaritySearch("神经网络的发展历史", 3);

// 3. 将检索结果注入提示词
const chain = createRetrievalChain({
  retriever: vectorStore.asRetriever(),
  combineDocsChain: new LLMChain(...)
});

推荐资料

官方资源

学习平台

社区与案例

  • GitHub示例库langchain-examples
  • Stack Overflow:搜索langchain.js标签解决常见问题。

扩展阅读

专栏系列