【仓颉 + 鸿蒙 + AI Agent】CangjieMagic框架(17):PlanReactExecutor

CangjieMagic框架:使用华为仓颉编程语言编写,专门用于开发AI Agent,支持鸿蒙、Windows、macOS、Linux等系统。

这篇文章剖析一下 CangjieMagic 框架中的 PlanReactExecutor。

1 PlanReactExecutor的工作原理

用户提问
PlanReactExecutor
知识提取
问题分解
生成多个子任务
执行子任务
汇总结果
返回最终答案

当你要组织一场生日派对时,你会怎么做?你不会一头扎进去就开始准备,而是会先:

  1. 了解寿星的喜好(知识提取)
  2. 分解任务:场地、食物、娱乐、礼物(问题分解)
  3. 一个个完成这些子任务(执行子任务)
  4. 最后把所有准备工作整合起来,举办一场成功的派对(汇总结果)

PlanReactExecutor就是这样工作的!它不会直接尝试解决一个复杂问题,而是先分析、分解,然后一步步解决,最后整合答案。

2 深入代码:构造函数和核心组件

我们先来看看PlanReactExecutor的构造函数:

protected class PlanReactExecutor <: AgentExecutor {protected PlanReactExecutor() { }// 其他成员...
}

这个构造函数非常简单,它背后连接了几个强大的组件:

PlanReactExecutor
知识提取器
问题分解器
ReactWorker
结果汇总器

就像一个专业厨师虽然看起来很简单地做了一道菜,但背后有一套完整的厨具和步骤一样,PlanReactExecutor看似简单,实则整合了多个专业组件。

3 同步执行流程:像项目经理一样工作

现在,让我们看看同步执行函数的实现:

override public func run(agent: Agent, request: AgentRequest): AgentResponse {// Extract necessary knowledgelet knowledge = knowledgeExtract(agent, request)// Decompose the problemlet subtasks: Array<Subtask> = problemDecompose(agent, request)let planTask = PlanTask(agent, request, subtasks, knowledge)// Solve each subtaskfor (subtask in subtasks) {let worker = ReactWorker(planTask)let result = worker.solve(subtask)subtask.result = result}// Summarize the resultlet result = resultSummarize(planTask)LogUtils.info(agent.name, "Summarized answer: ${result}")return AgentResponse(result)
}

我们来用一个房屋装修的例子来理解这个过程:

用户 PlanReactExecutor 知识提取 问题分解 ReactWorker 结果汇总 我要装修一套北欧风格的房子 提取需求和关键信息 返回用户喜好和关键需求 分解成多个施工任务 返回水电、木工、油漆等任务 分配子任务 完成子任务并报告 loop [每个子任务] 整合所有工作成果 提供最终验收报告 交付装修完成的房子 用户 PlanReactExecutor 知识提取 问题分解 ReactWorker 结果汇总
  1. 知识提取:就像设计师了解业主的喜好和需求

    let knowledge = knowledgeExtract(agent, request)
    
  2. 问题分解:就像项目经理将装修分解为水电、木工、油漆等工序

    let subtasks: Array<Subtask> = problemDecompose(agent, request)
    
  3. 创建计划任务:汇总需求和任务清单,形成施工方案

    let planTask = PlanTask(agent, request, subtasks, knowledge)
    
  4. 执行每个子任务:安排工人团队依次完成各个工序

    for (subtask in subtasks) {let worker = ReactWorker(planTask)let result = worker.solve(subtask)subtask.result = result
    }
    
  5. 汇总结果:整合所有工作,形成最终成果

    let result = resultSummarize(planTask)
    
  6. 返回结果:向业主交付完工的房子

    return AgentResponse(result)
    

这个过程既有条理又高效,每个步骤都有明确的职责,就像一个专业的项目团队!

4 异步执行流程:实时查看进度的魔力

当我们需要实时查看任务执行进度时,就可以使用异步执行函数:

override public func asyncRun(agent: Agent, request: AgentRequest): AsyncAgentResponse {let planTask = PlanTask(agent, request)// Create the worker threadlet fut: Future<Iterator<String>> = spawn {try {return workFn(planTask)} catch(ex: Exception) {planTask.execInfo.verboseChannel.close()throw ex}throw UnsupportedException("Unreachable")}return AsyncAgentResponse(IteratorWrapper(planTask, fut), execInfo: planTask.execInfo)
}

这就像你在手机APP上订购一份外卖,可以实时看到"商家接单→厨师制作→骑手取餐→配送中→已送达"的全过程,而不是只能干等结果。

用户请求
创建计划任务
创建工作线程
异步执行workFn
返回异步响应
实时进度更新
用户界面

这里的关键是spawn表达式,它创建了一个新的工作线程来执行workFn函数,这样主线程就不会被阻塞。用生活中的例子来说,这就像你在餐厅点菜后,服务员会给你一个电子呼叫器,你可以去做其他事情,等菜好了会通知你。

5 workFn函数:异步工作的实际执行者

workFn函数是实际执行异步工作的地方,让我们仔细看看它的实现:

private func workFn(planTask: PlanTask): Iterator<String> {let agent = planTask.agentlet request = planTask.request// Extract necessary knowledgeplanTask.knowledge = knowledgeExtract(agent, request)// Decompose the problemlet subtasks: Array<Subtask> = problemDecompose(agent, request)planTask.subtasks = subtasksif (request.verbose) {let strBuilder = StringBuilder()strBuilder.append("# The Plan\n")for (subtask in subtasks) {strBuilder.append(subtask.toMarkdown())strBuilder.append("\n")}planTask.execInfo.verboseChannel.put(strBuilder.toString().withTag(ReactTag.PLAN))}// Solve each subtaskfor (subtask in subtasks) {if (request.verbose) {planTask.execInfo.verboseChannel.put("Solve the subtask: ${subtask.name}".withTag(ReactTag.PLAN))}let worker = ReactWorker(planTask)let asyncResp = worker.asyncSolve(subtask, verbose: request.verbose)if (request.verbose) {// Transfer the internal information from the react worker to this agentfor (data in asyncResp.execInfo.getOrThrow().verboseInfo) {planTask.execInfo.verboseChannel.put(data)}}subtask.result = asyncResp.contentif (request.verbose) {planTask.execInfo.verboseChannel.put("# Subtask DONE!\n${subtask.toMarkdown()}".withTag(ReactTag.INFO))}}if (request.verbose) {planTask.execInfo.verboseChannel.close()}// Summarize the resultreturn asyncResultSummarize(planTask)
}

让我们用一个建造乐高模型的例子来理解这个过程:

用户 PlanReactExecutor 计划 子任务 ReactWorker 结果 准备阶段 我想搭建一个乐高城堡 提取关键信息 生成搭建计划 展示整体计划和分步骤 执行阶段 开始执行当前步骤 使用合适的零件和工具 完成当前部分 实时展示搭建进度 loop [每个搭建步骤] 完成阶段 整合所有部分 展示完整的乐高城堡 用户 PlanReactExecutor 计划 子任务 ReactWorker 结果

在这个过程中,最有价值的部分是用户可以看到计划和每个子任务的执行过程,这就是verbose模式的作用:

if (request.verbose) {let strBuilder = StringBuilder()strBuilder.append("# The Plan\n")for (subtask in subtasks) {strBuilder.append(subtask.toMarkdown())strBuilder.append("\n")}planTask.execInfo.verboseChannel.put(strBuilder.toString().withTag(ReactTag.PLAN))
}

这段代码就像是向用户展示乐高说明书的全貌,让用户知道接下来会发生什么。然后在执行每个子任务时,不断更新进度:

if (request.verbose) {planTask.execInfo.verboseChannel.put("Solve the subtask: ${subtask.name}".withTag(ReactTag.PLAN))
}

这就像是告诉用户"现在正在搭建城堡的塔楼部分",让用户了解当前进度。

6 与其他执行器的对比

执行器类型
NaiveExecutor
ReActExecutor
PlanReactExecutor
特点: 简单直接
场景: 简单问答
特点: 思考-行动-观察循环
场景: 需要使用工具
特点: 先规划后执行
场景: 复杂多步骤问题

如果用餐厅来比喻三种执行器:

  • NaiveExecutor:快餐店,直接点餐、直接出餐
  • ReActExecutor:普通餐厅,厨师根据订单现做现卖
  • PlanReactExecutor:高档餐厅,主厨先设计菜单,然后团队分工协作制作多道菜肴,最后组合成一顿完美的大餐

PlanReactExecutor最适合那些需要多步骤、多角度思考的复杂问题。

7 实际应用案例

案例一:学术研究助手

当用户请求研究神经网络的最新进展时,执行过程可能是:

用户请求: 研究神经网络最新进展
知识提取: 确定研究领域为神经网络和图像识别
问题分解
子任务1: 查找最新论文
子任务2: 阅读关键论文
子任务3: 总结主要发现
子任务4: 比较不同方法
执行子任务
汇总: 综合报告
最终结果: 全面的研究报告

案例二:旅行规划助手

想象一个用户想规划一次欧洲之旅:

用户: 请帮我规划一次为期7天的法国巴黎和意大利罗马的旅行,包括景点、住宿和交通。

使用PlanReactExecutor,执行过程可能是:

  1. 知识提取:了解用户想去巴黎和罗马,时间为7天
  2. 问题分解
    • 子任务1:规划巴黎部分的行程(3天)
    • 子任务2:规划罗马部分的行程(3天)
    • 子任务3:规划两地之间的交通(1天)
    • 子任务4:提供住宿建议
    • 子任务5:整合完整行程
  3. 执行每个子任务:分别解决每个子任务
  4. 汇总结果:生成完整的7天旅行计划

案例三:复杂数学问题求解

用户: 请求解下列方程组:
3x + 2y - z = 10
2x - 3y + 2z = -5
x + y + z = 7

使用PlanReactExecutor解决这个问题:

  1. 知识提取:确定这是一个三元一次方程组
  2. 问题分解
    • 子任务1:使用消元法消去z变量
    • 子任务2:解出x和y的关系
    • 子任务3:代回求解x、y、z的值
    • 子任务4:验证结果是否正确
  3. 执行子任务:依次解决每个数学步骤
  4. 汇总结果:提供完整的解答和解释

8 核心组件深度解析

PlanReactExecutor不是独立工作的,它依赖几个核心组件:

PlanReactExecutor
knowledgeExtract
problemDecompose
ReactWorker
resultSummarize
功能: 提取关键知识
实现: 使用LLM分析问题
功能: 分解为子任务
实现: 让LLM进行任务规划
功能: 解决单个子任务
实现: 使用ReAct方法
功能: 整合所有结果
实现: 让LLM综合所有信息
  1. knowledgeExtract:就像研究生开始论文前的文献综述,先了解相关知识

  2. problemDecompose:就像建筑师在开工前绘制详细的施工图纸

  3. ReactWorker:就像专业工人按照图纸完成具体工作

  4. resultSummarize:就像编辑将多篇文章整合成一本完整的书

这些组件协同工作,使得PlanReactExecutor能够处理非常复杂的问题。

9 PlanReactExecutor的优势与局限

PlanReactExecutor
优势
局限
能解决复杂问题
思路清晰可追踪
结果全面系统
可并行执行子任务
执行时间较长
资源消耗较大
简单问题反而复杂化

优势:

  1. 解决复杂问题:像专业律师处理复杂案件,有条不紊
  2. 思路清晰:用户可以看到完整的思考过程,增强可信度
  3. 结果全面:考虑问题的多个方面,不会遗漏重要内容
  4. 可追踪性:出现问题可以定位到具体哪个子任务

局限:

  1. 执行时间长:就像做一道复杂的菜肴,需要更多时间
  2. 资源消耗大:需要更多的API调用和计算资源
  3. 简单问题反而复杂化:用大炮打蚊子,对简单问题过度设计

10 何时选择PlanReactExecutor?

简单
复杂
只需一两个工具
需要多步规划
面对一个问题
是否复杂?
使用NaiveExecutor
需要工具吗?
使用ReActExecutor
使用PlanReactExecutor

适合使用PlanReactExecutor的场景:

  1. 多步骤问题:如规划旅行、制定学习计划
  2. 需要多角度分析:如进行SWOT分析、评估风险
  3. 需要综合信息:如撰写研究报告、市场分析
  4. 组织创作内容:如写一本书的大纲、设计课程体系

不适合的场景:

  1. 简单问答:如"今天天气怎么样"
  2. 单一工具调用:如"计算123 + 456"
  3. 快速响应场景:如紧急情况下的决策

11 总结

PlanReactExecutor就像一位经验丰富的项目经理,能够将复杂问题分解为可管理的小任务,然后一步步解决,最终整合成完整的解决方案。在处理复杂问题时,它的表现远超简单的执行器。

