diff --git a/docs/docs/concepts/low_level.md b/docs/docs/concepts/low_level.md index 297f97ec9..a3ab96bf1 100644 --- a/docs/docs/concepts/low_level.md +++ b/docs/docs/concepts/low_level.md @@ -353,6 +353,30 @@ def my_node(state: State) -> Command[Literal["my_other_node"]]: Check out this [how-to guide](../how-tos/command.ipynb) for an end-to-end example of how to use `Command`. +### Using inside tools + +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. To update the graph state from the tool, you can return `Command(update={"my_custom_key": "foo", "messages": [...]})` from the tool: + +```python +@tool +def lookup_user_info(tool_call_id: Annotated[str, InjectedToolCallId], config: RunnableConfig): + """Use this to look up user information to better assist them with their questions.""" + user_info = get_user_info(config.get("configurable", {}).get("user_id")) + return Command( + update={ + # update the state keys + "user_info": user_info, + # update the message history + "messages": [ToolMessage("Successfully looked up user information", tool_call_id=tool_call_id)] + } + ) +``` + +!!! important + You MUST include `messages` (or any state key used for the message history) in `Command.update` when returning `Command` from a tool and the list of messages in `messages` MUST contain a `ToolMessage`. This is necessary for the resulting message history to be valid (LLM providers require AI messages with tool calls to be followed by the tool result messages). + +If you are using tools that update state via `Command`, we recommend using prebuilt [`ToolNode`][langgraph.prebuilt.tool_node.ToolNode] which automatically handles tools returning `Command` objects and propagates them to the graph state. If you're writing a custom node that calls tools, you would need to manually propagate `Command` objects returned by the tools as the update from node. + ## Persistence LangGraph provides built-in persistence for your agent's state using [checkpointers][langgraph.checkpoint.base.BaseCheckpointSaver]. Checkpointers save snapshots of the graph state at every superstep, allowing resumption at any time. This enables features like human-in-the-loop interactions, memory management, and fault-tolerance. You can even directly manipulate a graph's state after its execution using the diff --git a/docs/docs/how-tos/command.ipynb b/docs/docs/how-tos/command.ipynb index b0ab12188..acc9ff2b4 100644 --- a/docs/docs/how-tos/command.ipynb +++ b/docs/docs/how-tos/command.ipynb @@ -171,7 +171,7 @@ "source": [ "!!! important\n", "\n", - " You might have noticed that we used `Command` as a return type annotation, e.g. `Command[Literal[\"node_b\", \"node_c\"]]`. This is necessary for the graph compilation and rendering, and tells LangGraph that `node_a` can navigate to `node_b` and `node_c`." + " You might have noticed that we used `Command` as a return type annotation, e.g. `Command[Literal[\"node_b\", \"node_c\"]]`. This is necessary for the graph rendering and tells LangGraph that `node_a` can navigate to `node_b` and `node_c`." ] }, {