運作原理

無內建 LLM 的設計哲學、兩層解析、RAM-first 管線

一句話

codebase-memory-mcp 是結構分析後端——它建圖、存圖、查圖,但不內建 LLM。你的 MCP client(Claude Code、OpenCode…)才是翻譯官:它把你的自然語言問題轉成對圖的結構查詢。

你:什麼呼叫了 ProcessOrder?

agent 呼叫: trace_path(function_name="ProcessOrder", direction="inbound")

CBM: 執行圖查詢,回傳結構化結果

agent: 用白話英文呈現呼叫鏈

為什麼不內建 LLM

其他 code graph 工具會內嵌 LLM 做「自然語言 → 圖查詢」翻譯,代價是多一組 API key、多一筆成本、多一個要設定的模型。CBM 的答案:你正在對話的那個 agent 本身就是查詢翻譯官。MCP 讓 agent 直接呼叫結構化工具,不需要在工具裡再塞一個模型。

兩層解析架構

單靠 tree-sitter 只能給語法 AST——它看得出命名、結構、呼叫點,但看不出 user.profile.display_name() 其實解析到三個 module 外的 Profile.display_name(tree-sitter 不追蹤 imports、generics、inheritance、stdlib 型別)。所以 CBM 疊上第二層:

做什麼適用
1. Tree-sitter pass快速、語法層:抽取定義、呼叫、import全部 158 語言
2. Hybrid LSP pass型別感知:用 import graph + 跨檔定義 registry 精煉呼叫邊Python/TS/PHP/C#/Go/C/C++/Java/Kotlin/Rust/Perl

Hybrid LSP 是一套用 C 實作的語言型別解析演算法,結構上受 tsserver / pyright / gopls / Roslyn / Eclipse JDT / rust-analyzer 啟發且相容——但不是真的語言 server(沒有獨立 process、沒有每專案設定、沒有 API key),直接編進靜態二進位,跑在每一次 parse 上。

結果:呼叫解析(CALLS / RESOLVED_CALLS)與可呼叫值解析(CALL_REFERENCE)用型別資訊精煉——產出的圖接近 IDE「Go to Definition」會解析出的樣子。沒有 Hybrid LSP 的語言則退回文字解析,總是有某種答案。

Hybrid LSP 各語言處理重點

語言處理重點
Pythonimports + dotted submodule、dataclasses、generics、SQLAlchemy 2.0 Mapped[T]、Pydantic、型別縮窄(isinstance / walrus)、常見 stdlib
TypeScript/JS/JSX/TSXgenerics、JSX 元件分派、JSDoc 推斷、.d.ts、module re-exports、method chaining 回傳型別傳播
PHPnamespaces、traits、late-static-binding、PHPDoc 推斷
C#global usings、file-scoped namespaces、records、LINQ、async Task<T> unwrap、var 推斷
Gopre-built 跨檔 registry、generics、embedded structs、interface satisfaction
C/C++macros + typedef chains + header-vs-source 連結;C++ templates、namespaces、auto、class hierarchy
Javaimports、class hierarchy、generics、annotations、overload 匹配、lambdas、常見 JDK stdlib
Kotlinextension functions、data classes、nullable unwrap、scope functions(let/apply/run)
Rustuse + module paths、impl/trait methods、generics、UFCS、operator-trait desugaring
Perl@ISA / use parent 繼承、Exporter import maps、bless 自型別推斷

RAM-first 索引管線

索引全程在記憶體跑,結束才落盤一次:

  1. LZ4 HC 壓縮讀入原始檔。
  2. in-memory SQLite:節點/邊先放記憶體。
  3. 多 pass 管線:structure → definitions → calls → HTTP links → config → tests…
  4. 單次 dump 到磁碟,之後記憶體釋放回 OS。

這解釋了為什麼 Linux kernel(28M LOC、75K 檔)能 3 分鐘全索引完——RAM-first + 平行 worker(pass_parallel.c,可用 CBM_WORKERS 調整)+ 記憶體用完即釋放。

索引完之後

圖存在 SQLite(~/.cache/codebase-memory-mcp/),WAL 模式、ACID-safe。查詢走 15 個 MCP 工具(見 MCP 工具全解)。之後 watcher 會偵測檔案變更做增量重索引,不用每次全跑。

看完這頁你應該能說出:為什麼 CBM 不需要內建 LLM、tree-sitter 與 Hybrid LSP 各負責什麼、RAM-first 如何支撐 3 分鐘索引 kernel、以及「Go to Definition 等級」的解析是什麼意思。