langgraph
langgraph copied to clipboard
how update graph state
eg:
# Define the agent def run_agent(data): agent_outcome = agent_runnable.invoke(data) logger.warning(f"Agent outcome: {data}") data['define state attr'] = "" return {"agent_outcome": agent_outcome}
Hi @linpan , tl;dr, each node can return a dictionary. If a key in the dictionary matches a key in the state, a state update will be performed. Other keys will be ignored.
The state update by default is to overwrite the existing state. You can update that behavior via type annotations on the state.
So if you're defining your graph like this:
def run_agent(data):
agent_outcome = agent_runnable.invoke(data)
logger.warning(f"Agent outcome: {data}")
data['define state attr'] = ""
return {"agent_outcome": agent_outcome}
from langgraph.graph import StateGraph, END
from typing import TypedDict, Any
class MyGraphState(TypedDict):
messages: List[BaseMessage]
agent_outcome: Any
builder = StateGraph(state)
builder.add_node("agent", run_agent)
builder.set_entry_point("agent")
...
chain = builder.compile()
chain.invoke(...)
any time run_agent returns, the agent_outcome variables is updated to whatever is returned by agent_runnable.invoke()
You can update this behavior to be e.g., append
only by using Annotated
attribution on the graph state.
thks.
Hi @hinthornw,
What if I want to update the state values with the tool call? Is there a way to do it? My understanding was if a tool call returns a dict() with a key present in the state, then it would automatically be updated in the state values? Am I wrong in my understanding here?
Thank you in advance, Vishwas
Hi @hinthornw,
What if I want to update the state values with the tool call? Is there a way to do it? My understanding was if a tool call returns a dict() with a key present in the state, then it would automatically be updated in the state values? Am I wrong in my understanding here?
Thank you in advance, Vishwas
Yes. You can also decide whether you want to replace or add to an existing list.
@hinthornw is it possible to initialise a state value while defining it? I tried doing value: str = 'abc'
but when I test it, I get an empty object
Is it possible to modify multiple state value using a single node/function?
Hi @hinthornw, What if I want to update the state values with the tool call? Is there a way to do it? My understanding was if a tool call returns a dict() with a key present in the state, then it would automatically be updated in the state values? Am I wrong in my understanding here? Thank you in advance, Vishwas
Yes. You can also decide whether you want to replace or add to an existing list.
I tested this out with a custom tool like below, it seems there's no way around returning the tool message 'content' or 'content, artifact'. If I was to return a dictionary, it would just return the whole dictionary as the tool message content.
Is a custom subclass base tool like this what you also meant? If not, any idea how we could update state in a custom tool like this?
The only thing that comes to mind is InjectedState but 1) that seems like an ugly anti pattern like weirdly mutating state that no one knows about. 2) The docs only show how to use InjectedState with @tools, not the subclass base tool, although I could probably get this to work with enough tinkering, still doesn't solve 1.
I'm thinking if you want to do this you need to call all your tools as functions, like have a switch statement in should_continue with the tool names and then just run the tool from a function. Then you are directly returning state, although it doesn't seem as clean as being able to integrate with LangChain custom tools classes.
class CustomBaseTool(BaseTool): """Custom Tool."""
name: str = "custom_tool"
description: str = """this is a custom tool."""
response_format: str = "content_and_artifact"
args_schema: Type[BaseModel] = _CustomBaseTool
Is it possible to modify multiple state value using a single node/function?
Yes, it is.