模型智能体开发之metagpt-单智能体实践

2024-05-01 13:52

本文主要是介绍模型智能体开发之metagpt-单智能体实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

需求分析

  1. 根据诉求完成函数代码的编写,并实现测试case,输出代码

代码实现

定义写代码的action

  1. action是动作的逻辑抽象,通过将预设的prompt传入llm,来获取输出,并对输出进行格式化

  2. 具体的实现如下

    1. 定义prompt模版

      1. prompt是传给llm的入参,所以llm对prompt的需求解析越准确,那么llm的输出就会越符合我们的诉求
      2. 如何抽象出最合适的prompt模版
      PROMPT_TEMPLATE = """Write a python function that can {instruction} and provide two runnnable test cases.Return ```python your_code_here ```with NO other texts,your code:"""
      
    2. 调用llm生成代码

      1. 通过传入的instruction参数来格式化llm入参,之后通过aask调用llm进行输出。因为llm的输出是并不一定会符合我们的诉求,所以需要按照需求对output进行格式化
      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  
      
    3. 对llm output进行格式化

      1. 正则表达式提取其中的code部分,llm在返回给我们代码时通常带有一些格式化标识,而这些格式化标识往往是我们所不需要的
      2. 格式方法:
       @staticmethoddef parse_code(rsp):pattern = r'```python(.*)```'match = re.search(pattern, rsp, re.DOTALL)code_text = match.group(1) if match else rspreturn code_text
      
  3. 完整代码

    import asyncio
    import re
    import subprocessimport firefrom metagpt.actions import Action
    from metagpt.logs import logger
    from metagpt.roles.role import Role, RoleReactMode
    from metagpt.schema import Messageclass 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@staticmethoddef parse_code(rsp):pattern = r"```python(.*)```"match = re.search(pattern, rsp, re.DOTALL)code_text = match.group(1) if match else rspreturn code_text
    

创建一个role

  1. 初始化上下文

    class SimpleCoder(Role):name: str = "Alice"profile: str = "SimpleCoder"def __init__(self, **kwargs):super().__init__(**kwargs)self.set_actions([SimpleWriteCode])
    
    1. 可以看到创建了一个名为SimpleCoder的类,继承了Role,标明当前类是一个role的定位
    2. 其中name指定了当前role的名称
    3. 其中name指定了当前role的类型
    4. 然后我们重写了__init__方法,
    5. 绑定要执行的action是SimpleWriteCode,这个Action 能根据我们的需求生成我们期望的代码,定义的行动SimpleWriteCode会被加入到代办self._rc.todo中,
  2. 定义执行规则

    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 messagescode_text = await todo.run(msg.content)msg = Message(content=code_text, role=self.profile, cause_by=type(todo))return msg 
    
    1. 重写_act,编写智能体具体的行动逻辑
    2. self.rc.todo:待办事项
    3. self.get_memories(k=1)[0]:获取最新的一条memory,即本次case里面的用户下达的指令
      1. 在本次的case里面,当用户输出instruction的时候,role需要把instruction传递给action,这里就涉及到了user如何传递消息给agent的部分,是通过memory来传递的
      2. memory作为agent的记忆合集,当role在进行初始化的时候,role就会初始化一个memory对象来作为self._rc.memory属性,在之后的_observe中存储每一个message,以便后续的检索,所以也可以理解role的memory就是一个含有message的list
      3. 当需要获取memory(llm的对话context)的时候,就可以使用get_memories(self, k=0) -> list[Message] 方法
    4. todo.run(msg.content):使用待办事项来处理最新一条memory
    5. Message:作为metagpt里面统一的消息处理格式
  3. 完整代码

        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 messagescode_text = await todo.run(msg.content)msg = Message(content=code_text, role=self.profile, cause_by=type(todo))return msg```
  4. 测试demo

    1. 代码

      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)asyncio.run(main())
      
    2. 运行

      1. 如下图,role alice 关联到了action,并且action调用了llm,获取到的llm输出是一条代码。注意,代码格式有python格式化标识,所以在代码实现层面我们通过parse_code方法去掉了python的格式化标识。
      2. llm输出分为两部分,一部分是方法,另外一部分是测试case
        在这里插入图片描述

demo如果想正常运行的话,需要调用llm的key,环境配置可以参照 metagpt环境配置参考

这篇关于模型智能体开发之metagpt-单智能体实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/951868

相关文章

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参

使用C++实现单链表的操作与实践

《使用C++实现单链表的操作与实践》在程序设计中,链表是一种常见的数据结构,特别是在动态数据管理、频繁插入和删除元素的场景中,链表相比于数组,具有更高的灵活性和高效性,尤其是在需要频繁修改数据结构的应... 目录一、单链表的基本概念二、单链表类的设计1. 节点的定义2. 链表的类定义三、单链表的操作实现四、

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus