-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[feat] Markdown Agent Context Handling #2934
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
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…ed the exmaple with outputs.
…search and the compression function from ChatAgent (avoid duplication)
Full problem description in #2919 This PR enables the compression of the memory context when it gets too long and bloated by setting a threshold on the number of messages/tokens used. It calls the agent and asks it to provide a summary of all the messages so far (including things done, tools called, user preferences, etc.) and saves it in a A The PR needs more edits and tests, the goal is to lock in the overall design so far. |
… a dedicated summarization agent to avoid circular calls during memory management.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @hesamsheikh 's contribution and sorry for the late review, left some comment below, I think we need to re-think the design. Would it be more tidy and high-efficient we manage everything within the Toolkit part? for one ChatAgent
, it could be stateless and only has the sys message, for each running the agent would call MarkdownMemoryToolkit
to get all the information from the .md file first, and after the execution it will record necessary content to the .md file. We can focus on the design of the toolkit itself to manage the context like how could be better link summarized information to the original information more accurate and high-efficient
thanks for the feedback @Wendong-Fan . if i remember correctly you mentioned to do the context summarization programmatically as opposed to doing it through agentic tool call, so does it make sense to focus on the toolkit? but in any case i made a fast refactor so please let me know if this is what you have in mind generally speaking. |
when I run the example code from the logo there's
|
Regarding my suggestion to handle the context store programmatically, your implementation in this pull request: https://github.com/camel-ai/camel/pull/2934/files#diff-da970aa6abc4c4210d4c69e073e39de90db0992ef64c461b31952e5e5a2f653aR220 is the approach I had in mind |
…n, added test cases, simplified the search function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @hesamsheikh ! Left some comments below
camel/memories/agent_memories.py
Outdated
@@ -43,6 +43,7 @@ def __init__( | |||
context_creator: BaseContextCreator, | |||
storage: Optional[BaseKeyValueStorage] = None, | |||
window_size: Optional[int] = None, | |||
warn_on_empty: bool = True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add docstring for this new arg
# Only warn if required | ||
if self.warn_on_empty: | ||
warnings.warn("The `ChatHistoryMemory` is empty.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we'd better not skip the warning by add one additional argument, the think the casedef retrieve
is called but the ChatHistoryMemory
is empty is not expected
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think this behavior happens when clear_memory() method in ChatAgent is called.
- self.memory.clear() - empties the memory
- self.update_memory(self.system_message,
OpenAIBackendRole.SYSTEM) - tries to re-add
system message - Inside update_memory(), it calls
self.memory.get_context() for token calculation - get_context() retrieves from empty memory →
triggers warning
without this if statement, every time the context is summarized the developer will see a warning which might be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be better to update the logic of def update_memory
in ChatAgent
?
# always overwrite if it exists (for compression use case) | ||
note_path.write_text(content, encoding="utf-8") | ||
|
||
# register note if it's new | ||
if note_name not in self._note_toolkit.registry: | ||
self._note_toolkit._register_note(note_name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't accesses _register_note()
which is a private method of NoteTakingToolkit
,if this function is required we'd better add it under NoteTakingToolkit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think a cleaner approach would be to add an optional arg to the create_note
ffunciton of the NoteTakingToolkit
.
return self.existing_summary or "" | ||
|
||
# check for over-compression prevention | ||
record_ids = {id(record) for record in memory_records} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would use uuid be better? use id()
could cause memory issues since these IDs may not be stable across garbage collection cycles, and the set grows indefinitely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could go for a better approach, but we basically need these records in the lifetime of a task/agentic session. wouldn't it be overengineering it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think given the stateful nature of agent, ensuring the integrity of the conversation history is critical, if there's case message is skipped due to same id()
, it would be very hard to debug, MemoryRecord
already has a uuid field, we could use it directly
…erwrite arg to notetakingtoolkit
ccd3b75
to
7415562
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks @hesamsheikh ! LGTM
Description
related to #2919
Checklist
Go over all the following points, and put an
x
in all the boxes that apply.Fixes #issue-number
in the PR description (required)pyproject.toml
anduv lock
If you are unsure about any of these, don't hesitate to ask. We are here to help!