1. add guideline in context of write_code_review.py

2. update prompt
This commit is contained in:
mannaandpoem 2024-01-12 17:33:15 +08:00
parent 3848596b0f
commit a363691c38
7 changed files with 73 additions and 31 deletions

View file

@ -49,9 +49,8 @@ FILE_LIST = ActionNode(
REFINED_FILE_LIST = ActionNode(
key="Refined File List",
expected_type=List[str],
instruction="Update and expand the original file list, including only relative paths. "
"Ensure that the refined file list reflects the evolving structure of the project due to incremental development."
"Only output filename! Do not include comments in the list.",
instruction="Update and expand the original file list including only relative paths, up to 2 files can be added."
"Ensure that the refined file list reflects the evolving structure of the project due to incremental development.",
example=["main.py", "game.py", "new_feature.py"],
)
@ -148,7 +147,7 @@ INC_NODES = [INCREMENTAL_IMPLEMENTATION_APPROACH, INCREMENTAL_DATA_STRUCTURES_AN
REFINE_NODES = [
REFINED_IMPLEMENTATION_APPROACH,
FILE_LIST,
REFINED_FILE_LIST,
REFINED_DATA_STRUCTURES_AND_INTERFACES,
REFINED_PROGRAM_CALL_FLOW,
ANYTHING_UNCLEAR,

View file

@ -75,16 +75,16 @@ INCREMENTAL_TASK_LIST = ActionNode(
instruction="Break down the incremental development tasks into a prioritized list of filenames."
"Organize the tasks based on dependency order, ensuring a systematic and efficient implementation."
"Only output filename! Do not include comments in the list ",
example=["new_feature.py", "utils.py", "main.py"],
example=["new_feature.py", "main.py"],
)
REFINED_TASK_LIST = ActionNode(
key="Refined Task list",
expected_type=List[str],
instruction="Review and refine the combined task list after the merger of Legacy Content and Incremental Content. "
instruction="Review and refine the combined task list after the merger of Legacy Content and Incremental Content, and consistent with Refined File List."
"Ensure that tasks are organized in a logical and prioritized order, considering dependencies for a streamlined and"
" efficient development process. Only output filename! Do not include comments in the list",
example=["game.py", "utils.py", "new_feature.py", "main.py"],
" efficient development process. ",
example=["new_feature.py", "utils", "game.py", "main.py"],
)
FULL_API_SPEC = ActionNode(

View file

@ -27,6 +27,7 @@ from metagpt.const import (
BUGFIX_FILENAME,
CODE_SUMMARIES_FILE_REPO,
DOCS_FILE_REPO,
PRDS_FILE_REPO,
REQUIREMENT_FILENAME,
TASK_FILE_REPO,
TEST_OUTPUTS_FILE_REPO,
@ -115,6 +116,11 @@ class WriteCode(Action):
docs_file_repo = CONFIG.git_repo.new_file_repository(relative_path=DOCS_FILE_REPO)
requirement_doc = await docs_file_repo.get(filename=REQUIREMENT_FILENAME)
prd_file_repo = CONFIG.git_repo.new_file_repository(PRDS_FILE_REPO)
prd = await prd_file_repo.get_all()
prd_json = json.loads("\n".join([doc.content for doc in prd]))
product_requirement_pool = prd_json.get("Requirement Pool", prd_json.get("Refined Requirement Pool"))
guideline = kwargs.get("guideline", "")
if bug_feedback:
code_context = coding_context.code_doc.content
@ -125,7 +131,8 @@ class WriteCode(Action):
if guideline:
prompt = REFINED_CODE_TEMPLATE.format(
requirement=requirement_doc.content if requirement_doc else "",
user_requirement=requirement_doc.content if requirement_doc else "",
product_requirement_pool=str(product_requirement_pool),
guideline=guideline,
design=coding_context.design_doc.content if coding_context.design_doc else "",
tasks=coding_context.task_doc.content if coding_context.task_doc else "",

View file

@ -15,7 +15,8 @@ GUIDELINES_AND_INCREMENTAL_CHANGE = ActionNode(
expected_type=str,
instruction="Developing comprehensive and step-by-step incremental development guideline, and Write Incremental "
"Change by making a code draft that how to implement incremental development including detailed steps based on the "
"context. Note: Track incremental changes using mark of '+' or '-' for add/modify/delete code",
"context. Note: Track incremental changes using mark of '+' or '-' for add/modify/delete code, and conforms to the "
"output format of git diff",
example="""
1. Guideline for calculator.py: Enhance the functionality of `calculator.py` by extending it to incorporate methods for subtraction, multiplication, and division. Additionally, implement robust error handling for the division operation to mitigate potential issues related to division by zero.
```python
@ -105,11 +106,11 @@ def add_numbers():
)
CODE_GUIDELINE_CONTEXT = """
## New Requirements
{requirement}
## User New Requirements
{user_requirement}
## PRD
{prd}
## Product Requirement Pool
{product_requirement_pool}
## Design
{design}
@ -388,13 +389,16 @@ class Interface:
REFINED_CODE_TEMPLATE = """
NOTICE
Role: You are a professional engineer; The main goal is to complete incremental development by combining legacy code and Incremental Change, ensuring the integration of new features.
Role: You are a professional engineer; The main goal is to complete incremental development by combining legacy code and Guidelines and Incremental Change, ensuring the integration of new features.
# Context
## New Requirement
{requirement}
## User New Requirements
{user_requirement}
## Incremental Change
## Product Requirement Pool
{product_requirement_pool}
## Guidelines and Incremental Change
{guideline}
## Design

View file

@ -7,6 +7,7 @@
@Modified By: mashenquan, 2023/11/27. Following the think-act principle, solidify the task parameters when creating the
WriteCode object, rather than passing them in when calling the run function.
"""
import json
from pydantic import Field
from tenacity import retry, stop_after_attempt, wait_random_exponential
@ -14,6 +15,7 @@ from tenacity import retry, stop_after_attempt, wait_random_exponential
from metagpt.actions import WriteCode
from metagpt.actions.action import Action
from metagpt.config import CONFIG
from metagpt.const import DOCS_FILE_REPO, PRDS_FILE_REPO, REQUIREMENT_FILENAME
from metagpt.logs import logger
from metagpt.schema import CodingContext
from metagpt.utils.common import CodeParser
@ -138,17 +140,41 @@ class WriteCodeReview(Action):
async def run(self, *args, **kwargs) -> CodingContext:
iterative_code = self.context.code_doc.content
k = CONFIG.code_review_k_times or 1
guideline = kwargs.get("guideline")
mode = "guide" if guideline else "normal"
for i in range(k):
format_example = FORMAT_EXAMPLE.format(filename=self.context.code_doc.filename)
task_content = self.context.task_doc.content if self.context.task_doc else ""
code_context = await WriteCode.get_codes(self.context.task_doc, exclude=self.context.filename)
context = "\n".join(
[
"## System Design\n" + str(self.context.design_doc) + "\n",
"## Tasks\n" + task_content + "\n",
"## Code Files\n" + code_context + "\n",
]
)
code_context = await WriteCode.get_codes(self.context.task_doc, exclude=self.context.filename, mode=mode)
if not guideline:
context = "\n".join(
[
"## System Design\n" + str(self.context.design_doc) + "\n",
"## Tasks\n" + task_content + "\n",
"## Code Files\n" + code_context + "\n",
]
)
else:
docs_file_repo = CONFIG.git_repo.new_file_repository(relative_path=DOCS_FILE_REPO)
requirement_doc = await docs_file_repo.get(filename=REQUIREMENT_FILENAME)
user_requirement = requirement_doc.content if requirement_doc else ""
prd_file_repo = CONFIG.git_repo.new_file_repository(PRDS_FILE_REPO)
prd = await prd_file_repo.get_all()
prd_json = json.loads("\n".join([doc.content for doc in prd]))
product_requirement_pool = prd_json.get("Requirement Pool", prd_json.get("Refined Requirement Pool"))
context = "\n".join(
[
"## User New Requirements\n" + str(user_requirement) + "\n",
"## Product Requirement Pool\n" + str(product_requirement_pool) + "\n",
"## Guidelines and Incremental Change\n" + guideline + "\n",
"## System Design\n" + str(self.context.design_doc) + "\n",
"## Tasks\n" + task_content + "\n",
"## Code Files\n" + code_context + "\n",
]
)
context_prompt = PROMPT_TEMPLATE.format(
context=context,
code=iterative_code,

View file

@ -160,7 +160,7 @@ REQUIREMENT_POOL = ActionNode(
REFINED_REQUIREMENT_POOL = ActionNode(
key="Refined Requirement Pool",
expected_type=List[List[str]],
instruction="List no less than 5 requirements with their priority (P0, P1, P2). "
instruction="List no less than 5 requirements with their priority (P0, P1, P2) from high to low. "
"Cover both legacy content and incremental content. Retain any content unrelated to incremental development",
example=[["P0", "The main code ..."], ["P0", "The game algorithm ..."]],
)

View file

@ -117,7 +117,7 @@ class Engineer(Role):
if review:
action = WriteCodeReview(context=coding_context, llm=self.llm)
self._init_action_system_message(action)
coding_context = await action.run()
coding_context = await action.run(guideline=guideline)
# Get dependencies
if guideline:
@ -346,12 +346,14 @@ class Engineer(Role):
async def _write_code_guideline(self):
logger.info("Writing code guideline..")
requirement = str(self.rc.memory.get_by_role("Human")[0])
user_requirement = str(self.rc.memory.get_by_role("Human")[0])
prd_file_repo = CONFIG.git_repo.new_file_repository(PRDS_FILE_REPO)
design_file_repo = CONFIG.git_repo.new_file_repository(SYSTEM_DESIGN_FILE_REPO)
task_file_repo = CONFIG.git_repo.new_file_repository(TASK_FILE_REPO)
prd = await prd_file_repo.get_all()
prd = "\n".join([doc.content for doc in prd])
prd_json = json.loads("\n".join([doc.content for doc in prd]))
product_requirement_pool = prd_json.get("Requirement Pool", prd_json.get("Refined Requirement Pool"))
design = await design_file_repo.get_all()
design = "\n".join([doc.content for doc in design])
tasks = await task_file_repo.get_all()
@ -359,7 +361,11 @@ class Engineer(Role):
old_codes = await self.get_old_codes()
context = CODE_GUIDELINE_CONTEXT.format(
requirement=requirement, prd=prd, tasks=tasks, design=design, code=old_codes
user_requirement=user_requirement,
product_requirement_pool=str(product_requirement_pool),
tasks=tasks,
design=design,
code=old_codes,
)
node = await WriteCodeGuideline().run(context=context)
guideline = node.instruct_content.model_dump_json()