【倉頡 + 鴻蒙 + 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.pswp.cn/news/902307.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/902307.shtml
英文地址,請注明出處:http://en.pswp.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 一.參數限流的應用場景 二.參數限流規則的屬性 …