戰(zhàn):我們?nèi)绾巫?AI 直接操作一個(gè)真實(shí)的 VR 全景 SaaS 平臺(tái))
最近我們?cè)谲吩迫吧暇€了一套 MCP 服務(wù)。這次做的事情不是再給 SaaS 后臺(tái)增加一個(gè) AI 聊天框而是嘗試解決一個(gè)更實(shí)際的問(wèn)題能不能讓 AI 不只是告訴用戶“應(yīng)該怎么操作”而是真正調(diào)用業(yè)務(wù)系統(tǒng)完成操作目前第一版已經(jīng)接入了作品、場(chǎng)景、素材、背景音樂(lè)、語(yǔ)音講解、熱點(diǎn)等 VR 全景業(yè)務(wù)能力。用戶可以直接使用自然語(yǔ)言描述需求例如查詢一下我最近創(chuàng)建的全景作品。看看這個(gè)作品有哪些場(chǎng)景。給這個(gè)作品找一首適合展廳的背景音樂(lè)。給大廳場(chǎng)景生成一段語(yǔ)音講解。在入口場(chǎng)景添加一個(gè)跳轉(zhuǎn)到展廳的熱點(diǎn)。AI 根據(jù)任務(wù)選擇對(duì)應(yīng)的 MCP 工具調(diào)用芊云全景真實(shí)業(yè)務(wù)接口然后把執(zhí)行結(jié)果返回給用戶。從產(chǎn)品交互角度看這意味著 AI 開(kāi)始從回答問(wèn)題逐漸變成理解任務(wù) → 選擇工具 → 執(zhí)行業(yè)務(wù) → 返回結(jié)果 → 繼續(xù)處理。本文主要分享這次實(shí)踐背后的思路。一、為什么我們沒(méi)有繼續(xù)做一個(gè) AI 聊天框現(xiàn)在很多 SaaS 產(chǎn)品接入 AI 的第一反應(yīng)是在頁(yè)面右下角增加一個(gè)聊天窗口。用戶可以問(wèn)怎么修改作品名稱AI 回答請(qǐng)打開(kāi)作品管理然后點(diǎn)擊編輯……從知識(shí)問(wèn)答的角度這當(dāng)然有價(jià)值。但實(shí)際使用一段時(shí)間以后會(huì)發(fā)現(xiàn)一個(gè)明顯的問(wèn)題AI 最終還是把工作重新交給了用戶。用戶仍然需要找到正確頁(yè)面找到對(duì)應(yīng)作品進(jìn)入編輯器找到具體配置填寫參數(shù)保存再檢查結(jié)果。也就是說(shuō)AI 優(yōu)化了“怎么做”的學(xué)習(xí)成本卻沒(méi)有真正降低“執(zhí)行”的成本。而 VR 全景平臺(tái)本身又是一個(gè)典型的復(fù)雜 SaaS。一個(gè)完整作品可能包含作品基礎(chǔ)信息數(shù)十個(gè)全景場(chǎng)景圖片、視頻、音頻素材場(chǎng)景熱點(diǎn)場(chǎng)景跳轉(zhuǎn)關(guān)系背景音樂(lè)語(yǔ)音講解導(dǎo)覽邏輯插件發(fā)布和傳播配置隨著平臺(tái)功能越來(lái)越多傳統(tǒng)做法只能不斷增加菜單、按鈕、彈窗、配置頁(yè)面。所以我們開(kāi)始思考另一條路線軟件繼續(xù)負(fù)責(zé)提供可靠的業(yè)務(wù)能力AI 負(fù)責(zé)理解用戶真正想完成什么。這也是這次接入 MCP 的核心原因。二、MCP 到底解決了什么MCP全稱Model Context Protocol如果不討論協(xié)議細(xì)節(jié)可以把它簡(jiǎn)單理解為讓 AI 以標(biāo)準(zhǔn)方式發(fā)現(xiàn)和調(diào)用外部工具。傳統(tǒng)大模型擅長(zhǎng)的是用戶 ↓ 自然語(yǔ)言 ↓ 大模型 ↓ 生成文字加入工具以后流程變成用戶 ↓ 自然語(yǔ)言 ↓ AI / Agent ↓ 理解任務(wù) ↓ 選擇工具 ↓ 調(diào)用真實(shí)業(yè)務(wù) ↓ 獲得結(jié)果 ↓ 繼續(xù)推理 / 執(zhí)行因此MCP 真正有價(jià)值的地方并不是“又多了一個(gè)協(xié)議”。而是它讓 AI 和真實(shí)軟件能力之間有了一層相對(duì)標(biāo)準(zhǔn)化的連接方式。對(duì)于 SaaS 產(chǎn)品而言這個(gè)變化尤其重要。三、芊云全景的 MCP 架構(gòu)我們目前的整體思路大致可以抽象成┌────────────────────────────┐ │ 支持 MCP 的 AI 客戶端 │ │ │ │ Chat / Agent / AI Workflow │ └─────────────┬──────────────┘ │ │ MCP ▼ ┌────────────────────────────┐ │ 芊云全景 MCP 入口 │ │ │ │ 鑒權(quán) / 限流 / Schema / 路由 │ └─────────────┬──────────────┘ │ ┌───────┼────────┐ │ │ │ ▼ ▼ ▼ 作品工具 場(chǎng)景工具 素材工具 │ │ │ ├───────┼────────┤ ▼ ▼ ▼ 音樂(lè)工具 語(yǔ)音工具 熱點(diǎn)工具 │ ▼ 芊云全景真實(shí)業(yè)務(wù)服務(wù)這里有一個(gè)設(shè)計(jì)原則非常重要MCP 不應(yīng)該繞過(guò)原業(yè)務(wù)系統(tǒng)重新實(shí)現(xiàn)一套業(yè)務(wù)邏輯。MCP 更適合作為 AI 與業(yè)務(wù)系統(tǒng)之間的適配層。真正的權(quán)限判斷數(shù)據(jù)隔離業(yè)務(wù)校驗(yàn)數(shù)據(jù)修改狀態(tài)管理仍然應(yīng)該由原有業(yè)務(wù)服務(wù)負(fù)責(zé)。否則 MCP 很容易逐漸發(fā)展成第二套后端。四、我們沒(méi)有把所有 API 直接暴露給 AI這是做 MCP 時(shí)一個(gè)很容易踩的坑。假設(shè)后臺(tái)有 200 個(gè) API。最簡(jiǎn)單粗暴的方式是把 200 個(gè)接口全部包裝成工具。理論上可行。實(shí)際上 AI 的工具選擇質(zhì)量很容易迅速下降。工具越多名稱越接近參數(shù)越相似上下文越大選擇錯(cuò)誤概率越高后續(xù)維護(hù)成本也越高。所以我們的第一版采用了分層能力設(shè)計(jì)。大致按照業(yè)務(wù)域劃分作品 ├── 查詢作品 ├── 讀取詳情 ├── 創(chuàng)建作品 ├── 修改信息 └── 作品評(píng)分 場(chǎng)景 ├── 查詢場(chǎng)景 ├── 場(chǎng)景詳情 ├── 修改場(chǎng)景 └── 刪除場(chǎng)景 素材 ├── 查詢 ├── 上傳 ├── 修改 ├── 刪除 └── 下載 背景音樂(lè) ├── 音樂(lè)搜索 ├── 標(biāo)簽 ├── 智能匹配 └── 配置作品音樂(lè) 語(yǔ)音講解 ├── 主播查詢 ├── 文字轉(zhuǎn)語(yǔ)音 ├── 任務(wù)查詢 └── 添加作品講解 熱點(diǎn) ├── 查詢熱點(diǎn) ├── 文本熱點(diǎn) └── 場(chǎng)景跳轉(zhuǎn)熱點(diǎn)用戶并不需要知道這些工具叫什么。比如用戶只需要說(shuō)幫我找一下最近發(fā)布的那個(gè)展廳作品。AI 再去決定應(yīng)該調(diào)用哪個(gè)工具。五、Schema 對(duì) AI 工具調(diào)用非常重要真正把 MCP 接到業(yè)務(wù)以后一個(gè)很現(xiàn)實(shí)的問(wèn)題是AI 會(huì)填錯(cuò)參數(shù)。例如ID 類型錯(cuò)誤枚舉錯(cuò)誤必填字段缺失字段名稱猜錯(cuò)不應(yīng)該傳的字段也傳了同一個(gè)業(yè)務(wù)概念存在多個(gè) ID所以我們給不同工具分別定義了比較明確的 Schema。理想情況下一個(gè)工具不僅應(yīng)該告訴 AI“這個(gè)工具是修改作品的?!边€應(yīng)該明確告訴它每個(gè)參數(shù)是什么意思哪些字段必填數(shù)據(jù)類型是什么枚舉有哪些哪些字段不能同時(shí)出現(xiàn)一個(gè)正確調(diào)用應(yīng)該長(zhǎng)什么樣。當(dāng)調(diào)用失敗以后也盡量返回可以讓 AI 自己修正的結(jié)構(gòu)化錯(cuò)誤。這樣才有機(jī)會(huì)形成第一次調(diào)用 ↓ 參數(shù)錯(cuò)誤 ↓ 讀取錯(cuò)誤信息 ↓ 自動(dòng)修正參數(shù) ↓ 第二次調(diào)用成功而不是每次失敗都重新把問(wèn)題丟給用戶。六、一個(gè)真實(shí)使用過(guò)程是什么樣的比如用戶告訴 AI幫我看看最近的幾個(gè)全景作品。AI 首先調(diào)用作品查詢工具。返回作品 A 作品 B 作品 C ...用戶繼續(xù)看一下作品 B 有哪些場(chǎng)景。AI 再調(diào)用場(chǎng)景工具。拿到大廳 展廳 會(huì)議室 走廊 ...然后用戶說(shuō)給大廳找一首輕松一點(diǎn)的背景音樂(lè)。AI 可以繼續(xù)調(diào)用音樂(lè)搜索或者智能匹配工具。返回幾首候選音樂(lè)。用戶確認(rèn)后再執(zhí)行設(shè)置背景音樂(lè)。整個(gè)過(guò)程中用戶并不需要先理解背景音樂(lè)在哪個(gè)頁(yè)面配置也不需要記住作品 ID、音樂(lè) ID、對(duì)應(yīng)接口參數(shù)分別是什么AI 負(fù)責(zé)把自然語(yǔ)言需求轉(zhuǎn)換成業(yè)務(wù)系統(tǒng)可以執(zhí)行的調(diào)用。七、真正值得關(guān)注的是“連續(xù)任務(wù)”如果 MCP 只能完成查詢一條數(shù)據(jù)。其實(shí)價(jià)值還比較有限。Agent 更有意思的地方在于一個(gè)用戶目標(biāo)往往會(huì)對(duì)應(yīng)多個(gè)工具調(diào)用。比如用戶說(shuō)幫我檢查一下這個(gè)全景作品還有哪些地方需要優(yōu)化。未來(lái) AI 可以按照類似流程處理讀取作品 ↓ 查詢?nèi)繄?chǎng)景 ↓ 檢查作品信息 ↓ 讀取熱點(diǎn) ↓ 檢查背景音樂(lè) ↓ 檢查語(yǔ)音講解 ↓ 讀取作品評(píng)分 ↓ 匯總問(wèn)題 ↓ 給出優(yōu)化建議 ↓ 用戶確認(rèn) ↓ 繼續(xù)執(zhí)行修改這時(shí)候用戶描述的是一個(gè)業(yè)務(wù)目標(biāo)。而不是某個(gè)按鈕操作。我認(rèn)為這才是 Agent 對(duì) SaaS 軟件最有價(jià)值的地方。八、讀操作容易寫操作才是真正的難點(diǎn)讓 AI 查詢作品并不危險(xiǎn)。讓 AI修改作品刪除場(chǎng)景上傳素材添加熱點(diǎn)發(fā)布內(nèi)容性質(zhì)就完全不同了。所以做生產(chǎn)環(huán)境 MCP 時(shí)不能把重點(diǎn)只放在“AI 能不能調(diào)通接口”還需要考慮1. 身份認(rèn)證AI 當(dāng)前到底代表哪個(gè)用戶2. 數(shù)據(jù)權(quán)限這個(gè)用戶是否真的有權(quán)限操作目標(biāo)作品3. 參數(shù)校驗(yàn)AI 生成的參數(shù)是否合法4. 限流如果 Agent 出現(xiàn)循環(huán)調(diào)用怎么辦5. 高風(fēng)險(xiǎn)操作刪除、發(fā)布、批量修改是否應(yīng)該額外確認(rèn)6. 操作復(fù)查寫操作完成后是否應(yīng)該重新查詢驗(yàn)證結(jié)果我們目前的 MCP 服務(wù)入口會(huì)經(jīng)過(guò)開(kāi)發(fā)者 Key ↓ 身份識(shí)別 ↓ 請(qǐng)求限流 ↓ Schema 校驗(yàn) ↓ 業(yè)務(wù)權(quán)限 ↓ 真實(shí)業(yè)務(wù)服務(wù)也就是說(shuō)AI 獲得的是工具使用能力不是繞開(kāi)系統(tǒng)權(quán)限的超級(jí)管理員權(quán)限。這是兩件完全不同的事情。九、為什么我們還做了一個(gè)9kvrnpm 包MCP 解決的是AI 如何調(diào)用芊云全景能力。但對(duì)于開(kāi)發(fā)者而言還存在另外一個(gè)問(wèn)題如何真正開(kāi)發(fā)和擴(kuò)展 VR 全景應(yīng)用所以我們同時(shí)維護(hù)了官方 npm 包npx 9kvr目前9kvr同時(shí)承擔(dān)兩類職責(zé)CLI SDKCLI負(fù)責(zé)插件開(kāi)發(fā)生命周期登錄 ↓ 初始化插件 ↓ 本地開(kāi)發(fā) ↓ 構(gòu)建 ↓ 發(fā)布 ↓ 上線例如npx 9kvr login --key開(kāi)發(fā)者Key初始化插件npx 9kvr plugin 插件ID發(fā)布npx 9kvr pub上線指定歷史版本npx 9kvr online --history-idID十、SDK 解決的是 VR 宿主能力除了 CLI9kvr還提供插件 SDK。開(kāi)發(fā)者不需要直接依賴底層全景播放器內(nèi)部對(duì)象。目前已經(jīng)覆蓋插件生命周期插件上下文場(chǎng)景讀取和切換視角控制熱點(diǎn)添加、更新、刪除熱點(diǎn)點(diǎn)擊事件宿主事件插件配置渲染狀態(tài)調(diào)試能力例如import { definePlugin, useScene, useDebug } from 9kvr export default definePlugin({ setup() { const scene useScene() const debug useDebug() scene.onSceneChange((packet) { debug.log(scene changed, packet) }) return { mount(el) { el.innerHTML 當(dāng)前場(chǎng)景${scene.getCurrentSceneId()} } } } })開(kāi)發(fā)者可以繼續(xù)操作場(chǎng)景await scene.switchScene(scene-id)或者調(diào)整視角await scene.setView({ hlookat: 90, vlookat: 0, fov: 80, duration: 800 })也就是說(shuō)現(xiàn)在正在逐漸形成這樣一套關(guān)系芊云全景 │ ┌──────────┴──────────┐ │ │ MCP 9kvr │ CLI SDK │ │ AI Agent 開(kāi)發(fā)者 │ │ └──────────┬──────────┘ │ VR 全景能力十一、下一步讓 AI 不只使用平臺(tái)還能幫助開(kāi)發(fā)平臺(tái)能力這是我們認(rèn)為更有意思的一件事情。第一階段AI 幫用戶使用芊云。比如管理作品、場(chǎng)景和素材。再往后AI 幫開(kāi)發(fā)者開(kāi)發(fā)芊云插件。例如開(kāi)發(fā)者說(shuō)幫我做一個(gè)場(chǎng)景導(dǎo)航插件。AI 可以查詢芊云插件開(kāi)發(fā)規(guī)范讀取 SDK 能力創(chuàng)建插件工程編寫代碼調(diào)試構(gòu)建發(fā)布測(cè)試版本。于是自然語(yǔ)言 ↓ AI ↓ MCP 獲取平臺(tái)上下文 ↓ 9kvr 創(chuàng)建開(kāi)發(fā)工程 ↓ SDK 開(kāi)發(fā) ↓ 構(gòu)建 / 發(fā)布這也是我們持續(xù)建設(shè) MCP、CLI、SDK 和插件體系的原因。它們并不是幾個(gè)完全獨(dú)立的功能。最終目標(biāo)其實(shí)是一致的讓 AI 真正進(jìn)入 VR 全景內(nèi)容生產(chǎn)和開(kāi)發(fā)工作流。十二、MCP 不會(huì)讓傳統(tǒng)后臺(tái)立刻消失這里也需要說(shuō)一個(gè)比較現(xiàn)實(shí)的判斷。Agent 并不會(huì)馬上替代全部 GUI。比如精細(xì)調(diào)整一個(gè)熱點(diǎn)的位置觀察復(fù)雜的全景空間關(guān)系大量素材的視覺(jué)篩選精確的 UI 配置很多工作依然更適合圖形界面。所以更可能出現(xiàn)的形態(tài)是AI Agent 負(fù)責(zé) 理解目標(biāo) 批量操作 自動(dòng)檢查 查找能力 串聯(lián)流程 GUI 負(fù)責(zé) 精確編輯 視覺(jué)操作 結(jié)果確認(rèn) 復(fù)雜配置兩者并不是競(jìng)爭(zhēng)關(guān)系。而是AI 正在成為軟件新的操作入口。十三、我們對(duì) AI SaaS 的一個(gè)判斷過(guò)去的軟件使用方式是用戶學(xué)習(xí)軟件 ↓ 理解菜單 ↓ 理解按鈕 ↓ 理解參數(shù) ↓ 完成任務(wù)未來(lái)可能逐漸變成用戶描述目標(biāo) ↓ AI 理解意圖 ↓ AI 調(diào)用工具 ↓ 軟件執(zhí)行 ↓ 用戶驗(yàn)收結(jié)果這里真正發(fā)生變化的不只是有沒(méi)有 AI。而是軟件的人機(jī)交互模型正在發(fā)生變化。對(duì)于復(fù)雜 SaaS 來(lái)說(shuō)尤其如此。功能越多、業(yè)務(wù)流程越長(zhǎng)Agent 能夠提供的價(jià)值反而越明顯。最后芊云小助手 MCP 第一版目前已經(jīng)正式上線?,F(xiàn)階段已經(jīng)接入作品管理場(chǎng)景管理素材管理背景音樂(lè)語(yǔ)音講解熱點(diǎn)管理芊云知識(shí)查詢部分開(kāi)發(fā)者能力這仍然只是第一階段。我們接下來(lái)會(huì)繼續(xù)嘗試讓 AI 從“知道怎么做”逐漸變成“真正幫助用戶做完”。對(duì)于我們來(lái)說(shuō)MCP 最值得關(guān)注的也不是協(xié)議本身。而是它背后的變化AI 正在開(kāi)始真正進(jìn)入軟件。相關(guān)地址芊云小助手 MCPhttps://9kvr.cn/html/qianyun_mcp_assistant.html芊云小助手工作臺(tái)https://9kvr.cn/tour/workbench/robot9kvr 官方 npm 包https://www.npmjs.com/package/9kvr芊云全景https://9kvr.cn/