本教程将带你从零开始,一步步打造你的第一个 MetaGPT 智能体。通过本教程,你将学会:
友情链接:ACEJoy
- 使用现成的智能体
- 开发一个可以执行一个或多个动作的智能体
使用现成的智能体
MetaGPT 提供了许多现成的智能体,你可以直接导入并使用。例如,以下代码展示了如何使用 ProductManager
智能体来编写一个产品需求文档 (PRD):
import asyncio
from metagpt.context import Context
from metagpt.roles.product_manager import ProductManager
from metagpt.logs import logger
async def main():
msg = "Write a PRD for a snake game"
context = Context() # 创建会话上下文对象
role = ProductManager(context=context) # 初始化智能体
while msg:
msg = await role.run(msg) # 运行智能体
logger.info(str(msg))
if __name__ == '__main__':
asyncio.run(main())
这段代码首先导入必要的模块,然后定义一个 main
函数。在 main
函数中,我们创建了一个会话上下文对象 context
,并使用 ProductManager
类初始化一个智能体 role
。最后,我们使用 role.run()
方法运行智能体,并打印输出结果。
开发你的第一个智能体
从实际应用的角度来看,一个有用的智能体需要能够执行某些动作。MetaGPT 提供了高度灵活的方式来定义自己的动作和智能体。
1. 定义动作
在 MetaGPT 中,Action
类是动作的抽象表示。你可以使用 LLM 来增强 Action
,只需调用 self._aask
函数即可。
例如,我们想创建一个名为 SimpleWriteCode
的动作,用于根据自然语言描述编写 Python 代码:
import re
from metagpt.actions import Action
class SimpleWriteCode(Action):
PROMPT_TEMPLATE: str = """
Write a python function that can {instruction} and provide two runnnable test cases.
Return ```python your_code_here ``` with NO other texts,
your code:
"""
name: str = "SimpleWriteCode"
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
这段代码定义了一个名为 SimpleWriteCode
的类,它继承自 Action
类。该类包含一个 PROMPT_TEMPLATE
属性,用于定义提示词模板。run
方法接受一个自然语言描述 instruction
,并使用提示词模板生成一个提示词,然后调用 _aask
函数向 LLM 发送请求,并返回代码文本。
2. 定义角色
在 MetaGPT 中,Role
类是智能体的抽象表示。一个角色可以执行某些动作,拥有记忆,并根据不同的策略进行思考和行动。
例如,我们想创建一个名为 SimpleCoder
的角色,它可以使用 SimpleWriteCode
动作来编写代码:
from metagpt.roles import Role
class SimpleCoder(Role):
name: str = "Alice"
profile: str = "SimpleCoder"
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_actions([SimpleWriteCode])
async def _act(self) -> Message:
logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
todo = self.rc.todo # 获取当前动作
msg = self.get_memories(k=1)[0] # 获取最近一条消息
code_text = await todo.run(msg.content) # 执行动作
msg = Message(content=code_text, role=self.profile, cause_by=type(todo))
return msg
这段代码定义了一个名为 SimpleCoder
的类,它继承自 Role
类。该类包含一个 name
属性和一个 profile
属性,用于定义角色的名称和描述。__init__
方法用于初始化角色,并使用 set_actions
方法添加 SimpleWriteCode
动作。_act
方法定义了角色的行动逻辑,它会获取最近一条消息,并使用当前动作执行代码编写任务。
3. 运行你的角色
现在,你可以初始化你的角色并运行它:
import asyncio
from metagpt.context import Context
async def main():
msg = "write a function that calculates the product of a list"
context = Context()
role = SimpleCoder(context=context)
logger.info(msg)
result = await role.run(msg)
logger.info(result)
asyncio.run(main())
这段代码首先定义一个 main
函数,并创建一个会话上下文对象 context
。然后,我们使用 SimpleCoder
类初始化一个角色 role
。最后,我们使用 role.run()
方法运行角色,并打印输出结果。
智能体拥有多个动作
一个智能体可以拥有多个动作,并根据不同的策略来选择执行哪个动作。例如,我们想创建一个名为 RunnableCoder
的角色,它可以编写代码并立即执行:
1. 定义动作
除了 SimpleWriteCode
动作,我们还需要定义一个名为 SimpleRunCode
的动作,用于执行代码:
class SimpleRunCode(Action):
name: str = "SimpleRunCode"
async def run(self, code_text: str):
result = subprocess.run(["python3", "-c", code_text], capture_output=True, text=True)
code_result = result.stdout
logger.info(f"{code_result=}")
return code_result
2. 定义角色
我们修改 RunnableCoder
角色,使其拥有 SimpleWriteCode
和 SimpleRunCode
两个动作:
class RunnableCoder(Role):
name: str = "Alice"
profile: str = "RunnableCoder"
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.set_actions([SimpleWriteCode, SimpleRunCode])
self._set_react_mode(react_mode="by_order")
async def _act(self) -> Message:
logger.info(f"{self._setting}: to do {self.rc.todo}({self.rc.todo.name})")
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
这段代码中,我们使用 set_actions
方法添加了两个动作,并使用 _set_react_mode
方法设置了动作执行策略为 by_order
,表示按照动作定义的顺序执行。
3. 运行你的角色
现在,你可以初始化 RunnableCoder
角色并运行它:
import asyncio
from metagpt.context import Context
async def main():
msg = "write a function that calculates the product of a list"
context = Context()
role = RunnableCoder(context=context)
logger.info(msg)
result = await role.run(msg)
logger.info(result)
asyncio.run(main)
这段代码与之前类似,只是使用了 RunnableCoder
角色。
总结
本教程展示了如何使用 MetaGPT 创建一个简单的智能体,并演示了如何定义动作和角色,以及如何运行智能体。你可以在此基础上进一步扩展你的智能体,使其能够执行更复杂的任务。
更多学习资源
- MetaGPT 文档:了解更多关于 MetaGPT 的信息。
- MetaGPT Github:查看 MetaGPT 的源代码和示例。
- MetaGPT 论文:深入了解 MetaGPT 的技术细节。