# LLM Wiki フルスペックRAG化完了 (2026-05-31)

LLM Wiki を「Retrievalのみの半RAG」から、検索→rerank→生成→引用を完結する**フルスペックRAG**へ改修した。llm-wiki#1。

## 改修前の致命的弱点(実測で発見)
1. `embed()` が `text[:2000]` で切り捨て → 2000字超の48ページの後半が意味検索に乗らなかった
2. ベクトルインデックス無し → 全件 seq scan
3. rerank無し / 生成(G)はエージェント任せ

## 実装した4フェーズ
- **Phase1 チャンク分割**: `wiki_chunks` テーブル新設。見出し優先チャンカ(~1000字・overlap100)。432→594チャンク・100%埋め込み。最長39,840字ページ→40チャンク
- **Phase2 HNSW**: `idx_wiki_chunks_hnsw`・`idx_wiki_pages_hnsw`・GIN(fts)。pgvector 0.6.0
- **Phase3 Rerank**: ハイブリッド上位→LLM rerank→top_k。fail-open
- **Phase4 /ask**: 検索→文脈注入→LLM生成→`[N]`引用付き

## モデル構成(鍵レス・非中華)
- 埋め込み: Ollama nomic-embed-text 768次元(ローカル・外部送信なし)
- rerank/生成: **9router経由** で `nvidia/meta/llama-3.3-70b-instruct` → `groq/llama-3.3-70b-versatile` → `cerebras/gpt-oss-120b` → `ollama/qwen2.5:3b` フォールバック
- 9routerが鍵を内部管理するため、Wikiコードに API キーを書かない

## 新エンドポイント
- `GET /api/rag_search?q=&top_k=` — チャンク検索+rerank
- `GET /api/ask?q=&top_k=` — RAG完結Q&A(引用付き)
- `GET /api/rag_health` — プロバイダ疎通+チャンク統計
- MCP: `wiki_ask` / `wiki_rag_search` 追加

## 重要な学び
- 9routerの `/v1/models` 一覧はキャッシュで不正確。**実測でモデルID確定が必要**(一覧に無くても叩ける、有っても404)
- `stream:false` 明示が必須。gpt-oss系は reasoning にトークン消費するので max_tokens を絞りすぎると content が空
- チャンカは冪等設計(DELETE→INSERT)にしたので `/api/add` フックで追加/更新ページを即再チャンク化できる
- HNSWは近似最近傍ゆえ少件数(594)ではプランナがseq scanを選ぶ。件数増で自動切替

## 関連
- ファイル: web/llm-wiki/{llm_client.py, chunk_and_embed.py, app.py}
- 9router: localhost:20128(PM2 id:14)。[[2026-05-24 9router学習]]
- ポリシー: [[ポリシー: 中華系API不使用]]