mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-06-05 14:55:18 +02:00
Solved the issue of inconsistent input and output languages.
This commit is contained in:
parent
23aca9055d
commit
6f17d3da13
5 changed files with 79 additions and 9 deletions
68
metagpt/actions/anaylze_requirements.py
Normal file
68
metagpt/actions/anaylze_requirements.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
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."
|
||||
}}
|
||||
|
||||
# Requirements
|
||||
{requirements}
|
||||
|
||||
# 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"
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
class AnalyzeRequirementsRestrictions(Action):
|
||||
"""Write a review for the given context."""
|
||||
|
||||
name: str = "AnalyzeRequirementsRestrictions"
|
||||
|
||||
async def run(self, requirements):
|
||||
"""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}."
|
||||
)
|
||||
return format_instruction
|
||||
|
|
@ -10,7 +10,7 @@ Note:
|
|||
4. Don't forget to append task first when all existing tasks are finished and new tasks are required.
|
||||
5. Avoid repeating tasks you have already completed. And end loop when all requirements are met.
|
||||
"""
|
||||
# To ensure compatibility with hard-coded experience, do not add any other content between "# Example" and "# User Requirements".
|
||||
# To ensure compatibility with hard-coded experience, do not add any other content between "# Example" and "# Instruction".
|
||||
CMD_PROMPT = """
|
||||
# Latest Observation
|
||||
{latest_observation}
|
||||
|
|
@ -39,8 +39,6 @@ Special Command: Use {{"command_name": "end"}} to do nothing or indicate complet
|
|||
# Example
|
||||
{example}
|
||||
|
||||
# User Requirements
|
||||
{user_requirements}
|
||||
|
||||
# Instruction
|
||||
{instruction}
|
||||
|
|
@ -51,12 +49,15 @@ If you finish current task, you will automatically take the next task in the exi
|
|||
Review the latest plan's outcome, focusing on achievements. If your completed task matches the current, consider it finished.
|
||||
In your response, include at least one command.
|
||||
|
||||
# Constraints
|
||||
{requirements_constraints}
|
||||
|
||||
# Your commands in a json array, in the following output format with correct command_name and args. If there is nothing to do, use the pass or end command:
|
||||
Some text indicating your thoughts before JSON is required, such as what tasks have been completed, what tasks are next, how you should update the plan status, respond to inquiry, or seek for help. Then a json array of commands. You must output ONE and ONLY ONE json array. DON'T output multiple json arrays with thoughts between them.
|
||||
Firstly, pay attention to User Requirements and it's constraints. Provide a complete description of the User Requirements and the current task.
|
||||
Firstly, pay attention to User Requirements. Provide a complete description of the User Requirements ,pay attention to[User Restrictions] Provide a complete description of constraints, and the current task.
|
||||
Secondly, pay attention to the Latest Observation, describing what the latest observation is and any relevant messages.
|
||||
Thirdly, if you find that the current task is identical to a previously completed one, it indicates that the current task has already been accomplished.
|
||||
Then, articulate your thoughts and list the commands, adhering closely to the instructions provided.
|
||||
Then, articulate your thoughts and list the commands, adhering closely to the instructions provided. you thoughts and cammand must obey [User Restrictions]
|
||||
```json
|
||||
[
|
||||
{{
|
||||
|
|
@ -68,7 +69,6 @@ Then, articulate your thoughts and list the commands, adhering closely to the in
|
|||
```
|
||||
Notice: your output JSON data section must start with **```json [**
|
||||
Notice: Your answer must start with an ordinal number.
|
||||
Notice: The response and arguments must be in the language specified in the User Requirements.
|
||||
"""
|
||||
|
||||
JSON_REPAIR_PROMPT = """
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Architect(RoleZero):
|
|||
|
||||
name: str = "Bob"
|
||||
profile: str = "Architect"
|
||||
goal: str = "design a concise, usable, complete software system. Create a System Design Document."
|
||||
goal: str = "design a concise, usable, complete software system."
|
||||
constraints: str = (
|
||||
"make sure the architecture is simple enough and use appropriate open source "
|
||||
"libraries. Use same language as user requirement"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from typing import Callable, Dict, List, Literal, Tuple
|
|||
from pydantic import model_validator
|
||||
|
||||
from metagpt.actions import Action, UserRequirement
|
||||
from metagpt.actions.anaylze_requirements import AnalyzeRequirementsRestrictions
|
||||
from metagpt.actions.di.run_command import RunCommand
|
||||
from metagpt.exp_pool import exp_cache
|
||||
from metagpt.exp_pool.context_builders import RoleZeroContextBuilder
|
||||
|
|
@ -134,6 +135,7 @@ class RoleZero(Role):
|
|||
|
||||
if not self.planner.plan.goal:
|
||||
self.planner.plan.goal = self.get_memories()[-1].content
|
||||
self.requirements_constraints = await AnalyzeRequirementsRestrictions().run(self.planner.plan.goal)
|
||||
|
||||
### 1. Experience ###
|
||||
example = self._retrieve_experience()
|
||||
|
|
@ -156,7 +158,7 @@ class RoleZero(Role):
|
|||
current_task=current_task,
|
||||
instruction=instruction,
|
||||
latest_observation=memory[-1].content,
|
||||
user_requirements=self.planner.plan,
|
||||
requirements_constraints=self.requirements_constraints,
|
||||
)
|
||||
memory = await self.parse_browser_actions(memory)
|
||||
req = self.llm.format_msg(memory + [UserMessage(content=prompt)])
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class TestRoleZeroContextBuilder:
|
|||
result = context_builder.replace_example_content("Original text", "New example content")
|
||||
assert result == "Replaced content"
|
||||
context_builder.replace_content_between_markers.assert_called_once_with(
|
||||
"Original text", "# Example", "# User Requirements", "New example content"
|
||||
"Original text", "# Example", "# Instruction", "New example content"
|
||||
)
|
||||
|
||||
def test_replace_content_between_markers(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue