ΓDocsInteractiveNet

06 · 运行时与调度网络

轨道 B 的工程核心。目标:单机把纯网跑快,把 Agent 的 effect 管好;多机把 cell 的归属、消息、迁移、故障处理清楚。 原则:compute 与 effects 分离;本地点火,远程传消息;确定性靠日志,不靠祈祷。

实现状态(M3):本文件是目标架构。M2/M3 已实现单机执行层的核心切片(stateful agents、 mock/HTTP/shell effects、effect rows、预算、journal/checkpoint、trace/replay、trace viewer、 独立 flow 批处理),见 10-m2-runtime.md 与 11-m3-language.md。 单 flow 内多线程 work stealing、真实 LLM provider、session-typed channels、分布式调度仍在 M4+。

6.1 目标与非目标

目标

指标 v1 目标
纯网吞吐(单核) ≥ 5M interactions/s
纯网吞吐(8 核) ≥ 20M interactions/s
Agent 消息吞吐(单节点) ≥ 20k msg/s
调度延迟 p99 < 10ms(本地)
重放一致率 100%(同 checkpoint + 同 effect log)
故障恢复 < 5s(3 节点,1 节点故障)
内存 < 64B/cell(纯网);大 payload 外置
可观测 每次交互/effect 可查询、可回放

非目标

  • 不做通用 GPU 运行时(纯计算子网可编译到 HVM/IC 后端)。
  • 不做跨公网拜占庭容错(v1 受信集群 + TLS)。
  • 不做通用数据库/对象存储(用适配器接 S3/Postgres/Redis)。
  • 不做"零拷贝跨机共享内存"(v1 消息传递;RDMA 是 v3 研究)。

6.2 总体架构

┌─────────────────────────────────────────────────────────────┐
│                        ain CLI / SDK                        │
│  .ain → parse → typecheck → AIN IR → bytecode               │
└───────────────────────────┬─────────────────────────────────┘
                            │ deploy / run
┌───────────────────────────▼─────────────────────────────────┐
│                     aind (single node)                      │
│                                                             │
│  ┌──────────────┐   ┌──────────────┐   ┌─────────────────┐  │
│  │ Compute      │   │ Effect bus   │   │ Durability      │  │
│  │ workers 0..N │   │ (tokio)      │   │ WAL + snapshot  │  │
│  │  - redex bag │   │  - LLM       │   │  - append       │  │
│  │  - steal     │   │  - HTTP      │   │  - fsync policy │  │
│  │  - heap/GC   │   │  - tool      │   │  - replay       │  │
│  └──────┬───────┘   │  - human     │   └─────────────────┘  │
│         │           └──────┬───────┘                        │
│  ┌──────▼───────────────────▼────────────────────────────┐  │
│  │              Net store (cells, wires, rules)          │  │
│  │              + routing table + leases                 │  │
│  └───────────────────────┬───────────────────────────────┘  │
│                          │ QUIC streams                     │
└──────────────────────────┼──────────────────────────────────┘
                           │
        ┌──────────────────┼──────────────────┐
        ▼                  ▼                  ▼
   ┌─────────┐        ┌─────────┐        ┌─────────┐
   │ node 2  │        │ node 3  │        │ node k  │
   └─────────┘        └─────────┘        └─────────┘

控制面(membership/placement/lease)在 v1 可以是嵌入式(每个节点跑一个轻量协调线程 + 静态配置),v2 抽出独立 ain-sched 服务。

6.3 单机运行时

6.3.1 数据表示

Term(纯网):64-bit word,HVM 风格:

 1    5      18            40
┌───┬─────┬──────────┬──────────────────┐
│sub│ tag │  label   │      value       │
└───┴─────┴──────────┴──────────────────┘
  • tag:CON / DUP / ERA / VAR / NUM / CTR / REF / EFFECT / JOIN / …
  • label:δ/γ 的标签、构造子 id、effect id。
  • value:节点地址(40-bit 本地堆偏移)或未装箱数字。
  • sub:是否已被替换(IC 的全局变量优化)。

Cell(Agent):

