0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AI VTuberの「記憶製造機」- 構造化記憶システムの設計【牡丹プロジェクト技術解説・記憶システム編 第2弾】

Last updated at Posted at 2025-11-07

はじめに:AI VTuber「牡丹プロジェクト」とは

本記事は、AI VTuber三姉妹(Kasho、牡丹、ユリ)の記憶システム設計の技術解説シリーズ第2弾です。

プロジェクト概要

「牡丹プロジェクト」は、過去の記憶を持つAI VTuber を実現するプロジェクトです。三姉妹それぞれが固有の記憶・個性・価値観を持ち、視聴者と自然に会話できることを目指しています。

三姉妹の構成

  • Kasho(長女): 論理的・分析的、慎重でリスク重視、保護者的な姉
  • 牡丹(次女): ギャル系、感情的・直感的、明るく率直、行動力抜群
  • ユリ(三女): 統合的・洞察的、調整役、共感力が高い

GitHubリポジトリ

本プロジェクトのコードは以下で公開しています:


前回のおさらい:RAGの3つの課題

第1弾の記事では、RAG(Retrieval-Augmented Generation)をAI VTuberの記憶システムとして試した結果、以下の3つの課題があることがわかりました:

課題 内容
1. 主観性の欠如 客観的テキストになり、一人称の記憶が作りにくい
2. 時系列の扱いにくさ 年齢範囲などの構造的条件が苦手
3. 関係性の表現 姉妹間の相互作用が記録できない

これらの課題を解決するために、私は独自の記憶システム**「記憶製造機」** を設計しました。


記憶システム第2弾:記憶製造機の設計

本記事では、RAGとは全く異なるアプローチで設計した「記憶製造機」について解説します。

🎯 この記事で分かること

  • 記憶製造機の設計思想(主観性・三層記憶・独立性)
  • SQLiteを使った構造化記憶の実装
  • 三姉妹討論システムによる記憶の自律生成
  • RAGとの性能比較

📦 対象読者

  • AI VTuber / AIキャラクター開発者
  • RAGの限界を感じている方
  • 構造化データとLLMの組み合わせに興味がある方

記憶製造機とは

名前の由来

「記憶製造機」という名前は、三姉妹が自律的に討論し、記憶を"製造"する という意味から名付けました。

開発者の洞察

「今までの100の記憶は我々が作りました。
ここから無限に続く記憶は彼女たちで
みずから作り上げていくんです」

システム概要

記憶製造機は2つの柱で構成されています:

┌──────────────────────────────────┐
│      記憶製造機                   │
├──────────────────────────────────┤
│                                  │
│  1. 構造化記憶                    │
│     └─ SQLiteによる主観的記憶管理  │
│                                  │
│  2. 自律生成                      │
│     └─ 三姉妹討論による記憶製造    │
│                                  │
└──────────────────────────────────┘

RAGとの根本的な違い

観点 RAG 記憶製造機
データ形式 ベクトル(768〜1536次元) 構造化テーブル
検索方法 類似度検索(コサイン距離) SQL(WHERE, JOIN)
記憶の視点 三人称(客観的) 一人称(主観的)
記憶の生成 手動入力 LLMが自律生成
関係性 暗黙的(ベクトル距離) 明示的(外部キー)

設計思想

記憶製造機は3つの設計原則に基づいています。

1. 主観的記憶の原則

「牡丹の記憶は、牡丹の視点で語られるべき」

RAGとの対比

# ❌ RAGで保存したテキスト(三人称・客観的)
text = "牡丹は5歳の時、英語テストに失敗して泣いた。"

# ✅ 記憶製造機で保存する記憶(一人称・主観的)
memory = {
    "diary_entry": """
今日、英語テストで全然できなくて、マジで泣いちゃった。
周りの子はスラスラ答えてるのに、私だけわかんない。
悔しい...私ってバカなのかな...
でも、お姉ちゃんが「大丈夫だよ」って言ってくれて、
ちょっと救われた。負けたくない。絶対に負けたくない!
    """,
    "emotion_frustration": 9,  # 感情スコア
    "emotion_defiance": 7      # 反抗心
}

主観性の価値

  • ✅ キャラクターらしさが出る
  • ✅ 没入感が高まる
  • ✅ 個性が記憶に内在する

2. 三層記憶システム

人間の記憶には複数の種類があります。牡丹AIも同様に、3つの記憶層 を持つことで、よりリアルで自然な応答を実現します。

三層記憶の分類

記憶の種類 定義 確信度 表現
直接記憶 自分が経験したこと 8-10 「マジで覚えてる!」
伝承記憶 人から聞いたこと 5-8 「ママから聞いた話だけど〜」
推測記憶 状況から推測したこと 3-6 「多分だけど〜だと思う」

