mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-11 15:15:18 +02:00
refactor: brain memory
This commit is contained in:
parent
2be79730a0
commit
0703c29030
1 changed files with 44 additions and 59 deletions
|
|
@ -18,6 +18,7 @@ import pydantic
|
|||
from metagpt import Message
|
||||
from metagpt.config import CONFIG
|
||||
from metagpt.const import DEFAULT_LANGUAGE, DEFAULT_MAX_TOKENS
|
||||
from metagpt.llm import LLMType
|
||||
from metagpt.logs import logger
|
||||
from metagpt.schema import RawMessage
|
||||
from metagpt.utils.redis import Redis
|
||||
|
|
@ -56,26 +57,6 @@ class BrainMemory(pydantic.BaseModel):
|
|||
texts = [Message(**m).content for m in self.knowledge]
|
||||
return "\n".join(texts)
|
||||
|
||||
# @property
|
||||
# def history_text(self):
|
||||
# if len(self.history) == 0 and not self.historical_summary:
|
||||
# return ""
|
||||
# try:
|
||||
# self.loads_raw_messages()
|
||||
# return self.dumps_raw_messages()
|
||||
# except:
|
||||
# texts = [self.historical_summary] if self.historical_summary else []
|
||||
# for m in self.history[:-1]:
|
||||
# if isinstance(m, Dict):
|
||||
# t = Message(**m).content
|
||||
# elif isinstance(m, Message):
|
||||
# t = m.content
|
||||
# else:
|
||||
# continue
|
||||
# texts.append(t)
|
||||
#
|
||||
# return "\n".join(texts)
|
||||
|
||||
@staticmethod
|
||||
async def loads(redis_key: str, redis_conf: Dict = None) -> "BrainMemory":
|
||||
redis = Redis(conf=redis_conf)
|
||||
|
|
@ -143,47 +124,19 @@ class BrainMemory(pydantic.BaseModel):
|
|||
self.last_talk = None
|
||||
return v
|
||||
|
||||
def loads_raw_messages(self):
|
||||
if not self.historical_summary:
|
||||
return
|
||||
vv = json.loads(self.historical_summary)
|
||||
msgs = []
|
||||
for v in vv:
|
||||
tag = set([MessageType.Talk.value]) if v.get("role") == "user" else set([MessageType.Answer.value])
|
||||
m = Message(content=v.get("content"), tags=tag)
|
||||
msgs.append(m)
|
||||
msgs.extend(self.history)
|
||||
self.history = msgs
|
||||
self.is_dirty = True
|
||||
async def summarize(self, llm, max_words=200, keep_language: bool = False, **kwargs):
|
||||
if self.llm_type == LLMType.METAGPT.value:
|
||||
return await self._metagpt_summarize(llm=llm, max_words=max_words, keep_language=keep_language, **kwargs)
|
||||
|
||||
def dumps_raw_messages(self, max_length: int = 0) -> str:
|
||||
summary = []
|
||||
return await self._openai_summarize(llm=llm, max_words=max_words, keep_language=keep_language, **kwargs)
|
||||
|
||||
total_length = 0
|
||||
for m in reversed(self.history):
|
||||
msg = Message(**m)
|
||||
c = RawMessage(role="user" if MessageType.Talk.value in msg.tags else "assistant", content=msg.content)
|
||||
length_delta = len(msg.content)
|
||||
if max_length > 0:
|
||||
if total_length + length_delta > max_length:
|
||||
left = max_length - total_length
|
||||
if left > 0:
|
||||
c.content = msg.content[0:left]
|
||||
summary.insert(0, c)
|
||||
break
|
||||
|
||||
total_length += length_delta
|
||||
summary.insert(0, c)
|
||||
|
||||
self.historical_summary = json.dumps(summary)
|
||||
self.history = []
|
||||
self.is_dirty = True
|
||||
return self.historical_summary
|
||||
|
||||
async def summerize(self, llm, max_words=200, keep_language: bool = False, **kwargs):
|
||||
async def _openai_summarize(self, llm, max_words=200, keep_language: bool = False, **kwargs):
|
||||
max_token_count = DEFAULT_MAX_TOKENS
|
||||
max_count = 100
|
||||
text = self.history_text
|
||||
texts = [self.historical_summary]
|
||||
for m in self.history:
|
||||
texts.append(m.content)
|
||||
text = "\n".join(texts)
|
||||
text_length = len(text)
|
||||
summary = ""
|
||||
while max_count > 0:
|
||||
|
|
@ -210,9 +163,41 @@ class BrainMemory(pydantic.BaseModel):
|
|||
if not summary:
|
||||
await self.set_history_summary(history_summary=summary, redis_key=CONFIG.REDIS_KEY, redis_conf=CONFIG.REDIS)
|
||||
return summary
|
||||
|
||||
raise openai.error.InvalidRequestError("text too long")
|
||||
|
||||
async def _metagpt_summarize(self, max_words=200, **kwargs):
|
||||
if not self.history:
|
||||
return ""
|
||||
|
||||
total_length = 0
|
||||
msgs = []
|
||||
for m in reversed(self.history):
|
||||
delta = len(m.content)
|
||||
if total_length + delta > max_words:
|
||||
left = max_words - total_length
|
||||
if left == 0:
|
||||
break
|
||||
m.content = m.content[0:left]
|
||||
msgs.append(m)
|
||||
break
|
||||
msgs.append(m)
|
||||
total_length += delta
|
||||
self.history = msgs
|
||||
self.is_dirty = True
|
||||
await self.dumps(redis_key=CONFIG.REDIS_KEY, redis_conf=CONFIG.REDIS_CONF)
|
||||
self.is_dirty = False
|
||||
|
||||
return BrainMemory.to_metagpt_history_format(self.history)
|
||||
|
||||
@staticmethod
|
||||
def to_metagpt_history_format(history) -> str:
|
||||
mmsg = []
|
||||
for m in reversed(history):
|
||||
msg = Message(**m)
|
||||
r = RawMessage(role="user" if MessageType.Talk.value in msg.tags else "assistant", content=msg.content)
|
||||
mmsg.append(r)
|
||||
return json.dumps(mmsg)
|
||||
|
||||
async def _get_summary(self, text: str, llm, max_words=20, keep_language: bool = False):
|
||||
"""Generate text summary"""
|
||||
if len(text) < max_words:
|
||||
|
|
@ -302,6 +287,6 @@ class BrainMemory(pydantic.BaseModel):
|
|||
|
||||
@property
|
||||
def is_history_available(self):
|
||||
return self.history or self.historical_summary
|
||||
return bool(self.history or self.historical_summary)
|
||||
|
||||
DEFAULT_TOKEN_SIZE = 500
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue