Re-embed the knowledge base when the embedding model changes
Vectors from two different embedding models are not comparable — Titan v2 has 1024 dimensions where nomic-embed-text has 768 — and _cosine_similarity zips them, so a mismatch produced quietly meaningless scores rather than an error. Nothing forced a re-embed either: sync_local_kb only looked at the content hash, so switching models left every cached vector in place. local_knowledge_docs now records the model each vector came from, and a row is re-embedded when its content hash OR its model differs. Saving a new LOCAL_KB_EMBEDDING_MODEL from the settings panel starts a background pass over every file; the knowledge base panel also has a button for it. While that pass runs, the per-request sync steps aside so no file is embedded twice. The panel now shows what the embedding model is doing: model name, vector size, how many files are embedded with the current model, how many are still on an older one, a progress bar while a pass runs, and the last error. A "接続テスト" button embeds one short string so a broken or unreachable model can be told apart from one that is merely slow to warm up. Also read TAVILY_API_KEY from os.environ at call time. It was imported as a config constant, which is evaluated before load_into_env() runs, so a key saved from the settings panel was stored but never used — not even after a restart. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+40
@@ -306,6 +306,46 @@ attachment; filename="______.md"; filename*=UTF-8''%E8%B2%B7%E3%81%84%E7%89%A9%E
|
||||
|
||||
---
|
||||
|
||||
### GET /api/kb/embedding
|
||||
埋め込みモデルの現状と、再埋め込みの進捗を返す。
|
||||
|
||||
```json
|
||||
{
|
||||
"model": "ollama/nomic-embed-text",
|
||||
"dimensions": 768,
|
||||
"file_count": 36,
|
||||
"indexed": 36,
|
||||
"stale": 0,
|
||||
"running": false,
|
||||
"total": 36,
|
||||
"done": 36,
|
||||
"failed": 0,
|
||||
"started_at": "2026-08-23T13:50:23.196274Z",
|
||||
"finished_at": "2026-08-23T13:50:29.951099Z",
|
||||
"last_error": null
|
||||
}
|
||||
```
|
||||
|
||||
`indexed` は**現在のモデルで**埋め込まれている件数、`stale` は別モデル(またはモデル不明)のまま残っている件数。
|
||||
`running` 以下は実行中の進捗で、プロセス内のメモリにしか無い(再起動で消える。ワーカーを複数立てるとワーカーごとに別の値になる)。
|
||||
|
||||
---
|
||||
|
||||
### POST /api/kb/embedding/test
|
||||
短いテキストを実際に 1 回埋め込んでみて、モデルが応答するかを確かめる。失敗しても 200 で返し、`error` に理由が入る。
|
||||
|
||||
```json
|
||||
{ "ok": true, "model": "ollama/nomic-embed-text", "dimensions": 768, "latency_ms": 412.3, "error": null }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /api/kb/embedding/reindex
|
||||
全ファイルの再埋め込みをバックグラウンドで開始し、開始直後の状態(`running: true`)を返す。
|
||||
すでに実行中なら何も起こさず現在の進捗を返す。
|
||||
|
||||
---
|
||||
|
||||
## ログ
|
||||
|
||||
### GET /logs
|
||||
|
||||
@@ -65,7 +65,7 @@ backend/
|
||||
| `memory_tags` | id, memory_id, tag, created_at | 要約への自動タグ |
|
||||
| `knowledge_entries` | id, query, summary, created_at | Web 検索で得た知識(セッション横断) |
|
||||
| `knowledge_sources` | id, entry_id, title, url | 上記知識の出典 URL |
|
||||
| `local_knowledge_docs` | id, path, title, content_hash, embedding_json, updated_at | ローカル Markdown KB の埋め込みキャッシュ |
|
||||
| `local_knowledge_docs` | id, path, title, content_hash, embedding_json, embedding_model, updated_at | ローカル Markdown KB の埋め込みキャッシュ(`embedding_model` が現在の設定と違う行は埋め直す) |
|
||||
| `note_pages` | id, title, content, position, section, created_at, updated_at | ユーザーと AI が共同編集する共有ノートのページ(`section` でタブをグループ化) |
|
||||
| `session_note_pages` | id, session_id, page_id, created_at | 「このセッションではこのページの本文をプロンプトに載せる」指定(session_id × page_id は一意) |
|
||||
| `app_settings` | key, value, updated_at | GUI 設定画面から編集した接続情報 |
|
||||
|
||||
+13
-2
@@ -28,7 +28,7 @@ Discord 連携は [discord-bot.md](discord-bot.md)、ノートの操作方法は
|
||||
| 4 | 自動要約による長期記憶 | 一定件数を超えたら古い会話を要約して圧縮 | `memory_kb/memory.py` |
|
||||
| 5 | Web 検索と知識の蓄積 | Tavily で検索 →要約 → DB とローカル KB に保存 | `core/search/` / `memory_kb/knowledge.py` |
|
||||
| 6 | ローカル Markdown ナレッジベース | 話題に近いファイルを埋め込み類似度で選んで全文注入 | `memory_kb/local_knowledge.py` |
|
||||
| 6.5 | ナレッジベース閲覧パネル | KB の Markdown をサイドパネルで一覧・全文表示 | `api/knowledge_base.py` / `KnowledgeBasePanel.vue` |
|
||||
| 6.5 | ナレッジベース閲覧パネル | KB の Markdown を一覧・全文表示。埋め込みの状態確認・接続テスト・再埋め込み | `api/knowledge_base.py` / `KnowledgeBasePanel.vue` |
|
||||
| 7 | 共有ノート | タブ/セクション付きノートを人と AI の両方が編集 | `core/notes.py` / `NotePanel.vue` |
|
||||
| 8 | 自動タグ付け | 発言・要約にタグを 3 つ付与(話題選びに使う) | `memory_kb/tagging.py` |
|
||||
| 9 | ワードプール | 直近の名詞をインメモリに保持しタグクラウド表示 | `memory_kb/word_memory.py` / `WordPool.vue` |
|
||||
@@ -103,9 +103,15 @@ Discord 連携は [discord-bot.md](discord-bot.md)、ノートの操作方法は
|
||||
|
||||
- `backend/knowledge_base/**.md` を置いておくだけで、話題が近いときに自動で全文が注入される。
|
||||
- 直近のユーザー発言との埋め込みコサイン類似度で選ぶ。埋め込みは `local_knowledge_docs` に
|
||||
内容ハッシュ付きでキャッシュされ、ファイルが変わったときだけ取り直す。
|
||||
内容ハッシュと**使用した埋め込みモデル名**付きでキャッシュされ、
|
||||
ファイルが変わったときと、埋め込みモデルが変わったときだけ取り直す。
|
||||
- 設定画面で `LOCAL_KB_EMBEDDING_MODEL` を変更すると、保存した時点でバックグラウンドの再埋め込みが走る
|
||||
(モデルが違えば次元も意味空間も変わり、古いベクトルは比較しても無意味なため)。
|
||||
パネルの「埋め直し」ボタンからも手動で開始できる。
|
||||
- プロンプト上は「Web 検索結果より優先。これで答えられるなら検索するな」と明示している。
|
||||
- ヘッダーのパネルメニュー →「ナレッジベース」で開くサイドパネル(`KnowledgeBasePanel.vue`)から中身を閲覧できる。
|
||||
パネル上部には埋め込みの状態(モデル名・次元数・埋め込み済み件数・進捗バー)が出る。
|
||||
「接続テスト」は短いテキストを 1 回埋め込んでみて、モデルが応答するかその場で確かめる。
|
||||
フォルダ単位のグループ表示・折りたたみ、タイトル/パス/本文先頭での絞り込み、Markdown 描画に対応。
|
||||
各ファイルの緑の点は埋め込み済み(=自動注入の対象)であることを示す。閲覧専用で、編集はできない。
|
||||
|
||||
@@ -164,6 +170,11 @@ Discord 連携は [discord-bot.md](discord-bot.md)、ノートの操作方法は
|
||||
現在値をそのまま表示し、入力欄も伏せ字にしない(今どれが効いているか分からないと設定しづらいため)
|
||||
- 空欄で保存すると「変更なし」扱い
|
||||
- 保存すると `app_settings` テーブルに入り `os.environ` に反映される。削除すると `.env` 由来の起動時の値に戻る
|
||||
- 保存した値は `backend_data` ボリュームに残るため、コンテナを作り直しても消えない。
|
||||
起動時に `load_into_env()` が `os.environ` へ流し込むので、`.env` の同名の値より優先される
|
||||
- **アプリ側は `config.py` の定数ではなく `os.environ` を都度読むこと**。定数は import 時に評価され、
|
||||
`load_into_env()` より前に確定してしまうため、GUI で保存した値が反映されない
|
||||
(`websearch._api_key()` / `knowledge._summary_model()` / `local_knowledge._embedding_model()` がその形)
|
||||
|
||||
## 15-16. ログビューアとシステムモニタ
|
||||
|
||||
|
||||
Reference in New Issue
Block a user