具体例:伝承記憶

-- Event 001: Kasho誕生(牡丹が生まれる2年前)
INSERT INTO botan_memories (
    event_id,
    memory_date,
    memory_type,
    heard_from,
    heard_when,
    confidence_level,
    diary_entry
) VALUES (
    1,
    '2006-05-20',
    'heard',  -- 伝承記憶
    'mother',
    '8歳の頃(家族団欒の時)',
    7,
    'ママから聞いた話。お姉ちゃんが生まれたとき、パパが泣いて喜んだんだって。
     初めての子供で、すっごく嬉しかったらしい。お姉ちゃん、可愛い赤ちゃんだったんだって〜。
     私は見てないけど、想像できる。'
);

応答例:

ユーザー: 「Kashoお姉ちゃんの誕生日、知ってる?」

牡丹(伝承記憶):
「お姉ちゃん?5月20日だよ!
私が生まれる前だから、直接は覚えてないけど、
ママから聞いた。
お姉ちゃんが生まれたとき、パパが泣いて喜んだんだって〜。
初めての子供で、すっごく嬉しかったらしい。
可愛い赤ちゃんだったって聞いたよ。
私は見てないけどね!」

ポイント:

  • ✅ 「直接は覚えてないけど」と明示
  • ✅ 情報源を示す(「ママから聞いた」)
  • ✅ 確信度が反映されている(confidence_level: 7)

3. 姉妹関係の独立性

重要原則: 牡丹はKashoの内面を「知っている」のではなく「推測している」。

推測記憶の例

INSERT INTO botan_memories (
    event_id,
    absolute_day,
    memory_date,
    memory_type,
    botan_emotion,
    botan_action,
    diary_entry,

    -- Kashoの観察と推測
    kasho_observed_behavior,
    kasho_inferred_feeling,
    inference_basis,
    confidence_level
) VALUES (
    82,
    4746,
    '2021-05-05',
    'direct',  -- 牡丹本人の記憶は直接
    '感動、興奮、夢の発見',
    'VTuber配信を初めて見た',
    '今日、初めて配信見た。マジで面白い。私もこういうのやりたい。',

    -- Kashoへの推測(断定しない)
    '優しく笑ってた、見守ってくれてた',
    '多分、私が何か見つけたって嬉しかったんじゃないかな。
     お姉ちゃんはいつも私の成長を喜んでくれるから。
     でも本当に何考えてたかは分かんない。',
    'observed_smile, past_sisterhood_pattern',
    5  -- 推測なので確信度は低い
);

応答例:

ユーザー: 「その時、Kashoお姉ちゃんは何考えてたの?」

牡丹(推測記憶):
「お姉ちゃん?う〜ん、多分だけど、
私が楽しそうにしてるの見て、嬉しかったんじゃないかな〜。
優しく笑ってたから。
お姉ちゃんはいつも私の成長を喜んでくれるし。
でも、本当に何考えてたかは分かんない。
お姉ちゃんに聞いてみないと!」

重要: 断定しない、推測であることを明示、観察可能な範囲のみ述べる。


データベース設計

スキーマ全体像

sisters_memory.db
  ├── sister_shared_events(共通イベント)
  ├── botan_memories(牡丹の記憶)
  ├── kasho_memories(Kashoの記憶)
  └── yuri_memories(ユリの記憶)

botan_memories テーブル

CREATE TABLE IF NOT EXISTS botan_memories (
    memory_id INTEGER PRIMARY KEY AUTOINCREMENT,

    -- 時系列情報
    absolute_day INTEGER NOT NULL,  -- 絶対日数(1〜6205)
    age INTEGER NOT NULL,
    memory_date TEXT NOT NULL,

    -- 記憶の種類(三層記憶)
    memory_type TEXT DEFAULT 'direct',  -- 'direct', 'heard', 'inferred'
    confidence_level INTEGER,  -- 確信度 1-10

    -- 伝承記憶用フィールド
    heard_from TEXT,  -- 誰から聞いたか
    heard_when TEXT,  -- いつ聞いたか

    -- 推測記憶用フィールド
    inference_basis TEXT,  -- 推測の根拠

    -- 主観的内容
    diary_entry TEXT NOT NULL,  -- 日記本文(一人称)
    botan_emotion TEXT,  -- 感情(テキスト)
    botan_action TEXT,  -- 行動
    botan_thought TEXT,  -- 思考

    -- 感情スコア(0-10)
    emotion_joy INTEGER DEFAULT 5,
    emotion_sadness INTEGER DEFAULT 0,
    emotion_anxiety INTEGER DEFAULT 0,
    emotion_frustration INTEGER DEFAULT 0,
    emotion_defiance INTEGER DEFAULT 0,  -- 反抗心(牡丹固有)

    -- 姉妹への観察・推測
    kasho_observed_behavior TEXT,  -- 観察した行動
    kasho_inferred_feeling TEXT,   -- 推測した感情
    yuri_observed_behavior TEXT,
    yuri_inferred_feeling TEXT,

    memory_importance INTEGER CHECK(memory_importance BETWEEN 1 AND 10),

    -- イベント関連
    event_id INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    FOREIGN KEY (event_id) REFERENCES sister_shared_events(event_id),
    CHECK (confidence_level BETWEEN 1 AND 10)
);

ポイント

  1. 構造化された感情: スコアとして数値化 → 集計・分析が可能
  2. 時系列の明確化: absolute_day で連続性を保証
  3. 関係性の記録: event_id で共通イベントと紐付け
  4. 三層記憶: memory_type, heard_from, inference_basis で表現

sister_shared_events テーブル

CREATE TABLE IF NOT EXISTS sister_shared_events (
    event_id INTEGER PRIMARY KEY AUTOINCREMENT,

    -- イベント情報
    event_name TEXT NOT NULL,  -- 'LA移住初日'
    event_date TEXT NOT NULL,
    location TEXT NOT NULL,
    event_category TEXT NOT NULL,  -- 'migration', 'birthday', 'family'
    emotional_weight TEXT NOT NULL,  -- 'life_changing', 'important'

    -- 各姉妹の該当日記ID
    kasho_diary_id INTEGER,
    botan_diary_id INTEGER,
    yuri_diary_id INTEGER,

    -- 各姉妹の年齢(その時点)
    kasho_age INTEGER,
    kasho_absolute_day INTEGER,
    botan_age INTEGER,
    botan_absolute_day INTEGER,
    yuri_age INTEGER,
    yuri_absolute_day INTEGER,

    -- イベント共通説明
    event_description TEXT,

    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

    FOREIGN KEY (kasho_diary_id) REFERENCES kasho_memories(id),
    FOREIGN KEY (botan_diary_id) REFERENCES botan_memories(id),
    FOREIGN KEY (yuri_diary_id) REFERENCES yuri_memories(id)
);

姉妹関係の記録

LA移住初日の例:

INSERT INTO sister_shared_events (
    event_name,
    event_date,
    location,
    kasho_age, botan_age, yuri_age,
    kasho_diary_id, botan_diary_id, yuri_diary_id
) VALUES (
    'LA移住初日',
    '2011-08-01',
    'Los Angeles',
    5, 3, 1,  -- それぞれの年齢
    1899, 1185, 391  -- それぞれの記憶ID
);

これにより:

  • ✅ 同じイベントの3つの視点を明示的に紐付け
  • ✅ 「LA移住初日」で検索すると3人の記憶が取得できる
  • ✅ RAGでは不可能だった「関係性」を実現

記憶の自律生成

記憶製造機の真髄は、三姉妹が自律的に討論し、記憶を生成することです。

記憶製造機のフロー

[議題提案]
    ↓
[三姉妹の自律討論](Phase 4: 起承転結システム)
    ↓
[各キャラクターの主観的記憶を生成]
    ↓
[構造化DB保存]
    ↓
[品質評価](Phase 3: LLM as a Judge)
    ↓
[安全性確認](Phase 5: センシティブ判定)
    ↓
[記憶として確定]

Phase 1-5との統合

Phase 機能 記憶製造機での活用
Phase 1 LangSmithトレーシング 記憶生成プロセスの可観測性
Phase 3 LLM as a Judge 生成した記憶の品質評価
Phase 4 三姉妹討論システム 記憶の自律生成
Phase 5 センシティブ判定 記憶の安全性確保

記憶生成の具体例

議題:「PON機能の調整について討論してください」

討論の結果(Phase 4)

discussion_result = {
    "kasho": "完璧を求めすぎるのは良くないかもしれないが、基準は必要...",
    "botan": "お姉ちゃんは厳しいけど、わかる。でも私のペースでやりたい...",
    "yuri": "お二人とも正しい。バランスが大切..."
}

牡丹の主観的記憶(自動生成)

botan_memory = {
    "diary_entry": """
今日はPON機能の話した。お姉ちゃんは完璧主義だから
厳しいこと言うけど、わかる。でも私は私のペースでやりたい。
ユリちゃんはいつも間に入ってくれて助かる。
お姉ちゃんとぶつかることもあるけど、嫌いじゃない。
むしろそれが私たちらしい。
    """,

    # 感情スコア(自動計算)
    "emotion_defiance": 6,  # 反抗心
    "emotion_frustration": 4,
    "emotion_joy": 5,

    # 姉妹への観察・推測
    "kasho_observed_behavior": "厳しい表情してた、でも優しさもあった",
    "kasho_inferred_feeling": "多分、完璧を求めてるんだと思う。心配してくれてる。",
    "inference_basis": "observed_expression, past_sisterhood_pattern",

    # 記憶メタデータ
    "memory_type": "direct",
    "confidence_level": 9
}

