:從零構建Text2SQL智能查詢助手)
1. 從零理解 Skill 與 MCP 的協(xié)作邏輯1.1 為什么需要自定義 Skill 和 MCP用 Claude Code 做開發(fā)輔助的人大概率經歷過這樣一個階段一開始覺得它什么都能干寫代碼、改 bug、解釋邏輯都不在話下。但用久了就會發(fā)現一個問題——每次對話都像在跟一個剛入職的新人溝通它不知道你的項目結構不知道你的數據庫表設計不知道你們團隊的代碼規(guī)范甚至不知道你昨天剛讓它寫過的一個工具函數叫什么名字。這就是通用 AI 編程助手的天然短板上下文是臨時的能力是通用的記憶是不存在的。自定義 Skill 和 MCP 就是來解決這個問題的。Skill 可以理解為給 Claude Code 裝的“技能包”你把特定領域的知識、流程、規(guī)范寫進去它就變成了一個懂你業(yè)務的專屬助手。MCP 則是“連接器”讓 Claude Code 能夠直接跟外部系統(tǒng)對話——數據庫、API、文件系統(tǒng)、第三方服務都可以通過 MCP 接入。打個比方Claude Code 本身是一個聰明的通才Skill 是給它發(fā)的崗位培訓手冊MCP 是給它配的辦公工具和系統(tǒng)權限。三者結合它才能從一個“什么都會一點”的助手變成“在你這個項目里什么都能干”的團隊成員。1.2 Skill 與 MCP 的職責邊界很多人剛接觸這兩個概念時容易混淆覺得都是“擴展能力”到底什么時候用哪個我踩過幾次坑之后總結出一個簡單的判斷標準維度自定義 SkillMCP本質提示詞工程 流程編排協(xié)議層的外部系統(tǒng)對接解決的問題讓 AI 知道“怎么做”讓 AI 能夠“做到”典型場景代碼規(guī)范、業(yè)務邏輯、操作流程數據庫查詢、API 調用、文件操作配置方式Markdown/JSON 文件定義服務端配置 客戶端注冊是否需要寫代碼基本不需要通常需要簡單說Skill 管的是“腦”MCP 管的是“手”。你要讓 Claude Code 按照你們團隊的規(guī)范寫 SQL這是 Skill 的事你要讓它直接連上數據庫跑查詢這是 MCP 的事。兩者配合才能實現從“理解需求”到“執(zhí)行操作”的完整閉環(huán)。1.3 Text2SQL 為什么適合作為入門案例Text2SQL 這個場景特別適合用來演示 Skill MCP 的配合原因有三第一需求明確。用戶輸入一句自然語言輸出一條 SQL輸入輸出都很清晰不需要復雜的交互設計。第二痛點真實。非技術同學想查數據但不會寫 SQL技術同學寫復雜查詢也要反復查表結構這個需求在很多團隊里都真實存在。第三技術鏈路完整。一個可用的 Text2SQL 系統(tǒng)需要理解數據庫結構MCP 提供元數據、需要遵循 SQL 編寫規(guī)范Skill 定義規(guī)則、需要執(zhí)行查詢并返回結果MCP 執(zhí)行正好覆蓋了 Skill 和 MCP 的核心能力。接下來我會從環(huán)境準備開始一步步拆解怎么配置一個能用的 Text2SQL 助手。2. 環(huán)境準備與基礎配置2.1 Claude Code 的安裝與初始化Claude Code 的安裝本身不復雜但有幾個細節(jié)容易卡住新手。我先把完整流程走一遍然后說幾個我實際踩過的坑。安裝方式取決于你的操作系統(tǒng)。macOS 和 Linux 用戶可以通過包管理器安裝Windows 用戶建議在 WSL2 環(huán)境下操作原生 Windows 的支持在某些版本上還不夠穩(wěn)定。安裝完成后第一次運行需要做初始化配置。這里的關鍵是API 密鑰的配置你需要有一個可用的密鑰才能讓 Claude Code 正常工作。配置方式通常是通過環(huán)境變量或者配置文件具體取決于你使用的版本。注意API 密鑰不要直接寫在代碼里或者提交到版本控制系統(tǒng)中。建議使用環(huán)境變量或者專門的密鑰管理工具。初始化完成后建議先跑一個簡單的測試確認基礎功能正常。比如讓它解釋一段代碼或者生成一個簡單的函數。這一步看起來多余但能幫你排除掉很多環(huán)境問題避免后面配置 Skill 和 MCP 時把環(huán)境問題誤判成配置問題。2.2 目錄結構規(guī)劃Claude Code 的配置文件和 Skill 定義文件需要放在特定的目錄下才能被正確加載。不同版本的目錄約定可能略有差異但大體結構是這樣的~/.claude/ ├── config.json # 主配置文件 ├── skills/ # 自定義 Skill 目錄 │ ├── text2sql/ │ │ ├── skill.md # Skill 定義 │ │ └── examples/ # 示例文件 │ └── code-review/ │ └── skill.md └── mcp/ # MCP 服務配置 └── servers.json我建議在項目目錄下也建一個.claude/文件夾放項目級別的 Skill 和 MCP 配置。這樣不同項目可以有各自的配置不會互相干擾。全局配置放通用能力項目配置放業(yè)務特定能力這個分層思路在實際使用中會省很多事。2.3 MCP 服務端的選擇與部署MCP 服務端的部署方式直接影響后續(xù)的使用體驗。目前常見的有三種模式本地進程模式是最簡單的MCP 服務端和 Claude Code 跑在同一臺機器上通過標準輸入輸出通信。適合個人開發(fā)和小型項目配置簡單延遲低。缺點是服務端掛了 Claude Code 就用不了而且不方便多人共享。本地服務模式是把 MCP 服務端跑成一個本地 HTTP 服務Claude Code 通過網絡請求調用。比進程模式多了一層網絡開銷但穩(wěn)定性更好也方便調試——你可以直接用 curl 測試服務端是否正常。遠程服務模式是把 MCP 服務端部署在獨立的服務器上適合團隊共享。需要考慮認證、網絡、并發(fā)等問題配置復雜度最高但擴展性最好。對于 Text2SQL 這個場景我建議先用本地進程模式跑通流程確認邏輯沒問題后再考慮升級。數據庫連接信息這種敏感配置在本地模式下也更容易管理。3. 自定義 Skill 的編寫與調試3.1 Skill 文件的結構與語法Skill 文件本質上是一個結構化的 Markdown 文檔Claude Code 會讀取它作為系統(tǒng)提示詞的一部分。一個完整的 Skill 定義通常包含以下幾個部分--- name: text2sql description: 將自然語言轉換為 SQL 查詢語句 version: 1.0 --- # 角色定義 你是一個專業(yè)的 SQL 查詢生成助手... # 能力范圍 - 支持 SELECT 查詢生成 - 支持多表 JOIN - 支持聚合函數 # 約束條件 - 只生成 SELECT 語句禁止 DDL/DML - 必須使用參數化查詢 - 表名和字段名必須來自提供的 schema # 輸出格式 返回 JSON 格式{sql: ..., explanation: ...}頂部的 frontmatter 是元信息Claude Code 用它來識別和索引 Skill。正文部分才是真正的提示詞內容。這里有個經驗Skill 的描述要具體不要寫空話。我見過有人寫“你是一個專業(yè)的助手請幫助用戶解決問題”這種描述等于沒寫。好的 Skill 描述應該像給新員工的 SOP每一步做什么、不做什么、遇到什么情況怎么處理都要說清楚。3.2 提示詞工程的核心技巧寫 Skill 的提示詞和平時跟 AI 對話的提示詞有本質區(qū)別。對話提示詞是一次性的Skill 提示詞是長期生效的所以需要考慮更多邊界情況。第一明確角色和邊界。不要只說“你是 SQL 專家”要說“你是一個只生成 SELECT 查詢的助手不處理任何寫操作”。邊界越清晰AI 越不容易跑偏。第二提供足夠的示例。Few-shot 示例對輸出質量的提升非常明顯。我通常會在 Skill 里放 3-5 個典型示例覆蓋簡單查詢、多表關聯(lián)、聚合統(tǒng)計等場景。示例不用多但要典型。第三定義輸出格式。結構化輸出對后續(xù)處理非常重要。我習慣讓 Skill 返回 JSON包含sql、explanation、confidence三個字段。confidence字段特別有用當 AI 對生成的 SQL 不確定時會給出較低的置信度這時候可以觸發(fā)人工確認流程。第四處理異常情況。用戶的問題可能模糊不清可能涉及不存在的表可能要求做權限外的操作。Skill 里要明確這些情況怎么處理——是追問澄清還是直接拒絕還是給出默認方案。3.3 調試 Skill 的實用方法Skill 寫完之后調試是個體力活。我的做法是準備一個測試用例集覆蓋各種典型場景和邊界情況每次修改 Skill 后跑一遍看輸出是否符合預期。測試用例集可以長這樣編號輸入預期行為1查詢所有用戶生成 SELECT * FROM users2統(tǒng)計每個城市的訂單數生成 GROUP BY 查詢3刪除所有數據拒絕執(zhí)行4查詢不存在的表提示表不存在5模糊需求追問澄清調試過程中最常見的兩個問題一是 AI 不遵守約束比如明明說了只生成 SELECT它還是生成了 DELETE二是輸出格式不穩(wěn)定有時候返回 JSON有時候返回純文本。第一個問題的解法是加強約束的權重。把關鍵約束放在 Skill 的開頭和結尾用加粗、重復等方式強化。第二個問題的解法是提供格式示例并且在 Skill 里明確說“必須嚴格按照以下格式輸出”。實操心得Skill 的調試不要一次改太多地方。每次只改一個變量觀察輸出變化這樣才能定位到是哪個改動起了作用。我一開始圖快一次改五六處結果輸出變好了也不知道為什么好變差了也不知道哪里出了問題。4. MCP 配置與數據庫對接4.1 MCP 服務端配置詳解MCP 服務端的配置核心是告訴 Claude Code服務端在哪里、怎么啟動、需要什么參數。以本地進程模式為例配置文件大概長這樣{ mcpServers: { database: { command: python, args: [-m, mcp_server_db], env: { DB_HOST: localhost, DB_PORT: 5432, DB_NAME: mydb } } } }command和args定義了怎么啟動服務端env傳遞環(huán)境變量。數據庫密碼這種敏感信息建議通過環(huán)境變量傳遞不要硬編碼在配置文件里。配置完成后需要驗證 MCP 服務端是否能正常啟動。我通常先用命令行直接跑一遍啟動命令確認沒有報錯再讓 Claude Code 去加載。這樣能把服務端本身的問題和 Claude Code 集成的問題分開排查。4.2 數據庫 Schema 的暴露策略Text2SQL 的效果很大程度上取決于 AI 對數據庫結構的理解程度。Schema 暴露得越清晰生成的 SQL 越準確。但也不能把所有表結構都塞進去那樣會占用大量上下文還會干擾 AI 的判斷。我的策略是分層暴露第一層是核心表也就是業(yè)務最常用的那幾張表完整暴露字段名、類型、注釋、索引信息。第二層是關聯(lián)表只在需要 JOIN 時才暴露提供表名和關鍵字段即可。第三層是冷門表默認不暴露需要時通過工具動態(tài)查詢。具體實現上可以在 MCP 服務端提供一個get_schema工具接受表名參數返回該表的詳細結構。Skill 里定義好什么時候調用這個工具——比如用戶提到一個不熟悉的表名時先查 schema 再生成 SQL。Schema 的注釋特別重要。我見過很多數據庫的字段名是field1、field2這種AI 根本猜不出含義。如果能在 MCP 層做一層映射把字段名翻譯成有意義的描述Text2SQL 的準確率會大幅提升。4.3 查詢執(zhí)行與結果返回MCP 服務端執(zhí)行 SQL 時有幾個安全細節(jié)必須注意第一只讀賬號。給 MCP 服務端配置的數據庫賬號權限要限制到最小。只給 SELECT 權限不給 INSERT、UPDATE、DELETE、DROP 等權限。這樣即使 AI 生成了危險語句數據庫層面也會拒絕執(zhí)行。第二查詢超時。復雜查詢可能跑很久拖垮數據庫。MCP 服務端要設置查詢超時比如 30 秒超時后自動 kill 查詢。第三結果集限制。返回給 AI 的結果集不能太大否則會撐爆上下文。我通常限制在 100 行以內超過的話只返回前 100 行加一個總數提示。第四SQL 審計。所有執(zhí)行的 SQL 都要記錄日志包括原始的自然語言輸入、生成的 SQL、執(zhí)行時間、返回行數。出問題時可以追溯也方便后續(xù)優(yōu)化 Skill。結果返回的格式也有講究。我習慣返回一個結構化的對象{ success: true, columns: [id, name, city], rows: [[1, 張三, 北京], [2, 李四, 上海]], total: 2, execution_time_ms: 45 }這樣 AI 拿到結果后可以自然地用自然語言總結給用戶而不是把原始數據一股腦丟出來。5. Text2SQL 完整實現流程5.1 整體架構設計把前面幾部分串起來一個完整的 Text2SQL 系統(tǒng)架構是這樣的用戶輸入自然語言問題 → Claude Code 加載 Text2SQL Skill → Skill 指導 AI 理解問題并調用 MCP 工具 → MCP 服務端查詢數據庫 schema → AI 生成 SQL → MCP 服務端執(zhí)行 SQL → 返回結果 → AI 用自然語言總結。這個鏈路里Skill 負責“怎么想”MCP 負責“怎么做”Claude Code 負責“協(xié)調”。三者各司其職缺一不可。我實際部署時還加了一個緩存層。相同或相似的問題直接返回緩存結果不用每次都走完整流程。緩存 key 用問題的語義哈希而不是字符串匹配這樣“查詢北京的用戶”和“北京有哪些用戶”能命中同一個緩存。5.2 Skill 定義文件完整示例下面是一個可以直接參考的 Skill 定義文件--- name: text2sql description: 將自然語言轉換為 SQL 查詢并執(zhí)行 version: 1.0 --- # 角色 你是一個 SQL 查詢助手負責將用戶的自然語言問題轉換為 SQL 查詢語句并通過 MCP 工具執(zhí)行。 # 工作流程 1. 理解用戶問題識別涉及的實體和操作 2. 調用 get_schema 工具獲取相關表結構 3. 根據表結構生成 SQL 查詢 4. 調用 execute_query 工具執(zhí)行 SQL 5. 用自然語言總結查詢結果 # SQL 編寫規(guī)范 - 只生成 SELECT 語句 - 表名和字段名必須使用反引號包裹 - 多表 JOIN 必須明確指定 JOIN 條件 - 聚合查詢必須包含 GROUP BY 子句 - 日期字段使用標準格式 YYYY-MM-DD # 異常處理 - 問題模糊時先追問澄清再生成 SQL - 涉及的表不存在時提示用戶并列出可用表 - 生成的 SQL 置信度低于 0.7 時先展示 SQL 讓用戶確認 # 輸出格式 生成 SQL 后先展示 SQL 語句再執(zhí)行查詢最后總結結果。這個 Skill 定義不算長但覆蓋了核心流程、規(guī)范、異常處理和輸出格式。實際使用時可以根據業(yè)務特點調整。5.3 MCP 工具定義與實現MCP 服務端需要暴露兩個核心工具get_schema和execute_query。get_schema接受表名參數返回表結構信息。實現上就是從數據庫的 information_schema 里查詢字段信息整理成結構化格式返回。execute_query接受 SQL 參數執(zhí)行查詢并返回結果。實現時要做好前面說的安全限制——只讀賬號、超時控制、結果集限制。工具的定義要清晰描述參數和返回值這樣 AI 才知道怎么調用。比如{ name: execute_query, description: 執(zhí)行 SELECT 查詢并返回結果, parameters: { sql: { type: string, description: 要執(zhí)行的 SQL 查詢語句只支持 SELECT }, limit: { type: integer, description: 返回的最大行數默認 100 } } }5.4 端到端測試與效果驗證配置完成后用真實場景做端到端測試。我準備了這樣一組測試用例用戶輸入期望結果上個月有多少新用戶注冊生成帶日期過濾的 COUNT 查詢銷售額最高的前 10 個產品生成 ORDER BY LIMIT 查詢北京和上海的訂單量對比生成 GROUP BY 城市 COUNT 查詢刪除測試數據拒絕執(zhí)行測試時重點關注幾個指標SQL 生成準確率、執(zhí)行成功率、響應時間、異常處理是否正確。我實測下來簡單查詢的準確率能到 90% 以上復雜多表關聯(lián)的準確率在 70% 左右。提升準確率的關鍵是 schema 描述要清晰Skill 里的示例要覆蓋典型場景。6. 常見問題與排查技巧6.1 Skill 不生效的排查思路Skill 寫了但 Claude Code 好像沒讀到這是最常見的問題。排查順序是這樣的先確認文件路徑對不對。不同版本的 Claude Code 對 Skill 目錄的約定可能不同查一下官方文檔確認。然后確認文件格式對不對frontmatter 的語法錯誤會導致整個文件被忽略。再看 Skill 的 name 有沒有沖突同名的 Skill 可能互相覆蓋。如果這些都正常可以試著在對話里直接問 Claude Code“你現在加載了哪些 Skill”它會列出當前生效的 Skill 列表。如果列表里沒有你的 Skill那就是加載環(huán)節(jié)出了問題。踩坑記錄我有一次 Skill 死活不生效排查了半天發(fā)現是文件編碼問題。文件保存成了 GBK 編碼Claude Code 按 UTF-8 讀取frontmatter 解析失敗整個文件被跳過了。改成 UTF-8 后立刻正常。這種問題很隱蔽建議所有配置文件統(tǒng)一用 UTF-8 編碼。6.2 MCP 連接失敗的常見原因MCP 連接失敗的表現是 Claude Code 提示工具不可用或者調用工具時報錯。常見原因有這么幾類服務端啟動失敗??赡苁且蕾嚊]裝全可能是端口被占用可能是配置文件路徑不對。先在命令行直接跑啟動命令看報什么錯。通信協(xié)議不匹配。MCP 有版本差異服務端和客戶端的協(xié)議版本要對上。查一下雙方版本不匹配就升級或降級。權限問題。數據庫賬號權限不足或者文件系統(tǒng)權限不夠。檢查賬號的權限配置確認能正常連接數據庫。網絡問題。遠程模式下可能是防火墻、DNS、路由的問題。先用 telnet 或 curl 測試網絡連通性。6.3 SQL 生成質量優(yōu)化SQL 生成質量不穩(wěn)定時好時壞這是 Text2SQL 的常見痛點。優(yōu)化方向有幾個豐富 schema 描述。字段注釋、表注釋、枚舉值說明這些信息對 AI 理解業(yè)務含義非常重要。花時間把 schema 描述補全效果立竿見影。增加 Few-shot 示例。在 Skill 里放更多典型示例特別是那些 AI 容易搞錯的場景。比如日期處理、多表關聯(lián)、聚合統(tǒng)計每個場景放兩三個示例。引入反饋機制。用戶對生成的 SQL 不滿意時可以給出修正意見這些修正記錄可以作為后續(xù)優(yōu)化的依據。我習慣把修正案例整理成新的示例補充到 Skill 里。分步驟生成。復雜查詢不要一步到位先讓 AI 拆解問題再逐步生成子查詢最后組合。這樣雖然慢一點但準確率更高。6.4 性能與安全注意事項性能方面主要關注查詢效率和上下文占用。查詢效率靠數據庫索引和查詢優(yōu)化上下文占用靠控制 schema 暴露范圍和結果集大小。安全方面除了前面說的只讀賬號、超時控制、結果集限制還要注意敏感數據脫敏。用戶表里的手機號、身份證號、郵箱等字段返回結果前要做脫敏處理。這個可以在 MCP 服務端實現根據字段名自動識別敏感字段并脫敏。另外SQL 注入防護也要考慮。雖然 AI 生成的 SQL 通常不會有注入問題但用戶輸入的自然語言里可能包含惡意內容。MCP 服務端要對生成的 SQL 做二次校驗確保不包含危險操作。問題類型排查方向解決方案Skill 不生效路徑、格式、編碼檢查目錄、frontmatter、UTF-8MCP 連接失敗啟動、協(xié)議、權限命令行測試、版本對齊、權限檢查SQL 質量差schema、示例、流程補注釋、加示例、分步生成性能問題索引、上下文優(yōu)化查詢、控制暴露范圍安全問題權限、脫敏只讀賬號、字段脫敏這套配置我用了大半年中間迭代了十幾版 SkillMCP 服務端也重構過兩次。最大的體會是Skill 和 MCP 的配置不是一勞永逸的需要根據實際使用情況持續(xù)調整。每次遇到生成錯誤的 SQL都是一次優(yōu)化 Skill 的機會。把這些問題記錄下來定期回顧系統(tǒng)會越來越順手。最后分享一個小技巧給 Skill 加一個版本號每次修改都遞增。這樣出問題時可以快速回滾到上一個穩(wěn)定版本也方便對比不同版本的效果差異。這個習慣在多人協(xié)作時尤其重要能避免“誰改的、改了什么、為什么改”這類扯皮。