9768 字
49 分钟
LangChain & LangGraph 框架源码学习路线

从 Agent 范式到 LangChain / LangGraph 框架源码:学习路线#

适用对象:已经理解 ReAct、Plan-and-Execute、Reflection、Workflow、Router、Agentic RAG 等 Agent 范式,并且已经完成一个基于 LangChain / LangGraph 的旅行规划助手,希望进一步从“会用框架”升级为“理解框架源码与设计思想”的学习者。
核心目标:以已完成的旅行规划助手为样本工程,建立“Agent 范式 → 框架 API → 执行机制 → 源码结构 → 工程判断”的完整学习链路。
学习原则:不再以堆功能为主,而是通过代码讲解、运行追踪、源码反查和框架设计复盘,深入掌握 LangChain 与 LangGraph 的核心抽象。

当前依赖基线: langchain==1.3.11langchain-core==1.4.8langgraph==1.2.7。后续文章默认使用写作时的最新正式版,并在文章开头固定具体版本与 commit。

篇次主题状态规范文件
1Runnable已完成并按新规范升级01-langchain-runnable-source-deep-dive.md
2Prompt / Message / ChatModel已完成并按新规范升级02_langchain_core_prompt_message_chatmodel_source_deep_dive.md
3Structured Output已完成并按新规范升级03_langchain_core_structured_output_source_deep_dive.md
4Tool Calling已完成并按新规范升级04_langchain_core_tool_calling_source_deep_dive.md
5create_agent / ReAct已完成并按新规范升级05_langchain_create_agent_react_source_deep_dive.md
6–13LangGraph 核心运行时已完成并发布langgraph-*-deep-dive.md
14–19生产级 Agent 能力与运行时扩展已完成并发布14_*19_* 源码解剖文章
20–21验证闭环与生产部署已完成并发布20_*21_* 源码解剖文章

1. 学习定位#

你当前已经完成了一个基于 LangChain 和 LangGraph 的旅行规划助手,因此接下来的目标不是继续改造项目,而是把这个项目当成一个“框架学习样本工程”。

这份路线的重点不是:

再做一个旅行规划助手
再加几个工具
再接几个 API
再写几个 Prompt

而是:

看到一段 Agent 代码,知道它对应哪个范式;
看到一个 LangChain API,知道它背后是哪个核心抽象;
看到一个 LangGraph 节点,知道它如何读写 state;
看到一次 Agent 执行,知道 invoke / stream / tool_call / checkpoint / interrupt 发生在哪里;
看到源码,知道应该从哪个类、哪个函数、哪个包开始读。

最终目标是达到:

范式层:知道为什么这样设计;
框架层:知道用哪个 API 实现;
执行层:知道运行时发生什么;
源码层:知道底层为什么能这样运行;
工程层:知道真实业务里如何取舍。

2. 学习总主线#

2.1 从范式语言到框架语言#

范式语言框架语言源码语言你要掌握的问题
普通 LLM Chainprompt | model | parserRunnableSequenceinvokestream为什么链式组合可以运行
Tool-use@toolStructuredToolToolNodeBaseToolargs_schemaToolMessage函数如何变成模型可调用工具
ReActcreate_agent、model-tool loopAIMessage.tool_calls、tools node、agent graph模型与工具循环如何执行
WorkflowStateGraphadd_nodeadd_edgeCompiledStateGraph、state update固定流程如何被图执行
Routeradd_conditional_edgespath function、branch mapping意图路由如何决定下一节点
Plan-and-Executeplanner node、executor subgraphstructured plan、subgraph、checkpoint计划如何转成可执行流程
Reflectionevaluator node、revise node、loop edgeconditional loop、max iteration反思如何成为有限循环
Agentic RAGretriever node、query rewrite nodeRetriever、Document、Runnable检索如何成为 Agent 节点
Memorycheckpointer、store、thread_idcheckpoint、StateSnapshot、Store为什么能保存执行状态和用户偏好
Guardrailsmiddleware、policy、retrymiddleware hooks、tool retry、model wrapper安全、成本和工具失败如何被控制
Multi-Agentsupervisor、subagent、handoffagent-as-tool、Command、subgraph多 Agent 如何交接控制权和状态
Functional Workflow@entrypoint@taskfunctional runtime、task result、checkpoint何时用函数式 API 替代显式图
Debug Replaytime travel、update_statecheckpoint history、StateSnapshot、fork如何从历史状态回放和修正执行
Human-in-the-loopinterrupt()Command(resume=...)interrupt、resume、checkpoint人工确认如何暂停/恢复图
Observabilitystream、events、LangSmith tracecallback、event stream、metadata如何观察每一步执行

3. 最新框架趋势校准#

3.1 LangChain 的定位变化#

LangChain v1 之后更强调“Agent 工程基础组件”和“可组合运行单元”,核心包括:

ChatModel
Prompt
Message
Tool
OutputParser
Runnable
Retriever
Middleware
create_agent

需要重点理解:

LangChain 不只是 Chain;
LangChain Core 的关键是 Runnable 抽象;
LangChain Agent 的关键是基于 LangGraph 的 agent runtime;
create_agent 成为构建 Agent 的标准入口之一;
middleware 成为模型调用、工具调用、上下文处理、安全控制的重要扩展点。

3.2 LangGraph 的定位变化#

LangGraph 更像是 Agent 的底层编排运行时,核心包括:

StateGraph
CompiledStateGraph
Node
Edge
Conditional Edge
Reducer
Checkpoint
Store
Thread
Interrupt
Command
Subgraph
Functional API
Time Travel
Durable Execution
Pregel Runtime

需要重点理解:

LangGraph 不是普通流程图;
它是有状态、可恢复、可中断、可回放的 Agent / Workflow 执行框架;
生产级 Agent 的很多能力,如 memory、HITL、time travel、durable execution,都建立在 checkpoint 和 runtime 机制之上。

3.3 当前学习重点#

不需要平均学习所有 API,而应该优先学习以下核心:

1. Runnable
2. ChatPromptTemplate / Messages
3. BaseChatModel / AIMessage / ToolMessage
4. @tool / StructuredTool
5. create_agent
6. StateGraph
7. add_node / add_edge / add_conditional_edges
8. Reducer / Annotated state
9. Checkpointer / thread_id
10. interrupt / Command
11. stream / events / tracing
12. subgraph / multi-agent graph

4. 学习方法:四层拆解法#

每学一个框架点,都按四层拆解。

4.1 范式层#

先问:

这个功能解决哪个 Agent 范式问题?

例如:

add_conditional_edges 解决 Router / Workflow 分支问题;
checkpoint 解决长期状态、恢复执行和 HITL 问题;
@tool 解决模型连接外部能力的问题;
create_agent 解决 ReAct 式模型-工具循环问题。

4.2 代码层#

再问:

这个范式在 LangChain / LangGraph 中用哪个 API 表达?

例如:

Tool-use → @tool / StructuredTool
Workflow → StateGraph
Router → add_conditional_edges
HITL → interrupt + Command
Memory → checkpointer + thread_id

4.3 执行层#

继续问:

运行时发生了什么?

例如:

graph.invoke(input)
→ 初始化 state
→ 执行 START 指向的 node
→ node 返回 partial update
→ reducer 合并 state
→ edge 决定下一个节点
→ checkpoint 保存状态
→ 直到 END

4.4 源码层#

最后问:

源码为什么这样设计?

例如:

为什么 Runnable 要统一 invoke / stream / batch?
为什么 StateGraph node 返回 partial state?
为什么 checkpoint 要绑定 thread_id?
为什么 interrupt 必须依赖 checkpointer?
为什么 ToolMessage 要重新放回 messages?

5. 总体学习节奏#

建议周期:6 到 8 周。

周次学习主题重点产出
第 1 周LangChain Core:Runnable / Prompt / Message / Model3 篇源码笔记 + 最小代码实验
第 2 周Tool Calling 与 create_agent2 篇源码笔记 + ReAct 执行链路图
第 3 周LangGraph 基础:StateGraph / Edge / Router / Reducer3 篇源码笔记 + 旅行助手 state 流转图
第 4 周LangGraph 进阶:Checkpoint / Interrupt / Subgraph / Streaming4 篇源码笔记 + checkpoint 时间线
第 5 周Memory、Middleware 与 Agentic RAG3 篇生产级 Agent 能力源码笔记,已补齐为第 14–16 篇
第 6 周Multi-Agent、Functional API 与 Time Travel3 篇运行时扩展与调试回放源码笔记,已补齐为第 17–19 篇
第 7 周旅行规划助手全链路框架复盘1 篇综合复盘 + API 到源码映射表
第 8 周框架设计复盘与工程判断框架误区总结 + 面试表达稿 + 后续学习清单

第一部分:LangChain Core 源码学习路线#

6. 第 1 篇:Runnable 源码解剖#

6.1 学习目标#

掌握 LangChain 中最核心的统一执行抽象:Runnable

你需要理解:

为什么 prompt | model | parser 可以组合;
为什么每个组件都能 invoke / stream / batch;
为什么普通函数可以变成 RunnableLambda;
为什么 LangChain 能把 Prompt、Model、Parser、Retriever、Tool 放在同一套执行协议下。

6.2 范式映射#

普通 LLM Chain
→ LangChain RunnableSequence

普通链路:

User Input
→ Prompt
→ Model
→ Parser
→ Output

框架表达:

chain = prompt | model | parser

6.3 最小代码#

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain.chat_models import init_chat_model
model = init_chat_model("openai:gpt-4.1-mini")
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个旅行规划助手。"),
("user", "请为 {destination} 规划 {days} 天行程。")
])
chain = prompt | model | StrOutputParser()
result = chain.invoke({
"destination": "东京",
"days": 5
})
print(result)

6.4 执行流程#

chain.invoke(input)
ChatPromptTemplate.invoke(input)
生成 PromptValue / messages
ChatModel.invoke(messages)
返回 AIMessage
StrOutputParser.invoke(AIMessage)
返回字符串

6.5 源码阅读入口#

langchain_core/runnables/base.py
langchain_core/runnables/config.py
langchain_core/runnables/utils.py
langchain_core/runnables/passthrough.py
langchain_core/runnables/branch.py

重点类:

Runnable
RunnableSequence
RunnableParallel
RunnableLambda
RunnableConfig

6.6 源码阅读问题#

1. Runnable 的核心抽象方法有哪些?
2. invoke、ainvoke、stream、batch 的默认实现关系是什么?
3. `|` 运算符如何构造 RunnableSequence?
4. RunnableConfig 如何向下传递?
5. callbacks、tags、metadata 如何进入执行链?
6. RunnableSequence 如何逐个调用子 Runnable?
7. RunnableParallel 如何并行调用多个子 Runnable?

6.7 实践任务#

在旅行规划助手中找到所有类似:

prompt | model
prompt | model | parser

的代码,并标注:

这是 RunnableSequence;
输入是什么;
中间输出是什么;
最终输出是什么;
是否支持 stream;
是否能加 with_retry / with_config。

6.8 产出#

01-langchain-runnable-source-deep-dive.md

7. 第 2 篇:Prompt / Message / ChatModel 源码解剖#

7.1 学习目标#

把对 Prompt 的理解从“字符串模板”升级为“结构化消息构造器”。

你需要掌握:

PromptTemplate
ChatPromptTemplate
MessagesPlaceholder
SystemMessage
HumanMessage
AIMessage
ToolMessage
BaseChatModel

7.2 范式映射#

Context Engineering / Prompt Engineering
→ ChatPromptTemplate + Messages + ChatModel

7.3 最小代码#

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
("system", "你是旅行规划助手,需要根据用户偏好规划行程。"),
MessagesPlaceholder("history"),
("user", "{input}")
])
messages = prompt.invoke({
"history": [],
"input": "我想去大阪玩 4 天,喜欢美食和城市漫步"
})
print(messages)

7.4 执行流程#

输入变量
ChatPromptTemplate 格式化
PromptValue
messages list
ChatModel 接收 messages
返回 AIMessage

7.5 源码阅读入口#

langchain_core/prompts/
langchain_core/messages/
langchain_core/language_models/chat_models.py

重点类:

BaseMessage
HumanMessage
SystemMessage
AIMessage
ToolMessage
BaseChatModel
ChatPromptTemplate
MessagesPlaceholder

7.6 源码阅读问题#

1. ChatPromptTemplate.invoke 返回的对象是什么?
2. PromptValue 如何转换为 messages?
3. AIMessage 为什么能携带 tool_calls?
4. response_metadata 和 usage_metadata 在哪里保存?
5. BaseChatModel.invoke 和 _generate 的关系是什么?
6. 不同模型供应商的返回值如何统一为 AIMessage?

7.7 实践任务#

对旅行规划助手中的 Prompt 进行拆解:

Prompt 名称输入变量输出类型使用场景是否进入 Agent State
需求解析 Promptuser_requestintent/slotsRouter
规划 Promptdestination/preferencesplan_stepsPlanner
搜索 Query Promptplan/current_stepsearch_queryTool-use
最终回复 Promptfull_statefinal_answerResponse

7.8 产出#

02_langchain_core_prompt_message_chatmodel_source_deep_dive.md

8. 第 3 篇:OutputParser 与结构化输出#

8.1 学习目标#

掌握模型输出从自然语言变成结构化对象的过程。

重点理解:

StrOutputParser
JsonOutputParser
PydanticOutputParser
with_structured_output
schema validation
parser failure
retry / repair

8.2 范式映射#

意图识别 / 槽位抽取 / 计划生成 / 责任判断
→ 结构化输出

8.3 最小代码#

from pydantic import BaseModel, Field
from langchain.chat_models import init_chat_model
class TravelIntent(BaseModel):
destination: str | None = Field(description="目的地")
days: int | None = Field(description="旅行天数")
preferences: list[str] = Field(description="用户偏好")
need_clarification: bool = Field(description="是否需要追问")
model = init_chat_model("openai:gpt-4.1-mini")
structured_model = model.with_structured_output(TravelIntent)
result = structured_model.invoke(
"我想去东京玩 5 天,喜欢美食和城市漫步"
)
print(result)

8.4 执行流程#

Pydantic schema
转换为模型可理解的结构化输出约束
模型生成结构化结果
框架解析并校验
返回 Pydantic 对象或 dict

8.5 源码阅读入口#

langchain_core/output_parsers/
langchain_core/language_models/chat_models.py
langchain_core/utils/function_calling.py

8.6 源码阅读问题#

1. with_structured_output 底层如何绑定 schema?
2. Pydantic schema 如何转换为 JSON schema?
3. 结构化输出和 tool calling 有什么关系?
4. 解析失败时异常在哪里抛出?
5. parser 应该放在 chain 里,还是依赖模型原生 structured output?

8.7 实践任务#

为旅行规划助手中的关键节点设计结构化输出:

IntentResult
TravelPlan
SearchQuery
ReflectionResult
FinalResponse

每个结构化输出都要写:

字段
含义
是否必填
失败样例
校验规则

8.8 产出#

03_langchain_core_structured_output_source_deep_dive.md

第二部分:Tool-use 与 Agent Loop#

9. 第 4 篇:Tool Calling 源码解剖#

9.1 学习目标#

理解普通 Python 函数如何变成模型可调用工具。

你需要掌握:

@tool
StructuredTool
BaseTool
args_schema
tool name
tool description
tool call
ToolMessage
tool error handling

9.2 范式映射#

Tool-use Agent
→ LangChain Tool / StructuredTool

9.3 最小代码#

from langchain.tools import tool
@tool
def search_attractions(city: str, preference: str) -> str:
"""Search attractions in a city based on user preference."""
return f"{city} attractions for {preference}"
print(search_attractions.name)
print(search_attractions.description)
print(search_attractions.args)

9.4 执行流程#

Python function
@tool 包装
BaseTool / StructuredTool
生成 name / description / args_schema
绑定到模型
模型输出 tool_calls
工具执行层调用真实函数
结果包装为 ToolMessage
重新放回 messages

9.5 源码阅读入口#

langchain_core/tools/
langchain/tools/
langchain_core/messages/tool.py

重点类:

BaseTool
StructuredTool
ToolException
ToolMessage

9.6 源码阅读问题#

1. @tool 装饰器如何读取函数名、参数和 docstring?
2. args_schema 如何从函数签名生成?
3. Tool.invoke 和普通函数调用有什么区别?
4. ToolMessage 如何保存 tool_call_id?
5. 工具异常如何被捕获并返回给模型?
6. 工具描述如何影响模型选择?

9.7 实践任务#

对旅行规划助手中的工具建立工具表:

工具名输入 schema输出 schema是否有副作用是否需要确认所属范式
search_destinationcity/querydocumentsTool-use / RAG
search_weathercity/dateweatherTool-use
search_transportfrom/to/dateroutesTool-use
save_planplan/user_idsaved_statusHITL / Tool-use

9.8 产出#

04_langchain_core_tool_calling_source_deep_dive.md

10. 第 5 篇:create_agent 与 ReAct 执行机制#

10.1 学习目标#

理解 LangChain Agent 如何通过模型-工具循环实现 ReAct 类行为。

需要掌握:

create_agent
model node
tools node
middleware
tool loop
stop condition
iteration limit
structured response

10.2 范式映射#

ReAct
→ model call
→ tool call
→ ToolMessage
→ model call
→ final answer

现代框架不一定显式暴露 Thought,生产中更推荐观察结构化 trace:

AIMessage
tool_calls
ToolMessage
final AIMessage

10.3 最小代码#

from langchain.agents import create_agent
from langchain.tools import tool
@tool
def search_city_info(query: str) -> str:
"""Search city information for travel planning."""
return f"Search result for {query}"
agent = create_agent(
model="openai:gpt-4.1-mini",
tools=[search_city_info],
system_prompt="你是一个旅行规划助手。"
)
result = agent.invoke({
"messages": [
{"role": "user", "content": "帮我规划东京 5 天行程,需要查一下热门景点"}
]
})
print(result)

10.4 执行流程#

用户 messages
model node
AIMessage 是否包含 tool_calls?
如果有:tools node 执行工具
ToolMessage 加入 messages
回到 model node
直到模型输出 final answer 或达到停止条件

10.5 源码阅读入口#

langchain/agents/
langchain/agents/factory.py
langgraph/prebuilt/
langchain_core/messages/
langchain_core/tools/

10.6 源码阅读问题#

1. create_agent 返回的是什么对象?
2. 它内部是否构建了 LangGraph graph?
3. model node 和 tools node 如何连接?
4. tool_calls 如何被识别?
5. 工具执行结果如何重新进入 messages?
6. middleware 在模型调用前后能做什么?
7. stop condition 在哪里判断?

10.7 实践任务#

在旅行规划助手中选一次带工具调用的请求,记录完整 ReAct-like trace:

轮次模型输出是否有 tool_calls调用工具工具结果下一步
1需要查询景点search_attractions返回候选景点继续规划
2需要查询天气search_weather返回天气调整行程
3输出最终计划结束

10.8 产出#

05_langchain_create_agent_react_source_deep_dive.md

10.9 后续篇章的统一源码主线#

从第 6 篇开始,每篇仍保留本路线给出的学习目标和实验任务,但正式文章必须围绕四条源码线组织核心正文:

  1. 构建期: 用户声明如何被校验、归一化,并组装成可执行对象;
  2. 运行时主链: 从公开入口进入哪些核心方法,对象与状态如何流转;
  3. 关键分支: 同步/异步、流式、异常、重试和终止条件如何分流;
  4. 扩展协作: 与 LangChain、LangGraph、middleware、checkpoint、store 等机制如何组合。

四条线分别落入统一框架的第 7–10 章,并占全文 65%–75%。这样路线负责回答“学什么、按什么顺序学”,文章框架负责回答“每篇怎样证明自己真的读懂了源码”。


第三部分:LangGraph Workflow 与状态图#

11. 第 6 篇:StateGraph 源码解剖#

11.1 学习目标#

理解 LangGraph 如何用图结构承载 Workflow Agent。

重点掌握:

StateGraph
State schema
add_node
add_edge
START
END
compile
CompiledStateGraph
partial state update

11.2 范式映射#

Workflow Agent
→ StateGraph + Node + Edge + State

