大语言模型(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软件的设计模式强调发挥智能体的自主性和动态决策能力,重点在于软件的自适应性。
传统软件是架构严谨、接口明确的单体结构和一个高效的过程,而智能体软件则是围绕大语言模型而构建的松而不散,关系复杂的模块化结构和一个不断迭代的过程。智能体强调充分发挥大模型的推理能力,通过迭代的方式提升性能,通过感知过程和环境变化、以及多智能体之间的协作来进行动态的决策等特点。
在洞察的过程中,我们感受到智能体软件设计模式和架构的发展远未成熟,尚缺乏有说服力的高价值典型应用出现。但是,我们同时也能够看到新技术所带来的前景,感受到其与传统技术的巨大差异。相信智能体技术必会继续快速发展,渐成大器。