diff --git a/docs/docs/how-tos/input_output_schema.ipynb b/docs/docs/how-tos/input_output_schema.ipynb index 9811b7a70..955c182b0 100644 --- a/docs/docs/how-tos/input_output_schema.ipynb +++ b/docs/docs/how-tos/input_output_schema.ipynb @@ -7,7 +7,7 @@ "source": [ "# How to define input/output schema for your graph\n", "\n", - "By default, `StateGraph` takes in a single schema and all nodes are expected to communicate with that schema. However, it is also possible to define explicit input and output schemas for a graph. This is helpful if you want to draw a distinction between input and output keys.\n", + "By default, `StateGraph` takes in a single schema and all nodes are expected to communicate with that schema. However, it is also possible to define explicit input and output schemas for a graph. Often, in these cases, we define an \"internal\" schema that contains all keys relevant to graph operations. But, we use specific input and output schemas to filter what's permitted when invoking and what's returned. We use type hints below to, for example, show that the output of `answer_node` will be filtered to `OutputState`. In addition, we define each node's input schema (e.g., as state: `OverallState` for `answer_node`).\n", "\n", "In this notebook we'll walk through an example of this. At a high level, in order to do this you simply have to pass in `input=..., output=...` when defining the graph. Let's see an example below!\n", "\n", @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 5, "id": "6ec0eb77-874e-443e-8c73-93125b515106", "metadata": {}, "outputs": [ @@ -60,7 +60,7 @@ "{'answer': 'bye'}" ] }, - "execution_count": 12, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -77,16 +77,18 @@ "class OutputState(TypedDict):\n", " answer: str\n", "\n", + "class OverallState(InputState, OutputState):\n", + " pass\n", "\n", "def answer_node(state: InputState):\n", " return {\"answer\": \"bye\"}\n", "\n", "\n", - "graph = StateGraph(input=InputState, output=OutputState)\n", - "graph.add_node(answer_node)\n", - "graph.add_edge(START, \"answer_node\")\n", - "graph.add_edge(\"answer_node\", END)\n", - "graph = graph.compile()\n", + "builder = StateGraph(OverallState, input=InputState, output=OutputState)\n", + "builder.add_node(answer_node)\n", + "builder.add_edge(START, \"answer_node\")\n", + "builder.add_edge(\"answer_node\", END)\n", + "graph = builder.compile()\n", "\n", "graph.invoke({\"question\": \"hi\"})" ] @@ -116,7 +118,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.1" + "version": "3.11.9" } }, "nbformat": 4, diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py index 809531f5f..3a20a06ab 100644 --- a/libs/langgraph/langgraph/graph/state.py +++ b/libs/langgraph/langgraph/graph/state.py @@ -23,6 +23,7 @@ from pydantic import BaseModel from pydantic.v1 import BaseModel as BaseModelV1 +from langgraph._api.deprecation import LangGraphDeprecationWarning from langgraph.channels.base import BaseChannel from langgraph.channels.binop import BinaryOperatorAggregate from langgraph.channels.dynamic_barrier_value import DynamicBarrierValue, WaitForNames @@ -139,6 +140,12 @@ def __init__( if input is None or output is None: raise ValueError("Must provide state_schema or input and output") state_schema = input + warnings.warn( + "Initializing StateGraph without state_schema is deprecated. " + "Please pass in an explicit state_schema instead of just an input and output schema.", + LangGraphDeprecationWarning, + stacklevel=2, + ) else: if input is None: input = state_schema