From d8f1a37334d32b65205975057f5ac8144a85b9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=98=E6=9D=83=20=E9=A9=AC?= Date: Fri, 14 Jun 2024 17:02:16 +0800 Subject: [PATCH] feat: + docstring --- examples/write_project_framework.py | 31 +++++----- .../trd/compress_external_interfaces.py | 25 +++++++- .../trd/detect_interaction.py | 33 +++++++++++ .../requirement_analysis/trd/evaluate_trd.py | 47 +++++++++++++-- .../requirement_analysis/trd/write_trd.py | 57 ++++++++++--------- 5 files changed, 143 insertions(+), 50 deletions(-) diff --git a/examples/write_project_framework.py b/examples/write_project_framework.py index 968576515..4e8a03789 100644 --- a/examples/write_project_framework.py +++ b/examples/write_project_framework.py @@ -61,32 +61,29 @@ async def _write_trd( user_requirements=r, use_case_actors=use_case_actors, available_external_interfaces=available_external_interfaces, - previous_version_trd=trd, evaluation_conclusion=evaluation_conclusion, interaction_events=interaction_events, - ) - evaluation = await evaluate_trd.run( - user_requirements=r, use_case_actors=use_case_actors, trd=trd, interaction_events=interaction_events + previous_version_trd=trd, ) else: trd = await write_trd.run( - legacy_user_requirements="\n".join(legacy_user_requirements), - use_case_actors=use_case_actors, - available_external_interfaces=available_external_interfaces, - legacy_user_requirements_trd=legacy_user_requirements_trd, - legacy_user_requirements_interaction_events="\n".join(legacy_user_requirements_interaction_events), - incremental_user_requirements=r, - previous_version_trd=trd, - evaluation_conclusion=evaluation_conclusion, - incremental_user_requirements_interaction_events=interaction_events, - ) - evaluation = await evaluate_trd.run( user_requirements=r, use_case_actors=use_case_actors, - trd=trd, + available_external_interfaces=available_external_interfaces, + evaluation_conclusion=evaluation_conclusion, + interaction_events=interaction_events, + previous_version_trd=trd, + legacy_user_requirements="\n".join(legacy_user_requirements), + legacy_user_requirements_trd=legacy_user_requirements_trd, legacy_user_requirements_interaction_events="\n".join(legacy_user_requirements_interaction_events), - incremental_user_requirements_interaction_events=interaction_events, ) + evaluation = await evaluate_trd.run( + user_requirements=r, + use_case_actors=use_case_actors, + trd=trd, + interaction_events=interaction_events, + legacy_user_requirements_interaction_events="\n".join(legacy_user_requirements_interaction_events), + ) is_pass = evaluation.is_pass evaluation_conclusion = evaluation.conclusion legacy_user_requirements.append(r) diff --git a/metagpt/actions/requirement_analysis/trd/compress_external_interfaces.py b/metagpt/actions/requirement_analysis/trd/compress_external_interfaces.py index c625da727..abaf6fc30 100644 --- a/metagpt/actions/requirement_analysis/trd/compress_external_interfaces.py +++ b/metagpt/actions/requirement_analysis/trd/compress_external_interfaces.py @@ -10,10 +10,16 @@ from tenacity import retry, stop_after_attempt, wait_random_exponential from metagpt.actions import Action from metagpt.logs import logger +from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import general_after_log +@register_tool(include_functions=["run"]) class CompressExternalInterfaces(Action): + """CompressExternalInterfaces deal with the following situations: + 1. Given a natural text of acknowledgement, it extracts and compresses the information about external system interfaces. + """ + @retry( wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(6), @@ -24,12 +30,29 @@ class CompressExternalInterfaces(Action): *, acknowledge: str, ) -> str: + """ + Extracts and compresses information about external system interfaces from a given acknowledgement text. + + Args: + acknowledge (str): A natural text of acknowledgement containing details about external system interfaces. + + Returns: + str: A compressed version of the information about external system interfaces. + + Example: + >>> compress_acknowledge = CompressExternalInterfaces() + >>> acknowledge = "## Interfaces\\n..." + >>> available_external_interfaces = await compress_acknowledge.run(acknowledge=acknowledge) + >>> print(available_external_interfaces) + ```json\n[\n{\n"id": 1,\n"inputs": {... + """ return await self.llm.aask( msg=acknowledge, system_msgs=[ + "Extracts and compresses the information about external system interfaces.", "Return a markdown JSON list of objects, each object containing:\n" '- an "id" key containing the interface id;\n' '- an "inputs" key containing a dict of input parameters that consist of name and description pairs;\n' - '- an "outputs" key containing a dict of returns that consist of name and description pairs;\n' + '- an "outputs" key containing a dict of returns that consist of name and description pairs;\n', ], ) diff --git a/metagpt/actions/requirement_analysis/trd/detect_interaction.py b/metagpt/actions/requirement_analysis/trd/detect_interaction.py index a46d77ba3..844266034 100644 --- a/metagpt/actions/requirement_analysis/trd/detect_interaction.py +++ b/metagpt/actions/requirement_analysis/trd/detect_interaction.py @@ -10,10 +10,16 @@ from tenacity import retry, stop_after_attempt, wait_random_exponential from metagpt.actions import Action from metagpt.logs import logger +from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import general_after_log, to_markdown_code_block +@register_tool(include_functions=["run"]) class DetectInteraction(Action): + """DetectInteraction deal with the following situations: + 1. Given a natural text of user requirements, it identifies the interaction events and the participants of those interactions from the original text. + """ + @retry( wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(6), @@ -27,6 +33,33 @@ class DetectInteraction(Action): legacy_interaction_events: str, evaluation_conclusion: str, ) -> str: + """ + Identifies interaction events and participants from the user requirements. + + Args: + user_requirements (str): A natural language text detailing the user's requirements. + use_case_actors (str): A description of the actors involved in the use case. + legacy_interaction_events (str): The previous version of the interaction events identified by you. + evaluation_conclusion (str): The external evaluation conclusions regarding the interactions events identified by you. + + Returns: + str: A string summarizing the identified interaction events and their participants. + + Example: + >>> detect_interaction = DetectInteraction() + >>> user_requirements = "User requirements 1. ..." + >>> use_case_actors = "- Actor: game player;\\n- System: snake game; \\n- External System: game center;" + >>> previous_version_interaction_events = "['interaction ...', ...]" + >>> evaluation_conclusion = "Issues: ..." + >>> interaction_events = await detect_interaction.run( + >>> user_requirements=user_requirements, + >>> use_case_actors=use_case_actors, + >>> legacy_interaction_events=previous_version_interaction_events, + >>> evaluation_conclusion=evaluation_conclusion, + >>> ) + >>> print(interaction_events) + "['interaction ...', ...]" + """ msg = PROMPT.format( use_case_actors=use_case_actors, original_user_requirements=to_markdown_code_block(val=user_requirements), diff --git a/metagpt/actions/requirement_analysis/trd/evaluate_trd.py b/metagpt/actions/requirement_analysis/trd/evaluate_trd.py index 2027a3c01..a46a38295 100644 --- a/metagpt/actions/requirement_analysis/trd/evaluate_trd.py +++ b/metagpt/actions/requirement_analysis/trd/evaluate_trd.py @@ -8,26 +8,66 @@ """ from metagpt.actions.requirement_analysis import EvaluateAction, EvaluationData +from metagpt.tools.tool_registry import register_tool from metagpt.utils.common import to_markdown_code_block +@register_tool(include_functions=["run"]) class EvaluateTRD(EvaluateAction): + """EvaluateTRD deal with the following situations: + 1. Given a TRD, evaluates the quality and returns a conclusion. + """ + async def run( self, *, user_requirements: str, use_case_actors: str, trd: str, - interaction_events: str = "", + interaction_events: str, legacy_user_requirements_interaction_events: str = "", - incremental_user_requirements_interaction_events: str = "", ) -> EvaluationData: + """ + Evaluates the given TRD based on user requirements, use case actors, interaction events, and optionally external legacy interaction events. + + Args: + user_requirements (str): The requirements provided by the user. + use_case_actors (str): The actors involved in the use case. + trd (str): The TRD (Technical Requirements Document) to be evaluated. + interaction_events (str): The interaction events related to the user requirements and the TRD. + legacy_user_requirements_interaction_events (str, optional): External legacy interaction events tied to the user requirements. Defaults to an empty string. + + Returns: + EvaluationData: The conclusion of the TRD evaluation. + + Example: + >>> evaluate_trd = EvaluateTRD() + >>> user_requirements = "User requirements 1. ..." + >>> use_case_actors = "- Actor: game player;\\n- System: snake game; \\n- External System: game center;" + >>> trd = "## TRD\\n..." + >>> interaction_events = "['interaction ...', ...]" + >>> evaluation_conclusion = "Issues: ..." + >>> legacy_user_requirements_interaction_events = ["user requirements 1. ...", ...] + >>> evaluation = await evaluate_trd.run( + >>> user_requirements=user_requirements, + >>> use_case_actors=use_case_actors, + >>> trd=trd, + >>> interaction_events=interaction_events, + >>> legacy_user_requirements_interaction_events=str(legacy_user_requirements_interaction_events), + >>> ) + >>> is_pass = evaluation.is_pass + >>> print(is_pass) + True + >>> evaluation_conclusion = evaluation.conclusion + >>> print(evaluation_conclusion) + ## Conclustion\n balabalabala... + + """ prompt = PROMPT.format( use_case_actors=use_case_actors, user_requirements=to_markdown_code_block(val=user_requirements), trd=to_markdown_code_block(val=trd), legacy_user_requirements_interaction_events=legacy_user_requirements_interaction_events, - incremental_user_requirements_interaction_events=incremental_user_requirements_interaction_events, interaction_events=interaction_events, ) return await self._vote(prompt) @@ -48,7 +88,6 @@ PROMPT = """ ## Interaction Events {legacy_user_requirements_interaction_events} -{incremental_user_requirements_interaction_events} {interaction_events} --- diff --git a/metagpt/actions/requirement_analysis/trd/write_trd.py b/metagpt/actions/requirement_analysis/trd/write_trd.py index 071de92f0..94fedb3b2 100644 --- a/metagpt/actions/requirement_analysis/trd/write_trd.py +++ b/metagpt/actions/requirement_analysis/trd/write_trd.py @@ -28,32 +28,28 @@ class WriteTRD(Action): use_case_actors: str, available_external_interfaces: str, evaluation_conclusion: str = "", - interaction_events: str = "", + interaction_events: str, + previous_version_trd: str = "", legacy_user_requirements: str = "", legacy_user_requirements_trd: str = "", legacy_user_requirements_interaction_events: str = "", - incremental_user_requirements: str = "", - previous_version_trd: str = "", - incremental_user_requirements_interaction_events: str = "", ) -> str: """ Handles the writing or updating of a Technical Requirements Document (TRD) based on user requirements. Args: - user_requirements (str, optional): New user requirements for creating a new TRD. This value must be not empty if a new TRD is wanted. + user_requirements (str): The new/incremental user requirements. use_case_actors (str): Description of the actors involved in the use case. available_external_interfaces (str): List of available external interfaces. - evaluation_conclusion (str, optional): Conclusion of the evaluation of the requirements. Defaults to an empty string. - interaction_events (str, optional): Events related to user interactions. Defaults to an empty string. - legacy_user_requirements (str, optional): Existing user requirements if updating. Defaults to an empty string. - legacy_user_requirements_trd (str, optional): The TRD associated with the existing user requirements. Defaults to an empty string. - legacy_user_requirements_interaction_events (str, optional): Interaction events related to the existing user requirements. Defaults to an empty string. - incremental_user_requirements (str, optional): New incremental user requirements for updating the TRD. Defaults to an empty string. - previous_version_trd (str, optional): The previous version of the TRD if updating incrementally. Defaults to an empty string. - incremental_user_requirements_interaction_events (str, optional): Interaction events related to the incremental user requirements. Defaults to an empty string. + evaluation_conclusion (str, optional): The conclusion of the evaluation of the TRD written by you. Defaults to an empty string. + interaction_events (str): The interaction events related to the user requirements that you are handling. + previous_version_trd (str, optional): The previous version of the TRD written by you, for updating. + legacy_user_requirements (str, optional): Existing user requirements handled by an external object for your use. Defaults to an empty string. + legacy_user_requirements_trd (str, optional): The TRD associated with the existing user requirements handled by an external object for your use. Defaults to an empty string. + legacy_user_requirements_interaction_events (str, optional): Interaction events related to the existing user requirements handled by an external object for your use. Defaults to an empty string. Returns: - str: The newly created or updated TRD. + str: The newly created or updated TRD written by you. Example: >>> # Given a new user requirements, write out a new TRD. @@ -63,48 +59,53 @@ class WriteTRD(Action): >>> previous_version_trd = "TRD ..." # The last version of the TRD written out if there is. >>> evaluation_conclusion = "Conclusion ..." # The conclusion returned by `EvaluateTRD.run` if there is. >>> interaction_events = "Interaction ..." # The interaction events returned by `DetectInteraction.run`. - >>> write_trd = WriteTRD(context=context) + >>> write_trd = WriteTRD() >>> new_version_trd = await write_trd.run( >>> user_requirements=user_requirements, >>> use_case_actors=use_case_actors, >>> available_external_interfaces=available_external_interfaces, - >>> previous_version_trd=previous_version_trd, >>> evaluation_conclusion=evaluation_conclusion, >>> interaction_events=interaction_events, + >>> previous_version_trd=previous_version_trd, >>> ) >>> print(new_version_trd) ## Technical Requirements Document\n ... >>> # Given an incremental requirements, update the legacy TRD. >>> legacy_user_requirements = ["User requirements 1. ...", "User requirements 2. ...", ...] - >>> use_case_actors = "- Actor: game player;\\n- System: snake game; \\n- External System: game center;" - >>> available_external_interfaces = "The available external interfaces returned by `CompressExternalInterfaces.run` are ..." >>> legacy_user_requirements_trd = "## Technical Requirements Document\\n ..." # The TRD before integrating more user requirements. >>> legacy_user_requirements_interaction_events = ["The interaction events list of user requirements 1 ...", "The interaction events list of user requiremnts 2 ...", ...] - >>> incremental_user_requirements + >>> use_case_actors = "- Actor: game player;\\n- System: snake game; \\n- External System: game center;" + >>> available_external_interfaces = "The available external interfaces returned by `CompressExternalInterfaces.run` are ..." + >>> increment_requirements = "The incremental user requirements are ..." + >>> evaluation_conclusion = "Conclusion ..." # The conclusion returned by `EvaluateTRD.run` if there is. + >>> previous_version_trd = "TRD ..." # The last version of the TRD written out if there is. + >>> write_trd = WriteTRD() >>> new_version_trd = await write_trd.run( - >>> legacy_user_requirements=str(legacy_user_requirements), + >>> user_requirements=increment_requirements, >>> use_case_actors=use_case_actors, >>> available_external_interfaces=available_external_interfaces, + >>> evaluation_conclusion=evaluation_conclusion, + >>> interaction_events=interaction_events, + >>> previous_version_trd=previous_version_trd, + >>> legacy_user_requirements=str(legacy_user_requirements), >>> legacy_user_requirements_trd=legacy_user_requirements_trd, >>> legacy_user_requirements_interaction_events=str(legacy_user_requirements_interaction_events), - >>> incremental_user_requirements=r, - previous_version_trd=trd, - evaluation_conclusion=evaluation_conclusion, - incremental_user_requirements_interaction_events=interaction_events, - ) + >>> ) + >>> print(new_version_trd) + ## Technical Requirements Document\n ... """ - if incremental_user_requirements: + if legacy_user_requirements: return await self._write_incremental_trd( use_case_actors=use_case_actors, legacy_user_requirements=legacy_user_requirements, available_external_interfaces=available_external_interfaces, legacy_user_requirements_trd=legacy_user_requirements_trd, legacy_user_requirements_interaction_events=legacy_user_requirements_interaction_events, - incremental_user_requirements=incremental_user_requirements, + incremental_user_requirements=user_requirements, previous_version_trd=previous_version_trd, evaluation_conclusion=evaluation_conclusion, - incremental_user_requirements_interaction_events=incremental_user_requirements_interaction_events, + incremental_user_requirements_interaction_events=interaction_events, ) return await self._write_new_trd( use_case_actors=use_case_actors,