You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@[`Command`] is a versatile primitive for controlling graph execution. It accepts four parameters:
1045
+
1046
+
-`update`: Apply state updates (similar to returning updates from a node).
1047
+
-`goto`: Navigate to specific nodes (similar to [conditional edges](#conditional-edges)).
1048
+
-`graph`: Target a parent graph when navigating from [subgraphs](/oss/langgraph/use-subgraphs).
1049
+
-`resume`: Provide a value to resume execution after an [interrupt](/oss/langgraph/interrupts).
1050
+
1051
+
`Command` is used in three contexts:
1052
+
1053
+
-**[Return from nodes](#return-from-nodes)**: Use `update`, `goto`, and `graph` to combine state updates with control flow.
1054
+
-**[Input to `invoke`/`stream`](#input-to-invokestream)**: Use `resume` to continue execution after an interrupt.
1055
+
-**[Return from tools](#return-from-tools)**: Similar to return from nodes, combine state updates and control flow from inside a tool.
1056
+
1057
+
### Return from nodes
1058
+
1059
+
#### `update` and `goto`
1060
+
1061
+
Return @[`Command`] from node functions to update state and route to the next node in a single step:
1062
+
1044
1063
:::python
1045
-
It can be useful to combine control flow (edges) and state updates (nodes). For example, you might want to BOTH perform state updates AND decide which node to go to next in the SAME node. LangGraph provides a way to do so by returning a @[`Command`] object from node functions:
# Command will NOT prevent "node_a" from going to "node_b"
1076
-
```
1077
-
1078
-
In the example above, **"node_a"** will go to both **"node_b"** and **"my_other_node"**.
1083
+
Use @[`Command`] when you need to **both** update state **and** route to a different node. If you only need to route without updating state, use [conditional edges](#conditional-edges) instead.
1079
1084
1080
1085
<Note>
1081
1086
@@ -1086,7 +1091,6 @@ When returning @[`Command`] in your node functions, you must add return type ann
1086
1091
:::
1087
1092
1088
1093
:::js
1089
-
It can be useful to combine control flow (edges) and state updates (nodes). For example, you might want to BOTH perform state updates AND decide which node to go to next in the SAME node. LangGraph provides a way to do so by returning a @[`Command`] object from node functions:
Note that @[Command] only adds dynamic edges, while static edges will still execute. In other words, @[Command] doesn't override static edges.
1118
-
1119
-
```typescript
1120
-
graph.addNode("nodeA", (state) => {
1121
-
if (state.foo==="bar") {
1122
-
returnnewCommand({
1123
-
update: { foo: "baz" },
1124
-
goto: "myOtherNode",
1125
-
});
1126
-
}
1127
-
});
1128
-
1129
-
// Add a static edge from "nodeA" to "nodeB"
1130
-
graph.addEdge("nodeA", "nodeB")
1131
-
1132
-
// Command will NOT prevent "nodeA" from going to "nodeB"
1133
-
```
1134
-
1135
-
In the example above, **"nodeA"** will go to both **"nodeB"** and **"myOtherNode"**.
1121
+
Use @[`Command`] when you need to **both** update state **and** route to a different node. If you only need to route without updating state, use [conditional edges](#conditional-edges) instead.
1136
1122
1137
1123
When using @[`Command`] in your node functions, you must add the `ends` parameter when adding the node to specify which nodes it can route to:
Check out this [how-to guide](/oss/langgraph/use-graph-api#combine-control-flow-and-state-updates-with-command) for an end-to-end example of how to use @[`Command`].
1133
+
<Warning>
1148
1134
1149
-
### When should I use command instead of conditional edges?
1135
+
@[`Command`] only adds dynamic edges — static edges defined with `add_edge` / `addEdge` still execute. For example, if `node_a` returns `Command(goto="my_other_node")` and you also have `graph.add_edge("node_a", "node_b")`, both `node_b` and `my_other_node` will run.
1136
+
1137
+
</Warning>
1150
1138
1151
-
- Use @[`Command`] when you need to **both** update the graph state **and** route to a different node. For example, when implementing [multi-agent handoffs](/oss/langchain/multi-agent/handoffs) where it's important to route to a different agent and pass some information to that agent.
1152
-
- Use [conditional edges](#conditional-edges) to route between nodes conditionally without updating the state.
1139
+
Check out this [how-to guide](/oss/langgraph/use-graph-api#combine-control-flow-and-state-updates-with-command) for an end-to-end example of how to use @[`Command`].
1153
1140
1154
-
###Navigating to a node in a parent graph
1141
+
#### `graph`
1155
1142
1156
1143
:::python
1157
-
If you are using [subgraphs](/oss/langgraph/use-subgraphs), you might want to navigate from a node within a subgraph to a different subgraph (i.e. a different node in the parent graph). To do so, you can specify`graph=Command.PARENT` in @[`Command`]:
1144
+
If you are using [subgraphs](/oss/langgraph/use-subgraphs), you can navigate from a node within a subgraph to a different node in the parent graph by specifying`graph=Command.PARENT` in @[`Command`]:
Setting `graph` to `Command.PARENT` will navigate to the closest parent graph.
1171
1158
1172
-
1173
1159
When you send updates from a subgraph node to a parent graph node for a key that's shared by both parent and subgraph [state schemas](#schema), you **must** define a [reducer](#reducers) for the key you're updating in the parent graph state. See this [example](/oss/langgraph/use-graph-api#navigate-to-a-node-in-a-parent-graph).
1174
1160
1175
1161
</Note>
1176
1162
1177
1163
:::
1178
1164
1179
1165
:::js
1180
-
If you are using [subgraphs](/oss/langgraph/use-subgraphs), you might want to navigate from a node within a subgraph to a different subgraph (i.e. a different node in the parent graph). To do so, you can specify`graph: Command.PARENT` in `Command`:
1166
+
If you are using [subgraphs](/oss/langgraph/use-subgraphs), you can navigate from a node within a subgraph to a different node in the parent graph by specifying`graph: Command.PARENT` in `Command`:
1181
1167
1182
1168
```typescript
1183
1169
import { Command } from"@langchain/langgraph";
@@ -1201,26 +1187,113 @@ When you send updates from a subgraph node to a parent graph node for a key that
1201
1187
1202
1188
:::
1203
1189
1204
-
This is particularly useful when implementing [multi-agent handoffs](/oss/langchain/multi-agent/handoffs).
1190
+
This is particularly useful when implementing [multi-agent handoffs](/oss/langchain/multi-agent/handoffs). Check out [this guide](/oss/langgraph/use-graph-api#navigate-to-a-node-in-a-parent-graph) for detail.
1205
1191
1206
-
Check out [this guide](/oss/langgraph/use-graph-api#navigate-to-a-node-in-a-parent-graph) for detail.
1192
+
### Input to `invoke`/`stream`
1207
1193
1208
-
### Using inside tools
1194
+
:::python
1209
1195
1210
-
A common use case is updating graph state from inside a tool. For example, in a customer support application you might want to look up customer information based on their account number or ID in the beginning of the conversation.
1196
+
<Warning>
1211
1197
1212
-
Refer to [this guide](/oss/langgraph/use-graph-api#use-inside-tools) for detail.
1198
+
`Command(resume=...)` is the **only**`Command` pattern intended as input to `invoke()`/`stream()`. Do not use`Command(update=...)` as input to continue multi-turn conversations — because passing any `Command` as input resumes from the latest checkpoint (i.e. the last step that ran, not `__start__`), the graph will appear stuck if it already finished. To continue a conversation on an existing thread, pass a plain input dict:
1213
1199
1214
-
### Human-in-the-loop
1200
+
```python
1201
+
# WRONG — graph resumes from the latest checkpoint
`new Command({ resume: ... })` is the **only**`Command` pattern intended as input to `invoke()`/`stream()`. Do not use `new Command({ update: ... })` as input to continue multi-turn conversations — because passing any `Command` as input resumes from the latest checkpoint (i.e. the last step that ran, not `__start__`), the graph will appear stuck if it already finished. To continue a conversation on an existing thread, pass a plain input object:
1222
+
1223
+
```typescript
1224
+
// WRONG — graph resumes from the latest checkpoint
@[`Command`] is an important part of human-in-the-loop workflows: when using `interrupt()` to collect user input, @[`Command`] is then used to supply the input and resume execution via `Command(resume="User input")`. Check out [this conceptual guide](/oss/langgraph/interrupts) for more information.
1239
+
1240
+
Use `Command(resume=...)` to provide a value and resume graph execution after an [interrupt](/oss/langgraph/interrupts). The value passed to `resume` becomes the return value of the `interrupt()` call inside the paused node:
# First invocation — hits the interrupt and pauses
1251
+
result = graph.invoke({"messages": [...]}, config)
1252
+
1253
+
# Resume with a value — the interrupt() call returns "yes"
1254
+
result = graph.invoke(Command(resume="yes"), config)
1255
+
```
1256
+
1257
+
Check out the [interrupts conceptual guide](/oss/langgraph/interrupts) for full details on interrupt patterns, including multiple interrupts and validation loops.
1258
+
1218
1259
:::
1219
1260
1220
1261
:::js
1221
-
@[`Command`] is an important part of human-in-the-loop workflows: when using `interrupt()` to collect user input, @[`Command`] is then used to supply the input and resume execution via `new Command({ resume: "User input" })`. Check out the [human-in-the-loop conceptual guide](/oss/langgraph/interrupts) for more information.
1262
+
1263
+
Use `new Command({ resume: ... })` to provide a value and resume graph execution after an [interrupt](/oss/langgraph/interrupts). The value passed to `resume` becomes the return value of the `interrupt()` call inside the paused node:
Check out the [interrupts conceptual guide](/oss/langgraph/interrupts) for full details on interrupt patterns, including multiple interrupts and validation loops.
1282
+
1222
1283
:::
1223
1284
1285
+
### Return from tools
1286
+
1287
+
You can return @[`Command`] from tools to update graph state and control flow. Use `update` to modify state (e.g., saving customer information looked up during a conversation) and `goto` to route to a specific node after the tool completes.
1288
+
1289
+
<Warning>
1290
+
1291
+
When used inside tools, `goto` adds a dynamic edge — any static edges already defined on the node that called the tool will still execute.
1292
+
1293
+
</Warning>
1294
+
1295
+
Refer to [this guide](/oss/langgraph/use-graph-api#use-inside-tools) for detail.
1296
+
1224
1297
## Graph migrations
1225
1298
1226
1299
LangGraph can easily handle migrations of graph definitions (nodes, edges, and state) even when using a checkpointer to track state.
- The value passed to `Command(resume=...)` becomes the return value of the @[`interrupt`] call
95
95
- The node restarts from the beginning of the node where the @[`interrupt`] was called when resumed, so any code before the @[`interrupt`] runs again
96
96
- You can pass any JSON-serializable value as the resume value
97
+
98
+
<Warning>
99
+
100
+
`Command(resume=...)` is the **only**`Command` pattern intended as input to `invoke()`/`stream()`. The other `Command` parameters (`update`, `goto`, `graph`) are designed for [returning from node functions](/oss/langgraph/graph-api#command). Do not pass `Command(update=...)` as input to continue multi-turn conversations — pass a plain input dict instead.
- The value passed to `new Command({ resume: ... })` becomes the return value of the @[`interrupt`] call
122
129
- The node restarts from the beginning of the node where the @[`interrupt`] was called when resumed, so any code before the @[`interrupt`] runs again
123
130
- You can pass any JSON-serializable value as the resume value
131
+
132
+
<Warning>
133
+
134
+
`new Command({ resume: ... })` is the **only**`Command` pattern intended as input to `invoke()`/`stream()`. The other `Command` parameters (`update`, `goto`, `graph`) are designed for [returning from node functions](/oss/langgraph/graph-api#command). Do not pass `new Command({ update: ... })` as input to continue multi-turn conversations — pass a plain input object instead.
0 commit comments