浅析智能体开发(第二部分):智能体设计模式和软件架构
大语言模型(LLM)驱动的智能体(AI Agent)展现出许多传统软件所不具备的特征。不仅与传统软件的设计理念、方法、工具和技术栈有显著的差异,AI原生(AI Native)的智能体还融入了多种新概念和技术。我们从多个维度对AI Native智能体与传统软件进行了比较和分析,涉及开发语言、软件架构、设计模式和编程模式等多个方面。

图:本文梳理的智能体软件设计模式和发展脉络
本文梳理智能体软件设计模式和快速发展的脉络。我们可以看到,以大模型推理为核心的AI原生软件开发,其设计模式和软件架构与传统软件相比有显著的不同;其发展就是一个不断挖掘、扩展和发挥大语言模型推理能力的过程,一“脉”相承。
设计模式
结构化工程 (Structured Engineering)
vs.
智能体推理(Agentic Reasoning)
设计模式是一套代码设计经验的抽象和总结,是对某类特定问题的通用解决方案。通过设计模式可以提高代码的可维护性、可重用性和可扩展性。

图:《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)是有关面向对象软件设计模式的一本书,提出和总结了对于23种常见软件设计问题的标准解决方案,称为软件设计模式。该书作者是Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides,后以“四人帮”(Gang of Four,GoF)著称(图片来自: WikiPedia)
设计模式是计算机相关专业的必修课之一。资深Java程序员们也一般都会对Factory、Proxy、Facade等面向对象软件设计模式有所了解。对于Web和移动应用程序员们,对模型-视图-控制器(MVC)的模式则一定不会感到陌生。
在AI 智能体开发中,大模型的出现和发展导致了软件设计模式出现了变化。我们发现,这个变化围绕着应用大模型推理的能力,以及充分挖掘大模型推理的潜力的底层逻辑展开。吴恩达博士在最近的演讲中,把这些模式称为“Agentic Reasoning”系统的设计模式。在本节里,我们简单地梳理Agentic Reasoning发展的脉络。
大模型推理(Reasoning)
首先是大语言模型推理(Reasoning)。大语言模型的推理是在AI软件应用不同于传统软件应用的根本特点。这可以说是最为基础的AI-Native设计模式。
思维链(Chain of Thought/CoT)
思维链的方法在提示中通过一步一步的推理和逻辑连接,将复杂问题拆解成一系列简单的问题,从而让大语言模型模拟或促进逻辑推理和决策过程,得出最终结论。

图:左侧的例子的提示中直接要求大模型推理,大模型给出了错误的答案。右侧的例子的提示中用思维链分解了复杂的问题,给出推理过程(蓝色文字部分),使大模型能够处理复杂的算术、常识和符号推理任务。来自于论文Chain-of-Thought Prompting Elicits Reasoning in Large Language Models, Wei et al., (2022)
行动(Action)
当大模型推理能力受限时,人们自然而然会想到要借助外部力量拓展大模型的能力,让大模型能够使用外部工具。
比如OpenAI提供的GPTs服务,用户可以配置定制化的ChatGPT,连接外部应用,比如Zapier 的 6,000 多个应用程序,使大模型有了搜索互联网,管理邮箱、日程等强大能力。让大模型如虎添翼。

