問題背景
這個專案的起點不是某一個 bug,而是一個每天都在發生的場景:營運遇到問題,第一反應是貼到工程群組問。這張訂單怎麼了、這個規則是什麼、幫我撈個資料——每一題都要一位工程師停下手邊的開發。我要做的事情從頭到尾只有一件:讓營運自己問 AI,就能得到那些原本要問工程師的答案。
微妙的是,當時該有的工具其實都有了:
- 後勤知識助手已經上線半年,能回答文件裡的知識。但文件會過期、檢索對口語問法不夠準——營運試過幾次搜不到之後,依賴度就低了。
- 老闆早就給了營運資料庫唯讀權限,而且他們都在用 Claude Code。所以他們選擇裸查。
裸查的問題在這裡。「這個月業績多少?」聽起來只是一句 SQL,但在我們系統裡:金額必須用 OrderDetailMainView 而非 Orders.TotalPrice,要按產線分組,訂購日期要用 CreateTime 而非 OrdersTime(那是訂閱續扣日),還得排除公益捐款單。任何一項踩錯,數字就是錯的——而且錯得很像對的,因為它會跑出一個看似合理的數字。實際發生過:營運算出來的業績與後台對不上,工程師被叫去對帳,一次耗掉半天。
盤到最後,缺的拼圖只有一塊:code。營運的 AI 讀不到程式碼,遇到「規則現在到底是怎麼運作的」只能靠文件(可能舊了)或用猜的。只要 AI 能同時讀到 code,它就能拿知識庫查到的內容去比對真實的程式碼再給答案,甚至回過頭把過期的文件修掉。
AI 不缺寫 SQL 的能力,缺的是「這家公司的常識」。 這個專案做的事,就是把常識變成基礎設施。
先盤使用者:手上有什麼、缺什麼
動手前我先照 UX 的做法盤了一輪使用者——不是盤功能,是盤每種人現在怎麼過日子:
| 使用者 | 手上有 | 缺的 | 於是 |
|---|---|---|---|
| 營運 | SQL 唯讀權限、Claude Code、知識助手 | 正確查法、code 存取 | 裸查算錯,或排隊問工程師 |
| 客服 | 知識助手 | 文件的新鮮度 | 搜不到就回頭問人 |
| 工程師 | 全部 | 時間 | 一天被打斷好幾次 |
沒有任何一個人缺「權限」或「工具」,缺的是把既有能力接成一條可信的路。 這不是「做一個新功能」的題目,是一個接線的題目——這個認知決定了後面所有設計。
第一個岔路:改後勤知識助手,還是做新工具?
這是整個專案初期花最多篇幅討論的一題。直覺的路線是幫知識助手加能力——使用者已經存在、介面現成,看起來最省。最後我選擇做新工具,三個理由:
- 正式服務不該當實驗場。 知識助手是客服每天在電話中使用的正式服務;把查 DB、讀 code 這些全新能力直接掛上去,每一次迭代都在賭它的穩定性。這個判斷後來被驗證了——唯一一次為了共用能力動到它的部署,就造成兩次短暫中斷(根因是部署方式,但重點是:正式服務承受不起這種賭注)。
- 介面選錯了整個產品就錯了。 知識助手住在 Teams,適合「問一句、答一句」;但目標使用者真正的工作介面已經是 Claude Code——他們要的不是換一個地方打字,是讓自己手上的 AI 變強。MCP 是「給 AI 用的介面」:接上去之後,營運的 Claude、工程的 Claude、未來任何 AI 都能用,不綁死在一個聊天視窗裡。
- 能力可以借,不必搬家。 我沒有複製知識助手的檢索與寫入邏輯——而是讓它對內開兩個小 API,新工具的知識庫搜尋與文件修改都「借」它的能力。全公司的文件寫入邏輯永遠只有一份,不會兩邊各改各的、越走越歪。(也有個現實因素:知識助手是 Node、新工具是 Python,硬塞在一起兩邊都難維護。)
改舊的還是做新的,判準不是成本,是誰在承擔風險。
解決構想
打造一個唯讀的 MCP,將業務邏輯固化為工具。
價值不在於「提供資料庫存取權」——那早就有了。價值在於每次查詢都自動套用正確的查法。業績算法鎖進工具裡,所有人問同一個問題,得到同一個數字。
規劃上是一個核心、兩個出口:同一套工具,Phase 1 先讓營運在 Claude Code 自助查詢、養成習慣;Phase 2 給工程部的自動 triage 用——報錯訊息進來,機器人用同一套工具查完、產出交接文件。核心做穩一次,兩邊受益。
12 支工具的來歷
沒有一支工具是「先想像功能、再找用途」——每一支都對應一句我真的聽過的話。
「這張訂單到底發生什麼事?」 原本的流程:貼單號到工程群,等人撈。現在是 query_sql + query_mongo。設計時的堅持是 Mongo 一定要收:發票真正的開立結果、客人有沒有走到完成頁、遺失訂單的結帳快照——這些真相 SQL 裡沒有,只接 SQL 就會有一類問題永遠查不到。
「這個規則現在到底是怎麼運作的?」 原本:翻文件(可能舊了)、問資深同事(可能記錯)。現在是 search_code,直接 grep 六個 repo 的遠端預設分支。設計理由一句話:程式碼是唯一不會過期的文件。
「文件跟系統行為對不上,我要信誰?」 這就是知識助手依賴度低的病根:檢索會抖、文件會舊,使用者被騙過一次就不再信了。explain_business_rule 是正面解法——同時 grep 程式碼和語意搜尋文件,把兩邊並列回傳,讓 AI 對照。code 是確定性的,它把整個答案的可信度撐起來。
「文件真的舊了,然後呢?」 原本:記在心裡,等有空再改(等於永遠不會改)。現在是 propose_kb_update / apply_kb_update:查到的當下順手產生修改草稿,人確認後發布。這把「知識保鮮」從某個人的待辦事項,變成查詢的副作用——治的正是知識助手「文件太舊」的根因。
「這類問題每次都要重新想怎麼查。」 → diagnostic_playbook,把每一類問題的固定查法沉澱成可讀的 SOP。
「營運寫的需求,工程還是要逐項逼問。」 → draft_requirement_guide,幫營運在寫需求的當下就找到既有程式碼的整合點、類似的需求範本、和該回答的完整性問題。
動手前的四個架構決策
寫第一行程式碼之前,有四個決策先要定下來。每一個都有「另一條比較省事的路」,我把當時的取捨原樣寫出來——這些決策後來都進了只能追加的決策紀錄(ADR),讓之後接手的人看得懂當初為什麼這樣蓋。
決策一:服務放哪裡。 有三個選項:塞進主站當一個 /mcp 路由(工程師提議,最省事)、擠進現有的 Windows 測試方案、或複用另一個既有的 Linux 方案。我否決了前兩個:search_code 要在伺服器上 clone 六個 repo 跑 git grep,這種工作不該有機會壓到正式站;Windows 那台不支援 Python,而且上面已經擠了九個站、還發生過資源吃緊把服務弄崩的紀錄。最後放在既有 Linux B1 方案上,額外成本是零。
決策二:權限模型。 資料全面開放,不做角色分層。營運和工程師都能查全公司的 SQL 與 Mongo。理由很務實:老闆本來就給了營運唯讀權限,如果 MCP 卡得比現狀更嚴,他們只會回頭直接裸查——那正是我要解決的問題。限制權限不會讓數字變準。
決策三:查詢打哪裡。 query_sql 一律打唯讀副本,不碰正式資料庫。這是「爆炸半徑」思維:先假設最壞情境一定會發生——某天有人一口氣下了一堆重查詢——然後問,那時候最多壞到哪裡?打副本的答案是「副本變慢」,客人結帳完全無感。打正式庫的答案我不想知道。
決策四:寫入邊界。 對正式程式碼、資料庫、雲端資源永遠唯讀。唯一的寫入入口是知識庫,而且要經過人工確認才落地。一個只能讀的工具被騙了、被玩壞了,最多回傳錯誤的字;一個能寫的工具出事,是另一回事。
這一段收一件事就好:架構決策的重點不是選了什麼,是把「沒選什麼、為什麼」寫下來。 這四條每一條都擋掉過一次「當初為什麼不直接……」的重新討論。
我跟 AI 的分工
程式碼幾乎都是 AI 寫的——這件事我不迴避。但這個工具知道的每一件事,都是我教的。我的工作不是打字,是把「code 和數據對應到的真實業務場景」餵給 AI,讓它產出的東西第一次就長在對的邏輯上。
三個具體的例子。
教它業績怎麼算。 「訂購日期用 CreateTime 不是 OrdersTime」這種知識,AI 猜不到,資料庫的欄位註解也不會告訴你——它是某次對帳對不上、追了半天才追出來的教訓。以前這種教訓存在我的腦子和聊天紀錄裡,每開一個新對話就要重教一次;現在它鎖在工具層,所有人、包括所有 AI,都自動查對。
用真實範例校準它。 draft_requirement_guide 不是讓 AI 憑空生一份「需求範本」,而是把我們需求庫裡四個寫得好的、三個被工程退回的、四個特別複雜的真實案例餵給它,一起提煉出結論:範本的五段結構只是骨架,但「範圍、狀態、例外、口徑」四件事缺一不可——被退回的需求全是死在這四件事上,靠工程 PM 事後逐項逼問才補齊。這支工具做的就是把那些逼問前移到營運寫需求的當下。
接受它的不確定,用架構補。 知識庫檢索有個誠實的限制:查詢展開是 LLM 做的,同一個問題重問,排名會抖。我的判斷是不要把檢索調到完美——那條路沒有盡頭——而是靠 explain_business_rule 的組合設計:讓確定性的 code 去撐住會抖的檢索。實測「粥寶寶不能併單」這個問題,程式碼命中 MergeOrdersService.cs:151,需求文件也排第一——兩者一致,答案就有可信度。
我不訓練模型,我訓練工具的邊界。 模型會換、對話會斷,寫進工具層的業務邏輯留得下來。
把知識放在對的層級
起初我將查法寫死在程式碼中,後來改為:會變動的知識放在 markdown 檔案,穩定的能力才留在程式碼裡。
diagnostic_playbook 就是這個想法的產物——每類問題的固定查法各自寫成一支 .md 檔案,工具只負責列出清單與回傳全文。要新增一種查法,只要放一個檔案即可,無須修改程式碼或重新部署。
這其實是全公司 AI 治理的一環:個人對話裡的 know-how,先沉澱成有版控、有審核流程的 skill(我們用 GitHub 管理、開分支走 PR,不直推主線),其中高風險、高頻、所有人必須拿到同一個答案的——像業績算法——再往下鎖進 MCP 工具層。三層的取捨很簡單:越往下越穩定、越難錯,但也越難改。放對層,就幾乎不用重發版。
安全設計
這個工具讓十幾個人直接摸到全公司的資料,安全這一層我是照「假設一定會出事」來設計的:
- 每人一把專屬權杖,沒有共用帳密。 驗證沿用公司後台既有的 PAT 系統,撤銷一個人不影響其他人。
- 帳密不落任何人的筆電。 中央託管,連線字串只存在伺服器端——這也是當初不做「每台電腦各裝一份」的主因。
- 稽核 log 記錄每一次呼叫:誰、哪支工具、查了什麼、耗時多久、回傳多大。這不是為了管控,而是出事能追溯,以及我能看見大家實際上在問什麼——那才是決定下一批工具要做什麼的依據。
- 連驗證機制本身都要驗證。 接上 PAT 之後,我發現一個陷阱:就算你貼的是舊的共用密鑰,請求照樣回 200,看起來像是 PAT 通了。我後來用的判別法是看健康端點上「已快取的身分數」有沒有 +1——只有真正走 PAT 驗證的請求會進快取。「請求成功」和「走的是你以為的那條路」是兩件事。
被我低估的最後一哩:安裝
工具蓋好之後,我以為最難的部分結束了。錯——最難的是把它裝進十幾個從來沒開過終端機的人的電腦裡。
第一版:操作手冊+「讓 AI 帶你裝」。 想法聽起來很合理:手冊寫得夠清楚,同事丟給自己的 AI,AI 一步步帶。實際發生的事是:大多數同事連 MCP 是什麼都不知道,而 AI 拿到手冊後會非常盡責地說「請打開終端機」「你需要先安裝 git」「執行這行指令」——每一句對非技術同事都是天書,看到就一頭霧水。第一批配合安裝的同事狀況百出,最後變成 IT 一台一台陪裝,裝了很久。
這一版錯在我的假設:我以為「手冊+AI」等於「有人帶」。實際上 AI 只是把手冊翻譯成一連串使用者做不到的指令。
對不會終端機的人來說,「請打開終端機」跟沒有說明是同一件事。 門檻不是使用者的問題,是設計者的問題。
第二版:安裝包,無腦裝。 我把所有「AI 會叫使用者自己做的事」全部收進一個安裝腳本:環境檢測不再讓 AI 用猜的,腳本自己判斷這台電腦裝到哪一步、缺什麼就補什麼;裝到一半卡住的人重跑一次,會從斷點接續而不是壞掉。使用者要做的事收斂到最少:到後台自助申請一把權杖(不用等 IT 發)、執行安裝、開始用。
配套再加一層:一支「幫同仁裝公司工具」的 skill。同事只要跟自己的 AI 說「幫我裝公司的工具」,AI 讀了 skill 之後的行為模式是動手做完、每一步用白話說明它在做什麼——而不是對使用者出考題。裝好與裝壞的判斷也內建在裡面,健檢、重裝都是同一個入口。
成效寫在下一段的數字裡:正式發布給全公司的當天,就有沒被 IT 陪裝過的同事自己完成安裝、直接開始查。採用率是設計出來的,不是宣導出來的。
實際運作數據
8/18 上線,9/1 正式發布給全公司。
截至 9/1:累計 1,702 次工具呼叫、14 位同仁實際查詢、17 人完成安裝。單日最高峰達 404 次。query_sql 使用最多(740 次,平均 3.4 秒),其次為 search_code(342 次,平均 7.3 秒)。
比數字更有趣的是誰在使用:使用量排名第二、第三的都不是工程師。他們現在自己查會員、查訂單、查商品設定,不必再貼訊息到工程群組苦等回覆。
學到的教訓
上線這件事本身教會我最多。
- 上線前兩天,SQL 其實是壞的。 我使用了全域連線快取,Azure 閘道會切斷閒置連線——切斷之後,所有
query_sql會永遠回傳「Not connected」,直到整個服務重啟才會恢復。它不會自行復原。加入失敗重連與重試機制後才解決。 - 容器中沒有 git。
search_code依賴 git grep 運作,但 App Service 的容器並未內建 git,必須在啟動腳本中自行安裝。我將安裝過程放到背景執行,代價是每次重啟後有 1~2 分鐘search_code會直接報錯,然後自行恢復。第一次遇到時我還以為是部署失敗。 - 兩個設定未正確配置就會出錯,且錯誤訊息完全不提示。
MCP_ALLOWED_HOSTS未設定會回傳 421 Invalid Host header;未開啟stateless_http的話,稍長的查詢會中途被中斷並顯示 Session terminated。 - 備份排程在半夜失敗了六次我才發現。 稽核 log 在伺服器上只保留三天,我排定每天 21:00 抓回本機——結果八個晚上失敗六次,因為筆電剛從睡眠中醒來、DNS 尚未就緒。連續三天失敗就會永久遺失資料。改為下班時間 18:00 執行、失敗自動重試五次、開機時補跑,才穩定下來。
- 發布當天揪出四個「系統回報成功、實際上壞掉」的問題。 最嚴重的一個是伺服器同步指令參數錯誤——意味著過去所有的查法更新,其實一次都沒生效。系統從頭到尾都回報成功。
「沒有錯誤訊息」不等於「正常運作」。 會騙人的從來不是紅色的錯誤,而是綠色的成功。
所以現在每做完一件事,我都會多問 AI 一句:好,現在假設它其實沒生效,你要怎麼證明它真的動了?
下一步計畫
- 將稽核 log 接入 Log Analytics,目前僅輸出到容器、三天即被清除,不足以進行長期使用行為分析。
- 從查詢紀錄回推工具設計:大家實際輸入的問題,就是下一批 playbook 的題目來源。
- 工程部的自動 triage(Phase 2):錯誤訊息進來 → 用同一套工具自動查詢完成、產出交接文件 → 工程師接手。不自動執行任何修改,只把「查詢」這部分做完。
技術架構
Python 3.13、FastMCP(Streamable HTTP)、Azure App Service(Linux B1,複用既有方案、零額外成本)、Azure SQL 唯讀副本、Cosmos DB for MongoDB、Bitbucket(六個 repo 鏡像 clone + 定時 fetch)、知識庫透過後勤知識助手的內部 API 重用、PAT 驗證與稽核 log、架構決策紀錄(ADR)。
內部工具,原始碼不公開。