mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-11 15:15:18 +02:00
update serializers
This commit is contained in:
parent
0c6786feaa
commit
8b9e992b56
6 changed files with 30 additions and 32 deletions
|
|
@ -121,7 +121,7 @@ class ExpCacheHandler(BaseModel):
|
|||
self.serializer = self.serializer or SimpleSerializer()
|
||||
self.tag = self.tag or self._generate_tag()
|
||||
|
||||
self._req = self.serializer.serialize_req(self.kwargs["req"])
|
||||
self._req = self.serializer.serialize_req(**self.kwargs)
|
||||
|
||||
return self
|
||||
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ class BaseSerializer(BaseModel, ABC):
|
|||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
@abstractmethod
|
||||
def serialize_req(self, req: Any) -> str:
|
||||
def serialize_req(self, **kwargs) -> str:
|
||||
"""Serializes the request for storage.
|
||||
|
||||
Do not modify req. If modification is necessary, use copy.deepcopy to create a copy first.
|
||||
Do not modify kwargs. If modification is necessary, use copy.deepcopy to create a copy first.
|
||||
Note that copy.deepcopy may raise errors, such as TypeError: cannot pickle '_thread.RLock' object.
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ from metagpt.exp_pool.serializers.simple import SimpleSerializer
|
|||
|
||||
|
||||
class RoleZeroSerializer(SimpleSerializer):
|
||||
def serialize_req(self, req: list[dict]) -> str:
|
||||
def serialize_req(self, **kwargs) -> str:
|
||||
"""Serialize the request for database storage, ensuring it is a string.
|
||||
|
||||
Only extracts the necessary content from `req` because `req` may be very lengthy and could cause embedding errors.
|
||||
|
|
@ -18,18 +18,20 @@ class RoleZeroSerializer(SimpleSerializer):
|
|||
{"role": "user", "content": "..."},
|
||||
{"role": "assistant", "content": "..."},
|
||||
{"role": "user", "content": "context"},
|
||||
{"role": "user", "content": "context exp part"},
|
||||
]
|
||||
|
||||
Returns:
|
||||
str: The serialized request as a JSON string.
|
||||
"""
|
||||
req = kwargs.get("req", [])
|
||||
|
||||
if not req:
|
||||
return ""
|
||||
|
||||
filtered_req = self._filter_req(req)
|
||||
filtered_req.append(req[-1])
|
||||
|
||||
if state_data := kwargs.get("state_data"):
|
||||
filtered_req.append({"role": "user", "content": state_data})
|
||||
|
||||
return json.dumps(filtered_req)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ from metagpt.exp_pool.serializers.base import BaseSerializer
|
|||
|
||||
|
||||
class SimpleSerializer(BaseSerializer):
|
||||
def serialize_req(self, req: Any) -> str:
|
||||
def serialize_req(self, **kwargs) -> str:
|
||||
"""Just use `str` to convert the request object into a string."""
|
||||
|
||||
return str(req)
|
||||
return str(kwargs.get("req", ""))
|
||||
|
||||
def serialize_resp(self, resp: Any) -> str:
|
||||
"""Just use `str` to convert the response object into a string."""
|
||||
|
|
|
|||
|
|
@ -8,16 +8,6 @@ Note:
|
|||
2. Carefully review your progress at the current task, if your actions so far has not fulfilled the task instruction, you should continue with current task. Otherwise, finish current task by Plan.finish_current_task explicitly.
|
||||
3. Each time you finish a task, use RoleZero.reply_to_human to report your progress.
|
||||
"""
|
||||
CMD_PROMPT_EXP_PART = """
|
||||
# Current Plan
|
||||
{plan_status}
|
||||
|
||||
# Current Task
|
||||
{current_task}
|
||||
|
||||
# Instruction
|
||||
{instruction}
|
||||
"""
|
||||
# To ensure compatibility with hard-coded experience, do not add any other content between "# Example" and "# Available Commands".
|
||||
CMD_PROMPT = """
|
||||
# Data Structure
|
||||
|
|
@ -38,7 +28,14 @@ Special Command: Use {{"command_name": "end"}} to do nothing or indicate complet
|
|||
# Available Task Types
|
||||
{task_type_desc}
|
||||
|
||||
{cmd_prompt_exp_part}
|
||||
# Current Plan
|
||||
{plan_status}
|
||||
|
||||
# Current Task
|
||||
{current_task}
|
||||
|
||||
# Instruction
|
||||
{instruction}
|
||||
|
||||
Pay close attention to the Example provided, you can reuse the example for your current situation if it fits.
|
||||
You may use any of the available commands to create a plan or update the plan. You may output mutiple commands, they will be executed sequentially.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ from metagpt.exp_pool.serializers import RoleZeroSerializer
|
|||
from metagpt.logs import logger
|
||||
from metagpt.prompts.di.role_zero import (
|
||||
CMD_PROMPT,
|
||||
CMD_PROMPT_EXP_PART,
|
||||
JSON_REPAIR_PROMPT,
|
||||
QUICK_THINK_PROMPT,
|
||||
ROLE_INSTRUCTION,
|
||||
|
|
@ -147,39 +146,39 @@ class RoleZero(Role):
|
|||
tool_info = json.dumps({tool.name: tool.schemas for tool in tools})
|
||||
|
||||
### Make Decision Dynamically ###
|
||||
cmd_prompt_exp_part = CMD_PROMPT_EXP_PART.format(
|
||||
plan_status=plan_status,
|
||||
current_task=current_task,
|
||||
instruction=self.instruction.strip(),
|
||||
)
|
||||
instruction = self.instruction.strip()
|
||||
prompt = self.cmd_prompt.format(
|
||||
example=example,
|
||||
available_commands=tool_info,
|
||||
task_type_desc=self.task_type_desc,
|
||||
cmd_prompt_exp_part=cmd_prompt_exp_part,
|
||||
plan_status=plan_status,
|
||||
current_task=current_task,
|
||||
instruction=instruction,
|
||||
)
|
||||
memory = self.rc.memory.get(self.memory_k)
|
||||
memory = await self.parse_browser_actions(memory)
|
||||
|
||||
req = self.llm.format_msg(memory + [UserMessage(content=prompt), UserMessage(content=cmd_prompt_exp_part)])
|
||||
req = self.llm.format_msg(memory + [UserMessage(content=prompt)])
|
||||
async with ThoughtReporter(enable_llm_stream=True) as reporter:
|
||||
await reporter.async_report({"type": "react"})
|
||||
self.command_rsp = await self.llm_cached_aask(req=req, system_msgs=self.system_msg)
|
||||
state_data = dict(
|
||||
plan_status=plan_status,
|
||||
current_task=current_task,
|
||||
instruction=instruction,
|
||||
)
|
||||
self.command_rsp = await self.llm_cached_aask(req=req, system_msgs=self.system_msg, state_data=state_data)
|
||||
|
||||
self.rc.memory.add(AIMessage(content=self.command_rsp))
|
||||
|
||||
return True
|
||||
|
||||
@exp_cache(context_builder=RoleZeroContextBuilder(), serializer=RoleZeroSerializer())
|
||||
async def llm_cached_aask(self, *, req: list[dict], system_msgs: list[str]) -> str:
|
||||
async def llm_cached_aask(self, *, req: list[dict], system_msgs: list[str], **kwargs) -> str:
|
||||
"""Use `exp_cache` to automatically manage experiences.
|
||||
|
||||
The `RoleZeroContextBuilder` attempts to add experiences to `req`.
|
||||
The `RoleZeroSerializer` extracts essential parts of `req` for the experience pool, trimming lengthy entries to retain only necessary parts.
|
||||
"""
|
||||
# Remove the "cmd_prompt_exp_part", it is only used within the exp_cache decorator.
|
||||
if req:
|
||||
req.pop()
|
||||
|
||||
return await self.llm.aask(req, system_msgs=system_msgs)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue