when enable_write is false, skip evaluating and saving the experience

This commit is contained in:
seehi 2024-07-11 10:26:42 +08:00
parent b5934a412b
commit 866d93b7db
5 changed files with 30 additions and 18 deletions

View file

@ -15,16 +15,15 @@ class RoleZeroContextBuilder(BaseContextBuilder):
Returns:
list[dict]: The updated request with formatted experiences or the original request if no experiences are available.
"""
req = kwargs.get("req", [])
if not req:
return req
exps_str = self.format_exps()
if not exps_str:
exps = self.format_exps()
if not exps:
return req
req[-1]["content"] = self.replace_example_content(req[-1].get("content", ""), exps_str)
req[-1]["content"] = self.replace_example_content(req[-1].get("content", ""), exps)
return req

View file

@ -1,7 +1,6 @@
"""Experience Decorator."""
import asyncio
import copy
import functools
from typing import Any, Callable, Optional, TypeVar
@ -33,9 +32,11 @@ def exp_cache(
):
"""Decorator to get a perfect experience, otherwise, it executes the function, and create a new experience.
1. This can be applied to both synchronous and asynchronous functions.
2. The function must have a `req` parameter, and it must be provided as a keyword argument.
3. If `config.exp_pool.enable_read` is False, the decorator will just directly execute the function.
Note:
1. This can be applied to both synchronous and asynchronous functions.
2. The function must have a `req` parameter, and it must be provided as a keyword argument.
3. If `config.exp_pool.enable_read` is False, the decorator will just directly execute the function.
4. If `config.exp_pool.enable_write` is False, the decorator will skip evaluating and saving the experience.
Args:
_func: Just to make the decorator more flexible, for example, it can be used directly with @exp_cache by default, without the need for @exp_cache().
@ -68,11 +69,14 @@ def exp_cache(
)
await handler.fetch_experiences()
if exp := await handler.get_one_perfect_exp():
return exp
await handler.execute_function()
await handler.process_experience()
if config.exp_pool.enable_write:
await handler.process_experience()
return handler._raw_resp
@ -117,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(copy.deepcopy(self.kwargs["req"]))
self._req = self.serializer.serialize_req(self.kwargs["req"])
return self
@ -140,7 +144,7 @@ class ExpCacheHandler(BaseModel):
"""Execute the function, and save resp."""
self._raw_resp = await self._execute_function()
self._resp = self.serializer.serialize_resp(copy.deepcopy(self._raw_resp))
self._resp = self.serializer.serialize_resp(self._raw_resp)
@handle_exception
async def process_experience(self):

View file

@ -11,11 +11,18 @@ class BaseSerializer(BaseModel, ABC):
@abstractmethod
def serialize_req(self, req: Any) -> str:
"""Serializes the request for storage."""
"""Serializes the request for storage.
Do not modify req. 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.
"""
@abstractmethod
def serialize_resp(self, resp: Any) -> str:
"""Serializes the function's return value for storage."""
"""Serializes the function's return value for storage.
Do not modify resp. The rest is the same as `serialize_req`.
"""
@abstractmethod
def deserialize_resp(self, resp: str) -> Any:

View file

@ -1,5 +1,6 @@
"""RoleZero Serializer."""
import copy
import json
from metagpt.exp_pool.context_builders import RoleZeroContextBuilder
@ -27,7 +28,8 @@ class RoleZeroSerializer(SimpleSerializer):
if not req:
return ""
last_content = req[-1]["content"]
req_copy = copy.deepcopy(req)
last_content = req_copy[-1]["content"]
last_content = RoleZeroContextBuilder.replace_content_between_markers(
last_content, "# Data Structure", "# Current Plan", ""
)
@ -35,6 +37,6 @@ class RoleZeroSerializer(SimpleSerializer):
last_content, "# Example", "# Instruction", ""
)
req[-1]["content"] = last_content
req_copy[-1]["content"] = last_content
return json.dumps(req)
return json.dumps(req_copy)

View file

@ -798,13 +798,13 @@ Explanation: I will first need to read the system design document and the projec
{
"command_name": "Editor.read",
"args": {
"path": "/tmp/docs/project_schedule.json"
"path": "/tmp/project_schedule.json"
}
},
{
"command_name": "Editor.read",
"args": {
"path": "/tmp/docs/system_design.json"
"path": "/tmp/system_design.json"
}
}
]