LangChain 设计与实现
深入 LangChain 1.0 的源码与架构。
prompt | model | parser 这三个竖线,是 LangChain 里最像魔法的一行。它凭什么能同步调、异步调、流式调、批量调,还自动带上重试、回调和配置?
答案是一个协议:Runnable。整个 LangChain 就是"把所有东西都变成 Runnable,然后让它们能用 | 拼起来"。本专栏以 langchain-core 1.2.26 / langchain-classic 1.0.3 源码快照为解剖对象,从这个协议开始往下拆。
flowchart TB
subgraph R [Runnable 协议 · 一切的地基]
direction LR
SEQ[RunnableSequence<br/>管道骨架] --- PAR[RunnableParallel<br/>分叉汇聚]
PAR --- BR[RunnableBranch<br/>条件分支]
BR --- FB[WithFallbacks<br/>优雅降级]
end
PT[PromptTemplate] --> R
R --> LM[BaseChatModel<br/>invoke / stream / bind_tools]
LM --> OP[OutputParser<br/>Str / Json / 结构化]
LM -.工具.-> TL["BaseTool<br/>@tool · StructuredTool"]
R -.每一步都穿过.-> CB[Callbacks / Tracer<br/>astream_events]
DOC[Documents] --> RET[Retrievers / VectorStore] --> R
为什么值得读源码。 LangChain 的文档教你怎么拼,但拼出来的东西为什么能流式、RunnableConfig 在嵌套调用里怎么传下去、with_structured_output 到底做了什么、回调是怎么穿过每一层的 —— 这些只有源码会告诉你。而它们恰恰是出问题时你必须知道的东西。
读完你能做到什么
- 手写一个 Runnable,并让它无缝接进任何管道。
|操作符的实现、六个组合原语各自的职责、RunnableConfig的完整生命周期,以及 fallback 的降级路径(第3章 Runnable 与 LCEL)。 - 说清一次
model.invoke()的完整链路。 从BaseLanguageModel到BaseChatModel,同步与异步两条路径、_generate这个扩展点、token 计数与UsageMetadata从哪来(第5章 语言模型)。 - 驾驭流式输出。
MessageChunk的增量合并规则、stream的实现,以及astream_events/astream_log这两个调试利器(第4章 消息体系、第12章 回调与追踪)。 - 写出模型第一次就能调对的工具。
@tool装饰器背后的create_schema_from_function、Tool 与 StructuredTool 的分野、InjectedToolArg运行时注入、把 Runnable 和 Retriever 直接变成工具(第8章 工具系统)。 - 搭一条可控的 RAG 链路。 Document 抽象、检索器接口、
create_history_aware_retriever这类历史感知检索的实现(第9章 文档、第10章 检索器)。 - 把老代码迁到 LCEL。 Chain 基类为什么是"连接两个时代的桥梁"、SequentialChain / RouterChain 对应到 LCEL 的哪个原语(第11章 Chain)。
- 理解 Agent 的执行循环。 规划、工具调用、结果回填,以及 tool-calling agent 与传统 ReAct agent 的差别(第14章 Agent、第15章 工具调用 Agent)。
这个专栏的讲法
锚定版本,不讲"大概"。 所有分析都基于 langchain-core 1.2.26 / langchain-classic 1.0.3 这个确定的快照 —— LangChain 迭代快,不锚定版本的源码分析半年后就是误导。
每章末尾是「设计决策分析」。 为什么消息要拆成 Content Blocks、为什么回调用 Mixin 架构、为什么工具有两套范式 —— 讲取舍,不只讲实现。
覆盖到边界。 序列化机制、partner 包的组织方式(第16章 序列化、第17章 生态)—— 你要写自己的集成时会用到这两章。
适合谁读
- 每天在用 LangChain、但一出问题就只能试的开发者。 这个专栏把"试"换成"知道"。
- 要写 LangChain 集成 / 插件的作者。 序列化、partner 包组织、Runnable 协议是必修。
- RAG 或 Agent 系统的架构师。 你需要知道这套抽象的边界在哪,才能判断哪里该绕开它。
不适合:找 LangChain 入门教程或 API 速查的读者 —— 官方文档更合适。这里从第 3 章开始就在读源码。
目录
第一部分:开篇
第二部分:核心抽象
第三部分:模型与提示
第四部分:工具与检索
第五部分:组合与编排
第六部分:Agent 系统
第七部分:生产与进阶
源码版本
本专栏基于 langchain-core 1.2.26 与 langchain-classic 1.0.3 源码分析。仓库为 monorepo,
langchain-core 的每个发布版都有对应的 git tag,checkout 到本专栏的基准快照即可逐行对照:
git clone https://github.com/langchain-ai/langchain.git
cd langchain
git checkout langchain-core==1.2.26 # 对应 commit 0a1d290a,2026-04-03
该快照下三个包的对应关系(libs/ 目录名与包名并不一一对应,容易踩坑):
| 目录 | 包名 | 该快照版本 | 本专栏用量 |
|---|---|---|---|
libs/core/langchain_core/ |
langchain-core |
1.2.26 | 主要解剖对象 |
libs/langchain/langchain_classic/ |
langchain-classic |
1.0.3 | Chain / Memory / 经典 Agent |
libs/langchain_v1/langchain/ |
langchain |
1.2.15 | 少量引用 |
别把 langchain-classic 1.0.3 当成 langchain 1.0.3
1.0 拆包后,0.x 时代的 Chain、Memory、AgentExecutor 等被整体迁入独立发行的
langchain-classic。本专栏讲这些经典组件时引用的 1.0.3 是 langchain-classic 的版本号
(2026-03-13 发布);PyPI 上的 langchain 1.0.3 是 2025-10-29 发布的另一个包,不要混淆。
核心代码在 libs/core/ 和 libs/langchain/ 目录下。
版权声明
本专栏内容为 杨艺韬 版权所有,保留一切权利。未经书面许可,不得全文或大段转载、改编、翻译,或用于任何商业用途(含以本专栏内容训练模型、生成衍生课程或商品)。
欢迎分享本专栏的链接。引用少量内容用于评论、教学或研究时,请署名 杨艺韬 并附上原文链接。