当你的AI应用需要处理复杂的多步骤问题时,不妨考虑使用PlanReactExecutor,它将帮助你的Agent像专业团队一样有条不紊地解决问题。

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

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

相关文章

一文了解相位阵列天线中的真时延

本文要点 真时延是宽带带相位阵列天线的关键元素之一。 真时延透过在整个信号频谱上应用可变相移来消除波束斜视现象。 在相位阵列中使用时延单元或电路板&#xff0c;以提供波束控制和相移。 市场越来越需要更快、更可靠的通讯网络&#xff0c;而宽带通信系统正在努力满…

Java中 关于编译(Compilation)、类加载(Class Loading) 和 运行(Execution)的详细区别解析

以下是Java中 编译&#xff08;Compilation&#xff09;、类加载&#xff08;Class Loading&#xff09; 和 运行&#xff08;Execution&#xff09; 的详细区别解析&#xff1a; 1. 编译&#xff08;Compilation&#xff09; 定义 将Java源代码&#xff08;.java文件&#x…

【KWDB 创作者计划】_深度学习篇---松科AI加速棒

文章目录 前言一、简介二、安装与配置硬件连接驱动安装软件环境配置三、使用步骤初始化设备调用SDK接口检测设备状态:集成到AI项目四、注意事项兼容性散热固件更新安全移除五、硬件架构与技术规格核心芯片专用AI处理器内存配置接口类型物理接口虚拟接口能效比散热设计六、软件…

如何清理Windows系统中已失效或已删除应用的默认打开方式设置

在使用Windows系统的过程中&#xff0c;我们可能会遇到一些问题&#xff1a;某些已卸载或失效的应用程序仍然出现在默认打开方式的列表中&#xff0c;这不仅显得杂乱&#xff0c;还可能影响我们快速找到正确的程序来打开文件。 如图&#xff0c;显示应用已经被geek强制删除&am…

NFC碰一碰发视频推广工具开发注意事项丨支持OEM搭建

随着线下门店短视频推广需求的爆发&#xff0c;基于NFC技术的“碰一碰发视频”推广工具成为商业热点。集星引擎在开发同类系统时&#xff0c;总结出六大核心开发注意事项&#xff0c;帮助技术团队与品牌方少走弯路&#xff0c;打造真正贴合商户需求的实用型工具&#xff1a; 一…

pgsql中使用jsonb的mybatis-plus和Spring Data JPA的配置

在pgsql中使用jsonb类型的数据时&#xff0c;实体对象要对其进行一些相关的配置&#xff0c;而mybatis和jpa中使用各不相同。 在项目中经常会结合 MyBatis-Plus 和 JPA 进行开发&#xff0c;MyBatis_plus对于操作数据更灵活&#xff0c;jpa可以自动建表&#xff0c;两者各取其…

kotlin + spirngboot3 + spring security6 配置登录与JWT

1. 导包 implementation("com.auth0:java-jwt:3.14.0") implementation("org.springframework.boot:spring-boot-starter-security")配置用户实体类 Entity Table(name "users") data class User(IdGeneratedValue(strategy GenerationType.I…

【JavaWeb后端开发03】MySQL入门

文章目录 1. 前言1.1 引言1.2 相关概念 2. MySQL概述2.1 安装2.2 连接2.2.1 介绍2.2.2 企业使用方式(了解) 2.3 数据模型2.3.1 **关系型数据库&#xff08;RDBMS&#xff09;**2.3.2 数据模型 3. SQL语句3.1 DDL语句3.1.1 数据库操作3.1.1.1 查询数据库3.1.1.2 创建数据库3.1.1…

人工智能在智能家居中的应用与发展

随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;智能家居逐渐成为现代生活的重要组成部分。从智能语音助手到智能家电&#xff0c;AI正在改变我们与家居环境的互动方式&#xff0c;让生活更加便捷、舒适和高效。本文将探讨人工智能在智能家居中的应用现状、…

【EasyPan】项目常见问题解答(自用持续更新中…)

EasyPan 网盘项目介绍 一、项目概述 EasyPan 是一个基于 Vue3 SpringBoot 的网盘系统&#xff0c;支持文件存储、在线预览、分享协作及后台管理&#xff0c;技术栈涵盖主流前后端框架及中间件&#xff08;MySQL、Redis、FFmpeg&#xff09;。 二、核心功能模块 用户认证 注册…

4.1腾讯校招简历优化与自我介绍攻略:公式化表达+结构化呈现

腾讯校招简历优化与自我介绍攻略&#xff1a;公式化表达结构化呈现 在腾讯校招中&#xff0c;简历是敲开面试大门的第一块砖&#xff0c;自我介绍则是展现个人魅力的黄金30秒。本文结合腾讯面试官偏好&#xff0c;拆解简历撰写公式、自我介绍黄金结构及分岗位避坑指南&#xf…

【Easylive】consumes = MediaType.MULTIPART_FORM_DATA_VALUE 与 @RequestPart

【Easylive】项目常见问题解答&#xff08;自用&持续更新中…&#xff09; 汇总版 consumes MediaType.MULTIPART_FORM_DATA_VALUE 的作用 1. 定义请求的数据格式 • 作用&#xff1a;告诉 Feign 和 HTTP 客户端&#xff0c;这个接口 接收的是 multipart/form-data 格式的…

OpenSSL1.1.1d windows安装包资源使用

环境&#xff1a; QT版本&#xff1a;5.14.2 用途: openssl1.1.1d版本 问题描述&#xff1a; 今天尝试用百度云人脸识别api搭载QT的人脸识别程序&#xff0c;需要用到 QNetworkManager 访问 https 开头的网址。 但是遇到了QT缺乏 openssl 的相关问题&#xff0c;找了大半天…

代码实战保险花销预测

文章目录 摘要项目地址实战代码&#xff08;初级版&#xff09;实战代码&#xff08;进阶版&#xff09; 摘要 本文介绍了一个完整的机器学习流程项目&#xff0c;重点涵盖了多元线性回归的建模与评估方法。项目详细讲解了特征工程中的多项实用技巧&#xff0c;包括&#xff1…

RS232 串行通信:C++ 实现指南

文章目录 一、RS232 简介1. 电气特性2. 传输速率3. 传输距离 二、在 C 中实现 RS232 通信1. Windows 平台&#xff08;1&#xff09;打开串行端口&#xff08;2&#xff09;配置串行通信参数&#xff08;3&#xff09;发送数据&#xff08;4&#xff09;接收数据&#xff08;5&…

Linux指令合集

一、VI的使用 命令行模式&#xff1a;默认此模式&#xff0c;从输入模式回到命令行模式&#xff1a;esc &#xff0c; esc按完&#xff0c;insert消失 输入模式&#xff1a;按 i 进入 &#xff0c; 看到insert就能编辑代码 退出vi 保存代码 命令行模式下 按&#xf…

IDEA使用jclasslib Bytecode Viewer查看jvm字节码

学习jvm的时候&#xff0c;想查看字节码和局部变量表&#xff0c;可以使用idea安装jclasslib Bytecode View插件查看。 &#xff08;1&#xff09;安装工具&#xff1a; 安装完成后需要重启idea. &#xff08;2&#xff09;准备一段代码&#xff0c;编译运行 package com.te…

从多个Excel批量筛查数据后合并到一起

这篇文章将讲解如何批量的从多个Excel文件中筛选出需要的数据&#xff0c;最后合并到一张新的Excel。 全程0代码图形化界面操作。 准备数据 这里准备了3个测试文件&#xff0c;每个文件的格式是一样的 现在我们需要筛选出每个文件里面&#xff0c;基金简称包含“南方远见”&a…

Debian GNU/Linux的新手入门介绍

Debian GNU/Linux&#xff1a;起源、基本介绍与发行版对比 一、起源与发展历程 Debian GNU/Linux 是现存最古老的 Linux 发行版之一&#xff0c;由 Ian Murdock 于 1993 年 8 月 16 日创立。其名称结合了他的女友&#xff08;后成为妻子&#xff09;Debra 和他自己的名字 Ian…

Sentinel源码—7.参数限流和注解的实现一

大纲 1.参数限流的原理和源码 2.SentinelResource注解的使用和实现 1.参数限流的原理和源码 (1)参数限流规则ParamFlowRule的配置Demo (2)ParamFlowSlot根据参数限流规则验证请求 (1)参数限流规则ParamFlowRule的配置Demo 一.参数限流的应用场景 二.参数限流规则的属性 …