11.3 最小代码#

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
class TravelState(TypedDict):
user_request: str
destination: str | None
days: int | None
plan: str | None
def parse_request(state: TravelState):
return {
"destination": "东京",
"days": 5
}
def generate_plan(state: TravelState):
return {
"plan": f"为 {state['destination']} 生成 {state['days']} 天旅行计划"
}
builder = StateGraph(TravelState)
builder.add_node("parse_request", parse_request)
builder.add_node("generate_plan", generate_plan)
builder.add_edge(START, "parse_request")
builder.add_edge("parse_request", "generate_plan")
builder.add_edge("generate_plan", END)
graph = builder.compile()
result = graph.invoke({
"user_request": "我想去东京玩 5 天",
"destination": None,
"days": None,
"plan": None
})
print(result)

11.4 执行流程#

StateGraph 构建阶段
注册节点
注册边
compile 生成可执行图
invoke 初始化 state
按边执行节点
节点返回 partial update
合并 state
到达 END

11.5 源码阅读入口#

langgraph/graph/state.py
langgraph/graph/graph.py
langgraph/pregel/

重点类:

StateGraph
CompiledStateGraph
Pregel

11.6 源码阅读问题#

1. StateGraph 为什么是 builder,而不是执行器?
2. add_node 如何保存节点函数?
3. add_edge 如何保存图结构?
4. compile 做了哪些校验?
5. CompiledStateGraph 如何实现 Runnable?
6. node 返回 partial update 后如何合并到 state?

11.7 实践任务#

为旅行规划助手画出真实 StateGraph:

START
→ parse_user_request
→ route_by_intent
→ generate_plan
→ search_tools
→ optimize_plan
→ final_response
→ END

每个节点标注:

输入 state
输出 partial update
是否调用 LLM
是否调用 tool
是否是路由节点
是否可能失败

11.8 产出#

06_langgraph_stategraph_source_deep_dive.md

12. 第 7 篇:Conditional Edge 与 Router#

12.1 学习目标#

理解意图路由、状态路由、错误路由如何在 LangGraph 中落地。

12.2 范式映射#

Router Agent / Workflow Branch
→ add_conditional_edges

12.3 最小代码#

from typing_extensions import TypedDict, Literal
from langgraph.graph import StateGraph, START, END
class TravelState(TypedDict):
user_request: str
intent: str | None
result: str | None
def classify_intent(state: TravelState):
text = state["user_request"]
if "预算" in text:
intent = "budget_planning"
elif "景点" in text:
intent = "attraction_planning"
else:
intent = "general_planning"
return {"intent": intent}
def route_by_intent(state: TravelState) -> Literal[
"budget_node",
"attraction_node",
"general_node"
]:
if state["intent"] == "budget_planning":
return "budget_node"
if state["intent"] == "attraction_planning":
return "attraction_node"
return "general_node"

12.4 执行流程#

classify_intent 节点执行
state.intent 被更新
route_by_intent(state)
返回下一个节点名
LangGraph 进入对应节点

12.5 源码阅读入口#

langgraph/graph/state.py
langgraph/graph/branch.py

12.6 源码阅读问题#

1. add_conditional_edges 如何注册 path function?
2. path function 的返回值可以是什么?
3. 返回 END 时如何终止?
4. 返回多个节点时如何并行?
5. mapping 参数有什么作用?
6. Literal 类型提示对可视化和校验有什么帮助?

12.7 实践任务#

给旅行规划助手补一张路由表:

路由类型判断依据路由函数目标节点风险
意图路由intentroute_by_intentplan/search/clarify意图误判
信息缺失路由missing_slotsroute_missing_infoask_user/planner追问过多
工具失败路由tool_errorroute_errorretry/fallback死循环
质量检查路由scoreroute_reflectionrevise/final过度反思

12.8 产出#

07_langgraph_conditional_edge_router_source_deep_dive_v2.md

13. 第 8 篇:Reducer 与并行状态合并#

13.1 学习目标#

理解为什么 LangGraph 的 state 不只是普通字典,而是有合并规则的状态模型。

13.2 范式映射#

并行检索 / 多 Agent 协作 / 多工具结果聚合
→ Reducer

13.3 最小代码#

from typing import Annotated
from operator import add
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
class TravelState(TypedDict):
user_request: str
research_notes: Annotated[list[str], add]
def search_food(state: TravelState):
return {"research_notes": ["推荐美食:寿司、拉面、居酒屋"]}
def search_attractions(state: TravelState):
return {"research_notes": ["推荐景点:浅草寺、涩谷、上野公园"]}

13.4 执行流程#

START 同时触发 search_food 和 search_attractions
两个节点都写 research_notes
LangGraph 根据 Annotated[list, add] 合并
merge_plan 读取合并后的 research_notes

13.5 源码阅读入口#

langgraph/graph/state.py
langgraph/channels/
langgraph/pregel/

13.6 源码阅读问题#

1. State schema 如何解析 Annotated?
2. Reducer 是在什么时候被调用的?
3. 多节点写同一个 key 时如何判断是否冲突?
4. 覆盖式更新和追加式更新有什么区别?
5. messages 为什么通常需要特殊 reducer?

13.7 实践任务#

检查旅行规划助手中哪些字段适合覆盖,哪些适合追加:

State 字段更新方式是否需要 reducer原因
destination覆盖单一目的地
preferences追加/覆盖视场景用户可能补充偏好
search_results追加多工具结果
messages追加对话历史
final_plan覆盖最终版本

13.8 产出#

08_langgraph_reducer_parallel_state_source_deep_dive.md

第四部分:计划、反思、记忆与人机协作#

14. 第 9 篇:Plan-and-Execute 在 LangGraph 中的实现#

14.1 学习目标#

理解 Planner Node、Executor Node、Subgraph 如何表达 Plan-and-Execute。

14.2 范式映射#

Plan-and-Execute
→ planner node
→ plan validator
→ executor node / subgraph
→ step verifier
→ replan

14.3 推荐实现结构#

START
→ parse_request
→ planner_node
→ validate_plan
→ execute_step
→ check_step_result
→ route_next_step
├── continue_execute
├── replan
└── final_response

14.4 最小代码骨架#

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
class PlanStep(TypedDict):
step_id: int
task: str
status: str
class TravelState(TypedDict):
user_request: str
plan_steps: list[PlanStep]
current_step_index: int
final_answer: str | None
def planner_node(state: TravelState):
return {
"plan_steps": [
{"step_id": 1, "task": "确认目的地和天数", "status": "pending"},
{"step_id": 2, "task": "查询景点和交通信息", "status": "pending"},
{"step_id": 3, "task": "生成每日行程", "status": "pending"},
],
"current_step_index": 0
}
def route_next_step(state: TravelState):
if state["current_step_index"] >= len(state["plan_steps"]):
return "final_response"
return "execute_step"

14.5 源码阅读入口#

