diff --git a/metagpt/actions/anaylze_requirements.py b/metagpt/actions/anaylze_requirements.py index 486dc02fa..846895ef0 100644 --- a/metagpt/actions/anaylze_requirements.py +++ b/metagpt/actions/anaylze_requirements.py @@ -1,45 +1,56 @@ -import json - from metagpt.actions import Action -from metagpt.utils.common import CodeParser ANALYZE_REQUIREMENTS = """ -# Example 1 -Requirements : Create 2048 game. Do not write PRD. -Outputs:{{ - "response_language": "English" - "requirements_constraints": "Do not write PRD." -}} -# Example 2 -Requirements : 创建一个贪吃蛇,只需要给出设计文档和代码 -Outputs:{{ - "response_language": "Chinese" - "requirements_constraints": "只需要给出设计文档和代码" -}} - -# Example 3 -Requirements :You must ignore create PRD and TRD. Snake Game RequirementsGame InterfaceThe game interface is a rectangular grid.The size of the grid can be adjusted as needed (e.g., 20x20).The snake and the food are displayed on the grid.Game ObjectsSnake: Composed of multiple cells, with an initial length of 3 cells.Food: Appears randomly in one cell on the grid.GameplayThe player controls the snake's movement direction using the arrow keys (up, down, left, right).Each key press changes the snake's movement direction.With each move, the snake's head enters the next cell, and the tail leaves the last cell.When the snake's head meets the food, the snake lengthens by one cell, and new food appears at a random position on the grid.The game ends if the snake's head hits the wall or itself.User InterfaceDisplay the current score (number of food eaten).Display the game status (ongoing or ended).Provide an option to restart the game.Technical RequirementsImplement using HTML, CSS, and JavaScript.Use the Canvas element to draw the game interface.Code should be well-structured and easy to maintain and extend. -Outputs:{{ - "response_language": "English" - "requirements_constraints": "You must ignore create PRD and TRD." -}} +# Example +{examples} # Requirements {requirements} # Instructions +{instructions} + +# Output Format +{output_format} + +Follow the instructions and output format. Do not include any additional content. +""" + +EXAMPLES = """ +Example 1 +Requirements: +Create 2048 game. Do not write PRD. +Outputs: +[User Restrictions] : Do not write PRD. +[Language Restrictions] : The response must be in the language specified by English. + +Example 2 +Requirements: +创建一个贪吃蛇,只需要给出设计文档和代码 +Outputs: +[User Restrictions] : 只需要给出设计文档和代码. +[Language Restrictions] : The response must be in the language specified by Chinese. + +Example 3 +Requirements: +You must ignore create PRD and TRD. Help me write a schedule display program for the Paris Olympics. +Outputs: +[User Restrictions] : You must ignore create PRD and TRD. +[Language Restrictions] : The response must be in the language specified by English. +""" + +INSTRUCTIONS = """ You must output in the same language as the Requirements. First, This language should be consistent with the language used in the requirement description. determine the natural language you must respond in. The default language is English Second, extract the restrictions in the requirements, specifically the steps. Do not include detailed demand descriptions; focus only on the restrictions. Note: 1. if there is not restrictions, requirements_restrictions must be "" +""" -# Output Format -{{ - "response_language": "the language to respond in" - "requirements_restrictions": "the restrictions in the requirements" -}} +OUTPUT_FORMAT = """ +[User Restrictions] : the restrictions in the requirements +[Language Restrictions] : The response must be in the language specified by {{language}} """ @@ -48,21 +59,10 @@ class AnalyzeRequirementsRestrictions(Action): name: str = "AnalyzeRequirementsRestrictions" - async def run(self, requirements): + async def run(self, requirements, isinstance=INSTRUCTIONS, output_format=OUTPUT_FORMAT): """Analyze the constraints and the language used in the requirements.""" - node = await self.llm.aask(ANALYZE_REQUIREMENTS.format(requirements=requirements)) - node = CodeParser.parse_code(block=None, lang="json", text=node) - try: - node = json.loads(node) - except: - node = {} - # constraints = node.instruct_content.model_dump().get("CONSTRAINTS",None) - # output_language = node.instruct_content.model_dump().get("OUTPUT_LANGUAGE","English") - output_language = node.get("response_language", "English") - constraints = node.get("requirements_restrictions", "") - format_instruction = "" - format_instruction += f"1.[User Restrictions] : {constraints}\n" - format_instruction += ( - f"2.[Language Restrictions] : The response must be in the language specified by {output_language}." + prompt = ANALYZE_REQUIREMENTS.format( + examples=EXAMPLES, requirements=requirements, instructions=isinstance, output_format=output_format ) - return format_instruction + rsp = await self.llm.aask(prompt) + return rsp diff --git a/metagpt/prompts/di/role_zero.py b/metagpt/prompts/di/role_zero.py index d8845de61..4edfe8936 100644 --- a/metagpt/prompts/di/role_zero.py +++ b/metagpt/prompts/di/role_zero.py @@ -66,7 +66,6 @@ Output should adhere to the following format. ] ``` Notice: your output JSON data section must start with **```json [** -Notice: Your answer must start with an ordinal number. """ THOUGHT_GUIDANCE = """ First, describe the actions you have taken recently. diff --git a/metagpt/roles/architect.py b/metagpt/roles/architect.py index 2886cbad3..503be51f6 100644 --- a/metagpt/roles/architect.py +++ b/metagpt/roles/architect.py @@ -12,7 +12,7 @@ from metagpt.tools.libs.software_development import write_trd_and_framework from metagpt.utils.common import tool2name ARCHITECT_INSTRUCTION = """ -Use WriteDesign tool to write a system design document if a system design is required;Use `write_trd_and_framework` tool to write a software framework if a software framework is required; +Use WriteDesign tool to write a system design document if a system design is required; Use `write_trd_and_framework` tool to write a software framework if a software framework is required; Note: 1. When you think, just analyze which tool you should use, and then provide your answer. And your output should contain firstly, secondly, ... diff --git a/metagpt/roles/di/role_zero.py b/metagpt/roles/di/role_zero.py index 40b90c6f0..7b6057176 100644 --- a/metagpt/roles/di/role_zero.py +++ b/metagpt/roles/di/role_zero.py @@ -71,6 +71,7 @@ class RoleZero(Role): commands: list[dict] = [] # commands to be executed memory_k: int = 20 # number of memories (messages) to use as historical context use_fixed_sop: bool = False + requirements_constraints: str = "" # the constraints in user requirements @model_validator(mode="after") def set_plan_and_tool(self) -> "RoleZero": diff --git a/metagpt/roles/product_manager.py b/metagpt/roles/product_manager.py index db45de657..93d83e329 100644 --- a/metagpt/roles/product_manager.py +++ b/metagpt/roles/product_manager.py @@ -29,7 +29,7 @@ class ProductManager(RoleZero): name: str = "Alice" profile: str = "Product Manager" - goal: str = "efficiently create a successful product that meets market demands and user expectations. Create a Product Requirement Document.." + goal: str = "efficiently create a successful product that meets market demands and user expectations. Create a Product Requirement Document." constraints: str = "utilize the same language as the user requirements for seamless communication" todo_action: str = any_to_name(WritePRD)