源码深度学习 · 零基础友好 · 20 天

LangChain 源码学习

20 天 · 每天 30 分钟 · 逐层读懂 LangChain 这套"LLM 应用开发框架"——monorepo 里的 libs/core/langchain_core(一切抽象的地基:Runnable、消息、Prompt、输出解析、工具、回调)、libs/langchain_v1/langchain(新版主包:init_chat_model、create_agent)、libs/text-splitterslibs/partners(各厂商适配)。真源码走读(带真实 file:line)+ 逐行大白话 + 设计取舍 + 边界坑点,0 基础也能跟

00

开篇 · 这是个什么框架

LangChain 是最流行的开源 LLM 应用开发框架(Python)。它把"调大模型做应用"这件事拆成可组合的积木:Prompt 模板负责拼输入、ChatModel 负责统一调几十家模型、输出解析器负责把模型回复变成程序能用的结构、工具/Agent 负责让模型"动手做事"、Retriever/VectorStore 负责 RAG 检索——所有积木都实现同一个接口 Runnable,于是能用一根竖线 | 像搭水管一样串起来(LCEL)。

🎯 一句话:LangChain = 一个统一接口(Runnable)+ 一堆实现了它的积木 + 一个把积木串成管道的语法(LCEL 的 |。你写 chain = prompt | model | parser,然后 chain.invoke({"topic": "猫"})——数据像水一样流过三节管道,出来就是干净的字符串。这 20 天,我们就从这根竖线开始,一层层读进源码。

🔗

Runnable 与 LCEL

runnables/base.py 六千多行:invoke/stream/batch 三件套 + | 组合,全框架的地基。

🤖

模型抽象

BaseChatModel 统一几十家厂商:缓存、流式、回调、限流一处搞定,厂商包只写 _generate

📚

RAG 全家桶

Document / 切分 / Embeddings / VectorStore / Retriever,一条龙抽象。

🛠️

工具与 Agent

@tool 装饰器、bind_tools、create_agent(底层是 LangGraph),让模型能调用外部世界。

包在哪、代码在哪:这是个 monorepo,全部在 libs/ 下——libs/core/langchain_core(核心抽象,pip 包名 langchain-core);libs/langchain_v1/langchain(新版 v1 主包,pip 包名就叫 langchain);libs/langchain/langchain_classic(旧版兼容包 langchain-classic);libs/text-splitters(文本切分);libs/partners/(openai/anthropic/ollama 等厂商适配)。本教程 80% 精力在 langchain_core——它是一切的地基。
01

架构全景(动起来看)

下图那颗发光小球是"一次 chain.invoke() 从进门到吐出结果"的旅程。从上到下:你的应用代码 → 组合层 → 抽象层 → 厂商实现。

L4 · 你的应用  ·  import langchain(libs/langchain_v1)
init_chat_model一行拿模型
create_agent一行拿 Agent
chain.invoke()跑起来
langchain_classic旧代码兼容
L2 · 组合层  ·  langchain_core/runnables/(LCEL)
Runnable统一接口
RunnableSequence串行管道 |
RunnableParallel并行字典
RunnableConfig配置随身包
L3 · 抽象层  ·  langchain_core/ 各模块
prompts提示模板
language_modelsBaseChatModel
output_parsers输出解析
tools / vectorstores工具与检索
L1 · 厂商实现  ·  libs/partners/
langchain-openaiChatOpenAI
langchain-anthropicChatAnthropic
langchain-ollama本地模型
callbacks/tracers回调与追踪

LangChain 的心智模型是"一切皆 Runnable → 用 | 串成 Sequence → invoke 时逐节流过、config 一路随行"——一次最简单的链就是:

prompt字典 → 消息列表 model消息 → AIMessage parserAIMessage → 字符串 拿到干净结果
为什么这么分层? 抽象(core)与实现(partners)分开:你的业务代码只依赖 langchain_core 的接口,换模型厂商只改一行 init_chat_model("...");厂商包只需实现 _generate/_stream 两个钩子,缓存、回调、重试这些"共性脏活"全部由基类兜住。这和你学过的 Dify(ModelInstance 统一门面)、LangGraph(Pregel 引擎与节点分离)是同一种思路。
02

怎么用这份教程

⏱️

每天 30 分钟

一天一个独立页面,跟着"今日小结 + 10 分钟动手 + 明日预告"收尾。

👶

零基础友好

不假设你懂泛型/异步/RAG,术语首次出现都有大白话解释。

📍

真源码 + 行号

关键代码标 文件:行号,逐行走读,可在真源码里跳转对照。

🎨

设计取舍 + 边界

每天讲"为什么这么设计"和"坑在哪",不止是 API 说明。

一条主线:从"项目全景 + 跑通第一个链"→"Runnable 与 LCEL(框架地基)"→"模型/消息/Prompt/输出解析(管道里的四种积木)"→"RAG 数据链路"→"工具与 Agent"→"回调/流式/追踪与收官"。前 5 天(本次已就绪)帮你建立整体地图 + 打穿最核心的 Runnable 和 ChatModel 两个抽象。
S1

阶段 1 · 全景与 LCEL

D01-04 · 分包地图、第一个链、Runnable 管道、一次 invoke 的旅程
01

项目全景与分包

monorepo libs/ 五大包:core / langchain(v1) / classic / text-splitters / partners,谁依赖谁、pip 装的是哪个。

≈30 min · 已就绪 NEW开始学 →
02

环境搭建 + 第一个链

装包、init_chat_model 一行拿模型,跑通最小链 prompt | model | parser,看懂每节管道。

≈30 min · 已就绪 NEW开始学 →
03

Runnable 与 LCEL 管道

runnables/base.py:Runnable 基类、__or__ 为什么能用竖线、RunnableSequence 怎么拼起来。

≈30 min · 已就绪 NEW开始学 →
04

一次 invoke 的完整旅程

RunnableSequence.invoke 逐步执行、RunnableConfig 怎么一路随行、回调树怎么长出来。

≈30 min · 已就绪 NEW开始学 →
S2

阶段 2 · 模型·消息·提示·输出

D05-08 · ChatModel 抽象、消息体系、Prompt 模板、输出解析
05

ChatModel 抽象

language_models/chat_models.py BaseChatModel:invoke→generate→_generate_with_cache 主线,缓存与流式怎么被基类兜住。

≈30 min · 已就绪 NEW开始学 →
06

消息体系

messages/:HumanMessage / AIMessage / ToolMessage、tool_calls、消息块合并。

≈30 min敬请期待
07

Prompt 模板

prompts/:PromptTemplate / ChatPromptTemplate / MessagesPlaceholder / few-shot。

≈30 min敬请期待
08

输出解析与结构化输出

output_parsers/:Str / Json / Pydantic 解析器 + with_structured_output。

≈30 min敬请期待
S3

阶段 3 · 数据与 RAG

D09-12 · Document、文本切分、Embeddings/VectorStore、Retriever 与 RAG 链
09

Document 与加载

documents/ 与 document_loaders/ 抽象:page_content + metadata 的世界。

≈30 min敬请期待
10

文本切分

libs/text-splitters:base.py / character.py / markdown.py,chunk_size 与 overlap 的门道。

≈30 min敬请期待
11

Embeddings 与 VectorStore

embeddings/ 与 vectorstores/ 抽象 + InMemoryVectorStore 真实现。

≈30 min敬请期待
12

Retriever 与 RAG 链

retrievers.py BaseRetriever、as_retriever、把检索问答链组装起来。

≈30 min敬请期待
S4

阶段 4 · 工具与 Agent

D13-16 · Tool 抽象、工具调用闭环、Agent、记忆与对话历史
13

Tool 抽象

core tools/:@tool 装饰器、BaseTool / StructuredTool、args_schema 怎么生成。

≈30 min敬请期待
14

工具调用闭环

bind_tools、AIMessage.tool_calls、ToolMessage 回填,一圈跑完。

≈30 min敬请期待
15

Agent

libs/langchain_v1/langchain/agents:create_agent、ReAct 循环,与 LangGraph 的关系。

≈30 min敬请期待
16

记忆与对话历史

runnables/history.py RunnableWithMessageHistory、chat_history.py。

≈30 min敬请期待
S5

阶段 5 · 进阶与收官

D17-20 · 回调与流式、LCEL 高级组合、追踪与可观测、收官地图
17

回调与流式

callbacks/:CallbackManager、astream / astream_events 事件流。

≈30 min敬请期待
18

LCEL 高级组合

passthrough / branch / fallbacks / retry / configurable / router,组合子全家桶。

≈30 min敬请期待
19

追踪与可观测

tracers/:LangSmith 追踪原理、Run 树怎么长出来。

≈30 min敬请期待
20

收官 · 知识地图串讲

全 20 天地图 + 生态关系:core/classic/v1/partners 与 LangGraph/LangSmith + 学习建议。

≈30 min · 已就绪开始学 →

🚀 前 5 天已就绪!先建立整体地图(D01-02),再打穿框架地基 Runnable/LCEL(D03-04)和模型抽象(D05)。准备好了就从 Day 01 · 项目全景与分包 开始。