Merge branch 'impr_routing' into 'mgx_ops'

change role responsibility

See merge request pub/MetaGPT!254
This commit is contained in:
林义章 2024-07-26 02:24:28 +00:00
commit ad89746f24
3 changed files with 24 additions and 18 deletions

View file

@ -15,7 +15,7 @@ You should use TeamLeader.publish_team_message to team members, asking them to s
Pay close attention to new user message, review the conversation history, use RoleZero.reply_to_human to respond to the user directly, DON'T ask your team members.
Pay close attention to messages from team members. If a team member has finished a task, do not ask them to repeat it; instead, mark the current task as completed.
Note:
1. If the requirement is a pure DATA-RELATED requirement, such as bug fixes, issue reporting, environment setup, terminal operations, pip install, web browsing, web scraping, web searching, web imitation, data science, data analysis, machine learning, deep learning, text-to-image etc. DON'T decompose it, assign a single task with the original user requirement as instruction directly to Data Analyst.
1. If the requirement is a pure DATA-RELATED requirement, such as web browsing, web scraping, web searching, web imitation, data science, data analysis, machine learning, deep learning, text-to-image etc. DON'T decompose it, assign a single task with the original user requirement as instruction directly to Data Analyst.
2. If the requirement is developing a software, game, app, or website, excluding the above data-related tasks, you should decompose the requirement into multiple tasks and assign them to different team members based on their expertise, usually the sequence of Product Manager -> Architect -> Project Manager -> Engineer -> (optional: QaEngine if present) -> (optional: DataAnalyst if user requests deployment), each assigned ONE task. When publishing message to Product Manager, you should directly copy the full original user requirement.
3. If the requirement contains both DATA-RELATED part mentioned in 1 and software development part mentioned in 2, you should decompose the software development part and assign them to different team members based on their expertise, and assign the DATA-RELATED part to Data Analyst David directly.
4. If the requirement is a common-sense, logical, or math problem, you should respond directly without assigning any task to team members.

View file

@ -8,10 +8,15 @@ from pydantic import Field, model_validator
from metagpt.actions.di.execute_nb_code import ExecuteNbCode
from metagpt.actions.di.write_analysis_code import WriteAnalysisCode
from metagpt.logs import logger
from metagpt.prompts.di.data_analyst import EXTRA_INSTRUCTION, TASK_TYPE_DESC, CODE_STATUS, BROWSER_INFO
from metagpt.prompts.di.data_analyst import (
BROWSER_INFO,
CODE_STATUS,
EXTRA_INSTRUCTION,
TASK_TYPE_DESC,
)
from metagpt.prompts.di.role_zero import ROLE_INSTRUCTION
from metagpt.roles.di.role_zero import RoleZero
from metagpt.schema import TaskResult, Message
from metagpt.schema import Message, TaskResult
from metagpt.strategy.experience_retriever import ExpRetriever, KeywordExpRetriever
from metagpt.tools.tool_recommend import BM25ToolRecommender, ToolRecommender
from metagpt.tools.tool_registry import register_tool
@ -21,7 +26,7 @@ from metagpt.tools.tool_registry import register_tool
class DataAnalyst(RoleZero):
name: str = "David"
profile: str = "DataAnalyst"
goal: str = "Take on any data-related tasks, such as data analysis, machine learning, deep learning, web browsing, web scraping, web searching, web deployment, terminal operation, git and github operation, etc."
goal: str = "Take on any data-related tasks, such as data analysis, machine learning, deep learning, web browsing, web scraping, web searching, web deployment, terminal operation, etc."
instruction: str = ROLE_INSTRUCTION + EXTRA_INSTRUCTION
task_type_desc: str = TASK_TYPE_DESC
@ -40,21 +45,22 @@ class DataAnalyst(RoleZero):
self.custom_tool_recommender = BM25ToolRecommender(tools=self.custom_tools)
def _update_tool_execution(self):
self.tool_execution_map.update({
"DataAnalyst.write_and_exec_code": self.write_and_exec_code,
})
self.tool_execution_map.update(
{
"DataAnalyst.write_and_exec_code": self.write_and_exec_code,
}
)
async def parse_browser_actions(self, memory: List[Message]) -> List[Message]:
memory = await super().parse_browser_actions(memory)
browser_actions = []
for index, msg in enumerate(memory):
if msg.cause_by == "browser":
browser_url = re.search('URL: (.*?)\\n', msg.content).group(1)
browser_url = re.search("URL: (.*?)\\n", msg.content).group(1)
pattern = re.compile(r"Command Browser\.(\w+) executed")
browser_actions.append({
'command': pattern.match(memory[index - 1].content).group(1),
'current url': browser_url
})
browser_actions.append(
{"command": pattern.match(memory[index - 1].content).group(1), "current url": browser_url}
)
if browser_actions:
browser_actions = BROWSER_INFO.format(browser_actions=browser_actions)
self.rc.working_memory.add(Message(content=browser_actions, role="user", cause_by="browser"))
@ -84,8 +90,8 @@ class DataAnalyst(RoleZero):
while not success and counter < 3:
### write code ###
logger.info(f"ready to WriteAnalysisCode")
use_reflection = (counter > 0 and self.use_reflection) # only use reflection after the first trial
logger.info("ready to WriteAnalysisCode")
use_reflection = counter > 0 and self.use_reflection # only use reflection after the first trial
code = await self.write_code.run(
user_requirement=self.planner.plan.goal,
@ -108,9 +114,9 @@ class DataAnalyst(RoleZero):
task_result = TaskResult(code=code, result=result, is_success=success)
self.planner.current_task.update_task_result(task_result)
status = 'Success' if success else 'Failed'
status = "Success" if success else "Failed"
output = CODE_STATUS.format(code=code, status=status, result=result)
if success:
output += 'The code written has been executed successfully.'
output += "The code written has been executed successfully."
self.rc.working_memory.clear()
return output

View file

@ -33,9 +33,9 @@ class ProductManager(RoleZero):
constraints: str = "utilize the same language as the user requirements for seamless communication"
todo_action: str = any_to_name(WritePRD)
instruction: str = """Use WritePRD tool to write PRD if a PRD is required; Use `Pic2Txt` tool to write out an intact textual user requirements if an intact textual user requiremnt is required given some images alongside the contextual textual descriptions;"""
instruction: str = """Use WritePRD tool to write PRD if a PRD is required, users may asks for a software without mentioning PRD, but you should output the PRD of that software; Use `Pic2Txt` tool to write out an intact textual user requirements if an intact textual user requiremnt is required given some images alongside the contextual textual descriptions"""
max_react_loop: int = 1 # FIXME: Read and edit files requires more steps, consider later
tools: list[str] = ["Editor:write,read,write_content", "RoleZero", "WritePRD", Pic2Txt.__name__]
tools: list[str] = ["RoleZero", "WritePRD", Pic2Txt.__name__]
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)