obsidian:~/vault$ search --hybrid obsidian

Obsidian MCP+混合式檢索:2026年參考指南

# 透過MCP將Obsidian串接至Claude及其他代理程式:涵蓋伺服器設定、BM25+向量混合式檢索,以及含16,894個檔案的儲存庫索引,並附上可直接使用的設定。

words: 4550 read_time: 51m updated: 2026-07-17 21:09
$ retriever search --hybrid obsidian

Obsidian不是筆記應用程式。它是本機優先、純文字、圖狀結構的markdown語料庫;加入檢索基礎架構後,就會成為AI脈絡資源池。16,894個檔案。49,746個片段。23ms查詢。0次API呼叫。1個83 MB SQLite檔案。本指南涵蓋完整系統:從知識庫架構,到hybrid檢索,再到MCP整合與營運工作流程。


重點摘要

重點在情境工程,而非筆記本身。 Obsidian vault 對 AI 的價值,不在筆記本身,而在讓筆記可被查詢的檢索層。沒有檢索能力的 16,000 個檔案 vault,只是一個只能寫入的資料庫。具備 hybrid 搜尋與 MCP 整合的 200 個檔案 vault,才是 AI 知識庫。檢索基礎設施才是產品,筆記只是原料。

Hybrid 檢索勝過純關鍵字或純語意搜尋。 BM25 能捕捉精確識別碼與函式名稱。向量搜尋能在不同術語之間捕捉同義詞與概念匹配。Reciprocal Rank Fusion (RRF) 能合併兩者,且不需要校準分數。單靠任一方法,都無法同時涵蓋這兩種失敗模式。MS MARCO passage ranking 的研究也確認了這個模式:hybrid 檢索穩定優於任一方法單獨使用。3hybrid retriever deep dive涵蓋 RRF 數學、使用真實數字的範例、失敗模式分析,以及互動式融合計算器。

MCP 讓 AI 工具能直接存取 vault。 Model Context Protocol(MCP)伺服器會將檢索器公開為工具,讓 Claude Code、Codex CLI、Cursor 與其他 AI 工具可直接呼叫。代理會查詢 vault,接收附有來源標註的排名結果,並在不載入整個檔案的情況下使用情境。MCP 伺服器只是檢索引擎外層的一層薄封裝。

Local-first 代表零 API 成本與完整隱私。 整個堆疊都在單一機器上執行:SQLite 負責儲存,Model2Vec 負責 embeddings,FTS5 負責關鍵字搜尋,sqlite-vec 負責向量 KNN。沒有雲端服務、沒有 API 呼叫、沒有網路依賴。個人筆記絕不離開本機。以 OpenAI API 價格計算,完整重新嵌入 49,746 個 chunks 的成本約為 $0.30;但真正的成本是延遲、隱私暴露,以及讓一個本應可離線運作的系統依賴網路。4

增量索引讓系統在 10 秒內保持最新。 透過比較檔案修改時間即可偵測變更。只有修改過的檔案會重新 chunking 並重新 embedding。在 Apple M 系列硬體上,完整重新索引約需 4 分鐘。一般日常編輯的增量更新可在 10 秒內完成。系統能自動保持最新,無需手動介入。

此架構可從 200 則筆記擴展到 20,000+ 則筆記。 同一套三層設計(擷取、檢索、整合)適用於任何 vault 規模。小型 vault 可先從純 BM25 搜尋開始。當關鍵字碰撞成為問題時,再加入向量搜尋。需要同時支援精確與語意匹配時,再加入 RRF 融合。每一層都可獨立發揮作用,也可獨立移除。


如何使用本指南

本指南涵蓋完整系統。您的起點取決於目前狀態:

您目前是… 從這裡開始 接著探索
剛開始接觸 Obsidian + AI 為什麼 AI 基礎設施適合使用 ObsidianObsidian MCP 設定 Vault 架構MCP 伺服器架構
已有 vault,想加入 AI 存取能力 MCP 伺服器架構Claude Code 整合 Embedding 模型全文搜尋
正在建置檢索系統 完整檢索管線Reciprocal Rank Fusion 效能調校疑難排解
團隊或企業情境 決策框架知識圖譜模式 開發者工作流程配方遷移指南

標示為 Contract 的章節包含實作細節、設定區塊與失敗模式。標示為 Narrative 的章節聚焦於概念、架構決策,以及設計選擇背後的推理。標示為 Recipe 的章節提供逐步工作流程。


為什麼 AI 基礎設施適合使用 Obsidian

本指南的核心主張是:Obsidian vault 是個人 AI 知識庫的最佳基底,因為它 local-first、純文字、具圖狀結構,而且使用者能控制堆疊的每一層。

Obsidian 提供了其他替代方案給不了 AI 的能力

純文字 markdown 檔案。 每則筆記都是檔案系統上的 .md 檔案。沒有專有格式、沒有資料庫匯出,也不需要 API 才能讀取內容。任何能讀取檔案的工具,都能讀取您的 vault。grepripgrep、Python 的 pathlib、SQLite FTS5——都能直接作用於原始檔案。當您建置檢索系統時,索引的是檔案,而不是 API 回應。索引永遠與來源一致,因為來源就是檔案系統。

Local-first 架構。 vault 存在於您的機器上。沒有伺服器、沒有雲端同步依賴、沒有 API 速率限制,也沒有服務條款規範您如何處理自己的內容。您可以在不使用任何外部服務的情況下,對筆記進行 embedding、索引、chunking 與搜尋。這對 AI 基礎設施很重要,因為檢索管線的速度取決於磁碟速度,而不是 API 端點的回應速度。這對隱私也同樣重要:包含憑證、健康資料、財務資訊與私人反思的個人筆記,永遠不會離開您的機器。

透過 wiki-link 形成圖狀結構。 Obsidian 的 [[wiki-link]] 語法會在筆記之間建立有向圖。一則關於 OAuth 實作的筆記,會連結到 token 輪替、工作階段管理與 API 安全性的筆記。圖狀結構編碼的是概念之間由人為整理過的關係。向量 embeddings 能捕捉語意相似度,但 wiki-link 捕捉的是作者在思考該主題時刻意建立的連結。這個圖是一種 embeddings 無法複製的訊號。

Plugin 生態系。 Obsidian 擁有 2,500+ 個社群 plugin(截至 2026 年 3 月,較 2025 年中期的 1,800+ 增加)。Dataview 可像查詢資料庫一樣查詢您的 vault。Templater 可用 JavaScript 邏輯從範本產生筆記。Git 整合可將 vault 同步到 repository。Linter 可強制格式一致性。Bases 核心 plugin(於 v1.9.10 引入)以 frontmatter properties 作為欄位,對 vault 檔案提供類資料庫檢視——表格、圖庫、日曆與看板——並儲存為 .base 檔案。15 這些 plugin 能在不改變底層純文字格式的前提下,為 vault 增加結構。檢索系統索引的是這些 plugin 的輸出,而不是 plugin 本身。

5 百萬+ 使用者。 Obsidian 擁有大型活躍社群,持續產出範本、工作流程、plugin 與文件。當您遇到 vault 組織或 plugin 設定問題時,多半已有人記錄了解法。社群也產出 Obsidian 周邊工具:MCP 伺服器、索引腳本、發布管線與 API wrapper。

單靠檔案系統缺少什麼

markdown 檔案目錄具備純文字優勢,但缺少 Obsidian 提供的 3 項能力:

  1. 雙向連結。 Obsidian 會自動追蹤 backlinks。當您從筆記 A 連到筆記 B,筆記 B 會顯示筆記 A 參照了它。圖譜面板會視覺化連結叢集。這種雙向感知是一種原始檔案系統無法提供的中繼資料。

  2. 含 plugin 渲染的即時預覽。 Dataview 查詢、Mermaid 圖表與 callout 區塊會即時渲染。寫作體驗比文字編輯器更豐富,但儲存格式仍維持純文字。您在豐富環境中撰寫與組織;檢索系統則索引原始 markdown。

  3. 社群基礎設施。 Plugin 探索、主題市集、同步服務(選用)、發布服務(選用)與文件生態系。您可以用獨立工具複製任何單項功能,但 Obsidian 將它們包裝成一套連貫的工作流程。

Obsidian 不會做什麼(以及您要建置什麼)

Obsidian 不包含檢索基礎設施。它有基本搜尋(全文、檔名、標籤),但沒有 embedding 管線、沒有向量搜尋、沒有融合排名、沒有 MCP 伺服器、沒有憑證過濾、沒有 chunking 策略,也沒有供外部 AI 工具使用的整合 hook。本指南涵蓋的是您在 Obsidian 之上建置的基礎設施。 vault 是基底。檢索管線、MCP 伺服器與整合 hook 才是基礎設施。

此處描述的架構是 markdown-first,而非 Obsidian-exclusive。 如果您使用 Logseq、Foam、Dendron,或單純的 markdown 檔案目錄,檢索管線也能以相同方式運作。chunker 讀取 .md 檔案。embedder 處理文字字串。indexer 寫入 SQLite。這些元件都不依賴 Obsidian 特定功能。Obsidian 的貢獻,是提供能產生 markdown 檔案的寫作與組織環境,而檢索器正是索引這些檔案。

Obsidian MCP設定

Model Context Protocol(MCP)是標準介面,讓Claude Code、Codex CLI、Cursor與其他AI工具能直接存取Obsidian vault。本節會在5分鐘內把vault連接到AI工具。您將安裝Obsidian、建立vault、安裝MCP伺服器,並執行第一次查詢。快速開始會使用社群MCP伺服器,以便立即看到結果。後續章節會說明如何建置自訂檢索管線供正式環境使用。

先決條件

  • macOS、Linux或Windows
  • Node.js 18+(供MCP伺服器使用)
  • Obsidian 1.12+(供CLI整合使用;1.13.1是目前公開的桌面版發行版本;較早版本也可用於僅使用MCP的設定)
  • 已安裝Claude Code、Codex CLI或Cursor

步驟1:建立vault

obsidian.md下載Obsidian並建立新的vault。選擇一個您記得的位置——MCP伺服器需要絕對路徑。

# Example vault location
~/Documents/knowledge-base/

新增幾則筆記,讓檢索器有內容可以處理。即使只有10到20則筆記,也足以看到結果。每則筆記都應該是.md檔案,具有有意義的標題,並至少包含一段內容。

步驟2:安裝MCP伺服器

有幾個社群MCP伺服器可立即提供vault存取能力。這個生態系在2025到2026年間大幅成長。其中值得注意的是MCPVault(npm @bitbonsai/mcpvault,repo bitbonsai/mcpvault),目前為v0.12.1——這是獨立於下方MarkusPfundstein/mcp-obsidian的專案,並非其改名版本。其v0.11.0(2026年3月)新增了list_all_tags,可掃描frontmatter與hashtags並統計數量,也改善了含點號資料夾的處理,並支援.base/.canvas。針對其路徑篩選限制目錄拒絕清單,曾揭露兩項中等嚴重性的安全公告(GHSA-9c83-rr99-vfwj與GHSA-j99q-93c9-h869),因此請執行目前版本。13

2026年4月轉向——以Obsidian CLI作為偏好的橋接方式: Obsidian 1.12.0導入了第一方CLI,而公開的1.12.7安裝程式(2026年3月23日)則隨附獨立binary、TUI與socket-file改善,讓終端工作流程更容易安裝與執行。16 目前公開桌面版發行版本1.13.1(公開通道,2026年6月9日)是在1.13.0上的版本更新——包含設定UX細節調整與CodeMirror升級——但在1.12.x CLI表面之外,沒有新增AI/自動化能力。2526 社群工具正積極從Local REST API plugin(mcp-obsidian所依賴)遷移到以CLI為基礎的整合,因為它更快也更穩定。MarkusPfundstein/mcp-obsidian repo仍在維護中——截至2026年5月的commits加入了包含search_by_tagget_frontmatter在內的工具——但沒有提供tagged releases(請從固定commit安裝)。它仍以Local-REST-API為基礎;新的設定通常建議優先採用CLI bridge或下方列出的較新社群替代方案,因為速度與穩定性更好。20 建議設定請參閱本指南後面的「AI Workflows的Obsidian CLI」章節。

Server Author Transport Requires Plugin Key Feature
obsidian-mcp-server StevenStavrakis STDIO No 輕量、以檔案為基礎
mcp-obsidian MarkusPfundstein STDIO Local REST API 透過REST提供完整vault CRUD,另有search_by_tag/get_frontmatter——積極維護中(commits截至2026年5月);沒有tagged releases,請固定commit20
obsidian-mcp-tools jacksteamdev STDIO Yes(plugin) 語意搜尋+Templater
obsidian-claude-code-mcp iansinnott WebSocket Yes(plugin) 供Claude Code使用的自動探索
obsidian-mcp-server cyanheads STDIO Local REST API 標籤、frontmatter管理
Hybrid Search MCP community STDIO No BM25+語意搜尋MCP伺服器+CLI。截至2026年4月仍是新的且積極維護。

快速開始最簡單的選項,是使用會直接讀取.md檔案的檔案型伺服器:

npm install -g obsidian-mcp-server

步驟3:設定您的AI工具

Claude Code——新增到~/.claude/settings.json

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-server",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

Codex CLI——新增到.codex/config.toml

[mcp_servers.obsidian]
command = "obsidian-mcp-server"
args = ["--vault", "/absolute/path/to/your/vault"]

Cursor——新增到.cursor/mcp.json

{
  "mcpServers": {
    "obsidian": {
      "command": "obsidian-mcp-server",
      "args": ["--vault", "/absolute/path/to/your/vault"]
    }
  }
}

步驟4:執行第一次查詢

開啟您的AI工具,詢問一個能由vault筆記回答的問題:

Search my Obsidian vault for notes about [topic you wrote about]

AI工具會呼叫MCP伺服器,由伺服器搜尋您的vault並回傳相符內容。您應該會看到包含檔案路徑與相關摘錄的結果。

Claude連線後能做什麼

確切工具名稱會因伺服器而異,但各實作的核心能力範圍大致一致:

Capability Typical tool What the agent does with it
搜尋vault obsidian_search / search 找出符合查詢的筆記,並回傳含檔案路徑與來源標註的排序摘錄
讀取完整筆記 obsidian_read_note / read_note 當搜尋摘錄不足時,擷取完整筆記內容
列出與瀏覽 obsidian_list_notes / list_notes 在沒有特定查詢時,依資料夾、標籤或日期範圍探索筆記
取得格式化context obsidian_get_context 回傳依主題整理、符合token budget大小的context區塊,可直接注入對話

實務上,Claude會從您的筆記中回答問題並附上來源標註,把先前決策與參考資料帶入程式開發工作階段,也能在不把整個檔案載入context的情況下探索vault結構。有些社群伺服器也提供寫入操作(建立、附加、標籤與frontmatter管理);本指南稍後建置的自訂伺服器刻意設計為唯讀,筆記建立則交由hooks處理。

深入閱讀:MCP Server Architecture說明工具與權限設計,Claude Code Integration說明hooks與bridge pattern,Codex CLI Integration以及Cursor and Other Tools則涵蓋其他agents。

您剛剛建置了什麼

您已透過標準協定,將本機知識庫連接到AI工具。MCP伺服器會讀取您的vault檔案、執行基本搜尋並回傳結果。這是最小可行版本。

這個快速開始不會提供: - Hybrid retrieval(BM25+vector search+RRF fusion) - 以embedding為基礎的語意搜尋 - 憑證篩選 - 增量索引 - 以hook為基礎的自動context注入

本指南其餘內容會說明如何逐一建置這些能力。快速開始證明概念可行;完整管線則提供正式環境品質的檢索能力。


Obsidian CLI在AI工作流程中的應用

Obsidian 1.12(2026年2月)導入內建命令列介面,為AI工作流程開啟新的整合介面;截至1.13.1公開桌面版(公開頻道,2026年6月9日)仍為最新狀態。該版本主要是settings-UX與CodeMirror版本升級,未新增CLI功能。162526 CLI就像Obsidian GUI的遠端控制器;Obsidian必須正在執行(或會在第一個命令時自動啟動)。請在Settings > General > Command line interface中啟用。

為什麼CLI對AI基礎架構很重要

CLI提供程式化方式存取Obsidian原生操作;這些操作過去需要GUI或plugin API。對AI工作流程而言,關鍵能力包括:

  • 從scripts與hooks搜尋。 obsidian search "query"obsidian search:context "query"可從任何shell script、hook或自動化pipeline執行vault搜尋。search:context變體會傳回符合的行及其周邊脈絡,適合將結果送入AI prompts。
  • 每日筆記自動化。 obsidian daily會開啟或建立今天的daily note。搭配shell scripting,便能實作自動化每日簡報工作流程;hook可將AI生成的摘要附加到daily note。
  • 以template建立筆記。 obsidian template listobsidian template create可從Templater或核心templates產生筆記,讓AI agents無須直接寫入markdown檔案,也能建立結構化vault項目。
  • 屬性管理。 obsidian property setobsidian property get可讀寫frontmatter屬性,讓scripts不必解析YAML,也能更新metadata。
  • Plugin控制。 obsidian plugin enable/disable/list可用程式化方式管理plugins,適合在批次操作期間切換indexing plugins。
  • 任務管理。 obsidian task list/add/complete提供結構化task存取,適合管理vault中工作項目的AI agents。

CLI與MCP在AI存取上的差異

CLI與MCP servers扮演不同角色,彼此互補,而非競爭:

面向 Obsidian CLI MCP Server
呼叫者 Shell scripts、hooks、cron jobs AI agents(Claude Code、Codex、Cursor)
協定 POSIX process(stdin/stdout/stderr) MCP(透過STDIO或HTTP的JSON-RPC)
強項 Obsidian原生操作(templates、plugins、properties) 自訂retrieval(embeddings、BM25、RRF fusion)
限制 無vector search,無embedding pipeline 無法存取Obsidian內部操作
最適合 自動化scripts、intake pipelines、hook actions 工作階段中的即時AI agent查詢

建議:將CLI用於intake自動化(建立筆記、管理properties、執行Obsidian原生搜尋),將MCP用於retrieval(搭配embeddings的hybrid search)。PreToolUse hook可先呼叫obsidian search:context進行快速預檢,再視需要退回完整MCP retriever取得排序結果。

範例:由CLI驅動的intake hook

#!/bin/bash
# Hook: append today's signals to daily note via CLI
DATE=$(date +%Y-%m-%d)
SUMMARY="$1"
obsidian daily  # ensure daily note exists
obsidian file append "Daily Notes/${DATE}.md" "## AI Summary\n${SUMMARY}"

Obsidian Agent Plugins

越來越多Obsidian plugins將AI coding agents直接嵌入vault UI,提供外部MCP server設定以外的替代方案。這些plugins會在Obsidian側邊欄內執行AI agent,而不是從外部工具連線。

Claudian

Claudian將Claude Code作為AI協作者嵌入vault。vault目錄會成為Claude的工作目錄,讓它具備完整agentic能力:檔案讀寫、搜尋、bash命令,以及多步驟工作流程。17

AI基礎架構的關鍵功能: - 具備脈絡感知的prompts。 自動附加目前聚焦的筆記,支援@notename檔案提及、以tag排除內容,以及將editor selection作為脈絡。 - Vision支援。 可透過拖放、貼上或檔案路徑分析圖片;適合處理vault中擷取的screenshots與diagrams。 - Slash commands。 建立可重複使用、由/command觸發的prompt templates,讓vault操作標準化。 - 權限模式。 YOLO(自動核准)、Safe(逐項核准)與Plan(僅規劃)模式,並具備安全blocklist與vault confinement。

Agent Client

Agent Client透過Agent Client Protocol(ACP),將Claude Code、Codex CLI與Gemini CLI整合到同一個Obsidian側邊欄。18

關鍵功能: - 多agent切換。 從同一面板與Claude Code、Codex或Gemini CLI對話,並可依需要在agents之間切換。 - 筆記提及。 使用@notename將筆記內容納入prompts,類似Claudian,但不綁定特定agent。 - Shell執行。 直接在chat中執行terminal commands;無論是build scripts、git commands,或任何terminal操作,都不必離開對話。 - 動作核准。 對檔案讀取、編輯與命令執行提供細緻控制。

何時使用agent plugins,何時使用外部MCP

情境 Agent plugin 外部MCP
以AI協助撰寫與編輯vault筆記 較佳:agent能看到editor context 可行,但沒有editor awareness
跨多個repos進行程式碼開發 受限:以vault為範圍 較佳:以project為範圍,具完整filesystem
從大型已indexed corpus進行retrieval 僅有基本搜尋 完整hybrid retrieval pipeline
記筆記時快速進行vault問答 理想:無須切換脈絡 需要切換到terminal

建議:將agent plugins用於以vault為核心的工作流程(撰寫、整理、摘要筆記)。將外部MCP servers用於開發工作流程,尤其是AI agent需要完整retrieval pipeline,並存取vault外部codebases時。兩種做法可以並存:在Obsidian內執行Claudian處理筆記工作,並在外部使用搭配MCP的Claude Code進行開發。


決策框架:Obsidian與替代方案

並非每個使用案例都需要Obsidian。本節說明何時Obsidian是合適的基礎,何時顯得大材小用,以及何時其他工具更適合。

決策樹

START: What is your primary content type?

├─ Structured data (tables, records, schemas)
   Use a database. SQLite, PostgreSQL, or a spreadsheet.
   Obsidian is for prose, not tabular data.

├─ Ephemeral context (current project, temporary notes)
   Use CLAUDE.md / AGENTS.md in the project repo.
   These travel with the code and reset per project.

├─ Team wiki (shared documentation, onboarding)
   Evaluate Notion, Confluence, or a shared git repo.
   Obsidian vaults are personal-first. Team sync is possible
    but not native.

└─ Growing personal knowledge corpus
   
   ├─ < 50 notes
      A folder of markdown files + grep is sufficient.
      Obsidian adds value mainly through the link graph,
       which needs density to be useful.
   
   ├─ 50 - 500 notes
      Obsidian adds value. Wiki-links create a navigable graph.
      BM25-only search (FTS5) is sufficient at this scale.
      Skip vector search and RRF until keyword collisions appear.
   
   ├─ 500 - 5,000 notes
      Full hybrid retrieval becomes valuable. Keyword collisions
       increase. Semantic search catches queries that BM25 misses.
      Add vector search + RRF fusion at this scale.
   
   └─ 5,000+ notes
       Full pipeline is essential. BM25-only returns too much noise.
       Credential filtering becomes critical (more notes = more
        accidentally pasted secrets).
       Incremental indexing matters (full reindex takes minutes).
       MCP integration pays dividends on every AI interaction.

比較矩陣

評估標準 Obsidian Notion Apple Notes Plain Filesystem CLAUDE.md
Local-first 否(雲端) 部分(iCloud)
Plaintext 是(markdown) 否(blocks) 否(專有格式)
圖狀結構 是(wiki-links) 部分(mentions)
AI可索引 直接存取檔案 需要API 需要匯出 直接存取檔案 已在context中
Plugin生態系 2,500多個plugins Integrations N/A N/A
離線能力 完整 快取唯讀 部分 完整 完整
可擴展至10K+筆記 是(搭配API) 效能下降 否(單一檔案)
成本 免費(核心功能) $10/月以上 免費 免費 免費

何時Obsidian顯得大材小用

  • 單一專案context。如果AI只需要目前程式碼庫的context,請放在CLAUDE.mdAGENTS.md或專案層級文件中。這些檔案會隨repo一起移動,並自動載入。
  • 結構化資料。如果內容是表格、記錄或schema,請使用資料庫。Obsidian筆記以 prose 為優先。Dataview可以查詢frontmatter欄位,但真正的資料庫更擅長處理結構化查詢。
  • 暫時性研究。如果筆記會在專案結束後丟棄,用一個放markdown檔案的scratch目錄會更簡單。不要為短暫內容建置retrieval基礎設施。

何時Obsidian是正確選擇

  • 累積數月或數年的知識。隨著語料庫成長,價值會持續複利。一個每天查詢、持續6個月的200則筆記vault,會比只查詢一次的5,000則筆記vault更有價值。
  • 單一語料庫涵蓋多個領域。包含程式設計、架構、安全、設計與個人專案筆記的vault,能受益於跨領域retrieval;這是專案專屬CLAUDE.md無法提供的。
  • 重視隱私的內容。Local-first表示retrieval pipeline永遠不會把內容傳送到外部服務。vault會包含您放入其中的任何內容,包括您不會上傳到雲端服務的資料。

心智模型:三個層次

此系統有三個彼此獨立運作、但結合後相輔相成的層次。每個層次關注的問題不同,失效模式也不同。

┌─────────────────────────────────────────────────────┐
                 INTEGRATION LAYER                     
  MCP servers, hooks, skills, context injection        
  Concern: delivering context to AI tools              
  Failure: wrong context, too much context, stale      
└──────────────────────┬──────────────────────────────┘
                        query + ranked results
┌──────────────────────┴──────────────────────────────┐
                  RETRIEVAL LAYER                      
  BM25, vector KNN, RRF fusion, token budget           
  Concern: finding the right content for any query     
  Failure: wrong ranking, missed results, slow queries 
└──────────────────────┬──────────────────────────────┘
                        chunked, embedded, indexed
┌──────────────────────┴──────────────────────────────┐
                   INTAKE LAYER                        
  Note creation, signal triage, vault organization     
  Concern: what enters the vault and how it's stored   │
  Failure: noise, duplicates, missing structure        
└─────────────────────────────────────────────────────┘

Intake決定哪些內容進入vault。若缺乏策展,vault會累積雜訊:推文截圖、沒有註解的複製貼上文章、缺少context的半成品想法。intake層負責在入口處進行品質控管。無論是評分pipeline、tagging慣例,或人工審查流程,目的都是確保vault包含值得retrieving的內容。

Retrieval讓vault可被查詢。這是引擎:將筆記chunking成搜尋單元、把chunks embedding到向量空間、建立關鍵字與語意搜尋索引,並用RRF融合結果。retrieval層會把一個檔案目錄轉換成可查詢的知識庫。沒有這一層,vault仍可透過手動瀏覽與基本搜尋來導覽,但AI tools無法以程式化方式存取。

Integration將retrieval層連接到AI tools。MCP伺服器會將retrieval公開為可呼叫的tool。Hooks會自動注入context。Skills會把新知識擷取回vault。integration層是知識庫與消費它的AI agents之間的介面。

這些層次在設計上彼此解耦。intake評分pipeline不了解embeddings。retriever不了解signal routing規則。MCP伺服器不了解筆記是如何建立的。這種解耦代表您可以獨立改善任何一層。更換embedding模型,不必變更intake pipeline。新增MCP能力,不必修改retriever。調整signal scoring heuristics,不必碰觸index。


供 AI 取用的 Vault 架構

為 AI 檢索最佳化的 vault,遵循的慣例不同於為個人瀏覽最佳化的 vault。本節說明資料夾結構、筆記 schema、frontmatter 慣例,以及能提升檢索品質的具體模式。

資料夾結構

使用編號前綴作為頂層資料夾名稱,以建立可預期的組織層級。這些數字不代表優先順序,而是用來群組相關領域,讓結構一目了然。

vault/
├── 00-inbox/              # Unsorted captures, pending triage
├── 01-projects/           # Active project notes
├── 02-areas/              # Ongoing areas of responsibility
├── 03-resources/          # Reference material by topic
   ├── programming/
   ├── security/
   ├── ai-engineering/
   ├── design/
   └── devops/
├── 04-archive/            # Completed projects, old references
├── 05-signals/            # Scored signal intake
   ├── ai-tooling/
   ├── security/
   ├── systems/
   └── ...12 domain folders
├── 06-daily/              # Daily notes (if used)
├── 07-templates/          # Note templates (excluded from index)
├── 08-attachments/        # Images, PDFs (excluded from index)
├── .obsidian/             # Obsidian config (excluded from index)
└── .indexignore            # Paths to exclude from retrieval index

應該建立索引的資料夾:所有包含 markdown 文字內容的資料夾,例如 projects、areas、resources、signals、daily notes。

應該排除於索引之外的資料夾:Templates(內含 placeholder 變數,而非內容)、attachments(二進位檔案)、Obsidian 設定,以及任何含有敏感內容、不希望進入檢索索引的資料夾。

.indexignore 檔案

在 vault 根目錄建立 .indexignore 檔案,明確排除不納入檢索索引的路徑。語法與 .gitignore 相同:

# Obsidian internal
.obsidian/

# Templates contain placeholders, not content
07-templates/

# Binary attachments
08-attachments/

# Personal health/medical notes
02-areas/health/

# Financial records
02-areas/finance/personal/

# Career documents (resumes, salary data)
02-areas/career/private/

indexer 會在掃描前讀取此檔案,並完全略過相符的路徑。被排除路徑中的檔案不會被 chunking、不會產生 embeddings,也不會出現在搜尋結果中。

筆記 Schema

每則筆記都應該有 YAML frontmatter。retriever 會使用 frontmatter 欄位進行篩選與脈絡補充:

---
title: "OAuth Token Rotation Patterns"
type: note           # note | signal | project | moc | daily
domain: security     # primary domain for routing
tags:
  - authentication
  - oauth
  - token-management
created: 2026-01-15
updated: 2026-02-28
source: ""           # URL if captured from external source
status: active       # active | archived | draft
---

檢索所需欄位:

  • title — 用於搜尋結果顯示,以及 BM25 的標題脈絡
  • type — 啟用依類型篩選的查詢(「只顯示 MOC」或「只顯示 signals」)
  • tags — 以 0.3 權重索引到 FTS5 標題脈絡中,即使正文使用不同術語,也能提供關鍵字比對

選用但很有價值的欄位:

  • domain — 啟用依領域限定範圍的查詢(「只搜尋 security 筆記」)
  • source — 標示擷取內容的來源;retriever 可以在結果中包含來源 URL
  • status — 可將封存或草稿筆記排除於 active search 之外

Chunking 慣例

retriever 會在 H2(##)標題邊界進行 chunking。也就是說,筆記結構會直接影響檢索粒度:

有利於檢索:

## Token Rotation Strategy

The rotation interval depends on the threat model...

## Implementation with refresh_token

The OAuth 2.0 refresh token flow requires...

## Error Handling: Expired Tokens

When a token expires mid-request...

3 個 H2 區段會產生 3 個可獨立搜尋的 chunks。每個 chunk 都有足夠脈絡,讓 embedding 捕捉其意義。關於「expired token handling」的查詢會精準比對到第 3 個 chunk。

不利於檢索:

# OAuth Notes

Token rotation depends on threat model. The OAuth 2.0 refresh
token flow requires storing the refresh token securely. When a
token expires mid-request, the client should retry after refresh.
The rotation interval is typically 15-30 minutes for access tokens
and 7-30 days for refresh tokens...

一個沒有 H2 標題的長區段會產生一個大型 chunk。embedding 會在該區段的所有主題之間取平均。查詢任何子主題時,都會同等比對到整則筆記。

經驗法則:如果一個區段涵蓋超過一個概念,請拆成 H2 子區段。chunker 會處理其餘部分。

不應放進筆記的內容

會降低檢索品質的內容:

  • 未加註解就完整複製貼上的整篇文章。retriever 會索引原文的關鍵字,讓您的 vault 被非您撰寫的內容稀釋。請改為加入摘要、摘錄重點,或連結到來源 URL。
  • 沒有文字說明的截圖。retriever 索引的是 markdown 文字。沒有 alt text 或周邊描述的圖片,對 BM25 與 vector search 都是不可見的。
  • credential 字串。API keys、tokens、passwords、connection strings。即使有 credential filtering,最安全的做法仍是永遠不要把 secrets 貼進筆記。請改用名稱參照(例如「~/.env 中的 Cloudflare API token」)。
  • 未經整理的自動產生內容。如果工具產生筆記(meeting transcript、Readwise highlights、RSS import),請先審閱並加註後,再放入永久 vault。未整理的自動匯入只會增加數量,卻不會增加可檢索價值。

AI Workflows 的 Plugin 生態系

能提升 AI 檢索用 vault 品質的 Obsidian plugins,可分為 3 類:結構型(強制一致性)、查詢型(公開 metadata),以及同步型(讓 vault 保持最新)。

必備 Plugins

Dataview。使用 frontmatter 欄位,像查詢資料庫一樣查詢您的 vault。可建立動態索引,例如:「過去 30 天內更新、標記為 security 的所有筆記」,或「狀態為 active 的所有專案筆記」。Dataview 不會直接幫助檢索,但能協助您找出 vault 覆蓋範圍的缺口,並找出需要更新的筆記。

TABLE type, domain, updated
FROM "03-resources"
WHERE status = "active"
SORT updated DESC
LIMIT 20

Templater。透過具備動態欄位的範本建立筆記。使用預先填入 createdtypedomain 欄位的範本,確保每則新筆記一開始就具備正確的 frontmatter。一致的 frontmatter 能改善檢索篩選。

<%* /* New Resource Note Template */ %>
---
title: "<% tp.file.cursor() %>"
type: note
domain: <% tp.system.suggester(["programming", "security", "ai-engineering", "design", "devops"], ["programming", "security", "ai-engineering", "design", "devops"]) %>
tags: []
created: <% tp.date.now("YYYY-MM-DD") %>
updated: <% tp.date.now("YYYY-MM-DD") %>
source: ""
status: active
---

## Key Points

## Details

## References

Linter。在整個 vault 中強制套用格式規則。一致的標題階層(H1 作為標題、H2 作為章節、H3 作為小節)可確保 chunker 產生可預期的結果。對檢索有影響的 Linter 規則包括:

  • 標題遞增:強制標題層級依序排列(不可從 H1 跳到 H3)
  • YAML 標題:符合檔案名稱
  • 行尾空格:移除(避免 FTS5 tokenization artifact)
  • 連續空白行:限制為 1 行(產生更乾淨的 chunks)

Git integration。為您的 vault 提供版本控制。可追蹤隨時間變化的修改、在多台機器間同步,並從意外刪除中復原。Git 也提供 mtime 資料,indexer 會用它進行增量變更偵測。

有助於 Indexing 的 Plugins

Smart Connections。這是一個 Obsidian plugin,可在 Obsidian 內提供 AI 驅動的語意搜尋。Smart Connections v4 預設會建立本機 embeddings;一旦 vault 完成索引,語意連結與查找即可完全離線運作,不需要 API 呼叫。11 v4.5.0(2026年5月5日)將頁尾連結納入 Smart Connections Core,因此每個安裝都能在頁尾顯示相關筆記連結,不必開啟側邊面板。近期 v4 版本也加入了連結清單的圖形檢視、可設定的 dock 位置、索引中斷後更完善的 block-embedding 復原,以及「Substrate」:一個跨 plugin 環境,讓 Smart Connections、Smart Chat 和 Smart Composer 能共享狀態。21 本指南中的檢索系統位於 Obsidian 外部(作為 Python pipeline 執行),但 Smart Connections 對寫作時探索語意關係很有幫助。兩套系統索引相同內容,但服務不同情境:Smart Connections 用於編輯器內探索;外部 retriever 則透過 MCP 與 AI tool 整合。

2026年4月推出的 AI-native plugins。一波新的社群 plugins 直接鎖定 Claude Code / Codex / Gemini-CLI workflow:

Plugin 發布時間 功能
Cortex 4月4日 由 Claude Code 驅動的 vault agent:將 vault 視為 agent 工作區,而不只是筆記儲存處
VaultSearch 4月7日 Local-first hybrid 搜尋:BM25 + 語意 + 模糊搜尋(與本指南的檢索堆疊直接重疊)
LLM Wiki 4月9日 將您的 vault 轉為可私下查詢的知識庫
Drift 4月11日 用於 AI 驅動 Obsidian 編輯的 VS Code 風格 diff 檢視器;定位於 Claude Code workflows
EngramQuest 4月11日 從筆記產生記憶挑戰;提供適用於 Claude Code / Gemini CLI / Cursor 的「AI Skills」
Hybrid Search MCP 3月(仍屬新項目) MCP server + CLI,搭配 BM25 + 語意搜尋,專為 AI assistants 打造

可將這視為正在浮現的應用表面:其中幾個很可能在接下來幾季整併,或被 Smart Connections / Obsidian core 吸收。如果今天要選一個,VaultSearch 和 Hybrid Search MCP 在理念上最接近本指南的外部 retriever。

Dataview note:Dataview(長期存在的 Obsidian 查詢 plugin)最後一次發布是 2025年4月的 0.5.70,之後實質上已停滯。對於新工作,Obsidian 內建的 Bases 功能(1.9+)是隱含的後繼者,也是建議採用的路徑。

Metadata Menu。提供結構化 frontmatter 編輯,並為欄位值提供自動完成。可減少 typedomaintags 欄位中的錯字。一致的 metadata 能提升檢索篩選準確度。

會傷害 Indexing 的 Plugins

Excalidraw。將繪圖以嵌入於 markdown 檔案中的 JSON 形式儲存。這些 JSON 在語法上是有效的 markdown,但在 chunking 和 embedding 時會產生雜訊。請透過 .indexignore 將 Excalidraw 檔案排除在索引之外,或依副檔名篩選。

Kanban。以特殊格式的 markdown 儲存看板狀態。此格式是為 Kanban 呈現而設計,不適合 prose retrieval。chunker 會產生卡片標題與 metadata 的片段,embedding 效果不佳。請將 Kanban boards 排除在索引之外。

Calendar。建立內容極少的每日筆記(通常只有日期標題)。空白或近乎空白的筆記會產生低品質 chunks。若使用每日筆記,請在其中撰寫實質內容,或將每日筆記資料夾排除在索引之外。

重要的 Plugin 設定

File recovery → Enabled。防止意外刪除筆記。這與檢索沒有直接關係,但對您所依賴的知識庫至關重要。

Strict line breaks → Disabled。Markdown 標準換行(以雙換行分隔段落)比 Obsidian strict mode(以單一換行產生 <br>)能產生更乾淨的 chunks。

Default new file location → Designated folder。將新檔案導向 00-inbox/,避免未分類筆記污染 domain folders。inbox 是暫存區;檔案會在 triage 後移至 domain folders。

Wiki-link format → Shortest path when possible。較短的 link targets 讓 retriever 在索引 link structure 時更容易解析。


Embedding Models:選擇與設定

embedding模型會將文字chunk轉換成語意搜尋使用的數值向量。模型選擇會決定擷取品質、索引大小、embedding速度,以及執行階段相依套件。本節說明為何Model2Vec的potion-base-8M是預設選擇,以及何時該選用替代方案。

為何選擇Model2Vec potion-base-8M

Model: minishlab/potion-base-8M Parameters: 760萬 Dimensions: 256 Size: 約30 MB Dependencies: model2vec(僅numpy,無PyTorch) Inference: 僅CPU、靜態word embeddings(無attention layers)

Model2Vec會將sentence transformer的知識蒸餾成靜態token embeddings。Model2Vec不像BERT、MiniLM與其他transformer模型那樣在輸入上執行attention layers,而是透過預先計算的token embeddings加權平均來產生向量。5實務上的結果是:embedding速度比transformer-based模型快50到500倍,因為沒有序列運算。

在目前的Model2Vec結果頁面中,potion-base-8M達到all-MiniLM-L6-v2全任務分數約92%(51.32對55.80),同時速度仍快上數個數量級。6剩餘的品質差距,是換取速度與簡潔性的取捨。對於較短的markdown chunk(典型vault平均200到400字),品質差異不像長文件那麼明顯,因為兩種模型都會對短而聚焦的文字收斂到相近表徵。

設定

# embedder.py
DEFAULT_MODEL = "minishlab/potion-base-8M"
EMBEDDING_DIM = 256

class Model2VecEmbedder:
    def __init__(self, model_name=DEFAULT_MODEL):
        self._model_name = model_name
        self._model = None

    def _ensure_model(self):
        if self._model is not None:
            return
        _activate_venv()  # Add isolated venv to sys.path
        from model2vec import StaticModel
        self._model = StaticModel.from_pretrained(self._model_name)

    def embed_batch(self, texts):
        self._ensure_model()
        vecs = self._model.encode(texts)
        return [v.tolist() for v in vecs]

延遲載入。模型會在首次使用時載入,而不是在import時載入。當retriever以僅BM25的fallback模式運作時(例如embedding venv尚未安裝),匯入embedder模組不會產生成本。

隔離的虛擬環境。模型會在專用venv中執行(例如~/.claude/venvs/memory/),避免與其餘toolchain發生相依套件衝突。_activate_venv()函式會在執行階段將venv的site-packages加入sys.path

# Create isolated venv
python3 -m venv ~/.claude/venvs/memory
~/.claude/venvs/memory/bin/pip install model2vec

批次處理。embedder會以64筆為一批處理文字,以攤平Model2Vec的額外成本。indexer會將chunk送入embed_batch(),而不是一次只embedding一個chunk。

何時選擇替代方案

Model Dim Size Speed Quality (MTEB) 最適合
potion-base-8M 256 30 MB 500x 51.32 預設:本機、快速、無GPU
potion-base-32M 256 120 MB 400x 52.83 較高品質,仍為靜態
potion-retrieval-32M 256 120 MB 400x 35.06(retrieval) 針對retrieval最佳化的靜態模型
potion-multilingual-128M 256 約500 MB 300x 多語言vault(101種語言)
all-MiniLM-L6-v2 384 80 MB 1x 55.80 較高品質,仍可本機執行
nomic-embed-text-v1.5 768 270 MB 0.5x 62.28 最佳本機品質
text-embedding-3-small 1536 API N/A 62.30 基於API,最高品質

若想要比potion-base-8M更好的品質,又不離開靜態embedding系列,請選擇potion-base-32M。它使用從baai/bge-base-en-v1.5蒸餾而來的較大詞彙表,達到52.83全任務分數(約比potion-base-8M高3%),同時維持相同的256維輸出與僅numpy相依。8模型檔案增為4倍會提高記憶體用量,但embedding速度仍比transformer模型快上數個數量級。

若主要使用案例是retrieval(vault搜尋正是如此),請選擇potion-retrieval-32M。此變體是從potion-base-32M針對retrieval任務微調而來,在Model2Vec的retrieval benchmark表中取得35.06分,高於potion-base-32M的32.67分。8取捨在於它是為retrieval最佳化,而不是一般用途的embedding品質。

若vault包含多種語言的筆記,請選擇potion-multilingual-128M。這個101語言模型於2025年5月發布,是多語言任務中表現最佳的靜態embedding模型,可為任何語言的任何文字產生embeddings,同時維持與其他potion模型相同的僅numpy相依。12較大的模型檔案(約500 MB)是換取跨語言能力的代價。若有日文、中文、德文或其他非英文筆記與英文內容並存,請使用此模型。

若retrieval品質比速度更重要,且已安裝PyTorch,請選擇all-MiniLM-L6-v2。384維向量會讓SQLite資料庫大小比256維向量增加約50%。在M系列硬體上,對15,000個檔案進行完整重新索引時,embedding速度會從少於1分鐘降至約10分鐘。

若需要最佳的本機retrieval品質,並能接受較慢的索引速度,請選擇nomic-embed-text-v1.5。768維向量大約會使資料庫大小變為3倍。需要PyTorch與現代CPU或GPU。

若網路延遲與隱私是可接受的取捨,請選擇text-embedding-3-small。API會產生最高品質的embeddings,但會引入雲端相依、按token計費(每百萬token 0.02美元),並將內容傳送到OpenAI的伺服器。

其他所有情況都維持使用potion-base-8M。速度優勢對反覆索引至關重要(開發期間重新索引),僅numpy相依可避開PyTorch安裝複雜度,而256維向量能讓資料庫保持精簡。

Quantization與維度縮減

Model2Vec v0.5.0+支援以降低精度與維度載入模型。8這對受限硬體部署,或在不切換模型的情況下降低資料庫大小很有幫助:

from model2vec import StaticModel

# Load with int8 quantization (25% of original size)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", quantize=True)

# Load with reduced dimensions (e.g., 128 instead of 256)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", dimensionality=128)

Quantized模型能以一小部分記憶體占用,保留幾乎相同的retrieval品質。維度縮減採Matryoshka式截斷,前N個維度承載最多資訊。從256維降到128維,可將向量儲存空間減半,且在短文字retrieval上品質損失極小。

Model2Vec v0.8.x更新tokenizer與persistence內部實作、棄用Python 3.9支援,並將發布結果更新到較新的MTEB表。升級production indexer前,請先釘選或測試model2vec,因為即使embedding模型名稱維持不變,函式庫升級仍可能改變模型載入路徑。10

針對Vault特定Embeddings進行微調

Model2Vec v0.4.0+支援在靜態embeddings之上訓練自訂分類模型,v0.7.0加入詞彙量化與可設定pooling以進行蒸餾,v0.8.x則重構tokenizer與persistence行為。10這對具備專門詞彙的vault很有關聯(醫療筆記、法律參照、領域專用術語),因為預設potion模型可能無法捕捉語意細微差異:

from model2vec import StaticModel
from model2vec.train import train_model

# Fine-tune on vault-specific data
model = StaticModel.from_pretrained("minishlab/potion-base-8M")
trained_model = train_model(model, train_texts, train_labels)
trained_model.save_pretrained("./vault-embeddings")

對大多數vault而言,預設potion-base-8M已能產生足夠的retrieval品質。只有當retrieval持續漏掉一般用途模型無法捕捉的領域特定連結時,微調才值得投入。

Model Hash追蹤

indexer會儲存由模型名稱與詞彙表大小衍生的hash。若更換embedding模型,indexer會在下一次incremental run偵測到不一致,並自動觸發完整重新索引。

def _compute_model_hash(self):
    """Hash model name + vocab size for compatibility tracking."""
    key = f"{self._model_name}:{self._model.vocab_size}"
    return hashlib.sha256(key.encode()).hexdigest()[:16]

這可避免在同一個資料庫中混用不同模型產生的向量,否則會產生毫無意義的cosine similarity分數。

失敗模式

模型下載失敗。首次執行會從Hugging Face下載模型。若下載失敗(網路問題、企業防火牆),retriever會fallback到僅BM25模式。第一次下載後,模型會快取到本機。

維度不一致。若未清除資料庫就切換模型,已儲存向量會與新的embeddings維度不同。indexer會透過model hash偵測此狀況,並觸發完整重新索引。若hash檢查失敗(自訂模型沒有正確hash),sqlite-vec會在維度不一致的KNN查詢上報錯。

大型vault的記憶體壓力。單一批次embedding 50,000個以上chunk可能消耗大量記憶體。indexer會以64筆為一批處理,以限制尖峰記憶體用量。若記憶體仍有問題,請降低batch size。


使用 FTS5 進行全文搜尋

SQLite 的 FTS5 擴充功能提供具備 BM25 排名的全文搜尋。FTS5 是 hybrid 檢索管線中的關鍵字搜尋元件。本節說明 FTS5 設定、BM25 擅長的情境,以及其特定失效模式。

FTS5 Virtual Table

CREATE VIRTUAL TABLE chunks_fts USING fts5(
    chunk_text,
    section,
    heading_context,
    content=chunks,
    content_rowid=id
);

內容同步模式。content=chunks參數會告訴 FTS5 直接參照chunks資料表,而不是儲存一份重複的文字副本。這能將儲存需求減半,但也表示當 chunk 被插入、更新或刪除時,必須手動同步 FTS5。

欄位。索引包含3個欄位: - chunk_text—每個 chunk 的主要內容(BM25 權重:1.0) - section—H2 標題文字(BM25 權重:0.5) - heading_context—筆記標題、標籤與 metadata(BM25 權重:0.3)

BM25 排名

BM25 會依據詞彙頻率、反向文件頻率,以及文件長度正規化來排列文件。FTS5 中的bm25()輔助函式可接受各欄位的權重:

SELECT
    c.id, c.file_path, c.section, c.chunk_text,
    bm25(chunks_fts, 1.0, 0.5, 0.3) AS score
FROM chunks_fts
JOIN chunks c ON chunks_fts.rowid = c.id
WHERE chunks_fts MATCH ?
ORDER BY score
LIMIT 30;

欄位權重(1.0、0.5、0.3)代表: - chunk_text中的關鍵字符合會對分數貢獻最多 - section(標題)中的符合貢獻為一半 - heading_context(標題、標籤)中的符合貢獻為30%

這些權重可以調整。如果您的 vault 中有描述性強、能高度預測內容品質的標題,請提高section權重。如果標籤完整且準確,請提高heading_context權重。

BM25 何時勝出

BM25 擅長處理包含精確識別碼的查詢:

  • 函式名稱:_rrf_fuseembed_batchget_stale_files
  • CLI 旗標:--incremental--vault--model
  • 設定鍵:bm25_weightmax_tokensbatch_size
  • 錯誤訊息:SQLITE_LOCKEDConnectionRefusedError
  • 特定術語:PostToolUsePreToolUseAGENTS.md

對這些查詢而言,BM25 會立即找到精確符合項目。向量搜尋會回傳語意相關的內容,但可能把精確符合項目排在概念性討論之後。

BM25 何時失效

當查詢使用的術語與儲存內容不同時,BM25 會失效:

  • 查詢:「how to handle authentication failures」→ Vault 中包含關於「login error recovery」與「session expiration handling」的筆記。BM25 不會符合,因為關鍵字不同。
  • 查詢:「what is the best way to manage state」→ Vault 中包含關於「Redux store patterns」與「context providers」的筆記。BM25 會漏掉,因為「state management」是透過特定技術名稱來表達。

BM25 在規模變大時也會因為關鍵字碰撞而失效。在15,000個檔案的 vault 中,搜尋「configuration」會符合數百則筆記,因為幾乎每個專案筆記都會提到 configuration。結果在技術上正確,實務上卻難以使用——排名無法判斷哪一則「configuration」筆記與目前查詢相關。

FTS5 Tokenizer

FTS5 預設使用unicode61 tokenizer,可處理 ASCII 與 Unicode 文字。若 vault 含有大量 CJK(中文、日文、韓文)內容,可以考慮使用trigram tokenizer:

-- For CJK-heavy vaults
CREATE VIRTUAL TABLE chunks_fts USING fts5(
    chunk_text, section, heading_context,
    content=chunks, content_rowid=id,
    tokenize='trigram'
);

預設的unicode61 tokenizer 會依單字邊界切分,對沒有空格分隔詞彙的語言效果不佳。trigram tokenizer 會每3個字元切分一次,能支援子字串符合,但代價是索引大小增加(約為3倍)。

維護

當底層chunks資料表變更時,FTS5 需要明確同步:

# After inserting chunks
cursor.execute("""
    INSERT INTO chunks_fts(chunks_fts)
    VALUES('rebuild')
""")

rebuild命令會從內容資料表重建 FTS5 索引。大量插入後(完整重新索引)執行此命令,但不要在個別增量更新後執行;針對這類情境,請使用INSERT INTO chunks_fts(rowid, chunk_text, section, heading_context)來同步個別資料列。


sqlite-vec 擴充功能將 vector KNN(K-Nearest Neighbors)搜尋帶入 SQLite。本節說明 sqlite-vec 設定、從筆記到可搜尋 vector 的 embedding pipeline,以及具體的查詢模式。

sqlite-vec Virtual Table

CREATE VIRTUAL TABLE chunk_vecs USING vec0(
    id INTEGER PRIMARY KEY,
    embedding float[256]
);

vec0 模組會將 256 維浮點 vector 儲存為封裝後的二進位資料。id 欄位與 chunks 資料表形成 1:1 對應,因此可在 vector 結果與 chunk metadata 之間進行 join。

Embedding Pipeline

pipeline 會從筆記一路流向可搜尋的 vector:

Note (.md file)
   Chunker: split at H2 boundaries
     Chunks (30-2000 chars each)
       Credential filter: scrub secrets
         Embedder: Model2Vec encode
           Vectors (256-dim float arrays)
             sqlite-vec: store as packed binary
               Ready for KNN queries

Vector Serialization

Python 的 struct 模組會將浮點 vector 序列化,以便存入 sqlite-vec:

import struct

def _serialize_vector(vec):
    """Pack float list into binary for sqlite-vec."""
    return struct.pack(f"{len(vec)}f", *vec)

def _deserialize_vector(blob, dim=256):
    """Unpack binary blob to float list."""
    return list(struct.unpack(f"{dim}f", blob))

KNN Query

vector search query 會先將輸入查詢轉成 embedding,接著依 cosine distance 找出最接近的 K 個 chunks:

def _vector_search(self, query_text, limit=30):
    query_vec = self.embedder.embed_batch([query_text])[0]
    packed = _serialize_vector(query_vec)

    results = self.db.execute("""
        SELECT
            cv.id,
            cv.distance,
            c.file_path,
            c.section,
            c.chunk_text
        FROM chunk_vecs cv
        JOIN chunks c ON cv.id = c.id
        WHERE embedding MATCH ?
            AND k = ?
        ORDER BY distance
    """, [packed, limit]).fetchall()

    return results

sqlite-vec 中的 MATCH 運算子會執行 approximate nearest neighbor search。k 參數控制要回傳多少結果。distance 欄位包含 cosine distance(0 = 完全相同,2 = 完全相反)。

使用 Distance Constraints 進行 KNN Pagination

自 sqlite-vec v0.1.7 起,KNN queries 支援 WHERE distance < ? constraints,可在大型結果集上進行 cursor-based pagination,且不必重新掃描先前頁面。14 後續 v0.1.8 與 v0.1.9 stable releases 主要是 packaging 與 DELETE bug-fix releases,而不是新的 query-model releases,因此 v0.1.7 仍是此 pagination pattern 的功能分界。23

接下來的 v0.1.10-alpha 系列(2026年3月31日至5月18日)是 sqlite-vec 首次超越 brute-force KNN 的版本:它引入 approximate-nearest-neighbor index types,包括 rescore、實驗性的 ivf(inverted-file)index(預設未啟用),以及適用於 vector 太大、無法常駐記憶體的大型 vault 的 disk-based DiskANN index。23 這些功能會改變超大型 vault 的擴展性敘事,但 0.1.10 系列仍是 pre-release (alpha)。請將 ANN indexing 視為實驗性功能;在 stable 0.1.10 發布前,production vaults 仍建議持續建立在 stable v0.1.9 brute-force KNN 路徑上。

def _paginated_vector_search(self, query_vec, page_size=20, max_distance=None):
    """Paginate through KNN results using distance constraints."""
    packed = _serialize_vector(query_vec)
    constraint = f"AND distance < {max_distance}" if max_distance else ""

    results = self.db.execute(f"""
        SELECT cv.id, cv.distance, c.file_path, c.chunk_text
        FROM chunk_vecs cv
        JOIN chunks c ON cv.id = c.id
        WHERE embedding MATCH ?
            AND k = ?
            {constraint}
        ORDER BY distance
    """, [packed, page_size]).fetchall()

    # Use last result's distance as cursor for next page
    next_cursor = results[-1][1] if results else None
    return results, next_cursor

這會取代過去先擷取很大的 k、再於 Python 中 slicing 的模式,降低在大型 vault 上執行探索式查詢時的記憶體用量。

vec0 Tables 中的 DELETE Support

sqlite-vec v0.1.7 為 vec0 virtual tables 加入原生 DELETE support,而 v0.1.9 修正了涉及長度超過 12 個字元的 metadata text columns 時的 DELETE error path。1423 先前若要移除 vectors,必須 drop 並重新建立資料表。現在 indexer 的 file-removal path 可以直接刪除 vectors:

# Before v0.1.7: required workaround (drop + recreate, or mark as inactive)
# After v0.1.7: direct DELETE works
db.execute("DELETE FROM chunk_vecs WHERE id = ?", [chunk_id])

這讓筆記被刪除或移動時的 incremental reindexing 更為簡潔。indexer 不再需要維護 shadow「active IDs」資料表,也不需要進行 batch rebuilds。

Vector Search 何時勝出

當概念比特定文字更重要時,vector search 表現尤其出色:

  • Query: “how to handle authentication failures” → 找到關於 “login error recovery” 的筆記(相同語意空間,不同關鍵字)
  • Query: “what patterns exist for caching” → 找到關於 “memoization,” “Redis TTL strategies,” 以及 “HTTP cache headers” 的筆記(相關概念,多樣術語)
  • Query: “approaches to testing asynchronous code” → 找到關於 “pytest-asyncio fixtures,” “mock event loops,” 以及 “async test patterns” 的筆記(同一概念透過實作細節表達)

Vector Search 何時失準

vector search 不擅長處理精確識別符:

  • Query: _rrf_fuse → 會回傳關於 “fusion algorithms” 與 “rank merging” 的筆記,但實際函式定義的排序可能低於概念討論
  • Query: PostToolUse → 會回傳關於 “tool lifecycle hooks” 與 “post-execution handlers” 的筆記,而不是特定 hook 名稱

vector search 也不擅長處理結構化資料。JSON 設定檔、YAML blocks,以及程式碼片段產生的 embeddings,往往捕捉的是結構模式,而非語意意義。含有 "review": true 的 JSON 檔案,embedding 結果會不同於一段討論 code review 的散文。

Graceful Degradation

如果 sqlite-vec 載入失敗(缺少 extension、平台不相容、library 損毀),retriever 會 fallback 到僅使用 BM25 的搜尋:

class VectorIndex:
    def __init__(self, db_path):
        self.db = sqlite3.connect(db_path)
        self._vec_available = False
        try:
            self.db.enable_load_extension(True)
            self.db.load_extension("vec0")
            self._vec_available = True
        except Exception:
            pass  # BM25-only mode

    @property
    def vec_available(self):
        return self._vec_available

retriever 會在嘗試 vector queries 前檢查 vec_available。停用時,所有搜尋都只使用 BM25,並略過 RRF fusion 步驟。


Reciprocal Rank Fusion(RRF)

RRF會合併兩個已排序清單,而不需要校準分數。本節涵蓋演算法、實際查詢追蹤、k參數調校,以及為何選擇RRF而非其他替代方案。若想使用可編輯排名、情境預設與視覺化架構探索器的互動式計算器,請參閱hybrid retriever深度解析

演算法

RRF只根據文件在各清單中的排名位置來分配分數:

score(d) = Σ (weight_i / (k + rank_i))

其中: - k是平滑常數(60,依循Cormack等人3) - rank_i是文件在結果清單i中的1起始排名 - weight_i是選用的各清單乘數(預設為1.0)

在多個清單中排名良好的文件,會取得較高的融合分數。只出現在單一清單中的文件,則會取得來自該單一來源的分數。

為何選擇RRF而非其他方案

加權線性組合需要校準BM25分數與cosine distances。BM25分數沒有上限,並會隨語料庫大小縮放。Cosine distances則限制在[0, 2]。若要合併兩者,就必須進行正規化,而正規化參數會依資料集而異。RRF只使用排名位置;無論評分方法為何,排名位置永遠是從1開始的整數。

學習式融合模型需要有標記的訓練資料,也就是查詢與文件的相關性配對。對個人知識庫而言,這種訓練資料並不存在。若要訓練出可用模型,您必須手動評判數百組查詢與文件配對。RRF不需要任何訓練資料即可運作。

Condorcet voting方法(Borda count、Schulze method)在理論上相當優雅,但實作與調校更為複雜。原始RRF論文證明,RRF在TREC評估資料上的表現優於Condorcet方法。3

實務中的融合

查詢:「how does the review aggregator handle disagreements」

BM25將review-aggregator.py排在第3名(精確關鍵字符合「review」、「aggregator」、「disagreements」),但把兩個設定檔排得更高(它們更醒目地符合「review」)。Vector search將同一個chunk排在第1名(語意上符合衝突解決)。經過RRF融合後:

Chunk BM25 Vec Fused Score
review-aggregator.py “Disagreement Resolution” #3 #1 0.0323
code-review-patterns.md “Multi-Reviewer” #4 #2 0.0317
deliberation-config.json “Review Weights” #1 0.0164

兩個清單中排名都好的chunk會浮上最前面。只出現在單一清單中的chunk會得到單一來源分數,並落到雙清單排名結果之後。實際的歧見解決邏輯會勝出,因為兩種方法都找到了它:BM25透過關鍵字,vector search透過語意。

如需包含每個排名RRF數學計算的完整逐步追蹤,可在互動式RRF計算器中嘗試不同的k值。

實作

RRF_K = 60

def _rrf_fuse(self, bm25_results, vec_results,
              bm25_weight=1.0, vec_weight=1.0):
    """Fuse BM25 and vector results using Reciprocal Rank Fusion."""
    scores = {}

    for rank, r in enumerate(bm25_results, start=1):
        cid = r["id"]
        if cid not in scores:
            scores[cid] = {
                "rrf_score": 0.0,
                "file_path": r["file_path"],
                "section": r["section"],
                "chunk_text": r["chunk_text"],
                "bm25_rank": None,
                "vec_rank": None,
            }
        scores[cid]["rrf_score"] += bm25_weight / (self._rrf_k + rank)
        scores[cid]["bm25_rank"] = rank

    for rank, r in enumerate(vec_results, start=1):
        cid = r["id"]
        if cid not in scores:
            scores[cid] = {
                "rrf_score": 0.0,
                "file_path": r["file_path"],
                "section": r["section"],
                "chunk_text": r["chunk_text"],
                "bm25_rank": None,
                "vec_rank": None,
            }
        scores[cid]["rrf_score"] += vec_weight / (self._rrf_k + rank)
        scores[cid]["vec_rank"] = rank

    fused = sorted(
        scores.values(),
        key=lambda x: x["rrf_score"],
        reverse=True,
    )
    return fused

調校k

k常數會控制排名最前面的結果相對於較後面結果所取得的權重:

  • 較低的k(例如10):排名最前面的結果主導性更強。第1名分數為1/11 = 0.091,第10名分數為1/20 = 0.050(相差1.8倍)。當您信任各個排序器能正確找出最佳結果時,這很適合。
  • 預設k(60):平衡。第1名分數為1/61 = 0.0164,第10名分數為1/70 = 0.0143(相差1.15倍)。排名差異會被壓縮,讓「出現在多個清單中」取得更多權重。
  • 較高的k(例如200):是否同時出現在兩個清單中,比排名位置更重要。第1名分數為1/201,第10名分數為1/210,幾乎相同。當各個排序器產生的排名雜訊較多,但跨清單一致性可靠時使用。

從k=60開始。原始RRF論文發現,這個值在多樣化的TREC資料集上都很穩健。只有在量測您自己的查詢分布中的失敗案例後,才進一步調校。

平手處理

當兩個chunk具有相同RRF分數時(少見,但若它們在某一個清單中排名相同,且未出現在另一個清單中,就可能發生),請依序用以下規則打破平手:

  1. 優先選擇同時出現在兩個清單中的chunk,而非只出現在單一清單中的chunk
  2. 在同時出現在兩個清單中的chunk之間,優先選擇合併排名較低者
  3. 在只出現在單一清單中的chunk之間,優先選擇在該清單中排名較低者

完整的 Retrieval Pipeline

本節會追蹤一個查詢如何從輸入一路通過整個 pipeline 產生輸出:BM25 搜尋、向量搜尋、RRF fusion、token budget 截斷,以及內容脈絡組裝。

端到端流程

User query: "PostToolUse hook for context compression"
  │
  ├─ BM25 Search (FTS5)
  │    → MATCH "PostToolUse hook context compression"
  │    → Top 30 results ranked by BM25 score
  │    → 12ms
  │
  ├─ Vector Search (sqlite-vec)
  │    → Embed query with Model2Vec
  │    → KNN k=30 on chunk_vecs
  │    → Top 30 results ranked by cosine distance
  │    → 8ms
  │
  └─ RRF Fusion
       → Merge 60 candidates (may overlap)
       → Score by rank position
       → Top 10 results
       → 3ms
       │
       └─ Token Budget
            → Truncate to max_tokens (default 4000)
            → Estimate at 4 chars per token
            → Return results with metadata
            → <1ms

總延遲:約 23ms,測試環境為 Apple M3 Pro 硬體上的 49,746 個 chunk 資料庫。

Search API

class HybridRetriever:
    def search(self, query, limit=10, max_tokens=4000,
               bm25_weight=1.0, vec_weight=1.0):
        """
        Search the vault using hybrid BM25 + vector retrieval.

        Args:
            query: Search query text
            limit: Maximum results to return
            max_tokens: Token budget for total result text
            bm25_weight: Weight for BM25 results in RRF
            vec_weight: Weight for vector results in RRF

        Returns:
            List of SearchResult with file_path, section,
            chunk_text, rrf_score, bm25_rank, vec_rank
        """
        # BM25 search
        bm25_results = self._bm25_search(query, limit=30)

        # Vector search (if available)
        if self.index.vec_available:
            vec_results = self._vector_search(query, limit=30)
            fused = self._rrf_fuse(
                bm25_results, vec_results,
                bm25_weight, vec_weight,
            )
        else:
            fused = bm25_results  # BM25-only fallback

        # Token budget truncation
        results = []
        token_count = 0
        for r in fused[:limit]:
            chunk_tokens = len(r["chunk_text"]) // 4
            if token_count + chunk_tokens > max_tokens:
                break
            results.append(r)
            token_count += chunk_tokens

        return results

Token Budget 截斷

max_tokens 參數可避免 retriever 回傳超出 AI 工具可使用範圍的內容脈絡。估算方式採用每個 token 4 個字元(對英文散文而言是合理近似值)。結果會以貪婪方式截斷:依排名順序加入結果,直到 budget 用盡為止。

這是一種保守策略。更精細的做法會考量每筆結果的品質分數,並偏好較短且品質較高的結果,而不是較長且品質較低的結果。貪婪方法更簡單,實務上也運作良好,因為 RRF 排名已經按照相關性排序結果。

資料庫 Schema(完整)

-- Chunk content and metadata
CREATE TABLE chunks (
    id INTEGER PRIMARY KEY,
    file_path TEXT NOT NULL,
    section TEXT NOT NULL,
    chunk_text TEXT NOT NULL,
    heading_context TEXT DEFAULT '',
    mtime_ns INTEGER NOT NULL,
    embedded_at REAL NOT NULL
);

CREATE INDEX idx_chunks_file ON chunks(file_path);
CREATE INDEX idx_chunks_mtime ON chunks(mtime_ns);

-- FTS5 for BM25 search (content-synced to chunks table)
CREATE VIRTUAL TABLE chunks_fts USING fts5(
    chunk_text, section, heading_context,
    content=chunks, content_rowid=id
);

-- sqlite-vec for vector KNN search
CREATE VIRTUAL TABLE chunk_vecs USING vec0(
    id INTEGER PRIMARY KEY,
    embedding float[256]
);

-- Model metadata for compatibility tracking
CREATE TABLE model_meta (
    key TEXT PRIMARY KEY,
    value TEXT
);

Graceful Degradation 路徑

Full pipeline:     BM25 + Vector + RRF    Best results
No sqlite-vec:     BM25 only              Good results (no semantic)
No model download:  BM25 only              Good results (no semantic)
No FTS5:           Vector only             Decent results (no keyword)
No database:       Error                   Prompt user to run indexer

retriever 會在初始化時檢查能力,並調整其查詢策略。缺少某個元件會降低品質,但不會造成錯誤。唯一的硬性失敗是找不到資料庫檔案。

Production 統計

以下是在包含 16,894 個檔案、49,746 個 chunks、83 MB SQLite 資料庫的 vault 上測得,硬體為 Apple M3 Pro:

指標 數值
檔案總數 16,894
chunks 總數 49,746
資料庫大小 83 MB
BM25 查詢延遲(p50) 12ms
向量查詢延遲(p50) 8ms
RRF fusion 延遲 3ms
端到端搜尋延遲(p50) 23ms
完整重新索引時間 約 4 分鐘
增量重新索引時間 <10 秒
Embedding 模型 potion-base-8M(256-dim)
BM25 候選池 30
向量候選池 30
預設結果限制 10
預設 token budget 4,000 tokens

內容 Hashing 與變更偵測

indexer 需要知道哪些檔案自上次索引執行後已經變更。本節說明變更偵測機制與 hashing 策略。

檔案修改時間比較

indexer 會在 chunks table 中為每個 chunk 儲存 mtime_ns(以奈秒表示的檔案修改時間)。在增量執行時,indexer 會:

  1. 掃描 vault 中允許資料夾內的所有 .md 檔案
  2. 從檔案系統讀取每個檔案的 mtime_ns
  3. 與資料庫中儲存的 mtime_ns 比較
  4. 識別 3 種類別:
  5. 新檔案:路徑存在於檔案系統,但不存在於資料庫
  6. 已變更檔案:路徑同時存在於兩者,但 mtime_ns 不同
  7. 已刪除檔案:路徑存在於資料庫,但不存在於檔案系統
def get_stale_files(self, vault_mtimes):
    """Find files whose mtime changed or are new."""
    stored = dict(self.db.execute(
        "SELECT DISTINCT file_path, mtime_ns FROM chunks"
    ).fetchall())

    stale = []
    for path, mtime in vault_mtimes.items():
        if path not in stored or stored[path] != mtime:
            stale.append(path)
    return stale

def get_deleted_files(self, vault_paths):
    """Find files in database that no longer exist in vault."""
    stored_paths = set(r[0] for r in self.db.execute(
        "SELECT DISTINCT file_path FROM chunks"
    ).fetchall())
    return stored_paths - set(vault_paths)

為什麼使用 mtime,而不是內容 Hash

內容 hashing(檔案內容的 SHA-256)會比 mtime 比較更可靠,因為它能偵測檔案被碰觸但內容未變的情況(例如 git checkout 還原原本的 mtime)。不過,hashing 需要在每次增量執行時讀取每個檔案。對 16,894 個檔案而言,讀取檔案內容需要 2 到 3 秒。從檔案系統讀取 mtimes 則少於 100ms。

取捨在於:mtime 比較偶爾會觸發對未變更檔案的不必要重新索引(false positives),但不會漏掉實際變更。False positives 的成本只是每次執行多幾次 embedding 呼叫。速度差異(100ms 對 3 秒)讓 mtime 成為這套會在每次 AI 互動時執行的系統中務實的選擇。

處理刪除

當檔案從 vault 刪除時,indexer 會從資料庫移除該檔案的所有 chunks:

def remove_file(self, file_path):
    """Remove all chunks and vectors for a file."""
    chunk_ids = [r[0] for r in self.db.execute(
        "SELECT id FROM chunks WHERE file_path = ?",
        [file_path],
    ).fetchall()]

    for cid in chunk_ids:
        self.db.execute(
            "DELETE FROM chunk_vecs WHERE id = ?", [cid]
        )
    self.db.execute(
        "DELETE FROM chunks WHERE file_path = ?",
        [file_path],
    )

DELETE FROM chunk_vecs 陳述式自 sqlite-vec v0.1.7 起可原生運作,並在 v0.1.9 修正了針對 metadata 文字欄位較長的 vec0 table 執行 DELETE 操作的 bug。1423 較早版本需要採用 workaround(刪除並重建 virtual table,或維護外部的「active IDs」集合)。如果正在執行 pre-0.1.9 版本,請先升級,再依賴 metadata-heavy schema 中的直接刪除。

FTS5 content-sync tables 需要針對每個移除的 row,透過 INSERT INTO chunks_fts(chunks_fts, rowid, ...) VALUES('delete', ?, ...) 明確刪除。indexer 會在檔案移除流程中處理這件事。

增量與完整重新索引

索引器支援兩種模式:增量(快速,日常使用)與完整(較慢,偶爾使用)。本節說明各自的使用時機、冪等性保證,以及毀損復原。

增量重新索引

使用時機:編輯筆記後的日常索引。這是預設模式。

執行內容: 1. 掃描 vault 中的檔案變更(比較 mtime) 2. 刪除已刪除檔案的 chunks 3. 重新 chunk 並重新 embed 已變更的檔案 4. 為新檔案插入新的 chunks 5. 同步 FTS5 索引

典型耗時:在含 16,000 個檔案的 vault 中,處理一天的編輯通常少於 10 秒。

python index_vault.py --incremental

完整重新索引

使用時機: - 變更 embedding model 之後(偵測到 model hash 不相符) - schema migration 之後(新增欄位、變更索引) - 資料庫毀損之後(integrity check 失敗) - 增量索引產生非預期結果時

執行內容: 1. 刪除所有既有資料(chunks、vectors、FTS5 entries) 2. 掃描整個 vault 3. 對所有檔案進行 chunk 4. 對所有 chunks 產生 embeddings 5. 從零開始建立 FTS5 索引

典型耗時:在 Apple M3 Pro 上處理 16,894 個檔案約需 4 分鐘。

python index_vault.py --full

冪等性

兩種模式都是冪等的:執行同一個命令兩次會產生相同結果。索引器會先刪除檔案既有的 chunks,再插入新的 chunks,因此在已是最新狀態的資料庫上重新執行增量索引,會產生零變更。重新執行完整索引則會產生相同的資料庫。

毀損復原

如果 SQLite 資料庫毀損(寫入期間斷電、磁碟錯誤、交易中途程序被終止):

# Check integrity
sqlite3 vectors.db "PRAGMA integrity_check;"

# If corruption detected, full reindex rebuilds from source files
python index_vault.py --full

真實來源永遠是 vault 檔案,而不是資料庫。資料庫是衍生產物,可隨時重建。這是關鍵的設計特性:您永遠不需要備份資料庫。

--incremental 旗標

索引器以 --incremental 執行時:

  1. Model hash 檢查。將已儲存的 model hash 與目前模型比較。若不同,會自動切換為完整重新索引模式,並警告使用者。
  2. 檔案掃描。走訪允許的資料夾,收集檔案路徑與 mtimes。
  3. 變更偵測。與已儲存資料比較。
  4. 批次處理。以每批 64 個檔案重新 chunk 並重新 embed 變更檔案。
  5. 進度回報。列印已處理檔案數與經過時間。
  6. 優雅關閉。處理 SIGINT 時,會先完成目前檔案再停止。

Credential Filtering 與資料邊界

個人筆記含有機密:API keys、bearer tokens、資料庫連線字串,以及除錯期間貼上的 private keys。credential filter 會防止這些內容進入 retrieval index。

問題

一則關於除錯 OAuth 整合的筆記可能包含:

The token was: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
I used this curl command:
  curl -H "Authorization: Bearer sk-ant-api03-abc123..."

若未過濾,JWT 與 API key 都會被 chunk、embed,並儲存在資料庫中。搜尋「authentication」會傳回含有真實機密的 chunk。更糟的是,如果 retriever 透過 MCP 將結果提供給 AI 工具,這些機密會出現在 AI 的 context window 中,甚至可能進入工具記錄。

以模式為基礎的過濾

credential filter 會在每個 chunk 儲存前執行,匹配 25 種 vendor-specific patterns,加上通用 patterns:

Vendor-Specific Patterns:

Pattern Example Regex
OpenAI API key sk-... sk-[a-zA-Z0-9_-]{20,}
Anthropic API key sk-ant-api03-... sk-ant-api\d{2}-[a-zA-Z0-9_-]{20,}
GitHub PAT ghp_... gh[ps]_[a-zA-Z0-9]{36,}
AWS Access Key AKIA... AKIA[0-9A-Z]{16}
Stripe key sk_live_... [sr]k_(live\|test)_[a-zA-Z0-9]{24,}
Cloudflare token ... Various patterns

Generic Patterns:

Pattern Detection
JWT tokens eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+
Bearer tokens Bearer\s+[a-zA-Z0-9_\-\.]+
Private keys -----BEGIN (RSA\|EC\|OPENSSH) PRIVATE KEY-----
高熵 base64 具有 >4.5 bits/char entropy、40+ chars 的字串
Password assignments password\s*[:=]\s*["'][^"']+["']

Filter 實作

def clean_content(text):
    """Scrub credentials from text before indexing."""
    result = ScanResult(is_clean=True, match_count=0, patterns=[])

    for pattern in CREDENTIAL_PATTERNS:
        matches = pattern.regex.findall(text)
        if matches:
            text = pattern.regex.sub(
                f"[REDACTED:{pattern.name}]", text
            )
            result.is_clean = False
            result.match_count += len(matches)
            result.patterns.append(pattern.name)

    return text, result

關鍵設計選擇:

  1. 先過濾再 embedding。清理後的文字才會被 embed。vector representation 永遠不會編碼 credential patterns。查詢「API key」會傳回討論 API key 管理的筆記,而不是含有實際 keys 的筆記。

  2. 替換,而非移除。[REDACTED:pattern-name] token 會保留周邊文字的語意脈絡。embedding 會捕捉「這裡曾有類似 credential 的內容」,但不會編碼 credential 本身。

  3. 記錄 patterns,不記錄 values。filter 會記錄哪些 patterns 命中(例如「Scrubbed 2 credential(s) from oauth-debug.md [jwt, bearer-token]」),但絕不記錄 credential value。

以路徑為基礎的排除

.indexignore 檔案提供以路徑為單位的粗粒度排除。credential filter 則在已索引檔案中提供細粒度清理。兩者缺一不可:

  • .indexignore 用於您明知含有敏感內容的整個資料夾(健康筆記、財務紀錄、職涯文件)
  • Credential filter 用於意外嵌入在原本可索引內容中的機密

資料分類

對於包含多樣內容的 vault,可考慮依敏感度分類筆記:

Level Examples Index? Filter?
Public 部落格草稿、技術筆記 Yes Yes
Internal 專案計畫、架構決策 Yes Yes
Sensitive 薪資資料、健康紀錄 No (.indexignore) N/A
Restricted Credentials、private keys No (.indexignore) N/A

MCP伺服器架構

Model Context Protocol(MCP)伺服器會將擷取器公開為 AI agent 可呼叫的工具。本節說明伺服器設計、能力範圍與權限邊界。

協定選擇:STDIO vs HTTP

MCP支援兩種傳輸模式:

STDIO——AI 工具會將MCP伺服器產生為子行程,並透過 stdin/stdout 通訊。這是本機工具的標準模式。Claude Code、Codex CLI 與 Cursor 都支援 STDIO MCP伺服器。

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/path/to/vault",
        "DB_PATH": "/path/to/vectors.db"
      }
    }
  }
}

HTTP——MCP伺服器會以獨立 HTTP 服務執行。適合遠端存取、多用戶端設定,或 vault 位於共用伺服器上的團隊設定。

{
  "mcpServers": {
    "obsidian": {
      "url": "http://localhost:3333/mcp"
    }
  }
}

建議:個人 vault 請使用 STDIO。它更簡單、更安全(沒有網路暴露),且伺服器生命週期由 AI 工具管理。只有在多個工具或多台機器需要同時存取同一個 vault 時,才使用 HTTP。

MCP規格演進。2025年6月的MCP規格新增了OAuth 2.1 授權、結構化工具輸出(型別化回傳 schema),以及 elicitation(由伺服器發起的使用者提示)。2025年11月版本將 Streamable HTTP 作為一級傳輸模式推出,並加入用於自動瀏覽伺服器能力的 .well-known URL 探索、宣告工具為唯讀或會變更狀態的結構化工具註解,以及SDK層級標準化系統。79下一版修訂如今已相當明確:2026-07-28 規格已於 2026年5月21日進入 Release Candidate,這是MCP推出以來規模最大的修訂。其主要變更包括無狀態協定核心(移除 initialize 握手與 Mcp-Session-Id 標頭,因此伺服器不再追蹤每個連線的工作階段狀態)、MCP Apps(伺服器可回傳由伺服器轉譯的HTML,顯示於沙盒化的用戶端 iframe 中)、Tasks 從實驗性核心畢業為官方擴充功能(針對長時間執行作業提供 tasks/gettasks/updatetasks/cancel)、強化的 OAuth 2.0 / OIDC 授權,以及12 個月功能棄用生命週期政策。最終規格將於 2026年7月28日發布。24對個人 vault 伺服器而言,STDIO 仍是最簡單的路徑,而無狀態核心讓單一使用者的 STDIO 伺服器更為輕量。Streamable HTTP 傳輸、.well-known 探索與MCP Apps 主要有利於具備多租戶路由與負載平衡的企業 HTTP 部署。請持續關注 MCP roadmap,掌握可能影響傳輸選擇的更新。

能力設計

MCP伺服器應公開最小化的一組工具:

search——主要工具。執行 hybrid 擷取並回傳排序後的結果。

{
  "name": "obsidian_search",
  "description": "Search the Obsidian vault using hybrid BM25 + vector retrieval",
  "parameters": {
    "query": { "type": "string", "description": "Search query" },
    "limit": { "type": "integer", "default": 5 },
    "max_tokens": { "type": "integer", "default": 2000 }
  }
}

read_note——依路徑讀取特定 note 的完整內容。當 agent 想查看搜尋結果的完整脈絡時很有用。

{
  "name": "obsidian_read_note",
  "description": "Read the full content of a note by file path",
  "parameters": {
    "file_path": { "type": "string", "description": "Relative path within vault" }
  }
}

list_notes——列出符合篩選條件的 notes(依資料夾、標籤、類型或日期範圍)。當 agent 沒有特定查詢、需要探索時很有用。

{
  "name": "obsidian_list_notes",
  "description": "List notes matching filters",
  "parameters": {
    "folder": { "type": "string", "description": "Folder path within vault" },
    "tag": { "type": "string", "description": "Tag to filter by" },
    "limit": { "type": "integer", "default": 20 }
  }
}

get_context——便利工具,會執行搜尋並將結果格式化為適合注入對話的脈絡區塊。

{
  "name": "obsidian_get_context",
  "description": "Get formatted context from vault for a topic",
  "parameters": {
    "topic": { "type": "string", "description": "Topic to get context for" },
    "max_tokens": { "type": "integer", "default": 2000 }
  }
}

權限邊界

MCP伺服器應強制執行嚴格邊界:

  1. 唯讀。伺服器讀取 vault 與索引資料庫。它不會建立、修改或刪除 notes。寫入作業(擷取新 notes)由獨立的 hooks 或 skills 處理,而不是由MCP伺服器處理。

  2. 限制於 vault 範圍。伺服器只會讀取已設定 vault 路徑內的檔案。必須拒絕路徑遍歷嘗試(../../etc/passwd)。

  3. 輸出經認證資訊過濾。即使資料庫已包含預先過濾的內容,仍應在輸出時套用認證資訊過濾,作為縱深防禦措施。

  4. 限制 token 的回應。對所有工具回應強制執行 max_tokens,避免 AI 工具收到過大的脈絡區塊。

錯誤處理

MCP工具應回傳結構化錯誤訊息,協助 AI 工具復原:

def search(self, query, limit=5, max_tokens=2000):
    if not self.db_path.exists():
        return {
            "error": "Index database not found. Run the indexer first.",
            "suggestion": "python index_vault.py --full"
        }

    results = self.retriever.search(query, limit, max_tokens)

    if not results:
        return {
            "results": [],
            "message": f"No results found for '{query}'. Try broader terms."
        }

    return {
        "results": [
            {
                "file_path": r["file_path"],
                "section": r["section"],
                "text": r["chunk_text"],
                "score": round(r["rrf_score"], 4),
            }
            for r in results
        ],
        "count": len(results),
        "query": query,
    }

Claude Code整合

Claude Code是Obsidian檢索系統的主要使用者。本節涵蓋MCP設定、hook整合,以及obsidian_bridge.py模式。

MCP設定

將Obsidian MCP伺服器新增至~/.claude/settings.json

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/absolute/path/to/vault",
        "DB_PATH": "/absolute/path/to/vectors.db"
      }
    }
  }
}

新增設定後,重新啟動Claude Code。MCP伺服器會以子行程啟動。確認它正在執行:

> What tools do you have from the obsidian MCP server?

Claude Code應會列出可用工具(obsidian_searchobsidian_read_note等)。

Hook整合

Hooks會在定義好的生命週期節點擴充Claude Code的行為。Obsidian整合有2個相關hook:

PreToolUse hook——在代理處理工具呼叫之前查詢知識庫。自動注入相關脈絡。

#!/bin/bash
# ~/.claude/hooks/pre-tool-use/obsidian-context.sh
# Automatically inject vault context before tool execution

TOOL_NAME="$1"
PROMPT="$2"

# Only inject context for code-related tools
case "$TOOL_NAME" in
    Edit|Write|Bash)
        # Query the vault
        CONTEXT=$(python /path/to/retriever.py search "$PROMPT" --limit 3 --max-tokens 1500)
        if [ -n "$CONTEXT" ]; then
            echo "---"
            echo "Relevant vault context:"
            echo "$CONTEXT"
            echo "---"
        fi
        ;;
esac

PostToolUse hook——將重要的工具輸出擷取回知識庫,供日後檢索。

#!/bin/bash
# ~/.claude/hooks/post-tool-use/capture-insight.sh
# Capture significant outputs to vault (selective)

TOOL_NAME="$1"
OUTPUT="$2"

