跳转到内容

从编码智能体使用 D2B

D2B 为智能体提供两条路径。MCP(工具调用:Claude Code / Claude Desktop / Cursor / VS Code 等)和 CLI(d2b:由 shell 驱动的智能体、git 同步、批处理)。两者暴露同一套接口:JSON 输出、带 suggested_fix 的错误、每次变更都有幂等键、没有交互式提示。

运行规范由服务器下发。 通过 MCP 连接时,初始化响应中的 instructions 包含「用哪个工具、按什么顺序」的规范,同样的文本也可作为资源 d2b://guide 读取。不需要把冗长的步骤贴进仓库,只贴连接方式和路径选择(见下)。

  1. 签发最小权限的 PAT — 交给智能体的令牌建议限定到 workbook 并带速率上限(若要委托整个工作区,使用 "resource": "workspace:<WS_ID>";创建也会固定在该工作区。令牌始终属于一个账户,省略 account_id 即默认账户):
Terminal window
curl -X POST $BASE/api/v1/me/tokens -H "Authorization: Bearer $JWT" \
-d '{"name": "agent", "scopes": ["workbooks:read", "workbooks:write"],
"resource": "workbook:<WB_ID>", "rate_limit_per_minute": 60}'
  1. 连接 — 使用 MCP 时 Claude Code 只需一条命令(其他宿主见 通过 MCP 连接):
Terminal window
claude mcp add d2b --transport http https://d2b.dev/mcp/ --header "Authorization: Bearer $PAT"

仓库侧由 d2b init 代写 — 添加下面的 AGENTS.md 小节,并打印任何宿主都能使用的标准 MCP 条目。已知宿主用 --host claude-code|cursor|vscode|codex|windsurf|claude-desktop 直接合并到其配置文件;其他宿主用 --config PATH(JSON 或 TOML)写入任意文件。令牌保持为环境变量引用,不会写入文件。

使用 CLI 时,export D2B_API_KEY / D2B_BASE_URL(Claude Code 不会自动读取 .env),并用 pipx install d2b-sdk 或 uvx --from d2b-sdk d2b 安装(作为项目依赖则 uv add d2b-sdk + uv run d2b)。

贴到仓库里的片段(只有连接和选择)

Section titled “贴到仓库里的片段(只有连接和选择)”

规范来自服务器,不要把步骤复制到这里;副本跟不上新工具,会过时。

## D2B
- 数据工作通过 D2B 完成。MCP 服务器 `d2b` 已连接 — 先遵循 `d2b://guide` 中的规范。
- 需要 git 管理(`d2b pull` / `d2b push`)和批处理时使用 CLI `uvx --from d2b-sdk d2b ...`(JSON 输出;认证来自 env 的 D2B_API_KEY / D2B_BASE_URL)。
- 创建位置、文件导入方式和版本处理以 guide 为准。拿不准时问人。

智能体遵循的规范(由服务器下发)

Section titled “智能体遵循的规范(由服务器下发)”

instructions / d2b://guide 的要点及其 CLI 对应。规范不依赖接口,只是工具名不同。

规范MCPCLI
先了解全局list_my_data → get_schemad2b workbooks list → d2b tables list --workbook WB
创建前按名称确认目标位置list_my_workspaces → create_workbookd2b workspaces list → d2b workbooks create --workspace-id …
文件按引用导入(绝不经过自己的上下文)ingest_url / request_upload → ingest_upload / import_cloud_filed2b upload FILE --workbook WB --wait (d2b jobs wait JOB_ID for long runs)
杂乱的表先看结构再实体化ingest_file (staged) → analyze_source → update_parse_spec → materialize_sourced2b upload --mode staged → d2b sources analyze → … materialize
派生用 transform,而不是行编辑add_transform / list_transformsd2b transforms add; d2b pull writes them to transforms/
遇到 409 重新读取并重新应用(绝不盲目覆盖)用 read_table 重新读取 edit_version用 d2b tables rows NAME --workbook WB 重新读取 edit_version
在节点处切版本以便回退commit_snapshot / restore_snapshot / undo_opd2b versions commit / d2b versions revert
报告前核对数字review_table / review_workbook(agent 模式用 get_job 等待作业)d2b review --workbook WB [--table NAME] [--agent]
清理delete_workbookd2b workbooks delete WB

d2b pull --workbook $WB 会生成 transforms/ sheets/ charts/ + d2b.json(--data TABLE 还会导出 base 表的 CSV)。编辑 → 用 d2b push --dry-run 确认 → d2b push --commit $(git rev-parse --short HEAD) → 提交 d2b.json。push 只发送变更(transform 重新执行,data 做三方合并);被拒绝时先 pull 合并再 push。charts/ 为只读。详见 用 git 管理工作簿。

保留原件的编辑(revise = 只修正相关行并返回原 Excel)

Section titled “保留原件的编辑(revise = 只修正相关行并返回原 Excel)”

“整体保持原 Excel 不动,只修正相关的行并输出为新文件”用一次 revise 调用即可完成(内部把 analyze → materialize → transform → 写回折叠为一步)。计算保留在服务器端的 SQL transform 中(可获取 lineage),样式、图表、其他工作表、区域之外的公式全部原样保留。

Terminal window
d2b sources revise equipment.xlsx --workbook $WB \
--transform-name merge_tokyo_sites --range A3:N8 --sheet Summary \
--sql-file merge.sql -o output.xlsx

merge.sql 是 {{ artifact_name }} 视图({{ src }} 会被绑定为目标区域的表)。折叠行的聚合的正确写法:

  • 可加的列(台数、件数、金额)用 SUM。
  • 比率(稼动率、完成率)不要取平均。合并后重新计算: SUM(分子) / NULLIF(SUM(分母), 0)。
  • 平均值(MTBF、MTTR 等)不用简单平均,用加权平均: SUM(値 * 重み) / NULLIF(SUM(重み), 0)(权重用台数、件数等有意义的列)。
  • 类别(评级等)取代表值: arg_max(rating, units_managed)。
  • 要保持行位置,在 SELECT 中加入 MIN("__d2b_row_id")(合并行落在首个成员的位置,空出的行就地置空,其他行不动)。
CREATE OR REPLACE VIEW "{{ artifact_name }}" AS
SELECT
CASE WHEN site IN ('Tokyo Site 1','Tokyo Site 2') THEN 'Tokyo' ELSE site END AS site,
SUM(units_managed) AS units_managed,
SUM(units_active) * 1.0 / NULLIF(SUM(units_managed), 0) AS utilization,
SUM("MTBF(h)" * units_managed) / NULLIF(SUM(units_managed), 0) AS "MTBF(h)",
arg_max(rating, units_managed) AS rating,
MIN("__d2b_row_id") AS "__d2b_row_id"
FROM {{ src }}
GROUP BY 1
ORDER BY MIN("__d2b_row_id")

即使区域内含有合计/小计行(=SUM(...)),这些公式单元格也不会被覆盖而是被保留(由 Excel 重新计算)。会让行数超出模板区域的编辑因破坏几何结构而被拒绝(409)。MCP 中是 revise_source,SDK 中是 sources.revise(...),走的是同一条路径。

把常量作为”活的公式”交付(formula column)

Section titled “把常量作为”活的公式”交付(formula column)”

可以把放常量的列(例:稼动率)在导出时替换为逐行的 Excel 公式。值本身不动,只是附加”在交付的 .xlsx 中如何重新推导”的交付投影。引用用 {列名} 占位符书写(不能用 A1 单元格地址 — 锚定在列的身份上,排序、筛选都不会错位)。坐标由服务器在导出时解析。

Terminal window
# Deliver utilization = units_active / units_total as a live per-row formula
d2b tables set-formula equipment utilization "{units_active} / {units_total}" --workbook <WB>
out = client.tables.set_formula(wb, "equipment", "utilization", "{units_active} / {units_total}")
out["verification"] # {checked, rows, matches, mismatches} — does it reproduce the current constants?

由于值才是正准,写入会返回验证报告(该公式是否在允许误差内复现当前的列值)。可以在确认之后再交付”把常量替换为计算式”。MCP 中是 set_formula_column / list_formula_columns / clear_formula_column。目前的适用对象是 xlsx 导出(可与 {{ ... }} 的 SQL transform、revise 的保留原件写回组合使用)。函数(SUM/IF 等)只做结构校验,跳过数值校验。underline 暂不支持。

跨工作表引用: 用 {table!column} 可以引用另一张表某列的整个数据区域(把多张表导出到同一个文件时,编译为该列所在工作表的绝对引用 'rates'!$B$2:$B$N)。要包在聚合函数里使用:

# Revenue share = this row's amount ÷ the sum of rates.weight
client.tables.set_formula(wb, "sales", "share", "{amount} / SUM({rates!weight})")
client.export.tables(wb, tables=["sales", "rates"], format="xlsx")
# → each share row compiles to =B2/SUM('rates'!$B$2:$B$N) (same-table {amount} relative, cross-refs absolute)

如果被引用的表不在同一次导出中,该公式无法解析,会回退为值。VLOOKUP 式的键关联请不要用公式,而用 **JOIN transform(add_transform)**来表达(会留下 lineage)。

  • 在云端沙箱(Codex 等)中,受 egress 限制,可能需要为 API 可达性做放行设置
  • 对 Bash 超时较短的 Agent,比起 upload --wait,“异步 upload → jobs wait”的两段式更稳妥