利用metaGPT多智能体框架实现智能体-2
1.一些帮助理解的概念
智能体
在MetaGPT看来,可以将智能体想象成环境中的数字人,其中
智能体 = 大语言模型(LLM) + 观察 + 思考 + 行动 + 记忆
这个公式概括了智能体的功能本质。为了理解每个组成部分,让我们将其与人类进行类比:
- 大语言模型(LLM):LLM作为智能体的“大脑”部分,使其能够处理信息,从交互中学习,做出决策并执行行动。
- 观察:这是智能体的感知机制,使其能够感知其环境。智能体可能会接收来自另一个智能体的文本消息、来自监视摄像头的视觉数据或来自客户服务录音的音频等一系列信号。这些观察构成了所有后续行动的基础。
- 思考:思考过程涉及分析观察结果和记忆内容并考虑可能的行动。这是智能体内部的决策过程,其可能由LLM进行驱动。
- 行动:这些是智能体对其思考和观察的显式响应。行动可以是利用 LLM 生成代码,或是手动预定义的操作,如阅读本地文件。此外,智能体还可以执行使用工具的操作,包括在互联网上搜索天气,使用计算器进行数学计算等。
- 记忆:智能体的记忆存储过去的经验。这对学习至关重要,因为它允许智能体参考先前的结果并据此调整未来的行动。
多智能体
多智能体系统可以视为一个智能体社会,其中
多智能体 = 智能体 + 环境 + 标准流程(SOP) + 通信 + 经济
这些组件各自发挥着重要的作用:
- 智能体:在上面单独定义的基础上,在多智能体系统中的智能体协同工作,每个智能体都具备独特有的LLM、观察、思考、行动和记忆。
- 环境:环境是智能体生存和互动的公共场所。智能体从环境中观察到重要信息,并发布行动的输出结果以供其他智能体使用。
- 标准流程(SOP):这些是管理智能体行动和交互的既定程序,确保系统内部的有序和高效运作。例如,在汽车制造的SOP中,一个智能体焊接汽车零件,而另一个安装电缆,保持装配线的有序运作。
- 通信:通信是智能体之间信息交流的过程。它对于系统内的协作、谈判和竞争至关重要。
- 经济:这指的是多智能体环境中的价值交换系统,决定资源分配和任务优先级。
任务
对于每一个任务,至少要明确两点:目标和期望。目标和期望都可以用自然语言去描述。
其他需要明确的是 上下文、回调、输出、使用的工具。
回调可以是一个python函数。使用的工具可以是一个python列表。
你可以用pydantic去约束输出。把大模型的模糊输出变为强制结构化输出。
2.单动作单智能体
如何去思考自定义一个智能体呢?一般都要从我们的目的出发,将实现目的的过程分解,然后得到动作,将动作赋予一个智能体,我们就得到了一个可以实现我们目的的智能体。
下面考虑这样一个问题”我们希望用自然语言编写代码“,那么就需要两个思考步骤:
- 定义一个编写代码的动作;
- 将该动作赋予智能体;
然后我们就得到了可以解决该问题的一个单动作智能体。接下来看看具体实现:
定义动作:
在 MetaGPT 中,类 Action 是动作的逻辑抽象。用户可以通过简单地调用 self._aask 函数令 LLM 赋予这个动作能力,即这个函数将在底层调用 LLM api。
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
定义角色:
在 MetaGPT 中,Role 类是智能体的逻辑抽象。一个 Role 能执行特定的 Action,拥有记忆、思考并采用各种策略行动。基本上,它充当一个将所有这些组件联系在一起的凝聚实体。目前,让我们只关注一个执行动作的智能体,并看看如何定义一个最简单的 Role。
import re
import os
from metagpt.roles import Role
from metagpt.schema import Message
from metagpt.logs import logger
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 # todo will be SimpleWriteCode()
msg = self.get_memories(k=1)[0] # find the most recent messages
code_text = await todo.run(msg.content)
msg = Message(content=code_text, role=self.profile, cause_by=type(todo))
return msg
运行
async def main():
msg = "write a function that calculates the sum of a list"
role = SimpleCoder()
logger.info(msg)
result = await role.run(msg)
logger.info(result)
return result
rtn = await main()
输出如下: