AI Agent 的 Office 运行时:Univer 表格交互与并发实践
1. 为什么 AI Agent 需要一个“Office 运行时”1.1 从“会聊天”到“会干活”的断层过去两年我一直在做 AI Agent 相关的落地项目从最早的纯对话机器人到后来接工具调用、接 RAG、接工作流编排踩过的坑基本能写一本书。但真正让我意识到问题严重性的是去年帮一家做供应链的公司做智能报表 Agent 的时候。那个项目的需求听起来特别朴素让 Agent 每天自动读取业务数据生成一份带格式的 Excel 周报里面要有合并单元格的标题、条件格式标红异常值、还有几个公式联动。我当时的第一反应是“这不就是个 openpyxl 的活儿吗”结果真上手才发现Agent 生成的表格结构稍微复杂一点openpyxl 的代码就开始变得又臭又长而且一旦用户想在生成结果上手动改两笔整个链路就断了——因为文件是“死”的改完再让 Agent 处理它根本不知道用户改了什么。这就是我想聊的核心问题AI Agent 缺的不是生成能力缺的是一个能承载“交互式文档”的运行时环境。传统的 Office 文件处理库本质上都是“批处理工具”——读进来、算一遍、写出去中间没有状态没有交互没有增量。而 Agent 要干的活儿恰恰是“边生成边协作边修改”的活儿。Univer 这个项目就是冲着这个断层来的。它把自己定位成“为 AI Agent 准备的一体化 Office 运行时”关键词是运行时三个字。不是文件格式转换器不是渲染库而是一个能让 Agent 和人类在同一份表格/文档上持续协作的执行环境。1.2 Univer 到底是什么能解决什么问题先把话说直白一点。Univer 是一个开源的、支持表格、文档、幻灯片的在线协作套件内核它提供了完整的 SDK可以嵌入到 Web 应用里也可以在 Node.js 环境里跑。它最核心的能力是把“电子表格”这件事抽象成了一套可编程的模型——单元格、公式、样式、权限、协同全都是可以通过 API 操作的。那它跟 AI Agent 有什么关系我理解下来有这么几层第一层Agent 需要一个结构化的操作对象。你让大模型直接吐一个 xlsx 文件它做不到你让它吐一段 JSON 描述表格它能做但这段 JSON 怎么变成用户能看能改的东西Univer 就是那个“把 JSON 变成活表格”的中间层。第二层Agent 需要感知用户的修改。用户在一个单元格里填了数Agent 应该能拿到这个变更事件然后决定要不要重算、要不要提醒、要不要触发下一步。这种“事件驱动”的能力普通文件库是没有的。第三层Agent 需要做权限控制。这是热词里提到的那个场景——“支持用户定义表格然后让用户去填写一些单元格其他的单元格用户无法修改”。这个需求在真实业务里太常见了Agent 生成一个模板锁定公式区和表头区只开放数据录入区给用户。Univer 的权限模型天然支持这种粒度。第四层Agent 需要扛并发。热词里有个“ai agent 怎么扛并发”这个问题在 Office 场景下尤其尖锐。如果每个用户会话都要起一个独立的表格实例内存和 CPU 怎么控Univer 支持服务端渲染和实例复用这是它能进生产环境的关键。所以你看Univer 不是一个“更好用的 Excel 库”它是把 Office 这件事从“文件”重新定义成了“服务”。这个视角的转换才是它对 Agent 生态真正的价值。1.3 适合谁来读这篇内容这篇东西我尽量写得实操一点适合几类人正在做 AI Agent 产品需要让 Agent 输出结构化文档尤其是表格的开发者想在自己的 SaaS 里嵌入在线表格能力又不想被商业组件绑死的技术负责人对“Agent 协作文档”这个方向感兴趣想找个练手项目的独立开发者单纯好奇 Univer 这套东西怎么用、能不能替代传统方案的前端/全栈工程师。我会从架构思路讲到具体代码从权限模型讲到并发处理中间穿插我自己踩过的坑。不保证面面俱到但保证每一条都是我实际验证过的。2. Univer 的核心架构与选型逻辑2.1 为什么是“运行时”而不是“文件库”要理解 Univer 的设计得先理解它跟传统方案的根本差异。我拿几个常见方案做个对比这样更直观。方案类型代表数据模型交互能力协同能力Agent 友好度文件处理库openpyxl、xlsxwriter文件流无无低只能批处理前端表格组件Handsontable、AG Grid内存表格强需自建中偏展示在线文档内核Univer可编程模型强原生支持高事件API 完整关键差异在“数据模型”这一列。openpyxl 处理的是文件你读进来的是一个 workbook 对象改完写出去中间没有“活”的状态。AG Grid 处理的是内存里的二维数组展示很强但它的模型是“表格数据”不是“文档结构”——公式、样式、权限这些它管不了。Univer 的模型是分层的最底层是数据层Data Model管单元格的值、公式、格式中间是渲染层Render管怎么画最上面是插件层Plugin管协同、权限、导入导出这些业务能力。这个分层的好处是Agent 可以直接操作数据层不用关心渲染而用户看到的是渲染层的结果两边通过事件同步。我打个比方。传统文件库像是“打印店”——你把内容给它它给你印出来印完就结束了。Univer 像是“共享白板”——你可以在上面写别人也可以改改的过程所有人都能看到而且白板本身知道每一笔是谁画的、什么时候画的。2.2 核心模块拆解从单元格到协同Univer 的代码结构挺清晰的我按自己的理解拆一下几个关键模块。univerjs/core是地基定义了所有基础类型Workbook、Worksheet、Range、Cell、Style、Formula 等等。你操作表格本质上就是在操作这些对象。比如你要设置 A1 单元格的值代码大概是这样const workbook univerAPI.getActiveWorkbook(); const worksheet workbook.getActiveSheet(); const range worksheet.getRange(A1); range.setValue(Hello Univer);这段代码看着简单但背后发生的事情不少range 对象会去 core 里找到对应的单元格模型改它的值然后触发一个变更事件渲染层收到事件后重绘协同层收到事件后广播给其他客户端。这一整套链路就是“运行时”的含义。univerjs/sheets是表格能力的实现公式引擎、条件格式、数据验证都在这里。公式引擎这块我要多说一句它是自己实现的不依赖第三方库支持大部分常用函数。这意味着 Agent 生成公式的时候不用担心兼容性问题而且公式的计算结果是可以被程序读取的——这对 Agent 做“自检”特别有用。univerjs/sheets-formula单独把公式能力抽出来了这个设计我觉得挺聪明。因为公式计算是 CPU 密集型的可以放到 Web Worker 里跑不阻塞主线程。Agent 场景下如果一次要算几千个单元格的公式这个隔离就很重要。univerjs/sheets-ui和univerjs/ui负责界面包括工具栏、右键菜单、单元格编辑器这些。如果你只是想在 Node.js 里跑 Univer 做服务端计算这两个可以完全不引入包体积能省一大截。univerjs/sheets-collaboration是协同模块基于 OTOperational Transformation算法。这块是 Univer 相对成熟的部分多人同时编辑同一个单元格的冲突处理做得比较稳。Agent 场景下如果多个 Agent 实例同时操作一份表格这个模块就是刚需。2.3 Node.js 环境下的运行方式热词里“node.js”出现频率很高我猜很多人关心的是Univer 能不能在服务端跑答案是能而且这是它区别于纯前端表格组件的关键优势。在 Node.js 里跑 Univer核心是不引入 UI 相关的包只引入 core 和 sheets。大概的初始化代码是这样import { Univer, LocaleType } from univerjs/core; import { UniverFormulaEnginePlugin } from univerjs/engine-formula; import { UniverSheetsPlugin } from univerjs/sheets; const univer new Univer({ locale: LocaleType.ZH_CN, }); univer.registerPlugin(UniverSheetsPlugin); univer.registerPlugin(UniverFormulaEnginePlugin); const workbook univer.createUniverSheet({ id: agent-workbook, sheetContainer: [], });这段代码跑起来之后你就有了一个纯内存的表格实例可以往里塞数据、算公式、读结果全程不需要浏览器环境。我实测下来一个空的 Univer 实例在 Node.js 里占用的内存大概在 20-30MB 左右具体取决于你注册了多少插件。这里有个坑要注意Univer 的某些插件依赖浏览器 API比如window、document在 Node.js 里直接 import 会报错。解决办法是用动态 import 按需加载或者用jsdom之类的库做 shim。我自己的做法是服务端只注册 core、sheets、formula 这三个其他一律不碰这样最干净。2.4 与 AI Agent 的集成切入点Univer 给 Agent 留的集成点我总结下来有三个层次。最浅的一层是“生成即导出”。Agent 生成表格数据通过 Univer 的 API 写入然后导出成 xlsx 给用户下载。这种用法最简单但没发挥出运行时的价值。中间一层是“生成即交互”。Agent 生成一个带公式和格式的表格用户在线打开可以改数据公式自动重算。Agent 通过监听变更事件知道用户改了什么可以给出反馈。这种用法已经能覆盖大部分报表场景了。最深的一层是“Agent 作为协作者”。Agent 和用户同时在线Agent 负责填一部分单元格用户负责填另一部分权限隔离实时同步。这种用法就是热词里说的“用户定义表格让用户填一些单元格其他单元格无法修改”的完整形态。我后面会重点讲第二层和第三层的实现因为这两层才是 Univer 真正区别于其他方案的地方。3. 权限控制与单元格锁定实操3.1 权限模型的设计思路先讲权限因为这是热词里最具体的一个需求也是很多 Agent 产品落地时的刚需。Univer 的权限模型是分层的我画个表说明权限层级控制对象典型场景工作簿级整个文件只读分享、禁止下载工作表级单个 sheet隐藏敏感 sheet区域级单元格范围锁定公式区、开放录入区单元格级单个单元格精细控制Agent 场景下最常用的是区域级权限。比如 Agent 生成一个预算表表头行和合计行是锁定的中间的明细行开放给用户填。这个用 Univer 的setRangePermission就能实现。3.2 锁定公式区、开放录入区的完整代码我直接上一段我实际项目里用过的代码场景是Agent 生成一个销售报表A1:C1 是标题锁定A2:C2 是表头锁定A3:C10 是数据区开放C11 是合计公式锁定。const fWorkbook univerAPI.getActiveWorkbook(); const fWorksheet fWorkbook.getActiveSheet(); // 先设置整个 sheet 为可编辑 fWorksheet.setSheetPermission({ edit: true }); // 锁定标题行 const titleRange fWorksheet.getRange(A1:C1); titleRange.setRangePermission({ edit: false, copy: true, paste: false, }); // 锁定表头行 const headerRange fWorksheet.getRange(A2:C2); headerRange.setRangePermission({ edit: false, copy: true, paste: false, }); // 锁定合计行 const totalRange fWorksheet.getRange(C11); totalRange.setRangePermission({ edit: false, copy: true, paste: false, }); // 数据区保持可编辑默认就是可编辑这里显式声明一下 const dataRange fWorksheet.getRange(A3:C10); dataRange.setRangePermission({ edit: true, copy: true, paste: true, });这段代码跑完之后用户在界面上点标题行会发现根本进不了编辑态点数据区正常编辑。这就是“用户定义表格让用户填一些单元格其他单元格无法修改”的实现。3.3 权限与 Agent 的联动让 Agent 知道“谁改了什么”光锁定还不够Agent 需要知道用户改了什么才能做后续处理。Univer 提供了事件监听机制我一般会监听RangeValueChanged事件univerAPI.getActiveWorkbook().onCommandExecuted((command) { if (command.id sheet.command.set-range-values) { const { range, value } command.params; console.log(用户修改了区域:, range); console.log(新值:, value); // 这里可以触发 Agent 的后续逻辑 // 比如检查数据是否合法、重算某个指标、发送通知 handleUserEdit(range, value); } });这个监听机制是 Agent 感知用户行为的核心。我踩过的一个坑是事件触发频率很高用户连续输入的时候会疯狂触发。解决办法是做防抖比如 500ms 内的连续修改合并成一次处理。这个在 Agent 场景下尤其重要因为每次触发都可能意味着一次 LLM 调用成本扛不住。提示权限设置和事件监听要配合使用。如果只锁权限不监听Agent 就是“瞎子”如果只监听不锁权限用户可能把公式改坏Agent 拿到脏数据。3.4 权限控制的常见坑与规避我整理了几个实际踩过的坑坑一权限设置顺序问题。如果你先锁了整个 sheet再想开放某个区域需要显式设置该区域为可编辑否则继承的是 sheet 级的锁定。这个逻辑跟 CSS 的继承有点像子级不设置就继承父级。坑二复制粘贴绕过权限。默认情况下用户虽然不能编辑锁定单元格但可以从别处复制内容粘贴进去。解决办法是在setRangePermission里把paste设为false。坑三公式引用被锁区域。如果用户的数据区公式引用了锁定的合计行而合计行又被锁了公式重算会不会出问题实测下来不会因为公式计算走的是数据层不受权限层影响。权限只控制“用户能不能手动改”不控制“程序能不能算”。坑四协同场景下的权限同步。多人协作时权限变更需要广播给所有客户端。Univer 的协同模块会自动处理这个但如果你自己实现了权限逻辑记得把权限变更也纳入协同范围。4. 并发处理与服务端 Agent 架构4.1 Agent 并发为什么是个真问题热词里“ai agent 怎么扛并发”这个问题在 Office 场景下会被放大。原因很简单表格是有状态的而且状态还不小。假设你的产品是一个“AI 报表助手”每个用户会话都需要一个独立的表格实例来承载他的数据。如果同时有 1000 个用户在线你就有 1000 个表格实例。每个实例按 30MB 算就是 30GB 内存。这个数字对大多数团队来说是扛不住的。所以并发问题的本质是如何在有限资源下管理大量有状态的表格实例。我总结了几种策略从简单到复杂。4.2 策略一实例池化与懒加载最简单的做法是实例池。维护一个 Univer 实例池用户请求来了就从池里取一个用完还回去。但这里有个问题表格实例是有数据的还回去之前得清空清空本身也有成本。我的做法是分级池化。把实例分成“热实例”和“冷实例”。热实例常驻内存处理活跃会话冷实例序列化成 JSON 存到 Redis 或数据库用户下次访问时再反序列化回来。// 伪代码示意 class UniverPool { constructor(maxHot 50) { this.hotPool []; this.maxHot maxHot; } async acquire(sessionId) { // 先从热池找 let instance this.hotPool.find(i i.sessionId sessionId); if (instance) return instance; // 热池满了把最久未用的序列化出去 if (this.hotPool.length this.maxHot) { const lru this.hotPool.shift(); await this.serializeToRedis(lru); } // 从 Redis 恢复或新建 const snapshot await this.loadFromRedis(sessionId); instance snapshot ? this.deserialize(snapshot) : this.createNew(); this.hotPool.push(instance); return instance; } }这个策略的关键参数是maxHot需要根据你的服务器内存和单实例占用来算。我的经验值是单实例 30MB服务器留 50% 内存给系统和其他服务剩下的除以 30MB 就是 maxHot 的上限。比如 8GB 内存的机器maxHot 设 100 左右比较稳。4.3 策略二计算与渲染分离Univer 的一个优势是计算层和渲染层是分开的。这意味着你可以在服务端只跑计算层把渲染交给客户端。具体做法是服务端用 Node.js 跑 Univer 的 core sheets formula负责数据存储、公式计算、权限校验客户端用浏览器跑完整的 Univer负责展示和交互。两边通过 WebSocket 同步数据变更。这样做的好处是服务端的实例可以做得更轻。我实测下来纯计算层的实例内存占用能降到 10MB 左右是完整实例的三分之一。而且计算层不需要渲染CPU 占用也低很多。坏处是架构复杂度上去了需要自己实现一套同步协议。如果你的团队没有协同编辑的经验这块会比较痛苦。4.4 策略三无状态化与快照最激进的策略是彻底无状态化。每次请求都从数据库读快照创建一个临时实例处理完就销毁。这种模式下并发能力取决于数据库的读取速度和实例创建速度。我测过 Univer 实例的创建速度一个空的 workbook 大概 50ms 左右加载 1000 行数据大概 200ms。如果 QPS 是 100那每秒要创建 100 个实例CPU 会吃不消。所以无状态化适合低频场景比如“用户点一下生成报表”这种。高频交互场景还是得用池化。4.5 并发场景下的 Agent 调用优化除了实例管理Agent 本身的调用也要优化。我的经验是批量合并。用户连续修改多个单元格不要每次都调 Agent攒一批再调。我一般设 1 秒的窗口窗口内的修改合并成一次 Agent 请求。结果缓存。同样的输入Agent 的输出应该缓存起来。比如用户把 A1 从 100 改成 200Agent 算出一个结果用户又改回 100Agent 应该直接返回缓存的结果不用重新算。异步化。Agent 调用是慢操作不能阻塞表格的交互。我的做法是把 Agent 调用放到消息队列里表格先响应用户操作Agent 结果算出来了再通过事件推回去。注意异步化会带来一致性问题。用户可能看到表格已经改了但 Agent 的反馈还没到。这个要在 UI 上做 loading 状态让用户知道“后台在算”。5. 从零搭建一个 Agent 表格助手5.1 环境准备与依赖安装我按从零开始的顺序讲一遍。假设你已经装好了 Node.js建议 18 以上热词里提到的 22.12 也可以先建项目mkdir univer-agent-demo cd univer-agent-demo npm init -y然后装依赖。服务端只需要核心包npm install univerjs/core univerjs/sheets univerjs/engine-formula如果你还要在浏览器里展示再加 UI 相关的npm install univerjs/sheets-ui univerjs/ui univerjs/design这里有个版本坑要注意Univer 的包版本要一致不能 core 用 0.1.x 而 sheets 用 0.2.x会报类型不匹配。我一般用npm install univerjs/corelatest统一装最新版或者锁定同一个版本号。5.2 服务端初始化与数据写入服务端初始化的代码我前面给过这里补充数据写入的部分。假设 Agent 生成了一批销售数据要写进表格const sheet workbook.getActiveSheet(); // 写入表头 sheet.getRange(A1:C1).setValues([[产品, 销量, 单价]]); // 写入数据 const data [ [产品A, 100, 25.5], [产品B, 200, 18.0], [产品C, 150, 32.0], ]; sheet.getRange(A2:C4).setValues(data); // 写入公式 sheet.getRange(D2).setFormula(B2*C2); sheet.getRange(D3).setFormula(B3*C3); sheet.getRange(D4).setFormula(B4*C4); // 写入合计 sheet.getRange(D5).setFormula(SUM(D2:D4));写完之后你可以通过getValue读回计算结果const total sheet.getRange(D5).getValue(); console.log(合计:, total); // 应该输出 25.5*100 18*200 32*150 10950这个“写入公式、读回结果”的能力是 Agent 做自检的基础。Agent 生成公式后可以自己读一遍结果判断是否符合预期不符合就重试。5.3 权限配置与用户交互权限配置我前面详细讲过这里补充一个完整的初始化流程function setupAgentSheet(univerAPI) { const workbook univerAPI.getActiveWorkbook(); const sheet workbook.getActiveSheet(); // 1. 写入 Agent 生成的内容 sheet.getRange(A1:C1).setValues([[产品, 销量, 单价]]); sheet.getRange(A2:C4).setValues([ [产品A, 100, 25.5], [产品B, 200, 18.0], [产品C, 150, 32.0], ]); sheet.getRange(D2:D4).setFormulas([[B2*C2], [B3*C3], [B4*C4]]); sheet.getRange(D5).setFormula(SUM(D2:D4)); // 2. 设置权限 sheet.getRange(A1:D1).setRangePermission({ edit: false }); sheet.getRange(D2:D5).setRangePermission({ edit: false }); sheet.getRange(A2:C4).setRangePermission({ edit: true }); // 3. 监听用户修改 workbook.onCommandExecuted((command) { if (command.id sheet.command.set-range-values) { debouncedHandleEdit(command.params); } }); }这段代码跑起来用户看到的就是一个“表头和公式锁死、数据区可填”的表格。用户改了销量或单价D 列的公式会自动重算Agent 也能通过事件知道改了什么。5.4 与 LLM 对接的完整链路最后把 Agent 接进来。我用一个简化的例子说明链路async function handleUserEdit(params) { const { range, value } params; // 1. 读取当前表格的完整状态 const sheet univerAPI.getActiveWorkbook().getActiveSheet(); const snapshot sheet.getSnapshot(); // 2. 构造 prompt 给 LLM const prompt 当前表格数据${JSON.stringify(snapshot)} 用户刚刚修改了 ${range}新值是 ${value}。 请分析这个修改是否合理如果不合理给出建议。 ; // 3. 调用 LLM const response await callLLM(prompt); // 4. 根据 LLM 的反馈决定是否要修改表格 if (response.shouldUpdate) { sheet.getRange(response.targetRange).setValue(response.newValue); } // 5. 给用户提示 showNotification(response.message); }这个链路的关键是快照的粒度。全量快照数据量大LLM 的 token 消耗高增量快照信息少LLM 可能判断不准。我的经验是对于小表格100 行以内用全量大表格用“修改区域 上下文若干行”的增量。5.5 一个完整的实操案例预算填报助手我把上面所有东西串起来讲一个完整的案例。场景是财务部门要填一份季度预算表Agent 负责生成模板、校验数据、汇总结果。第一步Agent 生成模板。表头是“部门、Q1预算、Q2预算、Q3预算、Q4预算、合计”合计列是公式。第二步设置权限。表头和合计列锁定四个季度的预算列开放。第三步用户填报。用户在各个季度列填数合计列自动算。第四步Agent 校验。用户每填一个数Agent 检查是否超过部门上限、是否与历史数据偏差过大。如果异常在单元格上加批注提示。第五步汇总。所有部门填完后Agent 生成一份汇总表按部门、按季度汇总。这个案例里Univer 承担的是“模板载体 权限控制 公式计算 事件通知”四个角色Agent 承担的是“生成 校验 汇总”三个角色。两边通过事件和 API 解耦各干各的。6. 常见问题与排查实录6.1 初始化相关的坑问题Node.js 里 import Univer 报window is not defined。原因是有插件依赖浏览器 API。解决办法是只 import 核心包或者用global.window {}做 shim。我推荐前者干净。问题公式计算结果不对。先检查公式引擎插件有没有注册。Univer 的公式计算是独立插件不注册的话公式就是个字符串不会算。注册代码是univer.registerPlugin(UniverFormulaEnginePlugin)。问题中文乱码。初始化的时候要指定 localenew Univer({ locale: LocaleType.ZH_CN })。不指定的话默认是英文中文可能显示异常。6.2 权限相关的坑问题设置了权限但用户还是能编辑。检查权限设置的顺序。如果先设了 sheet 级权限再设 range 级权限range 级会覆盖 sheet 级。反过来则不行。所以要先设 sheet 级再设 range 级。问题协同场景下权限不同步。Univer 的协同模块默认会同步权限变更但如果你用的是自定义的协同实现需要手动把权限变更纳入同步范围。问题权限设置后公式不重算。权限只影响用户手动编辑不影响程序计算。如果公式不重算检查是不是公式引擎的问题跟权限无关。6.3 并发相关的坑问题实例池化后数据串了。典型的池化 bug。从池里取实例时一定要先清空数据或者用 sessionId 做隔离。我推荐后者每个 session 一个独立实例用完销毁不要复用。问题内存泄漏。Univer 实例销毁时要调用univer.dispose()否则事件监听器不会释放。我踩过这个坑跑了一天内存涨到 4GB。问题Agent 调用把服务打挂。加限流。我的做法是用令牌桶每个用户每秒最多 1 次 Agent 调用超过就排队。同时设一个全局上限比如每秒 100 次超过直接拒绝。6.4 常见问题速查表现象可能原因排查方向import 报错依赖浏览器 API只 import 核心包公式不算公式引擎未注册检查插件注册中文乱码locale 未设置初始化时指定 ZH_CN权限失效设置顺序错误先 sheet 后 range内存泄漏实例未销毁调用 dispose()Agent 超时未做限流加令牌桶数据串号实例复用未清空用 sessionId 隔离6.5 我个人的几条经验第一不要一上来就上协同。协同的复杂度很高如果你的场景是单用户填报先把单机版跑通再考虑协同。第二公式能算的就别让 LLM 算。LLM 算数不靠谱公式引擎算数靠谱。让 LLM 生成公式让 Univer 算结果这是最稳的分工。第三权限要前置设计。不要等表格做完了再想权限要在设计表格结构的时候就规划好哪些锁定、哪些开放。第四快照要控制大小。给 LLM 的快照不要超过 2000 token超了就截断或者摘要。我一般只传修改区域前后各 10 行。第五测试要覆盖边界。空表格、满表格、公式循环引用、权限冲突这些边界情况都要测。我吃过亏上线后用户填了个空值公式直接报错。这套东西我陆陆续续做了大半年从最早的“用 openpyxl 硬扛”到现在的“Univer Agent”中间换过三次方案。Univer 不是完美的它的文档还在完善某些 API 会变社区也不算大。但它在“Agent 友好的 Office 运行时”这个定位上目前我没找到更好的替代品。如果你也在做类似的东西建议先从服务端计算这个最简单的场景入手跑通了再往上加交互和协同这样踩的坑会少很多。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →