SKILL.md — Agha Actor 模型:并发智能体系统设计
决策点
根据任务类型选择参与者创建策略
IF 任务具有顺序依赖关系:
├─ 使用客户模式: 创建带有回复地址的子actor
├─ 将客户地址作为参数传递给子actor
└─ 子actor将结果直接发送给客户(而不是父actor)
IF 任务需要长时间计算:
├─ 为计算创建不敏感actor
├─ 将入站消息转发到缓冲区actor
└─ 计算完成后从缓冲区恢复处理
IF 任务需要动态资源分配:
├─ 按需创建资源管理器actor
├─ 将能力(地址)作为消息数据传递
└─ 无中央注册表——地址通过系统流动
IF 任务需要故障隔离:
├─ 为高风险操作生成受监督的子actor
├─ 监督者通过缺失的回复检测故障
└─ 替换失败的actor,而不影响其他
IF 需要组合现有智能体系统:
├─ 验证接口是否保留因果结构
├─ 测试组合下的行为(而不仅仅是隔离)
└─ 使用消息协议作为边界(而非共享状态)
消息发送 vs 状态替换决策树
IF 需要与其他智能体协调:
├─ 发送消息(不要先修改本地状态)
├─ 如果预期有响应,则包含回复地址
└─ 永远不要假设消息顺序
IF 需要本地计算:
├─ 指定替换行为
├─ 封装新状态(不暴露内部细节)
└─ 确保一次只处理一条消息
IF 需要动态扩展:
├─ 创建具有特定行为的新actor
├─ 将必要地址传递给新actor
└─ 无共享初始化状态
故障模式
1. 中央编排器反模式
检测: 如果看到一个actor路由所有消息或持有所有系统状态 症状: 单点故障、负载下成为瓶颈、无限递归问题 修复: 分解为actor社区,每个只了解本地上下文,使用能力路由
2. 同步阻塞谬误
检测: 如果actor等待/阻塞响应,而不是指定替换行为 症状: 负载下死锁、隐藏的时间假设、并发性降低 修复: 建模为请求-回复消息对,使用客户模式处理依赖关系,应用不敏感actor模式
3. 共享状态污染
检测: 如果多个actor读/写相同的数据结构(即使有锁) 症状: 竞态条件、顺序瓶颈、隐藏的全局状态 修复: 将状态封装在单个actor中,使用消息传递进行协调,互斥是免费的
4. 仅输出验证
检测: 如果测试只比较最终输出,而不检查交互模式 症状: Brock-Ackerman 异常——相同的输出但不同的组合行为 修复: 验证因果结构保留、测试组合下的行为、使用观察等价性
5. 静态拓扑假设
检测: 如果通信图在启动时固定,无法在运行时重新配置 症状: 无法处理开放系统、无动态资源管理、面对变化时脆弱 修复: 将地址视为一等数据、实现能力路由、支持运行时拓扑变更
实战示例
示例 1:使用客户模式的任务分解
场景: 智能体需要处理一个复杂的请求,该请求需要顺序子任务 A → B → C,但必须保持对其他消息的响应能力。
新手方法:
receive request →
block while calling subtask A
block while calling subtask B
block while calling subtask C
send final result
Actor 模型的专家应用:
receive request →
create customer_BC actor with addresses for B, C, final recipient
send subtask A request to A_processor with customer_BC as reply address
specify replacement behavior: ready for next request
customer_BC receives A result →
send result to B_processor with customer_C as reply address
customer_C receives B result →
send result to C_processor with final_recipient as reply address
所作出的关键决策:
- 使用客户模式避免阻塞
- 每一步在链中创建下一个客户
- 原始智能体在整个过程中保持响应
- 任何子任务失败仅会影响该链
示例 2:使用监督模式的故障恢复
场景: 系统需要处理智能体故障,而不会级联影响到整个系统。
新手方法: 对智能体调用使用 try-catch,故障时重启所有内容。
专家应用:
supervisor creates worker_actor →
sends task to worker with reply timeout
specifies replacement: "waiting_for_reply"
IF reply received within timeout →
forward result to client
specify replacement: "ready"
IF timeout expires →
create new worker_actor (old one failed)
resend task to new worker
specify replacement: "waiting_for_reply"
权衡取舍:
- 监督是与业务逻辑分离的关注点
- 失败的actor被隔离和替换,而非修复
- 超时检测与保证传递之间的平衡
- 监督者和工作者之间无共享状态
质量门禁
- 没有actor阻塞其消息处理循环(在需要的地方应用了不敏感actor模式)
- 所有协调都使用消息传递(参与者之间无共享可变状态)
- 保证消息传递,但不假设顺序
- 地址被视为能力路由的一等数据
- 每个actor为每种消息类型指定替换行为
- actor的创建根据计算需求动态发生
- 故障隔离防止跨actor边界的级联故障
- 系统拓扑可以在没有中央注册表的情况下在运行时重新配置
- 组合行为得到验证,而不仅仅是隔离的组件行为
- 同步操作建模为请求-回复消息对
非适用边界
此技能不应被用于:
- 简单的顺序计算 → 改用函数式编程
- 物理上需要共享内存的系统 → 改用基于锁的并发模式
- 具有严格时序约束的实时系统 → 使用具有正式时序分析的同步消息传递
- 无需协调的数学计算 → 改用纯函数式方法
在以下情况委派给其他技能:
- 实现特定的actor框架 → 使用平台特定的实现指南
- 对actor系统进行性能调优 → 使用 [performance-optimization] 技能
- 对actor属性进行形式化验证 → 使用 [formal-methods] 技能
- 为actor持久性设计数据库 → 使用 [data-architecture] 技能
关于范围常见的误解:
- Actor不仅仅是“具有异步方法的对象”——它们需要完整的 3 元组响应
- Actor模型不仅仅适用于分布式系统——适用于任何并发计算
- 主要不是性能优化——它是一个正确性和可组合性框架