差分同期によるコスト最適化 — 変更があったものだけを処理する仕組み

数千件のデータを毎回処理すると時間もコストもかかる。コンテンツハッシュによる変更検知で効率的にデータを更新する方法

差分同期コスト最適化ハッシュAPI費用効率化Embedding
読了時間: 10分

はじめに

RAGシステムでは、データをベクトル化(Embedding)する必要があります。
しかし、数千件のデータを毎回処理すると、以下の問題が発生します。

  • 時間がかかる:全件処理に数十分〜数時間
  • コストがかかる:Embedding APIは従量課金

この記事では、**変更があったデータだけを処理する「差分同期」**の仕組みを解説します。
日常的な運用コストを抑えながら、データを最新に保つ方法です。

毎回フル処理する問題点

処理時間の問題

毎回フル処理すると、「ちょっとマニュアルを1件追加しただけ」でも長時間待つことになります。

コストの問題

OpenAIのEmbedding APIは従量課金です。
text-embedding-3-smallの場合、100万トークンあたり約$0.02です。

一見安そうに見えますが、変更がないのに毎回お金を払うのは無駄です。
このムダを減らすだけでも、運用はかなり楽になりますよね。

差分同期の考え方

基本的なアイデア

差分同期の基本的なアイデアは、**「変更があったものだけ処理する」**ことです。

差分同期の流れ
データを読み込む

各データソースから最新データを取得

ハッシュを計算

各データの「指紋」を計算

前回と比較

DBに保存されているハッシュと比較

差分だけ処理

ハッシュが異なるもののみEmbedding

コンテンツハッシュとは

コンテンツハッシュとは、データの内容を短い文字列(ハッシュ値)に変換したものです。同じ内容なら同じハッシュ値になります。

データ内容 → ハッシュ関数 → ハッシュ値

「返金の手続きについて...」 → MD5 → "a1b2c3d4e5f6..."
「返金の手続きについて...」 → MD5 → "a1b2c3d4e5f6..."(同じ)
「返金の手順について...」   → MD5 → "x7y8z9w0..."(異なる)

差分検知の仕組み

データベースに保存する際、ハッシュ値も一緒に保存しておきます。

同期時に、新しいデータのハッシュと保存済みのハッシュを比較します。

実装のポイント

ハッシュ計算の対象

ハッシュ計算には、Embeddingに影響する要素のみを含めます。

メタ情報が変わっただけで再Embeddingしないよう、検索に関わる部分だけをハッシュ対象にします。

バルク処理

差分が見つかった場合、1件ずつAPIを呼ぶのではなく、まとめて処理します。

変更あり: 10件
↓
10件をまとめてEmbedding APIに送信
↓
10件まとめてDBに保存

これにより、API呼び出し回数を減らし、処理効率を上げています。

トランザクション管理

データの整合性を保つため、トランザクションで処理します。

トランザクション処理
トランザクション開始

BEGIN

削除

元データにないものを削除

更新

変更があったものを更新

追加

新規データを追加

コミット

COMMIT(途中でエラーなら ROLLBACK)

途中でエラーが発生しても、中途半端な状態にならないようにしています。

コスト削減効果

比較シナリオ

実際のプロジェクトでの比較です。

日常的な運用

通常の運用では、大きな変更がないケースがほとんどです。

  • マニュアルの軽微な修正:数件
  • 新しいFAQの追加:週に数件
  • 対応履歴の追加:月に数十〜数百件

差分同期により、これらの日常的な更新は数秒〜数分で完了します。

運用フロー

推奨される更新サイクル

同期コマンド

同期は、シンプルなコマンド1つで実行できます。

npm run sync-all

このコマンドを実行すると、以下の処理が自動で行われます。

  1. 各データソースからデータを取得
  2. ハッシュを比較して差分を検出
  3. 差分のみをEmbedding
  4. DBを更新
  5. 処理結果をレポート表示

処理結果のレポート

同期完了後、以下のような結果が表示されます。

=== 同期完了 ===
処理時間: 45秒
変更検出: 15件
  - 追加: 8件
  - 更新: 5件
  - 削除: 2件
スキップ: 5,235件
API費用: 約$0.0002

どのくらいの処理が行われたか、一目で確認できます。

フォールバック:フル同期

いつフル同期が必要か

差分同期が基本ですが、以下の場合はフル同期が必要になることがあります。

フル同期コマンド

必要な場合は、フル同期も可能です。

npm run sync-all --force

--force オプションを付けると、ハッシュ比較をスキップして全件処理します。

まとめ

差分同期により、以下を実現しました。

  1. 処理時間の短縮:日常的な更新は数秒〜数分で完了
  2. コストの削減:変更がない場合はAPI費用ゼロ
  3. 運用のしやすさ:コマンド1つで完了、レポートで結果確認

データ量が増えても、差分同期なら日常的な運用コストを抑えたままデータを最新に保てます。