都在代码注释里了,主要记住这些步骤就写出代码来了
import asyncio
import os
import re
import subprocess
from metagpt.schema import Message
from metagpt.logs import logger
from metagpt.actions import Action
from metagpt.roles import Role
class SimpleWriteCode(Action):
PROMPT_TEMPLATE = """
Write a python function that can {instruction} and provide two runnable test cases.
Return ```python your_code_here ``` with NO other texts,
your code:
"""
def __init__(self, name="SimpleWriteCode", context=None, llm=None):
super().__init__(name, context, llm)
async def run(self, instruction: str):
prompt = self.PROMPT_TEMPLATE.format(instruction=instruction)
rsp = await self._aask(prompt)
code_text = SimpleWriteCode.parse_code(rsp)
return code_text
@staticmethod
def parse_code(rsp):
pattern = r'```python(.*)```'
match = re.search(pattern, rsp, re.DOTALL)
code_text = match.group(1) if match else rsp
return code_text
class SimpleRunCode(Action):
def __init__(self, name="SimpleRunCode", context=None, llm=None):
super().__init__(name, context, llm)
async def run(self, code_text: str):
# 在Windows环境下,result可能无法正确返回生成结果,在windows中在终端中输入python3可能会导致打开微软商店
#result = subprocess.run(["python3", "-c", code_text], capture_output=True, text=True)
# 采用下面的可选代码来替换上面的代码
# result = subprocess.run(["python", "-c", code_text], capture_output=True, text=True)
import sys
result = subprocess.run([sys.executable, "-c", code_text], capture_output=True, text=True)
code_result = result.stdout
logger.info(f"{code_result=}")
return code_result
class RunnableCoder(Role):
def __init__(self, name="Alice", profile = "RunnableCoder"):
#角色类初始化函数3部曲,调用父类初始化函数、初始化所要执行的动作、如果是多个动作,初始化多个动作的执行顺序
super().__init__(name, profile)
self._init_actions([SimpleWriteCode, SimpleRunCode])
self._set_react_mode(react_mode="by_order")
async def _act(self) -> Message:
logger.info(f'{self._setting}:准备 {self._rc.todo}')
#动作好函数5部曲
#获取要执行的动作,放入todo局部变量
todo = self._rc.todo
#获取执行动作需要的指令消息
msg = self.get_memories(k=1)[0]
#异步执行消息
result = await todo.run(msg.content)
#封装消息
msg = Message(content=result, role=self.profile,cause_by=type(todo))
#消息加入记忆列表,方便多动作使用
self._rc.memory.add(msg)
return msg
#运行 RunnableCoder 角色
async def main():
msg = "write a function that calculates the sum of a list"
role = RunnableCoder()
logger.info(msg)
result = await role.run(msg)
logger.info(result)
asyncio.run(main())