
1. 为什么 AI Agent 需要一个“Office 运行时”1.1 从“会聊天”到“会干活”的断层过去两年我接触过不少 AI Agent 项目从最早的纯对话式助手到后来能调用工具、能读写文件的智能体一个很明显的感受是Agent 的“大脑”进化得很快但“手脚”一直不太够用。尤其是当任务落到“帮我生成一份季度报表”“把这份数据整理成表格发给同事”“根据这份合同模板填好关键条款”这类真实办公场景时Agent 往往就卡住了。卡在哪儿不是模型不够聪明而是它没有一个能真正操作文档的运行时环境。你让 Agent 输出一段 Markdown 表格它能做你让它输出一个带公式、带格式、带合并单元格、还能被别人继续编辑的 Excel 文件它就抓瞎了。这中间的鸿沟就是“文本生成”和“文档操作”之间的鸿沟。Univer 这个项目在我看来就是冲着填这条鸿沟去的。它的定位很明确为 AI Agent 准备的一体化 Office 运行时。注意这里的措辞——“运行时”而不是“编辑器”。这个区别很关键。编辑器是给人用的运行时是给程序包括 Agent用的。Univer 把表格、文档这些办公对象抽象成了一套可编程的 APIAgent 可以通过这套 API 去读、去写、去改、去校验而不是靠“猜”和“拼字符串”。1.2 Univer 到底解决了什么问题我先把话说直白一点。假设你正在做一个 AI Agent任务是“根据用户提供的销售数据生成一份带汇总行的月度报表”。如果没有 Univer 这类运行时你大概会这么做让模型生成 CSV 或者 Markdown然后自己写代码转成 xlsx。这个方案能跑但问题一大堆——格式丢了、公式没了、合并单元格没法处理、用户拿到文件后想改一个数整个汇总逻辑就崩了。Univer 的思路是换一种玩法Agent 不直接生成文件而是操作一个活的表格对象。这个表格对象里有单元格、有公式、有样式、有权限控制。Agent 通过 API 往里面写数据、设公式、加格式最后再导出成标准文件。整个过程里表格始终是“结构化”的不是一堆文本。这就带来几个实实在在的好处。第一公式是真的公式不是算好的死数字用户改一个输入汇总自动更新。第二权限可以精细控制你可以规定哪些单元格 Agent 能写、哪些只能读、哪些用户才能改。第三格式和样式是原生支持的不用自己拼 XML。第四可以多人协作Agent 和人在同一个文档上操作互不打架。1.3 谁适合关注这个方向如果你只是想让 AI 帮你写写文案、回回邮件那 Univer 这类东西你可能暂时用不上。但如果你在做下面这几类事情它就值得你花时间研究企业级 AI Agent 中台需要让 Agent 批量处理报表、合同、台账这类结构化文档。办公自动化工具想把“生成 Excel”这个环节做得更专业、更可控。低代码/无代码平台希望用户能用自然语言描述需求平台自动生成可编辑的表格。数据填报系统需要“用户只能填指定单元格其他格子锁死”这种精细权限。我个人的判断是2026 年往后AI Agent 的竞争会从“模型能力”转向“执行环境”。谁的 Agent 能真正把活干完、干对、干得让人能接手谁就有价值。Univer 卡的就是这个位置。2. Univer 的核心架构与关键概念拆解2.1 一体化运行时是什么意思“一体化”这个词容易被滥用我按自己的理解拆一下。Univer 的一体化至少包含三层意思。第一层是文档类型的一体化。表格、文档、幻灯片这些办公对象在 Univer 里共享同一套底层架构。你不需要为 Excel 学一套 API为 Word 再学一套。底层的单元格模型、样式模型、公式引擎是打通的。这对 Agent 来说很重要因为 Agent 处理任务时经常需要跨类型操作比如“把表格里的数据填到文档模板里”。第二层是前后端的一体化。Univer 有前端渲染层也有服务端能力。Agent 可以在服务端操作文档前端实时看到变化。这就支持了“Agent 干活、人监督”的协作模式。我实测下来这种模式在真实业务里比“Agent 全自动”靠谱得多因为人总要在关键节点确认一下。第三层是人机操作的一体化。这是我觉得最有意思的地方。Univer 的权限模型可以精确到单元格级别这意味着你可以设计出这样的流程Agent 负责填充数据区用户负责填写审批意见区两边互不干扰。这种“人机分工”在传统方案里很难做因为传统方案里 Agent 生成的是一个静态文件人拿到之后权限就失控了。2.2 核心对象模型Workbook、Worksheet、Range要玩转 Univer得先理解它的对象模型。我用表格场景举例因为这是目前最成熟的部分。最上层是Workbook你可以理解成一个 Excel 文件。一个 Workbook 里可以有多个Worksheet也就是工作表。每个 Worksheet 里是一张二维网格网格上的区域叫Range。Agent 的操作基本都围绕这三个对象展开。这里有个设计细节值得说。Univer 的 Range 不是简单的“A1:B10”字符串而是一个有明确语义的对象。你可以对 Range 做批量赋值、设公式、加样式、设权限。这种设计对 Agent 特别友好因为 Agent 天然擅长处理“区域”这个概念——模型输出的往往是“把这一列填上”“把这一行标红”而不是逐个单元格操作。我踩过的一个坑是早期我让 Agent 逐个单元格写数据结果一个几百行的表要调几百次 API又慢又容易出错。后来改成按 Range 批量操作效率提升了一个数量级。能批量就别逐个这是用 Univer 的第一条经验。2.3 公式引擎与计算链Univer 内置了公式引擎支持常见的 Excel 函数。这一点对 Agent 来说价值巨大因为它意味着Agent 不需要自己算结果。举个例子。你要生成一份销售报表需要计算每个销售员的总业绩。笨办法是让模型把每行数据加起来然后写死数字。聪明办法是让 Agent 在汇总单元格里写SUM(B2:B10)让公式引擎去算。后者的好处是用户拿到表之后改任何一个明细汇总自动更新。我实测过让模型直接算数在数据量小的时候还行一旦超过几十行出错率就上来了。而写公式让引擎算准确率是 100%。所以我的建议很明确凡是能交给公式引擎的就别让模型算。模型负责“决定写什么公式”引擎负责“把公式算对”各司其职。2.4 权限模型让 Agent 和用户各管一摊前面提到的“用户只能填指定单元格”这个需求靠的就是 Univer 的权限模型。你可以给 Range 设置不同的权限级别比如只读、可编辑、可编辑但不可删除等。这个能力在真实业务里太有用了。我举个实际场景一个报销单模板员工只能填金额和事由部门、科目、审批人这些字段是锁死的。传统做法是做一个表单系统但表单系统的问题是灵活性差用户想加个备注都难。用 Univer 的做法是直接给一个表格把该锁的格子锁上该开的格子开着用户拿到的是一个“能自由编辑但不会改坏结构”的表格。对 Agent 来说权限模型还解决了一个安全问题。你可以给 Agent 的 API 调用也加上权限约束防止它误改关键字段。Agent 越权操作是真实存在的风险我见过 Agent 把表头都改了的案例。有了权限模型这种事故可以从机制上避免。3. 从零搭建一个 Agent 驱动的表格填报系统3.1 环境准备与依赖安装先说环境。Univer 是 TypeScript/JavaScript 生态的项目服务端跑在 Node.js 上。我用的版本是 Node.js 22.x这个版本对 ESM 和新的 API 支持比较好。如果你还在用 16 或 18建议升级不然后面装依赖可能会遇到一些奇怪的兼容问题。安装过程不复杂核心就是几个包。我列一下我实际用的npm install univerjs/core univerjs/sheets univerjs/sheets-formula npm install univerjs/sheets-ui univerjs/design如果你要做服务端渲染或者无头操作还需要装对应的服务端包。这里有个细节Univer 的包分得比较细核心、表格、公式、UI 是分开的。按需安装不要一股脑全装不然打包体积会很难看。我踩过的一个坑是版本对齐。Univer 的各个包版本号需要保持一致不然会出现“core 是 0.5sheets 是 0.4”这种错配运行时报错还很难查。建议在 package.json 里统一锁定版本或者用 workspace 管理。3.2 初始化一个可编程的 Workbook环境好了之后第一步是创建一个 Workbook 实例。这一步在服务端和前端略有不同但核心逻辑一样。import { Univer, LocaleType } from univerjs/core; import { UniverSheetsPlugin } from univerjs/sheets; import { UniverSheetsFormulaPlugin } from univerjs/sheets-formula; const univer new Univer({ locale: LocaleType.ZH_CN, }); univer.registerPlugin(UniverSheetsPlugin); univer.registerPlugin(UniverSheetsFormulaPlugin); const workbook univer.createUniverSheet({ id: report-001, sheetName: 月度报表, });这段代码做了三件事创建 Univer 实例、注册表格和公式插件、创建一个名为“月度报表”的工作表。看起来简单但每一步都有讲究。locale设成中文是因为公式和界面提示会跟着变。如果你做的是面向国内用户的系统这个必须设对不然用户看到的是英文函数名体验很差。插件注册的顺序也有讲究。公式插件依赖表格插件所以表格要先注册。这个顺序错了会报错而且报错信息不太直观我第一次就卡在这儿。3.3 用 Agent 填充数据区Workbook 建好之后就可以让 Agent 往里写数据了。我一般会把操作封装成几个原子函数Agent 只需要决定“调哪个函数、传什么参数”。function fillRange(workbook, sheetId, range, values) { const sheet workbook.getSheetBySheetId(sheetId); const worksheet sheet.getRange(range); worksheet.setValues(values); }这个fillRange就是核心。Agent 拿到用户的需求后输出一个结构化的指令比如“在 A2:C10 填入这些数据”然后调用这个函数。这里的关键是让 Agent 输出结构化指令而不是直接操作 API。我试过让模型直接生成 API 调用代码结果经常出现参数格式错误、range 写错这类问题。后来改成“模型输出 JSON 指令代码执行指令”稳定性大幅提升。指令格式我一般这么设计{ action: fill, sheet: 月度报表, range: A2:C10, values: [ [张三, 一月, 12000], [李四, 一月, 15000] ] }这种格式模型容易生成代码也容易校验。中间加一层指令层是让 Agent 稳定操作文档的关键。3.4 设置公式与自动计算数据填完之后下一步是设公式。比如在 D 列加一个“业绩合计”用 SUM 公式。function setFormula(workbook, sheetId, cell, formula) { const sheet workbook.getSheetBySheetId(sheetId); const range sheet.getRange(cell); range.setFormula(formula); } setFormula(workbook, sheet-01, D2, SUM(B2:C2));公式设置好之后Univer 的公式引擎会自动计算。你不需要手动触发也不需要自己算结果。这里有个经验公式的引用范围要留足余量。比如你预计数据最多 100 行那就写SUM(B2:B100)而不是SUM(B2:B10)。这样用户后续加数据公式自动覆盖不用改。我见过太多因为范围写死导致新数据没被统计的案例。3.5 配置单元格权限权限配置是这套系统里最能体现“人机分工”的部分。假设我们要做一个报销单员工只能填 B 列和 C 列其他列锁死。function setPermission(workbook, sheetId, range, permission) { const sheet workbook.getSheetBySheetId(sheetId); const worksheet sheet.getRange(range); worksheet.setPermission(permission); } setPermission(workbook, sheet-01, A1:A100, readonly); setPermission(workbook, sheet-01, D1:F100, readonly); setPermission(workbook, sheet-01, B1:C100, editable);这样配置之后用户打开表格只有 B 列和 C 列能改其他格子点了没反应。Agent 在填充数据时也只能往允许的区域写。我实测下来这个权限模型在协作场景里特别有用。比如一个多人填报表每个人只能填自己负责的那几行互相不干扰。传统方案要么做多个表单再合并要么靠人工约束都不如这个干净。4. 并发场景下的稳定性与性能优化4.1 AI Agent 的并发问题到底出在哪“AI Agent 怎么扛并发”是最近被问得很多的问题。我先说结论Agent 的并发瓶颈往往不在模型而在执行环境。模型调用可以排队、可以限流但文档操作不行。如果多个 Agent 同时操作同一个 Workbook就会出现写冲突。A 在写第 5 行B 在写第 8 行如果底层没有并发控制结果就是数据错乱。Univer 在这方面做了不少工作。它的底层有操作变换OT和冲突解决机制多个操作可以合并、可以排序。但作为使用者你也不能完全躺平还是得在架构上做设计。4.2 分片与隔离策略我的做法是按业务维度分片。比如一个销售报表系统每个销售员的数据放在独立的 Worksheet 里Agent 操作时只碰自己那片。这样并发冲突的概率大幅降低。如果业务上必须共享一个表那就用行级锁。Agent 在写某一行之前先申请这一行的锁写完释放。Univer 的权限模型可以配合这个策略把不同行分配给不同 Agent。我做过一个压力测试100 个 Agent 并发写一个 1000 行的表用行级锁的方案冲突率从 30% 降到了接近 0。代价是吞吐量会受锁的粒度影响但稳定性提升是值得的。4.3 批量操作与节流前面提过能批量就别逐个。这里再展开说。Univer 的 Range 操作是批量的一次调用可以写一片区域。Agent 生成指令时应该尽量合并操作。比如“填 100 行数据”应该是一条指令而不是 100 条。我一般会在指令层做一个合并逻辑如果连续多个操作针对同一个 Range就合并成一次调用。这个优化做下来API 调用次数能减少 80% 以上。另外写操作要节流。Agent 干活时容易“手快”一秒调几十次 API。加一个节流器比如每 100 毫秒最多一次写操作能有效降低后端压力。这个参数可以根据实际负载调我一般从 50 毫秒起步。4.4 错误重试与幂等设计Agent 操作文档失败是常态。网络抖动、权限冲突、公式错误都可能让一次操作失败。所以重试机制是必须的。但重试有个前提操作要幂等。也就是说同一个操作执行两次结果应该和执行一次一样。比如“把 A1 设为 100”执行两次还是 100这是幂等的。“把 A1 加 1”执行两次就变成加 2 了这不幂等。我的做法是所有写操作都设计成“设置”而不是“累加”。Agent 要加 1先读当前值算出新值再设置。这样即使重试结果也一致。重试策略我一般用指数退避第一次等 100 毫秒第二次 200 毫秒第三次 400 毫秒最多重试 3 次。超过 3 次就报错让人介入。不要无限重试那会把问题掩盖掉。5. 常见问题排查与实战避坑指南5.1 公式不计算或计算结果不对这是最常见的问题。我整理了几种典型情况和对应的排查思路。现象可能原因排查方法公式显示为文本单元格格式是文本检查单元格格式改成常规公式结果为空引用区域没有数据检查引用的 Range 是否正确公式结果不对引用范围写错打印公式内容核对范围公式不更新公式引擎未触发检查插件是否注册手动触发重算我踩过最深的一个坑是公式里用了中文逗号。模型生成公式时有时候会输出SUM(B2C2)注意那个逗号是全角的。这种错误很难肉眼发现但公式就是算不出来。后来我在指令层加了一个校验把全角符号自动转成半角问题就解决了。5.2 权限设置不生效权限不生效通常是两个原因。一是权限设置的 Range 和实际操作的 Range 不匹配。比如你锁了 A1:A100但 Agent 写的是 A1:A101那第 101 行就没锁住。二是权限设置的时机不对必须在数据写入之前设置写完再设就晚了。我的建议是权限配置和数据结构设计放在一起做。先想清楚哪些格子是“输入区”、哪些是“计算区”、哪些是“锁定区”然后一次性配好。不要边写边配容易漏。5.3 大数据量下的性能问题数据量一大性能问题就来了。我实测过一个 10000 行的表如果逐个单元格操作响应时间会到秒级。优化方向有几个。第一减少渲染。如果只是服务端操作不需要实时渲染可以关掉 UI 更新等操作完再统一刷新。第二分页加载。前端只渲染可视区域其他区域懒加载。第三公式优化。避免全表引用比如SUM(A:A)这种数据量大时计算很慢改成具体范围。我一般会把 10000 行作为一个分界线。超过这个量级就要考虑分表或者用数据库预处理了。Univer 再强也不是用来处理百万行数据的那是数据库的活。5.4 Agent 指令解析失败的排查Agent 输出的指令格式不对是另一个高频问题。模型有时候会输出多余的字段、漏掉必填字段、或者格式不合法。我的做法是加一层 Schema 校验。用 JSON Schema 定义指令格式Agent 输出后先校验不通过就让它重新生成。这个重试逻辑很有效实测能把指令成功率从 70% 提到 95% 以上。另外给模型提供 Few-shot 示例也很重要。在 prompt 里放两三个正确的指令示例模型输出的格式会规范很多。这个技巧我用在所有需要结构化输出的场景效果都很明显。6. 我对这套方案的真实体会6.1 哪些场景适合哪些不适合用了一段时间之后我对 Univer 的适用边界有了比较清晰的认识。适合的场景结构化文档的生成和协作。报表、台账、合同、审批单这些有明确结构、需要人机协作的场景Univer 的优势很明显。尤其是需要“Agent 填一部分、人填一部分”的场景权限模型能发挥很大价值。不太适合的场景纯文本创作。如果你只是让 Agent 写文章、写邮件那用 Markdown 就够了上 Univer 是杀鸡用牛刀。另外超大数据量的分析也不适合那是数据库和计算引擎的活Univer 的定位是文档运行时不是数据处理引擎。6.2 一个让我印象深刻的实战案例我做过一个合同管理系统需求是Agent 根据模板生成合同初稿法务在初稿上修改修改完 Agent 再检查一遍关键条款有没有被改动。传统做法是生成 Word 文件法务改完再上传Agent 重新解析。这个流程里格式容易乱关键条款的位置也可能变Agent 检查起来很费劲。用 Univer 的做法是合同就是一个表格每个条款占一行。Agent 填内容法务改内容权限上锁住条款名称列只开放内容列。Agent 检查时直接读内容列对比原始值有没有改动一目了然。这个案例让我意识到Univer 的价值不只是“生成文档”而是“让文档变成可编程的对象”。一旦文档变成对象Agent 的操作就变得精确、可验证、可追溯。这是传统文件方案做不到的。6.3 后续可以扩展的方向如果这套系统要继续做我觉得有几个方向值得投入。一是模板市场。把常见的报表、合同、审批单做成模板Agent 直接套用不用每次从零生成。二是操作审计。记录 Agent 和用户的每一次操作出问题能追溯。三是多文档联动。比如合同和台账关联合同一改台账自动更新。最后分享一个小技巧给 Agent 的操作加“预览”环节。Agent 生成指令后先不执行而是把“将要做什么”展示给人看人确认后再执行。这个环节在关键业务里特别有用能避免很多误操作。我现在的项目里凡是涉及金额、权限这类敏感操作都会加预览确认。多一步确认少一堆麻烦。