#[repr(C)]
struct Cell {
    header: u64,          // tag | state | flags
    principal: AtomicU64, // 端口(wire)
    aux: [AtomicU64; N],  // 端口
    payload: ValueId,     // 大状态/消息体(堆外)
}
  • 小状态内联;大状态(文本/JSON)放 ValueStore(bump arena + 引用计数)。
  • CellId = (node: u32, worker: u16, slot: u32, gen: u16),96-bit;v1 可用 128-bit 简化。

端口/线:

  • 每个端口是一个 AtomicU64,存对端 PortRef 或 FREE。
  • 连接 = CAS:两边都 free 才能连;一边是变量则做替换;两边是 cell 则形成活跃对。
  • 这就是 HVM2 的"atomic linker";好处:无锁、局部、可并行。

6.3.2 归约循环

fn worker_loop(w: &Worker) {
    loop {
        let Some(redex) = w.pop_or_steal() else { break };
        if !w.claim(&redex) { continue; }       // cell 状态 Idle -> Busy
        let rule = w.match_rule(&redex);
        let rhs = w.instantiate(rule);          // 分配 RHS cell
        w.splice(&redex, rhs);                  // 重接端口
        w.push_new_redexes();                   // 新活跃对入队
        w.release(&redex);
    }
}

关键点:

  • claim:每个 cell 有 Busy 位;两个 worker 不能同时点火同一个 cell。
  • splice:先接新线,再断开旧线;失败可回滚(或按顺序保证不会失败)。
  • redex bag:本地 deque;新 redex 优先入本地;空闲时随机偷取(Chase–Lev)。
  • 批量:小规则一次处理多个,减少队列开销;大规则(effect/IO)单独走。

6.3.3 内存与 GC

交互网是线性的:一个 cell 被规则消费后,通常可以立即回收。但有三个复杂点:

  1. 环:vicious circle 可能形成引用环;纯 refcount 会泄漏。
  2. 共享:δ 复制后,两个分支共享 payload;需要引用计数或不可变数据。
  3. 大 payload:文本/JSON 不应复制;用 Arc/arena + 引用计数。

v1 方案:

  • Arena + 引用计数:cell 分配在 per-worker slab;payload 用 Arc<Value>。
  • 周期回收:每 N 次交互或内存阈值触发一次 cycle collector(Bacon–Rajan 风格);或按 epoch 重置 arena(checkpoint 后)。
  • 擦除即释放:ε 规则显式减少引用;没有隐式 GC 扫描。
  • 上限保护:max_cells/max_bytes;超限返回 Error<ResourceExhausted>,由 supervisor 处理。

6.3.4 规则匹配与编译

  • 规则表按 (agent_tag_a, agent_tag_b) 索引;O(1) 查找。
  • 规则 RHS 预编译为分配模板:一串 alloc + set_port 指令;避免运行时解释。
  • 状态展开后,agent tag 已经包含状态;规则表可能较大(states × messages),用两级表/完美哈希。
  • 数字/字符串等原生操作走内建规则(ADD, CMP, CONCAT),避免 Church 编码。

6.3.5 确定性模式

  • --deterministic:单 worker + 固定 redex 顺序(FIFO);用于 golden trace/调试。
  • --parallel:多 worker;纯网结果仍由强合流保证;trace 记录实际调度顺序。
  • --replay:从 WAL 读 step 顺序,强制按序点火;effect 从 log 注入。

6.4 调度器

6.4.1 本地策略

策略 用途 说明
FIFO 基准/确定性 简单、可复现
EDF 截止时间 最早 deadline 优先;需可抢占(在交互边界)
WFQ 多租户公平 按 weight 分配点火配额
Critical Path 降低 makespan 优先在关键路径上的 redex(需 DAG 估计)
Cost-Aware 预算约束 优先低成本/高价值;避免在昂贵 effect 前做无用功
Locality 分布式 优先本地 redex,减少远程消息

默认:CostAware = EDF + WFQ + 关键路径 + 预算准入。

6.4.2 优先级传播

  • 每个任务有 deadline, weight, budget, criticality。
  • 消息携带优先级;Agent 处理消息时继承最高优先级(priority inheritance),避免低优先级任务卡住高优先级。
  • Effect 请求继承调用者的优先级;LLM 队列按优先级 + 租户配额调度。

