metagpt中ActionNode的用法

目录

    • 整体流程
      • 1. 基础组件:
      • 2. SIMPLE_THINK_NODE 和 SIMPLE_CHECK_NODE:
      • 3. THINK_NODES 类:
      • 4. ThinkAction 类:
      • 5. SimplePrint 类:
      • 6. Printer 类:
      • 7. main 函数:
      • 总结:
      • 主要执行流程:
    • 代码
    • 参考链接:

整体流程

实现一个基于节点 (Node) 结构和思维推理的系统,用于生成和打印数字列表。它使用了 ActionNode 和 Action 类来定义任务和节点,并且通过异步任务执行逻辑来实现工作流。

1. 基础组件:

ActionNode 和 Action 类:

  • ActionNode 是一个继承自 ActionNode 类的对象,负责执行特定任务的节点。每个节点可以有子节点,形成树形结构。
  • Action 是执行动作的基础类,ThinkAction 和 SimplePrint 继承自 Action。

2. SIMPLE_THINK_NODE 和 SIMPLE_CHECK_NODE:

这两个节点负责“思考”和“检查”数字列表的生成:

  • SIMPLE_THINK_NODE:这个节点的任务是思考生成一个数字列表的过程,传入的 instruction 说明需要生成什么样的数字列表(例如 Fibonacci 数列的前 10 个数字)。
  • SIMPLE_CHECK_NODE:这个节点负责接收数字列表,并确保返回的格式严格符合要求,返回的格式必须是像 [1,2,3,4] 这样的数组。

3. THINK_NODES 类:

THINK_NODES 类继承自 ActionNode,代表一个包含子节点的节点(SIMPLE_THINK_NODE 和 SIMPLE_CHECK_NODE)。
它有一个 simple_fill 方法,负责根据给定的 context 生成思考内容,并用 LLM(Large Language Model)生成数字列表。子节点的返回内容会被依次传递,最终父节点返回的内容是最后一个子节点的输出。

4. ThinkAction 类:

该类继承自 Action,用于“思考”任务,目的是根据传入的 instruction(例如,提供一个斐波那契数列的任务),生成一个数字列表。
它使用 THINK_NODES 类来生成数字列表,并且通过正则表达式(find_in_brackets 方法)从返回的字符串中提取数字列表。
如果提取到有效的数字列表,会将其返回,否则返回空列表。

5. SimplePrint 类:

该类继承自 Action,其任务是简单地打印数字。它接受一个 input_num 参数,并在 run 方法中打印这个数字。

6. Printer 类:

Printer 类代表一个角色(Role),它将多个动作(如 ThinkAction 和 SimplePrint)组合成一个完整的工作流。
它有多个方法来执行这些动作:

  • _think:确定下一个要执行的动作(基于角色的当前状态)。
  • _prepare_print:准备打印数字列表。
  • _act:执行实际的动作(例如,运行 ThinkAction,生成数字列表,然后调用 SimplePrint 打印数字)。
  • _react:在运行过程中根据状态决定执行顺序,直到所有任务完成。

7. main 函数:

main 函数是程序的入口点。在此函数中,首先定义了一个任务(例如,生成斐波那契数列的前 10 个数字),然后创建了一个 Printer 角色,运行任务并记录日志。

总结:

使用面向对象的设计,创建不同的 Action 和 ActionNode 来管理工作流。
ThinkAction 负责生成数字列表,SimplePrint 负责打印结果。
Printer 类作为角色,协调执行 ThinkAction 和 SimplePrint。
通过异步方法(async/await)实现了非阻塞的执行流程,使得每个任务都能并发执行。

主要执行流程:

Printer 类 调用 ThinkAction,根据指令生成数字列表。
生成的数字列表被 Printer 通过 SimplePrint 输出。
整个过程是异步的,通过 asyncio 来运行和协调多个任务。

最终,Printer 角色根据任务要求生成并打印一个数字列表,例如斐波那契数列。

代码

import asyncio
import refrom metagpt.actions.action import Action, ActionNode
from metagpt.logs import logger
from metagpt.roles import Role
from metagpt.schema import Message# 将思考斐波那契数列的10个数字作为prompt输入,在这里我们将“思考需要生成的数字列表”作为命令(instruction)写入
# 将期望返回格式(expected_type)设置为str,无需设置例子(example)
SIMPLE_THINK_NODE = ActionNode(key="Simple Think Node",expected_type=str,instruction="""Think about what list of numbers you need to generate""",example="",
)# 在这里通过命令(instruction)来规定需要生成的数字列表格式,提供例子(example)来帮助LLM理解
SIMPLE_CHECK_NODE = ActionNode(key="Simple CHECK Node",expected_type=str,instruction="""Please provide the number list for me, strictly following the following requirements:1. Answer strictly in the list format like [1,2,3,4]2. Do not have extra spaces or line breaks.Return the list here:""",example="[1,2,3,4]" "[4,5,6]",
)class THINK_NODES(ActionNode):def __init__(self, name="Think Nodes", expected_type=str, instruction="", example=""):super().__init__(key="",expected_type=expected_type,instruction=instruction,example=example,)self.add_children([SIMPLE_THINK_NODE, SIMPLE_CHECK_NODE])  # 初始化过程,将上面实现的两个子节点加入作为THINK_NODES类的子节点async def simple_fill(self,schema,mode,exclude=None,):prompt = self.compile(context=self.context, schema=schema, mode=mode, exclude=exclude)print(f"actionnode:{prompt}")if schema != "raw":mapping = self.get_mapping(mode, exclude=exclude)class_name = f"{self.key}_AN"content, scontent = await self._aask_v1(prompt,class_name,mapping,images=None,schema=schema,timeout=5,)self.content = contentself.instruct_content = scontentelse:self.content = await self.llm.aask(prompt)self.instruct_content = Nonereturn selfasync def fill(self, context, llm, schema="raw", mode="auto", strgy="complex"):self.set_llm(llm)self.set_context(context)if self.schema:schema = self.schemaif strgy == "simple":return await self.simple_fill(schema=schema, mode=mode)elif strgy == "complex":# 这里隐式假设了拥有childrenchild_context = context  # 输入context作为第一个子节点的contextfor _, i in self.children.items():i.set_context(child_context)  # 为子节点设置contextchild = await i.simple_fill(schema=schema, mode=mode)child_context = (child.content)  # 将返回内容(child.content)作为下一个子节点的contextself.content = child_context  # 最后一个子节点返回的内容设置为父节点返回内容(self.content)return selfclass SimplePrint(Action):"""Action that print the num inputted"""def __init__(self, name="SimplePrint", input_num: int = 0):super().__init__()self.input_num = input_numasync def run(self, **kwargs):print(str(self.input_num) + "\n")return "0"class ThinkAction(Action):"""Action that think"""def __init__(self, name="ThinkAction", context=None, llm=None):super().__init__()self.node = (THINK_NODES())  # 初始化Action时,初始化一个THINK_NODE实例并赋值给self.nodeasync def run(self, instruction) -> list:PROMPT = """You are now a number list generator, follow the instruction {instruction} and generate a number list to be printed please."""prompt = PROMPT.format(instruction=instruction)print(f"thinkaction: {prompt}")rsp_node = await self.node.fill(context=prompt, llm=self.llm, schema="raw", strgy="complex")  # 运行子节点,获取返回(返回格式为ActionNode)(注意设置 schema="raw" )rsp = rsp_node.content  # 获取返回的文本内容rsp_match = self.find_in_brackets(rsp)  # 按列表格式解析返回的文本内容,定位“[”与“]”之间的内容try:rsp_list = list(map(int, rsp_match[0].split(",")))  # 按列表格式解析返回的文本内容,按“,”对内容进行分割,并形成一个python语法中的列表return rsp_listexcept:return []@staticmethoddef find_in_brackets(s):pattern = r"\[(.*?)\]"match = re.findall(pattern, s)return matchclass Printer(Role):def __init__(self, name="Jerry", profile="Printer", goal="Print the number", constraints=""):super().__init__()self.set_actions([ThinkAction])# self.num_list = list()async def _think(self) -> None:"""Determine the action"""# logger.info(self.rc.state)if self.rc.todo is None:self._set_state(0)returnif self.rc.state + 1 < len(self.states):self._set_state(self.rc.state + 1)else:self.rc.todo = Noneasync def _prepare_print(self, num_list: list) -> Message:"""Add actions"""actions = list()for num in num_list:actions.append(SimplePrint(input_num=num))self.set_actions(actions)self.rc.todo = Nonereturn Message(content=str(num_list))async def _act(self) -> Message:"""Action"""todo = self.rc.todoif type(todo) is ThinkAction:msg = self.rc.memory.get(k=1)[0]self.goal = msg.contentresp = await todo.run(instruction=self.goal)# logger.info(resp)return await self._prepare_print(resp)resp = await todo.run()# logger.info(resp)return Message(content=resp, role=self.profile)async def _react(self) -> Message:""""""while True:await self._think()if self.rc.todo is None:breakmsg = await self._act()return msgasync def main():msg = "Provide the first 10 numbers of the Fibonacci series"role = Printer()logger.info(msg)result = await role.run(msg)logger.info(result)asyncio.run(main())

