START与END

图必须有唯一入口明确终止;否则调度器不知道从哪跑、何时停。STARTEND 是 LangGraph 提供的虚拟节点,标记图的入口与出口,不参与业务逻辑。


1. 定位

维度 内容
角色 图边界标记:入口调度、终止判定
输入 → 输出 add_edge(START, first_node) 指定首节点;到达 END 即结束 invoke
核心 API STARTEND(自 langgraph.graph
依赖 LangChain 无;纯拓扑概念

2. 图拓扑

节点表

节点名 职责 读 State 写 State
init 初始化计数 count
increment 自增 count count
done 标记完成 count status

边表

目标 类型
START init 固定(唯一入口)
init increment 固定
increment done 固定
done END 固定(唯一出口)

START / END 不是业务节点,不能 add_node("START", ...)


3. invoke 生命周期

1
2
3
4
5
1. invoke 传入 initial_state
2. 调度器从 START 出发,找 add_edge(START, *) 的后继 → init
3. 依次执行 init → increment → done
4. 遇到指向 END 的边,invoke 结束,返回最终 state
5. 若某节点无出边且未连 END → 运行错误

Superstep:本篇线性三节点,共 3 个 superstep;到达 END 后不再调度。


4. 原理

4.1 START 的多后继

通常 START 只连一个节点;若需条件分支,用 add_conditional_edges(START, router, path_map) 从入口分流(见路由专篇)。

4.2 END 与提前结束

条件边可路由到 END,实现「满足条件即终止」,无需经过后续节点。

4.3 与 compile 校验

编译期会检查孤立节点、无法到达 END 的子图(部分版本为运行时暴露)。


5. 最小可运行示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from typing import TypedDict

from langgraph.graph import StateGraph, START, END


class State(TypedDict):
count: int
status: str


def init_node(_: State) -> dict:
return {"count": 0}


def increment_node(state: State) -> dict:
return {"count": state["count"] + 1}


def done_node(state: State) -> dict:
return {"status": f"done at {state['count']}"}


builder = StateGraph(State)
builder.add_node("init", init_node)
builder.add_node("increment", increment_node)
builder.add_node("done", done_node)
builder.add_edge(START, "init")
builder.add_edge("init", "increment")
builder.add_edge("increment", "done")
builder.add_edge("done", END)

graph = builder.compile()
print(graph.invoke({"count": -1, "status": ""}))
# {'count': 1, 'status': 'done at 1'}

5.1 条件边直达 END

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from typing import Literal

def router(state: State) -> Literal["continue", "stop"]:
return "stop" if state.get("count", 0) >= 5 else "continue"

builder2 = StateGraph(State)
builder2.add_node("increment", increment_node)
builder2.add_conditional_edges(
START,
lambda s: "stop" if s.get("count", 0) >= 3 else "continue",
{"continue": "increment", "stop": END},
)
builder2.add_edge("increment", END)
graph2 = builder2.compile()
print(graph2.invoke({"count": 3, "status": ""})) # 直接 END

6. 执行追踪

线性示例(§5):count=-1 → init 后 0 → increment 后 1 → done 后 status="done at 1"

提前 END(§5.1):count=3 → router 返回 stop → 无节点执行 → 返回初始 state。


重要配置参数

参数 类型 / 默认 作用与影响 参考起点 配置指导
START 常量 图入口 必须连至少一条出边 勿当普通节点
END 常量 图终止 path_map 值可为 END 环图需 router 跳出
add_edge(START, node) 固定入口 单入口场景 多入口用条件边
add_conditional_edges(START, ...) 入口分流 按输入类型路由 router 键必须在 path_map
path_map 含 END dict 提前终止 "stop": END 键名与 router 一致
invoke 无 END 路径 图挂起/报错 自检边表 每分支都要能到 END

7. 易踩坑

  1. 忘记连 END:最后节点无出边,invoke 异常或状态不完整。
  2. 把 END 写成字符串 "END":应使用导入的 END 常量。
  3. 环图无退出边:router 永远不进 END,invoke 超步数或死循环。

小结

  • START = 唯一入口调度点;END = 正常终止。
  • 条件边可把 END 作为目标,实现提前结束。
  • 画边表时先确认每条路径最终能到达 END

参考链接

-------------本文结束感谢您的阅读-------------