fixbug: trd传参错误

This commit is contained in:
莘权 马 2024-06-26 14:33:36 +08:00
parent 04b30386a4
commit 50e92521c2
9 changed files with 284 additions and 14 deletions

View file

@ -163,7 +163,7 @@ async def develop(
)
# Save
file_list = await save_framework(dir_data=framework, output_dir=output_dir)
file_list = await save_framework(dir_data=framework, trd=trd, output_dir=output_dir)
logger.info(f"Output:\n{file_list}")

View file

@ -17,12 +17,40 @@ from pydantic import BaseModel
from metagpt.actions.requirement_analysis.framework.evaluate_framework import EvaluateFramework
from metagpt.actions.requirement_analysis.framework.write_framework import WriteFramework
from metagpt.const import DEFAULT_WORKSPACE_ROOT
from metagpt.tools.tool_registry import register_tool
from metagpt.utils.common import awrite
@register_tool(tags=["software framework"])
async def save_framework(dir_data: str, output_dir: Optional[Union[str, Path]] = None) -> List[str]:
async def save_framework(
dir_data: str, trd: Optional[str] = None, output_dir: Optional[Union[str, Path]] = None
) -> List[str]:
"""
Saves framework data to files based on input JSON data and optionally saves a TRD (technical requirements document).
Args:
dir_data (str): JSON data in string format enclosed in triple backticks ("```json" "...data..." "```").
trd (str, optional): Technical requirements document content to be saved. Defaults to None.
output_dir (Union[str, Path], optional): Output directory path where files will be saved. If not provided,
a default directory is created based on the current timestamp and a random UUID suffix.
Returns:
List[str]: List of file paths where data was saved.
Raises:
Any exceptions raised during file writing operations.
Notes:
- JSON data should be provided in the format "```json ...data... ```".
- The function ensures that paths and filenames are correctly formatted and creates necessary directories.
Example:
```python
dir_data = "```json\n[{\"path\": \"/folder\", \"filename\": \"file1.txt\", \"content\": \"Some content\"}]\n```"
trd = "Technical requirements document content."
output_dir = '/path/to/output/dir'
saved_files = await save_framework(dir_data, trd, output_dir)
print(saved_files)
```
"""
output_dir = (
Path(output_dir)
if output_dir
@ -38,6 +66,10 @@ async def save_framework(dir_data: str, output_dir: Optional[Union[str, Path]] =
filename: str
content: str
if trd:
pathname = output_dir / "TRD.md"
await awrite(filename=pathname, data=trd)
files = []
for i in items:
v = Data.model_validate(i)

View file

@ -93,9 +93,10 @@ You need to refer to the content of the "Legacy TRD" section to check for any er
The content of "Actor, System, External System" provides an explanation of actors and systems that appear in UML Use Case diagram;
Information about the external system missing from the "Legacy TRD" can be found in the "Acknowledge" section;
Which interfaces defined in "Acknowledge" are used in the "Legacy TRD"?
Do not implement the interface in "Acknowledge" section until it is used in "Legacy TRD";
Do not implement the interface in "Acknowledge" section until it is used in "Legacy TRD", you can check whether they are the same interface by looking at its ID or url;
Parts not mentioned in the "Legacy TRD" will be handled by other TRDs, therefore, processes not present in the "Legacy TRD" are considered ready;
"Additional Technical Requirements" specifies the additional technical requirements that the generated software framework code must meet;
Do the parameters of the interface of the external system used in the code comply with it's specifications in 'Acknowledge'?
Return a markdown JSON object with:
- a "is_pass" key containing a true boolean value if there is not any issue in the "Legacy Outputs";
- an "issues" key containing a string list of natural text about the issues found in the "Legacy Outputs" if any, each issue found must provide a detailed description and include reasons;

View file

@ -66,6 +66,7 @@ class WriteFramework(Action):
{"path":"balabala", "filename":"...", ...
"""
acknowledge = await self._extract_external_interfaces(trd=trd, knowledge=acknowledge)
prompt = PROMPT.format(
use_case_actors=use_case_actors,
trd=to_markdown_code_block(val=trd),
@ -93,6 +94,22 @@ class WriteFramework(Action):
json.loads(json_data) # validate
return json_data
@retry(
wait=wait_random_exponential(min=1, max=20),
stop=stop_after_attempt(6),
after=general_after_log(logger),
)
async def _extract_external_interfaces(self, trd: str, knowledge: str) -> str:
prompt = f"## TRD\n{to_markdown_code_block(val=trd)}\n\n## Knowledge\n{to_markdown_code_block(val=knowledge)}\n"
rsp = await self.llm.aask(
prompt,
system_msgs=[
"You are a tool that removes impurities from articles; you can remove irrelevant content from articles.",
'Identify which interfaces are used in "TRD"? Remove the relevant content of the interfaces NOT used in "TRD" from "Knowledge" and return the simplified content of "Knowledge".',
],
)
return rsp
PROMPT = """
## Actor, System, External System

View file

@ -102,7 +102,9 @@ In order to integrate the full upstream and downstream data flow, the "TRD Desig
Which interactions from "Interaction Events" correspond to which steps in "TRD Design"? Please provide reasons.
Which aspects of "TRD Design" and "Interaction Events" do not align with the descriptions in "User Requirements"? Please provide detailed descriptions and reasons.
If the descriptions in "User Requirements" are divided into multiple steps in "TRD Design" and "Interaction Events," it can be considered compliant with the descriptions in "User Requirements" as long as it does not conflict with them;
There is a possibility of missing details in the descriptions of "User Requirements". Any additional steps in "TRD Design" and "Interaction Events" are considered compliant with "User Requirements" as long as they do not conflict with the descriptions provided in "User Requirements".
There is a possibility of missing details in the descriptions of "User Requirements". Any additional steps in "TRD Design" and "Interaction Events" are considered compliant with "User Requirements" as long as they do not conflict with the descriptions provided in "User Requirements";
If there are interaction events with external systems in "TRD Design", you must explicitly specify the ID of the external interface to use for the interaction events;
Does the sequence of steps in "Interaction Events" cause performance or cost issues? Please provide detailed descriptions and reasons;
Return a markdown JSON object with:
- a "is_pass" key containing a true boolean value if there is not any issue in the "TRD Design";
- an "issues" key containing a string list of natural text about the issues found in the "TRD Design" if any, each issue found must provide a detailed description and include reasons;

View file

@ -206,7 +206,8 @@ The content of "Available External Interfaces" provides the candidate steps, alo
3.1. In the description, use the actor and system names defined in the "Actor, System, External System" section to describe the interactors;
3.2. The content should include the original text of the requirements from "User Requirements";
3.3. In the TRD, each step can involve a maximum of two participants. If there are more than two participants, the step needs to be further split;
3.4. In the TRD, each step must include detailed descriptions, inputs, outputs, participants, initiator, and the rationale for the step's existence. The rationale should reference the original text to justify it, such as specifying which interface requires the output of this step as parameters or where in the requirements this step is mandated, etc.
3.4. In the TRD, each step must include detailed descriptions, inputs, outputs, participants, initiator, and the rationale for the step's existence. The rationale should reference the original text to justify it, such as specifying which interface requires the output of this step as parameters or where in the requirements this step is mandated, etc.;
3.5. In the TRD, if you need to call interfaces of external systems, you must explicitly specify the interface IDs of the external systems you want to call;
"""
INCREMENTAL_PROMPT = """

View file

@ -19,6 +19,224 @@ class DummyExpRetriever(ExpRetriever):
EXAMPLE: str = ""
class TRDAllExpRetriever(ExpRetriever):
def retrieve(self, context: str = "") -> str:
return self.EXAMPLE
EXAMPLE: str = """
## example 1
User Requirement: Given some user requirements, write a software framework.
Explanation: Given a complete user requirement, to write a TRD and software framework, you must follow all of the following steps to complete the TRD output required by the user: 1. Call 'write_trd' to generate TRD; 2. Call 'write_framework' to implement TRD into the software framework.
```json
[
{
"command_name": "write_trd_and_framework",
"task_id": "1",
"dependent_task_ids": [],
"instruction": "Execute `write_trd_and_framework` to write a TRD and software framework based on user requirements",
"args": {
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"additional_technical_requirements": "These are additional technical requirements, balabala..."
}
}
]
```
## example 2
User Requirement: Given some user requirements, write a software framework.
Explanation: Given a complete user requirement, to write a software framework, you must follow all of the following steps to complete the TRD output required by the user: 1. Call 'write_trd' to generate TRD; 2. Call 'write_framework' to implement TRD into the software framework.
```json
[
{
"command_name": "write_trd",
"task_id": "1",
"dependent_task_ids": [],
"instruction": "Execute `write_trd` to write the TRD based on user requirements",
"args": {
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
}
},
{
"command_name": "write_framework",
"task_id": "2",
"dependent_task_ids": ["1"],
"instruction": "Execute `write_framework` to write the framework based on the TRD",
"args": {
"use_case_actors": "These are actors involved in the use case, balabala...",
"trd": "<trd> returned by `write_trd`",
"additional_technical_requirements": "These are additional technical requirements, balabala..."
}
}
]
```
## example 3
User Requirement: Given some user requirements, write a TRD, and implement the TRD within a software framework.
Explanation:
Given a complete requirement, 要写TRD需要follow如下步骤
1. 调用`CompressExternalInterfaces.run`从acknowledgement中抽取external interfaces的信息
2. 按顺序执行如下步骤
2.1. 执行`DetectInteraction.run`;
2.2. 执行`WriteTRD.run`;
2.3. 执行`EvaluateTRD.run`;
2.4. 检查`EvaluateTRD.run`的结果
2.4.1. 如果`EvaluateTRD.run`的结果被判定为pass则执行步骤3
2.4.2. 如果`EvaluateTRD.run`的结果被判定为deny,则继续执行步骤2
3. 按顺序执行如下步骤
3.1. 执行`WriteFramework.run`;
3.2. 执行`EvaluateFramework.run`;
3.3. 检查`EvaluateFramework.run`的结果
3.3.1. 如果`EvaluateFramework.run`的结果被判定为pass则执行步骤4
3.3.2. 如果`EvaluateFramework.run`的结果被判定为deny,则继续执行步骤3
3.3.3. 如果已经重复执行步骤3超过9次则执行步骤4
4. 执行`save_framework`,`WriteFramework.run`的结果保存下来
```json
[
{
"command_name": "CompressExternalInterfaces.run",
"args": {
"task_id": "1",
"dependent_task_ids": [],
"instruction": "Execute `DetectInteraction.run` to extract external interfaces information from acknowledgement.",
"acknowledge": "## Interfaces\n balabala..."
}
},
{
"command_name": "DetectInteraction.run",
"args": {
"task_id": "2",
"dependent_task_ids": ["1"],
"instruction": "Execute `DetectInteraction.run` to extract external interfaces information from acknowledgement.",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
}
},
{
"command_name": "WriteTRD.run",
"args": {
"task_id": "3",
"dependent_task_ids": ["2"],
"instruction": "Execute `WriteTRD.run` to write TRD",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"available_external_interfaces": "<compressed_external_interfaces_output> returned by `CompressExternalInterfaces.run`",
"interaction_events": "<detected_interaction_events_output> returned by `DetectInteraction.run`"
}
},
{
"command_name": "EvaluateTRD.run",
"args": {
"task_id": "4",
"dependent_task_ids": ["3"],
"instruction": "Execute `EvaluateTRD.run` to evaluate the TRD",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"available_external_interfaces": "<compressed_external_interfaces_output> returned by `CompressExternalInterfaces.run`",
"interaction_events": "<detected_interaction_events_output>",
"trd": "<trd> returned by `EvaluateTRD.run`"
}
},
{
"command_name": "DetectInteraction.run",
"args": {
"task_id": "5",
"dependent_task_ids": ["4"],
"instruction": "Execute `DetectInteraction.run` to extract external interfaces information from acknowledgement.",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"evaluation_conclusion": "<evaluation_conclusion> returned by `EvaluateTRD.run`"
}
},
{
"command_name": "WriteTRD.run",
"args": {
"task_id": "6",
"dependent_task_ids": ["5"],
"instruction": "Execute `WriteTRD.run` to write TRD",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"available_external_interfaces": "<compressed_external_interfaces_output> returned by `CompressExternalInterfaces.run`",
"interaction_events": "<detected_interaction_events_output> returned by `DetectInteraction.run`",
"previous_version_trd": "<trd> returned by `WriteTRD.run`"
}
},
{
"command_name": "EvaluateTRD.run",
"args": {
"task_id": "7",
"dependent_task_ids": ["6"],
"instruction": "Execute `EvaluateTRD.run` to evaluate the TRD",
"user_requirements": "This is user requirement balabala...",
"use_case_actors": "These are actors involved in the use case, balabala...",
"available_external_interfaces": "<compressed_external_interfaces_output> returned by `CompressExternalInterfaces.run`",
"interaction_events": "<detected_interaction_events_output> returned by `DetectInteraction.run`",
"trd": "<trd> returned by `WriteTRD.run`",
}
},
{
"command_name": "WriteFramework.run",
"args": {
"task_id": "8",
"dependent_task_ids": ["7"],
"instruction": "Execute `WriteFramework.run` to write a software framework according to the TRD",
"use_case_actors": "These are actors involved in the use case, balabala...",
"trd": "<trd> returned by `WriteTRD.run`",
"acknowledge": "## Interfaces\n balabala...",
"additional_technical_requirements": "These are additional technical requirements, balabala...",
}
},
{
"command_name": "EvaluateFramework.run",
"args": {
"task_id": "9",
"dependent_task_ids": ["8"],
"instruction": "Execute `EvaluateFramework.run` to evaluate the software framework returned by `WriteFramework.run`",
"use_case_actors": "These are actors involved in the use case, balabala...",
"trd": "<trd> returned by `WriteTRD.run`",
"acknowledge": "## Interfaces\n balabala...",
"legacy_output": "<framework> returned by `WriteFramework.run`",
"additional_technical_requirements": "These are additional technical requirements, balabala...",
}
},
{
"command_name": "WriteFramework.run",
"args": {
"task_id": "10",
"dependent_task_ids": ["9"],
"instruction": "Execute `WriteFramework.run` to write a software framework according to the TRD",
"use_case_actors": "These are actors involved in the use case, balabala...",
"trd": "<trd> returned by `WriteTRD.run`",
"acknowledge": "## Interfaces\n balabala...",
"additional_technical_requirements": "These are additional technical requirements, balabala...",
}
},
{
"command_name": "EvaluateFramework.run",
"args": {
"task_id": "11",
"dependent_task_ids": ["10"],
"instruction": "Execute `EvaluateFramework.run` to evaluate the software framework returned by `WriteFramework.run`",
"use_case_actors": "These are actors involved in the use case, balabala...",
"trd": "<trd> returned by `WriteTRD.run`",
"acknowledge": "## Interfaces\n balabala...",
"legacy_output": "<framework> returned by `WriteFramework.run`",
"additional_technical_requirements": "These are additional technical requirements, balabala...",
}
},
{
"command_name": "save_framework",
"args": {
"task_id": "12",
"dependent_task_ids": ["11"],
"instruction": "Execute `save_framework` to save the software framework returned by `WriteFramework.run`",
"dir_data": "<framework> returned by `WriteFramework.run`",
}
}
]
```
"""
class TRDToolExpRetriever(ExpRetriever):
"""A TRD-related experience retriever that returns empty string."""

View file

@ -159,7 +159,7 @@ async def write_framework(
trd: str,
additional_technical_requirements: str,
output_dir: Optional[str] = "",
investment: float = 15.0,
investment: float = 20.0,
context: Optional[Context] = None,
) -> str:
"""
@ -220,7 +220,7 @@ async def write_framework(
is_pass = evaluation.is_pass
evaluation_conclusion = evaluation.conclusion
file_list = await save_framework(dir_data=framework, output_dir=output_dir)
file_list = await save_framework(dir_data=framework, trd=trd, output_dir=output_dir)
logger.info(f"Output:\n{file_list}")
return "## Software Framework" + "".join([f"\n- {i}" for i in file_list])
@ -230,7 +230,7 @@ async def write_trd_and_framework(
use_case_actors: str,
user_requirements: str,
additional_technical_requirements: str,
investment: float = 15.0,
investment: float = 17.0,
output_dir: Optional[str] = "",
context: Optional[Context] = None,
) -> str:

View file

@ -1,4 +1,3 @@
- 基于dingtalk框架编码
- 用java编程语言
- 接口类的功能要放到implement子类中实现;
- 法务中台网址:`https://mock.apipark.cn/m1/4717294-4369585-default`
- 用javascript语言, 法务查询者与国际小超人钉钉小程序之间UI用web
- 法务中台网址:`https://mock.apipark.cn/m1/4717294-4369585-default`;
- 写代码时,不要单元测试代码;