-
Notifications
You must be signed in to change notification settings - Fork 5k
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
[Feature Request]: Resumable GroupChat #2359
Comments
I'll start testing out methods to resume a GroupChat and publish any questions and findings here. |
Check the implementation of |
Yes, sorry, I meant to include that link. There were two notable omissions from the example code in that blog:
So, my full implementation is: from typing import Dict, List, Optional
from autogen.agentchat import GroupChatManager, GroupChat
class ResumableGroupChatManager(GroupChatManager):
def __init__(self, groupchat: GroupChat, history: Optional[List[Dict]] = None, **kwargs):
super().__init__(groupchat, **kwargs)
if history:
self.restore_from_history(history)
def restore_from_history(self, history) -> None:
for message in history:
# broadcast the message to all agents except the speaker. This idea is the same way GroupChat is implemented in AutoGen for new messages, this method simply allows us to replay old messages first.
speaker_name = message.get("name", self.groupchat.admin_name)
if speaker_name is None:
raise ValueError("Speaker name is missing in the message and no admin name is set in the group chat")
speaker = self.groupchat.agent_by_name(name=speaker_name)
if speaker is None:
raise ValueError(f"Speaker {speaker_name} not found in the group chat")
self.groupchat.append(message, speaker)
for agent in self.groupchat.agents:
if agent != speaker:
self.send(message, agent, request_reply=False, silent=False)
speaker.send(message, self, request_reply=False) To get the results, I then call group_chat_manager = ResumableGroupChatManager(
....
history=history,
)
chat_result = initiating_agent.initiate_chat(..., clear_history=False) |
Thanks for detailing your implementation, @hardchor :)... very helpful... I've been testing a bit with your previous link's code with amendments. It was helpful having the code and your updated code will also be helpful. At this stage I'm testing without creating a new class, but either a function on an existing class or a new class, as you've done, may be the way to go... I'll update with my findings and code once I've tested it in a few group chat scenarios... |
Thank you @hardchor ! This is very helpful. |
I've tested some code with the GroupChat notebooks in the documentation and I think the following works to resume GroupChats. I believe creating the necessary resume function shouldn't be too difficult. Thanks again to @hardchor for your code! Here's the approach I took to test:
This worked with all notebooks (tweaking the termination check if needed). Resumption picked up code and ran it, continued conversations, etc. I tested on my own code as well (debating) and it continued the conversation okay. Here's a summary of the tests and links to the Python files and outputs
Here's a notebook with the code in it At this stage, I believe it's possible that with just the message history we can resume the group chat. This could be handled with It would need to take in the messages, assign the messages to the agents, ignore initial termination check, and include all the validations to make sure agents in the messages existed, etc. See steps 2 and 4 above. Happy to continue the conversation from here... |
Thanks @marklysze for the update. The test result is very useful! I have two questions:
For termination message removal, I think this can be part of the API for resuming a group chat, and caller can specify what to do with the termination messages, as in some cases the termination message may not be "TERMINATE". If user does not specify what to do with the termination messages, and the history contains it, we can raise a warning to notify the existence of termination messages in the history and warn that the group chat might be terminated early. |
Thanks @ekzhu...
I think logically I would initially say GroupChat, however, there's a case for consistency with resuming other, non-group, types of chats so perhaps agent-side resuming is better (e.g. GroupChatManager)? A lot of chats are also initiated through an agent, so resuming through an agent makes it feel similar. I also like that the manager agent is responsible for resuming, which feels more agentic (?). The one caveat here, though, is I don't think we want the user to resume a group chat through any agent other than the group chat manager.
Let me check that out, I haven't used summarisation so I'll have a look at that, too. If it makes sense to use
Yep, sounds fair. |
Sounds like we can have a |
For #2359 (comment) It seems reasonable enough, but when I tried something similar with my own project at the company, I had to consider the token limit for GPT-3.5/GPT-4. A few months ago, I saved all conversations into Redis. After doing so, I realized that this approach might either reach the token limit or consume a significant number of tokens. While I'm not concerned about the tokens spent, I do want to avoid hitting the limit. For instance, with a lengthy conversation, it's not clear to me how you would segment it into manageable chunks. In my project, I discovered two methods to circumvent this issue:
|
@Mai0313, thanks for highlighting that, it's definitely something I've been encountering in my general use of LLMs and particularly with long conversations. The summary agent sounds interesting, does that condense the live chat messages or condense for saving only? I assume manging the total conversation length/tokens is going to be an issue independent of the resuming functionality? |
Long context handling inside a group chat is definitely something we need to add to the library. For single agent, the current way to do it is to to use the transform message capability: https://microsoft.github.io/autogen/docs/topics/long_contexts Currently the capability is not working for GroupChat or GroupChatManager, as the group chat select speaker is using all messages. However @marklysze has made a recent change to convert the speaker selection into a two agent chat, so we can potentially apply the transformation capability to the agents in the inner chat. cc @WaelKarkoub for awareness |
Ah, that transform message capability is very interesting... Being able to transform messages for the select speaker inner chat would be very useful. Let me know if you have any specific approaches and I'm happy to incorporate. In line with that, in my separate, and much earlier, testing I found that using an LLM to summarise each message was also a good way of maintaining the context of the message and significantly reduce its length. I'm not sure whether introducing LLM-based TransformMessages capability would work though, as it appears to run for the full set of messages each time (which will reach token limits). So, how about an option to summarise each message when it comes in, by sending it back to the LLM prefixed with a summarise prompt, and store it alongside the context (e.g. a message has both "context" and "summarised")? This would be similar to the |
I'm currently reviewing the group chat implementation and noticed that it doesn't expose the inner agent externally, which could complicate integration with transform messages. Also, the roles of the group chat and group chat manager seem to have become blurred. Do you think it would be beneficial to refactor these components to better define their functions? I propose modeling the group chat primarily as a data store, with the group chat manager facilitating agent-to-agent communication. A while back I suggested creating a protocol for an agent selector, #1791 (comment). With this setup, we could implement an
It depends on how you design the transform. For example, you can create a transform that summarizes only the last message, or only if the message reaches a certain token count. The design for the transform message is pretty flexible and should allow us to create any behavior we would like. I'm more than happy to collaborate on adding a new transform that summarizes messages (or any other transform ideas you might have) |
Do you think we don't necessarily need to apply the capability concept here? It is basically the chat history we want to transform; can we just add a "message transformer" to the constructor? |
I've been quite focused on I'm happy to press forward with the resuming functionality, e.g. For the message transformations on the select speaker messages - would be great to work together @WaelKarkoub. I'd be keen to try and keep LLM summarisation at a message-level occurring only once per message to minimise LLM-hits. Should I create an issue? |
@ekzhu interesting idea, I didn't think about it that way. My goal was to keep it consistent with how we use message transform, but I do like your approach better.
@marklysze Yup sounds good 👍 |
Let's go forward with the functionality first before refining it.
The separation is certainly a bit unclear. At this stage, we still want to understand the usage cases and functionalities so keep it this way for the time being. There is an |
I've created issue #2583 to address this separate capability and will work on the PR, thanks @WaelKarkoub for the chat around the implementation of this. I'll work on the resuming group chat functionality for this issue and create a new PR when I have a first pass. |
This has been addressed thanks @marklysze ! |
Is your feature request related to a problem? Please describe.
Currently, when a group chat terminates, there isn't a straightforward way to resume it, either by resuming the current
GroupChat
object, or by creating a newGroupChat
object and start from the previous message history.GroupChat
class already acceptsmessages
in its constructor, so we can inject previous message history. However, the pain point is how to restart the conversation.See discussion on this here: #2301
Describe the solution you'd like
No response
Additional context
No response
The text was updated successfully, but these errors were encountered: