From 02a2467610efc41bbaf100fefe7f33e36f9843d8 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Fri, 27 Jun 2025 10:25:54 -0400 Subject: [PATCH] docs: context update (#5207) Update context --- docs/docs/agents/context.md | 234 ++++++++++++------------------ docs/docs/how-tos/tool-calling.md | 2 +- docs/mkdocs.yml | 2 +- 3 files changed, 93 insertions(+), 145 deletions(-) diff --git a/docs/docs/agents/context.md b/docs/docs/agents/context.md index 97e86ecb8..542379a44 100644 --- a/docs/docs/agents/context.md +++ b/docs/docs/agents/context.md @@ -1,17 +1,8 @@ ---- -search: - boost: 2 -tags: - - agent -hide: - - tags ---- - # Context -Agents often require more than a list of messages to function effectively. They need **context**. +**Context engineering** is the practice of building dynamic systems that provide the right information and tools, in the right format, so that a language model can plausibly accomplish a task. -Context includes *any* data outside the message list that can shape agent behavior or tool execution. This can be: +Context includes *any* data outside the message list that can shape behavior. This can be: - Information passed at runtime, like a `user_id` or API credentials. - Internal state updated during a multi-step reasoning process. @@ -22,18 +13,10 @@ LangGraph provides **three** primary ways to supply context: | Type | Description | Mutable? | Lifetime | |------------------------------------------------------------------------------|-----------------------------------------------|----------|-------------------------| | [**Config**](#config-static-context) | data passed at the start of a run | ❌ | per run | -| [**State**](#state-mutable-context) | dynamic data that can change during execution | ✅ | per run or conversation | -| [**Long-term Memory (Store)**](#long-term-memory-cross-conversation-context) | data that can be shared between conversations | ✅ | across conversations | +| [**Short-term memory (State)**](#short-term-memory-mutable-context) | dynamic data that can change during execution | ✅ | per run or conversation | +| [**Long-term memory (Store)**](#long-term-memory-cross-conversation-context) | data that can be shared between conversations | ✅ | across conversations | -You can use context to: - -- Adjust the system prompt the model sees -- Feed tools with necessary inputs -- Track facts during an ongoing conversation - -## Providing Runtime Context - -Use this when you need to inject data into an agent at runtime. +## Provide runtime context ### Config (static context) @@ -44,88 +27,83 @@ Specify configuration using a key called **"configurable"** which is reserved for this purpose: ```python -agent.invoke( - {"messages": [{"role": "user", "content": "hi!"}]}, +graph.invoke( # (1)! + {"messages": [{"role": "user", "content": "hi!"}]}, # (2)! # highlight-next-line - config={"configurable": {"user_id": "user_123"}} + config={"configurable": {"user_id": "user_123"}} # (3)! ) ``` -### State (mutable context) +1. This is the invocation of the agent or graph. The `invoke` method runs the underlying graph with the provided input. +2. This example uses messages as an input, which is common, but your application may use different input structures. +3. This is where you pass the configuration data. The `config` parameter allows you to provide additional context that the agent can use during its execution. -State acts as short-term memory during a run. It holds dynamic data that can evolve during execution, such as values derived from tools or LLM outputs. - -```python -class CustomState(AgentState): - # highlight-next-line - user_name: str - -agent = create_react_agent( - # Other agent parameters... - # highlight-next-line - state_schema=CustomState, -) - -agent.invoke({ - "messages": "hi!", - "user_name": "Jane" -}) -``` - -!!! tip "Turning on memory" - - Please see the [memory guide](../how-tos/memory/add-memory.md) for more details on how to enable memory. This is a powerful feature that allows you to persist the agent's state across multiple invocations. - Otherwise, the state is scoped only to a single agent run. - - - -### Long-Term Memory (cross-conversation context) - -For context that spans *across* conversations or sessions, LangGraph allows access to **long-term memory** via a `store`. This can be used to read or update persistent facts (e.g., user profiles, preferences, prior interactions). For more, see the [Memory guide](../how-tos/memory/add-memory.md). - -## Customizing Prompts with Context { #prompts } - -Prompts define how the agent behaves. To incorporate runtime context, you can dynamically generate prompts based on the agent's state or config. - -Common use cases: - -- Personalization -- Role or goal customization -- Conditional behavior (e.g., user is admin) - -=== "Using config" +=== "Agent prompt" ```python from langchain_core.messages import AnyMessage from langchain_core.runnables import RunnableConfig - from langgraph.prebuilt import create_react_agent from langgraph.prebuilt.chat_agent_executor import AgentState + from langgraph.prebuilt import create_react_agent - def prompt( - state: AgentState, - # highlight-next-line - config: RunnableConfig, - ) -> list[AnyMessage]: - # highlight-next-line + # highlight-next-line + def prompt(state: AgentState, config: RunnableConfig) -> list[AnyMessage]: user_name = config["configurable"].get("user_name") - system_msg = f"You are a helpful assistant. User's name is {user_name}" + system_msg = f"You are a helpful assistant. Address the user as {user_name}." return [{"role": "system", "content": system_msg}] + state["messages"] agent = create_react_agent( model="anthropic:claude-3-7-sonnet-latest", tools=[get_weather], - # highlight-next-line prompt=prompt ) agent.invoke( - ..., + {"messages": [{"role": "user", "content": "what is the weather in sf"}]}, # highlight-next-line config={"configurable": {"user_name": "John Smith"}} ) ``` -=== "Using state" + * See [Agents](../agents/agents.md) for details. + +=== "Workflow node" + + ```python + from langchain_core.runnables import RunnableConfig + + # highlight-next-line + def node(state: State, config: RunnableConfig): + user_name = config["configurable"].get("user_name") + ... + ``` + + * See [the Graph API](https://langchain-ai.github.io/langgraph/how-tos/graph-api/#add-runtime-configuration) for details. + +=== "In a tool" + + ```python + from langchain_core.runnables import RunnableConfig + + @tool + # highlight-next-line + def get_user_info(config: RunnableConfig) -> str: + """Retrieve user information based on user ID.""" + user_id = config["configurable"].get("user_id") + return "User is John Smith" if user_id == "user_123" else "Unknown user" + ``` + + See the [tool calling guide](../how-tos/tool-calling.md#configuration) for details. + +### Short-term memory (mutable context) + +State acts as [short-term memory](../concepts/memory.md) during a run. It holds dynamic data that can evolve during execution, such as values derived from tools or LLM outputs. + +=== "In an agent" + + Example shows how to incorporate state into an agent **prompt**. + + State can also be accessed by the agent's **tools**, which can read or update the state as needed. See [tool calling guide](../how-tos/tool-calling.md#short-term-memory) for details. ```python from langchain_core.messages import AnyMessage @@ -133,15 +111,14 @@ Common use cases: from langgraph.prebuilt import create_react_agent from langgraph.prebuilt.chat_agent_executor import AgentState - class CustomState(AgentState): - # highlight-next-line + # highlight-next-line + class CustomState(AgentState): # (1)! user_name: str def prompt( # highlight-next-line state: CustomState ) -> list[AnyMessage]: - # highlight-next-line user_name = state["user_name"] system_msg = f"You are a helpful assistant. User's name is {user_name}" return [{"role": "system", "content": system_msg}] + state["messages"] @@ -150,87 +127,58 @@ Common use cases: model="anthropic:claude-3-7-sonnet-latest", tools=[...], # highlight-next-line - state_schema=CustomState, - # highlight-next-line + state_schema=CustomState, # (2)! prompt=prompt ) agent.invoke({ "messages": "hi!", - # highlight-next-line "user_name": "John Smith" }) ``` -## Accessing Context in Tools { #tools } - -Tools can access context through special parameter **annotations**. - -* Use `RunnableConfig` for config access -* Use `Annotated[StateSchema, InjectedState]` for agent state + 1. Define a custom state schema that extends `AgentState` or `MessagesState`. + 2. Pass the custom state schema to the agent. This allows the agent to access and modify the state during execution. -!!! tip - - These annotations prevent LLMs from attempting to fill in the values. These parameters will be **hidden** from the LLM. - -=== "Using config" +=== "In a workflow" ```python - def get_user_info( - # highlight-next-line - config: RunnableConfig, - ) -> str: - """Look up user info.""" - # highlight-next-line - user_id = config["configurable"].get("user_id") - return "User is John Smith" if user_id == "user_123" else "Unknown user" + from typing_extensions import TypedDict + from langchain_core.messages import AnyMessage + from langgraph.graph import StateGraph - agent = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=[get_user_info], - ) + # highlight-next-line + class CustomState(TypedDict): # (1)! + messages: list[AnyMessage] + extra_field: int - agent.invoke( - {"messages": [{"role": "user", "content": "look up user information"}]}, - # highlight-next-line - config={"configurable": {"user_id": "user_123"}} - ) + # highlight-next-line + def node(state: CustomState): # (2)! + messages = state["messages"] + ... + return { # (3)! + # highlight-next-line + "extra_field": state["extra_field"] + 1 + } + + builder = StateGraph(State) + builder.add_node(node) + builder.set_entry_point("node") + graph = builder.compile() ``` + + 1. Define a custom state + 2. Access the state in any node or tool + 3. The Graph API is designed to work as easily as possible with state. The return value of a node represents a requested update to the state. -=== "Using State" - ```python - from typing import Annotated - from langgraph.prebuilt import InjectedState +!!! tip "Turning on memory" - class CustomState(AgentState): - # highlight-next-line - user_id: str + Please see the [memory guide](../how-tos/memory/add-memory.md) for more details on how to enable memory. This is a powerful feature that allows you to persist the agent's state across multiple invocations. Otherwise, the state is scoped only to a single run. - def get_user_info( - # highlight-next-line - state: Annotated[CustomState, InjectedState] - ) -> str: - """Look up user info.""" - # highlight-next-line - user_id = state["user_id"] - return "User is John Smith" if user_id == "user_123" else "Unknown user" +### Long-term memory (cross-conversation context) - agent = create_react_agent( - model="anthropic:claude-3-7-sonnet-latest", - tools=[get_user_info], - # highlight-next-line - state_schema=CustomState, - ) +For context that spans *across* conversations or sessions, LangGraph allows access to **long-term memory** via a `store`. This can be used to read or update persistent facts (e.g., user profiles, preferences, prior interactions). - agent.invoke({ - "messages": "look up user information", - # highlight-next-line - "user_id": "user_123" - }) - ``` - -### Update Context from Tools - -Tools can update agent's context (state and long-term memory) during execution. This is useful for persisting intermediate results or making information accessible to subsequent tools or prompts. See [Memory](../how-tos/memory/add-memory.md#read-short-term) guide for more information. \ No newline at end of file +For more information, see the [Memory guide](../how-tos/memory/add-memory.md). \ No newline at end of file diff --git a/docs/docs/how-tos/tool-calling.md b/docs/docs/how-tos/tool-calling.md index e60a2190d..a2e711ba3 100644 --- a/docs/docs/how-tos/tool-calling.md +++ b/docs/docs/how-tos/tool-calling.md @@ -507,7 +507,7 @@ def update_user_name( new_name: str, tool_call_id: Annotated[str, InjectedToolCallId] ) -> Command: - """Update user name in short-term memory.""" + """Update user-name in short-term memory.""" # highlight-next-line return Command(update={ # highlight-next-line diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index f5a928f01..883f4349b 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -153,7 +153,7 @@ nav: - Stream outputs: how-tos/streaming.md - Use Server API: cloud/how-tos/streaming.md - Context: - - Use in agent: agents/context.md + - Add context: agents/context.md - Memory: - Add memory: how-tos/memory/add-memory.md - Human-in-the-loop: