Markdown ノート群を embedding 類似度で可視化する、Electron + React + TypeScript のデスクトップ PoC です。
政策文書要約のような長文メモを対象に、タイトル重み付け・事前クラスタリング・k-NN グラフでノイズを抑えながら探索できる構成です。
- グローバルグラフ(会議クラスタ単位)を表示
- ノード hover でタイトル/パス/抜粋を表示
- ノード double-click で既定エディタで Markdown を開く
- 選択ノードから ローカルグラフ(クラスタ内の各
.md単位)を表示 - OpenAI Embeddings と Local TF-IDF の Provider 切り替え
- embedding キャッシュ(
.embedding_cache.json)で再計算を回避
- Desktop: Electron
- UI: React + TypeScript + Tailwind CSS
- Graph: sigma.js v2 + graphology + ForceAtlas2
- Embedding Provider:
- OpenAI API key あり: OpenAI Embeddings API
- API key なし: Local TF-IDF + cosine
- macOS / Linux / Windows
- Node.js 20+(推奨: 22+)
- npm
npm install
npm run postinstall:electronnpm run devnpm run typecheck
npm run buildChoose Folderで Markdown ルートを選択- 必要なら OpenAI API Key / Model を入力
Similarity ThresholdとMax Filesを調整Build Graph実行- ノードをクリックして詳細確認
- ノード詳細またはホバーカードの
ローカルグラフを表示で局所グラフ表示
- ノード: 事前クラスタ済みの会議グループ
- エッジ: cosine 類似度に基づく semantic edge
- 構築方式:
- 全ペア類似度を計算
- 各ノード上位
k件を候補化(k-NN) - threshold 未満を除外
- 上限
5 * Nでエッジ数を制御
- 対象: 選択クラスタに含まれる
sourcePathsの各.md - ノード:
.md1ファイル = 1ノード - エッジ: 同じく k-NN + threshold
- 対象ファイル: 選択フォルダ配下の
.md(再帰) Max Files超過時: 更新日時の新しい順(mtime desc)で採用- 抽出:
title: 先頭 H1、なければファイル名bodyText: YAML frontmatter 除去後本文snippet: 本文先頭 200 文字
- embedding 入力:
titleを重み付け(デフォルト x4)bodyText先頭を連結(合計上限あり)
- 事前クラスタ:
- 回数・版数・日付など末尾表記を正規化して同タイトルを統合
- 保存先:
<selected-folder>/.embedding_cache.json - キー要素:
relpathmtimeprovidermodelcorpusHash(Local TF-IDF などコーパス依存時)
- OpenAI API key / model は appData に保存
- PoC では平文保存(OS keychain 連携は未実装)
emb-graph/
electron/
main.ts # Electron main, IPC 登録
preload.ts # Renderer へ安全なAPIを公開
services/
pipeline.ts # グローバル/ローカルの埋め込み+グラフ構築
markdown.ts # スキャン/前処理/クラスタ/ローカル読込
knn-graph.ts # cosine + k-NN + エッジ生成
embedding-cache.ts # キャッシュ I/O
providers/ # OpenAI / Local TF-IDF
src/
App.tsx # UI・Sigma描画・ローカルグラフモーダル
types.ts # Renderer 側型定義
vite-env.d.ts # preload API の型
docs/
ARCHITECTURE.md # 詳細設計
TROUBLESHOOTING.md # よくあるトラブル対処
npm run dev: Renderer + Electron TS watch + Electron 起動npm run dev:renderer: Vite dev servernpm run dev:electron:build: Electron 側 TS watchnpm run dev:electron:run: Electron 実行npm run typecheck: Renderer/Electron 型チェックnpm run build: Renderer/Electron 本番ビルド
メインプロセスから Renderer へ以下を通知します。
scanning filesembeddingbuilding knn graphrendering
- 大規模データでは類似度計算(全ペア)がボトルネック
- ラベルの重なりはデータ密度とズームに依存
- Local TF-IDF は OpenAI embedding より意味精度が劣る場合がある
- ノード検索
- コミュニティ検出によるクラスタ色分け
[[wikilink]]/ Markdown link を別種エッジとして追加- ローカルグラフにフィルタ(日付、文書種別、最小類似度)
ISC