AI News HubLIVE
站內改寫4 分鐘閱讀

使用 Weaviate MCP 構建編碼助手:對程式碼與文件進行 RAG 檢索

本文介紹如何利用 Weaviate 內建的 MCP 伺服器為編碼助手(如 Claude Code、Cursor 和 VS Code)提供混合搜尋能力,無需額外編寫膠水程式碼。透過將程式碼庫與文件分塊並索引到 Weaviate,結合 BM25 精確匹配與向量語義檢索,LLM 智慧代理可以高效獲取所需上下文,避免上下文過載與成本浪費。

上週,我讓 Claude Code 在我的程式碼庫中實現一個相對簡單的功能。三輪對話後,上下文消耗超過 80K token,但 Claude 仍然缺少一些我忘記包含的關鍵資訊。沒有檢索機制,你就會陷入這樣的迴圈:貼上太少,代理靠猜測;貼上太多,又要為代理未使用的上下文付費。

大多數團隊透過 RAG 對程式碼庫進行檢索來解決這個問題。典型的方案是採用向量資料庫加上一個自定義的 MCP 伺服器作為橋樑。Weaviate 簡化了這一過程:MCP 伺服器內建於資料庫之中,位於與 REST API 同一埠的 /v1/mcp。僅需一個環境變數即可啟用。你可能已經在 Weaviate 中使用的混合檢索同樣適用於程式碼檢索,其中 BM25 部分可以匹配像 connect_to_local 這樣的函式識別符號,而向量部分則能發現語義意圖,例如“如何初始化客戶端”。

本文將指導你基於這一內建 MCP 伺服器構建編碼助手:包括如何攝取程式碼庫、攝取文件、連線 Claude Code、Cursor 和 VS Code,並執行真實的查詢。覆蓋以下主題:

  • 為什麼你的編碼助手需要超越訓練資料
  • 為什麼 Weaviate MCP 適合這項工作
  • 第一步:執行帶 MCP 的 Weaviate
  • 第二步:設計模式
  • 第三步:程式碼庫的分塊與攝取
  • 第四步:文件的分塊與攝取
  • 第五步:連線 Claude Code、Cursor 和 VS Code
  • 嘗試執行
  • 代理執行手冊:自動設定

為什麼編碼助手需要超越訓練資料

LLM 具有固定的知識截止期,且對私有程式碼一無所知。簡單的解決方法是直接把檔案丟進提示詞中。但這帶來三個問題:

  1. 成本:上下文中的 token 按輪次計費。一個 200 個檔案的 Python 專案無法完全放入提示詞,即使部分放入,在代理推理過程中也會持續計費。
  2. 過時的上下文:一旦檔案進入提示詞,它就被凍結了。如果代理修改了一個函式後又需要重新讀取,它必須重新載入整個檔案。模型所見的檢視與磁碟上的真實情況之間沒有即時連結。
  3. 不恰當的粒度:即使檔案能放入提示詞,模型的注意力也會浪費在無關的部分——匯入、模組級樣板程式碼等。代理正在編輯的函式與上百行 from x import y 爭奪上下文。

檢索解決了這三個問題。只需一次索引程式碼庫,將分塊存入向量資料庫,讓 LLM 客戶端按需拉取所需內容。這就是 RAG。編碼助手此前缺乏一種乾淨的方式與這類資料庫通訊,無需自定義適配層。這就是 MCP 發揮作用的地方。

為什麼 Weaviate MCP 適合這項工作

模型上下文協議(MCP)是 Claude Code、Cursor 和 VS Code 等 LLM 客戶端呼叫外部工具的標準方式。Weaviate v1.37.1 將其核心操作作為 MCP 工具暴露在 Streamable HTTP 端點 /v1/mcp 上。共提供四個工具:

  • weaviate-collections-get-config:讓 LLM 檢查可用的集合及其屬性
  • weaviate-tenants-list:在使用多租戶時列出租戶
  • weaviate-query-hybrid:執行混合(BM25+向量)搜尋
  • weaviate-objects-upsert:僅在啟用寫許可權時寫入物件

混合搜尋是該方案對編碼助手最具體的好處。程式碼是識別符號與意圖的混合體。BM25 精確匹配識別符號,向量捕獲意圖。像“我們在哪裡處理 429 重試?”這樣的查詢需要兩者同時作用:向量找到語義相關的重試程式碼,BM25 將 429 作為精確詞條錨定。純向量檢索會丟失整數匹配,純 BM25 會遺漏使用者未提及的措辭。混合搜尋在這種混合意圖查詢中勝出。

操作簡便性是第二個原因。其他方案需要執行一個 MCP 伺服器外加向量資料庫,相當於在生產中監視兩個服務。Weaviate 將 MCP 伺服器放在資料庫內部,同埠、同認證體系,你只需要監控 Weaviate 本身。

第三個原因是多租戶。一個 Weaviate 例項可以承載多個程式碼庫,每個庫作為獨立的租戶隔離。對於擁有多個倉庫的組織,一個叢集即可,無需為每個團隊單獨部署。

關於 Weaviate MCP 與函式呼叫(function calling)的區別:函式呼叫是針對具體 LLM API 的,而 MCP 是傳輸層協議——任何支援 MCP 的客戶端都可以呼叫任何支援 MCP 的伺服器,無需重寫。構建一次檢索,即可在 Claude Code、Cursor 和 VS Code 中使用,無需轉換。

第一步:執行帶 MCP 的 Weaviate

MCP 伺服器預設停用。兩個環境變數可啟用:

services:
  weaviate:
    image: cr.weaviate.io/semitechnologies/weaviate:1.37.1
    ports:
      - '8080:8080'
      - '50051:50051'
    environment:
      MCP_SERVER_ENABLED: 'true'
      MCP_SERVER_WRITE_ACCESS_ENABLED: 'true'
      AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: 'true'
      DEFAULT_VECTORIZER_MODULE: 'text2vec-openai'
      ENABLE_MODULES: 'text2vec-openai'
      OPENAI_APIKEY: ${OPENAI_APIKEY}

MCP_SERVER_ENABLED 暴露只讀工具(集合查詢、租戶列表、混合查詢)。MCP_SERVER_WRITE_ACCESS_ENABLED 新增 upsert 工具,允許代理寫回結果。如果只需要檢索,可以跳過寫許可權。建議先只開啟只讀模式,因為大多數編碼代理的工作都只涉及檢索,而且可以避免代理向知識庫寫入無意義內容的風險。

生產環境認證 本例使用匿名訪問以保持聚焦於 MCP 配置。對於任何網路部署,應啟用 API 金鑰並在客戶端配置中新增 Authorization: Bearer——Weaviate 的 MCP 伺服器支援標準認證和 RBAC。

啟動後,可透過 curl 傳送 initialize 握手確認端點是否存活:

docker compose up -d
curl -sf -X POST http://localhost:8080/v1/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'

如果 MCP 伺服器存活,會返回一個包含伺服器能力的 JSON-RPC 響應並設定 Mcp-Session-Id 頭。

第二步:設計模式 建立兩個集合:CodeChunksDocChunks,共享同一個 Weaviate 例項。

client.collections.create(
    name="CodeChunks",
    properties=[
        Property(name="content", data_type=DataType.TEXT, tokenization=Tokenization.WORD),
        Property(name="symbol", data_type=DataType.TEXT, tokenization=Tokenization.LOWERCASE),
        Property(name="file_path", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
        Property(name="language", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
        Property(name="repo", data_type=DataType.TEXT, tokenization=Tokenization.FIELD),
    ],
    vector_config=Configure.Vectors.text2vec_openai(),
)

symbol 使用小寫分詞,使 connect_to_local 作為一個 token 而非三個;file_pathlanguagerepo 使用 FIELD 實現精確匹配;contenttitle 使用 WORD

第三步:程式碼庫的分塊與攝取 基於行的樸素分塊會破壞程式碼結構。應採用語法邊界分塊:每個函式、每個類、每個頂級語句一個塊。Python 標準庫 ast 即可勝任 Python 程式碼的分塊:

import ast
from pathlib import Path

def chunk_python_file(path: Path) -> list[dict]:
    source = path.read_text()
    tree = ast.parse(source)
    lines = source.splitlines()
    chunks = []
    for node in ast.iter_child_nodes(tree):
        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
            start = node.lineno - 1
            end = node.end_lineno
            chunks.append({
                "content": "\n".join(lines[start:end]),
                "symbol": node.name,
                "file_path": str(path),
                "language": "python",
                "repo": "my-service",
            })
    return chunks

然後使用 Weaviate 的批次寫入模式:

with code_chunks.batch.dynamic() as batch:
    for py_file in Path("./").rglob("*.py"):
        for chunk in chunk_python_file(py_file):
            batch.add_object(properties=chunk)

每個分塊在插入時由 text2vec-openai 自動向量化。也可以替換為 text2vec-voyageaitext2vec-cohere

第四步:文件的分塊與攝取 文件分塊應以標題為邊界。推薦按 H2 分割,若某節過長再按 H3 細分:

import re

def chunk_markdown(text: str, max_chars: int = 1500) -> list[str]:
    sections = re.split(r"(?m)^## ", text)
    chunks = []
    for section in sections:
        if len(section) < max_chars:
            chunks.append(section.strip())
        else:
            subsections = re.split(r"(?m)^### ", section)
            for sub in subsections:
                if sub.strip():
                    chunks.append(sub.strip()[:max_chars])
    return chunks

每個塊同時保留 titlesource_url 屬性。

第五步:連線 Claude Code、Cursor 和 VS Code

  • Claude Code 原生支援 MCP:在 ~/.claude/settings.json 中新增配置指向 Weaviate 端點,混合搜尋工具自動可用。
  • Curs 透過 .cursor/mcp.json 配置:原理類似,只需指定 URL 和工具列表。
  • VS Code 需安裝 MCP 擴充套件後配置 mcp.json

代理執行手冊:自動設定 提供一個 shell 指令碼 setup.sh,包含以下步驟:檢查環境變數、拉取 Docker 映象、啟動 Weaviate、等待就緒、驗證 MCP 端點,然後執行 ingest.py 攝取資料。指令碼具有冪等性,可重複執行。

總之,Weaviate MCP 為編碼助手提供了一條極簡的路徑來實現高效的混合檢索。透過將 MCP 伺服器內建在資料庫內,該方案消除了額外的運維負擔,同時提供了強大的多租戶支援和開箱即用的混合搜尋能力。無論是個人專案還是團隊協作,都可以快速上手,讓 LLM 代理真正理解私有程式碼庫。