metagpt入门(三)多动作Agent

实现一个多动作Agent

都在代码注释里了,主要记住这些步骤就写出代码来了

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())

你可能感兴趣的:(python)