本节在全册位置:沉淀可复用的纪律。图式编排最易犯的错是「把控制流塞进 prompt」与「状态塞太多」。下面给出一组经过验证的模式,照着做能少走弯路。这些模式不是教条,而是前面各章踩坑的抽象。
一、状态只放跨节点数据,临时变量留局部。二、循环必须配退出条件,防死循环。三、敏感/写操作前置 interrupt 人工确认。四、可序列化优先,密钥不进状态。五、结构优先声明式,流向数据驱动才用编程式。这些模式在前面章都有对应落点。类比物理:像工程规范,照做少出事故。纪律提前遵循,比事后返工省得多。
# 模式三的通用封装:任何写操作加人工闸 from langgraph.types import interrupt from langgraph.graph import Command def human_gate(s, action): decision = interrupt({"action": action, "preview": s}) if decision != "allow": return Command(goto=END, update={"blocked": True}) return {} # 这是上线前最该加的一层
# 模式二的退出守卫:计数通道防死循环 from typing import TypedDict, Annotated import operator class S(TypedDict): round: Annotated[int, operator.add] def guard(s): return END if s["round"] >= 5 else "loop" # 软上限(模型自报)加硬上限(计数),双保险
背景:初版把整个流程写进一个超长 prompt,常跑飞且无审计。
操作:按上面五条重构成图:状态瘦身、循环加守卫、写操作加闸。
结果:稳定性与可维护性明显提升,排障时间大幅下降。
解读:模式的价值在「提前避坑」,而非事后补救,复盘的意义是把它变成团队习惯。
变式:把模式固化成团队内部节点模板库,新图直接套,一致性也更好。

状态只放跨节点数据,临时变量留局部,这是状态设计的第一纪律。
循环必须配退出条件,敏感写操作前置 interrupt 人工确认,密钥不进状态。
结构优先声明式,流向数据驱动才用编程式,这五条在前面章都有对应落点。
初版把整个流程写进一个超长 prompt,常跑飞且无审计;按五条重构成图后稳定性与可维护性明显提升,复盘的意义是把它变成团队习惯,比事后返工省得多。
五条纪律若只停留在文档,等于没写;把它变成「提交前可跑的检查」,团队才会真的遵守。
# 极简图结构体检(示意) def lint(graph): problems = [] if not graph.checkpointer: problems.append("缺检查点:状态不可恢复") if any(n.has_side_effect and not n.has_gate for n in graph.nodes): problems.append("写节点缺人工闸") if not graph.has_loop_guard: problems.append("循环缺退出守卫") return problems # 纪律从「人记得」变成「机器拦」
| 纪律 | 检查项 | 不达标后果 |
|---|---|---|
| 状态瘦身 | 无活资源 | 序列化失败 |
| 循环守卫 | 有退出条件 | 死循环 |
| 写操作闸 | 前置 interrupt | 误写 |
| 密钥隔离 | 不进状态 | 泄露 |
| 声明式优先 | 少动态路由 | 难调试 |
⚠️ 常见坑:五条写成 wiki 就结束,没人回看,事故照旧;纪律要落到 CI 检查或节点模板,强制生效才有意义。
💡 关键直觉:设计模式的价值不在「知道」,而在「每次新建图都自动符合」;把模式固化进模板与检查,是最省心的方式。
补充:检查单别只给开发看,运维与产品也该参与评审——安全与可恢复性往往是他们最先感知到问题,跨职能过一遍比开发自审更稳。
五条纪律要落地,最直接的方式是把它固化进建图模板,让每张新图从第一行起就符合纪律:
# 新图脚手架:状态、守卫、人工闸一起到位 class S(TypedDict): msgs: Annotated[list, add_messages] # 消息通道 round: Annotated[int, operator.add] # 循环计数(守卫用) errors: Annotated[list, operator.add] # 错误记录(降级用) def build(): b = StateGraph(S) b.add_node("agent", call_model) # 主体节点 b.add_conditional_edges("agent", route) # 路由 + 循环守卫 return b.compile(checkpointer=MemorySaver())
脚手架的要点是「三件套默认在场」:消息通道、循环计数、错误记录。业务加节点时在这套骨架上填,而不是每次从零想状态。模板不是限制,是让团队里每个人写的图都长一个样子——结构统一了,互相 review 的成本就低。
五条纪律的反面就是常见事故,列成对照表,评审时逐条对:
| 反模式 | 表现 | 后果 | 纠正 |
|---|---|---|---|
| 巨型 prompt | 流程全写进提示词 | 不可审计、常跑飞 | 控制流搬到图里 |
| 状态当仓库 | 什么字段都塞 | 检查点爆炸 | 只放跨节点字段 |
| 循环无守卫 | 条件边永远为真 | 成本失控 | 计数加硬上限 |
| 写操作裸放 | 发信改库直接执行 | 误操作事故 | 前置 interrupt |
| 动态路由滥用 | 全图 Command | 静态调试失效 | 收敛到声明式 |
评审时不用背条款,对照这张表看新图踩了几条就行。反模式之所以顽固,是因为它们写起来快、报错晚——违反纪律的代价通常在一周后才显现。把表放进评审模板,让检查发生在写代码时而不是出事时。
评审一张新图时,用下面六问代替泛泛的「你觉得怎么样」:
六问里只要有一问答不上来,就先别合代码。这些问题本身比答案更重要——它们迫使作者把图当「设计文档」而非「实现代码」来审视。把提问清单和脚手架一起放进团队的建图规范,五条纪律就从「记得」变成了「默认」。