LangGraph 复习:从 0 到生产级 Agent

April 24, 2026

LangGraph 复习:从 0 到生产级 Agent

LangGraph Crash Course · Python OSS

面向工程落地的速成版:把企业最常问的 LangGraph 问题,映射到可执行的图、状态、持久化、人机中断、记忆与评测方法。

写在前面:这篇文章的“企业高频问题”来自公开生产场景的共性抽象,不是单一公司的封闭题库。时间基准为 2026-04-24

很多人第一次接触 LangGraph,重点会放在“把图连起来”。
但企业面试与真实项目更关心的是另一组问题:状态如何恢复、故障如何重试、人工如何介入、输出如何约束、多 Agent 何时该上

TL;DR

你会被问什么面试官真正想验证什么
为什么要 LangGraph,不直接 while loop你是否理解“可控 agent runtime”而不是“demo 脚本”
checkpointerthread_id 怎么设计你是否能处理中断恢复与多会话隔离
interrupt 放在哪一层你是否能做 Human-in-the-loop 的审批闭环
结构化输出怎么防半截 JSON你是否懂 schema 约束与降级路径
多 Agent 什么时候值得上你是否懂复杂度收益比,而不是盲目拆节点
线上怎么排障你是否有观察性与回放调试思维

阅读路径

如果你是第一次系统用 LangGraph,建议按下面顺序读:

  1. 先看“最小可运行范式”,把 State + Router + Checkpoint + Interrupt 跑通。
  2. 再看“企业最常问的 7 个问题”,建立面试与项目的统一答题框架。
  3. 最后刷附录分组题库,按岗位重点背诵 A/B/E 三组。

一、10 分钟建立 LangGraph 心智模型

把 LangGraph 想成“图形化的 agent runtime”更准确。它不只负责调一次模型,而是管理一条有状态的执行路径。

概念你要掌握的最小定义企业常追问
State一次执行过程中可读可写的共享状态字段怎么演进,如何避免状态污染
Node一个确定职责的执行单元节点粒度怎么定,如何避免上帝节点
Edge节点间转移规则路由为何可解释,失败路径在哪
Checkpoint图执行快照如何恢复,恢复到哪一步
Thread多轮会话上下文容器thread_id 规则、并发隔离、清理策略
Interrupt人工审批中断点谁审批、超时怎么办、恢复命令是什么

官方文档把 LangGraph 的核心收益定义为 durable execution、human-in-the-loop、comprehensive memory、debugging with LangSmith。这四项正好对应企业面试的高频问题轴。

二、最小可运行范式(Python)

下面是一个最小的生产思维版本:
有状态、有路由、有持久化、有中断点、可恢复。

from typing import Literal, TypedDict
 
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.graph import END, START, StateGraph
from langgraph.types import interrupt
 
 
class ChatState(TypedDict):
    user_query: str
    need_approval: bool
    approved: bool
    answer: str
 
 
def router(state: ChatState) -> Literal["approval_gate", "finalize"]:
    if state["need_approval"] and not state["approved"]:
        return "approval_gate"
    return "finalize"
 
 
def approval_gate(state: ChatState) -> ChatState:
    decision = interrupt(
        {
            "kind": "approval",
            "reason": "sensitive_action",
            "question": "Allow this action?",
        }
    )
    return {**state, "approved": bool(decision)}
 
 
def finalize(state: ChatState) -> ChatState:
    if state["need_approval"] and not state["approved"]:
        return {**state, "answer": "Rejected by reviewer."}
    return {**state, "answer": f"Done: {state['user_query']}"}
 
 
graph = StateGraph(ChatState)
graph.add_node("approval_gate", approval_gate)
graph.add_node("finalize", finalize)
graph.add_conditional_edges(START, router)
graph.add_edge("approval_gate", "finalize")
graph.add_edge("finalize", END)
 
compiled = graph.compile(checkpointer=InMemorySaver())
 
config = {"configurable": {"thread_id": "tenant-a:user-42:chat-001"}}
result = compiled.invoke(
    {
        "user_query": "Delete stale records",
        "need_approval": True,
        "approved": False,
        "answer": "",
    },
    config,
)
print(result["answer"])

这段代码值得记住的不是 API 名字,而是顺序:

  1. 先定义状态契约,再写节点逻辑。
  2. 先固定路由边界,再引入模型决策。
  3. 先接入 checkpoint,再谈故障恢复。

LangGraph runtime map: state, router, checkpoint, interrupt, resume

这张图讲的不是“节点怎么连线”这么简单,而是 LangGraph runtime 怎么把一条生产级执行链真正拼完整。你可以把它理解成五件套:主流程、状态持久化、人工审批、失败恢复、可观测性

  1. 主干流程:上面这条线是 START -> Router Node -> Tool Node -> ENDSTART 接收输入,通常会同时带上 thread_idRouter Node 先用规则做确定性判断,必要时再让模型兜底决定下一步;Tool Node 才是真正执行外部动作的位置,例如写库、发消息、调用第三方 API;最后 END 输出最终结果。关键点不是“有几个节点”,而是把决策节点和副作用节点分开,这样路由、审批、恢复都会更清晰。

  2. Checkpoint:中间蓝框表示状态快照持久化。persist state snapshot 的意思是把当前 state 和执行位置一起存下来;resume by thread_id 表示后续可以靠 thread_id 找回同一条执行链继续跑。它解决的不是日志留痕,而是可恢复执行:进程重启、长流程跨轮、人工审批后继续,都依赖这层。

  3. Interrupt Gate (HITL):右侧红框表示 Human-in-the-Loop。它的作用是在高风险动作前显式暂停,等人工给出批准、拒绝或补充信息,再恢复图执行。这也是为什么 interrupt(...) 最好放在“外部副作用发生之前”,而不是藏在工具内部;否则流程虽然能停,但审批边界不清楚,也不利于审计。

  4. Failure Handling:右下角棕框强调生产系统不能把所有错误都当成一种错误处理。可恢复失败通常是超时、瞬时依赖故障、可重试工具异常,这类问题适合 retry 或从 checkpoint 恢复;不可恢复失败则要升级告警、人工接管,必要时执行补偿动作。换句话说,LangGraph 的价值不只是“失败了”,而是“失败后按类型进入不同路径”

  5. Observability Signals:左下角绿框是线上排障和评测的基础。至少要采集节点延迟、重试次数、路由决策、工具错误这些信号,它们会直接决定你能不能 replay 一次故障现场、能不能做回归检查、能不能知道问题到底出在路由、工具还是生成层。很多团队的问题不是图没搭出来,而是图跑起来后不可解释、不可回放、不可比较

一句话看完整张图:LangGraph 不只是把节点串起来执行,而是围绕 thread_id + checkpoint 搭出了一套可暂停、可恢复、可审批、可观测的 agent runtime。

如果你要把这张图记成面试回答,可以直接压缩成一句:LangGraph 的生产价值不在“图”本身,而在 durable execution、HITL、failure recovery 和 observability 这几层 runtime 能力。

三、为什么这些问题“企业高频”

截至 2026-04,官方公开案例覆盖客服、招聘、代码助手、安全运营、地产等多行业场景。
业务不同,但追问结构高度一致:稳定性、可控性、可恢复、可观测

企业会问什么本质上在验证什么对应能力
进程重启后如何继续你是否有 durable execution 思维checkpointer + thread_id
人工审批怎么接入你是否能做风控闭环interrupt
输出如何稳定入库你是否有结构化约束意识schema / structured output
多 agent 如何不失控你是否懂复杂度治理rule route + worker 边界
出问题怎么定位你是否具备运维与评测意识tracing + replay + regression

公开案例里常见的名字包括 Klarna、Replit、Elastic、LinkedIn、Uber、GitLab、AppFolio、Rakuten、BlackRock、Cisco Outshift。公司不同,问题同构。

四、企业最常问的 7 个 LangGraph 问题

问题 1:为什么 checkpointer 在生产里不是可选项

短答:没有 checkpoint,就没有真正意义上的 durable execution。进程重启、超时重试、人工审批恢复都会变脆弱。

工程落点

  • 每次图执行都要绑定 thread_id
  • 关键节点后持久化,确保“重放不是重算全部”。
  • 将恢复策略写进运行手册,而不是只存在代码注释里。

高频误区:把“日志里能看到上一步输出”误当成“可恢复”。

问题 2:thread_id 到底怎么设计

短答thread_id 不是随机字符串,而是会话隔离主键,通常包含租户、用户、会话三个维度。

工程落点

  • 推荐稳定格式:tenant:user:session
  • 同一会话复用同一 thread_id,跨会话必须换新 ID。
  • 为归档和清理预留可解析维度,不要用不可读 UUID 直接裸放。

高频误区:前端每次请求都新建一个 thread_id,导致记忆断裂。

问题 3:interrupt 应该放在哪一层

短答:放在“高风险动作之前”,例如写库、发消息、下单、执行外部副作用工具前。

工程落点

  • 将中断点建模为显式节点,不要藏在工具函数内部。
  • 审批结果也写入状态,保证审计可追溯。
  • 设计超时策略:超时默认拒绝还是降级文本答复。

高频误区:把 HITL 做成前端弹窗逻辑,后端图状态无感知。

问题 4:结构化输出怎么防“半截 JSON”

短答:用 schema 驱动输出,并提供 fallback,不能只靠 prompt 写“请严格输出 JSON”。

工程落点

  • 关键链路使用结构化输出能力(schema / model)。
  • 解析失败时返回可恢复错误结构,而不是直接抛 500。
  • 将“传输协议正确”和“语义字段正确”分开验证。

高频误区:只做 json.loads 成功判断,不做字段级校验。

问题 5:多 Agent 什么时候值得上

短答:当子任务有稳定职责边界,且能并行或独立演进时才值得上;否则先单图多节点。

工程落点

  • 优先“一个 supervisor + 明确 worker”模式。
  • 先通过路由规则消化 70% 简单请求,再用模型兜底复杂路由。
  • 观察指标:延迟、token 成本、失败率、可解释性是否实质改善。

高频误区:为了“看起来先进”过度拆 worker,结果调试复杂度爆炸。

问题 6:记忆到底怎么分层

短答:至少分三层:执行态(state)、会话态(thread/checkpoint)、跨会话长期态(store/profile/cache)。

工程落点

  • 执行态只存本次流程必需字段。
  • 会话态解决多轮连续性与恢复。
  • 长期态只保留高价值稳定偏好,不把整段对话全量写入。

高频误区:把所有历史无差别堆进 prompt,导致成本高、噪声大。

问题 7:线上怎么排查“答得不对”

短答:先拆层定位:路由层、工具层、检索层、生成层,不要一上来换模型。

工程落点

  • 记录每个节点输入输出与耗时。
  • 对失败样本做回放,定位首个偏离节点。
  • 维护最小回归集,升级提示词或模型前后都跑一遍。

高频误区:把所有问题都归因到“模型能力不够”。

五、生产化最小清单

如果你只有一周时间把 demo 拉到可上线,这份最小清单够用。

  1. 每条执行链都显式绑定 thread_id
  2. 图必须启用 checkpointer,并验证恢复路径。
  3. 高风险节点前配置 interrupt 审批。
  4. 关键输出使用 schema 校验并定义 fallback。
  5. 路由优先规则化,模型只处理不确定场景。
  6. 全链路记录节点耗时、错误类型、重试次数。
  7. 建立至少 20 条高价值回归样本。
  8. 将“可恢复失败”与“不可恢复失败”分开处理。

六、附录:面试题和解答(分组题库)

A 组:架构与运行时(6 题)

A1. LangGraph 和传统 AgentExecutor 的核心区别是什么

  • 30 秒短答:LangGraph 把 agent 执行过程显式图化并状态化,天然支持可恢复、可中断、可路由,而不仅是线性调用链。
  • 面试官追问点:你如何定义节点边界和状态字段。
  • 高频误区:只回答“功能更多”,但说不出 runtime 价值。

A2. 什么时候应该用图,什么时候一个循环就够

  • 30 秒短答:需要显式分支、恢复、中断审批、可观测节点时用图;纯线性一次性任务用循环足够。
  • 面试官追问点:复杂度门槛怎么评估。
  • 高频误区:把所有任务都图化。

A3. 节点应该按业务拆还是按技术层拆

  • 30 秒短答:先按职责拆,再按可独立失败和可独立观测原则微调,不按文件夹结构机械拆。
  • 面试官追问点:你如何避免“上帝节点”。
  • 高频误区:节点过粗导致不可调试,或过细导致调度成本高。

A4. 边路由规则和模型路由如何配合

  • 30 秒短答:规则路由先处理高置信场景,模型路由兜底长尾不确定场景。
  • 面试官追问点:规则命中率与误路由率如何平衡。
  • 高频误区:全量依赖模型路由,成本和波动都高。

A5. 为什么说 thread_id 是运行时主键

  • 30 秒短答:它绑定会话状态和 checkpoint,决定恢复、追踪与隔离边界。
  • 面试官追问点:跨设备同一会话如何一致。
  • 高频误区:把 thread_id 和 request_id 混用。

A6. 如何给非技术面试官解释 LangGraph 价值

  • 30 秒短答:把“智能回答”变成“可管理流程”,能暂停审批、失败恢复、定位问题。
  • 面试官追问点:对业务 KPI 有何直接影响。
  • 高频误区:只讲术语,不讲风控与成本收益。

B 组:可靠性与可控性(6 题)

B1. Durable execution 的必要条件是什么

  • 30 秒短答:稳定状态模型 + checkpointer + 可重入节点逻辑。
  • 面试官追问点:重复执行如何做到幂等。
  • 高频误区:有日志就以为可恢复。

B2. 中断恢复为什么不能靠前端重发请求

  • 30 秒短答:前端重发无法保证图状态连续性,审批语义也会丢;恢复应基于持久化状态。
  • 面试官追问点:恢复后从哪一节点继续。
  • 高频误区:重放全部步骤导致副作用重复触发。

B3. 如何处理工具调用超时

  • 30 秒短答:在节点层定义超时与重试策略,超限后走降级分支并保留可观测错误码。
  • 面试官追问点:哪些错误可重试,哪些不可重试。
  • 高频误区:统一无限重试。

B4. 如何防止高风险工具被误调用

  • 30 秒短答:高风险工具白名单 + 参数校验 + interrupt 审批三道关。
  • 面试官追问点:紧急场景如何旁路审批。
  • 高频误区:只做提示词警告,不做系统级限制。

B5. 如何定义可恢复失败与不可恢复失败

  • 30 秒短答:可恢复失败指重试后状态一致且无副作用放大;不可恢复失败需人工介入或补偿流程。
  • 面试官追问点:补偿动作如何设计。
  • 高频误区:所有失败都自动重试。

B6. 线上事故后第一件事做什么

  • 30 秒短答:冻结可疑变更并抽样回放,先找“首个偏离节点”再定责。
  • 面试官追问点:如何避免事故复发。
  • 高频误区:先改 prompt 再定位。

C 组:多 Agent 与工具编排(6 题)

C1. 什么时候必须上 supervisor-worker

  • 30 秒短答:当任务天然有分工且需要并行或独立迭代时,例如检索、分析、写作链路明显分离。
  • 面试官追问点:拆分后怎么衡量收益。
  • 高频误区:单任务也硬拆多 agent。

C2. Worker 输出为什么必须结构化

  • 30 秒短答:结构化才能被上游可靠消费,减少 supervisor 对自由文本的脆弱解析。
  • 面试官追问点:字段变更如何兼容。
  • 高频误区:worker 只返回一段自然语言。

C3. 并行 worker 结果冲突怎么处理

  • 30 秒短答:定义仲裁策略,例如优先级、证据打分或 finalizer 合并规则。
  • 面试官追问点:冲突证据如何展示给用户。
  • 高频误区:简单拼接所有结果。

C4. 为什么需要工具调用预算

  • 30 秒短答:防止循环调用和成本失控,预算是 agent 系统的止损器。
  • 面试官追问点:预算耗尽后如何优雅降级。
  • 高频误区:只限制 token,不限制工具次数。

C5. 工具 schema 设计最重要的原则是什么

  • 30 秒短答:参数可验证、语义单一、失败可观测。
  • 面试官追问点:版本升级如何不破坏老调用。
  • 高频误区:一个工具承载多个业务语义。

C6. 如何降低模型选错工具的概率

  • 30 秒短答:缩小工具集合、强化工具描述差异、增加路由规则和拒答分支。
  • 面试官追问点:离线如何评估工具选择质量。
  • 高频误区:把所有工具都注册给同一个节点。

D 组:记忆与长期状态(5 题)

D1. 短期记忆和长期记忆怎么划线

  • 30 秒短答:短期记忆服务当前会话任务完成,长期记忆只保留稳定偏好与高价值事实。
  • 面试官追问点:长期记忆更新触发条件是什么。
  • 高频误区:把整段对话原样长期存储。

D2. 会话变长后上下文成本怎么控

  • 30 秒短答:摘要压缩 + 关键事实提取 + 检索增强,而不是全量拼接历史。
  • 面试官追问点:摘要漂移如何纠正。
  • 高频误区:每轮都把历史完整送入模型。

D3. 缓存和长期记忆的关系是什么

  • 30 秒短答:缓存解决重复查询性能,长期记忆解决跨会话个性化,两者目标不同。
  • 面试官追问点:缓存失效策略如何定。
  • 高频误区:把缓存命中当作用户记忆。

D4. 多租户下记忆隔离怎么做

  • 30 秒短答:命名空间至少带租户维度,读取和写入都做租户校验。
  • 面试官追问点:迁移租户数据如何审计。
  • 高频误区:只在 UI 层做隔离,存储层无隔离键。

D5. 何时应该删除记忆

  • 30 秒短答:用户撤回授权、事实过期、风险信息变更时应触发删除或失效。
  • 面试官追问点:删除后如何保证不再被召回。
  • 高频误区:只标记软删除,检索仍可命中。

E 组:评测与线上排障(5 题)

E1. LangGraph 项目最小评测集怎么建

  • 30 秒短答:覆盖主流程、长尾、失败恢复、审批中断四类样本,先小后全。
  • 面试官追问点:样本更新节奏如何定。
  • 高频误区:只用 happy path 做评测。

E2. 如何判断问题在路由层还是生成层

  • 30 秒短答:先看节点轨迹与工具调用,再看最终生成;路由错通常在前半链路就可见。
  • 面试官追问点:你会记录哪些关键字段。
  • 高频误区:直接改提示词掩盖路由缺陷。

E3. 为什么要做回放测试

  • 30 秒短答:回放可以复现实例输入与状态,定位回归是由模型、提示词还是路由变更引起。
  • 面试官追问点:回放如何保证数据脱敏。
  • 高频误区:线上出错后只看聚合指标。

E4. 你如何定义“上线可接受”

  • 30 秒短答:功能正确率、失败恢复率、审批漏检率、延迟和成本都要达标,不能只看回答流畅度。
  • 面试官追问点:阈值如何制定。
  • 高频误区:只做人工主观打分。

E5. 模型升级时最容易出什么问题

  • 30 秒短答:工具选择分布漂移、结构化输出偏移、长尾路由策略失效。
  • 面试官追问点:如何做灰度与回滚。
  • 高频误区:升级后不跑历史回归集。

七、面试速答总纲(可直接背)

  1. LangGraph 的核心价值是把 agent 变成可管理运行时,不是只会“多步调用”。
  2. 生产系统先回答可控性问题,再回答模型能力问题。
  3. checkpointer + thread_id + interrupt 是工程三件套。
  4. 路由优先规则化,模型兜底长尾。
  5. 评测必须覆盖失败与恢复路径,而不是只测成功样本。

参考资料