
「あの件どこに書いたっけ」が探せない|自分のメモを意味で引くAI検索を自作して、精度が落ちた原因まで実測した
当サイトはアフィリエイトプログラムを利用しており、紹介リンク経由での申込により報酬を得る場合があります。記事内で紹介するサービスには筆者が実際に使用しているものと、客観情報として比較掲載しているもの(未使用・PR表記あり)が含まれます。
メモも議事録も溜まっているのに、必要なときに出てこない。この状態を長く放置していました。
原因ははっきりしています。検索がキーワード一致だからです。「補助金の話、どこかに書いたはず」と思って「補助金」で検索する分にはいい。問題は、自分が何と書いたか覚えていないときです。
結論
メモ検索が効かないのは、量が多いからではなく「思い出せる言葉」でしか引けないからです。文字の一致ではなく意味の近さで引く仕組み(いわゆるRAGの検索部分)を入れると、言い回しが1文字も一致しなくても引けるようになります。ただし入れれば効く、ではありません。実際に運用したところ、話題が散らかった長文ノート1本が検索結果の25%を占拠していました。効くかどうかを決めるのは検索の計算式ではなく、何を索引に入れたかです。
この記事は、自分のノート518本に対してその検索を自作し、毎日動かしている記録です。作り方の紹介というより、動かしてから精度が落ちた原因を突き止めるまでが主題です。
文字が1つも合っていないのに、なぜ見つかるのか#
先に、何が起きるのかを見てもらったほうが早いと思います。
自分のノートを、次の4つの言い回しで検索しました。いずれもそのままの文字列はノート全体に1件も存在しません(索引した本文4,619件を文字列一致で検索して0件と確認済み)。
| 検索した言い回し | 文字列一致(従来の検索) | 意味で引いた結果 |
|---|---|---|
| 返さなくていい国からのお金 | 0件 | 補助金情報をまとめたノートが1位 |
| 子ども連れが来られる喫茶店 | 0件 | 子ども向け飲食業態の調査ノートが1位 |
| 会社をやめて別の仕事に移る計画 | 0件 | 自分の年間目標ノートが1位 |
| 休みを取る制度の話 | 0件 | 有給・勤怠のルールを話した会議記録 |
「有給」と一文字も打っていないのに、有給の話が出てくる。ノート側にも「返さなくていい国からのお金」なんて書いてありません。書いてあるのは「補助金」です。
仕組みとしてはこうです。言葉に住所を与えている、というのが一番近い説明だと思います。
手順
- ノートを数百字ずつの断片に切る
- 断片ごとに、意味を表す座標(768個の数字の並び)に変換して保存する
- 質問も同じやり方で座標に変換する
- 質問の座標に近い断片を、上位数件だけ返す
意味が近い文章は近い座標に置かれるので、文字が違っても距離で探せる。これがキーワード検索との決定的な違いです。
全文をAIに読ませるのとは違います
「ノートを全部AIに渡せばいいのでは」と思うかもしれませんが、それは量的に無理があり、費用も毎回かかります。ここでやっているのは近い数ページだけを選び出す工程です。読ませる前の絞り込みだと考えると分かりやすいはずです。
実際に作った構成と、かかっている手間#
個人のノート環境(Markdownのメモが入ったフォルダ)に対して作りました。規模はこうです。
- 座標の次元数: 768次元(埋め込みモデルの出力次元を指定)
- 索引ファイルの容量: 12.6MB(本文の写し 4.6MB と別に保持)
- 更新: 毎日未明に自動実行。内容が変わったファイルだけを作り直す差分更新
差分更新は必須でした。毎日全件を作り直すと毎日課金されます。ファイルの内容をハッシュ化して保存しておき、ハッシュが変わったものだけ再計算する形にしたところ、日々の更新は変更分だけ(直近の実行では656件)で済んでいます。
落とし穴:断片には「何の話か」が書いていない
数百字で切ると、その断片だけを読んでも何の話題か分からないものが大量に出ます。「〜については来週までに確認」だけの断片は、意味の座標がほぼ無意味になります。断片の先頭にノートのタイトルを足してから変換するだけで、ここは改善しました。
本題:入れたのに、精度が落ちていた#
ここからが、この記事を書いた理由です。
作った直後は感動するのですが、しばらく運用してから多様な質問で検証したところ、明らかにおかしい結果が出るようになっていました。
検証は単純です。分野の異なる質問を12問用意し、それぞれ上位5件を見る(合計60枠)。すると──
| 検証結果 | 数値 |
|---|---|
| ある1本のノートが上位5件に入った回数 | 60枠中 15枠(25%) |
| そのノートが混入した質問数 | 12問中 9問 |
| 用意した正解に対する的中(1位に来た数) | 4問中 2問 |
関係のない質問の4件に1件を、同じノートが占めていました。
犯人は「話が多岐にわたった長い雑談の記録」でした。仕事の話、家族の話、移動の話が全部入っている。つまりどの質問に対しても、そこそこ近い。意味の地図の真ん中に居座って、全方位に手を伸ばしている状態です。
なぜキーワード検索では起きないのか
文字一致なら、その雑談ノートは「補助金」を含まない限り出てきません。意味で引くということは、部分点で拾えるということでもあります。部分点の常連が生まれるのは、意味検索に固有の壊れ方です。
検索側で直そうとして、失敗した記録#
最初に考えたのは「検索の計算式で殴る」でした。全断片の平均的な位置を出して、そこに近い=どの質問にも薄く近い断片を減点する。理屈は通っています。実装も数行です。
減点の強さを変えて実測した結果がこれです。
| 減点の強さ | 問題のノートの占有 | 正解が1位に来た数 |
|---|---|---|
| 0(減点なし) | 60枠中 15枠 | 4問中 2問 |
| 1.0 | 60枠中 9枠 | 4問中 2問 |
| 1.5 | 60枠中 3枠 | 4問中 0問 |
| 2.0 | 60枠中 0枠 | 4問中 0問 |
強くすればノイズは消えます。ただし正解も一緒に消えます。
一番マシに見えた減点1.0でも、個別に見ると「補助金の質問で、正解ノートが上位3件から脱落する」という副作用が出ていました。ノイズが減った枠を、別の無関係なノートが埋めただけです。
この対策は採用しませんでした(機能自体はスイッチとして残し、既定はオフ)。効かない補正をデフォルトで入れると、後から原因を追うときに邪魔になります。
直ったのは、索引の中身のほうだった#
問題のノートを開いて分かりました。ファイル名は「要約」なのに、中身は生の文字起こしそのものでした。01:38:09 のようなタイムスタンプの行が延々と続き、言い直しと相槌が並んでいる。
つまり要約フォルダに、要約されていないものが紛れていたわけです。
そこで、除外ルールを1つ足しました。
- 従来: 「話者ラベル(Speaker 1 など)が3つ以上あるノートは索引しない」
- 追加: 「タイムスタンプだけの行が5行以上あるノートも索引しない」
この条件でノート全体を走査すると、該当したのは3本だけ。そしてその3本が、検証で結果を占拠していた当人たちでした。
索引を作り直した結果です。
| 指標 | 対策前 | 対策後 |
|---|---|---|
| 該当3本の占有 | 60枠中 15枠 | 60枠中 2枠 |
| 正解が1位に来た数 | 4問中 2問 | 4問中 3問 |
| 索引した断片数 | 4,793件 | 4,619件(174件減) |
ここが一番の学び
検索の精度は、検索アルゴリズムではなく「何を索引に入れたか」でほぼ決まります。 断片を174件(全体の3.6%)減らしただけで、計算式をいくら調整しても得られなかった改善が出ました。入れる前に捨てるほうが、入れた後に減点するより確実です。
言い方を変えると、溜めたものを全部放り込むのが一番やってはいけないことでした。録音を大量に棚卸しした話でも同じ結論に行き着きましたが、資産化の工程では入り口の選別が9割です。
まだできないこと(正直に)#
運用して分かった限界も書いておきます。
できないこと・弱いところ
- 索引に無いものは、当然だが引けない。手元のメモに書いていない話題は、どんな言い回しでも出てきません。「メモしていなかった」問題は、検索では解決しません
- ほぼ同じ内容のコピーが複数あると、上位を仲良く占める。実際、同じ会議の要約が3本(末尾に (1) (2) が付いたもの)残っており、内容が微妙に違うので機械的な重複判定では消せませんでした
- 短い単語1つで引くのは苦手。「人流カメラ」のような短い名詞は、文章として意味が薄いぶん座標が定まらず、精度が落ちます。文章で聞くほうが当たります
- キーワード検索の置き換えではない。正確な型番・日付・固有名詞は、従来どおり文字一致のほうが速くて確実です。併用する前提で設計するのが正解でした
できるようになったこと
- 用語を思い出せなくても、覚えている「意味」で引ける
- 過去の議事録・メモを跨いで、関連する記述をまとめて出せる
- AIに質問するとき、関係する数ページだけを渡せる(全部読ませずに済む)
これから作る人へのチェックリスト#
同じものを作るなら、この順で確認すると回り道が減ります。
手順
- 入れる対象を決める前に、フォルダごとの分量比を見る(自分の場合、会議の要約だけで断片全体の39.3%を占めていました。多いものが結果を支配します)
- 生の文字起こし・自動ログ・重複ファイルは入れない。中身で判定する(ファイル名の命名規則は必ず揺れます)
- 断片の先頭にタイトルを足してから座標に変換する
- 更新は差分だけにする(内容のハッシュで判定。毎日全件は費用の無駄)
- 分野の違う質問を10問以上用意して、上位5件を目視する。これをやらないと、劣化に気づけません
5番が抜けると、今回のように動いてはいるが結果が偏っている状態に気づけません。「検索できるようになった」で満足せず、何度も同じノートが出てこないかだけは見てください。
なお、こうした仕組みの前段として、そもそも会議やメモがテキストとして溜まっていることが前提になります。録音を文字に起こす部分から整えたい場合は、専用サービスを使うほうが早いです。
PR会議の記録をテキストで溜める土台を整えるNotta(AI議事録・文字起こし)検索できる資産にする前に、まず会議がテキストとして残っている必要があります。録音から文字起こしまでを任せるなら専用サービスが早道です(記載の運用結果は個人の環境での実測であり、成果を保証するものではありません)。まとめ#
- メモが探せない原因は量ではなく、思い出せる言葉でしか引けないこと
- 意味の近さで引くと、文字が1つも一致しなくても引ける(実測:一致0件の質問4つで、いずれも意図したノートに到達)
- ただし入れれば効くわけではない。話題が散らかった長文1本が、無関係な質問の結果を25%占拠していた
- 検索の計算式で減点する対策は、強めると正解ごと消えるため不採用
- 効いたのは索引側の選別。断片を3.6%減らすだけで、計算式の調整では届かなかった改善が出た
AIに何かを検索させる仕組みを作るとき、手を入れたくなるのは検索の側です。ただ実際に効くのは、入り口で何を入れないかを決めるほうでした。関連する内容として、AIに毎回イチから説明するのをやめた話と、個人で回している自動化20件の全体像も合わせてどうぞ。