输出:

(metagpt) D:\llm\MetaGPT> d: && cd d:\llm\MetaGPT && cmd /C "d:\soft\anaconda\envs\metagpt\python.exe c:\Users\32564\.vscode\extensions\ms-python.debugpy-2024.14.0-win32-x64\bundled\libs\debugpy\adapter/../..\debugpy\launcher 55967 -- D:\llm\MetaGPT\notebook\TEST12.PY "
2024-12-17 17:44:27.438 | INFO     | metagpt.const:get_metagpt_package_root:21 - Package root set to d:\llm\metagpt
2024-12-17 17:44:33.566 | INFO     | __main__:main:224 - Provide the first 10 numbers of the Fibonacci series
thinkaction:You are now a number list generator, follow the instruction Provide the first 10 numbers of the Fibonacci series andgenerate a number list to be printed please.actionnode:You are now a number list generator, follow the instruction Provide the first 10 numbers of the Fibonacci series andgenerate a number list to be printed please.## Actions
Language: Please use the same language as Human INPUT.Think about what list of numbers you need to generateThe Fibonacci series is a sequence of numbers where each number is the sum of the two preceding ones, usually starting with 0 and 1. The first 10 numbers of the Fibonacci series are:0, 1, 1, 2, 3, 5, 8, 13, 21, 34Here is the number list generated:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
2024-12-17 17:44:38.394 | WARNING  | metagpt.utils.cost_manager:update_cost:49 - Model GLM-4-flash not found in TOKEN_COSTS.
actionnode:The Fibonacci series is a sequence of numbers where each number is the sum of the two preceding ones, usually starting with 0 and 1. The first 10 numbers of the Fibonacci series are:0, 1, 1, 2, 3, 5, 8, 13, 21, 34Here is the number list generated:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]## Actions
Language: Please use the same language as Human INPUT.Please provide the number list for me, strictly following the following requirements:1. Answer strictly in the list format like [1,2,3,4]2. Do not have extra spaces or line breaks.Return the list here:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
2024-12-17 17:44:41.264 | WARNING  | metagpt.utils.cost_manager:update_cost:49 - Model GLM-4-flash not found in TOKEN_COSTS.
01123581321342024-12-17 17:44:41.314 | INFO     | __main__:main:226 - : 0

参考链接:

https://deepwisdom.feishu.cn/wiki/KhCcweQKmijXi6kDwnicM0qpnEf

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/890404.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ExcelVBA编程输出ColorIndex与对应颜色色谱

标题 ExcelVBA编程输出ColorIndex与对应颜色色谱 正文 解决问题编程输出ColorIndex与对应色谱共56&#xff0c;打算分4纵列输出&#xff0c;标题是ColorIndex,Color,Name 1. 解释VBA中的ColorIndex属性 在VBA&#xff08;Visual Basic for Applications&#xff09;中&#xff…

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题

2024年11月 蓝桥杯青少组 STEMA考试 Scratch真题&#xff08;选择题&#xff09; 题目总数&#xff1a;5 总分数&#xff1a;50 选择题 第 1 题 单选题 Scratch运行以下程宇后&#xff0c;小兔子会&#xff08; &#xff09;。 A. 变小 B. 变大 C. 变色 D. …

springboot470基于协同过滤算法的东北特产销售系统的实现(论文+源码)_kaic

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

37. Three.js案例-绘制部分球体

37. Three.js案例-绘制部分球体 实现效果 知识点 WebGLRenderer WebGLRenderer 是Three.js中的一个渲染器类&#xff0c;用于将3D场景渲染到网页上。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数&#xff0c;可选。 常用…

leetcode 面试经典 150 题:长度最小的子数组

链接长度最小的子数组题序号209题型数组解题方法滑动窗口难度中等 题目 给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, …, numsr-1, numsr] &#xff0c;并返回其长度。如果不存在符合条件…

【游戏设计原理】22 - 石头剪刀布

一、游戏基础&#xff1a;拳头、掌心、分指 首先&#xff0c;石头剪刀布&#xff08;又名“Roshambo”&#xff09;看似简单&#xff0c;实际上可是个“深藏玄机”的零和博弈&#xff08;听起来很高深&#xff0c;其实就是输赢相抵消的意思&#xff09;。游戏中有三种手势&…

五、windows上vscode构建c/c++环境

1、安装vscode 官网下载界面&#xff1a;https://code.visualstudio.com/Download 请根据电脑系统安装所需版本点击下载链接&#xff08;一般情况下点击windows按钮即可&#xff09;鼠标左键双击&#xff0c;即可运行安装程序&#xff0c;点击【确认】&#xff1b;选择安装路径…