langgraph/graph/state.py
langgraph/graph/branch.py
langgraph/pregel/

14.6 源码阅读问题#

1. 计划列表应该存在 state 的哪个字段?
2. current_step_index 如何控制执行进度?
3. 每一步执行结果如何写回 state?
4. replan 是重新覆盖计划,还是追加修复步骤?
5. executor 应该直接调用工具,还是进入子图?

14.7 实践任务#

对旅行规划助手的规划链路做一次标注:

Planner 输出了什么?
Executor 每一步怎么选?
工具结果如何影响下一步?
什么时候需要 replan?
什么时候直接 final?

14.8 产出#

09_langgraph_plan_execute_subgraph_source_deep_dive.md

15. 第 10 篇:Reflection / Evaluator-Optimizer 在 LangGraph 中的实现#

15.1 学习目标#

理解 Reflection 如何从“让模型再想想”变成可控的评价-修改循环。

15.2 范式映射#

Reflection
→ generator node
→ evaluator node
→ revise node
→ conditional loop

15.3 推荐状态字段#

class TravelState(TypedDict):
draft_plan: str | None
critique: str | None
quality_score: float | None
revision_count: int
final_plan: str | None

15.4 推荐流程#

generate_draft
→ evaluate_draft
→ route_by_score
├── revise_draft
└── final_response
→ revise_draft
→ evaluate_draft

15.5 最小代码骨架#

MAX_REVISION = 2
def route_by_score(state):
if state["quality_score"] >= 0.8:
return "final_response"
if state["revision_count"] >= MAX_REVISION:
return "final_response"
return "revise_draft"

15.6 源码阅读入口#

langgraph/graph/branch.py
langgraph/pregel/

15.7 源码阅读问题#

1. 反思循环如何避免无限执行?
2. revision_count 应该如何更新?
3. evaluator 输出应该结构化吗?
4. evaluator 和 generator 是否应该用不同模型?
5. 高风险任务中 Reflection 能不能替代 Policy / Verifier?

15.8 工程注意事项#

Reflection 适合质量优化,不适合替代规则校验;
必须设置 max_revision_count;
必须有明确评价指标;
如果新版本更差,需要保留旧版本或回滚;
高风险动作不能由 Reflection 自动放行。

15.9 产出#

10_langgraph_reflection_loop_source_deep_dive.md

16. 第 11 篇:Checkpoint / Thread / Durable Execution#

16.1 学习目标#

理解 LangGraph 生产级能力的核心:状态持久化与可恢复执行。

16.2 范式映射#

Memory / Long-running Agent / Durable Workflow / HITL
→ checkpoint + thread_id

16.3 最小代码#

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
class TravelState(TypedDict):
user_request: str
plan: str | None
def plan_node(state: TravelState):
return {"plan": "生成旅行计划草稿"}
builder = StateGraph(TravelState)
builder.add_node("plan_node", plan_node)
builder.add_edge(START, "plan_node")
builder.add_edge("plan_node", END)
checkpointer = InMemorySaver()
graph = builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "travel-thread-001"}}
graph.invoke({"user_request": "东京 5 天旅行", "plan": None}, config=config)
latest_state = graph.get_state(config)
history = list(graph.get_state_history(config))

16.4 执行流程#

graph.invoke(input, config)
根据 thread_id 找到执行线程
每个 super-step 后保存 checkpoint
get_state 读取最新状态
get_state_history 读取历史状态

16.5 源码阅读入口#

langgraph/checkpoint/
langgraph/pregel/
langgraph/types.py

重点概念:

thread_id
checkpoint
StateSnapshot
super-step
writes
next
metadata

16.6 源码阅读问题#

1. checkpoint 保存了哪些信息?
2. thread_id 如何区分不同会话?
3. get_state 和 get_state_history 从哪里读数据?
4. super-step 的边界在哪里?
5. checkpoint 如何支持 time travel?
6. checkpoint 如何支持故障恢复?

16.7 实践任务#

对旅行规划助手跑一次带 thread_id 的请求,记录:

时间点节点state 变化checkpoint 是否产生备注
T1parse_request写入 destination/days初始化
T2planner_node写入 plan_steps计划生成
T3search_node写入 search_results工具结果
T4final_node写入 final_plan结束

16.8 产出#

11_langgraph_checkpoint_thread_durable_execution_source_deep_dive.md

17. 第 12 篇:Interrupt / Command / Human-in-the-loop#

17.1 学习目标#

理解人工确认如何从业务需求落到 LangGraph 运行机制。

17.2 范式映射#

Human-in-the-loop
→ interrupt()
→ checkpoint 保存
→ Command(resume=...)

17.3 最小代码#

from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.types import interrupt, Command
from langgraph.checkpoint.memory import InMemorySaver
class TravelState(TypedDict):
plan: str
approved: bool | None
def approval_node(state: TravelState):
approved = interrupt({
"question": "是否确认使用该旅行计划?",
"plan": state["plan"]
})
return {"approved": approved}
def final_node(state: TravelState):
if state["approved"]:
return {"plan": state["plan"] + "\n用户已确认。"}
return {"plan": "用户未确认,需要重新规划。"}
builder = StateGraph(TravelState)
builder.add_node("approval_node", approval_node)
builder.add_node("final_node", final_node)
builder.add_edge(START, "approval_node")
builder.add_edge("approval_node", "final_node")
builder.add_edge("final_node", END)
graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "travel-approval-001"}}
graph.invoke({"plan": "东京 5 天行程草案", "approved": None}, config=config)
graph.invoke(Command(resume=True), config=config)

17.4 执行流程#

执行到 approval_node
调用 interrupt(payload)
图暂停
checkpoint 保存当前 state
外部系统展示 payload
用户确认
graph.invoke(Command(resume=True), config)
interrupt 返回 True
图继续执行 final_node

17.5 源码阅读入口#

langgraph/types.py
langgraph/pregel/
langgraph/checkpoint/

17.6 源码阅读问题#

1. interrupt 如何让图暂停?
2. 暂停时 state 保存在哪里?
3. Command(resume=...) 如何把值传回 interrupt?
4. 为什么 interrupt 必须依赖 checkpointer?
5. 多个 interrupt 同时存在时如何恢复?

17.7 实践任务#

检查旅行规划助手中哪些场景适合 HITL:

场景是否需要 HITL原因
保存行程需要有状态写入
预订酒店必须高风险外部动作
修改日程视情况影响用户计划
查询天气不需要只读工具
生成建议不需要无副作用

17.8 产出#

12_langgraph_interrupt_hitl_source_deep_dive.md

第五部分:Streaming、Observability 与生产级 Agent 能力#

18. 第 13 篇:Stream 与事件观察#

18.1 学习目标#

掌握如何观察 LangChain / LangGraph 的运行过程。

需要掌握:

stream
astream
stream_mode="values"
stream_mode="updates"
stream_mode="messages"
event stream
metadata
callbacks

18.2 范式映射#

Agent Trace / Debugging / Observability
→ stream / events / tracing

18.3 最小代码#

for chunk in graph.stream(
{"user_request": "东京 5 天旅行"},
stream_mode="updates"
):
print(chunk)

18.4 常见 stream 模式理解#

模式观察内容适合场景
values每步后的完整 state状态调试
updates每个节点的增量更新节点输出调试
messages模型 token / message chunks流式回复
custom自定义事件工具进度、业务日志

18.5 源码阅读入口#

langgraph/pregel/
langchain_core/runnables/base.py
langchain_core/tracers/

18.6 源码阅读问题#

1. stream 与 invoke 的执行路径有什么不同?
2. stream_mode 如何影响输出?
3. token streaming 和 node update streaming 有什么区别?
4. callbacks 和 events 如何记录执行过程?
5. LangSmith trace 如何接入?

18.7 实践任务#

为旅行规划助手做一份 trace 表:

stepnodeupdatetool_callsmodel_usedlatencycost

18.8 产出#

13_langgraph_streaming_events_observability_source_deep_dive.md

19. 第 14 篇:Memory / Store 与上下文工程源码解剖#

19.1 学习目标#

理解 LangGraph 的 short-term memory、long-term memory、checkpointer 与 store 如何共同构成 Agent 记忆系统。

需要掌握:

thread_id
checkpoint
StateSnapshot
store
namespace
message trimming
summarization
memory write policy

19.2 范式映射#

Memory / Context Engineering
→ checkpointer + store + messages state + retrieval policy

19.3 最小代码骨架#

graph = builder.compile(checkpointer=checkpointer, store=store)
config = {
"configurable": {
"thread_id": "trip-thread-001",
"user_id": "jupiter",
}
}
graph.invoke({"messages": [("user", "记住我偏好城市漫步")]}, config=config)

19.4 核心源码主线#

主线重点问题
构建期compile(checkpointer=..., store=...) 如何把持久化能力注入运行时
运行时thread_id 如何决定 checkpoint 读写,store 如何被节点访问
分支边界checkpoint、store、message trimming、summary 的职责如何区分
扩展协作与 retrieval、profile memory、semantic memory、tool memory 如何协作

19.5 源码阅读入口#

langgraph/checkpoint/
langgraph/store/
langgraph/pregel/
langgraph/graph/message.py
langchain_core/messages/

19.6 源码阅读问题#

1. checkpoint 保存的是执行状态,还是用户长期记忆?
2. store 的 namespace 和 key 如何设计?
3. message trimming 与 summarization 应该发生在模型调用前还是图运行后?
4. 节点如何读取和写入 store?
5. 长期记忆写入失败是否应该中断主图?

19.7 实践任务#

为旅行规划助手设计三类记忆:

记忆类型存储位置示例
会话短期状态checkpoint当前旅行计划、已调用工具
用户长期偏好store喜欢城市漫步、预算中等
可检索旅行事实vector store / retriever目的地资料、历史计划片段

19.8 产出#

14_langgraph_memory_store_context_engineering_source_deep_dive.md

20. 第 15 篇:Middleware / Guardrails 与 Agent 执行控制源码解剖#

20.1 学习目标#

理解 LangChain Agent middleware 如何在模型调用、工具调用、上下文处理和安全控制之间提供统一扩展层。

需要掌握:

middleware
before_model
after_model
wrap_model_call
wrap_tool_call
tool retry
PII / safety guardrails
dynamic model selection
context editing

20.2 范式映射#

Agent Runtime Control / Guardrails
→ create_agent(..., middleware=[...])

20.3 最小代码骨架#

agent = create_agent(
model=model,
tools=tools,
middleware=[
dynamic_model_middleware,
pii_guardrail_middleware,
tool_retry_middleware,
],
)

20.4 核心源码主线#

主线重点问题
构建期create_agent 如何收集中间件并改写 model / tool 节点
运行时middleware hook 如何包裹一次模型调用或工具调用
分支边界guardrail 拒绝、工具重试、fallback 与正常执行如何分流
扩展协作与 structured output、HITL、LangGraph node、callback 如何协作

20.5 源码阅读入口#

langchain/agents/factory.py
langchain/agents/middleware/
langchain/agents/structured_output.py
langgraph/prebuilt/tool_node.py

20.6 源码阅读问题#

1. middleware 是改图结构,还是包装节点执行?
2. before_model / after_model 与 wrap_model_call 有什么边界?
3. tool retry 应该由 ToolNode、middleware 还是业务工具处理?
4. guardrail 拒绝后返回什么状态?
5. middleware 顺序如何影响最终行为?

20.7 实践任务#

为旅行规划助手设计三层 middleware:

Middleware触发阶段目的
Budget guardbefore_model控制长上下文和成本
Tool approvalwrap_tool_call高风险保存/预订前人工确认
Output safetyafter_model检查最终回复中的敏感信息

20.8 产出#

15_langchain_agent_middleware_guardrails_source_deep_dive.md

21. 第 16 篇:Agentic RAG 与 Retrieval Runtime 源码解剖#

21.1 学习目标#

理解 Retrieval 如何从普通查询组件升级为 Agent 可规划、可调用、可校验的运行时能力。

需要掌握:

Document
Retriever
VectorStore
retrieval tool
query rewrite
rerank
context assembly
grounding

21.2 范式映射#

Agentic RAG
→ retriever node / retrieval tool / query rewrite node / grounding evaluator

21.3 最小代码骨架#

retrieval_tool = create_retriever_tool(
retriever,
name="search_destination_knowledge",
description="Search destination facts for travel planning.",
)
agent = create_agent(model=model, tools=[retrieval_tool, *business_tools])

21.4 核心源码主线#

主线重点问题
构建期retriever 如何被包装为 Runnable 或 Tool
运行时query 如何进入 retriever,Document 如何回到 Prompt / State
分支边界无结果、低相关、冲突证据、上下文超长如何处理
扩展协作与 Tool Calling、Structured Output、Memory、Reflection 如何协作

21.5 源码阅读入口#

langchain_core/retrievers.py
langchain_core/documents/
langchain_core/vectorstores/
langchain/tools/retriever.py
langchain_core/runnables/

21.6 源码阅读问题#

1. Retriever 为什么是 Runnable?
2. retrieval tool 的 args_schema 和返回内容如何生成?
3. Document metadata 应该在何处被裁剪和格式化?
4. query rewrite 是模型节点、工具节点,还是普通 Runnable?
5. grounding evaluator 应该在最终回复前还是工具后执行?

21.7 实践任务#

把旅行规划助手的检索拆成三段:

阶段输入输出失败处理
query rewrite用户意图 + 当前计划搜索 query退回原始问题
retrievalquerydocuments换关键词或提示无资料
grounding checkdraft answer + documentsgrounded / not grounded触发 revise

21.8 产出#

16_langchain_agentic_rag_retrieval_runtime_source_deep_dive.md

第六部分:多 Agent、函数式工作流与调试回放#

22. 第 17 篇:Multi-Agent、Subagents 与 Handoffs 源码解剖#

22.1 学习目标#

理解 LangChain / LangGraph 如何表达多 Agent 协作,以及 subagent、handoff、supervisor 与 tool-based delegation 的边界。

需要掌握:

subagent
handoff
supervisor
agent-as-tool
Command
shared state
private state
message routing

22.2 范式映射#

Multi-Agent Collaboration
→ supervisor graph / subgraph / agent tool / handoff command

22.3 推荐实现结构#

travel_supervisor
├─ attraction_agent
├─ food_agent
├─ transport_agent
└─ budget_agent

22.4 核心源码主线#

主线重点问题
构建期subagent 如何被包装成 tool、node 或 subgraph
运行时消息、状态和控制权如何在 Agent 间传递
分支边界子 Agent 失败、循环委派、状态污染如何处理
扩展协作与 checkpoint、interrupt、store、structured output 如何协作

22.5 源码阅读入口#

langchain/agents/
langgraph/graph/
langgraph/prebuilt/
langgraph/types.py

22.6 源码阅读问题#

1. subagent 是工具、节点、子图,还是独立 runtime?
2. handoff 和普通 tool call 的本质区别是什么?
3. 多 Agent 共享 messages 是否会污染上下文?
4. supervisor 应该用模型路由还是 deterministic router?
5. 子 Agent 的 checkpoint 是否应该复用父图 thread_id?

22.7 实践任务#

为旅行规划助手画一张多 Agent 协作表:

Agent私有状态共享状态可调用工具交接条件
plannerplan draftitinerary计划拆分完成
attractionattraction factsevidenceretrieval景点信息不足
transportroute optionstransport planroute search行程路线冲突

22.8 产出#

17_langchain_langgraph_multi_agent_handoffs_source_deep_dive.md

23. 第 18 篇:Functional API、entrypoint 与 task 源码解剖#

23.1 学习目标#

理解 LangGraph Functional API 如何用 entrypointtask 表达可持久化、可重试、可流式的函数式工作流。

需要掌握:

entrypoint
task
workflow
retry
checkpoint
state passing
task result

23.2 范式映射#

Function-style Workflow
→ @entrypoint + @task + checkpointed execution

23.3 最小代码骨架#

@task
def search_city(query: str):
return search_tool.invoke(query)
@entrypoint(checkpointer=checkpointer)
def plan_trip(user_request: str):
docs = search_city(user_request).result()
return write_plan(docs)

23.4 核心源码主线#

主线重点问题
构建期装饰器如何把普通函数包装成可调度 task / entrypoint
运行时task 调用、结果等待、异常和 checkpoint 如何串联
分支边界retry、cache、并发 task、异常恢复如何处理
扩展协作与 StateGraph、Runnable、store、stream 如何取舍

23.5 源码阅读入口#

langgraph/func/
langgraph/pregel/
langgraph/checkpoint/
langgraph/types.py

23.6 源码阅读问题#

1. Functional API 是否真的绕过了 Pregel runtime?
2. task 的结果如何被持久化和恢复?
3. entrypoint 的输入输出边界与 StateGraph 有何不同?
4. 函数式工作流如何表达条件分支?
5. 什么时候应该用 Functional API,而不是 StateGraph?

23.7 实践任务#

把旅行规划助手中的一个确定性子流程改写为 Functional API,并对比:

维度StateGraphFunctional API
状态显式程度
分支可视化
编写成本较高较低
可恢复能力

23.8 产出#

18_langgraph_functional_api_entrypoint_task_source_deep_dive.md

24. 第 19 篇:Time Travel、update_state 与 Debug Replay 源码解剖#

24.1 学习目标#

理解 LangGraph 如何基于 checkpoint 历史实现状态回放、分叉调试、手动修正状态和从历史节点继续执行。

需要掌握:

get_state
get_state_history
update_state
checkpoint_id
StateSnapshot
replay
fork
debug replay

24.2 范式映射#

Debug Replay / Time Travel
→ checkpoint history + state update + resume from historical config

24.3 最小代码骨架#

history = list(graph.get_state_history(config))
target = history[-3]
patched_config = graph.update_state(
target.config,
{"plan_quality_score": 0.92},
)
graph.invoke(None, config=patched_config)

24.4 核心源码主线#

主线重点问题
构建期checkpointer 如何决定是否支持历史读取和分叉
运行时StateSnapshot 如何记录 values、next、tasks、config
分支边界replay、fork、manual update 与 resume 的边界
扩展协作与 interrupt、HITL、LangSmith trace、生产事故复盘如何协作

24.5 源码阅读入口#

langgraph/pregel/
langgraph/checkpoint/
langgraph/graph/state.py
langgraph/types.py

24.6 源码阅读问题#

1. checkpoint_id 如何定位一次历史状态?
2. get_state_history 返回的是完整历史还是可分页历史?
3. update_state 是覆盖 state,还是写入一次新的 checkpoint?
4. 从历史状态继续执行会不会重复执行已有副作用?
5. Time Travel 在生产环境应如何限制权限?

24.7 实践任务#

为旅行规划助手设计一次调试回放:

场景操作期望结果
planner 生成错误计划找到 planner 后的 snapshot定位错误写入字段
人工修正计划update_state 写入修正字段从 evaluator 继续执行
工具副作用已发生标记不可重放步骤避免重复保存或预订

24.8 产出#

19_langgraph_time_travel_update_state_debug_replay_source_deep_dive.md

第七部分:验证闭环、部署与生产运行#

25. 第 20 篇:LangSmith Trace、Evaluation 与 Dataset 闭环源码解剖#

25.1 学习目标#

理解 LangSmith 如何把线上 trace、feedback、dataset、evaluator 和 experiment 串成 Agent 回归评测闭环。

25.2 范式映射#

线上 Agent 执行
Trace / Feedback
Dataset Example
Evaluator / Experiment
Regression Gate

25.3 产出#

20_langsmith_trace_evaluation_dataset_feedback_source_deep_dive.md

26. 第 21 篇:LangGraph / LangChain Agent 部署与生产运行机制源码解剖#

26.1 学习目标#

理解 Agent 如何从本地 graph 进入 Agent Server、LangSmith Deployment、Remote Graph/API、持久化后端和线上观测体系。

26.2 范式映射#

Local Graph
langgraph.json / Agent Server
Remote runs / threads / stream
Persistence / Observability / Eval Gate
Production Agent

26.3 产出#

21_langgraph_langchain_agent_deployment_production_runtime_source_deep_dive.md

第八部分:最终产出规划#

27. 最终笔记目录#

建议最终形成如下目录:

langchain_langgraph_source_notes/
00_学习路线.md
01-langchain-runnable-source-deep-dive.md
02_langchain_core_prompt_message_chatmodel_source_deep_dive.md
03_langchain_core_structured_output_source_deep_dive.md
04_langchain_core_tool_calling_source_deep_dive.md
05_langchain_create_agent_react_source_deep_dive.md
06_langgraph_stategraph_source_deep_dive.md
07_langgraph_conditional_edge_router_source_deep_dive_v2.md
08_langgraph_reducer_parallel_state_source_deep_dive.md
09_langgraph_plan_execute_subgraph_source_deep_dive.md
10_langgraph_reflection_loop_source_deep_dive.md
11_langgraph_checkpoint_thread_durable_execution_source_deep_dive.md
12_langgraph_interrupt_hitl_source_deep_dive.md
13_langgraph_streaming_events_observability_source_deep_dive.md
14_langgraph_memory_store_context_engineering_source_deep_dive.md
15_langchain_agent_middleware_guardrails_source_deep_dive.md
16_langchain_agentic_rag_retrieval_runtime_source_deep_dive.md
17_langchain_langgraph_multi_agent_handoffs_source_deep_dive.md
18_langgraph_functional_api_entrypoint_task_source_deep_dive.md
19_langgraph_time_travel_update_state_debug_replay_source_deep_dive.md

28. 统一文章规范与质量门禁#

所有源码解剖文章以 源码解剖学习文章统一框架.md 为唯一结构规范,不再维护另一套简化模板。正式文章固定使用 0–14 章:

章节范围职责
0–2系列位置、问题边界、核心心智模型
3–6完整链路、源码地图、对象协议、阅读证据
7–10构建期、运行时、关键分支、扩展协作
11–14工程决策、误区、掌握检查、参考与衔接

其中第 7–10 章是主体,必须同时给出细粒度伪代码、逐步讲解和固定 commit 的源码证据。伪代码只保留控制流、对象变化和分支条件,不伪装成源码原文。

每篇文章发布前必须逐项通过:

  • H2 严格为 0–14,只有一个 H1,不出现标题跳级和未闭合代码围栏;
  • 第 7–10 章各有至少 3 个 H3,并同时包含伪代码与源码证据;
  • 第 7–10 章占全文 65%–75%,重点落在源码机制而非外围示例;
  • 依赖版本、源码 commit、官方文档、API Reference 和固定 commit 源码链接齐全;
  • 本地源笔记是正文唯一事实源,网站文章仅额外保留 frontmatter,正文必须逐字同步;
  • 自动校验、网站构建、专栏顺序和本地页面抽查全部通过后,才允许推送远端。

第九部分:学习检查清单#

29. LangChain 掌握标准#

  • 能解释 Runnable 的作用;
  • 能解释 prompt | model | parser 为什么能运行;
  • 能解释 PromptValue、Message、AIMessage 的关系;
  • 能解释 AIMessage.tool_calls 的作用;
  • 能解释 @tool 如何生成工具 schema;
  • 能解释 ToolMessage 为什么要放回 messages;
  • 能解释 create_agent 的模型-工具循环;
  • 能解释 middleware 能拦截哪些阶段;
  • 能解释 structured output 和 output parser 的区别;
  • 能解释 Retriever 如何作为 Runnable 参与链路;
  • 能解释 retrieval tool、query rewrite 与 grounding check 的边界;
  • 能解释 subagent / handoff / agent-as-tool 的差异。

30. LangGraph 掌握标准#

  • 能解释 StateGraph 为什么是 builder;
  • 能解释 compile 之后得到什么;
  • 能解释 node 为什么返回 partial state;
  • 能解释 reducer 的作用;
  • 能解释 add_edge 和 add_conditional_edges 的区别;
  • 能解释 START / END 的作用;
  • 能解释 checkpoint 和 thread_id 的关系;
  • 能解释 StateSnapshot 保存什么;
  • 能解释 interrupt 和 Command(resume=…) 如何工作;
  • 能解释 subgraph 如何复用;
  • 能解释 stream 的不同模式;
  • 能解释 Pregel runtime 的基本调度思想;
  • 能解释 store 与 checkpoint 的职责差异;
  • 能解释 Functional API 的 entrypoint / task 如何映射到底层运行时;
  • 能解释 Time Travel、update_state 与 replay 的调试边界。

29. 范式到框架映射掌握标准#

  • 能用 StateGraph 实现 Workflow;
  • 能用 conditional edge 实现 Router;
  • 能用 create_agent 解释 ReAct-like loop;
  • 能用 planner node + executor node 表达 Plan-and-Execute;
  • 能用 evaluator node + loop edge 表达 Reflection;
  • 能用 retriever node + answer node 表达 Agentic RAG;
  • 能用 checkpoint 表达短期执行记忆;
  • 能用 store 表达长期用户偏好;
  • 能用 interrupt 表达人工确认;
  • 能用 stream / trace 表达可观测性;
  • 能用 middleware 表达安全策略、动态模型和工具重试;
  • 能用 Time Travel 表达事故复盘和状态修正。

30. 源码阅读掌握标准#

  • 能定位 Runnable 源码;
  • 能定位 ChatModel 源码;
  • 能定位 Tool 源码;
  • 能定位 create_agent 源码;
  • 能定位 StateGraph 源码;
  • 能定位 CompiledStateGraph / Pregel 源码;
  • 能定位 checkpointer 源码;
  • 能定位 interrupt / Command 源码;
  • 能定位 store、Functional API 和 Time Travel 相关源码;
  • 能根据报错追踪到框架层问题。

第九部分:推荐资料#

31. 官方文档#

32. 源码仓库#

33. 关联学习资料#


第十部分:最终总结#

这条学习路线的核心不是“学会更多 API”,而是把 Agent 范式、框架实现和源码机制打通。

最终你应该形成三种能力:

第一,范式映射能力:
看到 ReAct、Workflow、Router、Plan、Reflection,知道在 LangChain / LangGraph 中如何表达。
第二,源码理解能力:
看到 Runnable、Tool、StateGraph、Checkpoint、Store、Middleware、Functional API、Time Travel,知道它们的执行机制和源码入口。
第三,工程判断能力:
知道哪些场景该用 Chain,哪些场景该用 Workflow,哪些场景该用 Agent loop,哪些场景必须加 checkpoint、HITL、Verifier 和 Guardrails。

学完这条路线后,你对 LangChain / LangGraph 的理解不应该停留在:

我会用框架写一个 Agent

而应该升级为:

我知道 Agent 范式如何被框架实现;
我知道框架运行时如何调度;
我知道源码该从哪里读;
我知道真实业务里该用哪一层抽象。
LangChain & LangGraph 框架源码学习路线
https://jupiter-ws.cn/posts/agent-frameworks/langchain-langgraph-source-learning-route/
作者
Jupiter
发布于
2026-03-04
许可协议
CC BY-NC-SA 4.0