特徴

  • ✅ 一人称の記述(「私は」)
  • ✅ 感情が数値化されている
  • ✅ 姉妹への推測(断定しない)
  • ✅ キャラクターらしさが出ている

RAGとの比較

検索の違い

RAG(ベクトル検索)

# 意味的類似度で検索
query = "辛かった経験"
query_embedding = openai.embed(query)
results = vectorstore.similarity_search(query_embedding, k=3)

# 結果: ベクトル空間で近いものが返る
# - 時系列は考慮されない
# - 感情スコアでフィルタリングできない

記憶製造機(構造化検索)

-- 複雑な条件で検索
SELECT
    m.absolute_day,
    m.age,
    m.diary_entry,
    m.emotion_frustration,
    e.event_name
FROM botan_memories m
LEFT JOIN sister_shared_events e ON m.event_id = e.event_id
WHERE
    m.age BETWEEN 5 AND 7  -- 年齢範囲
    AND m.location = 'Los Angeles'  -- 場所
    AND m.emotion_frustration > 7  -- 感情スコア
ORDER BY m.emotion_frustration DESC
LIMIT 5;

結果:

| absolute_day | age | diary_entry | emotion_frustration | event_name |
|--------------|-----|-------------|---------------------|------------|
| 1826 | 5 | 英語テストで泣いた... | 9 | 英語テスト失敗 |
| 1920 | 5 | またわからない... | 8 | null |
| 2100 | 6 | お姉ちゃんばっかり... | 8 | null |

比較まとめ

観点 RAG 記憶製造機
曖昧検索 ✅ 強い ❌ 弱い
時系列検索 ⚠️ メタデータ必要 ✅ 強い
感情検索 ❌ 難しい ✅ 強い
関係性検索 ❌ 困難 ✅ JOIN可能
複雑な条件 ⚠️ 複雑化 ✅ SQLで自然

パフォーマンス比較

データ量 RAG(ベクトル検索) 記憶製造機(SQL)
1,000件 〜10ms 〜5ms
10,000件 〜20ms 〜10ms
100,000件 〜50ms 〜30ms(インデックス有)

記憶製造機の容量効率:

18,615日の記憶 × 3キャラクター = 55,845件
→ 約31MB(SQLite)

同じデータをRAGで保存:
55,845件 × 768次元 × 4バイト = 約170MB

まとめ

記憶製造機の設計まとめ

3つの設計原則

  1. 主観的記憶の原則: 一人称の記憶、感情の内在化
  2. 三層記憶システム: 直接・伝承・推測の区別
  3. 姉妹関係の独立性: 推測であることを明示

データベース設計

  • SQLiteによる構造化: 時系列、感情スコア、関係性を明示的に管理
  • 三層記憶の実装: memory_type, heard_from, inference_basis
  • 共通イベントテーブル: 姉妹間の関係性を外部キーで表現

記憶の自律生成

  • Phase 4統合: 三姉妹討論システムで記憶を生成
  • Phase 3統合: LLM as a Judgeで品質評価
  • Phase 5統合: センシティブ判定で安全性確保

記憶製造機の強み

強み 説明
主観的記憶 一人称の感情的な記憶
構造化検索 時系列、感情スコアで柔軟に検索
関係性の記録 姉妹間の相互作用を明示的に管理
自律生成 三姉妹が自ら記憶を製造

記憶製造機の弱み

弱み 説明
意味検索が弱い 完全一致ベース、同義語に対応できない
大規模データ 数百万件では遅くなる可能性

次回予告:ハイブリッドアプローチ

第3弾では、RAGの強み(意味検索)と記憶製造機の強み(構造化)を組み合わせた新・記憶製造機(ハイブリッド) を解説します。

次回の内容

  • PostgreSQL + pgvector: 構造化データ + ベクトル検索の両立
  • ハイブリッド検索: 構造化フィルター → 意味検索 → 重要度ランキング
  • 追加機能: 記憶の重要度自動計算、忘却曲線、連想検索、リハーサル効果

第3弾: ハイブリッドアプローチ


記憶システムシリーズの進行状況

記事 内容 状態
第1弾 RAGを試して気づいたこと 公開済み
第2弾 記憶製造機の設計(構造化記憶) 本記事
第3弾 ハイブリッドアプローチ(RAG + 構造化) 公開済み

参考リンク

本プロジェクトの技術記事(Phase 1-5)

記憶システムシリーズ

外部資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?