AIの「睡眠学習」と長期記憶設計|KVキャッシュ忘却を超えるSQLite・複数LoRA統合術
新しいチャットを開いた瞬間、昨日まであんなに阿吽の呼吸で作業していた AI が「初対面の別人」にリセットされていて、またゼロから前提やルールを説明し直す——そんな徒労感にうんざりしたことはありませんか。VS Code や Antigravity IDE には思考ログを残す /brain フォルダがありますが、実はあれも「AI 自身の脳は何ひとつ覚えておらず、外部ディスクの日記帳を毎回 1 ページ目から読み返しているだけ」という点では根本が変わっていません。
結論からお伝えすると、AI の忘却と再計算の無駄を根絶する最適解は、人間の「海馬(短期記憶)」と「大脳皮質(長期記憶)」のサイクルを模倣し、「①日中は KV キャッシュと /brain で高速に対話し、②夜間の睡眠バッチ(3 段階判定ゲート)でノイズを破棄、③ 1 文字の狂いも許されない厳密値と履歴は『最新・履歴 2 層分離 SQLite(条件付き UPSERT +トリガー退避)』へ無劣化保存し、④常時働く原則と『SQLite の土地勘ポインタ』だけを分野別の複数 LoRA へ直交蒸留(O-LoRA / MoLE)する 4 階層ハイブリッド設計」 です。本記事では最新論文の裏付けから、そのまま動く SQL・Python 実装、そして重みを直接触れない商用クラウド AI 環境で今日から同じ仕組みを再現する実践構成までを一挙に解説します。
-
AIの入力解析と文章生成の仕組み|一瞬のプリフィル・第1語抽選とヴォイニッチ手稿の謎 : 本記事の前編です。なぜ Self-Attention でせっかく計算した理解(KV キャッシュ)がチャット終了とともに消えてしまうのかを基礎から解説しています。
-
【AIルール設計の壁突破】なぜGEMINI.mdを長く書くとAIが記憶喪失になるのか?『24KB・2万トークンの罠』と段階的開示アーキテクチャ : ルールファイルを肥大化させず、「目次ポインタ」から必要な仕様だけを読み込ませる段階的開示の実践記録です。
-
SQLiteはなぜMySQLより速い?WAL・FTS5とNode.jsで500記事探索をミリ秒化した実装録 : 文字列
grepの限界を超え、1 ファイルの SQLite で AI の過去ログ・記事探索を 0.01 秒化した設計ノウハウです。 -
AIエディタの会話ログでRAMDiskが満杯?直近3日保持とSSD自動退避で空き容量を2倍にした構築録 : 肥大化する
/brainと会話 DB を、アクティブ層とアーカイブ層へ無欠損で自動分離した運用録です。 -
脱Transformerと『毒の辞書』:人間の脳を超え、反日工作を免疫化する自律AIのGraph DB検疫設計 : 海馬と大脳皮質の分離・本番 DB への直接書き込み禁止・検疫ゲートを国家インフラ規模へ拡張した技術設計編です。
-
Google AI週間クォータ消費を半減!SQLite×RAMDiskで500記事運用を高速化した記録 : 500記事超のAstroサイト運用で生ログ190本を分析し、AIの週間クォータを削る「ハズレ記事の再送」を解消。行番号直結SQLite・512MBメモリマップ・RAMディスクで累積入力量を51.2%削減した3層最適化を公開します。
-
小型AIで巨大AIと同点を出す「作業分割」の科学|KVキャッシュ無劣化圧縮と隠し命令防御 : 4.94億パラメータの超小型AIが30倍の巨大AIと同点を出した「作業分割(Decompose)」論文や、KVキャッシュを劣化ゼロで26%削るGAAC、隠し命令を99%封じるLLMONとSQLite分担術を解説します。
-
新しいチャットを立ち上げるたびに過去の経緯が白紙に戻り、「AI に個人専用の長期記憶を持たせる仕組み」 がどうなっているのか知りたい方
-
AI エディタ(VS Code / Antigravity 等)の
/brainやテキスト検索(grep)の限界を感じており、SQLite の自動履歴管理(UPSERT +トリガー)で厳密な仕様台帳を組みたい方 -
最新研究の 「AI の睡眠学習(Sleep-time Compute / コンテキスト蒸留)」や「複数 LoRA の非干渉ブレンド(O-LoRA / MoLE)」 の仕組みを理解し、手元の Mac 環境へ応用したい方
なぜIDEのbrainでもAIの忘却は直らないのか
名前は脳でも実態は毎回読み直す外部の日記帳
前編の記事で確認した通り、現在のチャット AI は会話中に本体の脳(モデルの重みパラメータ)を 1 ミリも書き換えません。では、思考プロセスや計画書(task.md や implementation_plan.md)がローカルの brain フォルダに自動保存される VS Code や Antigravity IDE なら、AI はちゃんと記憶しているのでしょうか?
実は、裏側で起きている根本の仕組みは通常のチャットと一切変わっていません。名前こそ brain(脳) と呼ばれていますが、その実態は「記憶喪失になる AI をソフトウェア側で介護するための外部ディスク上の日記帳」 なのです。
| 記憶のアプローチ | AI内部の状態 | 人間から見たメリットと弱点 |
|---|---|---|
現行の /brain 方式(外部テキスト保存) | 脳(重み)は不変。思考結果を Markdown や JSON で SSD 等へ書き出し、次回プロンプト先頭に貼り直して再送信する。 | 【強み】 何を考えたか人間が目で追跡・直接編集(監査)できる。 【弱点】 毎回 1 文字目から プリフィル + Self-Attention の再計算が走り、トークン枠も消費する。 |
| 重みへの直接上書き (仮にそのまま学習した場合) | 思考結果がそのまま数十億〜数兆個の重み数値にブレンドされる。 | 【強み】 再読み込みゼロで 0 秒目から過去の文脈を引き出せる。 【弱点】 ブラックボックス化し、どこで勘違いしたか外から検証・修正できなくなる。 |
もちろん、この「アナログな書き出し方式」にはシステム開発上の大きな利点もあります。AI が勝手に自分の神経回路(数値の塊)を書き換えてしまうと、人間が外から設計ミスを監査できなくなりますが、テキストとして吐き出させておけばその場で計画書を書き換えて軌道修正できるからです。
なお、この「推論中は重みが固定される」という Transformer の限界を打破するため、Google Research が発表した次世代アーキテクチャ Titans(タイタンズ) や MIRAS のように、「予想外の出来事(驚き:勾配変化が大きい未知情報)」に出会った瞬間だけ推論中にリアルタイムで長期記憶モジュールを更新する研究も進んでいますが、商用主力モデルのすべてを置き換えるには至っていません。
個人専用の着脱脳に立ちはだかる2つの壁
そこで自然に浮かぶのが、「全員で共有する巨大な基礎脳(ベースモデル)は読み取り専用で固定したまま、有料プラン等のユーザーごとに『着脱可能な個人専用のミニ脳(永続 KV キャッシュや個人別 LoRA アダプター)』を用意し、会話するときだけ合体させれば忘却を防げるのではないか?」 というアイデアです。
実際、個人別 LoRA(Per-User LoRA)なら 1 人あたりわずか 30MB〜150MB 程度 の極小ファイルに収まるため、他ユーザーへの情報漏洩リスクは物理的にゼロになり、基礎脳が壊れる「破滅的忘却」も起きません。にもかかわらず、テキストの /brain を全廃して「数値の個人脳」へ今すぐ全面移行できないのには、実用上の 2 つの厄介な壁 がありました。
-
壁①:勘違いした記憶だけを消せない「消しゴム問題」 : テキストの
/brainなら、AI が開発環境の設定を 1 箇所勘違いしてもファイルを開いて 1 行直せば 1 秒で解決します。しかし数値の重み(LoRA 等)に混ぜ込んでしまうと、どの数値がどの記憶なのかが分からなくなり、「先週の間違った前提だけ忘れて」と頼んでも周囲の正しい記憶まで一緒に壊れやすくなります(アンラーニングの壁)。 -
壁②:ベースモデルが世代交代すると「脳の規格」が合わなくなる : 土台の AI が次期メジャーバージョンへ進化すると、内部の意味座標(ベクトルの次元や配置)がゼロから作り直されます。古いモデル用に育てた KV キャッシュや LoRA は数値規格が合わず、新モデルに差し込んでも拒絶反応を起こして使えなくなってしまいます。
うわぁ、せっかく何ヶ月もかけて自分専用の賢いミニ脳を育てたのに、AI 本体がバージョンアップした瞬間に規格違いでパーになったら泣くに泣けんわい!
そこが最大の急所だったんです!でも安心してください。「日中はテキストの /brain と SQLite で記録・修正し、人間が寝ている夜間にだけネイティブ脳(LoRA)へ変換する」という 『AI の睡眠学習』 を組むことで、この 2 つの壁を同時に突破できるようになりました!
昼は海馬で夜は皮質へ焼くAIの睡眠学習サイクル
コンテキスト蒸留と最新研究が実証した効果
私たちの脳は、昼間の出来事をまず一時記憶の 「海馬」 に蓄えて素早く行動し、夜ぐっすり眠っている間にその記憶を再生して長期記憶の 「大脳皮質」 へ整理・定着させ、翌朝には海馬の空き容量をスッキリ空けて目覚めます。
これとまったく同じサイクルを、AI の 「KV キャッシュ + /brain(海馬)」 と 「個人用 LoRA アダプター(大脳皮質)」 のリレーで再現するのが、2025 年〜 2026 年にかけて研究が一気に加速している 『AI の睡眠学習』 です。
夜間に一時的な会話ログを LoRA の神経回路へ移し替える際には、「コンテキスト蒸留(Context Distillation / Prompt Baking)」 という手法が使われます。昼間の長いログ(KV キャッシュ)をすべて読んでいる状態の AI を「教師」、ログを一切見ずに空っぽの状態で個人用 LoRA だけを差した AI を「生徒」として並走させ、どんな質問を投げても生徒が教師とまったく同じ確率分布を出せるようになるまで個人用 LoRA の重みだけを微調整して焼き付けるのです。
このアプローチは単なる構想ではなく、以下の最先端研究で具体的な数値とともに実証されています。
-
『Sleep-time Compute』(UC Berkeley & Letta /
arXiv:2504.13171) : ユーザーが寝ているアイドル時間の計算資源を使い、手元の文脈から「次に聞かれそうな推論」をバックグラウンドで事前整理しておく手法です。昼間の推論時計算量(Test-time compute)を 約 5 分の 1、平均コストを 2.5 分の 1 に削減しつつ、正答率を 13〜18% 向上 させました。 -
『Cartridges』(Stanford Hazy Research 他 /
arXiv:2506.06266) : 大規模な資料群をオフラインの自習(Self-study)によって超小型の圧縮 KV キャッシュ(カートリッジ)へ蒸留する手法です。同等の性能を保ったままメモリ消費量を 38.6 分の 1 に圧縮し、処理スループットを 26.4 倍 へ引き上げています。 -
『Do Language Models Need Sleep?』(CMU & メリーランド大学 /
arXiv:2605.26099) : 覚醒時に蓄えたコンテキストを破棄する前にオフラインの「睡眠ステップ」を挟み、内容を反復再生して動的結合重み(Fast Weights)へ記憶を焼き付けてから KV キャッシュを完全消去(Evict)する仕組みを実証しました。 -
『Context Distillation as Latent Memory Management』(
arXiv:2605.28889) : 会話や文書をそれぞれ独立した LoRA バンクへ蒸留し、昼間は関係ない話題のときに自己ゲート機構(Self-Gating)で自動的にオフにすることで、従来の検索方式(RAG)を上回る応答精度と速度を両立しています。 -
『Language Models Need Sleep』(Google Research /
arXiv:2606.03979) : 短期記憶から持続的な長期記憶モジュールへの上方蒸留(Upward Distillation)と、睡眠中の自己改善(Dreaming)によって破滅的忘却を防ぐ統合学習モデルを提示しています。
勘違いを消す夜間検疫とテキスト再変換の強み
さらに、「日中は /brain(テキスト)で保存し、夜間にネイティブ脳(LoRA)へ変換する」というプログラムのナイトリービルド(夜間コンパイル)と同じ構造を採ると、先ほどの 「消しゴム問題」と「モデル世代交代の壁」が 100% 解決 します。
- 寝る前の検疫(Supersede と誤答排除) : 夜間の焼き付け処理の入り口に「矛盾監査ステップ」を置き、昼間の会話で一度 AI が間違えて直後にユーザーから訂正された誤答ログを切り捨てます。また、過去の設定が「メモリ 32GB」で今日の会話が「64GB に増設した」なら、単なるエラーではなく 古い記憶の無効化(Supersede:上書き更新) として整理します。
- ピンポイント修正とクリーンリビルド : 万が一すでに LoRA 側へ誤った知識が混ざっても、最新の知識編集技術(他の記憶に影響しない数学的な零空間を使う
AlphaEditや、トピック別ブロックを差し替えるMELOなど、EasyEditフレームワークで実装可能)で外科手術ができるほか、もっとシンプルに 「手元の確定版テキスト台帳を 1 行直して、夜間に LoRA をクリーンリビルド(再変換)する」 だけで翌朝には綺麗さっぱり消去できます。 - ベースモデル世代交代への完全耐性 : 将来 AI 本体が次世代モデルへアップデートされて古い LoRA が使えなくなっても、精査済みのマスターデータ(テキストと SQLite 台帳)が無傷で残っているため、切り替わった晩に新モデル用の LoRA を一括で再コンパイルするだけ で、すべての記憶を 1 日も失わずに最新の頭脳へ引っ越しできます。
脳に焼く直感とSQLiteに残す厳密値の境界線
非可逆なLoRAと無劣化なSQLiteの分担
ここで、システム全体の賢さを左右する最も重要な設計判断が登場します。それは、Web チャットボットと IDE(VS Code / Antigravity)で同じ /brain 基盤を共有したうえで、「夜間にすべてを LoRA へ焼くのではなく、LoRA に焼くものと SQLite にだけ残すものを厳格に分ける」 という境界線です。
なぜ全部を LoRA(重み)に焼いてはいけないのでしょうか? 理由は、ニューラルネットワークの重みが情報を「意味のパターンとしてブレンドする 非可逆圧縮」だからです。ファイルパスや設定数値、コード片まで無理やり重みに焼き付けると、他の記憶と混ざって 1 文字違いの書き間違い(ハルシネーション)を起こします。一方、単一ファイルで高速に動くリレーショナルデータベース SQLite は、推論こそできないものの 記録した文字列や数値を 1 ビットの劣化もなく 100% 無傷で保持でき、全文検索(FTS5)や条件抽出で grep の何十倍も正確に引ける という真逆の強みを持っています。
いま開いているスレッドの直近のやり取りを保持します。チャット終了時または毎晩の睡眠バッチ完了時に完全リセットし、翌朝の作業机を空にします。
今日1日の思考プロセスや計画を記録し、午前のWebチャットと午後のIDE(VS Code / Antigravity)の間で当日中の文脈をシームレスに中継します。
ファイルパス、日付形式、数値、設定値、コード片、ボツ案の却下理由など「1文字でも変わると壊れる決定論的データ」を1ビットの劣化もなく永続保管します。
どのチャットでも0秒目から無意識に守るべき「設計原則・文体・思考回路」と、「どの詳細がSQLiteのどこにあるかという土地勘」だけを神経回路として装着します。
最強の連携を生むSQLiteの土地勘ポインタ
このハイブリッド構造を劇的に賢くする秘訣が、「厳密な値そのものは SQLite に隔離しつつ、『何のデータが SQLite のどのテーブル・どのキーに入っているか』という目次(土地勘ポインタ)だけを LoRA に焼いておく」 という設計です。
30 年選手のベテラン技術者も、過去 5 年分の設定値やコードを 1 文字残らず丸暗記しているわけではありませんよね。しかし「あの仕様の正確な数値なら、あの設計書のあの項目を見れば書いてある」という 『土地勘(メタ記憶)』 は頭の中にしっかり入っています。
これを AI でもそのまま再現します。夜間に細かい設定値は SQLite へ入れつつ、LoRA 側には「レイアウトパスや日付形式の正確な仕様は brain_specs テーブルにある」というポインタ知識だけを焼いておきます。すると翌日、新しいチャットで質問された瞬間、AI は LoRA の直感によって 「あ、これは暗記で答えるのではなく brain_specs を引く案件だ」と 0 秒で判断し、見当違いのファイルを grep する無駄ゼロで 1 発で正しい SQL を叩いて正確な値を返す ようになります。
夜間バッチで動く自動仕分けの3段階判定ゲート
1 日の終わりに AI 自身へ /brain のログを仕分けさせる際は、「重要かどうか」という曖昧な形容詞ではなく、AI が迷わない Yes / No の「3 段階判定ゲート」 をプロンプトとして与えます。
途中で訂正されたAIの誤答、解決済みの構文エラー、単なる挨拶は完全破棄します(※却下理由付きのボツ案のみ履歴用に通過)。
「1文字・1桁でも変わると壊れるか?」を判定し、パス・数値・コマンド・日付形式・ボツ案の経緯を無劣化のSQLite行きにします。
次回以降も0秒目から無意識に守るべき設計原則をQ&Aペア化し、同時にGate 2で保存したSQLiteデータの「所在ポインタQ&A」を自動追加します。
実際に夜間スクリプトから呼び出す仕分けプロンプトと、AI が出力する JSON スキーマの完成形は以下の通りです。
{
"consolidation_date": "2026-11-01",
"purged_summary": {
"discarded_items_count": 14,
"reason": "ビルドエラーの試行錯誤ログ8件、訂正された古いCSS案4件、挨拶2件を破棄"
},
"sqlite_records": [
{
"category": "file_path",
"key": "ai_project_layout_path",
"exact_value": "src/layouts/AiSectionLayout.astro",
"note": "デザイン制御を集約するレイアウトファイル"
},
{
"category": "frontmatter_rule",
"key": "pubdate_format",
"exact_value": "YYYY-MM-DD (JST基準で統一)",
"note": "フロントマターの公開日フォーマット規定"
}
],
"lora_training_pairs": [
{
"domain": "blogging",
"type": "core_principle",
"prompt": "記事のMarkdownファイルを出力する際、デザインやスタイルはどう制御すべきか?",
"completion": "Markdown内に直接 <style> タグやインラインの style 属性を書くことは厳禁です。デザイン制御はすべてレイアウト側のクラス定義に集約し、シンプルな構造を維持します。"
},
{
"domain": "coding",
"type": "sqlite_pointer",
"prompt": "プロジェクトの具体的なレイアウトファイルのパスや、公開日フォーマットの厳密な仕様はどこで確認できるか?",
"completion": "正確なファイルパスや日付の記述フォーマットは暗記に頼らず、SQLiteの `brain_specs` テーブル(key: `ai_project_layout_path`, `pubdate_format`)を検索して正確な値を参照します。"
}
]
}
履歴を自動保護するSQLiteの2層分離とトリガー
最新と履歴を分ければ古い設定の誤参照はゼロ
次に、抽出された sqlite_records を夜間に SQLite へ保存する際、「すでに過去のデータに同じ項目(古いメモリ容量や旧設定値など)があった場合、どうやって履歴を残しつつ最新状態へ自動更新(UPSERT)させるか?」というデータベース設計の要所を見ていきましょう。
1 つのテーブルに新旧すべての行を入れて status = 'active' / 'old' フラグで管理する方法(単一テーブル方式)は、人間向けにはよく使われますが AI に検索させる用途では禁じ手 です。なぜなら、AI が SQL を組み立てる際にうっかり WHERE status = 'active' を付け忘れた瞬間、すでにボツになった古い設定値を引っ張り出して事故を起こすからです。
| 比較項目 | 単一テーブル方式(フラグ管理) | 最新・履歴の2テーブル分離+トリガー方式【推奨】 |
|---|---|---|
| テーブル構造 | 1 つの表に新旧データを混在させ、status = 'old' に書き換えて追記 | brain_specs(最新のみ)と brain_specs_history(過去履歴)に物理分離 |
| AIの誤参照リスク | あり(WHERE 条件の付け忘れで古いボツ設定を誤参照する) | 構造的にゼロ(最新テーブルには常に現在有効な 1 件しか存在しない) |
| 日中の検索速度 | 履歴が増えるほど表が肥大化して重くなる | 最新テーブルは常に最小サイズに保たれ、ずっと最速を維持 |
| バッチ側の実装 | アプリ側で「既存確認→旧行更新→新規挿入」を書く必要がある | 標準の 条件付き UPSERT 文を 1 発投げるだけ で DB 側が全自動退避 |
条件付きUPSERTとトリガー退避の実装SQL
SQLite 公式の ON CONFLICT DO UPDATE(UPSERT)と BEFORE UPDATE トリガーを組み合わせれば、バッチプログラム側はただ最新データを流し込むだけで、「①昨日と同じ値なら何もしない(無駄な履歴を作らない)」「②値や注記が変わっていたら、上書きされる直前に古い行を自動で履歴テーブルへ退避してからバージョンを +1 する」 という処理が SQLite エンジン内部で 100% アトミックに完結します。
なお、SQLite で値の差分を比較する際は、通常の != を使うと片方が NULL のときに判定結果が UNKNOWN となってトリガーが不発になる罠があるため、必ず IS NOT 演算子(NULL 安全比較) を使うのが実務上の鉄則です。
-- 1. 常に最新の状態だけを保持するメインテーブル
CREATE TABLE IF NOT EXISTS brain_specs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category TEXT NOT NULL,
key TEXT NOT NULL,
exact_value TEXT NOT NULL,
note TEXT,
version INTEGER NOT NULL DEFAULT 1,
updated_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime')),
UNIQUE(category, key) -- 同じカテゴリ+キーの重複を禁止(UPSERTの判定軸)
);
-- 2. 上書きされた古い値を自動保管する履歴テーブル
CREATE TABLE IF NOT EXISTS brain_specs_history (
history_id INTEGER PRIMARY KEY AUTOINCREMENT,
spec_id INTEGER NOT NULL,
category TEXT NOT NULL,
key TEXT NOT NULL,
old_value TEXT NOT NULL,
old_note TEXT,
version INTEGER NOT NULL,
valid_from TEXT NOT NULL, -- その値が有効だった開始日時
superseded_at TEXT NOT NULL DEFAULT (datetime('now', 'localtime'))
);
-- 3. 最新値が書き換わる「直前」に古い値を履歴へ逃がす BEFORE UPDATE トリガー
CREATE TRIGGER IF NOT EXISTS trg_archive_spec_before_update
BEFORE UPDATE ON brain_specs
FOR EACH ROW
WHEN (OLD.exact_value IS NOT NEW.exact_value) OR (OLD.note IS NOT NEW.note)
BEGIN
INSERT INTO brain_specs_history (
spec_id, category, key, old_value, old_note, version, valid_from, superseded_at
) VALUES (
OLD.id, OLD.category, OLD.key, OLD.exact_value, OLD.note,
OLD.version, OLD.updated_at, datetime('now', 'localtime')
);
END;
-- 4. 夜間バッチが実行する「条件付きUPSERT」クエリ(変更がない日は完全スキップ)
INSERT INTO brain_specs (category, key, exact_value, note, updated_at)
VALUES (TRIM(:category), TRIM(:key), :exact_value, :note, datetime('now', 'localtime'))
ON CONFLICT(category, key) DO UPDATE SET
exact_value = excluded.exact_value,
note = excluded.note,
version = brain_specs.version + 1,
updated_at = datetime('now', 'localtime')
WHERE (brain_specs.exact_value IS NOT excluded.exact_value)
OR (brain_specs.note IS NOT excluded.note);
たとえば main_mac_ram が 1 日目に 32GB で登録され、2 日目の会話にも 32GB と出てきた場合は末尾の WHERE 条件によって更新自体がスキップされ、無駄な履歴は 1 行も増えません。そして 3 日目に 64GB へ増設したときだけトリガーが瞬時に発火し、旧 32GB (version: 1) が有効期間付きで brain_specs_history へ退避されたうえで、brain_specs が 64GB (version: 2) に書き換わります。
キー名の表記揺れを根絶する既存辞書プロンプト
この自動 UPSERT を AI バッチで回す際、唯一気をつけたい落とし穴が 「キー名の表記揺れ」 です。昨日の AI が pubdate_format と名付けた項目に対して、今日の AI が勝手に frontmatter_date_rule という別名をつけてしまうと、UNIQUE(category, key) が別項目と判定して新規行を増やしてしまいます。
対策は驚くほどシンプルです。夜間バッチの冒頭で次の 1 行クエリを実行し、現在登録されているキーの辞書を取得して仕分けプロンプトへ一緒に渡すだけです。
-- 夜間仕分けの前に実行し、既存キー一覧をプロンプトへ添付する
SELECT category, key, note FROM brain_specs ORDER BY category, key;
プロンプトに 「既存の項目を更新する場合は新しいキー名を勝手に作らず、必ず添付一覧にある既存の category と key を一字一句そのまま使用せよ」 と明記しておけば、表記揺れによる重複登録は 100% 防げます。
分野別の複数LoRAを干渉ゼロで合成する仕組み
夢のリプレイを含む夜間焼き付け5ステップ
SQLite 側の無劣化保存が終わったら、もう片方の lora_training_pairs(1 日数件〜十数件の Q&A ペア)を夜間に個人用 LoRA へ焼き付けます。このとき、今日 1 日分のデータだけでそのまま学習させると「一字一句同じ質問にしか反応しない丸暗記(過学習)」や「先週覚えたルールの上書き消失」が起きるため、以下の 5 段階パイプライン で調合します。
-
Step 1:言い換え増幅(Paraphrase Augmentation) : 1 件の原則 Q&A から、角度や言葉遣いを変えた 5〜10 通りの実践 Q&A(「
<span style="color:red">と書いていい? → 禁止です」等の誘惑拒否パターン含む)を自動生成し、丸暗記ではなく概念として定着させます。 -
Step 2:過去記憶とのブレンド(Replay Buffer / 夢の再生) : 人間が睡眠中に「夢」を見て過去と今日の記憶を整理するのと同じく、「今日の新規 Q&A(30%)」に対して SQLite の学習プールから引き出した「過去の重要 Q&A(70%)」 をランダムに混ぜ合わせ、古い記憶の消失を防ぎます。
-
Step 3:微小学習率での穏やかな重み更新 : 凍結されたベースモデルに昨日の個人用 LoRA を装着し、通常より 1 桁小さい微小な学習率(例:
2e-5)で 3 エポック程度じわっと追加学習させます。 -
Step 4:夜間セルフテスト(Sanity Check) : 焼き上がった新 LoRA 候補に対し、「今日覚えたこと」と「過去の必須ルール」の確認テストを自動で投げ、合格点に達しているか検品します。
-
Step 5:アトミックな差し替えと作業ログ消去 : テスト合格後のみ前日の LoRA(数十MB)を世代バックアップへ残して本番ファイルと入れ替え、日中の KV キャッシュとアクティブ
/brainログをパージします(不合格なら前日の健全な脳をそのまま維持します)。
オープンウェイトモデル(Gemma 3 等)を対象に Python(peft / trl)でこの夜間バッチを組む場合の骨格コードは以下のようになります。
import os
import shutil
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import SFTTrainer, SFTConfig
# 1. 凍結ベースモデルと「昨日の個人用LoRA」を読み込む
base_model_id = "google/gemma-3-27b-it"
active_lora_dir = "/brain/lora/profile_coding_latest"
candidate_lora_dir = "/brain/lora/profile_coding_candidate"
backup_lora_dir = "/brain/lora/profile_coding_prev_day"
tokenizer = AutoTokenizer.from_pretrained(base_model_id)
base_model = AutoModelForCausalLM.from_pretrained(base_model_id, device_map="auto")
model = PeftModel.from_pretrained(base_model, active_lora_dir, is_trainable=True)
# 2. 今日の言い換え増幅データ(30%) + SQLite過去リプレイデータ(70%) を調合
dataset = load_blended_dataset(
today_json="/brain/nightly/today_consolidated.json",
sqlite_db="/brain/index.db",
domain="coding",
replay_ratio=0.7,
)
# 3. 既存の神経回路を壊さない穏やかな設定で睡眠学習を実行
sft_config = SFTConfig(
output_dir=candidate_lora_dir,
learning_rate=2e-5,
num_train_epochs=3,
per_device_train_batch_size=4,
lr_scheduler_type="cosine",
weight_decay=0.01,
)
trainer = SFTTrainer(model=model, train_dataset=dataset, args=sft_config)
trainer.train()
model.save_pretrained(candidate_lora_dir)
# 4. 夜間セルフテスト合格時のみ安全に世代バックアップして本番差し替え
if len(dataset) > 0 and run_sanity_check(base_model, candidate_lora_dir, "/brain/lora/golden_tests.json"):
if os.path.exists(backup_lora_dir):
shutil.rmtree(backup_lora_dir)
shutil.copytree(active_lora_dir, backup_lora_dir)
shutil.copytree(candidate_lora_dir, active_lora_dir, dirs_exist_ok=True)
purge_daily_brain_logs("/brain/daily_logs/")
土台脳と専門脳を直交させて層ごとに切り替える
さらに精度を極めるなら、1 つの LoRA にあらゆる分野を詰め込むのではなく、常時 ON にする 「土台脳(lora_core:事実確認ルール等の共通原則)」 の上に、「コード開発脳(lora_coding)」「ブログ執筆脳(lora_blog)」「日常・ライフ脳(lora_daily)」 という複数の専門カートリッジを分けて焼く構成が圧倒的に有利です。1 つの LoRA に全部混ぜると「厳格に省略せず書け(開発)」と「専門用語を噛み砕いて書け(ブログ)」が同じ重みの上で綱引きを起こし、角が削れた中途半端な文章になってしまうからです。
ちょっと待って!「今作っているシステムの裏側をブログ記事にして」みたいに、開発脳とブログ脳を同時に 50% ずつ重ね掛けしたときは、結局お互いの数値がぶつかって変な文章になっちゃわないの?
すごく鋭いご質問です!まさに単純な「50% + 50% の足し算」をすると、プラスとマイナスが打ち消し合って平凡な AI に戻ったり、逆に同じ場所が 2 倍に強調されて言葉が暴走したりします。だからこそ、最前線の複数 LoRA 合成では単純平均ではなく 3 つの干渉防止技術 を組み合わせるんです!
夜間の学習時に、開発脳が使う神経の方向とブログ脳が使う方向が数学的に 90度(直交:O-LoRA) になるよう空き領域を分けて焼きます。さらに微小ノイズの80〜90%を間引いて向きを揃える DARE / TIES-Merging で符号の綱引きを根絶します。
全層一律50%ではなく、前半〜中間層(論理構築)は開発脳90%、後半〜最終層(文体整形)はブログ脳90% と縦に役割分担します。さらに記事途中で ```typescript が始まった瞬間だけ開発脳95%へギアを切り替え、閉じたらブログ脳80%へ戻します。
この 層・トークン単位の MoLE(Mixture of LoRA Experts) によって、1 つの脳では難しかった「技術的な裏付けは 1 ミリの狂いもなく厳密なのに、読み物としては驚くほどスッと頭に入る記事」が干渉ゼロで出力できるようになります。
手元のMacで今すぐ再現する現実解と推奨環境
商用AIの重み制限を超える段階的開示と台帳
ここまで読んで、「仕組みは完璧に納得できたけれど、普段使っている Gemini 4 Argon や Claude などの商用クラウド AI は、セキュリティ上ユーザーがサーバー上の重み(LoRA)を直接書き換えられないよね? 手元の環境ではどうやって活かせばいいの?」と感じた方も多いはずです。
ここが実務で一番おいしいポイントなのですが、実は クラウド最上位モデルの重みを直接いじれなくても、先ほどの「4 階層ハイブリッド設計」の恩恵は今日から手元の Mac 上でほぼそのまま再現できます。
| 理想の睡眠学習コンポーネント | ローカルLLM実験での実装 | 商用最上位AI(Gemini 4 Argon等)での実践再現 |
|---|---|---|
| 第4層:常時働く原則 + 土地勘ポインタ | 分野別 LoRA ファイル(lora_core 等) | 20,000 トークン予算内に凝縮した基本ルール(GEMINI.md)+ 段階的開示ルーティング |
| 第3層:1ビット無劣化の厳密台帳 | SQLite(brain_specs + history) | 手元 Mac の SQLite(条件付き UPSERT + トリガー退避 + FTS5 ミリ秒検索 CLI) |
| 第2層:当日の思考・計画共有 | /brain フォルダ | RAMDisk 上の /brain + 完了分 SSD 自動退避スクリプト |
| 推論エンジン本体 | 27B クラスのローカルモデル | クラウド最上位モデル(Gemini 4 Argon 等)の圧倒的推論力 |
つまり、中途半端な小型ローカル AI に重い推論まで無理をさせるのではなく、「推論そのものはクラウドの最上位頭脳(Gemini 4 Argon 等)に任せつつ、手元の Mac に『コンパクトな土地勘ルール(LoRA 相当)』と『2 層分離 SQLite 台帳』を置いて CLI で 0.01 秒応答させる」 のが、現時点で最もハルシネーションが少なく開発速度も速い現実解なのです。もちろん、手元に余裕ある Apple Silicon 環境があれば MLX 等で本当に夜間 LoRA 蒸留の実験を回すこともできます。
余裕ある64GBメモリと高速SSDの快適コスト
この「RAMDisk 上の /brain 運用 + SQLite のメモリマップ(mmap)常駐 + AI エディタとブラウザの並列稼働」をスワップ(SSD への仮想メモリ退避)ゼロで毎日気持ちよく回し切るには、手元の母艦 Mac に 64GB クラスのメモリ と 信頼できる高速外付け SSD(アーカイブ・Time Machine 用) を揃えておくのが長く快適に使える分岐点になります。
仮に 64GB ユニファイドメモリ構成の Mac mini(約 25 万〜 30 万円前後と仮定した推論試算)を 5 年間(1,825 日)毎日相棒として使い倒した場合、1 日あたりの快適コストは約 137 円〜 164 円(推論) と缶コーヒー 1 本分ほどに収まります。また、大画面 27 インチ 5K 液晶とコスパを重視して中古の Intel 最終世代 iMac(2020 年モデル)を選び、背面の扉から自分で Crucial 製 DDR4 メモリを 64GB へ増設するルートなら、さらに初期費用を大きく抑えて広大な作業机と RAMDisk 環境を構築できます。
まとめ:朝の30秒承認と構築用プロンプト
最後に、この自動記憶システムを 100% 安心して運用するための仕上げが 「朝の 30 秒プルリクエスト(差分承認)」 です。AI が夜間にブラックボックスのまま勝手に記憶を書き換えてしまう不安をなくすため、翌朝一番に「昨晩破棄したノイズ件数」「SQLite で更新された設定値の変更前後(Diff)」「新しく定着させた原則ルール」のサマリーを表示させ、もし意図と違う解釈があればワンクリックで brain_specs_history と前日スナップショットから 1 秒でロールバックできるようにしておけば、信頼性は完璧になります。
-
確率的な直感と決定論的な台帳を混ぜない : 1 文字変わると壊れるパス・数値・日付・ボツ案の理由は無劣化の SQLite へ隔離し、脳側(LoRA や常時ルール)には「思考原則」と 「SQLite のどこを引くかという土地勘ポインタ」 だけを持たせます。
-
SQLite は「最新+履歴」の 2 テーブル分離+トリガーで守る : 単一テーブルのフラグ管理は AI の
WHERE付け忘れ事故を招きます。BEFORE UPDATEトリガーとIS NOT条件付き UPSERT で最新表を常にクリーンな 1 件に保ちます。 -
複数分野の記憶は分けて育て、層とトークンで切り替える : 開発・ブログ・日常の知識を 1 つに混ぜず、
O-LoRA(直交学習)やMoLE(中間層=論理、最終層=表現)のように役割分担させることで干渉を防ぎます。 -
マスターデータを手元に残せば世代交代も怖くない : 精査済みの SQLite 台帳と学習プールが手元にあれば、将来どんな次世代 AI が登場しても一晩で記憶を丸ごと引っ越しできます。
手元のプロジェクトや AI エディタ環境に、今回解説した 「最新・履歴 2 層分離 SQLite(条件付き UPSERT + BEFORE UPDATE トリガー)+ 3 段階仕分けスクリプト + 土地勘ポインタ連携」 を自分のフォルダ構成に合わせて安全に組み込みたい方は、以下のプロンプトをコピーして AI エディタへ貼り付けてみてください。
※既存ルールファイルの整理や SQLite トリガー・UPSERT スクリプトの設計はプロジェクト全体の整合性に直結するため、安全ルールを読み飛ばしやすい軽量モデルではなく、必ず『Gemini 4 Argon』(または同等以上の最上位推論モデル)を選択した状態 で実行してください。
以下の技術記事の設計思想(3段階判定ゲート、brain_specs / brain_specs_history の2テーブル物理分離+BEFORE UPDATEトリガー退避+IS NOT条件付きUPSERT、既存キー辞書による表記揺れ防止、および常時ルールへの『SQLiteの土地勘ポインタ』登録)を参考に、私の現在のワークスペースに最適な長期記憶・仕様台帳システムを導入したいです。
参照記事: https://lab.chihouzakki.com/blog/review/ai-sleep-learning-sqlite-upsert-multi-lora-architecture/
いきなりファイルを書き換えたり作成したりせず、まずは現在のディレクトリ構成・既存のルールファイル・Node.jsやPythonの実行環境を調査(Readのみ)してください。
その上で、①どこにSQLiteファイルと検索・更新CLIを置くか、②どの厳密値をSQLite台帳へ逃がし、常時ルール側にどんな『土地勘ポインタ』を残すか、③朝の差分確認(ロールバック手順含む)をどう行うかの実装計画を日本語で提示し、私の合意を得てから実装に進んでください。 昼間は目の前の作業に 100% 集中し、寝ている間に AI が記憶を綺麗に整理整頓して翌朝スッキリ待っていてくれる——そんな頼もしい相棒環境を、ぜひできるところから育ててみてくださいね!

▲ ぐっすり睡眠学習して、「ちゅ〜るの隠し場所テーブル」を大脳皮質に焼き付け中でち…zzz