ΓDocsInteractiveNet

03 · Netbook:可视化交互网页规格

轨道 A 的产品规格。目标不是"做一个交互网百科",而是让读者在动手过程中建立正确的心理模型:计算是局部的图重写;复制/擦除是结构;并发是独立 redex 的集合;Agent 是带协议的 cell。

3.1 受众与场景

Persona 背景 来 Netbook 想解决什么 成功信号
CS 学生 学过 λ 演算/数据结构 听说交互网是最优归约的基础,但论文看不懂 能独立构造并解释一张网;能说明为什么共享能省工作
PL 研究者/工程师 写编译器/运行时 想快速验证一个编码/规则 能在 sandbox 里编辑规则、导出 trace
AI 工程师 用 LangGraph/AutoGen 想知道"以图为语义"的 Agent 编排有什么不同 能搭一个 3 Agent 网,看懂消息/成本/重放
教师 讲计算理论/函数式编程 需要可演示的课堂材料 能投影、能离线、能分享 permalink

非目标:不服务"只想看结论"的读者;不替代论文;不做视频课程。

3.2 学习路径与章节

三种模式:

  • Learn:按章引导,锁定部分交互,有检查点。
  • Play:自由 sandbox,所有 Agent/规则开放,可导入导出。
  • Lab:实验性章节(最优归约对比、并发调度、Agent 成本),允许改参数/跑基准。

章节表

# 标题 核心概念 交互组件 章末挑战
0 计算的另一种写法 重写系统、局部性 字符串重写器 → 图重写器 用 3 条规则把 SKK 归约到范式
1 Agent、端口、线 cell、principal/aux、wire、interface 拖拽搭建第一张网 给定额度,搭出指定接口的网
2 活跃对与规则 active pair、点火、局部重写 规则播放器 + "预测下一步" 补全一条规则,使网到达指定范式
3 三个组合子就够了 γ/δ/ε、湮灭/交换/擦除、通用性 组合子实验室(随机网 + 单步) 用 γ/δ/ε 实现布尔 XOR
4 把 λ 算进来 抽象/应用/变量、β 归约 λ→网 编译器 + 左右对照 编译并归约一个 Church numeral
5 共享与最优 复制、共享图、Lévy 最优、括号 naive vs sharing 双跑 + 计数 让 fib(10) 的交互数下降 ≥ 5×
6 类型与线性 线性逻辑、proof net、极化 线性检查器 + "能否复制这根线" 修一张违反线性的网
7 并发与调度 redex 图、独立集、work stealing N worker 调度可视化 + 合流检查 在 4 worker 下达到接近关键路径的下界
8 从网到 Agent 状态 cell、消息、工具、effect、预算 3 Agent 流水线(mock LLM)+ 成本表 加一个 Critic,使质量分 ≥ 阈值且预算不超
9 自己造一个网 综合 自由 sandbox + 挑战库 提交一个可复现的网/规则包

每章结构统一:

  1. Hook(1 段):一个反直觉的问题/现象。
  2. Concept(2–4 段 + 图):最小必要定义。
  3. Play(核心交互):读者必须动手才能继续。
  4. Explain(1–2 段):把刚才的操作映射回定义。
  5. Quiz(2–3 题):即时反馈,错的选项解释为什么错。
  6. Deep dive(可选折叠):论文引用、形式定义、边界情况。

章节设计要点

  • 第 0 章不出现"交互网"这个词:先让读者体验"重写";第 1 章才命名。
  • 第 1 章先限制为树:避免一开始就遇到环/共享;第 3 章再引入一般图。
  • 第 2 章必须让读者"预测":看规则 → 预测结果 → 点火验证;预测错误时高亮差异。
  • 第 3 章用"三规则"闭环:每个规则至少手动点火 3 次,直到形成直觉。
  • 第 4 章不教完整 Lamping:先给简化编码(LAM/APP/SUP/DUP),把括号/最优留到第 5 章。
  • 第 5 章的对比必须用同一台引擎、同一输入:只改共享策略,显示交互数/最大并行度/时间。
  • 第 6 章用"能否复制"作为钩子:让读者亲手制造一个违反线性的网,看到类型错误。
  • 第 7 章把调度器做成可拖拽的:读者可以把 redex 拖到不同 worker,观察关键路径。
  • 第 8 章用 mock LLM:默认离线、确定性;可选 BYO key(经代理),并显示 token/成本。
  • 第 9 章提供 6–8 个挑战:排序网、加法器、布尔电路、map/reduce、会话协议、监督树。

3.3 核心交互组件

3.3.1 Net Canvas

功能:

  • 平移/缩放(触控板、滚轮、触屏)。
  • 拖拽 cell;拖动端口拉线;吸附到最近合法端口;非法连接给出原因(类型不匹配/已占用/方向错误)。
  • 选中、框选、删除(连带擦除/悬空线处理)、复制子网(自动重命名端口)。
  • 自动布局:小图用分层(Sugiyama),大图/有环用力导向;可 pin 住节点。
  • 高亮:hover 显示 cell 类型/端口类型;选中显示可达子网;活跃对脉冲高亮。
  • 规则点火动画:LHS 高亮 → ghost 残影 → 新 cell 展开 → 线重接;可调速度/关闭。
  • 时间旅行:底部 slider,拖到任意 step;显示该步的 before/after diff。

实现:

  • PixiJS 8(WebGL)渲染 cell/线/动画;SVG 覆盖层负责可访问性与文本。
  • 自研布局(不引入 React Flow):端口级连接、活跃对高亮、几千节点性能。
  • 场景图分层:background grid → wires → cells → ports → overlays → labels。
  • 线的绘制:三次贝塞尔;端口切线方向由端口角度决定;避免穿过 cell(简单避障)。
  • LOD:缩放 < 0.4 时只画点/线;> 0.8 显示标签;> 1.2 显示端口名。

3.3.2 Rule Player

  • 显示当前活跃对、匹配的规则、变量绑定。
  • 按钮:Step、Step over(一次把一个 agent 的所有交互跑完)、Run、Pause、Reset。
  • 速度:0.25×–8×;可单步到下一个"有趣"事件(规则类型变化/共享节点出现)。
  • 断点:按 agent 类型、规则名、交互数、是否产生 δ/ε。
  • "为什么"面板:解释这条规则为什么匹配(类型/端口/标签),以及点火后哪些线被重接。

3.3.3 λ → Net 编译器

  • 输入:无类型 λ 项(支持 named terms、Church numerals、let、if)。
  • 输出:网 + 逐步 β 归约对照。
  • 左侧 λ 项高亮当前 redex;右侧网高亮对应活跃对。
  • 支持 call-by-name / call-by-need / 最优(Lamping 简化版)三种策略切换。
  • 显示:交互数、β 步数、共享节点数、最大并行度。
  • 错误:自由变量、非终止(fuel 用完)给出友好提示。

3.3.4 Sharing Lab

  • 同一程序两栏:naive(无共享)vs sharing(δ 节点)。
  • 实时计数器:交互数、分配 cell 数、峰值内存、最大并行度、关键路径。
  • 预设:fib、Church exponentiation、列表 map、树遍历。
  • "解释这一差距":点击计数展开,显示哪些子网被共享/复制。

3.3.5 Concurrency Lab

  • 可调 worker 数(1–16)、调度策略(FIFO/随机/关键路径优先)。
  • 可视化:每个 worker 的队列、偷取事件、活跃对颜色。
  • 指标:makespan、总交互数、并行效率、idle 时间。
  • 合流检查:不同调度跑同一程序,比较最终网 hash;不一致则红色警告(应只发生在 effect 章节)。

3.3.6 Agent Lab

  • 画布上预置 agent cell:Researcher、Critic、Writer、Tool(search)、LLM。
  • 消息是网上的 token;拖拽/连线构建流水线。
  • 运行:mock LLM(内置 5 个确定性响应)或 BYO key(经本地代理;key 不落库)。
  • 面板:消息时间线、每个 agent 的 state、token/成本、重放按钮。
  • 挑战:在预算内达到质量阈值;加一个 supervisor 处理 tool 失败。

3.3.7 Sandbox

  • 完整编辑器:自定义 agent(名称/端口/状态)、规则(图形化或文本)、初始网。
  • 文本模式:直接写 Netbook IR(JSON 或简化 DSL),与图形双向同步。
  • 导入/导出:JSON、PNG、SVG、分享链接。
  • 校验:类型/线性/端口匹配;错误定位到图元素。
  • 性能保护:cell 上限(如 20k)、交互上限(fuel)、Web Worker 中运行。

3.3.8 Quiz

  • 题型:单选、多选、排序(归约步骤)、连线(端口→类型)、预测(下一步图)。
  • 反馈:不只对错,显示"你的答案会导致哪条规则/哪根线出错"。
  • 进度:localStorage;可选账号(v2)。

3.4 视觉与动效规范

元素 规范
Agent 圆形/圆角矩形,直径 44–56px;principal port 用实心三角/凹槽标识;aux 用小圆点
颜色 γ 蓝、δ 绿、ε 灰、用户 agent 用色板(色盲安全);活跃对用琥珀色脉冲
线 2px,选中 4px;高亮时加外发光;不同数据类型可用虚线/颜色(可选)
动画 点火 240ms ease-out;ghost 120ms;新节点 180ms scale-in;支持 prefers-reduced-motion
字体 正文 Atkinson Hyperlegible / 思源黑体;代码 JetBrains Mono
布局 左侧课程导航(可折叠),中间画布,右侧解释/检查器;移动端上下堆叠
深色模式 默认跟随系统;画布颜色对比度 ≥ 4.5:1

3.5 技术架构

Astro 7 (static) + islands
├── Svelte 5 components
│   ├── LessonShell / MDX renderer
│   ├── NetCanvas (PixiJS 8)
│   ├── RulePlayer / Timeline
│   ├── LambdaEditor (CodeMirror 6)
│   ├── Quiz / Progress
│   └── AgentLab
├── ain-wasm (Rust → wasm-bindgen)
│   ├── Net IR / reducer / trace
│   ├── λ parser + encoder
│   └── layout hints / metrics
├── MDX content (zh/en)
├── KaTeX (inline math)
└── Service Worker (offline)

选择理由:

  • Astro:内容为主、islands 按需加载;首屏轻;适合 MDX 课程。
  • Svelte 5:细粒度响应式,画布 UI 状态简单;与 Astro islands 成熟。
  • PixiJS:WebGL 批渲染,几千 cell 稳定 60fps;比 SVG/DOM 更适合动画。
  • Rust/WASM:与生产运行时同一内核;性能足够;可离线。
  • 不用 React Flow:端口级交互、规则动画、性能都不匹配;自研成本可控。
  • MDX + 结构化 lesson JSON:散文与交互分离;交互状态可序列化/测试。

状态管理

  • WASM 侧:网状态、归约、trace、指标;暴露 step(), runUntil(), snapshot(), restore()。
  • Svelte 侧:UI 状态(选中、缩放、面板、进度);用 runes($state/$derived)。
  • URL:lesson id + step + 压缩后的网快照(lz-string);刷新可恢复。
  • 持久化:IndexedDB 存 sandbox 草稿;localStorage 存进度。

内容管线

content/zh/ch03.mdx
content/en/ch03.mdx
content/lessons/ch03.json   # 交互组件配置、初始网、挑战、quiz
        │
        ▼ build-time validation (Zod + golden traces)
dist/ 静态页面 + wasm + assets
  • 每个交互组件由 lesson.json 驱动;MDX 只负责叙述与嵌入。
  • 构建时跑 golden trace:初始网 + 规则 → 期望的 step 序列/最终 hash;不一致则构建失败。
  • 引用检查:每个"事实性"段落带 source 字段;缺失则 lint 警告。

3.6 数据模型

type PortRef = { cell: CellId; port: number };

type Cell = {
  id: CellId;
  type: string;          // "gamma" | "delta" | "epsilon" | "user:Planner" ...
  state?: unknown;       // 用户 agent 的状态(JSON)
  label?: number;        // δ/γ 标签
  x: number; y: number;  // 布局
  pinned?: boolean;
};

type Wire = { a: PortRef; b: PortRef };

type NetSnapshot = {
  cells: Cell[];
  wires: Wire[];
  free: PortRef[];
  meta?: { fuel: number; step: number; hash: string };
};

type Step = {
  index: number;
  redex: [CellId, CellId];
  rule: string;
  before: NetSnapshot;
  after: NetSnapshot;
  bindings: Record<string, unknown>;
  metrics: { interactions: number; cells: number; maxParallelism?: number };
  effect?: EffectEvent;
};

type Trace = {
  version: 1;
  program: string;
  initial: NetSnapshot;
  steps: Step[];
  finalHash: string;
};

type Lesson = {
  id: string;
  chapter: number;
  locale: "zh" | "en";
  title: string;
  objectives: string[];
  blocks: Block[];
  quiz: QuizItem[];
  sources: SourceRef[];
};

type Block =
  | { type: "prose"; md: string }
  | { type: "net"; initial: NetSnapshot; rules: string[]; goal?: Goal }
  | { type: "sandbox"; limits: { cells: number; fuel: number } }
  | { type: "compare"; program: string; strategies: Strategy[] }
  | { type: "agentLab"; scenario: string; budget?: Budget };

Trace 是唯一事实来源:动画、计数器、分享、测试都从它派生。

