Tech Blog

AIが自分と同じ設計思想に辿り着いていた話

RAG Gemini AI my-rag-brain CRAG

AIが自分と同じ設計思想に辿り着いていた話

1ヶ月ぶりに戻ってきた日

久しぶりにGeminiを開いた。

以前から気になっていたことがあった。質問の内容によって、Geminiが自信満々に間違いを言うことがあった。いわゆるハレーション(幻覚)だ。それが、1ヶ月ぶりに使ってみると消えていた。

普通の人はこの変化に気づかないと思う。「なんか最近いい感じ」で終わる。

SEの職業病かもしれないが、システムが正しく動いている状態より、誤動作していた状態が改善された瞬間のほうが気になる。ハレーションは「既知の不具合」だった。それが修正されたなら、何が変わったのかを確認したくなる。


設計を確認した

Geminiに直接聞いた。何が変わったのか、と。

返ってきた説明はこうだった。最新情報を検索してから回答を生成するRAG(Retrieval-Augmented Generation)の仕組みと、情報源を明示するGroundingを組み合わせることで、根拠のない推測を減らしているというものだった。

自分のmy-rag-brainと同じ設計思想だった。

興味が出て、情報源についても確認した。するとこんな回答が返ってきた。

私は様々な情報を取得しアップデートします。そして情報源にはQiitaも含まれるので、あなたの情報が私の一部になった可能性は事実であると考えることが妥当です。

以前Qiitaに書いた記事が、廻り廻ってGeminiの一部になっているかもしれない。確認できることではないが、面白い話だと思った。


Geminiの設計をmy-rag-brainに取り込んだ

設計が同じなら、Geminiが実装していることは自分のシステムにも入れられるはずだ。順番に取り込んだ。

CRAG(Corrective RAG)

ChromaDBで検索した結果の品質を、取得直後に評価するゲートを追加した。コサイン距離が0.55を超えたチャンクは「poor」と判定し、通過させない。

POOR_MATCH_THRESHOLD = 0.55

_best_dist = min(_type_min_dist.values()) if _type_min_dist else None
_poor_quality = _best_dist is not None and _best_dist > POOR_MATCH_THRESHOLD

poor判定になった場合は、typeフィルタを外して横断再検索するフォールバックも組み込んだ。type指定のズレ(正しい内容が別typeに記録されている)を救済するためだ。

Adaptive Retrieval Depth

すべてのクエリを同じ深さで検索するのは非効率だった。クエリの複雑度をスコアリングして、top 5 / 7 / 10を動的に切り替えるようにした。

def _calc_adaptive_top(query: str, user_top: int) -> tuple[int, str]:
    score = 0
    if len(query) > 60:     score += 2
    elif len(query) > 30:   score += 1
    # 「と」「および」「比較」「前回」などのマーカーでも加算
    if score >= 3: return 10, f"広域(score={score})"
    elif score >= 1: return 7, f"中域(score={score})"
    return 5, ""

Tiny-Critic RAG

CRAGが品質ゲートなら、Tiny-Criticは関連性フィルタだ。品質ゲートを通過したチャンクに対して、実際にクエリと関連しているかを小さなモデルで判定し、無関係なものを除去する。訓練の詳細は別記事に書く。

Self-RAGは見送った

RAGの出力品質を自己評価して必要なら再検索するアーキテクチャだが、採用しなかった。MCPサーバー経由でClaude Codeが呼ぶ構成では、Claude Code自体がゲートの役割を果たしているため、二重になる判断をした。

取り込んだ設計の流れは以下のとおりだ。

graph TD
    A[クエリ] --> B[Adaptive Retrieval Depth<br/>複雑度スコアで top 5 / 7 / 10 を決定]
    B --> C[ChromaDB 検索<br/>ベクトル類似度で候補を取得]
    C --> D{CRAG 品質ゲート<br/>dist > 0.55?}
    D -->|通過| E[Tiny-Critic<br/>関連なしチャンクを除去]
    D -->|poor 判定| F[CRAG Fallback<br/>type除去で再検索]
    F --> E
    E --> G[レスポンス生成]

なぜこれを書くか

SEの仕事は、要件定義から設計の段階で問題が発生しない状態をロジカルに構築することだ。ノイズの中から信号を見つけ、それが「なぜそうなっているか」を問い続けることでもある。

今回は、AIの変化というノイズの中に、設計思想という信号を見つけた。AIも例外ではなかった。


関連する記事

気軽にメッセージください

仕事の依頼、案件紹介、ご感想・ご質問なんでもお待ちしております。 高い志をもった同士の皆様と繋がることを切に願っております。 これからも人生を掛けたチャレンジを続けていきます。 何卒よろしくお願い致します。