LangGraph 面试复习总览本文是 5 份本地 LangGraph Markdown 教程的面试版压缩笔记。目标不是替代教程而是帮助你在面试中用一条稳定的主线回答状态如何流动流程如何控制执行如何恢复多个 Agent 如何组合以及系统如何上线。资料范围输入源Day1到Day5共 5 份 Markdown 教程。内容覆盖LangGraph v1 基础图模型、状态与 Reducer、条件路由与并行、持久化与人在回路、多 Agent 与生产部署。版本口径教程中的 API 结论来自本地教程的实测记录具体版本升级后以官方文档和当前环境验证结果为准。1. 60 秒总答LangGraph 是什么LangGraph 是一个面向有状态 Agent 和工作流的图运行时。它把流程拆成State节点之间共享、按字段流转的数据。Node读取 State 并返回局部更新的 Python 函数。Edge决定下一个执行节点既可以是固定边也可以是条件边。Runtime负责调度、并行超步、流式输出、检查点、暂停恢复和错误边界。一句话概括LangGraph 就是帮大模型写 “带判断、能循环、能中途暂停” 的办事流程的工具。以前的 LangChain Chain 像一条只能往前走的直跑道LangGraph 是可以分叉、绕圈、停下来等人干预的迷宫路线。顶部LangGraph 是什么LangGraph 是一个框架用来做大模型 AI 应用它有几个特点基于图编排把任务拆成一个个节点办事步骤节点之间画线代表怎么走有状态执行全程记着所有信息不会做着做着忘记前面聊了啥可控可观察跑一半可以暂停、重来、回退人可以插手改结果持久化恢复程序崩了能从刚才中断的地方接着跑不用从头再来高度可扩展很容易接上检索工具、数据库、记忆模块中间LangGraph 工作原理流程图重点黄色的State状态就像一个记事本全程保存聊天记录、查到的资料、用户信息所有节点都可以读、可以改这个本子。流程一步一步走START 开始 → 【LLM 节点理解用户问题】 AI 先看懂你想问啥把信息写到记事本。【菱形判断是否需要检索资料】✅是跑去检索节点查资料查到的内容写到记事本然后回到这个判断点❌否直接跳到生成回答【LLM 节点生成回答】 AI 结合记事本里的内容写出答案。【菱形判断是否满意】✅是结束 END❌否回到前面重新理解问题再来一遍循环图例小说明绿色圆圈起点 / 终点蓝色方框干活的步骤节点紫色菱形做选择、判断分支实线箭头固定往下走虚线箭头读取 / 修改那个记事本State 状态右侧LangGraph 核心能力状态管理全程维护记事本保存中间所有信息条件流转与循环可以判断满足条件就循环跑这就是 Agent 反复思考的基础持久化与恢复保存进度中断之后继续跑人工干预Human-in-the-loop流程跑到关键地方可以停下来交给人审核人确认完再继续流式输出、事件监听一边跑一边吐出结果实时看运行情况生态集成轻松对接大模型、检索工具、记忆库左下角能用在哪些场景智能对话多轮聊天复杂问答RAG查资料→生成答案→反复校验迭代智能 AgentAI 自己规划任务调用工具干活数据处理多步骤的数据清洗、汇总分析人工协同流程需要人中途审核的业务流程右下角对比传统 Chain传统 Chain一条直线一步接一步不能回头、没有记忆、不能中断走完就结束。LangGraph非线性有分支、有循环带着 “记事本”可以暂停、回退可控。最简单类比传统 Chain食堂流水线菜按顺序走一遍不能回头。 LangGraph你派一个助理办事。 助理拿个记事本State接到问题先判断要不要查资料写完答案还要检查行不行不行就重新查、重新写甚至做到一半喊你过来看看你点头了再继续。一句面试版回答LangGraph 用图来表达 Agent 的控制流用 State 表达业务数据用节点承载具体动作用边表达顺序和路由。相比一串if-else它把状态更新、并行合并、暂停恢复和执行轨迹变成了可观察、可持久化的运行时语义。五天压缩成一句话Day 1 画图Day 2 解释数据怎么合并Day 3 控制流程怎么分支/循环/并行Day 4 让流程能记住并等待人Day 5 把 Agent 组合起来并部署。最重要的六个词词面试中要说明什么State图中流转的业务数据不是随手传参的黑盒字典Reducer同一字段多次写入时的合并规则Conditional edge根据状态选择下一条路径Send运行时动态创建多个并行 workerCheckpointer把执行状态保存成可恢复的检查点Interrupt把控制权交给人再用Command恢复2. 五天知识地图阶段核心问题关键 API能完成的项目Day 1 基础怎么把流程画成可执行图StateGraph、START、END、add_node、add_edge、compile多节点文本处理流水线Day 2 状态数据为什么覆盖、累加或冲突TypedDict、Annotated、Reducer、add_messages、RunnableConfig、stream_mode多源信息汇总 AgentDay 3 控制流流程如何选择、循环、并行和嵌套add_conditional_edges、recursion_limit、Subgraph、Send、Command研究管线、质量检查和重试Day 4 持久化流程如何记忆、暂停、恢复checkpointer、thread_id、get_state、interrupt、update_state、task带人工审批的发布工作流Day 5 生产化Agent 如何组合并部署create_agent、Supervisor、langgraph.json、langgraph dev、LangSmith多专家报告生成系统更适合复述的依赖关系StateGraph - State Node Edge - Reducer 解决多次写入 - Conditional Edge / Send 解决动态控制 - Checkpointer thread_id 解决跨调用状态 - interrupt Command 解决人在回路 - Subgraph / create_agent 解决 Agent 组合 - langgraph.json tracing 解决上线与运维可单独渲染的知识地图见assets/knowledge-map.mmd。3. 核心心智模型3.1 图的三要素fromtyping_extensionsimportTypedDictfromlanggraph.graphimportStateGraph,START,ENDclassState(TypedDict):text:strsummary:strdefsummarize(state:State)-dict:return{summary:f文本长度:{len(state[text])}}builderStateGraph(State)builder.add_node(summarize,summarize)builder.add_edge(START,summarize)builder.add_edge(summarize,END)appbuilder.compile()resultapp.invoke({text:hello,summary:})回答时不要只背 API要说清职责StateGraph(State)声明图有哪些数据通道。add_node注册动作不决定业务顺序。add_edge决定依赖和执行顺序。compile()把声明式图变成可调用对象并做结构校验。invoke()适合拿最终结果stream()适合观察过程。3.2 节点不是“返回完整状态”节点通常只返回本次要更新的字段defclean_node(state:State)-dict:return{text:state[text].strip().lower()}这叫“返回即更新”返回的键会写回 State。没返回的键保持原值。不应直接依赖原地修改state来表达更新。默认写入语义是覆盖想累积必须显式声明 Reducer。3.3 建图、运行、排错三步建图先用纯函数节点验证拓扑和 State 字段。运行用invoke()验证最终值用stream()验证每个节点到底写了什么。排错先查 State schema再查节点返回键再查边和 Reducer最后才查模型提示词。这个顺序能快速区分“流程错”“数据合并错”和“模型输出错”。4. State、Reducer 与数据流4.1 默认覆盖 vs 显式合并fromoperatorimportaddfromtypingimportAnnotatedfromtyping_extensionsimportTypedDictclassState(TypedDict):draft:strlogs:Annotated[list[str],add]场景没有 Reducer配置 Reducer串行节点连续写draft后写覆盖先写按自定义规则合并并行节点同时写logsInvalidUpdateError按 Reducer 合并消息列表容易丢历史或误更新add_messages支持追加、按 ID 更新和删除Reducer 的统一视角defreducer(current_value,update_value):returnnew_value面试一定要说出参数顺序是“旧值、新值”并解释为什么它是并行写入的确定性边界。4.2add_messages与MessagesState消息状态不要简单使用普通列表拼接。add_messages能处理新消息追加。带相同 ID 的消息更新。RemoveMessage删除已有消息。消息对象和简短字典形式的兼容。fromtypingimportAnnotatedfromtyping_extensionsimportTypedDictfromlanggraph.graph.messageimportadd_messagesclassChatState(TypedDict):messages:Annotated[list,add_messages]如果状态只有消息可以使用官方预建的MessagesState如果还有业务字段再显式扩展自己的 schema。4.3config与state的分工维度stateconfig含义流程中的业务数据本次调用的运行时上下文例子query、draft、messagesthread_id、user_id、租户、运行参数是否进入业务结果通常会通常不会读取方式state[query]config[configurable][user_id]口诀state 是“流程正在处理什么”config 是“这次运行由谁、按什么方式处理”。4.4 并行与超步无依赖边的节点可以被放进同一个超步执行。多个节点在同一超步写同一个键时没有 Reducer框架拒绝猜测抛出并发更新错误。有 Reducer按明确规则合并。串行写同一键通常不会报错但可能静默覆盖仍然要检查业务语义。因此看到“并行 共享字段”第一反应应该是检查该字段是否声明了正确 Reducer。5. 控制流分支、循环、子图和并行5.1 固定边与条件边固定边builder.add_edge(load,transform)条件边defroute(state:State)-str:returnretryifstate[score]0.8elsefinishbuilder.add_conditional_edges(check,route,{retry:draft,finish:END},)路由函数返回的是映射表中的 key不一定是节点名。这样可以把“业务判断值”和“图节点命名”解耦。5.2 循环与recursion_limit循环本质上是条件边回到上游节点draft - check ^ | |------- score 不够循环必须同时具备明确的业务退出条件。运行时保险丝recursion_limit。达到上限时可识别、可恢复或可降级的错误处理。recursion_limit不能代替退出条件。它只是防止 bug、异常模型输出或数据污染把图无限运行下去。5.3 Subgraph子图是一个已经编译的图可以作为父图的节点expert_appexpert_builder.compile()parent_builder.add_node(researcher,expert_app)它适合把复杂业务隔离成独立模块。对专家图单独测试。在父图中复用同一套流程。让多 Agent 系统保持清晰边界。父图和子图之间只有双方都声明的字段才能自然穿透。子图私有字段不会自动泄漏到父图需要上报的字段要在两侧 schema 中对齐。5.4Send动态 map-reduceSend适用于运行时才知道要创建多少 worker 的场景fromlanggraph.typesimportSenddeffan_out(state:State):return[Send(worker,{item:item})foriteminstate[items]]要点Send走条件边通道。第一个参数是目标节点名。第二个参数是该 worker 的局部输入。多个 worker 的结果通常要写入带 Reducer 的汇聚字段。Send解决的是动态并行不是普通固定边。5.5CommandCommand可以同时完成两件事更新 State。指定下一步goto。这适合审批节点、动态分流节点和需要把判断结果与状态更新绑定在一起的流程。fromlanggraph.typesimportCommanddefdecide(state:State)-Command:ifstate[approved]:returnCommand(gotopublish,update{status:approved})returnCommand(gotocancel,update{status:rejected})6. 持久化、人在回路与 durable execution6.1 Checkpointer 与thread_id最小关系checkpointer 状态账本 thread_id 账本钥匙 checkpoint 某个执行时刻的快照编译时挂入 checkpointer调用时提供线程 IDfromlanggraph.checkpoint.memoryimportInMemorySaver appbuilder.compile(checkpointerInMemorySaver())config{configurable:{thread_id:ticket-001}}app.invoke({text:hello},config)关键边界没有 checkpointer两次调用通常互相独立。有 checkpointer 但没有thread_id运行时不知道读哪本账。InMemorySaver适合课堂和测试进程退出后数据会丢。生产场景需要持久后端并验证跨进程恢复。6.2 读取和改写检查点常用观察接口get_state(config)查看当前快照。get_state_history(config)查看历史链。snapshot.values快照中的状态值。snapshot.next恢复时下一步要执行的节点。update_state(config, values, as_node...)在断点处改写状态。6.3 动态中断与静态断点方式写在哪里适用场景interrupt(payload)节点内部运行到业务条件才请求人审批interrupt_before编译/调用配置不改节点代码统一在危险节点前拦截interrupt_after编译/调用配置节点执行后先审查结果动态审批的基本流程fromlanggraph.typesimportCommand,interruptdefask_approval(state:State):decisioninterrupt({prompt:是否发布,draft:state[draft],})return{approval:decision}# 暂停后由外部系统或人工决定app.invoke(Command(resumeapproved),config)6.4 最容易答错的“恢复”语义再次invoke不是恢复暂停后使用Command(resume...)才是恢复路径。原因是恢复时框架会从检查点重放流程。interrupt()之前的节点代码可能再次经过因此副作用不能裸写在中断前面。推荐做法把外部请求、写文件、扣款、发送通知等副作用包进task。把节点写成可重放、可观察、结果明确的单元。对任务设置合适的 retry、timeout 和降级策略。恢复时使用同一个编译后的 app 和同一个thread_id。6.5task的生产含义task不是“给函数加一个装饰器”这么简单它是 durable execution 的执行单元。面试时要说清checkpointer 保存进度。thread_id标识一条执行链。task保存副作用步骤的结果重放时避免重复执行。教程中的实测提醒task(timeout...)在当前教程环境中只对 async 任务有效。sync / async 组合要以当前版本验证。retry_policy解决可重试错误不能掩盖永久性业务错误。降级比无限重试更重要。7. Agent、多 Agent 与生产部署7.1create_agent与手写StateGraph方式优点适合create_agent快速得到模型与工具循环默认行为完整标准 Agent、快速原型手写StateGraph每个节点、边、状态和审批点都可控复杂业务流程、并行、精细治理子图 父图模块化、可复用、可单测多 Agent 和领域专家组合推荐表述create_agent是高层入口底层仍然可以理解为 LangGraph 的状态图。标准 Agent 先用高层入口提高开发速度需要控制循环、并行、审批或特殊状态时再下钻到手写StateGraph。旧资料中的create_react_agent需要谨慎对待。教程记录它已被create_agent取代新项目应优先采用当前官方入口。7.2 三种多 Agent 协作模式模式 A子图作为节点父图直接挂载专家子图parent_builder.add_node(researcher,researcher_app)parent_builder.add_node(writer,writer_app)优点是边界清晰、图可视化、专家可独立测试。模式 BSupervisor主编或协调 Agent 负责决定下一位专家supervisor - researcher - supervisor - writer - supervisor - finish适合任务顺序不固定、需要动态派单的场景。代价是协调逻辑和上下文传递更复杂。模式 C把专家包装成工具把专家 Agent 暴露成工具由模型自主决定是否调用。灵活但必须明确专家输入输出格式。上下文是否完整。失败和超时如何回传。什么时候应该改成显式子图以获得更强控制。7.3langgraph.json部署清单至少要让平台知道三件事字段作用dependencies安装哪些 Python 包graphs对外暴露哪些图格式通常是文件路径:导出变量env需要注入哪些环境变量常见坑graphs写了module:graph但模块中没有真正导出graph。把langgraph主包和 CLI 混为一谈langgraph dev可能需要单独安装 CLI。本地能导入不代表部署环境依赖完整。InMemorySaver能演示不等于生产可用。部署排查顺序先本地 import 目标模块。再验证graphs指向的对象存在。再检查依赖和环境变量。最后运行本地 dev 服务和真实 API 调用。7.4 生产级设计检查小节点一个节点做一件容易观察和重试的事。Reducer所有可能被多处写入的字段都明确合并规则。流式长任务优先提供stream尽早反馈进度。持久化审批、长任务和跨进程恢复不能依赖内存保存。容错重试、超时、降级和人工接管要有明确边界。可观测记录节点耗时、模型调用、token、重试和错误上下文。测试先测试纯函数节点再测试图拓扑最后测试模型和外部服务。8. 高频面试题与答题要点Q1LangGraph 和 LangChain 是什么关系答题要点LangChain 更偏模型、工具、消息和 Agent 组件。LangGraph 更偏有状态流程的图运行时。LangChain 的模型或工具可以作为 LangGraph 节点使用。真实项目通常是两者组合而不是二选一。Q2State、Node、Edge 分别负责什么答题要点State 定义共享数据和字段语义。Node 做动作并返回局部更新。Edge 表达依赖、顺序和路由。运行时负责调度、合并、流式和持久化。Q3为什么节点返回dict而不是直接修改state答题要点返回局部更新让框架知道本次写了哪些字段。没返回的字段可以保持不变。显式更新更容易做检查点、重放、流式和审计。原地修改会模糊写入边界也容易引入副作用。Q4字段默认是覆盖还是累积答题要点默认覆盖。需要累积时用Annotated[field_type, reducer]。messages通常用add_messages。Reducer 的签名是(current, update) - new。Q5两个并行节点同时写一个没有 Reducer 的字段会怎样答题要点同一超步发生多个更新框架无法判断合并顺序。会抛出并发更新错误而不是随机选择一个结果。给字段配置合适 Reducer或者改图让写入串行化。Q6updates和values有什么区别答题要点updates看每个节点写了什么增量。values看每一步的完整 State 快照。排查覆盖问题优先看updates。做 UI 或恢复状态展示时常看values。Q7固定边和条件边有什么区别答题要点add_edge代表固定依赖。add_conditional_edges通过路由函数选择路径。路由函数返回映射 key映射再指向真实节点。条件边适合分支、循环和动态结束。Q8recursion_limit能不能代替循环退出条件答题要点不能。退出条件是业务正确性。recursion_limit是运行时安全阀。两者都要有达到上限还要有可识别的错误处理。Q9Subgraph 解决什么问题答题要点把复杂流程封装为可复用、可单测的图。父图可以把编译后的子图当节点。父子之间通过共享字段传递数据。私有字段不会自动泄漏schema 不对齐时可能静默丢失。Q10Send和普通节点返回 State 有什么区别答题要点普通节点返回 State 更新。Send在运行时生成多个目标节点实例和局部输入。它适合动态 fan-out。worker 结果写回共享字段时必须考虑 Reducer。Q11Command有什么价值答题要点一个返回值同时表达状态更新和下一步去向。适合审批、动态 goto 和状态驱动路由。它把“做了什么”和“下一步去哪”绑定在一个业务决策中。Q12thread_id是什么答题要点它是 checkpointer 查找一条执行链的键。同一个线程可以恢复之前的状态。换线程通常就是新会话或新任务。生产中应让它对应明确业务实体例如工单、报告或订单。Q13再次invoke和Command(resume...)有什么区别答题要点再次invoke通常表示启动一次新的运行任务可能重跑。Command(resume...)是从 interrupt 检查点恢复。恢复涉及重放因此副作用必须用task或其他持久化边界保护。Q14interrupt()和静态断点有什么区别答题要点interrupt()写在节点内部条件满足时才暂停。interrupt_before/after是外部插桩不改业务节点。内容审批更适合动态 interrupt。统一审查危险节点更适合静态断点。Q15为什么 interrupt 前的代码可能执行两次答题要点恢复时节点从入口重放而不是从 Python 代码的某一行继续。interrupt 前的普通代码会再走一遍。有副作用的操作要移到task或中断之后并设计幂等性。Q16durable execution 的三个条件是什么答题要点有 checkpointer。调用时提供thread_id。非确定性或有副作用的工作包进task。Q17create_agent和手写StateGraph怎么选答题要点标准模型工具循环先用create_agent。需要精细控制状态、并行、审批、循环和节点边界时手写图。create_agent不妨碍继续使用 LangGraph 的流式、持久化和子图能力。Q18多 Agent 为什么需要 Supervisor答题要点Supervisor 负责拆解任务、选择专家、汇总结果。专家负责领域动作减少单个 Agent 的上下文和工具负担。代价是路由、共享状态和失败传播更复杂。如果顺序固定显式子图串联可能比 Supervisor 更简单。Q19langgraph.json的dependencies和graphs各管什么答题要点dependencies管安装什么。graphs管平台加载哪个模块中的哪个图对象。还要检查模块中确实存在导出变量。环境变量配置不能代替图对象导出。Q20如何设计一个生产级 LangGraph 系统答题要点按四层回答建模层State schema、Reducer、节点边界。控制层条件边、循环、并行、子图和审批。运行层checkpointer、thread、stream、task、重试和超时。运维层部署清单、环境变量、日志、trace、指标和回归测试。9. 综合项目多专家报告系统这是最适合面试现场讲解的综合例子输入主题 | 研究专家子图 | 写作专家子图 | 校对专家子图 | 人工审批 interrupt | approved | rejected 保存终稿 取消并记录原因面试讲解顺序建议ReportState存主题、研究结果、草稿、最终报告、审批状态和消息。三个专家分别是可单测的子图。子图之间通过父图共享字段传递结果。proof完成后进入interrupt把草稿预览交给审批人。Command(resume...)恢复后用Command(goto...)分流。checkpointer thread_id让审批任务可跨调用恢复。stream_modeupdates让前端看到每个专家完成进度。langgraph.json导出最终图生产环境替换内存检查点并开启 tracing。一张更适合讲项目的流程图见assets/interview-project-flow.mmd。10. 排错清单结果字段为空或被覆盖State schema 是否声明了该字段节点返回的 key 是否拼写一致字段是覆盖语义还是需要 Reducer是否有并行节点同时写入用stream_modeupdates找到最后一个写入者。对话没有记忆是否编译时传入 checkpointer每次调用是否复用了同一个thread_idmessages是否配置了add_messages是否错误地重建了 app导致拿到新的内存账本恢复后重复调用外部服务是否把副作用放在了 interrupt 前是否使用了task是否把“再 invoke”误当成“resume”外部接口是否具备幂等键部署加载失败langgraph.json是否存在且格式正确graphs是否是正确的文件:变量目标模块是否真的导出了graph依赖包是否在dependencies中必要环境变量是否注入11. 一页式复习顺序第 1 轮说清框架背出 State、Node、Edge 的职责。手写最小StateGraph。解释invoke()和stream()。第 2 轮说清数据默写 Reducer 签名。解释默认覆盖和并行冲突。解释add_messages、config和state。第 3 轮说清控制手写一个条件边。解释循环退出和recursion_limit。解释 Subgraph、Send、Command的边界。第 4 轮说清可靠性解释 checkpointer、thread_id、get_state。解释 interrupt 的暂停与恢复。解释为什么副作用要进task。第 5 轮说清生产比较create_agent和手写图。讲一种多 Agent 协作模式及取舍。讲清langgraph.json和 tracing。用综合项目串起全部能力。12. 官方资料与本地教程官方资料入口LangGraph OverviewLangGraph PersistenceLangGraph StreamingLangGraph InterruptsLangGraph Durable ExecutionLangChain Multi-agentLangSmith Observability最后记忆句状态负责记节点负责做边负责走条件边负责选Reducer 负责合并子图负责组合检查点负责存活interrupt 负责交权stream 负责让过程可见。