Hi looking for some guidance to see if there are any established patterns for solving an issue we’re having building an agent. (this is a simplified example).
Agent Setup
We have an agent that has a state_schema of:
class AgentState(AgentState):
item_color: str
item_size: str
And that agent is created with an AsyncPostgresSaver from langgraph.checkpoint.postgres.aio
# pseudocode
checkpointer = AsyncPostgresSaver(db_connection_here)
agent = create_agent(
prompt...
tools...
state_schema=AgentState
).compile(checkpointer=checkpointer)
Our agent can reference and update these the item_color and item_size through various tools.
Agent Use
So a conversation might start out and the agent might save item details as:
item_color = 'blue'
item_size = 'large'
A user could resume that conversation (thread) at a later date and ask about the item, and the agent could look at the state, and let the user know what the item details are. All is well.
Agent Modification
But down the line, we decide as a dev team that the AgentState isn’t sufficient as is, we need to expand it like so:
class Item():
item_color: str
item_size: str
item_type: str
class AgentState(AgentState):
items: List[Item]
Now our system is built to support tracking of multiple items, and our state is updated to reflect that. The agent now has tools that can reason about two items, comparing them and such.
If we start a new conversation with this updated agent, it works as expected.
Previous Conversations with New State
But how do we handle old conversations? We don’t want to break all chats that are saved for users currently. But if a user tries to resume a chat that existed with the old item_color, item_size state, then our tools won’t properly be able to get item information because they are expected a items key with an array of item details.
This is a contrived example above but the principle is how are state/graph changes handled over time for existing threads/checkpoints? We are using the provided AsyncPostgresSaver and one idea we had was to run a custom db migration to update all the item_color, item_size info to the update state object (items). But the checkpointer library stores things across tables in blobs… I think we’re nervous about the risk of trying to accomplish that.
Anyone else run into this or know of documentation or solutions to this problem? This isn’t a one-time concern either, maybe in the future we update the state to be a higher level products which might include items as one type, and then we run into the same issue.
Thanks in advance!