6.4.3 抢占与取消

  • 抢占只在交互边界发生(规则点火前后),不在规则中间;保证原子性。
  • 取消:Cancel 消息沿网传播;Effect 支持取消的 provider 直接 abort;不支持的在结果返回后丢弃(计费仍发生)。
  • 预算耗尽:调度器拒绝新的 effect 准入;已发出的调用不强制中断(除非 provider 支持)。

6.4.4 全局放置

v1:

  • 静态:@loc 标注 / 租户 / agent 类型 → 节点。
  • 一致性哈希:hash(agent_id) % nodes;迁移时更新。
  • 本地优先:跨节点 wire 只在必要时建立。

v2:

  • 通信图分区:统计 (cell_a, cell_b) 交互频率,做图分区(METIS 风格),最小化跨节点边。
  • 负载感知:队列深度、CPU、effect 延迟。
  • 迁移:小 cell 优先;迁移成本计入目标函数。

6.5 Effects 运行时

6.5.1 架构

EffectCell (compute worker)
   │ request
   ▼
Effect bus (tokio)
   ├── LLM adapter (provider pools, rate limit, retry)
   ├── HTTP adapter (reqwest, timeouts)
   ├── Tool adapter (WASM/process sandbox)
   └── Human adapter (queue, webhook)
   │ completion
   ▼
Owner worker (inject Result cell)
  • Compute worker 不阻塞:发出请求后继续跑其他 redex。
  • Effect bus 是多线程 tokio runtime;每个 provider 有独立的并发/速率限制。
  • 完成回调把 Result 投递到 owner 的完成队列;owner 在下一个循环注入。

6.5.2 LLM 适配器

  • Provider 抽象:OpenAI, Anthropic, Google, local (vLLM/Ollama), mock。
  • 请求:model, messages, temperature, max_tokens, tools, response_format。
  • 响应:text/tool_calls/usage/finish_reason。
  • 重试:429/5xx 指数退避 + jitter;4xx 不重试(除 408/409)。
  • 流式:SSE → Stream<Chunk>;chunk 作为消息注入;支持 early cancel。
  • 成本:按 provider 价目表计算 input/output tokens;记录到账本。
  • 缓存:可选 prompt cache(provider 支持时);本地 content-addressed cache(相同 prompt+params → 结果),带 TTL/租户隔离。
  • 安全:API key 只在 adapter 内存;日志脱敏;可配置区域端点。

6.5.3 工具适配器

  • 工具描述:JSON Schema 输入/输出;ToolCell 校验参数。
  • 执行:WASM(纯函数/轻量)、子进程(隔离)、HTTP(远程)。
  • 权限:工具能力由宿主注入;没有端口就调不到;审计每次调用。
  • 超时/资源限制:CPU/内存/网络配额;失败返回 Error。

6.5.4 人工适配器

  • 表单/审批:生成一个 URL/消息;人工决定后 webhook 回来。
  • 长延迟:不占用 worker;cell 处于 Pending;可超时/升级。
  • 审计:谁、何时、看了什么、决定了什么。

6.6 持久化与重放

6.6.1 WAL

追加记录:

Step    { seq, redex, rule, after_hash }
Effect  { job_id, op, input_hash, output_hash, output, cost, ts }
Remote  { wire, seq, payload_hash }
Checkpoint { seq, snapshot_ref, effect_offset }
  • fsync 策略:always(强一致,慢)、interval(10ms)(默认)、never(dev)。
  • 批量写:多个 step 合并成一个 record;CRC/哈希链。
  • 保留:按时间/大小轮转;冷数据归档到对象存储。

6.6.2 检查点

  • 内容:cells、wires、free ports、routing table、pending effects、effect log offset。
  • 编码:bincode/postcard + zstd;大 payload 只存引用。
  • 频率:每 10k steps / 30s / effect 边界;可配置。
  • 一致性:暂停调度(或 copy-on-write)→ 快照 → 继续;v1 用短暂 stop-the-world(< 10ms/1M cells)。

6.6.3 重放

