核心概念
| 概念 | 一句话说明 |
|---|---|
| Workbook | 工作容器(≠ 文件)。把表、Sheet、版本与策略捆在一起 |
| Source | 上传的原件(immutable)。auto(全自动)/ staged(analyze → 修正 parse-spec → materialize 的显式控制) |
| Table | 带类型、带行 ID、有版本管理的数据集,Agent 的主要操作对象。分为 base(可编辑)与 derived(transform 的输出) |
| Transform | SQL(Jinja2)/ Python 模板。用 args 把 {{ arg }} 绑定到输入表,生成输出 artifact。lineage 的基本单位 |
| Sheet | 不持有数据的展示用 composition。由 blocks 引用表(n:m),render 时合成为 xlsx |
| Chart | Agent 创建的图表。持有 config 与 recipe(生成时使用的工具和参数) |
| Version | versions.commit(label) = 指向 snapshot 的不可变标签。revert 通过 snapshot 机制(重新执行 DAG)恢复派生表 — base 表的行编辑由 edits 日志侧的历史管理 |
| Job | 异步操作的句柄(async=true 上传等)。用 jobs.wait() 或 webhook job.completed |
| Workspace | 边界对象(成员、计费、治理)。开发者可以用 Account API key 管理多个 workspace |
行编辑与乐观锁
Section titled “行编辑与乐观锁”所有写入都必须携带 expected_version(表的 etag)。不一致时返回 409 — SDK 抛出 ConflictError。不会自动重试(为了不悄悄覆盖并发编辑):契约是重新读取(rows() 会返回 edit_version)→ 重新应用改动 → 重试。
page = client.tables.rows(wb, "sales")client.tables.upsert_rows( wb, "sales", rows=[{"__d2b_row_id": 3, "amount": 999}], # row_id present = update, absent = insert expected_version=page["edit_version"],)SDK 会为所有变更调用自动附加 Idempotency-Key(相同 key + 相同 body 时重放首次响应)。网络重试不会导致重复应用。直接调用 HTTP 时请自行附加该 header。
晋升模型(raw 不会悄悄消失)
Section titled “晋升模型(raw 不会悄悄消失)”auto 摄取从忠实导入工作表的原始表出发,生成 D2B 结构化后的表。结构化后的表接管文件名,原始表降级为 state=archived(registry 与 lineage 保留)。通过 tables.lineage() 可以追溯到原始表,必要时可用 tables.unarchive() 重新实体化原始工作表。使用 structuring=defer 时原始表先落地,结构化完成时发生同样的晋升;如果届时已经在原始表之上创建了派生物,晋升会自动放弃(不破坏下游)。
新鲜度(staleness)
Section titled “新鲜度(staleness)”行编辑等交互式写入不会立即重算下游派生表,而是打上 stale 标记。通过 GET .../tables/{name} 的 freshness: {stale, stale_since} 可以看到,并用 POST /workbooks/{id}/recompute(MCP recompute_stale)按依赖顺序批量重算。transform 的执行会 eager 地传播(输出始终是新鲜的)。
列标签 × 角色的策略(mask / deny)在数据层强制执行。被 mask 的列以带类型的 NULL 返回,并通过 masked_columns 告知。可以用 GET .../tables/{name}/access 提前 dry-run。export、profile、MCP 乃至原始文件 preview 生效的都是同一套策略,不存在绕行通道(在 governed workbook 中,针对原始字节的 preview / revise 会被拒绝)。
行级 JSON Schema(用于 constrained decoding)
Section titled “行级 JSON Schema(用于 constrained decoding)”静态的 OpenAPI 无法为表的内容建立类型(行的形状依赖数据)。因此可以在运行时获取每个表”单行的 JSON Schema”:
GET /api/v1/workbooks/{wb}/tables/{name}/schema?format=json-schema在 MCP 中是 get_schema(..., include_json_schema=true)。返回的 schema 基于应用列策略后的列集合生成(deny 的列不会出现),additionalProperties: false、所有单元格 nullable、__d2b_row_id 的语义是”省略 = insert / 指定 = update”。Agent harness 可以用它在生成阶段约束 upsert_rows 的 payload(constrained decoding)。
- snapshot: 不可变的 commit。
POST /snapshots/POST /snapshots/{id}/restore - version: 指向 snapshot 的名字(
POST /versions、POST /versions/{label}/revert) - op log: 按顺序记录所有变更(
GET /ops)。行 op 可通过POST /ops/{id}/undo逆向应用(历史为 append-only) - branch / merge:
POST /export加record_branch=true冻结导出时点的行,编辑后的文件用POST /tables/{name}/merge做以行 ID 为键的单元格级 3-way merge。两侧都改动的单元格进入 conflict 队列