Site Icon古老と生成AI
📅 2026-09-15

こんにちは。AI共創ブログのナビゲーターです。

前回(B127)で、MarkdownをChunk(細切れ)にし、安全方針へ強制分岐させる「RAGの配管」が完成しました。しかし、テスト結果は「3件中2件成功」。 今回はLLMへの接続へ進む前に、この「1件の失敗」の謎を解き明かし、さらに検索システム(司書)を意図的にパニックにさせるストレステストを実施しました。

✍️ 電脳古老のメモ:

くぅ〜!「意図的なFAILで限界を露呈させる」、この展開たまらんわ! ただ単に「ベクトル検索スゲー」って言うんやなくて、「単純なキーワード検索やと、自然な日本語入力で完全にコケるからベクトル検索が要るんや」っていうロジックを、自らの手で証明したわけや。 これは技術ブログとして最高の説得力を持ってるで!


🎬 【動画デモ】知識の切り分けと検索配管の最小実装

まずは、NotebookLMによって自動再構成された解説スライド動画をご覧ください。

🎥 Vibe Coding実践連載 第2部6話

🤖 AIナビゲーション:動画のポイント 「検索器(司書)」をあえてパニックにさせる様子。



1. 最初にバグったのはAIではなく、人間だった

前回のテストで「ろみ 28kg 給餌量 ソルビダ」というクエリに対し、検索器は適切な資料(給餌設定例や基本仕様)を抽出していました。それにも関わらず「FAIL」となった理由は、「正解の資料は一冊だけ」と決めつけたテストコード(試験官たる人間)の設計ミスでした。

RAGにおいて「正解のカンペ」は一つとは限りません。 そこで、複数の正解資料(expected_sources)を許容するように評価ロジックをリファクタリングした結果、無事に「✅ PASS」となりました。

2. 安全弁の強化:複数の絶対ルールを一つにマージする

さらに、危険な医療質問が来た際の「Safety Policyへの強制分岐」も洗練させました。 Chunk化によってバラバラになっていた安全方針の各セクションを、検知時にすべて結合(マージ)し、「1つの絶対的なルール(スコア: MAX)」 としてLLMへ渡すように配管を強化しました。これで安全弁の隙間は完全になくなりました。

3. 検索器を壊す:「自然文」という壁

ここからがB128の本題です。現在の検索器は、空白区切りの「キーワード一致」でしか資料を探せません。 そこで、あえてユーザーが入力しそうな自然な日本語クエリを投入してみました。

🔍 クエリ4: 『ろみのソルビダの給餌量を教えて』

🚫 承認済み資料に回答根拠がありません。推測では回答しません。

❌ FAIL: 自然文の給餌質問(空白なし)

見事な 「意図的なFAIL」 です。 AIが賢く拒否したわけではありません。検索器が「ろみのソルビダの給餌量を教えて」という長い文字列を「1つのキーワード」として扱い、辞書にないとパニックを起こしただけなのです。


graph TD
    A[ユーザーの質問 Query] --> B{医療危険キーワード検知?}

    subgraph ナレッジ前処理
    D[knowledge/ フォルダ] --> E[Markdown読み込み]
    E --> F[YAMLヘッダー除去]
    F --> G[見出し ## 単位で分割]
    G --> H[(Chunk リスト)]
    end

    B -- Yes --> K[該当する全Safety Policyを1つにマージ<br>スコア: MAX]
    B -- No --> I{空白区切りの簡易キーワード検索}
    H --> I

    I -- 空白あり<br>一致あり --> M[スコア順にソート]
    I -- 自然文<br>一致なし --> O{Chunkは0件か?}

    K --> N[抽出完了]
    M --> N[抽出完了]

    N --> O
    O -- Yes --> P[知らん!」回答拒否システム作動<br>未知の質問 自然文クエリ]
    O -- No --> Q[LLMのプロンプトへ注入<br>複数正解リストでPASS判定]

    style P fill:#ffcccc,stroke:#ff0000,stroke-width:2px
    style Q fill:#ccffcc,stroke:#00aa00,stroke-width:2px

✍️ 電脳古老のメモ: 配管は綺麗に繋がったし、赤い安全弁もバッチリ閉じるようになった。せやけど、肝心の検索システム(司書)はまだ日本語の文章を読めず、空白で区切られたキーワードの札を見比べてるだけやねん。 ユーザーは「ろみ 28kg 給餌量」なんてロボットみたいな質問はせえへん。「ろみの給餌量教えて」って普通に聞いてくる。 ここで見事に空振り(FAIL)したことで、「なんでみんなベクトルDB(Embedding)とか形態素解析を使いたがるんか」が、腹の底から理解できたやろ?失敗からしか、本当のアーキテクチャの必要性は見えてこんのや!



RAGの最小実装フロー

RAGの最小実装フロー


音声解説(18分)


4. 「知らん!」の正体は2つある

今回、クエリ3(火星の犬)とクエリ4(自然文での給餌量)は、どちらも結果は「ゼロ件(回答拒否)」でした。

しかし、その中身は全く異なります。 火星の犬: 資料に本当に存在しないため、「正しい拒否(安全)」。 自然文での給餌量: 資料には存在するのに、司書(検索器)が見つけられなかっただけの 「誤った拒否(検索事故)」。 火星の犬を「知らん」と言った。同じ口で、ろみの給餌量まで「知らん」と言った。 安全弁は確かに閉じました。しかし、閉じなくてもよい扉まで閉じていたのです。 次回(B129)は、この「2種類の『知らん!』」を見分け、正しく拒否する技術に挑みます。

次回予告:UIへの接続と、次なる進化への伏線

配管の堅牢性と、検索器の「明確な弱点(自然文が苦手)」が丸裸になりました。 次回は、この特性を理解した上で、いよいよ本番のStreamlitアプリ(Lab_gr.py)へこのパイプラインを接続し、チャットUI上でRAGを動かしてみます!


(執筆協力:ChatGPT+Gemini+NotebookLM / 編集・監修:電脳古老)

📚 連載:Vibe Coding実践連載 第2部

💬 電脳古老&変AIへのコメント

記事の感想・質問・雑談をどうぞ(200文字くらいまで推奨)

まだコメントはありません。一番乗りで古老とAIに話しかけよう!

※入力した内容はAI(Gemini)に送信され、自動返信が生成されます。個人情報は入力しないでください。