使用手冊Slima MCP › 結構化編輯工具(update_*)

結構化編輯工具(update_*)

最後更新 2026 年 9 月 9 日 · 閱讀約 10 分鐘

一句話:這篇教你用 update_* 工具,讓外部 AI 工具改節拍看板、年表、劇本、關係圖與世界地圖,而不會把它沒看到的那部分弄丟。

這解決什麼問題

散文檔可以整檔重寫。AI 讀了 .md 的全部,也就送得回全部,最壞的情況是文字寫得不好,你用版本歷史退回去。

結構化檔沒有這個安全網。一份 .beats 裡有幕、有節拍,還有作者拖上去的章節卡;一張 .map 裡有節點、關係線、群組框,以及每個節點在畫布上的位置。叫 AI 把整份 JSON 送回來,等於叫它把沒看到的部分也一起送回來。它會照做,而失敗是安靜的:檔案照樣打得開,只是少了作者的東西。

所以 4.0 的伺服器對這五種副檔名關掉了整檔寫入。write_fileedit_fileappend_to_file 一律被拒,改走一次一個操作的欄位級工具。

副檔名 工具 操作
.beats 節拍看板 update_beat_board add_act / update_act / remove_act / add_beat / update_beat / remove_beat / move_beat
.timeline 年表 update_timeline add_entry / update_entry / remove_entry / set_config
.script 劇本 update_script add_scene / update_scene_heading / remove_scene / add_element / update_element / remove_element
.map 關係圖 update_relationship_map add_node / update_node / move_node / remove_node / add_edge / update_edge / remove_edge / add_group / update_group / remove_group / set_meta
.geomap 世界地圖 update_world_map add_place / update_place / add_label / update_label / remove_element / add_river / add_border / paint_region / set_meta

這張表不用背,也不該當成唯一依據:get_capabilities 會回這台伺服器現在真正認的清單,見指南與寫作技能

每一支都適用的規則

先讀檔。 每一個 id 都要來自那一次讀取,不要憑記憶重打,也不要自己編。送錯 id 會被拒絕,而拒絕訊息會把真實的 id 列出來——所以猜錯只花一次來回,不會動到作者的資料。

一次一個操作。 每個操作只吃自己的參數。把別的操作的欄位混進來會被拒絕,而不是被忽略掉。

op_ref 只在同一批次裡串接。 給新建的東西貼一個標籤 op_ref: "A2",同一批次裡後面的操作就能用 "@A2" 指到它。只能往回指,也只在這一批有效;下一次呼叫要用真實 id,而真實 id 就在上一次回覆的 applied 裡。

整批全有全無。 有一個操作失敗就什麼都不寫,你不必推理「它做到哪裡了」。一次最多 200 個操作,超過會被退回並要你拆成幾批。

一個完整的例子

update_relationship_map({
  "book_token": "bk_...",
  "path": "世界觀/人物關係圖.map",
  "intent": "把溫韞放到裴照旁邊,補上兩人的同僚關係",
  "operations": [
    { "op": "add_node", "label": "溫韞", "op_ref": "N1",
      "position": { "near_id": "n-peizhao", "direction": "right" } },
    { "op": "add_edge", "source_id": "n-peizhao", "target_id": "@N1", "label": "同僚" }
  ]
})

intent 不是註解,它會變成這顆 commit 的名字,也就是作者事後在版本歷史裡讀到的那一行。寫「這一批改了什麼」,不要寫「批次更新」。一行為限,太長會被退回來。

回覆會給你三樣東西:新建物件的真實 id、連帶發生的事(例如刪掉一個節點會一起刪掉它的線),以及這顆 commit 的 token。中間那一項要轉述給作者——那是他會在畫面上看到、但沒有要求過的變化。

沒有審查面板

在 app 裡跟 AI 對話改結構化檔,改動會先變成畫面上的虛線卡,作者按「採納」或「略過」才落地(見審查 AI 的改動)。

MCP 沒有這一層。 從外部工具送出去的一批操作就是一顆 commit,直接進版本歷史。所以動手之前先講你要做什麼,動手之後說你做了什麼,不要送出去再問「這樣可以嗎」。要退回就走版本歷史,跟退回自己寫的段落一樣。而且版本歷史裡沒有任何標記說「這顆 commit 來自外部工具」——一列上只有訊息、時間與字數。你寫的 intent 就是唯一的線索,這也正是它必須寫出內容的原因。

新建一份結構化檔

create_file 對這五種副檔名是可以用的,但你送的內容會被忽略:伺服器會產一份空骨架,檔名會成為檔案裡面那份文件的名字。回覆會明講內容被換掉了。

所以流程是兩步:先 create_file 建一個空的,再用 update_* 一批一批填。

誰能用

寫入這五種型別(刪除也一樣)屬於訂閱方案。免費帳號呼叫會拿到 403,錯誤碼 SUBSCRIPTION_REQUIRED,訊息會說明讀取不受限制:把檔案讀出來、用文字描述你建議的改動,作者可以自己在 app 裡改,或者訂閱之後讓 AI 直接改。

這跟另一種拒絕不一樣。.character.location.json.yaml 拿到的是 AI_READONLY_FILE_TYPE——那不是升級就能解,那些型別沒有欄位級路徑。兩個碼刻意分開,因為下一步完全不同。

各型別自己要注意的

.map 關係圖:位置是內容,不是排版。update_node 不會移動任何東西,移動是 move_node——這樣「我把她移到他旁邊」才會是一筆看得見、退得回的改動。優先用 {near_id, direction} 而不是自己算座標,既有節點不會被推開,最後落在哪裡會在回覆裡告訴你。群組框是從 member_ids 算出來的,永遠不要送寬高座標。

.geomap 世界地圖:座標是格子,不是像素(x 0–519、y 0–363)。read_file 會把三張地形網格換成一句說明——它們是機器編碼的,你不需要讀。paint_region 也是用格子。地形沒有復原,要改就蓋過去。remove_element 吃任何元素 id(pl_ 地點、lb_ 標籤、rv_ 河流、bd_ 邊界)。移動一個地點用 update_place,不要刪掉再加一個。

.timeline 年表:把事件掛到章節上不是這裡做的事,送掛接欄位會被拒絕並說明理由。

.beats 節拍看板:刪掉一幕不會刪掉裡面的節拍,它們會變成未歸幕,回覆會告訴你有幾個。

.script 劇本:一集一檔。場景標題(內外景、地點、時間)用 update_scene_heading,場景裡的動作、角色、對白、括號、轉場、鏡頭用 add_element / update_element

相關

到 Slima 裡試試

打開 app,用你自己的書做一次。免費開始,不用信用卡。

打開 Slima
這篇有幫助嗎?