Skip to content

Commit 4e58c16

Browse files
authored
Merge pull request #11 from VitaDynamics/codex/ractor-agent-harness-base
[codex] add actor runtime harness comparison
2 parents 5adf688 + 789ca35 commit 4e58c16

3 files changed

Lines changed: 280 additions & 1 deletion

File tree

docs/best-choices/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
| 文档 | 描述 | 分析框架 | 更新时间 |
1616
|------|------|----------|----------|
17+
| [Rust Actor Runtime 作为 Agent Harness 基座](./rust-actor-runtime-for-agent-harness.md) | `kameo` vs `ractor`:会话监督、事件流、worker/factory 路由与停机语义选型 | kameo, ractor | 2026-03-10 |
1718
| [LLM 错误处理设计](./llm-error-handling-design.md) | 结构化错误分类、重试策略、回退模式 | pydantic-ai, langchain, republic | 2026-02-26 |
1819
| [流式拉取防抖推送设计](./streaming-pull-debounced-push-design.md) | 拉取式和防抖推送的流式架构模式 | pydantic-ai, kimi-cli, republic | 2026-02-26 |
1920
| [机器人情绪与动作系统设计](./emotion-motion-system-design.md) | 永不静止原则、双层融合架构、音频驱动运动 | reachy-mini-conversation-app | 2026-03-02 |
@@ -68,4 +69,4 @@
6869

6970
---
7071