ain replay --checkpoint cp-123 --wal wal-123 --until seq=50000
  • 加载 checkpoint;按 WAL 顺序点火;effect 从 log 注入(不重新调用)。
  • 校验每步 after_hash;不一致立即报错并 dump 差异(expected vs actual)。
  • 重放速度目标:纯计算 ≥ 10× 实时;effect 0 调用。
  • 用途:事故复现、回归测试、审计、迁移验证。

6.6.4 一致性等级

模式 保证 代价
ephemeral 无持久化 最快;崩溃丢失
at-least-once WAL + 重试 可能重复 effect;需幂等键
exactly-once-effects WAL + 幂等键 + 去重表 大多数 LLM/工具可近似
strict 同步 fsync + 2PC(可选) 慢;仅关键任务

v1 默认 at-least-once + 幂等键;文档明确"LLM 调用本身不可能 exactly-once,只能去重/记账"。

6.7 分布式调度网络

6.7.1 成员与路由

  • 静态配置(v1):nodes.toml 列出 id, addr, capacity。
  • 动态(v2):gossip(SWIM)+ 一致性哈希;节点加入/离开更新路由。
  • 路由表:agent_id/tenant → node;cell_id → node;带 epoch。

6.7.2 远程 wire

node A                         node B
Cell a ── SendProxy ──┐
                       ├── QUIC stream (ordered, credit)
Cell b ── RecvProxy ──┘
  • 每个 (net, wire) 一个双向流;消息带 seq;接收端按序注入。
  • 信用窗口:每流 N 条未 ack;满则发送端暂停(背压)。
  • 去重:接收端滑动窗口 + seq;重复丢弃。
  • 失败:流断开 → 重连 → 从最后 ack 重发;超过阈值 → Error<Network>。

6.7.3 Cell 归属与迁移

  • Owner(cell) = node;只有 owner 能点火涉及该 cell 的规则。
  • 跨节点活跃对不直接点火:消息到达 owner 后形成本地活跃对。
  • 迁移:
    1. 获取 lease(epoch+1)。
    2. 暂停该 cell 的本地交互。
    3. 序列化 cell + payload 引用 + 邻接 proxy。
    4. 目标节点恢复;更新路由;旧节点释放。
    5. 重发 in-flight 消息(按 seq 去重)。
  • Fencing:旧 owner 的写被 epoch 拒绝,防止双写。

6.7.4 故障处理

故障 检测 处理
节点崩溃 心跳超时 lease 过期;supervisor 从 checkpoint 重启受影响的 agent
网络分区 心跳/租约 默认 CP:少数派停止写入;返回 Error<Partition>
消息丢失 ack/超时 重发;幂等键去重
磁盘满 监控 降级到 ephemeral;告警
Effect provider 故障 错误率/超时 重试/降级模型/人工

6.7.5 弹性

  • Scale out:新节点加入 → 迁移部分 cell → 更新路由。
  • Drain:节点标记 draining → 停止新调度 → 迁移 → 退出。
  • 热点:按队列深度/交互频率触发迁移;限制迁移带宽。

6.8 可观测性

6.8.1 Trace 事件

{
  "seq": 12345,
  "ts": "2026-11-10T12:00:00.123Z",
  "node": "n1",
  "worker": 3,
  "net": "research/abc",
  "redex": ["c17", "c42"],
  "rule": "Researcher_Idle__Task",
  "before": "sha256:...",
  "after": "sha256:...",
  "delta": { "add": [...], "remove": [...], "rewire": [...] },
  "effect": null,
  "cost": { "interactions": 1, "usd": 0 }
}
  • 小网存 full snapshot;大网存 delta + 周期性 snapshot。
  • trace_id 贯穿 agent/effect/remote;OpenTelemetry span link。

6.8.2 指标

  • ain_interactions_total{node,rule}
  • ain_redex_queue_depth{node,worker}
  • ain_effect_latency_seconds{provider,op}
  • ain_effect_cost_usd_total{tenant,agent}
  • ain_replay_divergence_total
  • ain_cells{node}, ain_memory_bytes{node}

