構想から実装まで4日!GeminiとThree.jsで社員の「1年の思い出」を銀河にしてみた
2026年を迎え、寒さが厳しい毎日ですが、新しい年が始まると気持ちも新たになります。 そんな新年の始まりですが、今回は少し時計の針を戻して、昨年末の社内イベントで行った「ある実験」についてお話ししたいと思います。
昨年末、社内にて社員参加型のインタラクティブな企画「NDD Galaxy 2025」を実施しました。 今回は、この企画の裏側にある技術的な仕組み、特にGoogle Gemini APIを用いたEmbedding(ベクトル化)の活用と、AIコーディングによる爆速開発について解説します。
なぜ作ったのか?:RAGの裏側を「見る」体験
昨今の生成AIブームにおいて、「RAG(Retrieval-Augmented Generation:検索拡張生成)」という言葉を耳にする機会が増えました。 RAGは、AIが外部知識を参照して回答を生成する技術ですが、その検索精度を支えているのが「Embedding(埋め込み表現)」による「多次元ベクトル」です。
しかし、「言葉をベクトル(数値の羅列)に変換して、空間的な距離で意味を計算する」と言われても、直感的にイメージするのは難しいものです。 そこで、この「普段は見えない計算処理」をあえて3D空間に可視化することで、社員が楽しみながら技術的な仕組みを知るきっかけを作りたいと考え、このアプリを企画しました。
「NDD Galaxy 2025」とは?
社員の皆様に「2025年のハイライト(思い出)」を投稿してもらい、そのテキストデータを生成AIで解析。ブラウザ上の3D空間に、無数の星々からなる「銀河」として配置するアプリです。
単にランダムに配置するのではなく、投稿の内容(意味)によって星の配置が決まるというのが最大の特徴です。

技術スタック
今回のシステムは、すべてGoogle Cloud上で構築しました。
- AIモデル: Google Gemini API (
gemini-embedding-001, gemini-2.5-flash) - バックエンド: Python (Flask)
- フロントエンド: JavaScript, Three.js
- データベース: Firestore
- インフラ: Google Cloud Run (Docker)
どのようなロジックで「意味」を「座標」に変換しているか
このアプリケーションの肝は、「言葉の意味をどうやって3D空間の座標(X, Y, Z)に変換するか」です。 処理は大きく分けて、サーバーサイドでの「ベクトル化」と、フロントエンドでの「座標計算」の2段階で行われます。
1. すべてをベクトル化する
まず、投稿されたテキストをPython(Flask)で受け取り、GeminiのEmbeddingモデル(gemini-embedding-001)に通して、意味を数値の配列(ベクトル)に変換します。 同時に、空間の基準点となる「ガイド(キーワード)」も同様にベクトル化しておき、これらのベクトルデータを保存・フロントエンドへ配信します。
2. 「ガイド」による重力モデル
ブラウザ(Three.js)側では、サーバーから受け取ったベクトルデータを元に、リアルタイムで座標を計算して描画します。 3D空間上には、あらかじめ管理者が設定した「ガイド(例:『楽しい』『技術』『挑戦』などのキーワード)」を球状に配置します。
それぞれの投稿(星)について、ブラウザ上で以下の計算が行われます。
- 類似度の計算: 投稿のベクトルと、すべてのガイドのベクトルとの「コサイン類似度(意味の近さ)」を計算します。
- 位置の決定(Softmax): 類似度スコアをSoftmax関数にかけ、「どのガイドにどれくらい強く引き寄せられるか」という重みを算出します。
- 座標の確定: 各ガイドの座標を加重平均し、最終的な星の位置を決定します。
例えば、「楽しかったし、嬉しかった」という投稿があったとします。
- 「楽しい」ガイドとの類似度:高
- 「嬉しい」ガイドとの類似度:高
- 「悲しい」ガイドとの類似度:低
この場合、この投稿(星)は「楽しい」と「嬉しい」というガイドの中間地点付近に配置されます。

上記のイメージのように、意味的に関連の深いガイドに強く引っ張られて座標が決まるため、似たような意味を持つ投稿は自然と近くに集まり、意味のクラスタ(星団)を形成する仕組みになっています。
3. 星座線による可視化
ガイドとなるキーワードをクリックすると、その概念に近い星々が線で結ばれ、「星座」のように浮かび上がります。
2で計算したコサイン類似度により、近いものから線でつなぎ、近いものは二又に分かれたりというような演出をして、星座のように表示してみました。
これにより、「今年は『技術』に関する話題が多かったな」といった傾向を視覚的に把握できるようになっています。 一つのガイドから見たときに近い星でも、他のガイドに引っ張られると遠ざかってしまうことがありますが、こうして線を繋ぐことで「実は関連度が高かった星」を再発見できるのも面白いポイントです。

4. インタラクティブな探索機能
Three.jsの特性を活かし、空間はマウスやタッチ操作で自由に回転・ズームが可能です。 また、画面上のコントロールパネルで、表示する「ガイド」を自由に増減(ON/OFF)させることができます。
あるガイドを無効にすると、そこに集まっていた星たちが、次に近い意味を持つ別のガイドへと移動していきます。逆にガイドを追加すると、その意味に吸い寄せられるように星が再配置されます。 この、ガイドの増減によってダイナミックに星が移動する様子を通じて、「言葉の意味が持つ引力」を視覚的に体感できる演出としても機能しています。
開発期間4日!AIとペアプログラミングした裏話
実はこのアプリケーション、公開の1週間前にひらめき、実施決定から本番までわずか4日で実装しました。(※実質的な工数はさらに短いです)
これを可能にしたのが、Gemini CLIを活用したAIコーディングです。
- コードの生成: バックエンドのFlask構成からフロントエンドのロジックまで、ほぼ100%のコードをAIが生成・提案しています。
- 未知の技術への挑戦: 私自身、Three.js(3Dライブラリ)の実装経験はほぼありませんでした。通常ならドキュメントを読み込むだけで数日かかるところですが、AIに「こういう演出をしたい」と自然言語で指示を出し、出力されたコードを修正していくスタイルをとることで、爆発的なスピードで形にすることができました。
厳密な仕様書がないプロトタイピングや、今回のようなイベント用アプリにおいて、「完成度よりも速度」が求められる場面では、生成AIにフロントエンド実装を任せる手法は極めて有効だと改めて感じました。
まとめ
今回の企画では、テキスト情報が持つ「意味」を空間的な距離として表現することに挑戦しました。 視認性の調整など課題もありましたが、実際に動かしてみることで、AIが言葉をどう捉えているかがより直感的に理解できたと感じています。
今後も、生成AI技術をより身近に、そして理解して使えるようにしていきたいと思います!
















