mirror of
https://github.com/FoundationAgents/MetaGPT.git
synced 2026-07-02 16:01:04 +02:00
write_prd_json
This commit is contained in:
parent
ddf4697381
commit
c2ad5a5036
9 changed files with 1912 additions and 3 deletions
|
|
@ -21,6 +21,7 @@ from metagpt.actions.search_and_summarize import SearchAndSummarize
|
|||
from metagpt.actions.write_code import WriteCode
|
||||
from metagpt.actions.write_code_review import WriteCodeReview
|
||||
from metagpt.actions.write_prd import WritePRD
|
||||
from metagpt.actions.write_prd_json import WritePRDJson
|
||||
from metagpt.actions.write_prd_review import WritePRDReview
|
||||
from metagpt.actions.write_test import WriteTest
|
||||
|
||||
|
|
@ -30,6 +31,7 @@ class ActionType(Enum):
|
|||
|
||||
ADD_REQUIREMENT = BossRequirement
|
||||
WRITE_PRD = WritePRD
|
||||
WRITE_PRD_JSON = WritePRDJson
|
||||
WRITE_PRD_REVIEW = WritePRDReview
|
||||
WRITE_DESIGN = WriteDesign
|
||||
DESIGN_REVIEW = DesignReview
|
||||
|
|
|
|||
|
|
@ -5,16 +5,20 @@
|
|||
@Author : alexanderwu
|
||||
@File : action.py
|
||||
"""
|
||||
import json
|
||||
from abc import ABC
|
||||
from typing import Optional
|
||||
|
||||
from tenacity import retry, stop_after_attempt, wait_fixed
|
||||
import regex
|
||||
|
||||
from metagpt.actions.action_output import ActionOutput
|
||||
from metagpt.llm import LLM
|
||||
from metagpt.utils.common import OutputParser
|
||||
from metagpt.logs import logger
|
||||
|
||||
|
||||
|
||||
class Action(ABC):
|
||||
def __init__(self, name: str = '', context=None, llm: LLM = None):
|
||||
self.name: str = name
|
||||
|
|
@ -62,6 +66,27 @@ class Action(ABC):
|
|||
instruct_content = output_class(**parsed_data)
|
||||
return ActionOutput(content, instruct_content)
|
||||
|
||||
@retry(stop=stop_after_attempt(2), wait=wait_fixed(1))
|
||||
async def _aask_json_v1(self, prompt: str, output_class_name: str,
|
||||
output_data_mapping: dict,
|
||||
system_msgs: Optional[list[str]] = None) -> ActionOutput:
|
||||
"""Append default prefix"""
|
||||
if not system_msgs:
|
||||
system_msgs = []
|
||||
system_msgs.append(self.prefix)
|
||||
content = await self.llm.aask(prompt, system_msgs)
|
||||
logger.debug(content)
|
||||
output_class = ActionOutput.create_model_class(output_class_name, output_data_mapping)
|
||||
json_regex = r"\{(?:[^{}]|(?R))*\}"
|
||||
json = regex.search(
|
||||
json_regex, content
|
||||
).group()
|
||||
generated_plan = json.loads(json)
|
||||
parsed_data = OutputParser.parse_data_with_mapping(content, output_data_mapping)
|
||||
logger.debug(parsed_data)
|
||||
instruct_content = output_class(**parsed_data)
|
||||
return ActionOutput(content, instruct_content)
|
||||
|
||||
async def run(self, *args, **kwargs):
|
||||
"""Run action"""
|
||||
raise NotImplementedError("The run method should be implemented in a subclass.")
|
||||
|
|
|
|||
133
metagpt/actions/write_prd_json.py
Normal file
133
metagpt/actions/write_prd_json.py
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
@Time : 2023/5/11 17:45
|
||||
@Author : alexanderwu
|
||||
@File : write_prd.py
|
||||
"""
|
||||
from typing import List, Tuple
|
||||
|
||||
from metagpt.actions import Action, ActionOutput
|
||||
from metagpt.actions.search_and_summarize import SearchAndSummarize
|
||||
from metagpt.logs import logger
|
||||
|
||||
PROMPT_TEMPLATE = """
|
||||
# Context
|
||||
## Original Requirements
|
||||
{requirements}
|
||||
|
||||
## Search Information
|
||||
{search_information}
|
||||
|
||||
## mermaid quadrantChart code syntax example. DONT USE QUOTO IN CODE DUE TO INVALID SYNTAX. Replace the <Campain X> with REAL COMPETITOR NAME
|
||||
```mermaid
|
||||
quadrantChart
|
||||
title Reach and engagement of campaigns
|
||||
x-axis Low Reach --> High Reach
|
||||
y-axis Low Engagement --> High Engagement
|
||||
quadrant-1 We should expand
|
||||
quadrant-2 Need to promote
|
||||
quadrant-3 Re-evaluate
|
||||
quadrant-4 May be improved
|
||||
"Campaign: A": [0.3, 0.6]
|
||||
"Campaign B": [0.45, 0.23]
|
||||
"Campaign C": [0.57, 0.69]
|
||||
"Campaign D": [0.78, 0.34]
|
||||
"Campaign E": [0.40, 0.34]
|
||||
"Campaign F": [0.35, 0.78]
|
||||
"Our Target Product": [0.5, 0.6]
|
||||
```
|
||||
|
||||
## Format example
|
||||
{format_example}
|
||||
-----
|
||||
Role: You are a professional product manager; the goal is to design a concise, usable, efficient product
|
||||
Requirements: According to the context, fill in the following missing information, note that each sections are returned in Python code triple quote form seperatedly. If the requirements are unclear, ensure minimum viability and avoid excessive design
|
||||
|
||||
## Original Requirements: Provide as Plain text, place the polished complete original requirements here
|
||||
|
||||
## Product Goals: Provided as Python list[str], up to 3 clear, orthogonal product goals. If the requirement itself is simple, the goal should also be simple
|
||||
|
||||
## User Stories: Provided as Python list[str], up to 5 scenario-based user stories, If the requirement itself is simple, the user stories should also be less
|
||||
|
||||
## Competitive Analysis: Provided as Python list[str], up to 7 competitive product analyses, consider as similar competitors as possible
|
||||
|
||||
## Competitive Quadrant Chart: Use mermaid quadrantChart code syntax. up to 14 competitive products. Translation: Distribute these competitor scores evenly between 0 and 1, trying to conform to a normal distribution centered around 0.5 as much as possible.
|
||||
|
||||
## Requirement Analysis: Provide as Plain text. Be simple. LESS IS MORE. Make your requirements less dumb. Delete the parts unnessasery.
|
||||
|
||||
## Requirement Pool: Provided as Python list[str, str], the parameters are requirement description, priority(P0/P1/P2), respectively, comply with PEP standards; no more than 5 requirements and consider to make its difficulty lower
|
||||
|
||||
## UI Design draft: Provide as Plain text. Be simple. Describe the elements and functions, also provide a simple style description and layout description.
|
||||
## Anything UNCLEAR: Provide as Plain text. Make clear here.
|
||||
|
||||
Your job is to create a properly formatted JSON
|
||||
"""
|
||||
FORMAT_EXAMPLE = """
|
||||
{
|
||||
"Original Requirements": "",
|
||||
"Search Information": "",
|
||||
"mermaid quadrantChart code": '''
|
||||
"title": "Reach and engagement of campaigns",
|
||||
"x-axis": "Low Reach --> High Reach",
|
||||
"y-axis": "Low Engagement --> High Engagement",
|
||||
"quadrant-1": "We should expand",
|
||||
"quadrant-2": "Need to promote",
|
||||
"quadrant-3": "Re-evaluate",
|
||||
"quadrant-4": "May be improved",
|
||||
"Campaign: A": [0.3, 0.6],
|
||||
"Campaign B": [0.45, 0.23],
|
||||
"Campaign C": [0.57, 0.69],
|
||||
"Campaign D": [0.78, 0.34],
|
||||
"Campaign E": [0.40, 0.34],
|
||||
"Campaign F": [0.35, 0.78],
|
||||
"Our Target Product": [0.5, 0.6]
|
||||
'''
|
||||
,
|
||||
|
||||
},
|
||||
"Role": "You are a professional product manager; the goal is to design a concise, usable, efficient product",
|
||||
"Requirements": "",
|
||||
"Product Goals": [],
|
||||
"User Stories": [],
|
||||
"Competitive Analysis": [],
|
||||
"Competitive Quadrant Chart": "",
|
||||
"Requirement Analysis": "",
|
||||
"Requirement Pool": [],
|
||||
"UI Design draft": "",
|
||||
"Anything UNCLEAR": "",
|
||||
}
|
||||
"""
|
||||
OUTPUT_MAPPING = {
|
||||
"Original Requirements": (str, ...),
|
||||
"Product Goals": (List[str], ...),
|
||||
"User Stories": (List[str], ...),
|
||||
"Competitive Analysis": (List[str], ...),
|
||||
"Competitive Quadrant Chart": (str, ...),
|
||||
"Requirement Analysis": (str, ...),
|
||||
"Requirement Pool": (List[Tuple[str, str]], ...),
|
||||
"UI Design draft":(str, ...),
|
||||
"Anything UNCLEAR": (str, ...),
|
||||
}
|
||||
|
||||
|
||||
class WritePRDJson(Action):
|
||||
def __init__(self, name="", context=None, llm=None):
|
||||
super().__init__(name, context, llm)
|
||||
|
||||
async def run(self, requirements, *args, **kwargs) -> ActionOutput:
|
||||
sas = SearchAndSummarize()
|
||||
# rsp = await sas.run(context=requirements, system_text=SEARCH_AND_SUMMARIZE_SYSTEM_EN_US)
|
||||
rsp = ""
|
||||
info = f"### Search Results\n{sas.result}\n\n### Search Summary\n{rsp}"
|
||||
if sas.result:
|
||||
logger.info(sas.result)
|
||||
logger.info(rsp)
|
||||
|
||||
prompt = PROMPT_TEMPLATE.format(requirements=requirements, search_information=info,
|
||||
format_example=FORMAT_EXAMPLE)
|
||||
logger.debug(prompt)
|
||||
#prd = await self._aask_v1(prompt, "prd", OUTPUT_MAPPING)
|
||||
prd = await self._aask_json_v1(prompt, "prd", OUTPUT_MAPPING)
|
||||
return prd
|
||||
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
@Author : alexanderwu
|
||||
@File : product_manager.py
|
||||
"""
|
||||
from metagpt.actions import BossRequirement, WritePRD
|
||||
from metagpt.actions import BossRequirement, WritePRD,WritePRDJson
|
||||
from metagpt.roles import Role
|
||||
|
||||
|
||||
|
|
@ -35,5 +35,5 @@ class ProductManager(Role):
|
|||
constraints (str): Constraints or limitations for the product manager.
|
||||
"""
|
||||
super().__init__(name, profile, goal, constraints)
|
||||
self._init_actions([WritePRD])
|
||||
self._init_actions([WritePRDJson])
|
||||
self._watch([BossRequirement])
|
||||
Loading…
Add table
Add a link
Reference in a new issue