SeaGOAT:本地向量檢索如何與 ripgrep 並存
local-first semantic code search engine
秒懂
- 它是什麼?
- SeaGOAT 用 ChromaDB 在本機建立程式碼向量索引,讓「數字在哪裡被四捨五入」這類語意查詢變成一行指令,同時保留正規表達式的精確比對。它的代價是一個必須常駐的伺服器,以及一份寫死的副檔名清單。
- 適合誰用?
- SeaGOAT 適合已經裝好 Python 3.11 與 ripgrep、且願意讓一個常駐伺服器佔用本機連接埠的開發者,特別是經常需要憑模糊記憶搜尋程式碼、又不想把原始碼送到外部 API 的團隊。若你的倉庫以 Rust、Kotlin、Swift 或 Terraform 為主,README 明列的硬編碼副檔名清單裡沒有這些格式,SeaGOAT 對你幾乎沒有作用,直接用 ripgrep 更實際。
- 可以商用嗎?
- 可以。MIT 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
- 還在維護嗎?
- 有在維護。儲存庫最近一次提交在 4 天前。
- 用什麼語言寫的?
- 主要是 Python(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
語意查詢解決的是關鍵字對不上的問題
用 grep 找程式碼有個前提:你得先猜對變數名稱或函式名稱。當你只記得「有一段在處理金額四捨五入」,卻想不起來那個函式叫 round_currency 還是 format_price,關鍵字搜尋就失效了。SeaGOAT 針對的正是這種情境。README 給的第一個範例查詢就是 gt "Where are the numbers rounded",一句自然語言描述,而不是符號名稱。
它的目標使用者是手上有一份中等規模、以 Python、JavaScript、TypeScript、Go 或 Java 為主的倉庫,並且在意原始碼不能離開本機的開發者。README 的 FAQ 明確寫道,SeaGOAT 不依賴第三方 API 或任何遠端 API,全部功能都在你自己執行的 SeaGOAT 伺服器上完成。這一點對受合規限制、不能把程式碼貼進外部服務的團隊是實質差異,而不是行銷詞彙。
兩套檢索引擎同時跑,向量庫負責語意,ripgrep 負責精確
SeaGOAT 不是把 grep 換掉,而是把它包在裡面。根據 README,它使用 ChromaDB 作為向量資料庫,搭配本機的向量嵌入引擎,並預設關閉遙測;同一時間,它也用 ripgrep 提供正規表達式與關鍵字的比對結果。查詢時你會同時拿到兩類命中:語意相近的片段,以及字面完全吻合的片段。
這個設計解釋了為什麼查詢可以混用兩種語法。README 舉的例子是 gt "function calc_.* that deals with taxes",其中 calc_.* 是正規表達式,其餘是自然語言描述。字面部分交給 ripgrep,語意部分交給向量檢索,兩邊各自回傳後再一起呈現。
至於為什麼非得有一個常駐伺服器,README 的說法很直接:SeaGOAT 大量依賴向量嵌入與向量資料庫,目前無法改成即時逐檔處理的架構,而伺服器是用來換取查詢速度的手段。這是一個架構上的取捨,不是可以靠參數關掉的選項。
安裝與啟動:三行指令與一個 YAML 檔
前置依賴是 Python 3.11 或更新版本、ripgrep,以及選用但官方推薦的 bat。bat 存在且終端機啟用色彩時,輸出會交給 bat 呈現;若 SeaGOAT 被放進管線使用,則改用 grep 風格的輸出行格式;若啟用了色彩但沒有 bat,會退回用 pygments 上色。
安裝透過 pipx 完成:
pipx install seagoat
使用前必須先為目標倉庫啟動伺服器:
seagoat-server start /path/to/your/repo
伺服器跑起來之後,用 gt 或 seagoat 下查詢:
gt "Where are the numbers rounded"
要停掉某個倉庫的伺服器:
seagoat-server stop /path/to/your/repo
設定走 YAML,可以是全域設定,也可以是專案根目錄下的 .seagoat.yml。README 示範的鍵是 server.port,例如指定 31134。這個埠號值得在採用前先確認,因為它會與機器上既有的服務競爭同一個連接埠。
索引建立刻意放慢,這是設計而非缺陷
初次對大型倉庫建立索引會很慢,而且 CPU 使用率看起來不高。README 把這件事列為 FAQ 條目,並說明這是刻意的設計選擇:SeaGOAT 允許你在處理檔案的同時繼續使用電腦,避免拖慢整台機器。文件也強調,這個決定不影響查詢效能。
更實用的是,索引還沒建完就能查詢。README 寫道,當你下查詢而檔案尚未處理完畢時,會收到一則警告,附上結果準確度的估計值;而正規表達式與全文檢索的結果從一開始就會顯示。換句話說,ripgrep 那條路徑不依賴索引狀態,向量那條路徑則會隨著索引進度逐步補上。這個降級行為比「請等索引完成」誠實得多。
需要保留的是:README 沒有給出任何具體的索引速度數字或倉庫規模上限。任何關於「多大倉庫要跑多久」的估計,都必須由使用者在自己的機器上實測,文件裡查不到。
硬編碼的副檔名清單是最硬的天花板
README 明言,SeaGOAT 目前硬編碼為只處理特定格式:純文字 .txt、Markdown .md、Python .py、C 的 .c 與 .h、C++ 的 .cpp/.cc/.cxx/.hpp、TypeScript 的 .ts 與 .tsx、JavaScript 的 .js 與 .jsx、HTML .html、Go .go、Java .java、PHP .php、Ruby .rb。
這份清單之外的語言不會被索引。Rust、Kotlin、Swift、Scala、Elixir、Terraform 的 .tf、SQL 檔、YAML 與 JSON 都不在其中。如果你的倉庫主力是這些格式,SeaGOAT 的語意搜尋對你等於不存在,你只會用到它包裝 ripgrep 的那一半,而那半用原生 ripgrep 就能得到。
平台支援同樣有明確邊界。README 標示 Linux 為已測試,macOS 為部分測試並附上 issue 連結請求協助,Windows 則是標註需要幫助。這不是模糊的「跨平台支援」,而是作者自己標出的成熟度落差。
編碼方面,偏好 UTF-8,多數其他編碼應該也能運作,但只支援文字檔,二進位檔會被忽略。
與 ripgrep、ast-grep 的實際差異
把 SeaGOAT 和 ripgrep 放在一起比較,差別在檢索的單位。ripgrep 比對的是位元組或正規表達式樣式,你必須先知道要搜什麼字串;SeaGOAT 多了一層向量嵌入,讓你可以用「這段程式在做什麼」來查,代價是索引、一個常駐伺服器,以及一份受限的語言清單。兩者不是替代關係,README 的架構就是把 ripgrep 當成其中一個後端。
如果需求是依語法結構搜尋,例如「找出所有呼叫 foo() 的位置」,ast-grep 這類以語法樹為基礎的工具會比向量相似度更精準,因為它比對的是 AST 節點而非嵌入距離。SeaGOAT 的向量檢索適合的是你還不知道確切符號名稱的探索階段,一旦你知道要找什麼,正規表達式或語法比對的結果更可靠,也更省資源。
同一位作者另外在開發 zeitgrep,README 開頭以提示形式連結過去。若你在評估 SeaGOAT,值得一併看看那個專案,因為它代表作者對搜尋工具的另一種取捨方向。
維護成本與授權
SeaGOAT 以 MIT 授權釋出,這是最寬鬆的一類授權,允許修改與再散布,通常只要求保留著作權聲明與授權條款。README 本身也提醒,FAQ 內容只是說明 SeaGOAT 如何運作,不構成法律契約;若對隱私或安全性有疑慮,作者建議直接閱讀原始碼、開 issue 或送 pull request。涉及實際條款適用,仍應自行確認。
版本節奏偏快。近期釋出包含 v0.54.17(2025-05-14)、v0.54.16(2025-05-13)與 v0.54.15(2025-05-09),三天內兩個 patch 版本。這種頻率意味著升級成本低但變動密集,若你把 SeaGOAT 接進 CI 或團隊腳本,值得固定版本,而不是永遠抓最新。
另外要注意 README 對未來的保留:目前版本不會把資料送到遠端伺服器,但未來可能出現會這麼做的選用功能。這句話現在不影響採用判斷,但它把「本地優先」定義成當前行為,而不是永久承諾。
開發端的需求是 Poetry、Python 3.11 以上與 ripgrep,測試用 poetry run pytest . 或 watch 模式的 poetry run ptw。若你打算改動原始碼而非只使用,這是進場的起點。
編輯結論
SeaGOAT 適合已經裝好 Python 3.11 與 ripgrep、且願意讓一個常駐伺服器佔用本機連接埠的開發者,特別是經常需要憑模糊記憶搜尋程式碼、又不想把原始碼送到外部 API 的團隊。若你的倉庫以 Rust、Kotlin、Swift 或 Terraform 為主,README 明列的硬編碼副檔名清單裡沒有這些格式,SeaGOAT 對你幾乎沒有作用,直接用 ripgrep 更實際。決定採用前,先確認三件事:seagoat-server start 之後索引要多久才追上你的倉庫規模、seagoat-server stop 是否真的釋放埠號、以及 .seagoat.yml 裡 server.port 是否與你機器上既有服務衝突。
社群筆記