图:Zapier网站截图,提供6000+ "Actions"给ChatGPT,扩展了大语言模型的能力(https://zapier.com/blog/gpt-assistant/)
工具使用(Tool Use)
人们自然不会满足于让大语言模型死板地使用预先定义好的工具。基于Action的方法,Tool Use进一步挖掘大模型的智能,让它能够根据不同的情景环境,动态地选择最适合的第三方工具,最优化使用。

图:几个大语言模型Tool Use的实例。来自论文Gorilla: Large Language Model Connected with Massive APIs, Patil et al. (2023)
现在的基础大模型都或多或少地具备Tool Use的能力。这是一项具有挑战性的任务,很大程度上是因为它们无法生成准确的输入参数,并且倾向于错误地使用 API 调用。值得一提的是加州伯克利大学的Gorilla大模型,基于 LLaMA 的微调模型,在 API 调用方面超越了 GPT-4 的性能。
反思(Reflection)之自我改善(Self-Refine)
不满足于一次性使用大模型推理获得结果,人们寄望于迭代多轮使用大模型推理来获得比单论推理更好的结果。反思模式(Reflection)应运而生。

图:自我改善的流程,来自于论文Self-Refine: Iterative Refinement with Self-Feedback, Madaan et al. (2023)
如上图所示,反思通过自我改善而实现。反思的迭代始于将大模型推理生成的输出交还给同一大模型M以获得反馈。反馈再作为提示的一部分交给大模型M再次生成结果,从而实现结果的改善。整个过程是自动化的,迭代改善,直到停止条件被满足。

图:自我改善的示例,来自于论文Self-Refine: Iterative Refinement with Self-Feedback, Madaan et al. (2023)
在上面的例子可以看到,(a)第一轮大模型生成答案。答案被交给同一个大模型进行评估。评估的反馈是:(b)答案没有提供足够的信息,缺乏对用户需求的理解。这个反馈再交个该大模型用于生成下一轮答案(c)。可以看到答案(c)吸收了反馈(b)的意见,质量明显高于上一轮(a)的答案。同理,在算法优化的例子中,前一轮的算法代码(d)交由大模型进行反馈(e),被认为太慢,并给出了替代算法。下一轮的代码生成则根据反馈意见给出了更加高效的算法。
ReAct (Reasoning+Action)

图:将Reasoning和Actions模式相结合,形成更加有效的ReAct模式。来自于ReAct: Synergizing Reasoning and Acting in Language Models,ShunYu et al. https://react-lm.github.io
单纯的大语言模型推理(例如思维链提示)和行动(例如行动计划生成)限制了大语言模型能力的发挥。人们探索使用以交错和迭代的方式将大模型的推理和行动相协同:通过大模型推理帮助模型通过提示诱导、跟踪和更新行动的计划以及处理异常,而行动则允许大语言模型与外部源(例如知识库或环境)进行交互,以收集更多信息。ReAct 模式往往比单纯的推理或行动模式有更高的可解释性和可信度,减少大模型推理中的幻觉。

图:案例:通过Reason或Action的模式无法获得正确结果,而ReAct模式解决了问题。来自于ReAct: Synergizing Reasoning and Acting in Language Models,ShunYu et al. https://react-lm.github.io
以上的各种模式,都建立在单个大模型推理的基础之上的。在AI应用中,为什么不能使用多个大模型推理呢?AI-Native的设计模式不断向多LLMs的场景发展。
反思(Reflection)之增强改善(Reinforced-Refine)
最初的反思模式是限于单个大模型的自我改善模式(Self-Refine)。后来迅速发展到了包括到系统其他部件和多个大模型的更加综合的模式。

图:Reflexion: Language Agents with Verbal Reinforcement Learning, Shinn et al., (2023)
相较于自我改善的方法,代表性的Reflexion系统扩展、泛化了Reflection模式,在其中,
有执行推理任务的Actor大模型,提供评估的Evaluator大模型和根据反馈提供结果改进建议的Self-reflection大模型,不同的大模型在反思的循环中各司其职,不再限制于一个大模型。而且,
结果改进不仅仅参考来自于评估提供的内部反馈,还来自于上一轮任务完成所导致的外部环境的变化(外部反馈)。
结果改进不仅仅依赖于上一轮的改进建议,而且参考当前环境的情况(Short-Term Memory)和数轮改进的历史经验(Long-term Memory)。
这样的反思模式综合了历史记忆、环境条件和任务解偶的多个大语言模型,从而形成了更加完善的具有增强学习机制的反思系统。我们且称之为增强改善(reinforced-Refine)。
规划(Planning)
在这个尚不成熟的模式中,大模型推理的能力被赋予了新的用途:根据系统的情况,将复杂的任务动态地解构成若干小任务去完成。吴恩达在他的博客《吴恩达来信:代理设计模式第 4 部分,规划》给出了几个例子。
几个月前, 我多次私下测试过可以访问各种在线搜索工具的研究智能体代理。期间它始终使用网络搜索工具来收集信息并撰写摘要。然而,在现场演示期间,网络搜索 API 意外返回并出现速率限制错误。我以为我的演示即将公开失败,我害怕接下来会发生什么。令我惊讶的是,该代理巧妙地转向维基百科搜索工具(我忘记了我给了它),并使用维基百科而不是网络搜索完成了任务。
- 节选翻译自Letters from Andrew Ng, https://www.deeplearning.ai/the-batch/agentic-design-patterns-part-4-planning/
在这个案例里,可以看到,从网络搜索工具使用(Tool Use)的失败的反馈中,负责规划的大模型(反思)并规划了维基百科搜索的任务。
多智能体协作(Multi-Agent Collaboration)
前面提到的所有智能体设计模型,都是基于单个智能体的模型。CrewAI、AutoGen等工作则将设计模式扩展到了多个智能体相互合作的设计模型。

图:CrewAI原理示意图,来自:https://github.com/joaomdmoura/crewai
CrewAI视AI软件应用系统为多个智能体(Agents)、多个任务(Tasks)和连接、管理它们的过程(Process)。

图:Autogen原理示意图,来自:https://microsoft.github.io/autogen/docs/Getting-Started
Autogen则视软件应用系统由多个智能体,以及它们之间沟通的方式所组成。
虽然概念抽象方式有所不同,在具体的实现中,CrewAI和Autogen都要求应用开发者给出各智能体的角色、目标和背景故事等提示,给出外部使用工具,并定义各智能体所使用的大模型,以及彼此之间的接口关系等各种配置。Tool Use/Function Call、Reflection、Memory、Planning等机制则均通过框架去运行和维护,不需要开发者费心。
多智能体协作使得系统更加动态化(dynamic),往往以出人意料的方式完成似乎不可能完成的任务。
层出不穷的智能体软件设计模式使得软件的架构也出现了新发展。
架构
单体(Monolithic)架构 vs. 智能体(Agent)架构
传统的软件工程中存在多种架构和设计方法,大家耳熟能详架构有:
将系统分为表示层(用户界面)、业务逻辑层和数据访问层的层次架构(Layered Architecture);
多个客户端(消费者)连接到一个或多个服务器的客户端-服务器架构(Client-Server Architecture);
将各功能封装为独立的服务,通过网络调用服务导向架构(Service-Oriented Architecture, SOA);
将单一应用程序分解成一组运行在其自己的进程中小服务,通过HTTP等轻量级机制进行通信微服务架构(Microservices Architecture);
...
传统的架构注重准确性和效率,强调所有功能组件集成在一个整体中。
在AI智能体系统中,架构更加侧重于发挥大语言模型的推理能力和支持不断学习和适应的能力,要求架构设计能够灵活处理各种信息流和反馈循环。综合吴恩达(Andrew Ng)的 Agentic Reasoning Design Patterns和OpenAI研究应用主管Lilian Wen总结的LLM Powered Autonomous Agents架构( https://lilianweng.github.io/posts/2023-06-23-agent/),我们试图从多智能体协作系统中一个智能体的视角,描述系统的组件架构。基于本文所述的多种软件设计模式而形成的功能模块,通过该架构结合在一起,构成完整的多智能体系统,以LLM为引擎,以迭代的,动态的和合作的方式,完成复杂的、不确定性的和具有开放性的任务。

图:从单个智能体视角描述的多智能体协同系统组件架构综合Andrew Ng's Agentic Reasoning Design Patterns和Lilian Wen LLM Powered Autonomous Agents架构( https://lilianweng.github.io/posts/2023-06-23-agent/)
总结
我们可以看到,在这短短几年中,智能体设计模式的发展迅速,从简单的推理,到思维链推理,到对外部工具的利用,引入迭代进一步改进大模型的推理,利用推理进行目标分解和动态的行动规划,再利用推理能力动态管理多个智能体之间合作 ... 这就是一个不断挖掘、扩展和发挥大语言模型推理能力的过程。
不同于传统设计模式将重点放在结构化和工程化,AI Native软件的设计模式强调发挥智能体的自主性和动态决策能力,重点在于软件的自适应性。
传统软件是架构严谨、接口明确的单体结构和一个高效的过程,而智能体软件则是围绕大语言模型而构建的松而不散,关系复杂的模块化结构和一个不断迭代的过程。智能体强调充分发挥大模型的推理能力,通过迭代的方式提升性能,通过感知过程和环境变化、以及多智能体之间的协作来进行动态的决策等特点。
在洞察的过程中,我们感受到智能体软件设计模式和架构的发展远未成熟,尚缺乏有说服力的高价值典型应用出现。但是,我们同时也能够看到新技术所带来的前景,感受到其与传统技术的巨大差异。相信智能体技术必会继续快速发展,渐成大器。
相关文章:
浅析智能体开发(第二部分):智能体设计模式和软件架构
大语言模型(LLM)驱动的智能体(AI Agent)展现出许多传统软件所不具备的特征。不仅与传统软件的设计理念、方法、工具和技术栈有显著的差异,AI原生(AI Native)的智能体还融入了多种新概念和技术。…...
Unity学习笔记---Transform组件
组件介绍 Transform组件在每个游戏对象中都存在,且只存在一个。该组件保存了游戏对象的位置、平移、旋转、缩放等信息。 组件相关方法 //获取当前游戏对象的Transform组件this.transform; getObject.transform; GetComponent<Transform>();//属性 gameObje…...
springboot+jsp校园理发店美容美发店信息管理系统0h29g
前台管理:会员管理、会员预定、开单点单、收银结帐、技师提成 后台管理:数据维护、物料管理、数据查询、报表分析、系统设置等 灵活的付款方式,支持现金、挂帐、会员卡,同时支持多种折扣方式并可按用户要求设置多种结帐类型善的充值卡管理模块:支持优惠卡…...
css - sass or scss ?
总的来说,Sass 和 SCSS 提供的功能是一样的,选择哪种语法主要取决于你的个人或团队的偏好。...
html5 笔记01
01 表单类型和属性 input的type属性 单行文本框: typetext 电子邮箱 : typeemail 地址路径 : type url 定义用于输入数字的字段: typenumber 手机号码: typetel 搜索框 : typesearch 定义颜色选择器 : typecolor 滑块控件 : typerange 定义日期 :typedate 定义输入时间的控件…...
E5063A是德科技e5063a网络分析仪
181-2461-8938产品概述: 简 述: E5063A 是低成本网络分析仪,可提供优化的性能和功能,适用于测试简单的无源器件,例如天线、电缆、滤波器和 PCB 等。它利用工业标准 ENA 系列始终如一的测量架构,能够极…...
【星海随笔】微信小程序(二)
WXML 模板语法 - 数据绑定 在data中定义页面的数据 在页面对应的 .js 文件中,把数据定义到 data 对象中即可: Page({data: {// 字符串类型的数据info: init data,// 数据类型的数据msgList: [{msg: hello},{msg: world}]} })Mustache 语法的格式 把 …...
Python采集安居客租房信息
Python采集安居客租房信息 一、需求介绍二、完整代码一、需求介绍 本次采集的需求就是获取到页面中的所有信息: 将数据采集好之后保存为如下csv文件: 爬取的流程不再展开分析,完整代码附后。 二、完整代码 import csvimport requests from lxml import etreeclass Anju…...
Rust构造JSON和解析JSON
目录 一、Rust构造JSON和解析JSON 二、知识点 serde_json JSON 一、Rust构造JSON和解析JSON 添加依赖项 cargo add serde-json 代码: use serde_json::{Result, Value};fn main() -> Result<()>{//构造json结构 cpu_loadlet data r#"{"…...
Linux 信号捕捉与处理
💓博主CSDN主页:麻辣韭菜💓 ⏩专栏分类:Linux知识分享⏪ 🚚代码仓库:Linux代码练习🚚 🌹关注我🫵带你学习更多Linux知识 🔝 目录 前言 1. 信号的处理时机 1.1用户…...
桂林电子科技大学计算机工程学院、广西北部湾大学计信学院莅临泰迪智能科技参观交流
5月18日,桂林电子科技大学计算机工程学院副院长刘利民、副书记杨美娜、毕业班辅导员黄秀娟、广西北部湾大学计信学院院长助理刘秀平莅临广东泰迪智能科技股份有限公司产教融合实训基地参观交流。泰迪智能科技副总经理施兴、广西分公司郑廷和、梁霜、培训业务部孙学镂…...
Qt笔记:动态处理多个按钮点击事件以更新UI
问题描述 在开发Qt应用程序时,经常需要处理多个按钮的点击事件,并根据点击的按钮来更新用户界面(UI),如下图。例如,你可能有一个包含多个按钮的界面,每个按钮都与一个文本框和一个复选框相关联…...
Excel模板计算得出表格看板
背景 表格看板及导出,单元格时间年是根据筛选器时间变化的 较往年和往年是计算单元格 思路 1.通过excel模板来把数据填入excel再数据清洗得到数据返回前端 2.数据填充,通过行列作为key 列如:key整体20241月,根据key匹配数据填…...
es数据备份和迁移Elasticsearch
Elasticsearch数据备份与恢复 前提 # 注意: 1.在进行本地备份时使用--type需要备份索引和数据(mapping,data) 2.在将数据备份到另外一台ES节点时需要比本地备份多备份一种数据类型(analyzer,mapping,data,template) …...
Oracle数据块之数据行中的SCN
从Oracle 10g开始,如果在表级别打开ROW DEPENDENCIES,业务数据行发生更改时会在数据块中进行登记。 可以通过DUMP数据块来观察上述SCN: (1)创建测试表,插入3条测试数据,插入一条提交一次。并调用…...
手写tomcat(Ⅱ)——Socket通信+tomcat静态资源的获取
Socket通信简介 参考文章:socket通讯原理及例程(一看就懂) socket是介于应用层(http协议)和传输层(TCP/UDP协议)之间的一层虚拟层 Socket是一个程序,符合TCP/UDP协议的规范&…...
解决Error: error:0308010C:digital envelope routines::unsupported的四种解决方案
问题描述: 报错:Error: error:0308010C:digital envelope routines::unsupported 报错原因: 主要是因为 nodeJs V17 版本发布了 OpenSSL3.0 对算法和秘钥大小增加了更为严格的限制,nodeJs v17 之前版本没影响&am…...
shell 脚本笔记2
3.env与set区别 env用于查看系统环境变量 set用于查看系统环境变量自定义变量函数 4.常用环境变量 变量名称含义PATH命令搜索的目录路径, 与windows的环境变量PATH功能一样LANG查询系统的字符集HISTFILE查询当前用户执行命令的历史列表 Shell变量:自定义变量 目标…...
aws eks集成wasm运行时并启动pod
参考资料 WebAssembly 在云原生中的实践指南,https://cloud.tencent.com/developer/article/2324065 作为一种通用字节码技术,wasm的初衷是在浏览器中的程序实现原生应用性能。高级语言将wasm作为目标语言进行编译并运行在wasm解释器中。和nodejs类似的…...
linux:切分大文件
文章目录 1. 前言2. 用法3. 例子 1. 前言 如果传输、存储过程中出现大文件,希望切分成小文件。在 Linux 中,可以使用多种工具来切分大文件,最常用的是 split 命令。split 命令可以将一个大文件按照指定大小切分成多个小文件。 2. 用法 spl…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...
