第 1 课: LangChain.js 全景概览

0 阅读7分钟

课程目标

理解 LangChain.js 解决的核心问题、设计哲学以及在 LLM 应用开发生态中的定位。


1.1 LLM 应用开发的挑战

在直接调用 LLM API 构建应用时,开发者面临一系列工程问题:

1.1.1 模型调用的复杂性

每个 LLM Provider 的 API 格式不同:

// OpenAI 格式
const response = await openai.chat.completions.create({
  model: "gpt-4o",
  messages: [{ role: "user", content: "Hello" }],
});

// Anthropic 格式
const response = await anthropic.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Hello" }],
});

// Google 格式
const result = await model.generateContent("Hello");

直接后果:

  • 切换模型需要改大量代码
  • 无法在运行时动态选择模型
  • 错误处理、重试、降级逻辑需要针对每个 Provider 单独写

1.1.2 工具调用的碎片化

让 LLM 调用外部工具(搜索、计算、数据库查询)是 Agent 的核心能力,但:

  • 不同 Provider 的工具调用格式不同(OpenAI 叫 function calling,Anthropic 叫 tool_use)
  • 工具的定义、执行、结果回传需要大量胶水代码
  • 工具的组合与编排没有统一模式

1.1.3 对话管理的复杂性

多轮对话需要:

  • 消息历史的存储和检索
  • 上下文窗口的管理(token 超限时如何截断)
  • 不同消息类型的处理(系统消息、用户消息、AI 回复、工具结果)

1.1.4 组件组合的困难

一个典型的 AI 应用需要将多个步骤串联:

  1. 用户输入 → 2. 提示词模板填充 → 3. 模型调用 → 4. 输出解析 → 5. 工具执行 → 6. 结果汇总

没有框架支持时,这些步骤之间的衔接全靠手写胶水代码。


1.2 LangChain.js 的核心理念

LangChain.js 用一个核心设计理念解决上述所有问题:

一切皆 Runnable,Runnable 皆可组合。

1.2.1 什么是 Runnable?

Runnable 是 LangChain.js 的基础抽象。任何组件 — 模型、提示词模板、输出解析器、工具、检索器 — 都实现了同一个接口:

interface Runnable<Input, Output> {
  invoke(input: Input): Promise<Output>;     // 单次调用
  stream(input: Input): AsyncGenerator<Output>; // 流式调用
  batch(inputs: Input[]): Promise<Output[]>;    // 批量调用
  pipe(next: Runnable): RunnableSequence;       // 管道组合
}

1.2.2 统一接口的威力

因为所有组件共享同一接口,你可以像搭积木一样组合它们:

// 三个完全不同的组件,但因为都是 Runnable,可以直接 pipe
const chain = promptTemplate    // Runnable<{topic: string}, BaseMessage[]>
  .pipe(chatModel)              // Runnable<BaseMessage[], AIMessage>
  .pipe(outputParser);          // Runnable<AIMessage, string>

// 一行代码调用整条链
const result = await chain.invoke({ topic: "TypeScript" });

// 流式调用也是一行
for await (const chunk of chain.stream({ topic: "TypeScript" })) {
  process.stdout.write(chunk);
}

1.2.3 Provider 无关性

切换模型不需要改链的逻辑:

// 从 OpenAI 切到 Anthropic,只改这一行
const chatModel = new ChatAnthropic({ model: "claude-sonnet-4-20250514" });
// 链的其余部分完全不变
const chain = promptTemplate.pipe(chatModel).pipe(outputParser);

1.3 项目规模与结构

LangChain.js 是一个大型开源项目:

维度数据
TypeScript 源文件1034+ 个
npm 包40+ 个 (monorepo)
Provider 集成33 个
核心文件 runnables/base.ts3542 行
支持运行时Node.js, Deno, Bun, Browser, Edge
许可证MIT

1.3.1 三层架构

┌────────────────────────────────────────────────────┐
│                  你的应用代码                         │
├────────────────────────────────────────────────────┤
│  langchain (上层)          │  Provider 包 (33个)     │
│  - Agent 编排              │  - @langchain/openai   │
│  - 高级 Chain              │  - @langchain/anthropic│
│  - 内置工具                │  - @langchain/google   │
│  - Hub 集成                │  - @langchain/ollama   │
│                            │  - ...                 │
├────────────────────────────────────────────────────┤
│              @langchain/core (核心)                  │
│  - Runnable 体系      - Messages 数据模型            │
│  - 模型抽象           - 工具抽象                      │
│  - 提示词模板         - 输出解析器                    │
│  - 回调/追踪          - 检索器/向量存储               │
└────────────────────────────────────────────────────┘
  • @langchain/core:定义所有抽象接口,不依赖任何 LLM Provider。你可以只安装 core + 一个 Provider 包。
  • langchain:提供上层实现,如 Agent、高级编排能力。依赖 core。
  • Provider 包:每个 LLM 服务一个独立包,用户按需安装。

1.3.2 33 个 Provider 集成

完整列表:

类别Provider
通用大模型OpenAI, Anthropic, Google GenAI, Google VertexAI, DeepSeek, Groq, Mistral, xAI, Perplexity, Fireworks, Together AI, OpenRouter
本地/私有Ollama
云服务AWS (Bedrock), IBM, Cloudflare
向量数据库Pinecone, MongoDB, Qdrant, Weaviate, PGVector, Redis, Turbopuffer, Neo4j, Google Cloud SQL PG, LanceDB
搜索Tavily, Exa
工具类Cohere (重排)

1.4 技术栈速览

维度选型说明
语言TypeScriptstrict mode, target ES2022
包管理pnpm 10.14workspace monorepo
构建编排Turborepo增量构建,任务依赖
编译tsdownESM + CJS 双输出
测试Vitest单元/集成/类型测试
LintoxlintRust 实现,比 ESLint 快 10-100x
格式化oxfmtRust 实现,比 Prettier 快
SchemaZod v3 + v4双版本兼容

为什么选这些工具?核心考量是性能。1034+ 个 TypeScript 文件的 monorepo,传统工具(ESLint、Prettier)太慢了。oxlint/oxfmt 用 Rust 写的,速度提升 10-100 倍。


1.5 横向对比

1.5.1 vs LangChain (Python)

维度LangChain.jsLangChain (Python)
语言TypeScriptPython
运行时Node/Deno/Bun/Browser/EdgeCPython
类型安全编译期泛型检查运行时检查 (Pydantic)
前端集成原生支持 Browser 和 Edge需要后端 API
生态成熟度较新,增长快更成熟,社区更大
Agent 框架内置 + LangGraph.js内置 + LangGraph

LangChain.js 的独特优势:可以运行在浏览器和 Edge Functions 中,这是 Python 版做不到的。

1.5.2 vs Vercel AI SDK

维度LangChain.jsVercel AI SDK
定位通用 LLM 应用框架前端 AI UI 组件
抽象层级Runnable 统一抽象Provider 适配 + UI hooks
Agent 支持完整 (ReAct, 多 Agent)基础
RAG 支持完整 (分割/嵌入/检索)无内置
可观测性Callbacks + LangSmithOpenTelemetry
适合场景复杂 Agent、RAG、编排前端聊天 UI、简单调用

1.5.3 vs 直接调用 API

维度LangChain.js直接调用 API
Provider 切换改一行代码重写调用层
组件组合pipe() 管道手写胶水代码
流式支持内置 stream/streamEvents手动解析 SSE
重试/降级withRetry/withFallbacks手写
可观测性Callbacks + Tracers手写日志
学习曲线需要理解 Runnable 抽象直接,无额外概念
灵活性框架约束完全自由

什么时候不用 LangChain.js?

  • 只调一个模型、不需要组合 → 直接用 Provider SDK
  • 前端聊天 UI 为主 → Vercel AI SDK 可能更简单
  • 对框架抽象有洁癖 → 直接调 API

什么时候用 LangChain.js?

  • 需要多 Provider 支持和切换
  • 需要 Agent / 工具调用 / RAG
  • 需要复杂的链组合和编排
  • 需要生产级可观测性 (LangSmith)
  • 需要在 Edge/Browser 运行

1.6 核心概念速览

在后续课程中会深入每个概念,这里先建立整体印象:

概念一句话解释对应课程
Runnable万物基石,所有组件的统一接口第 4-8 课
Messages对话的数据模型 (Human/AI/System/Tool)第 9 课
ChatModelLLM 的统一抽象,Provider 只需实现 _generate()第 11 课
Prompts提示词模板,支持变量、few-shot、组合第 12 课
Tools让 LLM 调用外部函数第 14 课
OutputParser将 LLM 文本输出解析为结构化数据第 15 课
Callbacks事件系统,贯穿整个执行过程第 21 课
AgentLLM + Tools + 推理循环第 24 课
Retriever从知识库检索相关文档 (RAG)第 31 课

1.7 动手体验:最小示例

import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";

// 1. 创建组件
const prompt = ChatPromptTemplate.fromMessages([
  ["system", "你是一个 {role},请用简洁的语言回答。"],
  ["human", "{question}"],
]);
const model = new ChatOpenAI({ model: "gpt-4o-mini" });
const parser = new StringOutputParser();

// 2. 用 pipe 组合成链
const chain = prompt.pipe(model).pipe(parser);

// 3. 调用
const result = await chain.invoke({
  role: "TypeScript 专家",
  question: "什么是泛型?",
});
console.log(result);
// → "泛型是 TypeScript 中一种参数化类型的机制,让你编写可复用的..."

这 15 行代码展示了 LangChain.js 的核心能力:

  • Prompt 模板化 — 变量 {role}{question} 自动填充
  • Runnable 组合pipe() 将三个组件串成链
  • Provider 无关 — 把 ChatOpenAI 换成 ChatAnthropic,其余不变

1.8 源码精读路线

优先级文件关注点
P0AGENTS.md项目总览、核心抽象说明、开发规范、测试约定
P0README.md项目定位、生态说明、Quick Start
P1pnpm-workspace.yamlworkspace 定义,了解包的组织方式
P1turbo.json构建任务定义,理解包之间的依赖关系
P2package.json (根目录)脚本命令、devDependencies、工具链选型

本课收获总结

级别你应该掌握的
🟢 基础LLM 应用的四大挑战;LangChain.js 的"一切皆 Runnable"理念;能描述三层架构
🔵 中阶理解 Runnable 统一接口的设计动机;知道 core / langchain / providers 的职责边界
🟡 高阶能对比 LangChain.js 与 Python 版的差异;理解多运行时支持的意义
🟠 资深能分析 40+ 包 monorepo 的模块拆分策略及其工程收益
🔴 架构能评估"统一 Runnable 抽象"的 trade-off:灵活性 vs 复杂性 vs 性能

下一课预告

第 2 课将深入 Monorepo 架构与工程体系,从零搭建开发环境,理解 pnpm workspace、Turborepo 和 tsdown 的配置与协作。