旗舰 3 · 系统边界与压测

agent-tree

让多个智能体安全地改同一份状态——一个基于黑板模式的动态协作系统, 用乐观锁、能力路由和依赖拓扑排序把并发冲突挡在数据层之外。

PRODUCT → EVIDENCE

产品视角 · 问题、判断与结果

问题:多个智能体同时修改任务,可能发生覆盖或依赖倒挂。我的判断:用版本校验、能力匹配与依赖排序约束协作。

结果:09-06 本地报告记录 100/100 请求成功、API P95 最高 44.40 ms;当前源码有批量写入和请求关联。不足:旧压测不代表新版本容量,长尾抖动仍待定位。

核验进展与复现材料 · 2026-10-06

已核对批量写入 API、X-Request-ID → 领域事件 trace_id、观测测试和 docs/rollout.md。发布设计已完成;应用内关联不等于跨服务 span 链,实际灰度、回滚演练和新版容量仍待验证。

下一步:在目标机器批准观察窗口与基线,演练正确性故障、长尾延迟和回滚;对批量写入作同环境比较,避免预设 20 entries/s 为硬上限。

材料区分报告记录、源码核对与待办设计;不代表真实用户效果或本轮重新运行了底层项目。

职责与范围 ↓技术结果与口径 ↓

② 角色与时间

角色
独立(架构 + 实现 + 压测)
时间
首份压测报告日期:2026.09.06;前期设计与实际投入时长待确认
规模
本地单实例参考实现;规模与性能数字对应 2026-09-06 历史报告。当前源码已增加批量写入与请求关联,不将旧指标冒充新版压测。
技术
Python 3.11 + FastAPI 0.115.6 + Uvicorn + SQLite(aiosqlite) + WebSocket;httpx / websockets 自建压测

③ 问题背景

多个智能体共享一块状态时,最容易出的不是「算不出来」,而是算对了但写坏了:两个智能体同时改同一个任务、依赖还没完成就被分配、冲突静默覆盖。黑板模式的好处是状态集中可审计,坏处是所有并发压力都集中在一点。

这一版要回答的是:在 SQLite 这种单写锁的存储上,这套协作机制能撑到什么程度,先坏在哪里。

④ 关键判断与实现代价

01

用乐观锁而不是悲观锁控制版本冲突

依据智能体任务多为「读—算—写」,持锁期间在算会产生长事务;乐观锁把冲突推到提交时检查,读路径完全无锁。

代价高冲突场景下会频繁失败重试,需要调用方处理重试语义。

02

任务分配走能力匹配,而不是抢单

依据抢单会让「有能力但慢」的智能体拿不到任务,最终质量取决于谁反应快,而不是谁更合适。

代价需要维护能力标签,且分配逻辑比抢单慢一步。

03

依赖关系做拓扑排序,不允许「先做后补依赖」

依据依赖倒挂会产出看起来完成、实际不可用的结果,比直接失败更难排查。

代价有环的依赖会被直接拒绝,灵活性下降。

04

压测自己写脚本,而不是只跑功能测试

依据不压测就不知道瓶颈在哪,也不知道该优化什么。功能测试全绿的系统在高并发下可能第一个请求就坏。

代价多花了一份压测脚本的成本,但换来了明确的瓶颈结论。

⑤ 实现要点

八个服务模块围绕黑板展开:智能体注册与心跳(无心跳即视为下线,任务可被重新分配)、乐观锁版本控制(写入时校验版本号)、基于能力的任务分配、依赖拓扑排序、冲突解决。

状态存在 SQLite 单库,WebSocket 负责把黑板变更推给订阅方,避免轮询。

⑥ 可验证结果

API 延迟 P95 < 45 ms(最高 44.40 ms) ✓ 目标 < 100 ms
100 并发 100 / 100 成功 ✓ 目标 100+
吞吐量 125–135 req/s(129.4 / 135.0 / 126.8 / 133.8)
并发批次总耗时 / 请求数 7.73 / 7.41 / 7.89 / 7.47 ms(报告以总耗时 / 请求数计算,非逐请求平均延迟) ✓ 不可据此推断并发下每个请求的平均响应时间
WebSocket P95 9.82 ms(均值 24.69 ms) ✓ 目标 < 50 ms
数据规模 142 智能体 / 636 任务 / 2,003 条目 / 4 规则
Python 分配采样(非进程内存) 0.31 MB 当前 / 0.34 MB 峰值(tracemalloc Python 分配采样;非进程 RSS) ✓ 不与服务总内存或生产容量比较
历史写入样本 22.7 / 21.8 / 19.7 entries/s(09-06 历史样本;非当前硬上限) !

证据:trae_projects/agent-tree/reports/performance_test_report.md(4,075 B)

诚实附注

  • 本机单实例,不可外推为生产并发能力。
  • 历史报告的条目创建样本为 22.7 / 21.8 / 19.7 entries/s;约 20/s 是该轮样本概括。源码后来已有批量提交,不能把旧数值称为当前版本硬上限。
  • WebSocket 最大延迟出现过 821.88 ms 的偶发抖动,根因未定位。我没有在报告里把它平均掉。
  • python-embed.zip(11 MB)与 get-pip.py 是工具链,不计入项目体量。

⑦ 已落实的改进与下一步

当前源码已提供批量条目接口、请求关联 ID、领域事件 trace_id 及发布/回滚设计稿。它们补齐了实现与运维入口;本轮未重跑性能或回滚演练,不能据此声称写入吞吐提升。

下一步在同一机器、相同数据与负载下,对照单条提交和批量提交,记录错误率、吞吐与长尾延迟;继续定位历史 821.88 ms 推送抖动,再审批发布阈值。