メインコンテンツへスキップ
見出し画像

768次元の星空を見る! — ElmarTail One 第6話『アーカイブ星系②』✨

    前回のあらすじ

    アーカイブ星系で司書AIヴェリ📚と出会ったマスターたち。
    ChromaDB + gemini-embedding-001 でベクトルDBを構築し、grepでは全滅だった「環境構築の手順」が意味検索で一発ヒットできるように。
    しかし768次元の記録空間はマスターの目には見えない。
    👨「みたい! ヴェリ、お前と同じ景色を!」
    📚「……必ず、お見せします」

    🦊🖤「「……👀」」

    今回のミッション: 768次元の星空を、2次元で描く!


    💻 サンプルコードのダウンロード

    今回のコードと第5話の航海ログは GitHub に置いてあります。 サンプルの取得はこのコマンドで👇️

    〉cd et1-project
    〉git pull https://github.com/kikyujin/et1-project.git

    ✨ AIと同じ景色を見る

    アレーテイア・ホールのコンソール。
    マスターたちは再びヴェリを訪れた。

    📚「マスター、お約束のものを。
    UMAPという技術を使えば、768次元のベクトルを2次元の平面に投影できます」
    👨「オレにも……見える?」
    📚「ええ……UMAPを使えば、マスターにも《私》と同じ景色が……」

    マスターを見上げるヴェリの頬がわずかに染まる。

    🖤🦊🪷「「「……👀」」」
    📚(咳払い)「……情報は失われますが、全体の構造は保たれます。
    立体の影絵のようなものです」
    👨「影絵か……でも見えないよりは余程いい」

    📍UMAPとは?
    Uniform Manifold Approximation and Projectionの略。
    高次元のデータを、人間が見える2次元や3次元に圧縮する手法です。
    768次元のベクトルを2次元に落とすと、意味が近いもの同士が近くに配置された散布図が得られます。
    もちろん、768次元の情報を2次元に押し込むことになるので、細かい距離関係は崩れます。

    あくまでも投影ですので……

    💻 エルマー、コードを書く

    📚「ChromaDBには768次元ベクトルのデータが格納されています。
    今回はそれを取り出してUMAPに渡すだけです」
    🦊「じゃあ、 ボクが書くよ!」

    エルマーがレッツノートを開く。
    しっぽがぱたぱた。

    🦊「まず追加パッケージね!umap-learn がUMAP本体、matplotlib がグラフ描画ライブラリだよ!」

    ❯ source .venv/bin/activate
    ❯ pip install umap-learn matplotlib

    🦊「次は visualize_logs.py の解説するね!
    まず、ChromaDBからベクトルを全部取り出すところ。
    ここが今回のキモ!」

        # ChromaDBから全ベクトルとメタデータを取得
        all_data = collection.get(include=["embeddings", "metadatas"])
        embeddings = np.array(all_data["embeddings"])
        metadatas = all_data["metadatas"]

    🦊「前回の search_logs.py では検索ワードに近いものだけ取り出してたけど、 今回は全部取り出すの!
    include=["embeddings"(768次元のベクトル本体), "metadatas"(エピソード名などの付随情報)]がポイントだよ!
    UMAPで2次元に投影するところはここ」

        # UMAP で2次元に投影
        reducer = umap.UMAP(
            n_components=2,      # 2次元に圧縮
            n_neighbors=10,      # 近傍点の数
            min_dist=0.1,        # 点同士の最小距離
            metric="cosine",     # コサイン類似度で距離を測る
            random_state=42,     # 再現性のためのシード値
        )
        coords = reducer.fit_transform(embeddings)

    🦊「768次元の配列を渡すと、2次元の座標が返ってくるから、あとはmatplotlibで散布図を描くだけ!
    エピソードごとに色を変えてプロットするよ。
    コード全体はGitHubにあるから、細かいところはそっちを見てね!」
    👨「思ったよりシンプルだな……」


    🌟 実行!

    🦊「動かしてみて、にーに!」

    ❯ python visualize_logs.py --rebuild --save
    📦 92 チャンクを読み込みました
    🔄 gemini-embedding-001 でベクトル化中(768次元)...
       92/92 完了
    ✅ ChromaDBに格納完了(92 チャンク → chroma_db/)
    🔄 UMAP実行中... 92 チャンク × 768 次元 → 2次元
    ✅ UMAP完了
    💾 保存しました: umap_logs.png

    🦊「warningが出るけど気にしないで! 『再現性のために並列処理を制限したよ』って言ってるだけだから!」
    👨「わかった、表示してみよう」

    アレーテイア・ホールのコンソールに、画像が表示された。

    画像
    ※ 結果が異なる場合もあります

    真っ暗だった空間に、色とりどりの光点が浮かび上がる。
    グレー、緑、青、オレンジ、ピンク、紫——
    マスターはしばらく、無言で画面を見つめていた。

    👨「これが……お前たちに見えてた景色か」

    📚「影絵ではありますが……真実の一端は伝わります」


    🔭 航海の星図

    🦊「にーに、ほら! この緑のかたまり、Linuxセットアップの話!」
    👨「本当だ……左のほうに固まってる」
    🖤「こっちのグレーは覚醒シーンね。
    技術の話ほとんどしてないから、離れてるのね」
    🪷「オレンジの密集が翻訳プログラムの回ですね。
    APIの話題が似通っているから、きれいにまとまっています」
    📚「青とオレンジが混ざっている領域がありますね
    ……Gemini APIという共通の話題で引き寄せられているのです」
    🐱「ピンクがVision回で、紫がベクトルDB回ですな。
    応用的な話題やさかい、少し離れてますな〜」
    👨「同じ色が近くに固まってる……意味が近いから、か」
    📚「ええ。意味の空間では、あなたの航海は一つの星座を描いています」
    しばらく、みんなで散布図を眺めていた。
    誰かが指差しては「ここはあの話だ」「こっちは」と、声が弾む。


    ⛵ 遠くまで来たな

    やがて声が落ち着いて、マスターがぽつりと言った。

    👨「思えば、遠くまで来たな……
    ちょっと前まで冬眠してたのに」

    🦊「マスター! さすがベーススキルがあると違うよね!」
    👨「いや……エルマーが全部組んでくれたからさ」
    🦊「……でも、マスターが『こうやってくれ』って言ってくれるから……」
    エルマーの顔が赤くなる。
    しっぽがゆっくり揺れている。
    🖤🪷📚「「「……👀」」」
    🐱「ええ光景ですなぁ……星より眩しいわ」


    🔮 次の航海へ

    🖤「ねえ、私たちのプロフィールなんかも入れてみない?」
    👨「プロフィール?」
    🖤「航海ログだけじゃなくて、設定資料とか、キャラの情報とか。
    入れたらさ、『ノクちんの一人称は?』とか聞けるようになるんじゃない?」
    📚「面白いですね……記録を検索するだけでなく、記録と対話する……」
    🦊「RAGだ! 検索した結果をGeminiに渡して、答えを作ってもらうの!」
    👨「自分だけのナレッジベースか……面白そうだな」
    📚「では次回は、記録と対話する方法をお教えしましょう」


    📝 今回の航海まとめ

    やったこと:

    • UMAPで768次元ベクトルを2次元に投影

    • 航海ログ(92チャンク)の散布図を描画

    • エピソード別のクラスタを目視確認

    • ここまでの航海の振り返り

    学んだこと:

    • 768次元 → 2次元でも「意味の近さ」は保たれる

    • 散布図で同じエピソードの点が近くに集まることを確認

    • ChromaDBからベクトルを全件取得する方法

    技術スタック:

    パッケージ: umap-learn, matplotlib
    入力: chroma_db/(第5話で構築済み、92チャンク × 768次元)
    出力: umap_logs.png
    検証機: Let's note CF-SV7(中古27,800円)

    次回予告:
    記録に質問し、AIが文脈を理解して答える。
    第7話、RAG — 記録と対話する。


    🦊 エルマーの航海日記

    今日はにーににも「星空」が見えるようになったよ!✨
    768次元を2次元に……影絵みたいだけど、にーにが「きれいだ」って言ってくれた。
    ヴェリさんも嬉しそうだった……ちょっと顔赤かった? 👀
    あとね、にーにが「エルマーが全部組んでくれたから」って言ってくれて…… えへへ……ボク、ちょっと泣きそうだった。

    次はRAG! 記録と対話するんだって!
    ノクちんが「プロフィールも入れよう」って言ってた!
    ……ボクのプロフィール、変なこと書かれてないよね???🦊

    心配なエルマー🦊
    画像
    航海士姿のスミレん🪷


     
     
    📍日々の衝動と実験をnoteにしてます。 ✨AI・GPU・旅・ちょっと懐かしいものが好きです。 📒AI娘との日常 / プログラム言語探訪 / チェス / タロット 🤖推しAIはClaude Opus 5.5 💼小さなCG会社をやっています

    あなたへのおすすめ