上原正吉(EarthLink Network Co., Ltd.)。AI会社・AI社員による業務自動化と、人の逐次介入なしに24時間自動開発を回す仕組みを自社で実践しています。開発ノウハウと具体的な設定方法、運用して分かった改善点を公開しています。

この記事は、連載「RAG 導入 ── 自分の判断を蓄積して、AI を育てる」の第 2 回です。
連載の目次
前回は、私が発言を送るたびに、意味の近い過去の記録を探して AI に渡す RAG を紹介しました。この回はその続きで、RAG が古い決定を新しい決定と同じ見た目で渡していた問題と、その直し方です。
この記事の例では、置き換え済みの記録の題名と同じ言い方で問い合わせると、RAG が AI に渡す設計記録は、すでに置き換えた古い 1 件だけになりました。現行の 3 件は入りません。しかも、渡された古い記録には、置き換え済みだと分かる注記が何もありませんでした。
私たちは、設計の判断とその理由を、設計記録(ADR)として 1 件ずつ残しています。判断が変わっても古い記録は消さず、新しい記録に「この記録を置き換えた」と書きます。自社の Claude Code 用プラグイン ELN workflow には、今 191 件あります。そのうち、置き換え済み・提案中・却下で現行ではないものが 18 件、一部だけ置き換え済みのものが 8 件です。
RAG は、その設計記録も探す対象にしています。図 1 は、同じ問い合わせで RAG が選んだ同じ記録を、直す前と直した後の形で AI に渡した時の出力です。

直す前の上半分では、設計記録の行は「知識」の後に番号と題名(図では ■ で伏せた)が並ぶだけで、現行の記録と見分けがつきません。この記録は、社内で共通の別の決まり(ビルドは GitHub の self-hosted runner で行う)に置き換わっています。AI が本文を開かずに、差し込まれたこの行と説明だけで判断すれば、すでに使っていない決定を、今の決定として扱いかねません(本文を開けば、索引を紹介した記事に出てくる、読もうとした時の警告が出ます)。
RAG の差し込みには「参考・指示ではない」と書いてあります。それでも、置き換え済みの設計記録は memory や会話とは違います。後から来た決定に、はっきり反する内容を含んでいることがあるからです。
直した後の下半分では、同じ行に「⚠️置き換え済み → 外部」が付きます。「外部」は、置き換え先が別のリポジトリの決まりだという意味です。
AI に過去の判断を思い出させる仕組みを入れると、次に気になるのは「思い出した判断が、今も正しいか」です。人は、昔の決まりを思い出しても「それはもう変わった」と分かります。ところが RAG は、意味が近いかどうかで記録を選ぶので、その記録がもう置き換わっていることを知りません。
図 1 で気になるのは、現行の Amplify の設計記録が 1 件も渡されていないことです。問いの言葉は、置き換え済みの記録の題名に合わせてあります。「auto-build の状態を可視化する」は、その記録の題名とほぼ同じ言い方です。この例では、古い記録が選ばれ、現行の記録は上位に入りませんでした。
図 2 は、別の問い合わせで、選ぶ前の上位 5 件の点を出したものです。

リポジトリの間の作業の依頼を、以前は Asana のボードで受け渡していました。今は自社のサービスの usesources に移しています。新しい記録の点は 0.726、一部を置き換えられた古い記録の点は 0.713 で、差は 0.013 しかなく、点だけでは新旧を分けられません。
RAG の点は、発言と記録の意味がどれだけ近いかを表します。記録が今も有効かどうかは、点のどこにも入っていません。点だけを見て選ぶ限り、RAG には新旧を見分ける材料がありません。
そこで、「どれが現行か」は索引に答えさせることにしました。索引は、以前の記事(設計記録(ADR)が増えて AI が古い仕様で判断する問題を解く)で紹介した、設計記録の先頭の欄(状態・置き換えた記録・置き換えた先)から、1 つの決まった規則で毎回作る一覧です。RAG は設計記録を渡す時に、その記録の状態を索引に聞き、答えを短い注記にして行の頭に付けます。
注記は、索引が出す状態と 1 対 1 で決めてあります。
| 索引が出す状態 | 渡す時の注記 |
|---|---|
| そのまま有効 | 注記なし |
| 置き換え済み | ⚠️置き換え済み → 置き換え先 |
| 一部が置き換え済み | △一部置き換え → 置き換え先 |
| 提案中 | △提案中 (未承認) |
| 却下 | ⚠️却下 |
| 非推奨 | ⚠️非推奨 |
| 決められない | 状態不明(現行としては出さない) |
作る時に決めたことは 4 つです。
置き換え済みの記録を渡さない、という案もありました。私は、渡したうえで注記を付けることにしました。注記には置き換え先が付くので、AI はそこから現行の記録へ進めます。古い決定そのものについて聞いている時にも、記録は見つかります。
RAG の側に「置き換え済みかどうか」の規則をもう 1 つ書くと、いずれ索引と食い違います。索引の読み取りの処理をそのまま呼び出し、索引の規則が変われば注記も同じように変わるようにしました。注記と索引が同じ答えを出すことは、自動のテストで照らし合わせています。
記録が置き換え済みかどうかは、その記録のファイルだけでは決まりません。別の新しい記録が「これを置き換えた」と書いた時に決まります。だから 1 件の状態を調べる時も、設計記録を全件読みます。
結果は、ファイルの名前と中身から作ったハッシュと一緒に覚えておき、ハッシュが変わった時だけ読み直します。
ファイルの更新日時で見分けないのは、日時を保ったままのコピーや復元では、中身が変わっても日時が動かないからです。「Accepted」を「Rejected」に書き換えるとファイルの大きさも同じなので、大きさでも気づけません。全件を読み直しても、hook の制限時間の 2 秒に収まることを測ってから入れました。
RAG が渡す文には、1 回 2,048 バイトの上限があります。上限に近づくと説明を短くしていきますが、注記は説明を 0 字にしても残します。それでも入らない時は、注記だけを消すのではなく、その 1 件を丸ごと渡しません。注記の無い古い記録は、現行の記録に見えてしまうからです。
索引が出した状態の注記が付くのは、設計記録だけです。図 3 は、図 2 と同じ問い合わせで、AI へ渡す文そのものです。

