前言
在上一篇文章中,我们大致演示了 ai_agent 的基本使用方法。本文重点深入核心模块 runtime(运行时)的设计与实现。
无论是单个 Agent 还是 Workflow,其基础功能的实现相对简单。真正的挑战在于如何将它们有机地组合起来,使其按照特定的逻辑流转,并支持层层嵌套,从而实现无限的能力扩展。
为了更直观地理解这一概念,我们先分析几个典型的应用场景及其对应的流程设计需求。
1. 简单的 Workflow 场景
我们可以使用一个简单的 Workflow 来处理特定场景,例如奶茶店的智能推荐系统。其基本流程如下:
graph LR
User --用户画像+query+上下文--> Prompt
Prompt --> LLM
LLM --> Answer
Answer --> Card
在这个流程中,我们将 LLM、Memory、Prompt 等视为独立的节点,按照图中定义的顺序依次执行,最终得到推荐结果。这是 Workflow 的基础功能体现,适用于线性任务。
2. Smartflow 场景
对于某些复杂问题,我们无法预先完全预测执行流程。例如 Least-to-Most 和 Smartflow 场景,这些节点往往是在执行过程中动态生成的。
以'评阅大师'Agent 为例,目标是优化输入文案。其工作流程可能包含一个评分 LLM 和一个优化 LLM。评分 LLM 不断给出需要优化的点并追加到上下文中,优化 LLM 根据要求不断优化,直到评分达到阈值(如>80)。
graph TD
User -->|文案| PF[评分 LLM]
PF -->|评分>80| Output
PF -->|评分<80\n待优化方向| YHP[追加上下文]
YHP --> YH[优化 LLM]
YH --> PF
这种设计表明,我们的流程不能仅仅是有向无环图(DAG),因为可能存在循环依赖。运行时必须支持动态节点生成和状态回溯。
3. Multi-Agent 场景
Multi-Agent 常用于解决复杂问题,对流程设计的要求更高。典型的场景是狼人杀游戏。流程可能涉及多个角色交互:
graph TD
Start[入夜] --> Host[主持人]
Host -->|第一轮| Wolf[狼人开刀]
Wolf --> Host
Host -->|第二轮| Witch[女巫药]
Witch --> Host
Host -->|第三轮| Seer[预言家查人]
Seer --> Host
Host -->|第四轮| Talk[所有人发言]
Talk --> Vote[归票]
Vote --> Host
Host --> End[结束]
虽然上图游戏规则并不严谨,但能感受到 Multi-Agent 的工作方式。每个角色都是一个独立的 Agent,拥有自己的 Prompt 和 Memory。主持人可以是固定的脚本或另一个 Agent。这个场景要求流程设计能够层层嵌套,将一个 Agent 放大后,它本身也应该是一个由无数节点拼接而来的 Workflow。
4. NL2Code 场景
保持开放是至关重要的能力。一方面允许程序员直接编写脚本,另一方面大模型也能自行生成代码(NL2Code)。
例如在文档处理场景中,用户自由操作文档(归类、摘取),结果通过 text2sql 存入数据库。仅仅提供有限功能的节点是不够的,必须具备无限扩展的能力,允许运行时调用外部工具或解释器。
5. 开放域场景
在开放域中,Agent 将具备更自由的意志。典型场景包括聊天室、游戏 NPC、虚拟宠物等。
在这种应用中,Agent 应被视为一个完备的 AI,具备更长的生命周期和更强的主观能动性。从运行到结束,要像人一样,生下来就有意识,直到死亡。
简单的做法是先构建一个 Single Agent,赋予其 Memory、Tool 和设定模块,采用多模态大模型做基座,然后不断循环调用。另一种方法是双循环:一个循环响应外界输入,另一个循环定时唤起 Agent 的主观意识,从而节能减排。
Runtime 设计
一个 Agent 的 Runtime 可以看作由调度、节点服务、执行计划和上下文四部分组成。
节点 Service
Service 可以理解为一个原子能力,比如 LLM 调用、工具函数或自定义 Function。我们需要对其进行抽象,确保线程安全和异步执行。


