从 Agent 范式到 LangChain / LangGraph 框架源码:学习路线
适用对象:已经理解 ReAct、Plan-and-Execute、Reflection、Workflow、Router、Agentic RAG 等 Agent 范式,并且已经完成一个基于 LangChain / LangGraph 的旅行规划助手,希望进一步从“会用框架”升级为“理解框架源码与设计思想”的学习者。
核心目标:以已完成的旅行规划助手为样本工程,建立“Agent 范式 → 框架 API → 执行机制 → 源码结构 → 工程判断”的完整学习链路。
学习原则:不再以堆功能为主,而是通过代码讲解、运行追踪、源码反查和框架设计复盘,深入掌握 LangChain 与 LangGraph 的核心抽象。
当前依赖基线:
langchain==1.3.11、langchain-core==1.4.8、langgraph==1.2.7。后续文章默认使用写作时的最新正式版,并在文章开头固定具体版本与 commit。
| 篇次 | 主题 | 状态 | 规范文件 |
|---|---|---|---|
| 1 | Runnable | 已完成并按新规范升级 | 01-langchain-runnable-source-deep-dive.md |
| 2 | Prompt / Message / ChatModel | 已完成并按新规范升级 | 02_langchain_core_prompt_message_chatmodel_source_deep_dive.md |
| 3 | Structured Output | 已完成并按新规范升级 | 03_langchain_core_structured_output_source_deep_dive.md |
| 4 | Tool Calling | 已完成并按新规范升级 | 04_langchain_core_tool_calling_source_deep_dive.md |
| 5 | create_agent / ReAct | 已完成并按新规范升级 | 05_langchain_create_agent_react_source_deep_dive.md |
| 6–13 | LangGraph 核心运行时 | 已完成并发布 | 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 Chain | prompt | model | parser | RunnableSequence、invoke、stream | 为什么链式组合可以运行 |
| Tool-use | @tool、StructuredTool、ToolNode | BaseTool、args_schema、ToolMessage | 函数如何变成模型可调用工具 |
| ReAct | create_agent、model-tool loop | AIMessage.tool_calls、tools node、agent graph | 模型与工具循环如何执行 |
| Workflow | StateGraph、add_node、add_edge | CompiledStateGraph、state update | 固定流程如何被图执行 |
| Router | add_conditional_edges | path function、branch mapping | 意图路由如何决定下一节点 |
| Plan-and-Execute | planner node、executor subgraph | structured plan、subgraph、checkpoint | 计划如何转成可执行流程 |
| Reflection | evaluator node、revise node、loop edge | conditional loop、max iteration | 反思如何成为有限循环 |
| Agentic RAG | retriever node、query rewrite node | Retriever、Document、Runnable | 检索如何成为 Agent 节点 |
| Memory | checkpointer、store、thread_id | checkpoint、StateSnapshot、Store | 为什么能保存执行状态和用户偏好 |
| Guardrails | middleware、policy、retry | middleware hooks、tool retry、model wrapper | 安全、成本和工具失败如何被控制 |
| Multi-Agent | supervisor、subagent、handoff | agent-as-tool、Command、subgraph | 多 Agent 如何交接控制权和状态 |
| Functional Workflow | @entrypoint、@task | functional runtime、task result、checkpoint | 何时用函数式 API 替代显式图 |
| Debug Replay | time travel、update_state | checkpoint history、StateSnapshot、fork | 如何从历史状态回放和修正执行 |
| Human-in-the-loop | interrupt()、Command(resume=...) | interrupt、resume、checkpoint | 人工确认如何暂停/恢复图 |
| Observability | stream、events、LangSmith trace | callback、event stream、metadata | 如何观察每一步执行 |
3. 最新框架趋势校准
3.1 LangChain 的定位变化
LangChain v1 之后更强调“Agent 工程基础组件”和“可组合运行单元”,核心包括:
ChatModelPromptMessageToolOutputParserRunnableRetrieverMiddlewarecreate_agent需要重点理解:
LangChain 不只是 Chain;LangChain Core 的关键是 Runnable 抽象;LangChain Agent 的关键是基于 LangGraph 的 agent runtime;create_agent 成为构建 Agent 的标准入口之一;middleware 成为模型调用、工具调用、上下文处理、安全控制的重要扩展点。3.2 LangGraph 的定位变化
LangGraph 更像是 Agent 的底层编排运行时,核心包括:
StateGraphCompiledStateGraphNodeEdgeConditional EdgeReducerCheckpointStoreThreadInterruptCommandSubgraphFunctional APITime TravelDurable ExecutionPregel Runtime需要重点理解:
LangGraph 不是普通流程图;它是有状态、可恢复、可中断、可回放的 Agent / Workflow 执行框架;生产级 Agent 的很多能力,如 memory、HITL、time travel、durable execution,都建立在 checkpoint 和 runtime 机制之上。3.3 当前学习重点
不需要平均学习所有 API,而应该优先学习以下核心:
1. Runnable2. ChatPromptTemplate / Messages3. BaseChatModel / AIMessage / ToolMessage4. @tool / StructuredTool5. create_agent6. StateGraph7. add_node / add_edge / add_conditional_edges8. Reducer / Annotated state9. Checkpointer / thread_id10. interrupt / Command11. stream / events / tracing12. subgraph / multi-agent graph4. 学习方法:四层拆解法
每学一个框架点,都按四层拆解。
4.1 范式层
先问:
这个功能解决哪个 Agent 范式问题?例如:
add_conditional_edges 解决 Router / Workflow 分支问题;checkpoint 解决长期状态、恢复执行和 HITL 问题;@tool 解决模型连接外部能力的问题;create_agent 解决 ReAct 式模型-工具循环问题。4.2 代码层
再问:
这个范式在 LangChain / LangGraph 中用哪个 API 表达?例如:
Tool-use → @tool / StructuredToolWorkflow → StateGraphRouter → add_conditional_edgesHITL → interrupt + CommandMemory → checkpointer + thread_id4.3 执行层
继续问:
运行时发生了什么?例如:
graph.invoke(input)→ 初始化 state→ 执行 START 指向的 node→ node 返回 partial update→ reducer 合并 state→ edge 决定下一个节点→ checkpoint 保存状态→ 直到 END4.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 / Model | 3 篇源码笔记 + 最小代码实验 |
| 第 2 周 | Tool Calling 与 create_agent | 2 篇源码笔记 + ReAct 执行链路图 |
| 第 3 周 | LangGraph 基础:StateGraph / Edge / Router / Reducer | 3 篇源码笔记 + 旅行助手 state 流转图 |
| 第 4 周 | LangGraph 进阶:Checkpoint / Interrupt / Subgraph / Streaming | 4 篇源码笔记 + checkpoint 时间线 |
| 第 5 周 | Memory、Middleware 与 Agentic RAG | 3 篇生产级 Agent 能力源码笔记,已补齐为第 14–16 篇 |
| 第 6 周 | Multi-Agent、Functional API 与 Time Travel | 3 篇运行时扩展与调试回放源码笔记,已补齐为第 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 | parser6.3 最小代码
from langchain_core.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParserfrom 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.pylangchain_core/runnables/config.pylangchain_core/runnables/utils.pylangchain_core/runnables/passthrough.pylangchain_core/runnables/branch.py重点类:
RunnableRunnableSequenceRunnableParallelRunnableLambdaRunnableConfig6.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 | modelprompt | model | parser的代码,并标注:
这是 RunnableSequence;输入是什么;中间输出是什么;最终输出是什么;是否支持 stream;是否能加 with_retry / with_config。6.8 产出
01-langchain-runnable-source-deep-dive.md7. 第 2 篇:Prompt / Message / ChatModel 源码解剖
7.1 学习目标
把对 Prompt 的理解从“字符串模板”升级为“结构化消息构造器”。
你需要掌握:
PromptTemplateChatPromptTemplateMessagesPlaceholderSystemMessageHumanMessageAIMessageToolMessageBaseChatModel7.2 范式映射
Context Engineering / Prompt Engineering→ ChatPromptTemplate + Messages + ChatModel7.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 ↓返回 AIMessage7.5 源码阅读入口
langchain_core/prompts/langchain_core/messages/langchain_core/language_models/chat_models.py重点类:
BaseMessageHumanMessageSystemMessageAIMessageToolMessageBaseChatModelChatPromptTemplateMessagesPlaceholder7.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 |
|---|---|---|---|---|
| 需求解析 Prompt | user_request | intent/slots | Router | 是 |
| 规划 Prompt | destination/preferences | plan_steps | Planner | 是 |
| 搜索 Query Prompt | plan/current_step | search_query | Tool-use | 是 |
| 最终回复 Prompt | full_state | final_answer | Response | 否 |
7.8 产出
02_langchain_core_prompt_message_chatmodel_source_deep_dive.md8. 第 3 篇:OutputParser 与结构化输出
8.1 学习目标
掌握模型输出从自然语言变成结构化对象的过程。
重点理解:
StrOutputParserJsonOutputParserPydanticOutputParserwith_structured_outputschema validationparser failureretry / repair8.2 范式映射
意图识别 / 槽位抽取 / 计划生成 / 责任判断→ 结构化输出8.3 最小代码
from pydantic import BaseModel, Fieldfrom 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 对象或 dict8.5 源码阅读入口
langchain_core/output_parsers/langchain_core/language_models/chat_models.pylangchain_core/utils/function_calling.py8.6 源码阅读问题
1. with_structured_output 底层如何绑定 schema?2. Pydantic schema 如何转换为 JSON schema?3. 结构化输出和 tool calling 有什么关系?4. 解析失败时异常在哪里抛出?5. parser 应该放在 chain 里,还是依赖模型原生 structured output?8.7 实践任务
为旅行规划助手中的关键节点设计结构化输出:
IntentResultTravelPlanSearchQueryReflectionResultFinalResponse每个结构化输出都要写:
字段含义是否必填失败样例校验规则8.8 产出
03_langchain_core_structured_output_source_deep_dive.md第二部分:Tool-use 与 Agent Loop
9. 第 4 篇:Tool Calling 源码解剖
9.1 学习目标
理解普通 Python 函数如何变成模型可调用工具。
你需要掌握:
@toolStructuredToolBaseToolargs_schematool nametool descriptiontool callToolMessagetool error handling9.2 范式映射
Tool-use Agent→ LangChain Tool / StructuredTool9.3 最小代码
from langchain.tools import tool
@tooldef 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 ↓重新放回 messages9.5 源码阅读入口
langchain_core/tools/langchain/tools/langchain_core/messages/tool.py重点类:
BaseToolStructuredToolToolExceptionToolMessage9.6 源码阅读问题
1. @tool 装饰器如何读取函数名、参数和 docstring?2. args_schema 如何从函数签名生成?3. Tool.invoke 和普通函数调用有什么区别?4. ToolMessage 如何保存 tool_call_id?5. 工具异常如何被捕获并返回给模型?6. 工具描述如何影响模型选择?9.7 实践任务
对旅行规划助手中的工具建立工具表:
| 工具名 | 输入 schema | 输出 schema | 是否有副作用 | 是否需要确认 | 所属范式 |
|---|---|---|---|---|---|
| search_destination | city/query | documents | 否 | 否 | Tool-use / RAG |
| search_weather | city/date | weather | 否 | 否 | Tool-use |
| search_transport | from/to/date | routes | 否 | 否 | Tool-use |
| save_plan | plan/user_id | saved_status | 是 | 是 | HITL / Tool-use |
9.8 产出
04_langchain_core_tool_calling_source_deep_dive.md10. 第 5 篇:create_agent 与 ReAct 执行机制
10.1 学习目标
理解 LangChain Agent 如何通过模型-工具循环实现 ReAct 类行为。
需要掌握:
create_agentmodel nodetools nodemiddlewaretool loopstop conditioniteration limitstructured response10.2 范式映射
ReAct→ model call→ tool call→ ToolMessage→ model call→ final answer现代框架不一定显式暴露 Thought,生产中更推荐观察结构化 trace:
AIMessagetool_callsToolMessagefinal AIMessage10.3 最小代码
from langchain.agents import create_agentfrom langchain.tools import tool
@tooldef 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.pylanggraph/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.md10.9 后续篇章的统一源码主线
从第 6 篇开始,每篇仍保留本路线给出的学习目标和实验任务,但正式文章必须围绕四条源码线组织核心正文:
- 构建期: 用户声明如何被校验、归一化,并组装成可执行对象;
- 运行时主链: 从公开入口进入哪些核心方法,对象与状态如何流转;
- 关键分支: 同步/异步、流式、异常、重试和终止条件如何分流;
- 扩展协作: 与 LangChain、LangGraph、middleware、checkpoint、store 等机制如何组合。
四条线分别落入统一框架的第 7–10 章,并占全文 65%–75%。这样路线负责回答“学什么、按什么顺序学”,文章框架负责回答“每篇怎样证明自己真的读懂了源码”。
第三部分:LangGraph Workflow 与状态图
11. 第 6 篇:StateGraph 源码解剖
11.1 学习目标
理解 LangGraph 如何用图结构承载 Workflow Agent。
重点掌握:
StateGraphState schemaadd_nodeadd_edgeSTARTENDcompileCompiledStateGraphpartial state update11.2 范式映射
Workflow Agent→ StateGraph + Node + Edge + State11.3 最小代码
from typing_extensions import TypedDictfrom 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 ↓到达 END11.5 源码阅读入口
langgraph/graph/state.pylanggraph/graph/graph.pylanggraph/pregel/重点类:
StateGraphCompiledStateGraphPregel11.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.md12. 第 7 篇:Conditional Edge 与 Router
12.1 学习目标
理解意图路由、状态路由、错误路由如何在 LangGraph 中落地。
12.2 范式映射
Router Agent / Workflow Branch→ add_conditional_edges12.3 最小代码
from typing_extensions import TypedDict, Literalfrom 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.pylanggraph/graph/branch.py12.6 源码阅读问题
1. add_conditional_edges 如何注册 path function?2. path function 的返回值可以是什么?3. 返回 END 时如何终止?4. 返回多个节点时如何并行?5. mapping 参数有什么作用?6. Literal 类型提示对可视化和校验有什么帮助?12.7 实践任务
给旅行规划助手补一张路由表:
| 路由类型 | 判断依据 | 路由函数 | 目标节点 | 风险 |
|---|---|---|---|---|
| 意图路由 | intent | route_by_intent | plan/search/clarify | 意图误判 |
| 信息缺失路由 | missing_slots | route_missing_info | ask_user/planner | 追问过多 |
| 工具失败路由 | tool_error | route_error | retry/fallback | 死循环 |
| 质量检查路由 | score | route_reflection | revise/final | 过度反思 |
12.8 产出
07_langgraph_conditional_edge_router_source_deep_dive_v2.md13. 第 8 篇:Reducer 与并行状态合并
13.1 学习目标
理解为什么 LangGraph 的 state 不只是普通字典,而是有合并规则的状态模型。
13.2 范式映射
并行检索 / 多 Agent 协作 / 多工具结果聚合→ Reducer13.3 最小代码
from typing import Annotatedfrom operator import addfrom typing_extensions import TypedDictfrom 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_notes13.5 源码阅读入口
langgraph/graph/state.pylanggraph/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→ replan14.3 推荐实现结构
START→ parse_request→ planner_node→ validate_plan→ execute_step→ check_step_result→ route_next_step ├── continue_execute ├── replan └── final_response14.4 最小代码骨架
from typing_extensions import TypedDictfrom 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.pylanggraph/graph/branch.pylanggraph/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.md15. 第 10 篇:Reflection / Evaluator-Optimizer 在 LangGraph 中的实现
15.1 学习目标
理解 Reflection 如何从“让模型再想想”变成可控的评价-修改循环。
15.2 范式映射
Reflection→ generator node→ evaluator node→ revise node→ conditional loop15.3 推荐状态字段
class TravelState(TypedDict): draft_plan: str | None critique: str | None quality_score: float | None revision_count: int final_plan: str | None15.4 推荐流程
generate_draft→ evaluate_draft→ route_by_score ├── revise_draft └── final_response→ revise_draft→ evaluate_draft15.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.pylanggraph/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.md16. 第 11 篇:Checkpoint / Thread / Durable Execution
16.1 学习目标
理解 LangGraph 生产级能力的核心:状态持久化与可恢复执行。
16.2 范式映射
Memory / Long-running Agent / Durable Workflow / HITL→ checkpoint + thread_id16.3 最小代码
from typing_extensions import TypedDictfrom langgraph.graph import StateGraph, START, ENDfrom 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_idcheckpointStateSnapshotsuper-stepwritesnextmetadata16.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 是否产生 | 备注 |
|---|---|---|---|---|
| T1 | parse_request | 写入 destination/days | 是 | 初始化 |
| T2 | planner_node | 写入 plan_steps | 是 | 计划生成 |
| T3 | search_node | 写入 search_results | 是 | 工具结果 |
| T4 | final_node | 写入 final_plan | 是 | 结束 |
16.8 产出
11_langgraph_checkpoint_thread_durable_execution_source_deep_dive.md17. 第 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 TypedDictfrom langgraph.graph import StateGraph, START, ENDfrom langgraph.types import interrupt, Commandfrom 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_node17.5 源码阅读入口
langgraph/types.pylanggraph/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 的运行过程。
需要掌握:
streamastreamstream_mode="values"stream_mode="updates"stream_mode="messages"event streammetadatacallbacks18.2 范式映射
Agent Trace / Debugging / Observability→ stream / events / tracing18.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.pylangchain_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 表:
| step | node | update | tool_calls | model_used | latency | cost |
|---|
18.8 产出
13_langgraph_streaming_events_observability_source_deep_dive.md19. 第 14 篇:Memory / Store 与上下文工程源码解剖
19.1 学习目标
理解 LangGraph 的 short-term memory、long-term memory、checkpointer 与 store 如何共同构成 Agent 记忆系统。
需要掌握:
thread_idcheckpointStateSnapshotstorenamespacemessage trimmingsummarizationmemory write policy19.2 范式映射
Memory / Context Engineering→ checkpointer + store + messages state + retrieval policy19.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.pylangchain_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.md20. 第 15 篇:Middleware / Guardrails 与 Agent 执行控制源码解剖
20.1 学习目标
理解 LangChain Agent middleware 如何在模型调用、工具调用、上下文处理和安全控制之间提供统一扩展层。
需要掌握:
middlewarebefore_modelafter_modelwrap_model_callwrap_tool_calltool retryPII / safety guardrailsdynamic model selectioncontext editing20.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.pylangchain/agents/middleware/langchain/agents/structured_output.pylanggraph/prebuilt/tool_node.py20.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 guard | before_model | 控制长上下文和成本 |
| Tool approval | wrap_tool_call | 高风险保存/预订前人工确认 |
| Output safety | after_model | 检查最终回复中的敏感信息 |
20.8 产出
15_langchain_agent_middleware_guardrails_source_deep_dive.md21. 第 16 篇:Agentic RAG 与 Retrieval Runtime 源码解剖
21.1 学习目标
理解 Retrieval 如何从普通查询组件升级为 Agent 可规划、可调用、可校验的运行时能力。
需要掌握:
DocumentRetrieverVectorStoreretrieval toolquery rewritererankcontext assemblygrounding21.2 范式映射
Agentic RAG→ retriever node / retrieval tool / query rewrite node / grounding evaluator21.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.pylangchain_core/documents/langchain_core/vectorstores/langchain/tools/retriever.pylangchain_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 | 退回原始问题 |
| retrieval | query | documents | 换关键词或提示无资料 |
| grounding check | draft answer + documents | grounded / 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 的边界。
需要掌握:
subagenthandoffsupervisoragent-as-toolCommandshared stateprivate statemessage routing22.2 范式映射
Multi-Agent Collaboration→ supervisor graph / subgraph / agent tool / handoff command22.3 推荐实现结构
travel_supervisor ├─ attraction_agent ├─ food_agent ├─ transport_agent └─ budget_agent22.4 核心源码主线
| 主线 | 重点问题 |
|---|---|
| 构建期 | subagent 如何被包装成 tool、node 或 subgraph |
| 运行时 | 消息、状态和控制权如何在 Agent 间传递 |
| 分支边界 | 子 Agent 失败、循环委派、状态污染如何处理 |
| 扩展协作 | 与 checkpoint、interrupt、store、structured output 如何协作 |
22.5 源码阅读入口
langchain/agents/langgraph/graph/langgraph/prebuilt/langgraph/types.py22.6 源码阅读问题
1. subagent 是工具、节点、子图,还是独立 runtime?2. handoff 和普通 tool call 的本质区别是什么?3. 多 Agent 共享 messages 是否会污染上下文?4. supervisor 应该用模型路由还是 deterministic router?5. 子 Agent 的 checkpoint 是否应该复用父图 thread_id?22.7 实践任务
为旅行规划助手画一张多 Agent 协作表:
| Agent | 私有状态 | 共享状态 | 可调用工具 | 交接条件 |
|---|---|---|---|---|
| planner | plan draft | itinerary | 无 | 计划拆分完成 |
| attraction | attraction facts | evidence | retrieval | 景点信息不足 |
| transport | route options | transport plan | route search | 行程路线冲突 |
22.8 产出
17_langchain_langgraph_multi_agent_handoffs_source_deep_dive.md23. 第 18 篇:Functional API、entrypoint 与 task 源码解剖
23.1 学习目标
理解 LangGraph Functional API 如何用 entrypoint 和 task 表达可持久化、可重试、可流式的函数式工作流。
需要掌握:
entrypointtaskworkflowretrycheckpointstate passingtask result23.2 范式映射
Function-style Workflow→ @entrypoint + @task + checkpointed execution23.3 最小代码骨架
@taskdef 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.py23.6 源码阅读问题
1. Functional API 是否真的绕过了 Pregel runtime?2. task 的结果如何被持久化和恢复?3. entrypoint 的输入输出边界与 StateGraph 有何不同?4. 函数式工作流如何表达条件分支?5. 什么时候应该用 Functional API,而不是 StateGraph?23.7 实践任务
把旅行规划助手中的一个确定性子流程改写为 Functional API,并对比:
| 维度 | StateGraph | Functional API |
|---|---|---|
| 状态显式程度 | 高 | 中 |
| 分支可视化 | 强 | 弱 |
| 编写成本 | 较高 | 较低 |
| 可恢复能力 | 强 | 强 |
23.8 产出
18_langgraph_functional_api_entrypoint_task_source_deep_dive.md24. 第 19 篇:Time Travel、update_state 与 Debug Replay 源码解剖
24.1 学习目标
理解 LangGraph 如何基于 checkpoint 历史实现状态回放、分叉调试、手动修正状态和从历史节点继续执行。
需要掌握:
get_stateget_state_historyupdate_statecheckpoint_idStateSnapshotreplayforkdebug replay24.2 范式映射
Debug Replay / Time Travel→ checkpoint history + state update + resume from historical config24.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.pylanggraph/types.py24.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 Gate25.3 产出
20_langsmith_trace_evaluation_dataset_feedback_source_deep_dive.md26. 第 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 Agent26.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.md28. 统一文章规范与质量门禁
所有源码解剖文章以 源码解剖学习文章统一框架.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. 官方文档
- LangChain Agents
https://docs.langchain.com/oss/python/langchain/agents - LangChain Runtime
https://docs.langchain.com/oss/python/langchain/runtime - LangChain Middleware
https://docs.langchain.com/oss/python/langchain/middleware - LangChain Retrieval
https://docs.langchain.com/oss/python/langchain/retrieval - LangChain Multi-agent
https://docs.langchain.com/oss/python/langchain/multi-agent - LangChain v1 Release Notes
https://docs.langchain.com/oss/python/releases/langchain-v1 - LangChain
create_agentReference
https://reference.langchain.com/python/langchain/agents/factory/create_agent - LangChain Runnable Reference
https://reference.langchain.com/python/langchain-core/runnables - LangGraph Overview
https://docs.langchain.com/oss/python/langgraph/overview - LangGraph Memory
https://docs.langchain.com/oss/python/langgraph/add-memory - LangGraph Persistence
https://docs.langchain.com/oss/python/langgraph/persistence - LangGraph Functional API
https://docs.langchain.com/oss/python/langgraph/functional-api - LangGraph Time Travel
https://docs.langchain.com/oss/python/langgraph/use-time-travel - LangGraph StateGraph Reference
https://reference.langchain.com/python/langgraph/graph/state/StateGraph - LangGraph Durable Execution
https://docs.langchain.com/oss/python/langgraph/durable-execution - LangGraph Interrupts
https://docs.langchain.com/oss/python/langgraph/interrupts - LangGraph Subgraphs
https://docs.langchain.com/oss/python/langgraph/use-subgraphs - LangGraph Runtime / Pregel
https://docs.langchain.com/oss/python/langgraph/pregel - LangSmith Evaluation
https://docs.langchain.com/langsmith/evaluation
32. 源码仓库
- LangChain GitHub
https://github.com/langchain-ai/langchain - LangGraph GitHub
https://github.com/langchain-ai/langgraph
33. 关联学习资料
- ReAct: Synergizing Reasoning and Acting in Language Models
https://arxiv.org/abs/2210.03629 - Reflexion: Language Agents with Verbal Reinforcement Learning
https://arxiv.org/abs/2303.11366 - Plan-and-Solve Prompting
https://aclanthology.org/2023.acl-long.147/ - Anthropic: Building Effective Agents
https://www.anthropic.com/engineering/building-effective-agents - OpenAI Agents SDK
https://developers.openai.com/api/docs/guides/agents - Model Context Protocol
https://modelcontextprotocol.io/docs/getting-started/intro
第十部分:最终总结
这条学习路线的核心不是“学会更多 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 范式如何被框架实现;我知道框架运行时如何调度;我知道源码该从哪里读;我知道真实业务里该用哪一层抽象。