三格电子——新品IE103转ModbusTCP网关

型号&#xff1a;SG-TCP-IEC103 产品概述 IE103转ModbusTCP网关型号SG-TCP-IEC103&#xff0c;是三格电子推出的工业级网关&#xff08;以下简称网关&#xff09;&#xff0c;主要用于IEC103数据采集、DLT645-1997/2007数据采集&#xff0c;IEC103支持遥测和遥信&#xff0c;可…

数据结构---------二叉树前序遍历中序遍历后序遍历

以下是用C语言实现二叉树的前序遍历、中序遍历和后序遍历的代码示例&#xff0c;包括递归和非递归&#xff08;借助栈实现&#xff09;两种方式&#xff1a; 1. 二叉树节点结构体定义 #include <stdio.h> #include <stdlib.h>// 二叉树节点结构体 typedef struct…

UE5仿漫威争锋灵蝶冲刺技能

这两天玩了一下漫威争锋Marvel Rivals&#xff0c;发现是UE5做的&#xff0c;对里面一些角色技能挺感兴趣的&#xff0c;想简单复刻一下技能功能&#xff0c;顺便复习一下学过的知识 首先把摄像机设置调整一下 CameraBoom里搜索lag 把摄像机延迟关掉 &#xff0c;这样摄像机就…

常用类晨考day15

1.基本数据类型以及对应包装类 Byte Short Integer Long Float Double Boolean Character 2.什么是自动拆箱和装箱&#xff0c;jdk版本有什么要求&#xff1f;代码举 例并标明 Integer a 100; // 装箱 int b a; // 拆箱 从JDK1.5才开始支持 3.NumberFormatException是什么异常…

etcd+京东hotkey探测使用

qhotKey链接 京东hotkey把热点数据默认缓存在了本地缓存caffeine中&#xff0c;也可以存到redis中&#xff0c;但是京东hotkey的SDK没有redis的实现方法&#xff0c;因此需要自己实现。 官方目录结构下&#xff1a;分别是client客户端&#xff08;要打包引入到自己的项目&…

如何实现层叠布局

文章目录 1 概念介绍2 使用方法3 示例代码我们在上一章回中介绍了GirdView Widget,本章回中将介绍Stack这种Widget,闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 在Flutter中Stack主要用来叠加显示其它的Widget,类似我们日常生活中的楼层或者说PS中的图层,因此它也是一…

Java 上机实践11(组件及事件处理)

&#xff08;大家好&#xff0c;今天分享的是Java的相关知识&#xff0c;大家可以在评论区进行互动答疑哦~加油&#xff01;&#x1f495;&#xff09; 目录 Plug&#xff1a;程序实现 方法一&#xff08;记事本&#xff09; 方法二&#xff08;IDEA&#xff09; 实验一&am…

本地如何启动casdoor

1、下载代码 GitHub - casdoor/casdoor at v1.777.0 下载对应tag的代码&#xff0c;我这里选择的时v1.777.0版本 通过网盘分享的文件&#xff1a;casdoor-1.777.0.zip 链接: https://pan.baidu.com/s/1fPNqyJYeyfZnem_LtEc0hw 提取码: avpd 2、启动后端 1、使用goland编译…

CSDN外链失效3:

参考我之前的博客&#xff1a; 外链失效博客1&#xff1a;随想笔记1&#xff1a;CSDN写博客经常崩溃&#xff0c;遇到外链图片转存失败怎么办_csdn外链图片转存失败-CSDN博客 外链失效博客2&#xff1a;网络随想2&#xff1a;转语雀_md格式转语雀lake格式-CSDN博客 markdown…

Kubernates

kubernates是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;Kubernetes的目标是让部署容器化的应用简单并且高效&#xff08;powerful&#xff09;,Kubernetes提供了应用部署&#xff0c;规划&#xff0c;更新&#xff0c;维护的一种机制。 架构…

Pycharm 更改字体大小

更改代码字体的大小 更改软件字体的大小

Ubuntu20.04解决docker安装后is the docker daemon running? 问题

Ubuntu20.04解决docker安装后is the docker daemon running? 问题 问题描述问题分析问题解决 问题描述 docker info后报错 ERROR: Cannot connect to the Docker daemon at unix:///root/.docker/desktop/docker.sock. Is the docker daemon running? errors pretty printi…

四、使用langchain搭建RAG:金融问答机器人--构建web应用,问答链,带记忆功能

经过前面3节完成金融问答机器人基本流程&#xff0c;这章将使用Gradio构建web应用&#xff0c;同时加入memory令提示模板带有记忆的&#xff0c;使用LCEL构建问答链。 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingF…