定位: 从零基础到架构师,系统掌握 LangChain.js 框架设计与源码实现。
受众分层:
标记 级别 画像 🟢 基础 有 JS/TS 基础,初次接触 LLM 框架 🔵 中阶 用过 LangChain 做过 demo,想理解底层 🟡 高阶 能写 Provider/工具,想掌握架构设计 🟠 资深 有大型项目经验,关注可维护性与性能 🔴 架构 需要做技术选型、设计框架级方案 原则: 每节课前半段打基础,后半段拔高度。所有级别都能在每节课中有所收获。
第一模块: 全局认知 (第 1-3 课)
建立对项目整体的认知框架,为后续深入打下基础。
第 1 课: LangChain.js 全景概览
核心问题: LangChain.js 解决了什么问题?它的设计哲学是什么?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 LLM 应用开发的基本挑战:模型调用、工具使用、对话管理 |
| 🔵 中阶 | 掌握 LangChain.js 的核心定位:统一接口 + 可组合 + 多 Provider |
| 🟡 高阶 | 理解 LangChain.js vs LangChain (Python) 的差异与权衡 |
| 🟠 资深 | 分析 40+ 包 monorepo 的模块边界划分策略 |
| 🔴 架构 | 评估"统一 Runnable 抽象"这一设计决策的利弊 |
知识点:
- LLM 应用开发的典型挑战与痛点
- LangChain.js 的核心理念:一切皆 Runnable
- 项目规模:1035+ 源文件、40+ npm 包、33 个 Provider
- 与 Python 版 LangChain、LlamaIndex、Vercel AI SDK 的横向对比
- 适用场景与不适用场景
源码入口: README.md, AGENTS.md
第 2 课: Monorepo 架构与工程体系
核心问题: 一个 40+ 包的大型 TypeScript 项目是如何组织和管理的?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会克隆、安装依赖、运行测试,搭建本地开发环境 |
| 🔵 中阶 | 理解 pnpm workspace 和包之间的依赖关系 |
| 🟡 高阶 | 掌握 Turborepo 增量构建与任务编排的配置 |
| 🟠 资深 | 分析 ESM + CJS 双输出策略 (tsdown) 的必要性 |
| 🔴 架构 | 评估 monorepo vs polyrepo 对此项目的影响,理解包拆分边界 |
知识点:
- pnpm 10.14 workspace 配置 (
pnpm-workspace.yaml) - Turborepo 任务依赖图 (
turbo.json) - tsdown 编译配置:ESM + CJS 双输出
- 目录结构:
libs/(核心 + 上层)、libs/providers/(集成)、internal/(构建工具)、examples/ - 开发命令:
pnpm --filter,pnpm build,pnpm test,pnpm lint - 共享 TypeScript 配置 (
internal/tsconfig/)
实操: 从零搭建开发环境,成功构建 @langchain/core 并运行测试
源码入口: pnpm-workspace.yaml, turbo.json, internal/build/, internal/tsconfig/
第 3 课: TypeScript 高级特性在框架中的应用
核心问题: LangChain.js 用了哪些 TypeScript 高级特性?为什么这些特性对框架设计至关重要?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 补齐泛型、异步迭代器、类型推断等核心 TS 知识 |
| 🔵 中阶 | 理解 Runnable<RunInput, RunOutput> 的泛型链如何保证类型安全 |
| 🟡 高阶 | 掌握条件类型、映射类型在框架 API 设计中的运用 |
| 🟠 资深 | 理解 Zod v3/v4 双版本兼容的实现策略 |
| 🔴 架构 | 分析类型系统如何在编译期阻止非法组合 |
知识点:
- 泛型约束与传递:
Runnable<I, O>→RunnableSequence类型链 AsyncGenerator与AsyncIterable:流式输出的类型基础- 抽象类 vs 接口:
Runnable为何选择抽象类 - Zod v3 + v4 双版本共存机制
strict mode下的类型安全保障- 工具函数中的类型推断 (
tool()函数如何从 Zod schema 推断参数类型)
源码入口: langchain-core/src/runnables/types.ts, langchain-core/src/tools/index.ts
第二模块: Runnable 体系 — 万物基石 (第 4-8 课)
这是整个框架最核心的部分。理解 Runnable,就理解了 LangChain.js 的灵魂。
第 4 课: Runnable 接口与核心契约
核心问题: 为什么 LangChain.js 要把一切都统一为 Runnable?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Runnable 的三大核心方法:invoke / stream / batch |
| 🔵 中阶 | 掌握 RunnableConfig 的作用:callbacks, tags, metadata, configurable |
| 🟡 高阶 | 理解 _invoke vs invoke 的模板方法模式 |
| 🟠 资深 | 分析 Runnable 对 Serializable 的继承设计 |
| 🔴 架构 | 评估"统一接口"模式的扩展性边界与 trade-off |
知识点:
Runnable<RunInput, RunOutput>抽象类定义- 三大核心方法:
invoke(),stream(),batch() RunnableConfig:运行时配置传递机制- 模板方法模式:public
invoke()→ protected_invoke()→ 子类实现 Serializable基类与序列化能力
源码精读:
langchain-core/src/runnables/types.ts—RunnableInterface定义langchain-core/src/runnables/config.ts—RunnableConfig结构langchain-core/src/runnables/base.ts—Runnable抽象类 (重点 invoke/stream/batch)
练习: 实现一个最简单的自定义 Runnable(如 UpperCaseRunnable),跑通 invoke/stream/batch
第 5 课: RunnableSequence — 管道组合的核心
核心问题: prompt.pipe(model).pipe(parser) 背后发生了什么?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 pipe() 将多个组件串成链 |
| 🔵 中阶 | 理解 RunnableSequence 的 first/middle/last 结构 |
| 🟡 高阶 | 掌握泛型如何在 pipe 链中传递和校验类型 |
| 🟠 资深 | 分析 RunnableSequence 的流式传播机制:如何让中间节点也支持 stream |
| 🔴 架构 | 对比管道模式 vs 责任链模式的适用场景 |
知识点:
pipe()方法:语法糖与类型推断RunnableSequence:内部first → middle[] → last三段式结构- 流式传播:
transform()方法如何实现逐节点流式 RunnableSequence.from()静态工厂方法- 错误在管道中的传播与中断
源码精读:
langchain-core/src/runnables/base.ts—RunnableSequence类- 重点方法:
pipe(),invoke(),_streamIterator(),transform()
练习: 手写 RunnableSequence.from([prompt, model, parser]),对比 pipe() 的效果
第 6 课: RunnableLambda — 函数即组件
核心问题: 如何把一个普通函数变成可组合的 Runnable?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 RunnableLambda 封装任意函数 |
| 🔵 中阶 | 理解 RunnableLambda 如何自动处理 async 函数与 Generator |
| 🟡 高阶 | 掌握 RunnableLambda 的流式回退:无 Generator 时的 chunk 策略 |
| 🟠 资深 | 分析 RunnableLambda 在函数式与 OOP 之间的桥梁作用 |
| 🔴 架构 | 讨论"任意函数可组合"带来的灵活性与类型安全的 tension |
知识点:
RunnableLambda:函数包装器- 普通函数 vs async 函数 vs Generator 的处理差异
RunnableLambda的自动流式化- 与
RunnableSequence的配合
源码精读:
langchain-core/src/runnables/base.ts—RunnableLambda类
练习: 用 RunnableLambda 封装一个数据预处理函数,嵌入到 pipe 链中
第 7 课: RunnableParallel — 并行执行与数据编排
核心问题: 如何让多个 Runnable 并行执行并合并结果?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 RunnableParallel 并行处理多个子任务 |
| 🔵 中阶 | 理解 RunnableParallel 的输入广播与输出合并机制 |
| 🟡 高阶 | 掌握 RunnablePassthrough 在数据编排中的关键角色 |
| 🟠 资深 | 分析并行执行中的错误处理策略 (fail-fast vs collect-all) |
| 🔴 架构 | 用 RunnableParallel + RunnablePassthrough 实现 DAG 数据流 |
知识点:
RunnableParallel:键值对并行执行- 输入广播:同一输入分发给所有子 Runnable
- 输出合并:各子 Runnable 输出合并为一个对象
RunnablePassthrough:透传原始输入RunnablePassthrough.assign():扩展输入对象
源码精读:
langchain-core/src/runnables/base.ts—RunnableParallellangchain-core/src/runnables/passthrough.ts—RunnablePassthrough
练习: 构建一条链:接收用户问题 → 并行查询多个知识源 → 合并后交给 LLM 回答
第 8 课: RunnableBranch 与 Router — 条件路由
核心问题: 如何根据运行时条件动态选择不同的执行路径?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 RunnableBranch 实现 if/else 逻辑 |
| 🔵 中阶 | 理解 RouterRunnable 的多路由分发机制 |
| 🟡 高阶 | 掌握 Branch + Parallel + Sequence 的复杂组合 |
| 🟠 资深 | 分析条件路由对流式传输的影响 |
| 🔴 架构 | 设计可扩展的路由策略:静态路由 vs LLM 驱动的动态路由 |
知识点:
RunnableBranch:条件分支,支持[condition, runnable]对RouterRunnable:基于 key 的路由分发- 默认分支与 fallback 设计
- 条件路由与流式输出的兼容性
源码精读:
langchain-core/src/runnables/branch.ts—RunnableBranchlangchain-core/src/runnables/router.ts—RouterRunnable
练习: 构建一个智能路由链:根据用户意图分发到不同处理管道(问答 / 翻译 / 代码生成)
第三模块: 核心组件精讲 (第 9-16 课)
在 Runnable 体系之上,逐个击破 Messages、Models、Prompts、Tools、Parsers,并增加对话历史、示例选择器与组合实战。
第 9 课: Messages — 对话数据模型
核心问题: LangChain.js 如何抽象不同 Provider 的消息格式?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 掌握五种消息类型:Human, AI, System, Tool, Function |
| 🔵 中阶 | 理解 AIMessage 的 tool_calls 与 contentBlocks |
| 🟡 高阶 | 掌握多模态内容的表示:text, image_url, base64 |
| 🟠 资深 | 分析 AIMessageChunk 的流式合并策略 |
| 🔴 架构 | 评估消息数据模型的扩展性:如何支持未来的新内容类型 |
知识点:
BaseMessage继承体系:HumanMessage, AIMessage, SystemMessage, ToolMessageAIMessage.tool_calls:结构化工具调用AIMessage.contentBlocks:多模态内容块AIMessageChunk:流式消息分片与合并- 消息序列化与反序列化
源码精读:
langchain-core/src/messages/base.ts—BaseMessagelangchain-core/src/messages/ai.ts—AIMessage,AIMessageChunklangchain-core/src/messages/human.ts,system.ts,tool.ts
练习: 手动构造一段包含多模态内容的对话历史,传给 FakeChatModel 验证
第 10 课: 对话历史与消息管理 🆕
核心问题: 多轮对话中,消息历史如何存储、检索和注入到链中?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解多轮对话的核心挑战:上下文窗口有限,但对话可以无限长 |
| 🔵 中阶 | 掌握 BaseChatMessageHistory 的接口:getMessages(), addMessage() |
| 🟡 高阶 | 理解 RunnableWithMessageHistory 如何自动注入历史消息到链中 |
| 🟠 资深 | 分析 session ID 路由机制:同一链如何服务多个独立会话 |
| 🔴 架构 | 设计对话历史的存储策略:内存 vs Redis vs 数据库,消息截断 vs 摘要压缩 |
知识点:
BaseChatMessageHistory:对话历史抽象接口getMessages()/addMessage()/addUserMessage()/addAIMessage()/clear()
BaseListChatMessageHistory:基于列表的实现基类RunnableWithMessageHistory:将对话历史自动注入 Runnable 链getMessageHistory回调函数:按 session ID 获取历史inputMessagesKey/historyMessagesKey/outputMessagesKey配置
MessagesPlaceholder(第 12 课 Prompts 的前置依赖):在模板中预留历史消息插槽- 历史消息的存储后端:InMemory、Redis、MongoDB 等
源码精读:
langchain-core/src/chat_history.ts—BaseChatMessageHistory,BaseListChatMessageHistorylangchain-core/src/runnables/history.ts—RunnableWithMessageHistory
练习: 构建一个多轮对话链:
- 使用内存存储管理对话历史
- 用
RunnableWithMessageHistory包装链 - 用不同 session ID 模拟两个独立会话,验证上下文隔离
第 11 课: Language Models — 模型抽象层
核心问题: 不同 LLM Provider 的 API 千差万别,如何用一套接口统一?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 BaseChatModel 的调用方式:invoke 返回 AIMessage |
| 🔵 中阶 | 掌握 _generate() 模板方法:Provider 只需实现这一个方法 |
| 🟡 高阶 | 理解 bindTools() 和 withStructuredOutput() 的默认实现 |
| 🟠 资深 | 分析 token 计算、上下文窗口管理的抽象设计 |
| 🔴 架构 | 评估"最小实现接口"的设计模式:如何降低 Provider 接入门槛 |
知识点:
BaseLanguageModel→BaseChatModel继承链_generate()模板方法:Provider 的最小实现接口_streamResponseChunks()可选实现:流式支持bindTools(tools):将工具描述绑定到模型withStructuredOutput(schema):结构化输出getNumTokens(),getModelContextSize()token 管理
源码精读:
langchain-core/src/language_models/base.ts—BaseLanguageModellangchain-core/src/language_models/chat_models.ts—BaseChatModel
练习: 用 FakeChatModel / FakeListChatModel 编写测试,理解模型调用的完整流程
第 12 课: Prompts — 提示词模板系统
核心问题: 如何将提示词工程化、模板化、可组合?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 掌握 ChatPromptTemplate 的创建与变量填充 |
| 🔵 中阶 | 理解 MessagesPlaceholder 如何与对话历史 (第 10 课) 配合 |
| 🟡 高阶 | 掌握 PipelinePromptTemplate 的多模板组合 |
| 🟠 资深 | 分析 Prompt 作为 Runnable 的设计:输入是变量字典,输出是消息列表 |
| 🔴 架构 | 设计可复用的 Prompt 库:版本管理与 Hub 集成 |
知识点:
ChatPromptTemplate.fromMessages()创建消息模板- 变量占位符:
{variable}语法 MessagesPlaceholder:动态插入消息列表(如对话历史)FewShotPromptTemplate:动态 few-shot 示例PipelinePromptTemplate:模板组合ImagePromptTemplate:图片提示- Prompt 的 Runnable 本质:
Runnable<Record<string, any>, BaseMessage[]> PromptValue类型:prompt_values.ts中的中间表示
源码精读:
langchain-core/src/prompts/chat.ts—ChatPromptTemplatelangchain-core/src/prompts/few_shot.tslangchain-core/src/prompts/pipeline.tslangchain-core/src/prompt_values.ts
练习: 构建一个带有 MessagesPlaceholder 的 ChatPromptTemplate,结合第 10 课的历史管理
第 13 课: ExampleSelector 与高级 Few-Shot 🆕
核心问题: 当有大量示例时,如何智能地选择最相关的几个?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Few-shot learning 的原理:给 LLM 看几个例子再让它干活 |
| 🔵 中阶 | 掌握 LengthBasedExampleSelector:按 token 预算选择示例 |
| 🟡 高阶 | 理解 SemanticSimilarityExampleSelector:用向量相似度选最相关的示例 |
| 🟠 资深 | 分析 ConditionalExampleSelector:按条件分支选择不同策略 |
| 🔴 架构 | 设计动态示例管理系统:示例库的维护、评估与自动更新 |
知识点:
BaseExampleSelector抽象接口:selectExamples(),addExample()LengthBasedExampleSelector:按长度/token 数约束选择SemanticSimilarityExampleSelector:基于 Embedding 的语义相似度选择ConditionalExampleSelector:条件分支选择器- 与
FewShotPromptTemplate的集成:Selector 作为示例源 - 示例格式化:如何将结构化示例转为 Prompt 片段
源码精读:
langchain-core/src/example_selectors/base.ts—BaseExampleSelectorlangchain-core/src/example_selectors/length_based.tslangchain-core/src/example_selectors/semantic_similarity.tslangchain-core/src/example_selectors/conditional.ts
练习: 构建一个语义选择的 Few-shot 链:
- 准备 20 个 QA 示例
- 用 SemanticSimilarityExampleSelector 动态选出最相关的 3 个
- 注入到 FewShotPromptTemplate → Model 链中
第 14 课: Tools — 工具系统
核心问题: 如何让 LLM "调用函数"?工具系统的核心抽象是什么?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 tool() 函数和 StructuredTool 类创建工具 |
| 🔵 中阶 | 理解 Zod schema 如何转化为 LLM 可理解的工具描述 |
| 🟡 高阶 | 掌握 DynamicTool 和 DynamicStructuredTool 的动态工具创建 |
| 🟠 资深 | 分析工具调用的完整链路:schema → LLM tool_calls → 执行 → ToolMessage |
| 🔴 架构 | 设计工具注册、发现、权限控制的治理策略 |
知识点:
tool()函数:推荐的工具创建方式StructuredTool类:面向对象的工具定义DynamicTool/DynamicStructuredTool:运行时动态创建- Zod schema → JSON Schema 的转换
- 工具调用链路:LLM 返回
tool_calls→ 框架执行 → 返回ToolMessage - 工具也是 Runnable:
Runnable<ToolInput, string> langchain/src/tools/:内置工具 (headless.ts等)
源码精读:
langchain-core/src/tools/index.ts—StructuredTool,tool(),DynamicToollangchain/src/tools/— 上层内置工具
练习: 创建三个工具(天气查询、计算器、搜索),用 model.bindTools() 绑定到模型
第 15 课: Output Parsers — 结构化输出解析
核心问题: LLM 返回的是非结构化文本,如何安全地解析为程序可用的数据?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 掌握 StringOutputParser 和 JsonOutputParser 的基本用法 |
| 🔵 中阶 | 理解 StructuredOutputParser 如何结合 Zod 进行严格校验 |
| 🟡 高阶 | 掌握流式输出解析:OutputParser 如何处理 chunk 流 |
| 🟠 资深 | 分析 withStructuredOutput vs OutputParser 的选择策略 |
| 🔴 架构 | 设计容错解析策略:auto-fix, retry, fallback |
知识点:
BaseOutputParser抽象与 Runnable 统一StringOutputParser:提取纯文本JsonOutputParser:JSON 解析StructuredOutputParser:Zod 校验ListOutputParser,XMLOutputParser,BytesOutputParser- 流式解析:
transform()方法的逐块处理 withStructuredOutput()与 OutputParser 的对比
源码精读:
langchain-core/src/output_parsers/string.tslangchain-core/src/output_parsers/json.tslangchain-core/src/output_parsers/structured.ts
练习: 构建 Prompt → Model → JsonOutputParser 链,处理正常和异常情况
第 16 课: 第一条完整 Chain — 组合实战
核心问题: 如何把前面学的所有组件组合成一个真实可用的应用?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 完成第一个从 Prompt 到结构化输出的完整链 |
| 🔵 中阶 | 理解链中每个节点的输入输出类型如何匹配 |
| 🟡 高阶 | 掌握链的流式执行:streamEvents 观察中间状态 |
| 🟠 资深 | 分析链的错误传播与优雅降级策略 |
| 🔴 架构 | 建立"组件化 AI 应用"的系统思维 |
知识点:
- 完整链构建:Prompt → Model → Parser
- 带工具的链:Prompt → Model.bindTools → Tool execution → Response
- 带历史的链:RunnableWithMessageHistory 包装 (结合第 10 课)
- 链的流式执行:
chain.stream()vschain.streamEvents() withRetry():自动重试策略withFallbacks():降级方案withConfig():运行时配置绑定- 实战模式:问答链、翻译链、提取链
实操: 构建一个"智能客服"链:
- 接收用户问题
- 并行检索 FAQ + 用户历史
- 组合上下文 + 原始问题 + 对话历史
- 模型生成回答
- 解析为结构化 JSON(answer + confidence + sources)
源码入口: examples/src/
第四模块: 上下文系统与错误体系 (第 17 课) 🆕
Runnable 链的运行时基础设施:上下文如何跨层传递?错误如何结构化处理?
第 17 课: 上下文变量、单例系统与错误类型
核心问题: Callbacks 是怎么在深层嵌套的 Runnable 链中传播的?框架的错误为什么有结构?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解"上下文传递"的问题:深层嵌套中如何共享状态 |
| 🔵 中阶 | 掌握 getContextVariable() / setContextVariable() 的使用 |
| 🟡 高阶 | 理解 AsyncLocalStorage 如何在异步调用链中保持上下文 |
| 🟠 资深 | 分析框架错误类型体系:OutputParserException, ToolInputParsingException 等结构化错误 |
| 🔴 架构 | 设计基于上下文变量的跨组件通信方案,评估 AsyncLocalStorage 的多运行时兼容性 |
知识点:
AsyncLocalStorageProviderSingleton:全局单例,运行时初始化context.ts模块:getContextVariable(),setContextVariable(),registerConfigureHook()singletons/目录:AsyncLocalStorage provider 的抽象- 上下文变量 vs RunnableConfig:两种跨层通信方式的对比
- 错误类型体系 (
errors/目录):OutputParserException:输出解析失败ToolInputParsingException:工具参数解析失败- 与普通 Error 的区别:携带结构化信息 (observation, llmOutput 等)
- 错误恢复策略:retry vs fallback vs 用户干预
源码精读:
langchain-core/src/context.tslangchain-core/src/singletons/langchain-core/src/errors/
练习: 利用上下文变量实现一个"请求级别的 trace ID",在链的所有节点中访问同一个 ID
第五模块: Provider 集成 (第 18-20 课)
从抽象到具体,看核心接口如何被不同 Provider 实现。
第 18 课: Provider 架构 — 以 OpenAI 为例
核心问题: ChatOpenAI 是如何实现 BaseChatModel._generate() 的?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Provider 包的结构和配置方式 |
| 🔵 中阶 | 掌握 _generate() 中 BaseMessage → OpenAI API 的消息转换 |
| 🟡 高阶 | 理解 _streamResponseChunks() 的流式实现 |
| 🟠 资深 | 分析 bindTools() 如何将 LangChain 工具描述转为 OpenAI function calling 格式 |
| 🔴 架构 | 评估 Provider 层的职责边界:转换 vs 适配 vs 增强 |
知识点:
@langchain/openai包结构ChatOpenAI类:继承BaseChatModel_generate()实现:消息格式转换、API 调用、结果映射_streamResponseChunks():SSE 解析、AIMessageChunk 构造bindTools()实现:Zod schema → OpenAI function calling 格式- 配置管理:API key、base URL、model name、temperature 等
源码精读:
libs/providers/langchain-openai/src/chat_models/index.ts- 重点方法:
_generate(),_streamResponseChunks(),bindTools()
第 19 课: Provider 对比 — Anthropic 实现与差异分析
核心问题: 同一抽象,不同 Provider 的实现差异有多大?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会切换 Provider:从 OpenAI 切到 Anthropic 只需改一行 |
| 🔵 中阶 | 理解 Anthropic API 与 OpenAI API 在消息格式上的差异 |
| 🟡 高阶 | 对比两个 Provider 的工具调用实现差异 |
| 🟠 资深 | 分析多模态支持(图片、PDF)的 Provider 差异化处理 |
| 🔴 架构 | 提炼 Provider 适配器模式的最佳实践 |
知识点:
@langchain/anthropic包结构ChatAnthropic._generate()vsChatOpenAI._generate()对比- 消息格式差异:system 消息处理、多模态内容块格式
- 工具调用差异:Anthropic tool_use vs OpenAI function calling
- 流式响应差异:event types 不同
- 统一抽象的价值:上层代码无需关心这些差异
源码精读:
libs/providers/langchain-anthropic/src/chat_models.ts- 对比
langchain-openai的同名方法
练习: 写一段同时支持 OpenAI 和 Anthropic 的代码,通过配置切换 Provider
第 20 课: 自定义 Provider — 从零实现一个 ChatModel
核心问题: 如果要接入一个新的 LLM API,需要实现什么?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Provider 接入的最小实现要求 |
| 🔵 中阶 | 用脚手架 create-langchain-integration 生成项目骨架 |
| 🟡 高阶 | 实现完整的 _generate() 和 _streamResponseChunks() |
| 🟠 资深 | 用 @langchain/standard-tests 验证实现的正确性 |
| 🔴 架构 | 设计 Provider 的测试策略:unit test vs integration test vs standard test |
知识点:
npx create-langchain-integration脚手架- 最小实现:
_generate()方法 - 可选增强:
_streamResponseChunks(),bindTools(),withStructuredOutput() @langchain/standard-tests:标准测试套件FakeChatModel/FakeListChatModel:测试辅助类- 发布流程:npm 包配置、ESM/CJS 双输出
源码精读:
langchain-core/src/utils/testing/— FakeModel 系列libs/langchain-standard-tests/— 标准测试- 任意一个简单 Provider 包(如
langchain-ollama)作为参考
实操: 用 FakeListChatModel 模拟一个 Provider,实现并通过 standard tests
第六模块: Callbacks 与可观测性 (第 21-23 课)
理解事件系统如何贯穿框架全局,支撑调试、追踪、监控。
第 21 课: Callbacks 系统 — 框架的神经网络
核心问题: LangChain.js 如何让你观测到 chain/model/tool 执行过程中的每一步?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 ConsoleCallbackHandler 打印执行过程 |
| 🔵 中阶 | 理解 CallbackManager 的事件分发机制 |
| 🟡 高阶 | 掌握 callback 在 Runnable 链中的传播规则 |
| 🟠 资深 | 分析 callback 的性能影响与异步处理策略 |
| 🔴 架构 | 设计自定义的可观测性方案:日志、指标、追踪三支柱 |
知识点:
BaseCallbackHandler接口:handleLLMStart/End/Error, handleChainStart/End, handleToolStart/EndCallbackManager:事件注册、分发、生命周期管理- Callback 传播:通过
RunnableConfig.callbacks沿链传递 - Callback 与上下文变量 (第 17 课) 的协作:AsyncLocalStorage 驱动的自动传播
handleLLMNewToken:流式 token 回调- 异步 callback 的处理:
awaitHandlers选项
源码精读:
langchain-core/src/callbacks/base.ts—BaseCallbackHandlerlangchain-core/src/callbacks/manager.ts—CallbackManagerlangchain-core/src/callbacks/dispatch/— 事件分发
练习: 自定义一个 CallbackHandler,统计 LLM 调用的耗时、token 数、成功率
第 22 课: Tracers 与 Event Stream — 生产级可观测
核心问题: 如何在生产环境中追踪和调试复杂的 AI 应用?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 ConsoleCallbackHandler 和日志输出调试 |
| 🔵 中阶 | 理解 streamEvents() 的事件流机制 |
| 🟡 高阶 | 掌握 LangChainTracer 与 LangSmith 的集成 |
| 🟠 资深 | 分析 EventStreamCallbackHandler 的 SSE 实现 |
| 🔴 架构 | 设计分布式追踪方案:parent-child run 关系、run tree |
知识点:
ConsoleCallbackHandler:开发环境调试LangChainTracer:LangSmith 追踪上报LogStreamCallbackHandler:结构化日志EventStreamCallbackHandler:SSE 事件流 (支撑streamEventsAPI)RunCollectorCallbackHandler:收集所有 run 信息RootListenerCallbackHandler:顶层监听- Run 层级关系:parent run → child runs (链式追踪)
源码精读:
langchain-core/src/tracers/console.tslangchain-core/src/tracers/event_stream.tslangchain-core/src/tracers/tracer_langchain.ts
练习: 用 chain.streamEvents("v2") 监听一条链的完整执行过程,输出事件日志
第 23 课: Graph 可视化与调试技巧 🆕
核心问题: 复杂的 Runnable 链看不懂结构怎么办?测试该怎么写?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 学会用 chain.getGraph() 生成 Mermaid 图,可视化链的拓扑结构 |
| 🔵 中阶 | 掌握 Vitest 测试框架在 LangChain.js 中的用法与约定 |
| 🟡 高阶 | 理解 Graph 的节点/边数据结构:如何遍历和分析链的组成 |
| 🟠 资深 | 用 FakeChatModel / FakeListChatModel 系列构建无 API 依赖的测试 |
| 🔴 架构 | 设计 AI 应用的测试金字塔:单元测试 (FakeModel) → 集成测试 (真实 API) → E2E 测试 |
知识点:
Graph类:节点 (Node) 与边 (Edge) 的数据结构getGraph()方法:从 Runnable 链自动生成图drawMermaid()/drawMermaidImage():Mermaid 语法输出与图片渲染- 图的遍历:用于链的分析和验证
- 测试框架与约定:
- Vitest 配置与运行方式
- 单元测试 (
*.test.ts) vs 集成测试 (*.int.test.ts) 命名约定 @langchain/core/utils/testing工具类:FakeChatModel:最简模型 mockFakeListChatModel:预设响应列表FakeStreamingChatModel:模拟流式
- 测试中的 Callback 验证:断言事件是否正确触发
源码精读:
langchain-core/src/runnables/graph.ts—Graph,Node,Edgelangchain-core/src/runnables/graph_mermaid.ts—drawMermaid(),drawMermaidImage()langchain-core/src/testing/— 测试工具类
练习:
- 对第 16 课构建的"智能客服"链调用
getGraph()→drawMermaid(),生成可视化图 - 用
FakeListChatModel为同一条链编写完整单元测试,覆盖正常和异常路径
第七模块: Agent 系统 (第 24-28 课)
从被动执行到主动推理。Agent 是 LangChain.js 的高阶能力。
第 24 课: Agent 基础 — ReAct 模式
核心问题: Agent 和 Chain 的本质区别是什么?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Agent 的核心循环:思考 → 行动 → 观察 → 再思考 |
| 🔵 中阶 | 学会用 createReactAgent() 创建基本 Agent |
| 🟡 高阶 | 理解 ReAct 循环的终止条件与最大迭代控制 |
| 🟠 资深 | 分析 Agent 的状态管理与消息累积策略 |
| 🔴 架构 | 评估 ReAct vs Plan-and-Execute vs Reflection 等不同 Agent 范式 |
知识点:
- Agent 定义:LLM + Tools + 推理循环
- ReAct 模式:Reasoning + Acting 的交替执行
createReactAgent()工厂函数- Agent 执行循环:LLM 决策 → 工具执行 → 结果反馈 → 再决策
- 循环终止条件:直接回复 / 最大迭代 / 错误
- Agent vs Chain:有循环 vs 无循环
- Agent 响应处理:
responses.ts
源码精读:
langchain/src/agents/ReactAgent.ts— ReAct Agent 完整实现langchain/src/agents/model.ts— 模型调用节点langchain/src/agents/responses.ts— 响应处理examples/src/createAgent/— 示例
练习: 创建一个带搜索和计算工具的 ReAct Agent,观察执行日志理解推理过程
第 25 课: Agent 状态与注解系统
核心问题: Agent 如何管理对话状态和上下文?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Agent 状态的数据结构:messages 列表 |
| 🔵 中阶 | 掌握 Annotation 系统:类型安全的状态定义 |
| 🟡 高阶 | 理解状态的 reducer 机制:消息如何累积和更新 |
| 🟠 资深 | 分析状态持久化与恢复的设计模式 |
| 🔴 架构 | 设计有状态 Agent 的内存管理策略:短期 vs 长期记忆 |
知识点:
AgentState:消息列表 + 自定义字段Annotation系统:声明式状态定义- Reducer 函数:状态合并策略
- 状态检查点:暂停与恢复
structuredClone与状态不可变性
源码精读:
langchain/src/agents/state.ts— 状态定义langchain/src/agents/annotation.ts— 注解系统
第 26 课: Agent 中间件与节点系统
核心问题: 如何在 Agent 执行流程中插入自定义逻辑?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Agent 内部的图结构:节点 + 边 |
| 🔵 中阶 | 掌握中间件的概念与基本使用 |
| 🟡 高阶 | 自定义 Agent 节点:在模型调用前/后添加逻辑 |
| 🟠 资深 | 分析 RunnableCallable 在 Agent 中的桥接作用 |
| 🔴 架构 | 设计 Agent 中间件体系:验证、审计、限流、日志 |
知识点:
- Agent 的图结构:节点 (nodes) + 边 (edges)
- 中间件系统:
middleware.ts的设计 - 内置节点:model node, tool node
RunnableCallable:Runnable 与普通函数的桥接- Agent 的流式输出控制:
stream.ts
源码精读:
langchain/src/agents/middleware.ts/langchain/src/agents/middleware/langchain/src/agents/nodes/langchain/src/agents/RunnableCallable.tslangchain/src/agents/stream.ts
练习: 给 Agent 添加一个中间件:在每次工具调用前检查权限
第 27 课: 多 Agent 协作
核心问题: 多个 Agent 如何分工协作,完成单个 Agent 无法完成的复杂任务?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解多 Agent 的典型场景:分工、审核、辩论 |
| 🔵 中阶 | 学会用 supervisor 模式编排多个 Agent |
| 🟡 高阶 | 掌握 Agent 间的消息传递与状态共享 |
| 🟠 资深 | 分析多 Agent 的错误传播与恢复策略 |
| 🔴 架构 | 设计可扩展的多 Agent 架构:supervisor / swarm / hierarchical |
知识点:
- 多 Agent 模式分类:supervisor、swarm、hierarchical、debate
- Agent 间通信:消息传递 vs 共享状态
- supervisor Agent:任务分配与结果汇总
withAgentName():Agent 身份标识- Agent 运行时管理:
runtime.ts
源码精读:
examples/src/multi-agent/— 多 Agent 示例langchain/src/agents/withAgentName.tslangchain/src/agents/runtime.ts
练习: 构建一个"研究助手"系统:Researcher Agent 搜索信息 + Writer Agent 撰写报告 + Reviewer Agent 审核
第 28 课: 生产级 Agent — 错误处理、限流与安全
核心问题: 把 Agent 部署到生产环境,需要考虑哪些问题?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 Agent 常见故障模式:死循环、幻觉工具、超时 |
| 🔵 中阶 | 掌握 Agent 的超时控制与最大迭代限制 |
| 🟡 高阶 | 实现 Agent 的工具调用白名单与参数校验 |
| 🟠 资深 | 设计 Agent 的分级限流与成本控制方案 |
| 🔴 架构 | 构建 Agent 的完整生产运维方案:监控、告警、降级、回滚 |
知识点:
- 错误类型与处理:
langchain/src/agents/errors.ts - 最大迭代控制:防止无限循环
- 超时机制:设置 Agent 和工具的超时
- 工具调用安全:白名单、参数校验、敏感操作确认
- 成本控制:token 预算、API 调用限制
- 响应质量检查:输出验证与自动重试
- 人机协作:human-in-the-loop 中断点
源码精读:
langchain/src/agents/errors.tslangchain/src/agents/constants.tslangchain/src/agents/utils.ts
实操: 为上一课的多 Agent 系统添加:超时控制、错误重试、成本上限、执行日志
第八模块: RAG 与文档处理 (第 29-32 课)
检索增强生成 (RAG) 是 LLM 应用的最常见模式。从 Document 数据模型到完整 pipeline。
第 29 课: Document 模型与 DocumentLoader 🆕
核心问题: LangChain.js 中的"文档"是什么?如何从各种数据源加载文档?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 掌握 Document 数据结构:pageContent + metadata |
| 🔵 中阶 | 理解 BaseDocumentLoader 抽象:load() 和 loadAndSplit() |
| 🟡 高阶 | 掌握 DocumentTransformer:对文档进行后处理(清洗、过滤、增强) |
| 🟠 资深 | 分析 Indexing 系统:RecordManager 如何实现文档去重与增量更新 |
| 🔴 架构 | 设计大规模文档 ingestion pipeline:去重、版本控制、增量同步 |
知识点:
Document类:pageContent(文本内容) +metadata(结构化元数据)BaseDocumentLoader:文档加载器抽象load():加载全部文档loadAndSplit(textSplitter):加载并分块
DocumentTransformer:文档转换器transformDocuments():批量转换- 用途:HTML 清洗、元数据提取、语言检测
- Indexing 系统:
RecordManager:记录已索引的文档 hashindexDocs():增量索引,自动跳过已存在的文档- 去重策略:content hash vs source + hash
- Structured Query:
structured_query/:Self-query retriever 的基础设施Comparator,Operator:查询条件的 IR 表示
源码精读:
langchain-core/src/documents/document.ts—Document类langchain-core/src/documents/transformers.ts—DocumentTransformerlangchain-core/src/document_loaders/base.ts—BaseDocumentLoaderlangchain-core/src/indexing/—RecordManager,indexDocslangchain-core/src/structured_query/— 结构化查询 IR
练习: 实现一个自定义 DocumentLoader,从 JSON 文件加载文档并附带 metadata
第 30 课: 文本分割与 Embeddings
核心问题: 如何把大量文档变成 LLM 可检索的知识库?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 RAG 的基本流程:加载 → 分割 → 嵌入 → 存储 → 检索 → 生成 |
| 🔵 中阶 | 掌握 TextSplitter 的分块策略:按字符、递归、语义 |
| 🟡 高阶 | 理解 Embeddings 抽象:文本 → 向量的转换接口 |
| 🟠 资深 | 分析分块大小对检索质量的影响与调优策略 |
| 🔴 架构 | 设计大规模文档处理的批量 pipeline |
知识点:
- RAG 全流程概览 (基于第 29 课的 Document 基础)
TextSplitter:文本分块RecursiveCharacterTextSplitter:递归分割 (最常用)CharacterTextSplitter:按字符分割- 分块参数:
chunkSize,chunkOverlap
Embeddings抽象:embedQuery(),embedDocuments()- 分块与 Document.metadata 的联动:保留来源信息
源码精读:
langchain-textsplitters/src/text_splitter.tslangchain-core/src/embeddings.ts
练习: 加载一个 Markdown 文件 → RecursiveCharacterTextSplitter 分块 → 打印分块结果与 metadata
第 31 课: VectorStore 与 Retriever — 检索核心
核心问题: 如何高效地从向量数据库中检索相关文档?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解向量检索的基本原理:相似度搜索 |
| 🔵 中阶 | 掌握 VectorStore 接口:addDocuments, similaritySearch |
| 🟡 高阶 | 理解 Retriever 抽象与 VectorStoreRetriever 的关系 |
| 🟠 资深 | 分析不同向量数据库 (Pinecone, MongoDB, Chroma) 的 trade-off |
| 🔴 架构 | 设计完整的 RAG pipeline:分块策略 + 检索 + 重排 + 生成 |
知识点:
VectorStore抽象:addDocuments(),similaritySearch(),asRetriever()BaseRetriever:检索器抽象,也是 RunnableVectorStoreRetriever:基于向量存储的检索器- 检索器也是 Runnable:可以 pipe 到链中
- 完整 RAG 链:
retriever.pipe(formatDocs).pipe(prompt).pipe(model).pipe(parser) - Provider 集成:Pinecone, MongoDB, Chroma 等
BaseStore<K, V>:通用 KV 存储抽象 (与 VectorStore 的区别)
源码精读:
langchain-core/src/vectorstores.tslangchain-core/src/retrievers/langchain-core/src/stores.ts—BaseStore
第 32 课: 完整 RAG 应用实战
核心问题: 如何从零构建一个生产可用的 RAG 系统?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 完成一个端到端的 RAG 应用:从文档加载到问答 |
| 🔵 中阶 | 整合 Document → Split → Embed → Store → Retrieve → Generate 全流程 |
| 🟡 高阶 | 实现增量索引:只处理新增和修改的文档 |
| 🟠 资深 | 添加对话历史支持:RAG + 多轮对话 (结合第 10 课) |
| 🔴 架构 | 设计 RAG 的评估方案:检索召回率、答案准确率、幻觉检测 |
实操: 构建一个完整的 RAG 应用:
- 用 DocumentLoader 加载文档 → TextSplitter 分块
- 用 RecordManager 增量索引 (跳过已处理文档)
- 嵌入 → 存入向量库
- 用户提问 → 检索相关文档 → 组合上下文 → LLM 生成答案
- 用 RunnableWithMessageHistory 支持多轮对话
- 用 streamEvents 实时展示检索和生成过程
第九模块: 高级专题 (第 33-35 课)
深入框架的边界能力,为架构决策提供深度理解。
第 33 课: MCP 协议适配
核心问题: 如何将 MCP (Model Context Protocol) 的工具无缝接入 LangChain.js?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解 MCP 协议的基本概念:标准化的工具通信协议 |
| 🔵 中阶 | 学会用 MCP Adapter 将 MCP Server 的工具转为 LangChain 工具 |
| 🟡 高阶 | 理解 MCP 连接管理:SSE, stdio, HTTP 等传输层 |
| 🟠 资深 | 分析 MCP 工具描述到 LangChain StructuredTool 的映射策略 |
| 🔴 架构 | 评估 MCP 在 Agent 生态中的定位与未来发展 |
知识点:
- MCP 协议概述:标准化 AI 工具调用协议
@langchain/mcp-adapters包结构tools.ts:MCP tool → LangChain StructuredTool 转换client.ts:MCP 客户端管理connection.ts:连接管理 (SSE, stdio, HTTP)hooks.ts:生命周期钩子- 与 Agent 的集成:MCP 工具作为 Agent 的外部能力
源码精读:
langchain-mcp-adapters/src/tools.tslangchain-mcp-adapters/src/client.tslangchain-mcp-adapters/src/connection.ts
练习: 创建一个 MCP Server,通过 adapter 接入 LangChain Agent
第 34 课: 序列化、缓存与存储系统
核心问题: 如何持久化和复用 LangChain.js 的组件和链?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解为什么需要序列化:配置持久化、组件复用 |
| 🔵 中阶 | 掌握 Serializable 基类的设计 |
| 🟡 高阶 | 理解动态加载机制:按名称查找和实例化组件 |
| 🟠 资深 | 分析缓存与存储系统的分层设计 |
| 🔴 架构 | 设计组件注册与发现的治理方案 |
知识点:
Serializable基类:lc_serializable,lc_namespace,toJSON()- 动态加载:
load/index.ts的组件查找与实例化 langchain/src/load/:import map 与序列化支持- 缓存系统:
langchain-core/src/caches/- 内存缓存
- 缓存 key 策略
- 存储层实现 (
langchain/src/storage/):InMemoryStore:内存 KV 存储FileSystemStore:文件系统持久化EncoderBackedStore:编码器包装,支持序列化/反序列化
- 序列化安全:防止恶意反序列化
- LangChain Hub (
langchain/src/hub/):远程 Prompt 仓库
源码精读:
langchain-core/src/load/serializable.tslangchain-core/src/load/index.tslangchain-core/src/caches/langchain/src/storage/— InMemoryStore, FileSystemStore, EncoderBackedStorelangchain/src/hub/— Hub 集成
第 35 课: 流式架构与多运行时支持 🆕 (合并)
核心问题: LangChain.js 的流式能力如何实现?如何在 Node/Deno/Bun/Browser/Edge 全平台运行?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 理解流式输出的用户体验价值 + 多运行时的概念 |
| 🔵 中阶 | 掌握 stream() 和 streamEvents() 的区别 |
| 🟡 高阶 | 理解流式在 RunnableSequence 中的传播:transform 链 |
| 🟠 资深 | 分析 convertToHttpEventStream() 的 SSE 转换 + AsyncGenerator 背压管理 |
| 🔴 架构 | 设计端到端流式方案 + 多运行时兼容策略 |
Part 1: 流式架构
知识点:
stream()方法的默认实现与自定义重写_streamIterator()与_transform()的关系streamEvents("v2"):事件级别的流式监控IterableReadableStream:langchain-core 的流工具类- 流式在 RunnableSequence 中的逐节点传播
streamLog()与streamEvents()的对比convertToHttpEventStream():Runnable stream → HTTP SSE- 端到端流式:模型 SSE → LangChain stream → HTTP response → 前端
Part 2: 多运行时支持
知识点:
- 支持的运行时:Node.js (ESM/CJS), Deno, Bun, Browser, Cloudflare Workers, Vercel Edge, Supabase Edge
- ESM + CJS 双输出的构建配置 (
tsdown.config.ts) internal/build/插件与工具:构建流程自动化browser.ts入口:Browser 环境的特殊导出AsyncLocalStorage的运行时差异:Node 原生 vs Web polyfill- Universal ChatModel (
langchain/src/chat_models/universal.ts):运行时动态选择 Provider internal/model-profiles/:模型配置信息
源码精读:
langchain-core/src/runnables/base.ts—stream(),transform(),_streamIterator()langchain-core/src/runnables/iter.ts— 迭代器工具langchain-core/src/runnables/wrappers.ts—convertToHttpEventStream()internal/build/src/— 构建插件langchain/src/chat_models/universal.ts— Universal ChatModellangchain/src/browser.ts— Browser 入口
练习: 构建一个流式 Web 应用:后端用 streamEvents 推送,前端逐步渲染 Agent 的思考和行动
第十模块: 架构回顾与实战 (第 36 课)
第 36 课: 框架架构总结与生产实战
核心问题: 如何用 LangChain.js 构建一个生产级 AI 应用?如何为框架贡献代码?
| 级别 | 收获 |
|---|---|
| 🟢 基础 | 建立完整的知识体系回顾,巩固核心概念 |
| 🔵 中阶 | 掌握从 demo 到生产的关键差距与解决方案 |
| 🟡 高阶 | 理解框架的测试策略与贡献流程 |
| 🟠 资深 | 形成技术选型的决策框架:何时用 LangChain,何时直接调 API |
| 🔴 架构 | 提炼 LangChain.js 的设计模式,应用到自己的框架设计中 |
Part 1: 架构总复盘
- 核心设计模式回顾:
- 统一接口模式 (Runnable):一切组件实现同一抽象
- 管道组合模式 (pipe):组件像积木一样拼接
- 模板方法模式 (_generate/_invoke):框架定流程,子类填实现
- 适配器模式 (Provider):统一外部差异
- 观察者模式 (Callbacks):事件驱动的可观测性
- 状态机模式 (Agent):有限状态 + 循环推理
- 上下文传播模式 (AsyncLocalStorage):隐式跨层通信
- 包依赖关系全景图:core → providers / langchain → 应用
- 类型系统的层级:Interface → Abstract Class → Concrete Implementation
langchain-classic/兼容层:旧版 API 的过渡策略
Part 2: 生产化检查清单
- 可靠性:重试、降级、超时、熔断
- 可观测性:日志、指标、追踪 (LangSmith)
- 安全性:工具白名单、输入校验、敏感信息过滤
- 性能:缓存策略、并行执行、流式输出
- 成本:token 预算、模型分级、缓存命中率
Part 3: 贡献代码指南
- 代码规范:oxlint + oxfmt
- 测试要求:单元测试 (
*.test.ts) + 集成测试 (*.int.test.ts) - Standard Tests:标准测试套件的使用
- PR 流程与 review 标准
- 新 Provider 接入的完整步骤
实操: 综合实战项目 — 构建一个完整的 AI 助手:
- 多 Provider 支持 (OpenAI + Anthropic + 本地模型) + Universal ChatModel
- RAG 知识库检索 + 增量索引
- 多工具 Agent (搜索、计算、MCP 工具)
- 多轮对话 + 对话历史持久化
- 流式输出 + 实时追踪
- 错误处理 + 优雅降级
- 完整的测试覆盖 (FakeModel 单元测试 + 集成测试)
附录
A. 知识依赖图
第 1-3 课 (全局认知)
│
▼
第 4-8 课 (Runnable 体系) ◄── 核心,后续所有内容的基础
│
├──► 第 9-16 课 (核心组件)
│ │
│ ├── 第 9-10 课 (Messages + 对话历史)
│ ├── 第 11 课 (Language Models)
│ ├── 第 12-13 课 (Prompts + ExampleSelector)
│ ├── 第 14 课 (Tools)
│ ├── 第 15 课 (Output Parsers)
│ └── 第 16 课 (组合实战)
│
├──► 第 17 课 (上下文 + 错误体系) ◄── Callbacks 的前置知识
│ │
│ └──► 第 21-23 课 (Callbacks + Tracers + 调试)
│
├──► 第 18-20 课 (Provider) ◄── 依赖 Models + Tools
│
├──► 第 24-28 课 (Agent) ◄── 依赖 Messages + Models + Tools + Callbacks
│ │
│ └──► 第 33 课 (MCP)
│
└──► 第 29-32 课 (RAG) ◄── 依赖 Documents + Embeddings + Retrievers
│
└── 第 29 课 (Document 模型) → 第 30-31 课 (分割+检索) → 第 32 课 (实战)
第 34-35 课 (高级专题) ◄── 需要对框架有整体理解
│
▼
第 36 课 (总结实战) ◄── 融合所有知识
B. 新增课程与原课程的对应关系
| 新增课程 | 课号 | 填补的知识缺口 | 关联的原有课程 |
|---|---|---|---|
| 对话历史与消息管理 | 第 10 课 | chat_history.ts, runnables/history.ts | 第 9 课 Messages、第 12 课 Prompts |
| ExampleSelector 与高级 Few-Shot | 第 13 课 | example_selectors/ (5 个文件) | 第 12 课 Prompts |
| 上下文变量、单例系统与错误类型 | 第 17 课 | context.ts, singletons/, errors/ | 第 21 课 Callbacks |
| Graph 可视化与调试技巧 | 第 23 课 | runnables/graph.ts, graph_mermaid.ts, Vitest 测试 | 第 22 课 Tracers |
| Document 模型与 DocumentLoader | 第 29 课 | documents/, document_loaders/, indexing/, structured_query/ | 第 30-31 课 RAG |
| 多运行时与构建系统 (合入第 35 课) | 第 35 课 | internal/build/, browser.ts, universal.ts, runnables/wrappers.ts | 第 34 课序列化 |
C. 各级别推荐学习路径
| 级别 | 推荐路径 | 预计时长 |
|---|---|---|
| 🟢 基础 | 全部 36 课顺序学习,重点关注每课基础层收获 | 7-9 周 |
| 🔵 中阶 | 可跳过第 1-3 课,从第 4 课开始精读 | 5-7 周 |
| 🟡 高阶 | 重点攻克第 4-8 课 + 第 18-20 课 + 第 24-28 课 + 第 29-32 课 | 4-5 周 |
| 🟠 资深 | 选择性深入,重点是架构决策与设计模式 | 2-3 周 |
| 🔴 架构 | 聚焦每课的架构层收获 + 第 36 课的设计模式总结 | 1-2 周 |
D. 源码精读优先级
| 优先级 | 文件 | 课程 |
|---|---|---|
| P0 | runnables/base.ts | 第 4-8 课 |
| P0 | language_models/chat_models.ts | 第 11 课 |
| P0 | tools/index.ts | 第 14 课 |
| P0 | messages/*.ts | 第 9 课 |
| P1 | chat_history.ts + runnables/history.ts | 第 10 课 |
| P1 | prompts/chat.ts | 第 12 课 |
| P1 | agents/ReactAgent.ts | 第 24 课 |
| P1 | callbacks/manager.ts | 第 21 课 |
| P1 | documents/document.ts | 第 29 课 |
| P2 | example_selectors/*.ts | 第 13 课 |
| P2 | context.ts + singletons/ | 第 17 课 |
| P2 | runnables/graph.ts + graph_mermaid.ts | 第 23 课 |
| P2 | Provider 实现 (langchain-openai, langchain-anthropic) | 第 18-19 课 |
| P2 | tracers/event_stream.ts | 第 22 课 |
| P2 | vectorstores.ts, embeddings.ts | 第 31 课 |
| P3 | mcp-adapters/src/*.ts | 第 33 课 |
| P3 | load/serializable.ts | 第 34 课 |
| P3 | internal/build/src/ | 第 35 课 |
| P3 | langchain/src/chat_models/universal.ts | 第 35 课 |
| P3 | indexing/, structured_query/ | 第 29 课 |
E. 覆盖率自查清单
以下是项目中所有需要覆盖的核心模块及其对应课程:
| 模块 | 源码路径 | 对应课程 | 状态 |
|---|---|---|---|
| Runnable 核心 | runnables/base.ts, types.ts, config.ts | 第 4-5 课 | ✅ |
| RunnableLambda | runnables/base.ts | 第 6 课 | ✅ |
| RunnableParallel + Passthrough | runnables/base.ts, passthrough.ts | 第 7 课 | ✅ |
| RunnableBranch + Router | runnables/branch.ts, router.ts | 第 8 课 | ✅ |
| Runnable Graph | runnables/graph.ts, graph_mermaid.ts | 第 23 课 | ✅ |
| RunnableWithMessageHistory | runnables/history.ts | 第 10 课 | ✅ |
| Runnable Wrappers | runnables/wrappers.ts | 第 35 课 | ✅ |
| Runnable Iter | runnables/iter.ts | 第 35 课 | ✅ |
| Messages | messages/*.ts | 第 9 课 | ✅ |
| Chat History | chat_history.ts | 第 10 课 | ✅ |
| Language Models | language_models/*.ts | 第 11 课 | ✅ |
| Prompts | prompts/*.ts | 第 12 课 | ✅ |
| Prompt Values | prompt_values.ts | 第 12 课 | ✅ |
| Example Selectors | example_selectors/*.ts | 第 13 课 | ✅ |
| Tools | tools/index.ts | 第 14 课 | ✅ |
| Output Parsers | output_parsers/*.ts | 第 15 课 | ✅ |
| Callbacks | callbacks/*.ts | 第 21 课 | ✅ |
| Tracers | tracers/*.ts | 第 22 课 | ✅ |
| Context & Singletons | context.ts, singletons/ | 第 17 课 | ✅ |
| Errors | errors/ | 第 17 课 | ✅ |
| Documents | documents/*.ts | 第 29 课 | ✅ |
| Document Loaders | document_loaders/ | 第 29 课 | ✅ |
| Text Splitters | langchain-textsplitters/ | 第 30 课 | ✅ |
| Embeddings | embeddings.ts | 第 30 课 | ✅ |
| Vector Stores | vectorstores.ts | 第 31 课 | ✅ |
| Retrievers | retrievers/ | 第 31 课 | ✅ |
| Stores | stores.ts | 第 31 课 | ✅ |
| Indexing | indexing/ | 第 29 课 | ✅ |
| Structured Query | structured_query/ | 第 29 课 | ✅ |
| Caches | caches/ | 第 34 课 | ✅ |
| Serialization & Load | load/*.ts | 第 34 课 | ✅ |
| Testing Utils | testing/ | 第 23 课 | ✅ |
| Agent (ReactAgent) | agents/ReactAgent.ts | 第 24 课 | ✅ |
| Agent State & Annotation | agents/state.ts, annotation.ts | 第 25 课 | ✅ |
| Agent Middleware & Nodes | agents/middleware/, nodes/ | 第 26 课 | ✅ |
| Agent Runtime & Utils | agents/runtime.ts, utils.ts | 第 27 课 | ✅ |
| Agent Errors | agents/errors.ts | 第 28 课 | ✅ |
| Provider OpenAI | langchain-openai/ | 第 18 课 | ✅ |
| Provider Anthropic | langchain-anthropic/ | 第 19 课 | ✅ |
| Standard Tests | langchain-standard-tests/ | 第 20 课 | ✅ |
| MCP Adapters | langchain-mcp-adapters/ | 第 33 课 | ✅ |
| Universal ChatModel | langchain/src/chat_models/ | 第 35 课 | ✅ |
| Built-in Tools | langchain/src/tools/ | 第 14 课 | ✅ |
| Hub | langchain/src/hub/ | 第 34 课 | ✅ |
| Storage | langchain/src/storage/ | 第 34 课 | ✅ |
| Build System | internal/build/ | 第 35 课 | ✅ |
| TS Config | internal/tsconfig/ | 第 2 课 | ✅ |
| langchain-classic | langchain-classic/ | 第 36 课 | ✅ |