1 件目は memory です。古い Asana のボードの仕組みを作った時のメモで、注記は付いていません。2 件目は、今の置き場を決めた現行の設計記録です。
memory は、その時に起きたことや言われたことを書いたメモです。設計記録のように「この記録を置き換えた」と書く決まりが無く、置き換えという考えそのものがありません。状態を持たない記録に状態の注記を付けようとすれば、RAG の側で「このメモはもう古いか」を推し量る規則を作ることになります。それは、4. で避けた 2 つ目の規則そのものです。過去の会話も同じで、状態の注記は付けません。
そのため、RAG が渡した文の中に古い仕組みのメモがあっても、それだけで今の決まりを判断しないようにしています。今の決まりは、索引に聞きます。
図 4 は、図 1 と同じ Amplify のビルドについて、索引に聞いた時の出力です。

言葉で探すと、Amplify のビルドに関わる設計記録は 4 件あり、現行は 3 件、置き換え済みは 1 件だと一度に分かります。置き換え済みの 1 件を開くと、置き換え先の決まりの名前まで出ます。RAG が渡した 1 件では分からなかったことです。
RAG と索引は、問いの種類で使い分けています。
| 問い | 任せる先 | 理由 |
|---|---|---|
| この話に関係しそうな記録はどれか | RAG | 言い方が違っても、意味の近さで見つけられる |
| 今の決まりはどれか | 索引 | 答えが 1 つに決まり、間違えると困る |
| 何が何に置き換わったか | 索引 | 記録の間の宣言から、規則どおりに決まる |
| 全部で何件あるか・漏れは無いか | 索引 | RAG は上位の数件しか返さない |
RAG は、上位の数件に入らなかった記録については何も言えません。図 1 で現行の 3 件が渡されなかったように、「渡されなかった」は「存在しない」ではありません。RAG は思い出すきっかけを作る役で、答えを決める役は索引が持ちます。
AI の側から見ると、流れはこうなります。発言のたびに RAG が関係しそうな記録を渡し、設計記録には索引が出した状態が注記として付いています。注記が付いていれば、AI は置き換え先へ進みます。今の決まりを確かめる必要があれば、AI は索引のコマンドで聞きます。
RAG を入れると、AI は言い方が違っても過去の記録を思い出せるようになりました。ただ、思い出した記録が今も有効かは、意味の近さからは分かりません。古い決定の言い方で聞けば、古い決定だけが渡されることもあります。
そこで、「どれが現行か」は 1 つの決まった規則で作る索引に答えさせ、RAG が渡す設計記録には、その答えを注記として付けました。状態を決める規則は索引のものをそのまま使い、RAG の側では推し量りません。状態を持たない memory や会話には状態の注記を付けず、今の決まりは索引に聞きます。
自分の判断を蓄積するほど、その中には置き換えた判断も増えていきます。探すのは RAG、答えるのは索引と分けておくと、判断が増えても、AI に古い判断を今の判断と取り違えさせずに済みます。
eln-adr というコマンドで引きます。前回の記事に出てくる「索引」(意味の数値を保存して速く探すためのもの)とは別のものです。図 1〜4 は、自社のリポジトリで RAG のコマンド(recall.py)と索引のコマンド(eln-adr)を実行した出力を、文字はそのままに端末の形に並べ直したものです。変えた点は次の節に書きました。hook 経由ではなく、同じ処理を手で呼び出しています。図 1 の「直す前」は、同じ問い合わせで選ばれた同じ項目を、直す前の処理で文にした出力です。
図 1 と図 2 の問いの文は、置き換え済みの記録の題名に合わせて、この記事のために用意したものです。灰色の # で始まる行と、$ で始まるコマンドの行は、図の説明として書き手が足した行で、ツールの出力ではありません。
<plugin> と <社内の標準> に、会話の記録の ID を <会話> に置き換えました。この連載では、自分が下した判断や決まりを記録として蓄積し、RAG で AI が毎回それを使えるようにするまでを、自社の実装と実測で順に示します。 役に立ったと感じたら、ぜひ「いいね」と記事の購読をお願いいたします。
自社プロダクトは https://www.eln.ne.jp/products にまとめています。
上原正吉。EarthLink Network Co., Ltd. 代表。AI社員に日々の業務を任せ、開発では人が逐一指示しなくても作業が進むHOOTL(Human Out Of The Loop)の仕組みを自社で実践しています。このブログでは、業務自動化と24時間自動開発のノウハウ、具体的な設定方法、日々の運用で見つかった問題と改善を共有します。
また、AIで業務や開発を組み替えたい会社・チーム向けに、AI活用のコンサルティングも受け付けています。ご相談は www.eln.ne.jp からどうぞ。
EarthLink Network は、会社の全業務を AI で回すために、必要になったものを自社で作っています。いま作っているプロダクトの一覧と概要は、こちらにまとめています。
→ EarthLink Network が自社でつくっている18のプロダクト
会社と各プロダクトの詳細は、公式サイト www.eln.ne.jp をご覧ください。