71-
*最后更新:2026-03-02*
72+
*最后更新:2026-03-10*
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
---
2+
tags: actor-model, rust, agent-harness, concurrency, best-practice, kameo, ractor
3+
---
4+
5+
# Rust Actor Runtime 作为 Agent Harness 基座:Kameo vs Ractor
6+
7+
> **综合自**: kameo, ractor
8+
>
9+
> **结论先行**: 如果目标是给 `dive-agent` 选一个更稳的 agent harness 实现基座,我更推荐 **`ractor`**
10+
> `kameo` 更适合做 async-first、Tokio-native、带内建 tracing/metrics 的快速原型;`ractor` 更适合做需要明确生命周期、监督、优先级、worker/factory 路由和可控停机语义的长期运行时内核。
11+
12+
---
13+
14+
## 问题定义
15+
16+
Agent harness 不是普通业务服务。它通常同时承担这几类职责:
17+
18+
- **会话隔离**:每个 session / agent run 都需要自己的状态边界
19+
- **请求-响应**:主控 agent 要能同步等待 model/tool/subagent 的结果
20+
- **事件流**:token、tool-progress、trace、UI status 需要持续扇出
21+
- **监督与取消**:子 agent 卡死、tool 超时、run 被用户终止时,需要明确收尾语义
22+
- **并发治理**:tool worker 池、session 粘性路由、背压、限流不能全靠业务层手写
23+
24+
所以这次选型的重点不是“谁的 actor API 更顺手”,而是“谁更像一个能承载 harness 的运行时骨架”。
25+
26+
---
27+
28+
## 方案 A:Kameo
29+
30+
### 它更像什么
31+
32+
`kameo` 是一个 **Tokio-first、async 友好、类型化 request/reply 体验很顺手** 的 actor 框架。
33+
它有这些很吸引 harness 的点:
34+
35+
- `ask` / `tell` API 直接,且支持 `mailbox_timeout``reply_timeout`
36+
- actor 可以 `attach_stream`,把外部 stream 挂进 actor 生命周期
37+
- 内建 `tracing``metrics``otel` feature
38+
- 自带 supervision 模块,支持 `OneForOne / OneForAll / RestForOne`
39+
- 内建 remote 模式,底层直接走 `libp2p`
40+
41+
### 映射到 agent harness 的数据流
42+
43+
如果用 `kameo` 搭 harness,一个比较自然的链路是:
44+
45+
```text
46+
UserTurn
47+
-> SessionActor.ask(TurnInput)
48+
-> PlannerActor.ask(PlanStep)
49+
-> ToolPool.ask/Tell(ToolCall)
50+
-> attach_stream(TokenDelta / ToolProgress / TraceEvent)
51+
-> EventSink.tell(EventEnvelope)
52+
-> SessionActor.reply(TurnResult)
53+
```
54+
55+
它的优点是:
56+
57+
- **把流式 token / tool progress 接进 actor 很自然**
58+
- **请求超时是现成能力**,不用业务层重复包一层
59+
- **如果以后真想做 P2P agent swarm**`libp2p` 集成路径比多数 actor 库更直接
60+
- **观测接入成本低**,适合快速把 tracing/metrics 打通
61+
62+
### 它不够适合作为基座的地方
63+
64+
问题不在“不能做”,而在“做成 runtime kernel 之后,很多关键语义不如 `ractor` 明确”:
65+
66+
- **运行时优先级语义不够突出**
67+
harness 很在意 `Kill``Stop`、普通消息、监督事件谁先处理;`kameo` 有生命周期和 supervision,但对“优先级调度语义”没有 `ractor` 那么明确的运行时文档和建模。
68+
- **worker/factory 级别编排能力偏轻**
69+
它有 `ActorPool`,但更偏“负载均衡池”;如果你要做 key-based routing、priority queue、discard policy、dead-man's switch、动态 worker 数调整,`ractor` 的现成能力更完整。
70+
- **更偏框架易用性,而不是 runtime 语义完整性**
71+
对 prototype 是优点;对 harness 内核,这反而意味着很多治理策略要自己补。
72+
- **编译器门槛更高**
73+
当前 `kameo` 需要 Rust `1.88``edition = 2024`,这会提高落地门槛。
74+
75+
---
76+
77+
## 方案 B:Ractor
78+
79+
### 它更像什么
80+
81+
`ractor` 明确沿着 **Erlang/OTP 风格运行时语义** 往前走。
82+
它的核心价值不是“actor 很容易写”,而是“actor 系统在出故障、停机、扩缩容时语义更清楚”。
83+
84+
几个对 harness 很关键的点:
85+
86+
- 明确区分 `Signal(Kill)``Stop``SupervisionEvent`、普通 `Message` 的优先级
87+
- supervision tree、monitor、registry、process group 都是第一层能力
88+
- `RpcReplyPort` 把 call/reply 语义做成框架原语
89+
- `Factory` 提供 worker 池、路由、队列、限流、discard、动态配置更新
90+
- `OutputPort` 提供事件扇出能力,适合 token/status/trace 广播
91+
- 默认带 `message_span_propogation`
92+
93+
### 映射到 agent harness 的数据流
94+
95+
如果用 `ractor` 搭 harness,一个更像“运行时内核”的链路会是:
96+
97+
```text
98+
UserTurn
99+
-> SessionSupervisor.call(TurnMessage, timeout)
100+
-> PlannerActor.call(PlanMessage)
101+
-> ToolFactory.Dispatch(Job<SessionKey, ToolCall>)
102+
-> Worker.handle(Job)
103+
-> OutputPort<TokenEvent / StatusEvent / TraceEvent>
104+
-> UIActor / TraceCollector / PersistenceActor
105+
-> SupervisionEvent / Stop / Kill
106+
-> SessionSupervisor decides restart / stop / cleanup
107+
```
108+
109+
这条链路和 agent harness 的几个核心诉求更贴:
110+
111+
- **session 粘性路由**:同一 session 的任务可以稳定落到同一 worker
112+
- **事件旁路扇出**:token 流不必强耦合在 call 返回值里
113+
- **停机语义更清楚**:正常 stop 和强制 kill 是分开的
114+
- **监督决策更显式**:子 actor 异常退出后由 supervisor 统一收口
115+
- **并发治理更像“平台能力”**:不是每个 tool actor 各自发明限流和队列
116+
117+
### 它的代价
118+
119+
`ractor` 的问题也很明确:
120+
121+
- **开发体验没 `kameo` 那么轻**
122+
想把一个业务 actor 写出来,模板代码和概念负担更重。
123+
- **cluster 仍需谨慎**
124+
`ractor_cluster` 已经很完整,但仓库 README 仍明确说不该把它视为 production ready。
125+
- **观测能力更偏“可插拔”而不是“内建套餐”**
126+
你会拿到 message span propagation、output port、supervision event 这些接点,但要自己把 tracing/metrics 体系拼完整。
127+
128+
---
129+
130+
## 关键维度对比
131+
132+
| 维度 | Kameo | Ractor | 对 harness 的含义 |
133+
|------|------|--------|-------------------|
134+
| actor 易用性 | 更顺手,Tokio-first | 更偏 OTP 风格 | 原型期 `kameo` 占优 |
135+
| request/reply | `ask/tell` 直观,超时现成 | `call/cast` + `RpcReplyPort`,更底层 | 两者都够用 |
136+
| 流式事件接入 | `attach_stream` 很自然 | `OutputPort` 更适合广播扇出 | 单流接入偏 `kameo`,多订阅扇出偏 `ractor` |
137+
| 监督语义 | 有 supervision tree | supervision + monitor + priority channels 更完整 | `ractor` 更适合 runtime 内核 |
138+
| 并发治理 | `ActorPool` 偏基础 | `Factory` 有 routing/queue/discard/rate-limit | `ractor` 明显更强 |
139+
| 运行时可预测性 | 足够,但更偏框架层 | 显式文档化 stop/kill/supervision 优先级 | `ractor` 更稳 |
140+
| 可观测性 | `tracing/metrics/otel` feature 很友好 | 需要自己组装,但接点明确 | 原型接观测偏 `kameo` |
141+
| 分布式方向 | `libp2p` 内建 remote | `ractor_cluster` 仍需谨慎 | 如果要 P2P swarm,`kameo` 更有吸引力 |
142+
| 落地门槛 | Rust `1.88` / edition 2024 | Rust `1.64+`,默认 Tokio | `ractor` 更稳妥 |
143+
144+
### 维护活跃度补充
145+
146+
按 2026-03-10 的 GitHub 官方仓库数据看:
147+
148+
- `kameo`:约 1.2k stars,最近 release 是 `v0.19.2`(2025-11-17)
149+
- `ractor`:约 2.0k stars,最近 release 是 `v0.15.12`(2026-03-09)
150+
151+
两边都还在维护,但 `ractor` 在公开活跃度、发布连续性和生态可见度上更占优,这会降低它作为底层基座的选型风险。
152+
153+
---
154+
155+
## 为什么我给 `dive-agent` 的建议是 Ractor
156+
157+
### 1. Agent harness 更像“运行时内核”,不是“普通 async 应用”
158+
159+
真正难的地方不是把消息发出去,而是:
160+
161+
- run 中途取消时,哪些任务必须立刻停
162+
- 哪些子 actor 异常后要重启,哪些要整棵 session 停掉
163+
- token 流、trace 流、持久化流如何旁路扇出
164+
- tool worker 爆满时,如何限流、排队、丢弃或降级
165+
166+
这些问题上,`ractor` 的语义和现成模块更接近 harness 需要的“操作系统层能力”。
167+
168+
### 2. `Factory + OutputPort + SupervisionEvent` 这组三件套很适合 harness
169+
170+
`dive-agent` 这种系统,一个很自然的最小骨架是:
171+
172+
```rust
173+
SessionSupervisor
174+
-> PlannerActor
175+
-> ToolFactory
176+
-> MemoryActor
177+
-> TraceCollector
178+
-> UI/Event subscribers
179+
```
180+
181+
其中:
182+
183+
- `Factory` 负责 tool worker 池和路由策略
184+
- `OutputPort` 负责 token/status/trace 广播
185+
- `SupervisionEvent` 负责统一收口子 actor 生命周期
186+
187+
这比“先用轻量 actor 跑起来,再慢慢补平台治理能力”更像一个能长期演进的起点。
188+
189+
### 3. `kameo` 更适合做探索型实现,不是最稳的内核底座
190+
191+
如果目标是:
192+
193+
- 单机 Tokio runtime
194+
- 快速做出一个流式 agent demo
195+
- 很快把 tracing/metrics 接进去
196+
- 未来可能玩 P2P actor swarm
197+
198+
`kameo` 非常有吸引力。
199+
200+
但如果目标是把 `dive-agent` 做成一个 **长期可维护的 harness runtime**,我会优先选 `ractor`,然后在上层补更顺手的 API facade。
201+
202+
---
203+
204+
## 落地建议
205+
206+
### 推荐选型
207+
208+
**默认基座:`ractor`**
209+
210+
### 推荐分层
211+
212+
```text
213+
App API Layer
214+
-> Harness Facade
215+
-> Ractor Runtime Layer
216+
- SessionSupervisor
217+
- ToolFactory
218+
- OutputPort-based event bus
219+
- TraceCollector
220+
- Registry / PG / monitors
221+
-> Provider / Tool adapters
222+
```
223+
224+
### 什么时候改选 Kameo
225+
226+
满足下面任一条件,可以优先考虑 `kameo`
227+
228+
- 先做原型,3 周内要出可运行 demo
229+
- 强依赖 Tokio-native stream 接入体验
230+
- 观测体系希望尽量“开 feature 就能用”
231+
- 未来路线偏 libp2p / 去中心化 agent 网络,而不是 OTP 风格 supervision 内核
232+
233+
---
234+
235+
## 最终建议
236+
237+
**如果是给 `dive-agent` 选 agent harness 的实现基座,我建议选 `ractor`**
238+
239+
一句话概括:
240+
241+
- `kameo` 更像“更顺手的 async actor 框架”
242+
- `ractor` 更像“更适合承载 harness 的 actor 运行时”
243+
244+
前者更适合把东西尽快做出来,后者更适合让这个系统在复杂生命周期、并发治理和故障恢复里站得住。
245+
246+
---
247+
248+
## 参考
249+
250+
- [tqwewe/kameo](https://github.com/tqwewe/kameo)
251+
- [Kameo Book](https://docs.page/tqwewe/kameo)
252+
- [Kameo Distributed Actors](https://github.com/tqwewe/kameo/blob/main/docs/distributed-actors.mdx)
253+
- [Kameo Observability](https://github.com/tqwewe/kameo/blob/main/docs/observability.mdx)
254+
- [slawlor/ractor](https://github.com/slawlor/ractor)
255+
- [Ractor Runtime Semantics](https://github.com/slawlor/ractor/blob/main/docs/runtime-semantics.md)
256+
- [ractor_cluster README](https://github.com/slawlor/ractor/blob/main/ractor_cluster/README.md)

website/tags.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,25 @@ truncation:
379379
permalink: /truncation
380380
description: 自动发现的标签
381381

382+
383+
# 自动发现的标签
384+
actor-model:
385+
label: actor-model
386+
permalink: /actor-model
387+
description: 自动发现的标签
388+
389+
kameo:
390+
label: kameo
391+
permalink: /kameo
392+
description: 自动发现的标签
393+
394+
ractor:
395+
label: ractor
396+
permalink: /ractor
397+
description: 自动发现的标签
398+
399+
rust:
400+
label: rust
401+
permalink: /rust
402+
description: 自动发现的标签
403+

0 commit comments

Comments
 (0)