6.8.3 调试器

  • ain trace view <trace> 启动本地 Web UI:
    • 网图(复用 Netbook 渲染器)
    • 时间线/因果链
    • 过滤:agent、rule、effect、cost
    • 对比:两次 run 的 diff(模型/prompt/调度)
  • 与 Netbook 共享 ain-wasm,保证渲染一致。

6.9 安全

层 机制
能力 端口即能力;没有全局工具表;工具 capability 由宿主显式注入
撤销 断线/发送 Revoke;EffectCell 检查 token epoch
沙箱 用户规则编译到 WASM;无文件/网络/环境变量,除非显式 capability
租户隔离 进程/WASM 隔离;CPU/内存/网络配额;静态加密
审计 追加日志:谁、哪个 agent、哪个 capability、输入/输出 hash、成本
数据溯源 消息带 provenance(来源 agent、工具、文档);策略 cell 可隔离不可信内容
Prompt injection 最小权限 + 数据/指令分离 + 策略 cell(拒绝外发敏感数据)
密钥 只在 adapter 内存;不进入网/trace;可接 KMS/Vault

为什么端口即能力很重要:在传统框架里,Agent 拿到一个全局 tools 对象,prompt injection 可以诱导它调用任意工具。AIN 里,Agent 只能沿它被接上的线发送消息;没有线就没有能力。这是结构性安全,不是靠 prompt 说"不要这样做"。

6.10 性能模型与基准

6.10.1 成本模型

T_total ≈ max(
  Σ_interactions / throughput,
  critical_path × interaction_latency,
  Σ_effect_latency / effect_concurrency,
  network_bytes / bandwidth
) + scheduling_overhead + GC_pause
  • 纯网:交互数 × 单交互成本;work stealing 开销 < 5%。
  • Agent:effect 延迟主导;调度器要保证关键路径上的 effect 优先。
  • 分布式:跨节点 wire 数量 × 消息率;放置优化目标是最小化跨节点边。

6.10.2 基准套件

类别 用例 指标
纯网 fib(30)、bitonic sort 1M、Church 2^20、树遍历 MIPS、内存、扩展比
λ Church numeral、Y 组合子、列表 map/filter 交互数 vs 朴素 λ
Agent 100 任务流水线、50 扇出、10 竞速、故障注入 msg/s、p99、成本
重放 1k 次重放一致性 一致率、速度
分布 3/10/50 节点、迁移、节点故障 恢复时间、跨节点流量
安全 越权调用、能力撤销、沙箱逃逸 拦截率(应为 100%)

6.10.3 对比基线

  • HVM4:纯网/IC 性能。
  • Inpla:多线程交互网。
  • Temporal:durability/重放(概念对比,不是同类)。
  • LangGraph:Agent 编排吞吐/成本(同类场景)。

6.11 部署形态

形态 说明 阶段
单二进制 aind + ain CLI;本地/SQLite WAL v1
容器 Docker image;K8s Deployment/StatefulSet v1
嵌入式库 ain-runtime 作为 Rust crate;napi/PyO3 绑定 v2
托管控制面 多租户、UI、计费 v3(可选)

配置示例:

# aind.toml
[node]
id = "n1"
listen = "0.0.0.0:7000"
workers = 8

[storage]
wal = "/var/lib/ain/wal"
checkpoint_interval = "30s"
fsync = "interval:10ms"

[effects.llm]
providers = ["openai", "anthropic"]
max_concurrency = 64
default_budget_usd = 0.50

[cluster]
nodes = ["n1@10.0.0.1:7000", "n2@10.0.0.2:7000", "n3@10.0.0.3:7000"]
placement = "consistent-hash"

6.12 风险与缓解

风险 缓解
原子链接的 ABA/内存回收 epoch + generation;压力测试;参考 HVM2
大 payload 复制 Arc + 外置 store;消息只传引用/hash
Effect 长尾 优先级 + 超时 + 降级模型;隔离 provider
重放不一致 每步 hash 校验;effect log 不可变;CI 跑 1k 次
分布式调试困难 trace 全局 id;单机 deterministic 模式复现
安全漏洞 能力模型 + WASM 沙箱 + 审计;第三方渗透测试
复杂度失控 v1 只做单机 + 静态 3 节点;分布式特性按需开启

在 GitHub 编辑本文