FlowSpec v1(draft)
M2 的单机执行声明。文本 Ainet 编译器在 M3;本 spec 是它的目标 IR。
1. 形状
{
"version": 1,
"id": "research-pipeline",
"agents": [
{ "id": "researcher", "kind": "researcher", "config": { "model": "mock-fast" } },
{ "id": "critic", "kind": "critic", "config": { "model": "mock-strong" } },
{ "id": "writer", "kind": "writer", "config": { "model": "mock-fast" } }
],
"edges": [
{ "from": "researcher", "port": "out", "to": "critic" },
{ "from": "critic", "port": "out", "to": "writer" }
],
"budget": { "usd": 0.10, "tokens": 10000, "steps": 100 },
"input": {
"to": "researcher",
"tag": "task",
"payload": { "question": "How do interaction nets help multi-agent systems?" }
}
}
字段:
| 字段 | 类型 | 说明 |
|---|---|---|
version |
1 |
当前唯一版本 |
id |
string | flow 名称 |
agents[].id |
string | 唯一;运行时按字典序调度 |
agents[].kind |
string | 行为注册名(researcher/critic/writer/…) |
agents[].config |
any | 行为配置(模型、温度等) |
edges[] |
{from,port,to} |
发送端口 → 下游 agent;无 edge 的端口是终端输出 |
budget |
{usd,tokens,steps} |
可选;steps=0 表示不按步数限制 |
input |
{to,tag,payload} |
可选;启动时投递的第一条消息 |
2. 消息
type Message = { tag: string; payload: any; from?: string };
from由运行时填写(发送者 id;effect 响应为"effect")。- 每个 agent 的 inbox 是 FIFO;运行时每次只取队首。
- 发送到没有 edge 的端口 → 进入
outputs["<agent>.<port>"]。
3. 调度
M2 是单线程确定性调度:
- 按
agent.id字典序遍历,选第一个 inbox 非空的 agent。 - 取队首消息,调用其 behavior。
- 应用状态;先发送所有
send,再执行 effect(若有)。 - effect 响应入同一 agent 的 inbox(tag
"effect")。 - 重复直到所有 inbox 为空 / 错误 / step 上限。
这保证同一 spec + 同一 behavior/effect 实现 → 同一事件序列与最终 state hash。
4. Effects
- behavior 返回
EffectRequest { op, input };运行时同步调用EffectBus。 - M2 内置:
llm(mock)、search(mock)。 - 响应:
EffectResponse { output, usage };usage = { input_tokens, output_tokens, usd }。 - 账本按 effect 累加;超过 budget 返回
BudgetExceeded。 - 真实 provider 的超时/重试/流式在 M3。
5. Trace 与重放
事件(JSON array;crates/ain-runtime/src/runtime.rs):
type Event =
| { type: "receive"; step; agent; message }
| { type: "act"; step; agent; state; send; effect? }
| { type: "send"; step; from; port; to?; message }
| { type: "effect"; step; agent; request; response; usage }
| { type: "error"; step; agent?; error }
| { type: "finish"; steps; state_hash; ledger; outputs };
重放:
- 从
effect事件提取(request_hash, response)。 - 重置 flow;按同样调度重跑;effect 请求必须与记录逐一匹配。
- 结束后比较
state_hash/ outputs。
6. State hash
sha256(canonical_json({agents, outputs, ledger})),其中 agents 包含 id/kind/state/inbox/ports。
用于:
- 重放一致性校验。
- 回归测试(固定 hash)。
- 未来的检查点/迁移。
7. 限制(M2)
- Agent 通信是运行时信箱,不是 net wire;session-typed channel 在 M3。
- Effect 同步执行;真实 provider 的异步/取消/流式在 M3。
- 没有 fsync WAL/检查点;trace 以 JSON 文件保存,重放从文件加载。
- 没有类型检查;
FlowSpec只校验 id/edge/target/behavior 存在。 - 没有
par/race/supervise;M3 加。
8. 版本
version: 1。- 新增可选字段 → minor;改变调度/消息语义 → major。
- 测试向量:
examples/research-pipeline.json+examples/research-trace.json。