3.7 内容正确性与测试

  1. 参考实现:ain-core 的朴素解释器(Rust)作为 oracle;WASM 是同一代码的编译产物。
  2. Golden traces:每个章节的初始网/规则 → 期望 trace(step 数、最终 hash、关键中间态)。
  3. 属性测试:
    • 随机网 + 随机规则 → 不同归约顺序得到同一范式(纯子集)。
    • 编码/解码 λ 项 → 归约结果与参考 λ 解释器一致。
    • 线性检查器:随机网 → 违反线性的网必须被拒绝。
  4. 规则覆盖:γ/δ/ε 的 4 类规则 × 端口排列组合,逐一快照测试。
  5. 内容审校:每章至少一位外部审校(PL/数学背景);引用可点击;术语表统一。
  6. 可访问性测试:axe-core + 键盘走查;画布提供文本描述("当前有 3 个活跃对...")。

3.8 性能与可访问性预算

指标 目标
首屏 HTML+CSS+JS(不含 WASM) < 300KB gzip
WASM < 600KB gzip
TTI(M1 MBA / 4G 模拟) < 2.5s
2,000 cells / 5,000 wires ≥ 55fps(M1)
单步延迟 < 16ms(P95)
内存(10k cells) < 200MB
离线 全部课程 + sandbox 可用
WCAG AA;画布有键盘替代;动画可关闭

3.9 MVP 与 v1 范围

MVP(M1,约 6 周)

  • 第 1–3 章 + sandbox(组合子)。
  • Net Canvas(拖拽/连接/点火/单步/重置)。
  • WASM 引擎(γ/δ/ε + 用户二元 cell)。
  • 中/英各 1 套文案;部署到 Cloudflare Pages。
  • Golden trace 测试 + 规则覆盖测试。

v1(M5,约 6 个月)

  • 第 0–8 章 + 第 9 章挑战库。
  • λ 编译器 + Sharing Lab + Concurrency Lab + Agent Lab(mock)。
  • 时间旅行、断点、permalink、离线、深色模式、移动端。
  • 外部审校 + 可访问性审计。
  • 可选的"课堂模式"(教师锁定章节/隐藏答案)。

3.10 风险与缓解

风险 缓解
范围膨胀(变成通用图编辑器) 只做教学需要的交互;sandbox 功能按章节递进解锁
数学/规则错误 参考实现 + golden trace + 外部审校;每个规则有出处
动画性能 PixiJS + LOD + Web Worker;超过阈值切换"简化渲染"
内容枯燥 每章先给反直觉问题;动手优先于定义;挑战即时反馈
LLM 成本/隐私 默认 mock;BYO key 只存内存;代理不记录 prompt
移动端体验 画布手势优先;关键交互提供按钮替代;不追求完整编辑

3.11 与轨道 B 的接口

  • ain-wasm 的 API 即 Netbook 的引擎 API;文档在 specs/wasm-api.md。
  • Trace 格式即生产调试器的格式;Netbook 的"时间旅行"复用于 aind 的 trace viewer。
  • 第 8 章的 Agent 示例用 Ainet Flow 的语义(mock 运行时),确保概念一致。
  • 第 9 章的挑战可以作为 examples/ 的测试用例。

3.12 M1 实现状态(2026-11)

已落地(apps/netbook):

  • 第 1–3 章 + Sandbox,数据驱动(src/lib/lessons.ts),不是 MDX;内容与交互分离的边界保留。
  • PixiJS 画布:渲染、拖拽 cell、端口连线、点击已连接端口断开、缩放/平移、选中/删除。
  • 确定性力导向布局(src/lib/layout.ts);拖拽位置保留;分享链接包含布局。
  • Step/Run/Reset、活跃对高亮、点火 flash、trace chips + 右侧 trace 列表。
  • 任务校验:基于当前网、交互数、累计规则集(rulesSeen)。
  • Undo/Redo(按网快照);permalink(URL hash,base64 JSON)。
  • Golden trace:crates/ain-core/tests/golden.rs 锁定 M1 两个 demo 的最终 hash。

与规格的差异 / 顺延:

  • 规格写"MDX + lesson JSON";M1 先用 lessons.ts + Astro 单页,M2 再引入 MDX 内容管线。
  • 规格写"分层布局";M1 用力导向,分层留到 M2(小图效果已够)。
  • 时间旅行/断点/速度控制、规则编辑器、英文文案顺延到 M2。
  • 自由端口仍是 cell 端口;接口保持(free-standing endpoint)在 M2 修。

在 GitHub 编辑本文