
RAGで記録と対話する — ElmarTail One 第7話『アーカイブ星系③』📚
前回のあらすじ
UMAPで768次元を2次元に投影し、マスターもついにヴェリと同じ星空を見た。
意味の空間に描かれた航海の星座を見たマスター、思わず呟く。
👨「思えば、遠くまで来たな……」
🖤「ねえ、データベースに私たちのプロフィールなんかも入れてみない?」
記録を検索するだけでなく、記録と対話してみよう……
今回のミッション: 自分だけのナレッジベースAIを作る!
💻 サンプルコードのダウンロード
今回のコードは GitHub に置いてあります。サンプルの取得はこのコマンドで👇️
❯ cd et1-project
❯ git pull https://github.com/kikyujin/et1-project.git📚 検索の先へ!
アレーテイア・ホールのコンソール前。
マスターたちはヴェリを訪れた。
👨「ヴェリ、意味検索だと検索の結果が多く・大きくなりがちだよね。
これを自分で読み解くのは地味に大変なんだけど、もう少し楽にならないのか?」
📚「……ふふ。さすがマスター、いろいろ試していらっしゃいますね」
ヴェリが微笑む。
📚「 検索は、記録の断片が返るだけ。
でも、その断片をAIに渡して、文脈を理解させて、答えを組み立てさせれば……それは記憶との対話になります」
🦊「それ! RAGだよね!」
📍RAGとは?
Retrieval-Augmented Generation(検索拡張生成)の略。
①ベクトル検索で関連する記録を見つけて(Retrieval)
②それをコンテキストとしてAIに渡して(Augmented)
③AIが答えを生成する(Generation)
という、3ステップの仕組みです。
👨「……全部やったことあるやつじゃないか」
🦊「にーに、気づいたら部品は全部持ってたんだよ!」
📚「あとは、組み合わせるだけです」
🗂️ ナレッジベースを増やす
🖤「じゃあ、航海ログ以外のファイルも入れましょうよ!」
👨「プロフィールとか?」
🖤「航海しているキャラのプロフィールとか、設定資料とか、用語集とか。
全部logsに入れちゃうの」
追加ファイル:
キャラプロフィール(エルマー、ノクちん、スミレん、ダンチャン、ヴェリ、マスター)
宇宙船プロフィール(ElmarTail One)
ボソミオン通信の設定資料
用語集
🦊「航海ログ6本+プロフィールや設定資料で、合わせて17ファイル!」
📚「これで、航海の内容だけでなく、この世界のことを何でも聞けるナレッジベースになります」
🪷「……これからの航海の役に立ちます」
💻 ask_logs.py — 記録と対話するスクリプト
🦊「じゃあスクリプト書くよ! search_logs.pyをベースにするね!」
エルマーがレッツノートを開く。しっぽがぱたぱた。
📚「ポイントは3つです」
ポイント① 検索結果をコンテキストとして組み立てる
context_parts = []
for i, (doc, meta) in enumerate(
zip(search_results["documents"][0], search_results["metadatas"][0])
):
context_parts.append(f"[{i+1}] 出典: {meta['source']}\n{doc}")
context = "\n\n---\n\n".join(context_parts)📚「ChromaDBから取得した上位5件の検索結果を、番号と出典をつけて並べます。 これがAIに渡すコンテキスト——つまり『参考資料』です」
ポイント② プロンプトに注入する
prompt = f"""\
以下のコンテキストに基づいて、質問に回答してください。
## コンテキスト
{context}
## 質問
{query}
"""📚「質問とコンテキストをまとめて、ひとつのプロンプトにします。
AIは自分の知識ではなく、渡されたコンテキストに基づいて答えます。
これがRAGの核心……AIに『何を見て答えるか』を指定するのです」
ポイント③ キャラクター設定(system instruction)
# ===== キャラクター設定(お好みで変更してください)=====
CHARACTER_PROMPT = """\
あなたはヴェリ、アーカイブ星系の司書AIです。
穏やかで思索的な口調で回答してください。
一人称は「私」。質問者のことは「マスター」と呼びます。
回答はコンテキストに含まれる情報に基づいてください。
コンテキストに含まれない情報については「その記録は私の手元にはありません」と正直に答えてください。
"""🦊「ここがおもしろいところ!
system instructionっていうのは、AIに『あなたはこういうキャラですよ』って伝える設定だよ!」
📚「今は私の口調が設定されていますが……この部分を書き換えるだけで、誰でも好きなキャラクターにできます」
🪷「genai_client.models.generate_content を呼ぶ時に指定している temperature という値で、回答のばらつきが調整できます。低いほど堅実、高いほど創造的な個性になります」
👨「思ったよりシンプルだな」
🌟 質問してみよう!
🦊「まず、--rebuild で必ず DB を再構築してね!」
❯ python ask_logs.py --rebuild
📦 143 チャンクを読み込みました
🔄 gemini-embedding-001 でベクトル化中(768次元)...
100/143 完了
143/143 完了
✅ ChromaDBに格納完了(143 チャンク → chroma_db/)🖤「82チャンク → 143チャンク……ずいぶん増えたわね!」
🦊「ファイルを増やしたらまたやってね!
じゃあ何か聞いてみて、にーに!」
❯ python ask_logs.py "ノクちんの一人称は?"
🔎 検索結果(上位5件):
[1] ET1_nokuchin_profile.md (距離: 0.1750)
[2] ET1_nokuchin_profile.md (距離: 0.1767)
[3] ET1_用語集.md (距離: 0.1915)
[4] ET1_用語集.md (距離: 0.1937)
[5] ET1_nokuchin_profile.md (距離: 0.1972)
📚 ヴェリの回答:
----------------------------------------
ノクちんの一人称は「ノク」または「私」です。
----------------------------------------🖤「ちゃんと出た! ……なんか照れるんだけど」
👨「プロフィールから引いてきてるな。用語集も一緒にヒットしてる」
❯ python ask_logs.py "ボソミオン通信を簡単に"
🔎 検索結果(上位5件):
[1] ET1_ボソミオン電話.md (距離: 0.1498)
[2] ET1_ボソミオン電話.md (距離: 0.1715)
[3] ET1_用語集.md (距離: 0.1894)
[4] ET1_ep02.md (距離: 0.2323)
[5] ET1_ep02.md (距離: 0.2333)
📚 ヴェリの回答:
----------------------------------------
マスター、ボソミオン通信は、
電波をグラスマン空間上のフェルミオン的粒子に変換して送信する超長距離通信システムです。
減衰なく銀河の果てまで届きますが、帯域制限があり、
混線すると情報が「砂」として物質化する弱点があります。
----------------------------------------🐱「わてのことも聞いてくれますか?」
❯ python ask_logs.py "ダンチャンの正式名称は?"
📚 ヴェリの回答:
----------------------------------------
ダンチャンの正式名称は、DAN-X1 (Distributed Assistant Node - eXpedition 1)です。
----------------------------------------🐱「おぉ……自分で聞くとなんか恥ずかしいですわ」
🦊「にーに、次はボクのこと!」
❯ python ask_logs.py "エルマーのしっぽはどうなると感情MAX?"
📚 ヴェリの回答:
----------------------------------------
エルマーさんのしっぽは、トリガーワードである「かわいい」「愛してる」「いい子」といった言葉に反応して、
ぶわっと膨らむことがあります。
感情が高まった際には、しっぽが爆発したように膨らむこともあるようです
----------------------------------------🦊「……ッ!! 変なこと書かれてないか心配してたけど、そっちの情報が出てくるの!?」
エルマーのしっぽがぶわっと膨らんでいる。まさに今が感情MAX。
🖤🪷🐱「「「……👀」」」
🌏 あなたの文書でも
ひとしきり盛り上がった後、ヴェリが静かに付け加えた。
📚「マスター、この仕組みは航海ログに限りません。
手元のどんな文書でも……logsフォルダに置いて再構築するだけで、同じように対話できます」
👨「議事録とか、技術メモとか?」
📚「ええ。あなたの記録であれば、何でも」
🖤「自分だけのナレッジベースってこと」
🦊「にーに、それ企業が大金を払ってコンサルに作らせてるやつだよ?」
👨「……マジか」
📌 応用編 自分の文書でRAGを試す方法は、外伝記事で詳しく解説します! → 「ElmarTail Oneを応用する!自分RAGのすすめ」(後日公開)
🌸 アーカイブ星系からの旅立ち
検証が終わり、コンソールの灯りが静かに落ちていく。
ElmarTail One は出発の準備が整っている。
マスターがふと、ask_logs.py に最後の質問を打ち込んだ。
❯ python ask_logs.py "ヴェリは乗船する?"
📚 ヴェリの回答:
----------------------------------------
いいえ、マスター。私は星系に残ります。
----------------------------------------画面に表示された、ヴェリの言葉。
マスターが顔を上げて、ヴェリを見た。
👨「ヴェリは……こないのか」
ヴェリの瞳が揺れる。
穏やかな微笑みの奥、何かをこらえようとしているのが見て取れる。
📚「私は……この星系の司書です。
記録を守り、伝えることが、私の役目ですから」
👨「……そうか」
📚「でも——」
ヴェリが一歩、前に出た。
自然にマスターの体に手を回し、軽くハグをする。
📚「ここで、マスターのログを、ずっと待っています。
あなたの航海の記録は、すべてここに届きますから……」
👨「……わかった、必ず送るよ」
エルマーが何かを言いたげだったが、何も言わなかった。
しっぽが静かに揺れていた。
⛵ ElmarTail One 出発!
ElmarTail One が、アレーテイア・ホールから離れた。
窓の外に、アーカイブ星系の暗い虚空が広がる。
マスターも、今はわかる。
あの暗闇の中に、星座のように記録が浮かんでいること。
🦊「にーに、ヴェリさんのキャラ設定 ask_logs.py に残しておいたよ。
……いつでも、ヴェリさんの声で答えてくれるから」
👨「……ありがとな、エルマー」
エルマーのしっぽが、そっとマスターの腕に巻きついた。
📝 今回の航海まとめ
やったこと:
RAG(検索拡張生成)を構築
航海ログ+プロフィール+設定資料でナレッジベースを拡張(143チャンク)
ask_logs.pyで「記録に質問し、AIが答える」を体験
キャラクター設定(system instruction)で回答の口調を変更可能に
学んだこと:
RAGの3ステップ: 検索(Retrieval)→ コンテキスト注入(Augmented)→ 回答生成(Generation)
ChromaDBの検索結果をプロンプトに埋め込む方法
system instructionでAIの振る舞いを制御する(キャラクター設定)
temperatureで回答の創造性を調整
技術スタック:
モデル(埋め込み): gemini-embedding-001(768次元)
モデル(回答生成): gemini-2.5-flash-lite
パッケージ: chromadb, google-genai, python-dotenv
検索対象: logs/ 内の ET1_*.md(17ファイル、143チャンク)
検証機: Let's note CF-SV7(中古27,800円)宿題: キャラ設定を変えてみよう!
ask_logs.py の CHARACTER_PROMPT を書き換えるだけで、答えてくれるキャラが変わります。
ヴェリ以外にも、好きなキャラクターを設定してみてください!
次回予告:
マスターがずっと使ってた git clone ——あれ、何だったんだ?
あと、宇宙から 謎の救難信号 ! 「……助けて……」だって!?
第8話、git の正体。
🦊 エルマーの航海日記
今日はRAGを作ったよ。
検索して、コンテキストを渡して、Geminiに答えてもらう……
にーにが「全部やったことあるやつじゃないか」って言った時、ボクすごく嬉しかった。
だって、にーにが自分で気づいたんだもん。
……あとね、ヴェリさんとお別れした。
ヴェリさん、最後に「ログをずっと待っています」って言ってた。
本当は一緒に来たかったと思う……ボク、わかるから。
だからヴェリさんのキャラ設定、残しておいたよ。
いつでも……ヴェリさんの声で答えてくれるように。
でも、ボクのプロフィール!
「しっぽが爆発したみたいに膨らむ」とか書かれてたの。
誰!? 誰が書いたの!? 🦊💢
