11 · M3:Ainet Flow 语言层
状态:M3a(语言)核心完成(2026-11)。M3b(并行/调试/真实 effects)仍在后续。
11.1 完成了什么
新增 crates/ain-lang:
| 模块 | 内容 |
|---|---|
lexer.rs |
标识符/字符串/数字/符号;// 注释;行/列跟踪 |
parser.rs |
flow/budget/agent/edge/input;JSON-like value(对象/数组/字符串/数字/布尔/null) |
ast.rs |
带位置信息的 AST |
compile.rs |
AST → FlowSpec;重复 id/未知 kind/未知 edge 目标/重复出边/input 目标/可达性警告 |
diag.rs |
Diagnostic { severity, code, message, line, column } + 源码 caret 渲染 |
CLI:
ain check examples/research.flow
ain flow compile examples/research.flow
ain flow run examples/research.flow
ain flow run/replay 现在同时接受 .flow(先编译)与 .json(FlowSpec)。
11.2 示例
examples/research.flow:
flow Research {
budget { usd: 0.10, tokens: 10_000, steps: 100 }
agent researcher = researcher(model: "mock-fast")
agent critic = critic(model: "mock-strong")
agent writer = writer(model: "mock-fast")
researcher.out -> critic
critic.out -> writer
input researcher {
tag: "task",
question: "How do interaction nets help multi-agent systems?"
}
}
运行:
$ ain check examples/research.flow
ok: flow Research · 3 agents · 2 edges
$ ain flow run examples/research.flow
flow=Research steps=7 state=cb15b135...
ledger={"input_tokens":282,"output_tokens":115,"usd":0.0003215,"effects":4,"steps":7}
output writer.out=[{"tag":"final",...}]
与 JSON research-pipeline.json 得到同一个 state hash(cb15b135...),说明编译结果等价。
11.3 诊断
$ ain check bad.flow
error[E-EDGE-TARGET] 3:3: edge target `missing` is not a declared agent
a.out -> missing
^
- 解析错误:
E-PARSE-01,带行/列与 caret。 - 语义错误:
E-DUP-AGENT、E-KIND、E-EDGE-SOURCE/TARGET、E-DUP-EDGE、E-INPUT-TARGET、E-BUDGET-01。 - 警告:
W-UNREACHABLE(从 input 不可达的 agent)。 - 缺
)时会尝试把后面的agent识别为"缺少)",避免误报为字段错误。
11.4 测试
crates/ain-lang/tests/flow.rs(8 个):
- 编译 Research 示例;字段/预算/input 正确。
- 编译后直接交给
ain-runtime运行,输出writer.outfinal。 - 解析错误带位置。
- 未知 edge 目标、重复 agent、未知 kind。
- FlowSpec JSON round-trip。
- 不可达 agent 警告。
11.5 与 M3 规格的差异
M3 原路线图的另一半(并行/调试)没有在这个切片完成:
| 项目 | 状态 |
|---|---|
| Ainet Flow 文本 DSL | ✅ |
| FlowSpec 编译 + 诊断 | ✅ |
ain check / flow compile |
✅ |
| 类型检查(线性/session/effect row) | ⏳ |
effect/type/session 声明 |
⏳ |
par/race/timeout/supervise |
⏳ |
| session-typed net channels | ⏳ |
| 真实 LLM/HTTP/tool effects | ⏳ |
| WAL/checkpoint/崩溃恢复 | ⏳ |
| 并行 runtime(work stealing) | ⏳ |
ain trace view / Netbook 第 4–5 章 |
⏳ |
11.6 下一步
- 类型层:
effect声明 + agent effect row;budget与 effect 的绑定;端口/session 类型。 - 控制流:
par/race/timeout/supervise编译到 FlowSpec 的调度子图。 - 运行时:真实 effects(provider/HTTP/tool)+ 超时/取消/重试。
- 持久化:append-only WAL + checkpoint;崩溃恢复。
- 并行:多 worker + work stealing;把
ain-core的纯网 reducer 接进来。 - 可视化:
ain trace view复用 Netbook 渲染器;Netbook 第 4–5 章。
11.7 M3b 追加(同一天完成)
Effect rows
AgentSpec.effects: Option<Vec<String>>(None= 旧 spec 不约束;Some([])= 禁止 effect)。DSL:
agent researcher = researcher(model: "mock-fast") effects { search, llm } agent critic = critic(model: "mock-strong") effects { llm }ain check校验 effect 名(未知 →E-EFFECT)。运行时在
perform_effect前检查 allowlist;未声明 →UndeclaredEffect。测试:
undeclared_effect_is_rejected、unknown_effect_is_reported。Edge protocol labels:
researcher.out -> critic : draft编译为EdgeSpec.protocol;运行时校验消息 tag(ProtocolViolation)。这是单消息 session 的轻量版。
WAL / checkpoint
ain-runtime/src/journal.rs:Journal:append-only JSONL;sync()调用sync_data()。load_events:读回事件(用于 replay)。Checkpoint:version/flow/step/agents/outputs/ledger/state_hash;写/读 JSON。
- Runtime:
enable_journal(path):运行中逐事件写入。save_checkpoint/restore_checkpoint:含 inbox,恢复后继续运行。
- CLI:
ain flow run ... --journal <path> --checkpoint <path>ain flow resume <flow> <checkpoint>
- 测试:journal replay 同 state hash;mid-run checkpoint 续跑到同一结果;checkpoint 磁盘 round-trip。
真实 effects
HttpEffect(ureq):{method,url,headers,body}→{status,body}。ShellEffect:只允许 allowlist(默认echo/printf),{cmd,args}。EffectBus::with_standard()= mock llm/search + http + shell。- CLI
--real-effects使用 standard bus。 - 测试:本地
TcpListenerHTTP round-trip;shell allowlist 执行/拒绝。
并行批处理
ain-runtime::parallel::run_batch(specs, workers):独立 flow 的 worker pool;结果按输入顺序。- CLI
ain flow bench <flow> --repeat N --workers W。 - 测试:8 个 flow × 4 workers 与顺序执行 state hash 全等。
- 说明:这是批级并行;单个 flow 内的 net-level work stealing 仍需线程安全 cell heap(后续)。
Trace viewer
ain flow trace-view <trace.json> --out view.html:生成自包含 HTML(无外部依赖)。- 事件按类型过滤;effect/error/finish/send 颜色;finish 显示 steps/state/ledger。
- 适合
browser.preview或直接打开。 - Netbook 也有
/trace页面:内置research-trace.json,支持播放/单步/类型筛选,复用同一份 trace。
测试总数:51(26 core/golden + 9 language + 16 runtime)。