整体概念总结
智能体的实现方法
-
安装与配置:安装和配置MetaGPT,包括Python环境的准备、MetaGPT的安装(通过pip或git拉取代码),以及配置大模型API(如智谱、科大讯飞、百度千帆等)。
-
单动作单智能体:我们通过定义简单的动作(如写唐诗、写代码)和角色(如SimpleCoder),实现了一个能够执行单一任务的智能体。
-
多动作单智能体:通过组合多个动作(如写代码和运行代码),我们实现了一个能够执行复杂任务的智能体(如RunnableCoder)。
-
多智能体系统:通过模拟辩论场景(辩论智能体为例),我们展示了如何设计多个智能体并促进它们之间的互动,帮助我们在实际工作中做出更好的决策。
代码解析与核心逻辑
-
动作(Action):动作是智能体执行任务的基本单元。通过定义
Action
类,我们可以让智能体执行特定的任务。例如,SimpleWriteCode
动作可以让智能体根据自然语言描述生成代码。 -
角色(Role):角色是智能体的抽象,它包含了智能体的名称、配置文件、动作和记忆。通过定义
Role
类,我们可以为智能体配备特定的动作,并定义其行为逻辑。例如,SimpleCoder
角色配备了SimpleWriteCode
动作,能够根据用户指令生成代码。 -
多智能体交互:在多智能体系统中,智能体之间通过消息进行通信。通过定义
Debator
角色和SpeakAloud
动作,我们模拟了正方和反方之间的辩论过程。每个智能体根据对方的论点进行反驳,并通过消息传递进行交互。
核心代码解释
动作定义:这段代码定义了一个SimpleWriteCode
动作,它根据用户指令生成Python代码,并返回代码文本。
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:
"""
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
角色定义:这段代码定义了一个SimpleCoder
角色,它配备了SimpleWriteCode
动作,能够根据用户指令生成代码并返回结果。
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:
msg = self.get_memories(k=1)[0]
code_text = await self.rc.todo.run(msg.content)
return Message(content=code_text, role=self.profile, cause_by=type(self.rc.todo))
多智能体交互:这段代码定义了一个Debator
角色,它配备了SpeakAloud
动作,能够根据对方的论点进行反驳,并通过消息传递进行交互。
class Debator(Role):
name: str = ""
profile: str = ""
opponent_name: str = ""
def __init__(self, **data: Any):
super().__init__(**data)
self.set_actions([SpeakAloud])
self._watch([UserRequirement, SpeakAloud])
async def _act(self) -> Message:
memories = self.get_memories()
context = "\n".join(f"{msg.sent_from}: {msg.content}" for msg in memories)
rsp = await self.rc.todo.run(context=context, name=self.name, opponent_name=self.opponent_name)
return Message(content=rsp, role=self.profile, cause_by=type(self.rc.todo), sent_from=self.name, send_to=self.opponent_name)