:Univer 開源 SDK 接入與實操指南)
1. 為什么“AI Agent 辦公應用”這個組合值得單獨聊AI Agent 這個詞在過去一年多里被反復提及但真正落到“能干活”的場景其實并不多。大部分演示停留在問答、檢索、寫幾段文案一旦讓它去操作一個真實的電子表格、改一份文檔、生成一張帶格式的報表立刻就露怯了。原因不復雜Agent 需要一個能被程序化操控的“工作臺”而傳統(tǒng)辦公軟件要么是封閉的桌面程序要么是面向人類交互設計的 Web 界面根本沒有給 Agent 留出穩(wěn)定的操作接口。Univer 這個項目切入的正是這個縫隙。它把自己定位成“面向 AI Agent 的開源辦公應用 SDK”說白了就是提供一套可編程的表格、文檔、幻燈片內(nèi)核讓開發(fā)者能在自己的產(chǎn)品里嵌入辦公能力同時讓 AI Agent 通過 API 直接讀寫單元格、樣式、公式、批注這些結構化對象而不是靠模擬鼠標點擊去“猜”界面。這個定位很關鍵因為它決定了 Univer 不是又一個在線 Excel 的克隆品而是一層基礎設施。我第一次接觸這類需求是在做一個內(nèi)部數(shù)據(jù)填報工具的時候。業(yè)務方希望用戶能在網(wǎng)頁里編輯表格同時后臺的自動化流程要能直接改某些單元格的值并觸發(fā)重算。當時試過幾種方案用現(xiàn)成的在線表格組件API 能力弱改個公式得繞一大圈自己用 canvas 畫表格光是公式引擎和協(xié)同沖突處理就能拖垮整個排期。Univer 這類項目的價值就在于它把公式引擎、渲染、協(xié)同、插件體系這些臟活累活都封裝好了你只需要關心業(yè)務邏輯和 Agent 的接入方式。這篇文章適合幾類人看一是正在做 AI Agent 產(chǎn)品、需要給 Agent 配一個“辦公操作面板”的開發(fā)者二是想在自己的 SaaS 里嵌入表格或文檔編輯能力、又不想從零造輪子的團隊三是對開源辦公內(nèi)核感興趣、想研究公式引擎和協(xié)同架構的技術人。我會從整體設計思路、核心模塊拆解、實操接入步驟、常見坑這幾個角度展開盡量把“為什么這么設計”講清楚而不是只羅列 API。2. Univer 的整體設計與架構思路拆解2.1 它到底解決的是哪一層問題要理解 Univer 的定位先得把“辦公應用”拆成幾層。最底層是數(shù)據(jù)模型比如一個表格由工作表、行、列、單元格、樣式、公式、批注等對象組成往上是計算引擎負責公式解析、依賴圖、重算再往上是渲染層把數(shù)據(jù)畫到 canvas 或 DOM 上最上面是交互層處理選區(qū)、拖拽、快捷鍵、菜單。傳統(tǒng)辦公軟件把這四層揉在一起對外只暴露一個給人用的界面。Univer 的做法是把它們拆開每一層都可以被程序調(diào)用。這個拆分對 AI Agent 特別友好。Agent 不需要去理解“用戶點了哪個按鈕”它只需要調(diào)用類似setCellValue(sheetId, row, col, value)或者setFormula(...)這樣的方法然后觸發(fā)一次重算再讀取結果。整個過程是確定性的、可測試的不會因為界面改版就失效。這也是為什么 Univer 強調(diào)自己是 SDK 而不是應用——它把“辦公能力”變成了一組可組合的模塊。從架構上看Univer 采用了插件化 分層依賴的設計。核心包提供基礎的數(shù)據(jù)結構和事件總線公式、渲染、協(xié)同、UI 這些都以插件形式掛載。這樣做的好處是體積可控如果你只需要一個只讀的表格展示可以不引入編輯相關的插件如果你要做協(xié)同編輯再按需加載協(xié)同模塊。對 Agent 場景來說你甚至可以只引入數(shù)據(jù)層和公式層完全不要 UI把它當成一個純計算服務來用。2.2 為什么選擇 Canvas 渲染而不是 DOMUniver 的表格渲染走的是 Canvas 路線這一點和很多輕量表格組件不同。DOM 渲染的優(yōu)點是天然支持無障礙、文本選擇和 CSS 樣式但缺點也很明顯當單元格數(shù)量上萬時DOM 節(jié)點數(shù)量會爆炸滾動和重算都會卡。Canvas 把整個表格畫成一張位圖節(jié)點數(shù)量恒定性能上限高得多。代價是你要自己實現(xiàn)文本測量、選區(qū)繪制、滾動虛擬化、輸入法處理這些細節(jié)。Univer 在這方面做了不少工作比如它維護了一套自己的文本排版邏輯支持富文本、換行、對齊還處理了 Canvas 上的光標和輸入框疊加。對 Agent 來說Canvas 渲染其實是個加分項因為 Agent 不關心視覺細節(jié)它關心的是數(shù)據(jù)操作是否高效。Canvas 方案讓大規(guī)模數(shù)據(jù)的批量修改和重算變得更快Agent 一次改幾千個單元格也不會把頁面拖死。不過這里有個實操注意點如果你要在 Canvas 表格上做自動化測試傳統(tǒng)的 DOM 選擇器是抓不到單元格的。你需要通過 Univer 暴露的 API 去讀取數(shù)據(jù)或者用它的測試工具來斷言。這一點在寫 Agent 的回歸測試時要提前規(guī)劃好否則會走彎路。2.3 公式引擎的獨立性設計公式是辦公表格的靈魂也是 Agent 最容易出錯的環(huán)節(jié)。Univer 把公式引擎做成了相對獨立的模塊支持常見的數(shù)學、統(tǒng)計、文本、日期函數(shù)并且維護了一張依賴圖。當你修改某個單元格時引擎會根據(jù)依賴圖找出所有受影響的單元格按拓撲順序重算而不是全表重算。這個設計對 Agent 很重要。假設 Agent 要在一個預算表里改一個稅率它只需要改那一個單元格引擎會自動把相關的合計、稅額、凈額都更新掉。如果引擎是全表重算大表上每次操作都要幾秒Agent 的多步操作就會變得不可接受。依賴圖的存在讓增量重算成為可能這是 Agent 高頻操作場景下的性能基礎。另外公式引擎和渲染是解耦的。這意味著你可以在沒有界面的環(huán)境里跑公式計算比如在服務端用 Node.js 加載 Univer 的數(shù)據(jù)層和公式層對上傳的表格做批量計算。這個能力在做數(shù)據(jù)導入導出、報表生成的時候非常實用也是很多純前端表格組件做不到的。2.4 協(xié)同能力的預留雖然標題里沒提協(xié)同但 Univer 的架構里給協(xié)同留了位置。它的數(shù)據(jù)變更走的是命令模式每次修改都會產(chǎn)生一個可序列化的操作記錄。這個設計本來是為了撤銷重做但同樣適合做協(xié)同同步——把操作記錄廣播出去其他端按順序應用即可。對 AI Agent 來說這個特性有個隱含價值Agent 的每一次修改都可以被記錄、回放、審計。在需要合規(guī)或者需要人工復核的場景里你可以把 Agent 的操作日志拿出來逐步檢查它改了什么。這比“Agent 直接改了數(shù)據(jù)庫但沒留痕”要可控得多。我在做自動化流程的時候特別看重這一點因為一旦 Agent 改錯了數(shù)據(jù)沒有操作記錄就很難定位問題。3. 核心模塊與實操接入要點3.1 環(huán)境準備與依賴安裝Univer 是 TypeScript 項目主流的接入方式是通過 npm 安裝。核心包通常包括univerjs/core、univerjs/sheets、univerjs/sheets-ui、univerjs/sheets-formula這幾個。如果你要做文檔或幻燈片還有對應的包。安裝的時候要注意版本對齊Univer 的包之間版本號是聯(lián)動的混用不同小版本可能會遇到類型不匹配或者運行時錯誤。npm install univerjs/core univerjs/sheets univerjs/sheets-ui univerjs/sheets-formula安裝完之后你需要創(chuàng)建一個 Univer 實例注冊需要的插件然后把它掛載到一個容器元素上。下面是一個最小化的表格初始化示例import { Univer, LocaleType, merge } from univerjs/core; import { UniverSheetsPlugin } from univerjs/sheets; import { UniverSheetsUIPlugin } from univerjs/sheets-ui; import { UniverSheetsFormulaPlugin } from univerjs/sheets-formula; const univer new Univer({ locale: LocaleType.ZH_CN, theme: defaultTheme, }); univer.registerPlugin(UniverSheetsPlugin); univer.registerPlugin(UniverSheetsUIPlugin); univer.registerPlugin(UniverSheetsFormulaPlugin); univer.createUnit(UniverInstanceType.UNIVER_SHEET, { id: agent-sheet, sheetOrder: [sheet-01], sheets: { sheet-01: { id: sheet-01, name: 數(shù)據(jù)表, rowCount: 1000, columnCount: 26, cellData: {}, }, }, });這段代碼做了三件事創(chuàng)建實例、注冊插件、創(chuàng)建一張工作表。注意rowCount和columnCount決定了表格的初始規(guī)模Agent 如果要處理大數(shù)據(jù)量可以把這個值調(diào)大但也要考慮內(nèi)存占用。實測下來一萬行乘五十列的空白表在瀏覽器里初始化大概幾百毫秒屬于可接受范圍。提示Univer 的包更新比較快接入前建議先看官方倉庫的 release notes確認當前穩(wěn)定版本。不要盲目追最新版尤其是生產(chǎn)環(huán)境。3.2 用 API 操作單元格Agent 的核心動作Agent 操作表格歸根結底就是讀和寫。Univer 提供了基于命令的寫入方式和基于 Facade 的讀寫方式。命令方式更底層適合需要撤銷重做的場景Facade 方式更直觀適合快速開發(fā)。對 Agent 來說我推薦用 Facade因為它的語義更接近“設置某個單元格的值”這種自然語言描述。const sheet univer.getActiveSheet(); const facade sheet.getFacade(); // 寫入一個值 facade.setCellValue(0, 0, 產(chǎn)品名稱); facade.setCellValue(0, 1, 銷量); // 寫入公式 facade.setCellFormula(1, 1, SUM(B2:B10)); // 讀取值 const value facade.getCellValue(1, 1);這里有個細節(jié)要注意行列索引是從 0 開始的而公式里的引用是從 1 開始的。Agent 在生成公式的時候如果它內(nèi)部用的是 0 基索引就很容易差一位。我在做 Agent 的時候就踩過這個坑Agent 說“把第二行第一列設為合計”結果寫到了第三行。解決辦法是在 Agent 的工具層做一次統(tǒng)一的索引轉換不要讓 Agent 直接接觸底層索引。批量寫入的時候逐條調(diào)用setCellValue會有性能問題因為每次調(diào)用都可能觸發(fā)一次重算。更好的做法是用batch或者直接構造命令數(shù)組一次性提交。Univer 的命令系統(tǒng)支持批量執(zhí)行這樣依賴圖只會更新一次重算也只跑一遍。const commands []; for (let i 0; i 100; i) { commands.push({ id: sheet.command.set-range-values, params: { range: { startRow: i, startColumn: 0, endRow: i, endColumn: 0 }, values: [[i * 2]], }, }); } univer.executeCommand(commands);批量提交在 Agent 場景里非常關鍵。Agent 經(jīng)常需要一次性填充幾百行數(shù)據(jù)如果逐條寫頁面會卡到無法交互。我實測過一千條逐條寫入大概要兩三秒批量提交能壓到兩百毫秒以內(nèi)差距很明顯。3.3 公式與依賴圖的實操細節(jié)公式是 Agent 最容易出錯的地方因為公式涉及引用、范圍、函數(shù)簽名這些結構化信息。Univer 的公式引擎支持大部分常用函數(shù)但不同版本支持的范圍會有差異。接入前最好先確認你要用的函數(shù)在不在支持列表里尤其是財務函數(shù)和數(shù)組函數(shù)。寫公式的時候范圍引用要用 A1 表示法比如SUM(A1:A10)。如果你用 API 設置公式字符串里不要帶等號以外的多余空格否則解析可能失敗。下面是一個設置公式并讀取計算結果的例子facade.setCellFormula(9, 1, SUM(B2:B10)); // 等待重算完成 await univer.getActiveSheet().getFormulaEngine().calculate(); const result facade.getCellValue(9, 1);注意重算可能是異步的尤其是在大數(shù)據(jù)量下。Agent 在寫完公式后如果立刻讀值可能讀到的是舊值或者空值。穩(wěn)妥的做法是監(jiān)聽重算完成事件或者在 API 層做一次顯式的 calculate 并等待。我在做自動化報表的時候就遇到過這個問題Agent 寫完公式馬上讀結果拿到的是 undefined排查了半天才發(fā)現(xiàn)是時序問題。依賴圖還有一個特性循環(huán)引用會被檢測出來并報錯。Agent 如果生成了循環(huán)引用比如 A1 引用 B1、B1 又引用 A1引擎會標記錯誤。這時候 Agent 需要能讀懂錯誤信息并修正。建議在 Agent 的工具層把公式錯誤映射成自然語言比如“檢測到循環(huán)引用請檢查 A1 和 B1 的公式”這樣 Agent 更容易自我糾正。3.4 樣式與格式的編程化控制Agent 生成的表格如果只有數(shù)據(jù)沒有格式可讀性會很差。Univer 支持通過 API 設置字體、顏色、邊框、對齊、數(shù)字格式這些樣式。樣式對象的結構和常見的表格庫類似但字段名有自己的約定接入時要查文檔確認。facade.setCellStyle(0, 0, { fontFamily: Arial, fontSize: 12, bold: true, backgroundColor: #f0f0f0, horizontalAlign: center, });數(shù)字格式是個容易被忽略的點。Agent 寫入的如果是金額默認可能顯示成1234.5但業(yè)務上希望顯示成¥1,234.50。Univer 支持通過 number format 來控制顯示你需要設置對應的格式字符串。這個格式只影響顯示不影響底層值所以 Agent 讀到的還是原始數(shù)字不會因為格式化而丟失精度。邊框和合并單元格也是 Agent 常用操作。合并單元格要注意合并后只有左上角的單元格保留值其他單元格的值會被清空。Agent 如果在合并前沒保存數(shù)據(jù)就會丟數(shù)據(jù)。建議在 Agent 的工具層把“合并單元格”實現(xiàn)成“先讀取所有值、合并、再把值寫回左上角”的復合操作避免數(shù)據(jù)丟失。4. 完整實操流程從零接入一個 Agent 可操作的表格4.1 項目初始化與目錄結構假設我們要做一個最小的 Agent 辦公面板前端用 React后端用 Node.js 跑 Agent 邏輯。目錄結構大概是這樣agent-office/ packages/ web/ # 前端嵌入 Univer agent/ # Agent 邏輯調(diào)用 Univer API shared/ # 共享類型和工具函數(shù)前端負責渲染表格和接收用戶輸入Agent 邏輯可以跑在前端也可以跑在后端。如果 Agent 需要調(diào)用外部模型建議放后端避免密鑰泄露。前端通過 WebSocket 或者 HTTP 和后端通信后端把 Agent 的指令轉成 Univer 的命令再同步回前端。這里有個架構選擇Agent 是直接操作前端的 Univer 實例還是操作服務端的一份數(shù)據(jù)副本兩種都可以。直接操作前端實例的延遲低但 Agent 邏輯必須跑在瀏覽器里操作服務端副本更安全但需要做雙向同步。我傾向于后者因為 Agent 的邏輯往往涉及模型調(diào)用和敏感數(shù)據(jù)放服務端更可控。同步可以用 Univer 的命令流把服務端的命令廣播到前端應用。4.2 定義 Agent 可用的工具集Agent 要操作表格需要一組明確的工具。工具的定義要盡量原子化一個工具做一件事參數(shù)要少而清晰。下面是我常用的一組工具定義工具名功能關鍵參數(shù)read_range讀取指定范圍的值sheetId, rangewrite_range寫入一批值sheetId, range, valuesset_formula設置公式sheetId, row, col, formulaapply_style應用樣式sheetId, range, styleinsert_rows插入行sheetId, index, countmerge_cells合并單元格sheetId, rangeget_sheet_info獲取表結構sheetId工具的參數(shù)設計要避免讓 Agent 去猜索引。比如read_range的 range 可以用 A1 表示法Agent 更容易理解“讀取 A1:C10”而不是“讀取第 0 行到第 9 行、第 0 列到第 2 列”。在工具內(nèi)部再做一次轉換把 A1 表示法解析成行列索引。這樣 Agent 的提示詞可以寫得更自然出錯率也低。工具的返回值也要結構化。不要返回一大段自然語言而是返回 JSON讓 Agent 能解析。比如read_range返回{ values: [[...]], formulas: [[...]] }Agent 拿到后可以自己決定下一步。如果返回的是“A1 的值是 100”Agent 還得再做一次文本解析容易出錯。4.3 處理 Agent 的多步操作與事務Agent 做復雜任務時往往是多步的比如“先讀取銷售數(shù)據(jù)按地區(qū)匯總再生成一張新表”。這中間任何一步失敗都可能留下半成品。Univer 的命令系統(tǒng)支持撤銷但 Agent 不一定知道怎么撤銷。更好的做法是在工具層做事務封裝把一組操作打包成一個事務要么全成功要么全回滾。實現(xiàn)方式可以是在執(zhí)行前記錄一個快照失敗時恢復到快照。Univer 的數(shù)據(jù)層支持序列化你可以把當前工作表的狀態(tài)存下來出錯時反序列化回去。這個快照不需要很深只存受影響的范圍即可避免大表上快照開銷過大。另一個細節(jié)是并發(fā)。如果多個 Agent 同時操作同一張表或者 Agent 和用戶同時操作就可能沖突。Univer 的命令流是有序的但如果你在服務端和前端各有一份狀態(tài)就要保證命令的應用順序一致。我的做法是給每個命令帶一個遞增的序號接收方按序號應用亂序的緩存起來等前序到達。這個機制和協(xié)同編輯里的 OT 或 CRDT 思路類似但實現(xiàn)可以簡化很多因為 Agent 場景下并發(fā)度通常不高。4.4 前端渲染與交互的銜接前端嵌入 Univer 后用戶和 Agent 操作的是同一張表。用戶手動改了一個單元格Agent 應該能感知到Agent 改了數(shù)據(jù)用戶界面也要實時更新。Univer 的事件總線可以監(jiān)聽數(shù)據(jù)變更把變更同步給 Agent 的上下文。univer.getActiveSheet().onCellChanged((event) { // 把變更推送給 Agent 的上下文 agentContext.updateCell(event.row, event.col, event.value); });這里要注意事件風暴。用戶快速輸入時會產(chǎn)生大量變更事件如果每個事件都推給 AgentAgent 的上下文會被刷爆。建議做一層節(jié)流比如 200 毫秒合并一次只推送最終狀態(tài)。Agent 不需要知道用戶按了哪些鍵它只需要知道最終的數(shù)據(jù)是什么。還有一個體驗問題Agent 操作表格時用戶應該能看到過程。如果 Agent 一次性改了五百個單元格界面直接跳到最終狀態(tài)用戶會一臉懵??梢栽?Agent 的工具層加一個“逐步應用”的選項每批操作之間留一點間隔讓用戶看到變化。這個間隔不用太長50 到 100 毫秒就夠既能看到過程又不至于太慢。5. 常見問題與排查技巧實錄5.1 公式不重算或重算結果不對這是接入初期最常見的問題。表現(xiàn)是設置了公式但單元格顯示的還是舊值或者顯示#ERROR。排查順序是這樣的先確認公式字符串本身是否合法有沒有多余空格、括號是否匹配、函數(shù)名是否拼錯再確認依賴的單元格是否有值如果依賴的是空單元格某些函數(shù)會返回 0 而不是報錯最后確認重算是否被觸發(fā)Univer 的公式引擎在數(shù)據(jù)變更后會自動標記臟區(qū)但如果你直接改了底層數(shù)據(jù)而沒走命令可能不會觸發(fā)重算。解決辦法是統(tǒng)一走 Facade 或命令 API不要直接改數(shù)據(jù)對象。如果確實需要直接改改完后手動調(diào)用一次calculate()。另外公式里的范圍引用如果超出了表格的實際行列數(shù)也可能導致計算異常。建議在 Agent 生成公式后做一次范圍校驗確保引用在有效范圍內(nèi)。5.2 大數(shù)據(jù)量下的性能瓶頸當表格行數(shù)超過五千、或者 Agent 頻繁批量寫入時可能會遇到卡頓。瓶頸通常出現(xiàn)在三個地方渲染、重算、事件通知。渲染方面Canvas 雖然比 DOM 快但如果每次變更都全量重繪依然會卡。Univer 內(nèi)部有臟區(qū)重繪機制但如果你繞過了它直接操作就會觸發(fā)全量重繪。重算方面依賴圖越大單次重算越慢尤其是跨表引用多的時候。事件通知方面如果每個單元格變更都觸發(fā)一次事件監(jiān)聽方處理不過來就會堆積。優(yōu)化手段包括批量提交命令、限制單次操作的范圍、關閉不必要的事件監(jiān)聽、對大數(shù)據(jù)表做分頁或虛擬滾動。我實測過一個一萬行乘二十列的表批量寫入一千行數(shù)據(jù)如果不做優(yōu)化大概要三到四秒做了批量提交和關閉中間事件后能壓到一秒以內(nèi)。對于 Agent 場景還可以考慮把重計算放到 Web Worker 里避免阻塞主線程。5.3 Agent 生成的公式引用錯位前面提過索引問題這里再展開一下。Agent 通常用自然語言描述位置比如“第二行第三列”模型在轉成代碼時可能把“第二行”理解成索引 2 而不是索引 1。如果 Agent 直接生成 A1 表示法比如C2出錯概率會低一些因為 A1 表示法和人類的行列描述更接近。建議在工具層強制使用 A1 表示法內(nèi)部再做轉換。還有一個相關問題是相對引用和絕對引用的混淆。Agent 如果生成A1B1然后往下拖拽相對引用會變成A2B2這可能是它想要的也可能不是。如果 Agent 想固定引用某一行應該用$A$1。在工具層可以提供一個“填充公式”的工具讓 Agent 指定源公式和目標范圍由工具來處理相對引用的偏移而不是讓 Agent 自己算。5.4 樣式設置不生效樣式不生效的原因通常有幾個一是樣式對象字段名寫錯Univer 的樣式字段和 CSS 不完全一樣比如背景色是backgroundColor而不是background二是樣式被后設置的樣式覆蓋比如你先設了紅色又設了默認樣式結果紅色沒了三是樣式應用到了錯誤的范圍比如行列索引差一位。排查的時候可以先把樣式設到一個單元格上確認生效后再擴展到范圍。如果范圍樣式不生效檢查范圍的起止行列是否正確。另外合并單元格的樣式要設在左上角單元格上設在其他被合并的單元格上不會顯示。這個細節(jié)在文檔里不一定顯眼但實際用的時候很容易踩。5.5 常見問題速查表現(xiàn)象可能原因排查方向公式顯示 #ERROR公式語法錯誤或引用無效檢查函數(shù)名、括號、范圍寫入后讀不到值異步重算未完成等待 calculate 完成再讀批量寫入卡頓逐條提交觸發(fā)多次重算改用批量命令提交樣式不顯示字段名錯誤或范圍錯誤單單元格測試后擴展Agent 改錯位置索引基準不一致統(tǒng)一用 A1 表示法合并后數(shù)據(jù)丟失合并清空非左上角值合并前先保存值事件重復觸發(fā)未做節(jié)流合并高頻事件6. 我對這類項目的一點實際體會接入 Univer 做 Agent 辦公能力最深的體會是“接口的穩(wěn)定性比功能的豐富度更重要”。Agent 不像人類它不會因為界面好看就容忍 API 的反復無常。一個字段名改了、一個索引基準變了Agent 的整條鏈路就可能崩掉。所以在選型的時候我會優(yōu)先看這個項目的 API 是否穩(wěn)定、是否有版本化的文檔、是否有測試覆蓋。Univer 在這方面做得還算扎實但快速迭代期難免有 breaking change生產(chǎn)環(huán)境一定要鎖版本。另一個體會是Agent 操作辦公軟件本質(zhì)上是在做“結構化數(shù)據(jù)的增刪改查”而不是“模擬人類操作界面”。凡是讓 Agent 去點按鈕、拖滾動條、識別截圖的方案長期看都不靠譜因為界面一變就全廢。Univer 這種提供編程接口的思路才是正路。如果你正在設計 Agent 產(chǎn)品建議盡早把“操作層”和“展示層”分開讓 Agent 只依賴操作層的 API展示層怎么改都不影響 Agent。最后分享一個小技巧在 Agent 的工具層加一個“dry run”模式讓 Agent 可以先模擬執(zhí)行一遍看看會產(chǎn)生什么變更確認無誤后再真正提交。這個模式在調(diào)試階段特別有用能避免 Agent 把測試數(shù)據(jù)寫進生產(chǎn)表。實現(xiàn)上就是在執(zhí)行命令前攔截把命令記錄下來但不應用返回一個預覽結果給 Agent。等 Agent 確認后再真正執(zhí)行。這個機制花不了多少代碼但能省下很多排查數(shù)據(jù)問題的時間。