# Only capture substantial outputs
if [ ${#OUTPUT} -gt 500 ]; then
    python /path/to/capture.py --text "$OUTPUT" --source "claude-code-$TOOL_NAME"
fi

obsidian_bridge.py模式

橋接模組提供一個Python API,供hooks和skills呼叫:

# obsidian_bridge.py
from retriever import HybridRetriever

_retriever = None

def get_retriever():
    global _retriever
    if _retriever is None:
        _retriever = HybridRetriever(
            db_path="/path/to/vectors.db",
            vault_path="/path/to/vault",
        )
    return _retriever

def search_vault(query, limit=5, max_tokens=2000):
    """Search vault and return formatted context."""
    retriever = get_retriever()
    results = retriever.search(query, limit, max_tokens)

    if not results:
        return ""

    lines = ["## Vault Context\n"]
    for r in results:
        lines.append(f"**{r['file_path']}** — {r['section']}")
        lines.append(f"> {r['chunk_text'][:500]}")
        lines.append("")

    return "\n".join(lines)

/capture Skill

用來將洞察擷取回知識庫的Claude Code skill:

/capture "OAuth token rotation requires both access and refresh token invalidation"
  --domain security
  --tags oauth,tokens

此skill會在00-inbox/中建立一則新筆記,包含正確的frontmatter,並觸發增量重新索引,讓新筆記可立即搜尋。

自訂命令模式

Claude Code skills可以將知識庫操作包裝成具名命令。實務工作者已建立多套Obsidian專用命令庫,將知識庫同時視為讀取來源與寫入目標。

訊號掃描。/scan-intel命令會查詢外部來源,依個人研究興趣為發現項目評分,並將符合條件的訊號寫成含有frontmatter的知識庫筆記:

/scan-intel --topics "agent infrastructure, security" --lookback 7d

此命令會從設定好的來源(arXiv、HN、RSS)擷取內容,套用評分模型(相關性、可行動性、深度、權威性),並將通過門檻的訊號寫入知識庫中對應主題的資料夾。知識庫於是成為自動化情報管線的下游使用者。

船長日誌。/captains-log命令會彙整所有儲存庫的每日git活動,將結構化日誌項目寫入知識庫,並包含已做出的決策、領悟,以及尚未收束的線索:

/captains-log

此命令會從GitHub拉取commit歷史,依儲存庫分組,並格式化為敘事式日誌項目。日積月累後,每日日誌會形成一份可搜尋的紀錄,說明交付了什麼,以及為何交付。

Obsidian擷取。/obsidian-capture命令會從目前的Claude Code工作階段擷取一則洞察,並以正確的metadata直接寫入知識庫:

/obsidian-capture "SAST gates in agent loops increase security degradation"
  --folder AI-Tools --tags security,agents

此模式可延伸至任何知識庫操作:建立MOC、更新專案狀態筆記、連結相關訊號,或從累積的每日日誌產生每週摘要。

社群範例。實務工作者正在發布自己的命令庫。一位開發者分享了22個自訂Obsidian + Claude Code命令,涵蓋每日回顧、專案規劃、研究擷取與內容工作流程。1另一位則打造了「Visual Explainer」skill,可根據程式碼分析在知識庫中產生圖解筆記。2這些命令各有不同,但架構一致:以Claude Code skills作為介面、以知識庫筆記作為儲存層,並以檢索基礎設施作為查詢引擎。

脈絡視窗管理

整合時應留意Claude Code的脈絡視窗:

  • 將每次查詢注入的脈絡限制在1,500-2,000 tokens。超過此範圍會與代理的工作記憶競爭。
  • 包含來源標註。一律包含檔案路徑與章節標題,讓代理能引用來源。
  • 截斷chunk文字。較長的chunks應以...截斷,而非整段省略。前300-500個字元通常包含關鍵資訊。
  • 不要在每次工具呼叫都注入。PreToolUse hook應根據被呼叫的工具選擇性注入脈絡。讀取操作不需要知識庫脈絡;Write與Edit操作則會受益於此。

Codex CLI整合

Codex CLI透過config.toml連接至MCP伺服器。其整合模式與Claude Code不同,差異在於設定語法與指令傳遞方式。

MCP設定

新增至.codex/config.toml~/.codex/config.toml

[mcp_servers.obsidian]
command = "python"
args = ["/path/to/obsidian_mcp.py"]

[mcp_servers.obsidian.env]
VAULT_PATH = "/absolute/path/to/vault"
DB_PATH = "/absolute/path/to/vectors.db"

AGENTS.md模式

Codex CLI會讀取AGENTS.md作為專案層級指令。請納入知識庫搜尋指引:

## Available Tools

### Obsidian Vault (MCP: obsidian)
Use the `obsidian_search` tool to find relevant context from the knowledge base.
Search the vault when you need:
- Background on a concept or pattern
- Prior decisions or rationale
- Reference material for implementation

Example queries:
- "authentication patterns in FastAPI"
- "how does the review aggregator work"
- "sqlite-vec configuration"

與Claude Code的差異

功能 Claude Code Codex CLI
MCP設定 settings.json config.toml
Hooks ~/.claude/hooks/ 不支援
Skills ~/.claude/skills/ 不支援
指令檔案 CLAUDE.md AGENTS.md
核准模式 --dangerously-skip-permissions suggest / auto-edit / full-auto

關鍵差異:Codex CLI不支援hooks。因此無法使用自動脈絡注入模式(PreToolUse hook)。請改在AGENTS.md中加入明確指令,要求代理在開始工作前先搜尋知識庫。

Cursor 與其他工具

Cursor 以及其他支援 MCP 的 AI 工具,都可以連接到同一個 Obsidian MCP 伺服器。本節說明常見工具的設定方式。

Cursor

將以下內容加入專案根目錄中的 .cursor/mcp.json

{
  "mcpServers": {
    "obsidian": {
      "command": "python",
      "args": ["/path/to/obsidian_mcp.py"],
      "env": {
        "VAULT_PATH": "/absolute/path/to/vault",
        "DB_PATH": "/absolute/path/to/vectors.db"
      }
    }
  }
}

Cursor 的 .cursorrules 檔案可以包含使用知識庫的指示:

When working on implementation tasks, search the Obsidian vault
for relevant context before writing code. Use the obsidian_search
tool with descriptive queries about the concept you're implementing.

相容性矩陣

Tool MCP 支援 Transport 設定位置
Claude Code 完整 STDIO ~/.claude/settings.json
Codex CLI 完整 STDIO .codex/config.toml
Cursor 完整 STDIO .cursor/mcp.json
Windsurf 完整 STDIO .windsurf/mcp.json
Continue.dev 部分 HTTP ~/.continue/config.json
Zed 進行中 STDIO 設定 UI
Claudian(Obsidian plugin) N/A(嵌入式) Claude Code CLI Obsidian plugin 設定
Agent Client(Obsidian plugin) N/A(嵌入式) ACP Obsidian plugin 設定

不支援 MCP 工具的替代方案

對於不支援 MCP 的工具,可以將檢索器包裝成 CLI:

# Search from command line
python retriever_cli.py search "query text" --limit 5

# Output formatted for copy-paste into any tool
python retriever_cli.py context "query text" --format markdown

CLI 會輸出結構化文字,可手動貼到任何 AI 工具的輸入中。這不如 MCP 整合優雅,但通用性最高。


從結構化筆記進行 Prompt Caching

知識庫中的結構化筆記可以作為可重複使用的上下文區塊,降低多次 AI 互動中的 token 使用量。本節說明快取鍵設計與 token 預算管理。

模式

與其在每次互動時都搜尋上下文,不如從結構良好的知識庫筆記預先建立上下文區塊,並加以快取:

# cache_keys.py
CONTEXT_BLOCKS = {
    "auth-patterns": {
        "vault_query": "authentication patterns implementation",
        "max_tokens": 1500,
        "ttl_hours": 24,  # Rebuild daily
    },
    "api-conventions": {
        "vault_query": "API design conventions REST patterns",
        "max_tokens": 1000,
        "ttl_hours": 168,  # Rebuild weekly
    },
    "project-architecture": {
        "vault_query": "current project architecture decisions",
        "max_tokens": 2000,
        "ttl_hours": 12,  # Rebuild twice daily
    },
}

快取失效

快取失效依據兩個訊號:

  1. TTL 到期。每個上下文區塊都有存活時間。TTL 到期後,系統會重新查詢知識庫並重建該區塊。
  2. 知識庫變更偵測。當 indexer 偵測到曾用於快取上下文區塊的檔案發生變更時,該區塊會立即失效。

Token 預算管理

每個 session 開始時都有總上下文預算。快取區塊會消耗其中一部分:

Total context budget:    8,000 tokens
├─ System prompt:        1,500 tokens
├─ Cached blocks:        3,000 tokens (pre-loaded)
├─ Dynamic search:       2,000 tokens (on-demand)
└─ Conversation:         1,500 tokens (remaining)

快取區塊會在 session 開始時載入。動態搜尋結果則依每次查詢填入剩餘預算。這種 hybrid 方法讓 agent 擁有常用上下文的基準,同時保留預算給特定查詢使用。

Token 使用量前後比較

未使用快取:每個相關查詢都會觸發知識庫搜尋,回傳 1,500-2,000 個 token 的上下文。在一個 session 的 10 次查詢中,agent 會消耗 15,000-20,000 個 token 的知識庫上下文。

使用快取:3 個預先建立的上下文區塊總共消耗 4,500 個 token。額外搜尋則為每個唯一查詢增加 1,500-2,000 個 token。若 10 次查詢中有 6 次由快取區塊涵蓋,agent 會消耗 4,500 + (4 * 1,500) = 10,500 個 token,約為未快取用量的一半。


用於上下文壓縮的 PostToolUse Hooks

工具輸出可能很冗長:stack traces、檔案清單、測試結果。PostToolUse hook 可以在這些輸出消耗 context window 空間之前先進行壓縮。

問題

執行測試的 Bash 工具呼叫可能會回傳:

PASSED tests/test_auth.py::test_login_success
PASSED tests/test_auth.py::test_login_failure
PASSED tests/test_auth.py::test_token_refresh
PASSED tests/test_auth.py::test_session_expiry
... (200 more lines)
FAILED tests/test_api.py::test_rate_limit_exceeded

完整輸出有 5,000 個 token,但真正的訊號只在 2 行:200 passed、1 failed。

Hook 實作

#!/bin/bash
# ~/.claude/hooks/post-tool-use/compress-output.sh
# Compress verbose tool outputs to preserve context window

TOOL_NAME="$1"
OUTPUT="$2"
OUTPUT_LEN=${#OUTPUT}

# Only compress large outputs
if [ "$OUTPUT_LEN" -lt 2000 ]; then
    exit 0  # Pass through unchanged
fi

case "$TOOL_NAME" in
    Bash)
        # Compress test output
        if echo "$OUTPUT" | grep -q "PASSED\|FAILED"; then
            PASSED=$(echo "$OUTPUT" | grep -c "PASSED")
            FAILED=$(echo "$OUTPUT" | grep -c "FAILED")
            FAILURES=$(echo "$OUTPUT" | grep "FAILED")
            echo "Tests: $PASSED passed, $FAILED failed"
            if [ "$FAILED" -gt 0 ]; then
                echo "Failures:"
                echo "$FAILURES"
            fi
        fi
        ;;
esac

防止遞迴觸發

若沒有防護,會輸出內容的壓縮 hook 可能觸發自身:

# Guard against recursive invocation
if [ -n "$COMPRESS_HOOK_ACTIVE" ]; then
    exit 0
fi
export COMPRESS_HOOK_ACTIVE=1

壓縮啟發式規則

輸出類型 偵測方式 壓縮策略
測試結果 PASSED / FAILED 關鍵字 統計通過/失敗,只顯示失敗項目
檔案清單 command 中有 lsfind 截斷為前 20 個項目 + 總數
Stack traces Traceback 關鍵字 保留第一個與最後一個 frame + 錯誤訊息
Git status modified: / new file: 依狀態彙總數量
Build output warning: / error: 移除 info 行,保留 warnings/errors

訊號匯入與分流流程

匯入層決定哪些內容能進入 vault。若缺乏策展,vault 會累積雜訊。本節說明將訊號路由到各領域資料夾的評分流程。

來源

訊號來自多個管道:

  • RSS feeds:技術部落格、安全公告、release notes
  • 透過 Web Clipper 建立的書籤:官方 Obsidian Web Clipper 擴充功能(Chrome、Firefox、Safari)是瀏覽器端擷取中保真度最高的匯入路徑。2026年4月的發布週期,讓它對 AI 工作流程更具實用價值:22
    • 1.4.0(4月9日):互動式 YouTube 逐字稿 UI:固定影片、在逐字稿中拖曳瀏覽、自動捲動,並醒目標示目前位置。另有預設的「Open in Reader」,可一鍵將擷取內容直接送入 Reader 模式。
    • 1.5.0–1.5.1(4月15日):Highlights viewer:在整個 vault 中瀏覽與搜尋已擷取的 highlight。淡入轉場進入 Reader。YouTube 播放/暫停更順暢。1.5.1 修正了 webpack 編譯回歸問題。
    • 1.6.0–1.6.2(4月21–23日):Highlighter UX 全面改版並支援行動裝置。Defuddle 0.18 為 LinkedIn、Threads、Bluesky、Discourse 和 Medium 加入來源專屬擷取器。1.6.2 修正了 Safari embedded-mode clipboard 回歸問題。 依來源網域設定範本,讓 YouTube 逐字稿、GitHub README,以及長篇文章都能落在命名合理的筆記中,並帶有下方評分流程所需的正確 frontmatter。
  • Newsletters:電子報中的重點摘錄
  • 手動擷取:閱讀、對話或研究期間撰寫的筆記
  • 工具輸出:透過 hooks 擷取的重要 AI 工具輸出
  • iOS Share Extension:Obsidian 的 iOS app(2026年初更新)包含 Share Extension,可將 Safari、社群網路與其他 app 的內容直接儲存到 vault,不必開啟 Obsidian。19這建立了低摩擦的行動匯入路徑:從 Safari 分享一篇文章,它就會以 vault 筆記的形式抵達,並可立即進行評分。
  • Obsidian CLI:Shell scripts 和 hooks 可透過 obsidian file create 建立筆記,或透過 obsidian file append 附加到既有筆記,讓桌面端自動化匯入流程成為可能。

評分面向

每個訊號會依 4 個面向評分(各為 0.0 到 1.0):

面向 問題 低分(0.0-0.3) 高分(0.7-1.0)
相關性 這是否與我的活躍領域有關? 僅略有關聯、超出範圍 與目前工作直接相關
可行動性 我能運用這項資訊嗎? 純理論,沒有應用 可套用的具體技巧或模式
深度 內容有多紮實? 標題、淺層摘要 含範例的詳細分析
權威性 來源可信度如何? 匿名部落格、未經驗證 第一手來源、經同儕審查、受認可的專家

綜合分數與路由

composite = (relevance * 0.35) + (actionability * 0.25) +
            (depth * 0.25) + (authority * 0.15)
分數範圍 動作
0.55+ 自動路由到領域資料夾
0.40 - 0.55 排入手動審查佇列
< 0.40 捨棄(不儲存)

領域路由

分數高於 0.55 的訊號,會根據關鍵字比對與主題分類,路由到 12 個領域資料夾之一:

05-signals/
├── ai-tooling/        # Claude, LLMs, AI development tools
├── security/          # Vulnerabilities, auth, cryptography
├── systems/           # Architecture, distributed systems
├── programming/       # Languages, patterns, algorithms
├── web/               # Frontend, backends, APIs
├── data/              # Databases, data engineering
├── devops/            # CI/CD, containers, infrastructure
├── design/            # UI/UX, product design
├── mobile/            # iOS, Android, cross-platform
├── career/            # Industry trends, hiring, growth
├── research/          # Academic papers, whitepapers
└── other/             # Signals that don't fit a domain

Production 統計

運作 14 個月後:

指標 數值
已處理訊號總數 7,771
自動路由(>0.55) 4,832(62%)
排入審查佇列(0.40-0.55) 1,543(20%)
已捨棄(<0.40) 1,396(18%)
活躍領域資料夾 12
每日平均訊號數 ~18

Knowledge Graph 模式

Obsidian 的 wiki-link graph 會編碼筆記之間的關係。本節說明連結語意、用於脈絡擴展的 graph traversal,以及會降低 graph 品質的 anti-patterns。

每個 wiki-link 都會在 graph 中建立一條有向邊。Obsidian 會同時追蹤 forward links 和 backlinks:

  • Forward link:筆記 A 包含 [[Note B]] → A 連結到 B
  • Backlink:筆記 B 顯示筆記 A 參照了它

graph 會依脈絡編碼不同類型的關係:

連結模式 語意 範例
Inline link 「與其相關」 「詳情請參閱 [[OAuth Token Rotation]]」
Header link 「具有子主題」 ”## Related\n- [[Token Rotation]]\n- [[Session Management]]”
類 tag link 「分類為」 ”[[type/reference]]”
MOC link 「屬於」 列出相關筆記的 Map of Content 筆記

Maps of Content(MOCs)

MOCs 是索引筆記,用來將相關筆記整理成可瀏覽的結構:

---
title: "Authentication & Security MOC"
type: moc
domain: security
---

## Core Concepts
- [[OAuth 2.0 Overview]]
- [[JWT Token Anatomy]]
- [[Session Management Patterns]]

## Implementation Patterns
- [[OAuth Token Rotation]]
- [[Refresh Token Security]]
- [[PKCE Flow Implementation]]

## Failure Modes
- [[Token Expiry Handling]]
- [[Session Fixation Prevention]]
- [[CSRF Defense Strategies]]

MOCs 以兩種方式有助於 retrieval:

  1. 直接比對。搜尋「authentication overview」會命中 MOC 本身,提供 agent 一份經策展的相關筆記清單。
  2. 脈絡擴展。找到特定筆記後,retriever 可以檢查該筆記是否出現在任何 MOCs 中,並將 MOC 的結構納入結果,讓 agent 取得更大主題的地圖。

用於脈絡擴展的 Graph Traversal

retriever 的未來增強方向:找到 top results 後,沿著連結擴展脈絡:

def expand_context(results, depth=1):
    """Follow wiki-links from top results to find related context."""
    expanded = set()
    for result in results:
        # Parse wiki-links from chunk text
        links = extract_wiki_links(result["chunk_text"])
        for link_target in links:
            # Resolve link to file path
            target_path = resolve_wiki_link(link_target)
            if target_path and target_path not in expanded:
                expanded.add(target_path)
                # Include target's most relevant chunk
                target_chunks = get_chunks_for_file(target_path)
                # ... rank and include best chunk
    return results + list(expanded_results)

這尚未在目前的 retriever 中實作,但它是 graph 結構的自然延伸。

Anti-Patterns

孤立叢集。彼此互相連結、卻沒有連到 vault 其餘部分的一組筆記。Obsidian 的 graph panel 會把它們顯示為不相連的孤島。孤立叢集表示缺少 MOCs,或缺少跨領域連結。

Tag 蔓生。不一致地使用 tags,或建立太多過細的 tags。若一個 vault 在 5,000 則筆記中有 500 個獨特 tags,平均每 10 個 tags 才對應 1 則筆記,這些 tags 對篩選並無助益。請整併為 20-50 個高層級 tags,並對應到您的領域資料夾。

連結很多、內容很少的筆記。筆記完全由 wiki-links 組成,沒有任何 prose。這類筆記索引效果不佳,因為 chunker 沒有可嵌入的文字。請至少加入一段脈絡,說明這些連結筆記為何相關。

凡事都建立雙向連結。不是每個參照都需要成為 wiki-link。順帶提到「OAuth」並不需要 [[OAuth 2.0 Overview]]。請將 wiki-links 保留給有意圖、可瀏覽的關係,也就是點擊連結能提供有用脈絡的地方。

開發者工作流程範例

結合知識庫擷取與日常開發任務的實用工作流程。

早晨載入脈絡

一天開始時,先載入相關脈絡:

Search my vault for notes about [current project] updated in the last week

擷取器會回傳與目前專案相關的近期筆記,讓您快速回想上次停在哪裡。這比重新閱讀昨天的 commit 訊息更有效。

編碼期間擷取研究心得

實作功能時,不必離開編輯器也能擷取心得:

/capture "FastAPI dependency injection with async generators requires yield,
not return. The generator is the dependency lifecycle."
  --domain programming
  --tags fastapi,dependency-injection

擷取到的心得會立即建立索引,日後可供擷取使用。幾個月下來,這些微型擷取會累積成一套與實作細節密切相關的知識語料庫。

專案啟動

開始新專案或新功能時:

  1. 搜尋知識庫:「我對 [technology/pattern] 知道什麼?」
  2. 檢視前 5 筆結果,找出過去的決策與注意事項
  3. 檢查該領域是否已有 MOC;若沒有,建立一個
  4. 搜尋失敗模式:「[technology] 的問題」

使用知識庫搜尋進行除錯

遇到錯誤或非預期行為時:

Search my vault for [error message or symptom]

過去的除錯筆記通常包含根本原因與修正方式。對於跨專案反覆出現的問題,這特別有價值——知識庫會記住您忘記的事。

Code Review 準備

審查 PR 前:

Search my vault for patterns and conventions about [module being changed]

知識庫會回傳與待審查程式碼相關的既有決策、架構限制與程式碼標準。這讓審查能以組織知識為依據,而不只是看 diff。


效能調校

本節涵蓋針對不同知識庫大小與使用模式的最佳化策略。

索引大小管理

知識庫大小 Chunks DB 大小 完整重新索引 增量
500 則筆記 ~1,500 3 MB 15 秒 <1 秒
2,000 則筆記 ~6,000 12 MB 45 秒 2 秒
5,000 則筆記 ~15,000 30 MB 2 分鐘 4 秒
15,000 則筆記 ~50,000 83 MB 4 分鐘 <10 秒
50,000 則筆記 ~150,000 250 MB 15 分鐘 30 秒

達到 50,000 則以上筆記時,建議考慮: - 將 batch size 從 64 提高到 128,以加快 embedding - 使用 WAL 模式(預設)支援並行存取 - 在離峰時段執行完整重新索引

查詢最佳化

WAL 模式。 SQLite 的 Write-Ahead Logging 模式可讓索引器寫入時仍能並行讀取:

db.execute("PRAGMA journal_mode=WAL")

當 MCP 伺服器在索引器執行增量更新期間處理查詢時,這一點至關重要。

連線池。 MCP 伺服器應重複使用資料庫連線,而不是每次查詢都開啟新連線。搭配 WAL 模式的單一長期連線即可支援並行讀取。

# MCP server initialization
db = sqlite3.connect(DB_PATH, check_same_thread=False)
db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA mmap_size=268435456")  # 256 MB mmap

Memory-mapped I/O。 mmap_size pragma 會告訴 SQLite 對資料庫檔案使用 memory-mapped I/O。對於 83 MB 的資料庫,將整個檔案映射到記憶體可消除大多數磁碟讀取。

FTS5 最佳化。 完整重新索引後,請執行:

INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');

這會合併 FTS5 內部的 b-tree segments,降低後續搜尋的查詢延遲。

擴充基準測試

於 Apple M3 Pro、36 GB RAM、NVMe SSD 上測得:

操作 500 則筆記 5K 則筆記 15K 則筆記 50K 則筆記
BM25 query 2ms 5ms 12ms 25ms
Vector query 1ms 3ms 8ms 20ms
RRF fusion <1ms <1ms 3ms 5ms
Full search 3ms 8ms 23ms 50ms

所有基準測試都包含資料庫存取、查詢執行與結果格式化。MCP STDIO 通訊的網路延遲會增加 1-2ms。


疑難排解

索引漂移

症狀: 搜尋回傳過期結果,或找不到最近新增的筆記。

原因: 新增筆記後未執行增量索引器,或檔案的 mtime 未更新(例如從另一台機器同步且保留時間戳記)。

修正: 執行完整重新索引:python index_vault.py --full

更換 Embedding 模型

症狀: 變更 embedding 模型後,向量搜尋回傳不合理的結果。

原因: 舊向量(來自先前模型)正在與新的查詢向量比較。其維度或向量空間語意不相容。

修正: 索引器應偵測模型 hash 不相符,並自動觸發完整重新索引。若未自動執行,請手動清除資料庫並重新索引:

rm vectors.db
python index_vault.py --full

FTS5 維護

症狀: 多次增量更新後,FTS5 查詢回傳錯誤或不完整的結果。

原因: FTS5 內部 segments 可能在多次小型更新後變得碎片化。

修正: 重建並最佳化:

INSERT INTO chunks_fts(chunks_fts) VALUES('rebuild');
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');

MCP 逾時

症狀: AI 工具回報 MCP 伺服器逾時。

原因: 第一次查詢會觸發模型載入(lazy initialization),需花費 2-5 秒。AI 工具預設的 MCP 逾時時間可能更短。

修正: 在伺服器啟動時預先暖機模型:

# In MCP server initialization
retriever = HybridRetriever(db_path, vault_path)
retriever.search("warmup", limit=1)  # Trigger model load

SQLite 檔案鎖定

症狀: 出現 SQLITE_BUSYSQLITE_LOCKED 錯誤。

原因: 多個程序同時寫入資料庫。WAL 模式允許並行讀取,但同一時間只能有一個寫入者。

修正: 確保只有一個程序(索引器)寫入資料庫。MCP 伺服器與 hooks 應只讀取。若需要並行寫入,請使用 WAL 模式並設定 busy timeout:

db.execute("PRAGMA busy_timeout=5000")  # Wait up to 5 seconds

sqlite-vec 無法載入

症狀: 向量搜尋被停用;擷取器以僅 BM25 模式執行。

原因: sqlite-vec extension 未安裝、在 library path 中找不到,或與 SQLite 版本不相容。

修正:

# Install via pip
pip install sqlite-vec

# Or compile from source
git clone https://github.com/asg017/sqlite-vec
cd sqlite-vec && make

確認 extension 可載入:

import sqlite3
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
db.load_extension("vec0")
print("sqlite-vec loaded successfully")

大型知識庫記憶體問題

症狀: 對大型知識庫(50,000 則以上筆記)執行完整重新索引時出現記憶體不足錯誤。

原因: Embedding batch size 過大,或一次將所有檔案內容載入記憶體。

修正: 降低 batch size,並以增量方式處理檔案:

BATCH_SIZE = 32  # Reduce from 64

同時請確保索引器一次處理一個檔案(先讀取、chunking,並對每個檔案進行 embedding 後,再移至下一個),而不是將所有檔案載入記憶體。


遷移指南

從 Apple Notes 遷移

  1. 透過「Export All」選項(macOS)匯出 Apple Notes,或使用 apple-notes-liberator 之類的遷移工具
  2. 使用 markdownifypandoc 將 HTML 匯出內容轉換為 markdown
  3. 將轉換後的檔案移至知識庫的 00-inbox/ 資料夾
  4. 檢查並為每則筆記加入 frontmatter
  5. 將筆記移至適當的領域資料夾

從 Notion 遷移

  1. 從 Notion 匯出:Settings → Export → Markdown & CSV
  2. 將匯出檔解壓縮到知識庫的 00-inbox/ 資料夾
  3. 修正 Notion 特有的 markdown 產物:
  4. Notion 使用 - [ ] 作為檢查清單——這是標準 markdown
  5. Notion 會將 property tables 納入 HTML——請轉換為 YAML frontmatter
  6. Notion 會以相對路徑嵌入圖片——請將圖片複製到 attachments 資料夾
  7. 加入標準 frontmatter(typedomaintags
  8. 將 Notion 頁面連結替換為 Obsidian wiki-links

從 Google Docs 遷移

  1. 使用 Google Takeout 匯出所有文件
  2. .docx 檔案轉換為 markdown:pandoc -f docx -t markdown input.docx -o output.md
  3. 批次轉換:for f in *.docx; do pandoc -f docx -t markdown "$f" -o "${f%.docx}.md"; done
  4. 移至知識庫、加入 frontmatter,並整理到資料夾中

從純 Markdown 遷移(未使用 Obsidian)

如果您已經有一個 markdown 檔案目錄:

  1. 將該目錄開啟為 Obsidian vault(Obsidian → Open Vault → Open folder)
  2. 若該目錄有版本控管,請將 .obsidian/ 加入 .gitignore
  3. 建立 frontmatter templates,並套用到既有檔案
  4. 閱讀與整理時,開始使用 [[wiki-links]] 連結筆記
  5. 立即執行索引器——擷取系統從第 1 天起即可運作

從其他擷取系統遷移

如果您正從不同的 embedding/搜尋系統遷移:

  1. 不要嘗試遷移向量。不同模型會產生不相容的向量空間。請使用新模型執行完整重新索引。
  2. 遷移內容,而不是索引。知識庫檔案才是真實來源。索引是衍生產物。
  3. 遷移後進行驗證。執行 10-20 個您知道答案的查詢,並確認結果符合預期。

更新紀錄

日期 變更
2026-07-17 發行版本檢視,工作流程未變更。Obsidian 1.13.2(7月14日)目前僅供 Catalyst 搶先體驗,公開頻道仍為 1.13.1,因此本文的版本資訊依然有效;唯一與本指南相關的項目,是 iOS 分享表單範本新增 url 變數(可將分享的連結插入筆記),待 1.13.2 公開發布後,將納入擷取路徑章節。Web Clipper 1.7.0(6月16日,先前未收錄):升級至 Defuddle 0.19.0、{{content}} 現在會保留 ==highlight== 標記,且醒目提示可在即時頁面與閱讀器檢視之間持續保留。Obsidian 官方尚未宣布推出 MCP 伺服器或 AI 整合;MCP 規格的無狀態版本仍預定於7月28日發布。已對照 obsidian.md/changelog、github.com/obsidianmd/obsidian-clipper 發行版本及 blog.modelcontextprotocol.io 完成驗證。
2026-07-07 正確性修訂。釐清 MCPVault 是獨立專案(npm @bitbonsai/mcpvault、儲存庫 bitbonsai/mcpvault),目前版本為 v0.12.1,並有兩項中度嚴重性的路徑篩選安全公告(GHSA-9c83-rr99-vfwj、GHSA-j99q-93c9-h869);先前的 [^24] 連結誤指向其他儲存庫(MarkusPfundstein/mcp-obsidian)。修正 MarkusPfundstein/mcp-obsidian 的狀態:該專案仍在積極維護(提交紀錄延續至2026年5月15日,並新增 search_by_tagget_frontmatter),並非「自2025年6月起便停止維護」;但目前仍未提供任何帶有標籤的發行版本。已對照 GitHub 提交紀錄、GitHub Security Advisories 及 npm 完成驗證。
2026-07-06 為提升可尋性而重整編輯架構:將「快速開始:第一個連接 AI 的知識庫」更名為 Obsidian MCP 設定(錨點 #obsidian-mcp-setup),並新增「Claude 連線後可以做什麼」功能摘要(搜尋、讀取、列出及提供格式化脈絡;維持唯讀界線,寫入則由 hooks 處理)。內容整合自 MCP 伺服器架構章節。未新增事實;內部連結已更新。
2026-06-10 更新現行版本。Obsidian 1.13.1 桌面版已進入公開頻道(2026年6月9日);相較於 1.13.0,此版本升級了設定介面體驗與 CodeMirror,未帶來重大 AI/自動化變更。內文中的現行版本已由 1.13.0 更新為 1.13.1(公開版,2026年6月9日)。
2026-06-09 生態系更新。MCP 2026-07-28 規格已進入候選發布階段(2026年5月21日宣布),這是 MCP 推出以來規模最大的修訂:無狀態通訊協定核心(移除 initialize 握手與 Mcp-Session-Id)、MCP Apps(伺服器在沙箱化 iframe 中呈現的 HTML)、Tasks 從實驗性核心功能提升為正式擴充功能、強化 OAuth 2.0/OIDC,以及12個月的淘汰生命週期政策(最終規格將於2026年7月28日發布);MCP 規格演進附註中推測性的「暫定於2026年中」藍圖說法,已改為明確的候選發布資訊。sqlite-vec v0.1.10-alpha(2026年3月31日至5月18日)除了暴力 KNN 之外,新增近似最近鄰索引類型(rescore、實驗性的 ivf、以磁碟為基礎的 DiskANN);由於 0.1.10 系列仍屬預發行版本,本文將其標示為即將推出/實驗性功能。內文中的現行版本已全面更新為 Obsidian 1.13.0 桌面版(2026年5月28日搶先體驗);此版本著重於使用者體驗、安全性與開發工具,沒有新增 AI/自動化功能。
2026-06-08 維護檢查。Model2Vec v0.8.2(2026年5月29日)已發布:此維護版本新增訓練期間凍結權重的選項,並包含多詞 token 修正、訓練重構及非量化權重處理修正;註腳已更新。其餘項目均未超越既有基準:Obsidian 最新版本仍為 1.13.0(5月28日,已於下文記載)、sqlite-vec 穩定版仍為 v0.1.9(v0.1.10 仍為 alpha),而 MCP 規格仍採用 2025-11-25 修訂版。除 Model2Vec 版本附註外,內文未變更。
2026-05-28 Obsidian 1.13.0 桌面版與 1.13.0 行動版(Catalyst 搶先體驗)發布。桌面版:重新設計的設定面板可在獨立視窗中開啟,內建搜尋與鍵盤導覽;Obsidian URI 現在會在執行動作前顯示確認對話框;從網路磁碟載入 HTML 資源前會顯示新的警告;書籤檢視新增搜尋功能;強化編輯器的圖片處理;改善檔案總管/屬性/同步功能;並提供大量開發者 API 與錯誤修正。行動版:新增可設定目標位置的 iOS 分享表單;可從分頁切換器重新排序分頁;在平板上可長按調整分割檢視與釘選側邊欄的大小;Bases 的表格檢視新增調整欄寬的選單項目;並修正 iOS 與搜尋問題。對 AI 工作流程的影響:Obsidian URI 的確認對話框為 URI 驅動的 MCP/代理程式整合增添一道刻意設置的關卡;Bases 欄寬調整選單提升 Bases 作為代理程式查詢之知識庫前端索引的實用性;iOS 分享表單可設定目標位置,讓 iPhone 擷取路徑(已記載為主要輸入管道)能更快接入 Claude/Codex 管線。
2026-05-06 依來源驗證並更新現況:Smart Connections v4.5.0 將頁尾連線功能移入 Core;sqlite-vec v0.1.8/v0.1.9 穩定版更新封裝與 DELETE 行為;Model2Vec v0.8.x 更新 tokenizer/持久化內部機制與基準測試表格;修正 Obsidian CLI 的版本沿革,將「1.12.7 導入 CLI」改為「1.12.0 導入 CLI,1.12.7 改善安裝/執行階段封裝」。
2026-04-27 Web Clipper 4月更新週期:1.4.0(互動式 YouTube 逐字稿介面+預設使用「在閱讀器中開啟」)、1.5.0(醒目提示檢視器)、1.6.0(全面翻新醒目提示工具的使用者體驗+Defuddle 0.18 新增 LinkedIn/Threads/Bluesky/Discourse/Medium 來源擷取器)、1.6.1+1.6.2(閱讀器與 Safari 修正)。重新定位 Web Clipper,將其視為 AI 工作流程主要的瀏覽器端輸入管道,而非順帶一提的書籤工具。在此期間,Obsidian 桌面版、Sync 與 Bases 均無新版本。
2026-04-16 Smart Connections v4.3.0(圖形檢視、可設定的停駐區、區塊嵌入向量復原、Substrate 跨外掛環境)。記錄2026年4月的 AI 原生外掛浪潮(Cortex、VaultSearch、LLM Wiki、Drift、EngramQuest、Hybrid Search MCP)。將 MarkusPfundstein/mcp-obsidian 標示為維護模式(最後提交於2025年6月)。Dataview 已停止活躍開發;新專案應改用其後繼方案 Bases。Obsidian CLI 1.12.7 仍是 AI 助理的首選橋接方式。
2026-04-01 新增 Obsidian CLI 章節(用於 AI 工作流程的 v1.12 命令)。新增代理程式外掛章節(Claudian、Agent Client)。記錄用於整理知識庫的 Bases 核心外掛。將外掛數量更新為 2,500+。新增 iOS 分享擴充功能作為輸入來源。更新相容性矩陣,納入嵌入式代理程式外掛。
2026-03-30 MCPVault v0.11.0:新增 list_all_tags 工具與 .base.canvas 支援,並更名為 @bitbonsai/mcpvault。Obsidian Desktop v1.12.7 內附 CLI 二進位檔,可加快終端機互動。
2026-03-23 記錄 sqlite-vec v0.1.7 穩定版:支援從 vec0 資料表執行 DELETE,並新增用於分頁的 KNN 距離限制。已宣布 DiskANN 近似最近鄰索引將於後續版本推出。
2026-03-07 在嵌入模型比較中新增 potion-multilingual-128M(支援101種語言,2025年5月)。sqlite-vec 更新至 v0.1.7-alpha.10(CI/CD 修正,無功能變更)。已確認 MCP 規格與檢索技術仍為最新資訊。
2026-03-03 更新 MCP 規格演進(2025年11月已推出:Streamable HTTP、.well-known、工具註解)。新增 Model2Vec 微調與 BPE/Unigram tokenizer 支援。新增社群 MCP 伺服器比較表。將 Smart Connections 更新至 v4。
2026-03-02 在模型比較中新增 potion-base-32M 與 potion-retrieval-32M。新增量化/降維章節。新增 MCP 規格演進附註。
2026-03-01 首次發布

參考資料


  1. Internet Vin, “22 commands I use with Obsidian and Claude Code,” March 2026, x.com/internetvin/status/2026461256677245131

  2. Nicopreme, “Visual Explainer” agent skill with slash commands, x.com/nicopreme/status/2023495040258261460

  3. Cormack, G.V., Clarke, C.L.A., and Buettcher, S. Reciprocal Rank Fusion outperforms Condorcet and individual Rank Learning Methods。SIGIR,2009。介紹 RRF,並以 k=60 作為無參數方法,用於合併排序清單。 

  4. OpenAI Embeddings Pricing。text-embedding-3-small:每百萬 token $0.02。估計每次完整重新索引知識庫的成本:約 $0.30。 

  5. van Dongen, T. et al. Model2Vec: Turn any Sentence Transformer into a Small Fast Model。arXiv,2025。說明從 sentence transformers 蒸餾出靜態 embeddings 的方法。 

  6. potion-base-8M Model CardModel2Vec results。目前發布的表格顯示,potion-base-8M 為 51.32 Avg (All) / 51.08 Avg (MTEB),相較 all-MiniLM-L6-v2 的 55.80 Avg (All) / 55.93 Avg (MTEB),在全任務分數上約保留 92%。 

  7. Model Context Protocol Specification。用於將 AI 工具連接至資料來源的 MCP 標準。 

  8. Model2Vec Potion Modelspotion-base-32Mpotion-retrieval-32M。目前的 model cards 顯示,potion-base-32M 為 52.83 Avg (All),potion-retrieval-32M 在 retrieval 表格中為 35.06。 

  9. Update on the Next MCP Protocol Release。2025年11月版本推出 Streamable HTTP transport、.well-known URL discovery、structured tool annotations,以及 SDK tier 標準化。下一版暫定於 2026 年中發布,將包含 async operations、domain-specific extensions 與 agent-to-agent communication。 

  10. Model2Vec Releases。v0.4.0(2025年2月):training/fine-tuning 支援。v0.5.0(2025年4月):backend rewrite、quantization、dimensionality reduction。v0.7.0(2025年10月):vocabulary quantization、BPE/Unigram tokenizer 支援。v0.8.0/v0.8.1(2026年3月):tokenizer 與 persistence 重構、Python 3.9 棄用、MTEB V2 結果更新,以及 Windows 路徑相容性。v0.8.2(2026年5月29日):維護版本,新增訓練用 frozen-weights 選項,並包含 multiword-token 修正、training 重構,以及 non-quantized weight-handling 修正。 

  11. Smart Connections for Obsidian。Smart Connections v4:local-first AI embeddings;初次索引後,語意搜尋可離線運作。 

  12. potion-multilingual-128M。Minish Lab,2025年5月。101 語言靜態 embedding 模型,為表現最佳的多語靜態 embeddings。與其他 potion 模型相同,僅需 numpy 依賴。 

  13. MCPVault — bitbonsai/mcpvault。npm @bitbonsai/mcpvault,最新 v0.12.1(發布於 2026-06-23);這是不同於 MarkusPfundstein/mcp-obsidian 的專案,並非後者改名。v0.11.0(2026年3月)新增 list_all_tags 工具,可掃描 frontmatter 與 hashtags 並計算數量,也改進 dotted-folder 處理,並支援 .base/.canvas 檔案。其路徑篩選器受到兩項中等嚴重度 GitHub Security Advisories 影響:GHSA-9c83-rr99-vfwj(限制目錄只在知識庫根目錄被拒絕,巢狀位置不會)與 GHSA-j99q-93c9-h869(可透過大小寫與尾端點號/空白等價性繞過 deny-list)——請執行 v0.12.1 或更新版本。 

  14. sqlite-vec v0.1.7 Release。2026年3月17日。穩定版本:支援 vec0 虛擬表的 DELETE、用於分頁的 KNN distance constraints、fuzz testing 改進。DiskANN approximate nearest neighbor indexing 已宣布將於未來版本推出。 

  15. Introduction to Bases。Obsidian core plugin 於 v1.9.10 引入。可在知識庫檔案上建立類似資料庫的檢視(表格、圖庫、行事曆、kanban boards),並使用 frontmatter properties 作為欄位。檔案會儲存為 .base 格式。 

  16. Obsidian Desktop v1.12.0 ChangelogObsidian Desktop v1.12.7 Changelog。v1.12.0 引入 CLI,用於以 terminal 進行知識庫自動化;v1.12.7 則透過 standalone binary、TUI 與 socket-file 行為改善安裝/runtime packaging。另請參閱 CLI documentation。 

  17. Claudian。Obsidian plugin,可將 Claude Code 作為 AI 協作者嵌入知識庫。提供 sidebar chat、context-aware prompts、vision support、slash commands 與 permission modes。 

  18. Agent Client。Obsidian plugin,透過 Agent Client Protocol (ACP) 為 Claude Code、Codex CLI 與 Gemini CLI 提供統一介面。支援 note mentions、shell execution 與 action approval。 

  19. Obsidian iOS Changelog。2026年初的更新包含 Share Extension,可將其他 app 的內容直接儲存到知識庫;也包含 Daily Note 與 Bookmark widget 修正,以及 View Note widget refresh 改進。 

  20. MarkusPfundstein/mcp-obsidian。仍積極維護——提交記錄截至 2026年5月15日,近期工作新增了包含 search_by_tagget_frontmatter 在內的工具,並擴充測試覆蓋(已依據 repository 的 commit history 與 tools.py 驗證)。仍未提供 tagged releases,因此請從 pinned commit 安裝。此專案基於 Local-REST-API;論壇討論(2026年4月)指出,新設定中社群正轉向第一方 Obsidian CLI bridge(1.12.x),但 mcp-obsidian 對既有 REST-API 部署而言,仍是可用且持續更新的選項。 

  21. Smart Connections v4.5.0 Release。2026年5月5日。Footer connections 成為 Core 功能;近期 v4 版本也包含 connection lists 的 graph views、可設定的 connection-panel locations、改進的 block-embedding recovery、Substrate cross-plugin state、transformer fallback 修正,以及減少重複 connection calculations。 

  22. obsidianmd/obsidian-clipper releases——Web Clipper 版本與功能對照的主要來源。2026年4月週期:1.4.0(4月9日,YouTube transcript UI + Open in Reader 預設值)、1.5.0(4月15日,Highlights viewer + Reader fade-in)、1.5.1(4月15日,webpack compilation 修正)、1.6.0(4月21日,Highlighter UX + Defuddle 0.18,含 LinkedIn/Threads/Bluesky/Discourse/Medium extractors)、1.6.1(4月22日,Reader outline 修正 + highlights search)、1.6.2(4月23日,Safari embedded-mode clipboard 修正)。亦同步列於 Mozilla Add-ons storeChrome Web Store。 

  23. sqlite-vec v0.1.8sqlite-vec v0.1.9sqlite-vec v0.1.10-alpha.3sqlite-vec v0.1.10-alpha.4。v0.1.8 修正 npm packaging;v0.1.9 修正 metadata text columns 超過 12 個字元時的 DELETE bug;v0.1.10-alpha.3 新增正確的 INSERT OR REPLACE INTO 支援;v0.1.10-alpha.4(2026年5月18日)修正使用新 ivf/diskann 功能的 vec0 表在 ALTER TABLE RENAME 失敗的問題,以及 DiskANN 中 cached-statement cleanup bug。0.1.10 系列仍為 prerelease。 

  24. MCP 2026-07-28 Specification Release Candidate。於 2026年5月21日宣布;最終 spec 將於 2026年7月28日發布。這是 MCP 自推出以來最大幅度的修訂:stateless protocol core(移除 initialize handshake 與 Mcp-Session-Id header)、MCP Apps(server-rendered HTML 於 sandboxed client iframes 中執行)、Tasks 從 experimental core 畢業為官方 extension(tasks/gettasks/updatetasks/cancel)、OAuth 2.0 / OIDC authorization hardening,以及 12 個月 feature-deprecation lifecycle policy。 

  25. Obsidian Desktop v1.13.0 Changelog。Early access,2026年5月28日。UX/security/developer-tooling 版本:重新設計 Settings panel,可在獨立視窗中開啟,並具備搜尋與鍵盤導覽;Obsidian URIs 觸發前會顯示確認對話框;為 plugin developers 新增 Settings API;並修正 flatpak 安裝的 CLI 問題。除 1.12.x CLI 表面之外,沒有新增主要 AI/automation 能力。 

  26. Obsidian Changelog。Obsidian 1.13.1 desktop 於 2026年6月9日進入 public channel——相較 1.13.0,這是 settings-UX 細節調整與 CodeMirror 升級,沒有新增 AI/automation 能力。 

VAULT obsidian.md INDEXED