From d9c0a5d827ade21b0d676903f2dc4b24311cc625 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Wed, 11 Dec 2024 11:40:09 -0500 Subject: [PATCH] x --- docs/docs/concepts/human_in_the_loop.md | 35 ++++++++++++------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/docs/docs/concepts/human_in_the_loop.md b/docs/docs/concepts/human_in_the_loop.md index 47c37dd37..d2ad6fa49 100644 --- a/docs/docs/concepts/human_in_the_loop.md +++ b/docs/docs/concepts/human_in_the_loop.md @@ -38,7 +38,7 @@ graph = graph_builder.compile( checkpointer=checkpointer # Required for `interrupt` to work ) -# Run the graph and hit the breakpoint +# Run the graph until the interrupt thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(some_input, config=thread_config) @@ -52,7 +52,7 @@ To use `interrupt` in your graph, you need to: 1. [**Specify a checkpointer**](persistence.md#checkpoints) to save the graph state after each step. 2. **Call `interrupt()`** in the appropriate place. See the [Design Patterns](#design-patterns) section for examples. -3. **Run the graph** with a [**thread ID**](./persistence.md#threads) to pause execution at the breakpoint. +3. **Run the graph** with a [**thread ID**](./persistence.md#threads) until the `interrupt` is hit. 4. **Resume execution** using `invoke`/`ainvoke`/`stream`/`astream` (see [**The `Command` primitive**](#the-command-primitive)). ## Design Patterns @@ -99,7 +99,7 @@ def human_approval(state: State) -> Command[Literal["some_node", "another_node"] graph_builder.add_node("human_approval", human_approval) graph = graph_builder.compile(checkpointer=checkpointer) -# After running the graph and hitting the breakpoint, the graph will pause. +# After running the graph and hitting the interrupt, the graph will pause. # Resume it with either an approval or rejection. thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke(Command(resume=True), config=thread_config) @@ -141,7 +141,7 @@ graph = graph_builder.compile(checkpointer=checkpointer) ... -# After running the graph and hitting the breakpoint, the graph will pause. +# After running the graph and hitting the interrupt, the graph will pause. # Resume it with the edited text. thread_config = {"configurable": {"thread_id": "some_id"}} graph.invoke( @@ -236,7 +236,7 @@ it may be part of a larger graph consisting of multiple nodes and include a cond graph_builder.add_edge("human_input", "agent") graph = graph_builder.compile(checkpointer=checkpointer) - # After running the graph and hitting the breakpoint, the graph will pause. + # After running the graph and hitting the interrupt, the graph will pause. # Resume it with the human's input. graph.invoke( Command(resume="hello!"), @@ -306,13 +306,13 @@ def human_node(state: State): ## The `Command` primitive -When using the `interrupt` function, the graph will pause at the breakpoint and wait for user input. +When using the `interrupt` function, the graph will pause at the interrupt and wait for user input. Graph execution can be resumed using the [Command](../reference/types.md#langgraph.types.Command) primitive which can be passed through the `invoke`, `ainvoke`, `stream` or `astream` methods. The `Command` primitive provides several options to control and modify the graph's state during resumption: -1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. The `resume` value is only used when using `interrupt` as a breakpoint. +1. **Pass a value to the `interrupt`**: Provide data, such as a user's response, to the graph using `Command(resume=value)`. Execution resumes from the beginning of the node where the `interrupt` was used, however, this time the `interrupt(...)` call will return the value passed in the `Command(resume=value)` instead of pausing the graph. ```python # Resume graph execution with the user's input. @@ -331,12 +331,12 @@ By leveraging `Command`, you can resume graph execution, handle user inputs, and ## Using with `invoke` and `ainvoke` -When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know that a breakpoint has been hit. +When you use `stream` or `astream` to run the graph, you will receive an `Interrupt` event that let you know the `interrupt` was triggered. `invoke` and `ainvoke` do not return the interrupt information. To access this information, you must use the [get_state](../reference/graphs.md#langgraph.graph.graph.CompiledGraph.get_state) method to retrieve the graph state after calling `invoke` or `ainvoke`. ```python -# Run the graph up to the breakpoint +# Run the graph up to the interrupt result = graph.invoke(inputs, thread_config) # Get the graph state to get interrupt information. state = graph.get_state(thread_config) @@ -362,20 +362,20 @@ graph.invoke(Command(resume={"age": "25"}), thread_config) ) # Pending tasks. interrupts ``` -## How does resuming from a breakpoint work? +## How does resuming from an interrupt work? !!! warning Resuming from an `interrupt` is **different** from Python's `input()` function, where execution resumes from the exact point where the `input()` function was called. -A critical aspect of using breakpoints is understanding how resuming from a breakpoint works. When you resume execution after a breakpoint, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. +A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution after an `interrupt`, graph execution starts from the **beginning** of the **graph node** where the last `interrupt` was triggered. -**All** code from the beginning of the node to the **breakpoint** will be re-executed. +**All** code from the beginning of the node to the `interrupt` will be re-executed. ```python counter = 0 def node(state: State): - # All the code from the beginning of the node to the breakpoint will be re-executed + # All the code from the beginning of the node to the interrupt will be re-executed # when the graph resumes. global counter counter += 1 @@ -393,15 +393,15 @@ Upon **resuming** the graph, the counter will be incremented a second time, resu The value of counter is: 2 ``` -## Gotchyas +## Common Pitfalls !!! warning - Resuming from a breakpoint is **different** from traditional breakpoints or Python's `input()` function, where execution resumes from the exact point where the breakpoint was triggered or where the `input()` function was called. + Resuming from a interrupt is **different** from using Python's `input()` function, where execution resumes from the exact point where `input()` was called. -A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the last breakpoint was triggered. +A critical aspect of using `interrupt` is understanding how resuming works. When you resume execution, the graph execution starts from the **beginning** of the **graph node** where the `interrupt` was triggered. -**All** code from the beginning of the node to the **breakpoint** will be re-executed. +**All** code from the beginning of the node to the `interrupt` will be re-executed. ### Side-effects @@ -545,6 +545,5 @@ To avoid issues, refrain from dynamically changing the node's structure between ## Additional Resources 📚 - [**Conceptual Guide: Persistence**](persistence.md#replay): Read the persistence guide for more context on replaying. -- [**Conceptual Guide: Breakpoints**](breakpoints.md): Read the breakpoints guide for more context on breakpoints. - [**How to Guides: Human-in-the-loop**](../how-tos/index.md#human-in-the-loop): Learn how to implement human-in-the-loop workflows in LangGraph. - [**How to implement multi-turn conversations**](../how-tos/multi-agent-multi-turn-convo.ipynb): Learn how to implement multi-turn conversations in LangGraph.