Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement vector memory #13352

Merged
merged 39 commits into from
May 25, 2024
Merged

Implement vector memory #13352

merged 39 commits into from
May 25, 2024

Conversation

jerryjliu
Copy link
Collaborator

@jerryjliu jerryjliu commented May 8, 2024

UPDATE

  • Re-jigged vector memory to only supply list of chat messages and not handle any thing having to do with composing messages
  • Added BaseComposableMemory and SimpleComposableMemory for better separation of concerns
    • With this class, now we can pass a VectorMemory and ChatMemoryBuffer to a SimpleComposableMemory which will do a simple composition on the messages that are retrieved by all of its memory sources
  • Modified vector_memory.ipynb and added new composable_memory.ipynb (added these to docs as well)
  • Added these classes to api reference (I think?)

OLDER

was way harder than i originally anticipated, summary of main changes:

general interface stuff:

  • added input argument to get function in memory
  • added put_messages to memory
  • replaced all memory.set(..) calls in the agent with memory.put_messages in terms of updating state
  • added BaseChatStoreMemory for all memory modules that depend on a chat store

implemented vector memory:

  • track each "node" in a vector index
  • each "node" is by default a group of messages, instead of a single message. this is because if we index individual messages, we'll retrieve just the user message or just the assistant message, but not both. you may end up retrieving a user message and an unrelated assistant message leading to hallucinations
  • we track the current "message batch" in the chat store, to accumulate user message, then assistant/tool msgs, etc.
  • we also track all message ids in a separate collection in the chat store. this is to allow us to perform deletes, which right now consists of deleting messages one by one.
  • NOTE: deletes from vector stores are hard, we do some hacks to make delete_ref_doc work

@dosubot dosubot bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label May 8, 2024
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@jerryjliu jerryjliu marked this pull request as draft May 8, 2024 04:43
self.vector_index.delete_nodes([last_node_id])

self.vector_index.insert_nodes([super_node])
self.chat_store.add_message(self.chat_store_key, ChatMessage(content=node_id))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little confused on the flow here

The chat store is keeping track of the inserted node ids (effectively maintaining order)? Not 100% sure what override last is for

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so I think override_last is needed since we're updating the "batch" as we go. So if its not the end of the batch, we gotta delete the last entered node, and replace it in favor with the newly updated one... i.e. one that has the latest message.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The chat_store is acting as a temp buffer (I think you had mentioned before, and I'm just getting caught up with now) to track the current user batch i.e., group.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah tbh it's a bit hacky, and we're not using chatstore for its intended purpose. but if we want to batch messages together we need some way of making sure the latest node is 1) always updated, but 2) can still be returned as part of vector search

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see working PR here for removing chat_store as buffer: #13729

@nerdai nerdai marked this pull request as ready for review May 21, 2024 15:35
@nerdai nerdai changed the title [WIP] implement vector memory Implement vector memory May 21, 2024
chat_store: BaseChatStore = Field(default_factory=SimpleChatStore)
# NOTE/TODO: we need this to store id's for the messages
# This is not needed once vector stores implement delete_all capabilities
chat_store_key: str = Field(default=DEFAULT_CHAT_STORE_KEY)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm i guess we don't have delete_all in the vector store yet, so we still need to maintain a list of all the ids

maybe fine for now, but may want to change this later to make vector memory less brittle (right now the chat store is in memory, so if we try to reinitialize the vector memory module there's no easy way to delete old data in vector memory)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have a clear() method now that should delete all. Tbh, wasn't 100% clear on what this note meant. Are you saying that we only need chat_store to maintain the id's. And, since we have "clear()we can implement this without thechat_store`?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah basically. i think we still need the cur_user_msg_key for batching, but we no longer need to have a chat store track all user ids

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm still hung up on this, but if we do a delete_all on the vector store, wouldn't that remove all past batches in addition to the current running batch? I think we would want to delete the current running batch so that we can start a new one with the incoming user message?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left this for a future PR, but have started a working branch/PR for this that removes chat_store. I have effectively got it working, but it needs further polishing.

#13729

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label May 24, 2024
@nerdai nerdai enabled auto-merge (squash) May 25, 2024 10:26
@nerdai nerdai merged commit 7a7cc05 into main May 25, 2024
8 checks passed
@nerdai nerdai deleted the jerry/memory_modules branch May 25, 2024 10:34
DarkLight1337 added a commit to DarkLight1337/llama_index that referenced this pull request May 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm This PR has been approved by a maintainer size:XXL This PR changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants