智能体触碰模型的三种方式——以及它真正会选的那一种

用 openpyxl 处理二进制 .xlsx、直接改 .deepcell 的 XML,还是用 deepcell CLI。同一个任务,三种截然不同的可操作性。这就是智能体为什么会选 CLI。

9 分钟阅读DeepCell 团队

把一个财务模型和一项任务交给编程智能体——"加一个下行情景,然后告诉我 自由现金流在哪里转负"——它做的第一件事,其实是悄无声息地决定如何触碰 这个文件。这个选择在任何一个数字被改动之前就已经做出,而它决定了之后 的一切:任务要来回多少趟、这些编辑是否安全、以及你能否信任最终结果。

Claude 可能会伸手去够的触碰方式有三种。从外面看它们像是可以互换的。 其实不是。

方式一:用 openpyxl 处理二进制 .xlsx#

对任何用 Python 自动化过电子表格的人来说,这是本能反应。它也是最不适合 智能体的一种,而且原因会层层叠加、越滚越大。

文件是不透明的。 一个 .xlsx 是一堆 XML 组件压缩成的包。智能体 没法 cat 它、没法 grep 它、没法 diff 它。为了看一个值,它必须 写并运行一段脚本:

from openpyxl import load_workbook
wb = load_workbook("model.xlsx", data_only=True)
print(wb["Model"]["C7"].value)

每一次观察都是它自己写的一段代码的往返。想看下一个单元格?再写一段, 或者写一段更长的、去猜测布局的脚本。

公式是死的。 openpyxl 给你的要么是公式字符串,要么是 Excel 上次缓存的那个值(data_only=True)——从来不会有一次实时重算。改了 一个输入项,所有依赖它的单元格都是过期的,直到有什么东西在 Excel 或 LibreOffice 里重新打开这份工作簿。智能体加了一个下行情景,然后就真的 看不到它对自由现金流做了什么——除非它启动一个自己进程里根本没有的计算 引擎。

没有任何语义。 一个单元格就是 Model!C7。没有任何东西说明这是 基准情形下 2027 年的收入。智能体只能从位置去重建含义,并祈祷布局不会 错开一行。合并一个单元格、插入一列,它的心智地图就悄悄烂掉了。

写回是有损的。 让样式、合并区域、命名区域和图表安然穿过一次 openpyxl 的往返,是一片雷区;很多东西会被丢掉或弄乱。而且没有历史—— 这次编辑是一次二进制覆盖,不留下改了什么、为什么改的任何记录。

openpyxl 只在一件事上称职:把数据一份遗留工作簿里捞出来,放进 更好的东西里。作为智能体的工作台面,它是最后的手段。

方式二:手改 .deepcell 的 XML#

一份 .deepcell 就是纯 XML——可 grep、可 diff、天生对 git 友好。于是很自然的下一个念头是:跳过工具, 让智能体直接读写文件。

对于读取,这确实很好。智能体可以打开文件,扫一遍 ItemDefs 和 CalcDefs,不运行任何东西就建立起一份准确的心智模型。结构是清晰可读的, 这是二进制块永远给不了的。

对于写入,这是个陷阱。这个格式的全部价值——依赖追踪、约束强制、 Status 与 Context 规则、schema 校验——都活在计算引擎里,而不是在 原始文本里。手改 XML,你就径直绕过了这一切。要写出一份内部自相矛盾的 文档易如反掌:

  • 一个公式引用了一个不存在的 Item,
  • 一个 Value 违反了它自己的 ItemDef 护栏,
  • 一个维度元组已经无法解析。

没有任何东西拦住你,因为什么都没运行。而把跨许多带维度值的批量改动当成 原始字符串手术来做,恰恰是智能体最容易埋下一个差一错误的那类活儿——它 要到很久以后才会发现。

直接改 XML,适合读取结构或做一次外科式的单点修补。作为主要的写入 路径,它很糟糕。

方式三:deepcell CLI(或进程内的同款工具)#

这才是智能体真正想要的界面,因为它就是围绕着智能体所拥有的可操作性 设计的:

读取便宜且结构化。 lscatdescribequery 能在合适的 高度检视模型,无需自己写代码——而且 query 返回的是已解析、实时 计算的值,并附带它们的维度。智能体问"下行情景下 2027 年的自由现金流 是多少?",得到的是一个反映它刚做完那次编辑的数字。

通过引擎写入。 defs apply 和批量编辑都经过 Jingwei,因此每一次 改动都会跑一遍依赖重算、约束检查和 schema 校验。智能体不可能悄悄 损坏文档——一次非法编辑会作为报错返回,而不是一颗地雷。

版本化是与生俱来的。 每一次 commit 都带着标题和理由,因此文件的 历史读起来是一条为什么的链条,而不是一次二进制覆盖。"智能体做了这个" 和"我做了这个"之间的那道缝,事后依然清晰可辨

自我描述且可预测。 每一个 CLI 命令都是对某个 Jingwei 端点的薄 转发——Click 的参数与 pydantic 字段一一对应。智能体通过 --help 和 产品内的 guide 主题来发现能力,而不是去逆向一个文件格式。而且 CLI、 MCP 的 deepcell(command) 工具、以及子智能体进程内的工具,全都派发到 同一个服务层,因此无论 Claude 是在终端里还是在编排一次构建,行为都完全 一致。

同一个任务,做三遍#

openpyxl + .xlsx原始 .deepcell XMLdeepcell CLI/工具
读一个值写并运行脚本读文件query
编辑后看到实时结果❌ 需要 Excel/LibreOffice❌ 绕过引擎✅ 已重算
非法编辑被拦截✅ 校验报错
保留结构/样式有损手动
带理由的版本化仅 git
智能体裁决仅用于导入读取 / 一次性首选

主线很简单。openpyxl 让智能体边猜边祈祷。原始 XML 让它能读但不能 安全地写。而 CLI 把一项建模任务变成一串清晰、经校验、可回退的命令—— 这恰恰是智能体擅长的形状。

这就是一种新文件格式背后的全部论点: 格式是唯一的真实来源,而 CLI 是你在不弄坏它的前提下触碰它的方式。当你 只需要时,去用原始 XML。只在要把数据从遗留工作簿里拖出来时,才降到 openpyxl。至于其余一切——构建和修改一个模型这件真正的活儿——智能体会 伸手去够 CLI,而它选得没错。