どうも!sodaエンジニアの國田です。
みなさん、プロテインは好きですか?私は大好きです。いや、「好き」という言葉だけでは足りませんね。プロテインは、神の粉です。
朝の筋トレ後に一杯。仕事前に一杯。バグが直らず、心がカタボリックになりそうな夜にも一杯。
筋肉は嘘をつかない。プロテインは常に私と共にある。だから私は今日もシェイカーを振ります。
バグを潰し、ジムでウェイトを挙げ、プロテインを流し込む。
プロテインを飲んでさえいれば、ありとあらゆる問題が自ずと解決していく感覚さえ覚えます。
......ただし、こう熱く語っている私にもプロテインに関する難問が1つだけあります。
おすすめのプロテインを紹介するのは、かなり難しい。
なぜなら、プロテイン選びは「これが最強です」と一言で決められないからです。
人によって、体質も目的も違います。常に「チョコレート味のホエイプロテインが最強」とは限りません。
・増量したい人。
・減量中の人。
・甘い味が苦手な人。
・ソイのほうが続けやすい人。
・価格を最優先したい人。
・水に溶かさず、粉を直接頬張る人。
みんな、要件が違います。
あーあ、こんな時、AIがスパッとオススメのプロテインを紹介してくれたら良いのに......。
...
......
.........すみません。前置きが長くなりました。
ということで今回は「プロテイン選びの相談役になるAI」を作ってみたいと思います。
ただし、ChatGPTやGeminiのWeb検索におすすめ商品を聞くのではありません。手元に用意したプロテインの商品データセットを対象に、ユーザーの条件に合う商品を提案するRAGを構築します。
単に「ホエイプロテインが良い」「ソイプロテインが良い」「増量向けが良い」といった分類だけでなく、価格、栄養成分、味、溶けやすさなど、データセットに記載されたスペックをもとに推薦するAIです。
なお、今回もまたベクトル検索は使いません。
前回、前々回の記事では、Agentic Searchを使って、社内規約のような、あらかじめ構造が整理された情報を探索する方法を試してきました。
こうしたデータは、フォルダ構造やファイル名そのものが意味を持っているため、AIが必要な情報を探しに行くAgentic Searchと相性が良いと感じています。
では、商品レコメンドのような用途ではどうでしょうか。
商品データそのものは、コードリポジトリや社内規約とは違います。しかし、味・価格・栄養成分といった属性をもとに検索インデックス用のフォルダ構造を構築することで、Agentic Search的に探索できるのではないか。
今回は、その可能性を試してみます。
さぁ、やってみよう
方法
まず今回のプロテインレコメンドAIに使う商品データを用意します。
実在する商品ではなく、架空のプロテインとして、以下のような商品詳細情報を作成しました。
# 朝霧ホエイ チョコレート
## 基本情報
- 製品ID: P001
- 製品名: 朝霧ホエイ チョコレート
- ブランド: 朝霧ニュートリション
- 味: チョコレート
- 種類: ホエイ
- 価格: 3980円
- 食数: 30食
## 栄養情報 1食あたり
- タンパク質: 24g
- タンパク質含有率: 78%
- 糖質: 2.8g
- 脂質: 1.9g
- カロリー: 121kcal
## 評価
- おいしさ評価: 5 / 5
- 溶けやすさ評価: 5 / 5
- ダイエット適性: 3 / 5
- 増量適性: 4 / 5
- 初心者適性: 5 / 5
- リカバリー適性: 4 / 5
## 属性
- 植物性: いいえ
- 乳糖不使用: いいえ
## メモ
甘めで牛乳との相性がよい。水でも粉っぽさが少ない。
こちらのデータは、"P001_朝霧ホエイ_チョコレート.md"という名前で保存します。
同様の形式で、25種類のプロテインのデータを作成しました。以下が今回用意したダミーデータの一覧です。
P001_朝霧ホエイ_チョコレート.md
P002_朝霧ホエイ_バニラ.md
P003_抹茶静寂アイソレート.md
P004_透明柑橘クリア.md
P005_黒ごま大豆プロテイン.md
P006_きなこ大豆ライト.md
P007_完熟バナナゲイナー.md
P008_焦がしキャラメルゲイナー.md
P009_夜凪カゼイン_ココア.md
P010_眠りのミルクカゼイン.md
P011_青豆ピープロテイン.md
P012_玄米ナチュラルプロテイン.md
P013_珈琲集中ホエイ.md
P014_抹茶集中ホエイ.md
P015_苺ヨーグルトホエイ.md
P016_白桃クリアホエイ.md
P017_塩バニラミネラル.md
P018_蜂蜜レモンリカバリー.md
P019_無糖プレーンアイソレート.md
P020_低価格チョコスタンダード.md
P021_大容量バニラスタンダード.md
P022_高タンパク質チョコアイソレート.md
P023_シナモンオートミールプロテイン.md
P024_南国マンゴークリア.md
P025_ミックスベリービーガン.md
で、ここからが重要なのですが、一般的なRAG...例えばベクトル検索を使う場合には、商品データの本文をベクトル化し、ユーザーの質問に近い文章を検索する構成にすることが多いと思います。
しかし、今回はAgentic Searchを使いたいので、以下のように索引用のフォルダを構成します。
索引
├── 体質・食事制限
│ ├── アレルゲン
│ ├── 乳成分
│ ├── P001_朝霧ホエイ_チョコレート.md
│ ├── P002_朝霧ホエイ_バニラ.md
│ ├── ...
│ :
│ ├── 大豆
│ ├── P005_黒ごま大豆プロテイン.md
│ └── P006_きなこ大豆ライト.md
│ :
├── 味
│ ├── チョコレート系
│ ├── P001_朝霧ホエイ_チョコレート.md
│ ├── P020_低価格チョコスタンダード.md
│ ├── ...
│ :
│ ├── バニラ系
│ ├── P002_朝霧ホエイ_バニラ.md
│ ├── ...
│ :
この構成を見ると、少し不思議な点があります。
同じ `.md` ファイルが、複数のフォルダに登場しているんですよね。
たとえば、`P001_朝霧ホエイ_チョコレート.md` は、以下のように複数の場所に配置されています。
・索引/体質・食事制限/アレルゲン/乳成分/P001_朝霧ホエイ_チョコレート.md
・索引/味/チョコレート系/P001_朝霧ホエイ_チョコレート.md
一見すると、同じ製品データをコピーしているように見えるかもしれません。
しかし、これは配置ミスでも、製品情報の重複管理でもありません。
P001_朝霧ホエイ_チョコレート.md は、「乳成分を含む」「チョコレート系である」という複数の属性を持っています。そのため、それぞれの属性に対応するディレクトリの下に、同じ名前のファイルを置いています。
ただし、ここで置いている .md ファイルには、製品情報の本文は書きません。
製品情報の本体は、別の場所にあるマスターデータとして1製品1ファイルで管理します。索引フォルダ配下の .md ファイルには、そのマスターデータへの参照だけを記載します。
つまり、索引フォルダにある .md ファイルは「製品データそのもの」ではなく、「この製品はこの属性に該当する」という印として置いている参照ファイルです。
これにより、製品情報の本文を重複させずに、同じ製品を複数の属性から見つけられるようにしつつ、この配置そのものが検索インデックスとして機能します。
たとえば「チョコレート系で、乳成分を含むプロテイン」を探したい場合は、味/チョコレート系 と 体質・食事制限/アレルゲン/乳成分 の両方に登場するファイルを見ればよいわけです。
検索処理
検索方法は、以下の手順で実施します。
① ユーザーの希望条件と索引フォルダを照合する
まず、ユーザーがLLMに質問します。
その質問文をもとに、LLMが索引フォルダの一覧から、「どのフォルダを見るべきか」照合します。
たとえば「チョコレート味の安いプロテイン」という質問では、以下のようなフォルダが候補になります。
・味/チョコレート系
・価格/低価格帯
この段階では、まだマスターデータは読みません。あくまで、どの索引を見るべきかを選ぶだけです。
② 複数の索引フォルダに含まれる製品ファイル名を比較する
次に、選択された複数の索引フォルダに含まれるファイル名をリストアップし、比較します。
ここで、もし同一のファイル名が複数の索引フォルダに出現する場合、その製品は複数のユーザー条件に対応している可能性が高いとみなせます。
完全一致する製品が存在しない場合は、より多く出現する製品を優先します。
③ 候補製品の正規データを読み込む
最後に、手順②で得られた候補のうち、優先度の高い最大5件についてマスターデータを読み込み、実際の回答を生成します。
結果
では結果に移りましょう。
以下のような質問を投げてみます。
Q. おいしくて水に溶けやすいチョコ系が欲しい
ここで、想定している答えは、「P001_朝霧ホエイチョコレート.md」もしくは「P022_高タンパク質チョコアイソレート.md」です。
実際の答えは、
「おいしくて水に溶けやすいチョコ系」という条件だと、読めた中ではこの2つが候補です。
1. 朝霧ホエイ チョコレート(P001)
- 味:チョコレート
- 種類:ホエイ
- おいしさ評価:5 / 5
- 溶けやすさ評価:5 / 5
- 推薦メモ:甘めで牛乳との相性がよいが、水でも粉っぽさが少ないとされています。
→ 「おいしさ」「水での溶けやすさ」の両方が最高評価なので、あなたの希望に最も近いです。
2. 高タンパク質チョコアイソレート(P022)
- 味:チョコレート
- 種類:ホエイアイソレート
- おいしさ評価:4 / 5
- 溶けやすさ評価:5 / 5
- 属性:乳糖不使用
- 推薦メモ:高タンパク質・低糖質で、チョコ味としては甘さ控えめとされています。
→ 溶けやすさは最高評価で、おいしさも高めですが、甘さ控えめのチョコが好きな人向きです。
「甘めでおいしいチョコ」を重視するなら P001 朝霧ホエイ チョコレート、
甘さ控えめ・乳糖不使用も気になるなら P022 高タンパク質チョコアイソレートを候補にしてみてください。
良いですね。ちなみに、上記の答えを生成するために実際に読み込んだファイルを確認すると、以下の3つが該当していました。
P001_朝霧ホエイ_チョコレート.md
P020_低価格チョコスタンダード.md
P022_高タンパク質チョコアイソレート.md
チョコ系の候補を3点確認しているようです。
ちなみに、最終的な回答には含まれなかった「P020_低価格チョコスタンダード」は以下のようなスペックでした。
## 評価
- おいしさ評価: 3 / 5
- 溶けやすさ評価: 3 / 5
## メモ
価格を抑えたチョコ味。成分や溶けやすさは標準的
「チョコ系」という条件は満たしていますが、おいしさや溶けやすさは標準的です。そのため、回答生成時の最終候補からは外れたということですね。
それでは、他のプロンプトでも試してみましょう。
Q. 低糖質でタンパク質が多いものを探している
想定している答えは、「P022_高タンパク質チョコアイソレート.md」と「P019_無糖プレーンアイソレート.md」です。
実際の回答は以下のようになりました。
低糖質かつ高タンパクという条件だと、次のあたりが候補になります。
1. 高タンパク質チョコアイソレート(P022)
- タンパク質: 29g(含有率 91%)
- 糖質: 0.9g
- 脂質: 0.5g
- カロリー: 114kcal
- 種類: ホエイアイソレート(乳由来・乳糖不使用)
- 味: チョコレート(甘さ控えめ)
- 特徴: 今回の候補の中で最もタンパク質量が多く、糖質も1g未満。
2. 無糖プレーンアイソレート(P019)
- タンパク質: 28g(含有率 90%)
- 糖質: 0.6g
- 脂質: 0.4g
- カロリー: 109kcal
- 種類: ホエイアイソレート(乳由来・乳糖不使用)
- 味: プレーン(無糖・無香料)
- 特徴: 味より成分重視向け。甘さや香りが不要で、とにかく低糖質・高タンパクを優先したい人向け。
3. 抹茶静寂アイソレート(P003)
- タンパク質: 27g(含有率 86%)
- 糖質: 1.1g
- 脂質: 0.6g
- カロリー: 113kcal
- 種類: ホエイアイソレート(乳由来・乳糖不使用)
- 味: 抹茶(甘さ控えめ・やや苦味)
- 特徴: 糖質は1gを少し超えますが、それでもかなり低糖質で高タンパク。抹茶味が好きなら候補。
4. 白桃クリアホエイ(P016)
- タンパク質: 21g(含有率 80%)
- 糖質: 1.8g
- 脂質: 0.2g
- カロリー: 96kcal
- 種類: クリアホエイ(乳由来・乳糖不使用)
- 味: 白桃ジュース風
- 特徴: タンパク質量はやや少なめですが、低糖質でさっぱり飲みやすいタイプ。
5. 青豆ピープロテイン(P011)
- タンパク質: 24g(含有率 80%)
- 糖質: 1.5g
- 脂質: 1.4g
- カロリー: 112kcal
- 種類: ピープロテイン(植物性・乳糖不使用)
- 味: プレーン(豆の風味が強め)
- 特徴: 動物性を避けたい人向け。味よりも「植物性」「乳糖不使用」「低糖質・高タンパク」といった条件を優先する場合に合います。
ざっくりまとめると、
- 味も重視しつつ、できるだけ高タンパク → P022 高タンパク質チョコアイソレート
- とにかく成分重視(無糖・プレーン) → P019 無糖プレーンアイソレート
- 植物性がよい → P011 青豆ピープロテイン
あたりが特に条件に近いです。
良いですね!想定通りです。
解説のために、索引部分から見ていきましょう。
今回の条件は「低糖質」かつ「高タンパク」です。該当するフォルダは以下のような構成になっていました。
栄養成分
├── タンパク質量
│ ├── 20g以上25g未満
│ ├── ...
│ :
│ ├── 25g以上30g未満
│ ├── P003_抹茶静寂アイソレート.md
│ ├── P007_完熟バナナゲイナー.md
│ ├── P019_無機プレーンアイソレート.md
│ └── P022_高タンパク質チョコアイソレート.md
├── 糖質
│ ├── 1g未満
│ ├── P019_無機プレーンアイソレート.md
│ └── P022_高タンパク質チョコアイソレート.md
│ ├── 1g以上3g未満
│ ├── P003_抹茶静寂アイソレート.md
│ ├── P011_青豆ピープロテイン.md
│ ├── P016_白桃クリアホエイ.md
│ ├── ...
│ :
│ ├── 5g以上
│ ├── P007_完熟バナナゲイナー.md
│ ├── ...
│ :
:
タンパク質量が25g以上の候補は4つあります。
その中で、P007_完熟バナナゲイナーは最終的に提案から除外されています。これは、糖質が5g以上含まれているプロテインだからです。
一方、P019_無糖プレーンアイソレートとP022_高タンパク質チョコアイソレートは、「25g以上30g未満」と「糖質1g未満」の両方に出現します。
つまり、複数条件に強く一致しているため、優先的に候補として扱われているわけです。
さらに、次点として、タンパク質量が比較的多く、糖質も3g未満の製品が候補に挙がるというわけです。
続けて、ちょっと難しい質問を投げてみます。
Q. お腹がゴロゴロしにくいプロテインが欲しい。でも、価格は抑えたいです。
これは、なかなかマニアックな質問ですよね?
一部の乳由来プロテインには、乳糖が含まれます。乳糖をうまく消化しにくい人の場合、乳製品を摂ったあとにお腹の張り、ガス、下痢、腹痛などが起きることがあります。
そのような方は、乳糖が少ない、または乳糖不使用の製品が候補になります。プロテインであれば、ホエイアイソレートや、乳由来ではないソイプロテインなどが選択肢になります。
ただし、ホエイアイソレートは価格が高めになりやすい傾向があります。
つまり、今回の質問では、AIが以下のような意味の変換を行う必要があります。
お腹がゴロゴロしにくい = 乳糖不使用、または乳由来ではないもの
価格を抑えたい = ホエイよりもソイプロテイン
これはかなり難しい検索です。果たして、うまくいくでしょうか。
実際の回答は以下です。
お腹のゴロゴロを避けつつ、できるだけ価格を抑えたい条件に近いものとして、読めた中からおすすめできるのは次の2つです。
---
### 1. きなこ大豆ライト(P006)
- 種類: ソイ(植物性)
- 乳糖不使用: はい
- 価格: 3280円 / 30食
- 1食あたり: タンパク質20g、糖質2.0g、脂質1.8g、112kcal
- 味: きなこ
- 推薦メモ: 甘さ控えめで和風の味。夜や間食の置き換えに使いやすい。
乳糖不使用で植物性ソイなので、乳由来のプロテインでお腹が気になりやすい人には選択肢になりやすいです。
読めた中では、価格と内容のバランスが最も「安め寄り」です。
---
### 2. 黒ごま大豆プロテイン(P005)
- 種類: ソイ(植物性)
- 乳糖不使用: はい
- 価格: 3480円 / 30食
- 1食あたり: タンパク質21g、糖質2.4g、脂質2.2g、118kcal
- 味: 黒ごま
- 推薦メモ: 香ばしさが強く、腹持ちがよい。水では少しざらつきが出やすい。
こちらも乳糖不使用のソイで、価格も比較的抑えめです。黒ごま風味が好きなら候補になります。
---
上記2つはいずれも「乳糖不使用」で、読めた中では価格が低めのグループに入る製品です。
この2つのどちらかから試してみるのが、条件に一番近い選び方になります。
素晴らしいです。
見事にソイ系のプロテインを選定し、提案できました。
では、ソイを避けたい場合でもうまくいくのでしょうか。
ソイプロテインの特徴として、一般にホエイと比べて吸収がゆるやかだとされる点があります。そこで、その条件を言い換えて質問してみます。
Q. お腹がゴロゴロしにくいプロテインが欲しい。でも吸収は早い方が良いです。
実際の回答は以下のとおりです。
お腹のゴロゴロを避けつつ、吸収の早さを重視する条件だと、「乳糖不使用」かつ「ホエイ(特にアイソレート/クリアホエイ)」が候補になります。
その中から、以下の5つを紹介します。
### 1. 高タンパク質チョコアイソレート(P022)
- 種類: ホエイアイソレート
- 乳糖不使用: はい
- タンパク質: 29g(含有率 91%)
- 糖質: 0.9g / 脂質: 0.5g / 114kcal
- 特徴:
- 高タンパク・低糖質・低脂質で成分がかなりストイック。
- 推薦メモでは「高タンパク質かつ低糖質。チョコ味としては甘さ控えめ」とされており、甘さ控えめのチョコが好みなら有力候補です。
### 2. 無糖プレーンアイソレート(P019)
- 種類: ホエイアイソレート
- 乳糖不使用: はい
- タンパク質: 28g(含有率 90%)
- 糖質: 0.6g / 脂質: 0.4g / 109kcal
- 特徴:
- 味付けなしで高タンパク。
- 推薦メモでは「おいしさより成分重視の人向け」とされており、味よりも成分・シンプルさを優先したい人向きです。
### 3. 透明柑橘クリア(P004)
- 種類: クリアホエイ
- 乳糖不使用: はい
- タンパク質: 22g(含有率 82%)
- 糖質: 1.6g / 脂質: 0.3g / 98kcal
- 特徴:
- 推薦メモで「ジュースに近い飲み心地。後味がすっきりしており、甘ったるさが苦手な人に向く」とされています。
- 柑橘系でさっぱりしており、運動直後にも飲みやすいタイプです。
### 4. 白桃クリアホエイ(P016)
- 種類: クリアホエイ
- 乳糖不使用: はい
- タンパク質: 21g(含有率 80%)
- 糖質: 1.8g / 脂質: 0.2g / 96kcal
- 特徴:
- 「軽い白桃ジュースのような味。運動後でも飲みやすい」と記載されています。
- 甘さはありつつも軽めで、フルーツジュース感覚で飲みたい場合に合います。
### 5. 南国マンゴークリア(P024)
- 種類: クリアホエイ
- 乳糖不使用: はい
- タンパク質: 21g(含有率 79%)
- 糖質: 2.0g / 脂質: 0.2g / 99kcal
- 特徴:
- 「果物系で後味が軽い。夏場や運動直後に飲みやすい」とされています。
- トロピカル系の味が好きで、さっぱりした後味を求める場合に向きます。
---
吸収の早さを重視するなら、いずれもホエイ由来で、乳糖不使用と明記されているため、一般的なホエイよりお腹のゴロゴロを避けたい人向けの選択肢になりえます(ただし、個人差はあります)。
味の好みで選ぶなら:
- 甘さ控えめ・成分重視: P022(チョコ)、P019(無糖プレーン)
- ジュース感・さっぱり: P004(柑橘)、P016(白桃)、P024(マンゴー)
きちんと選定できています。
「お腹がゴロゴロしにくい」という自然言語の表現を、乳糖不使用という属性に変換しつつ、「吸収は早い方が良い」という条件から、ソイではなくホエイを候補にできています。
このあたりは、単純なベクトル検索だけでは難しい問題です。
もちろん、ベクトル検索でも「お腹に優しい」「消化に良い」という文言が商品説明に含まれていれば拾える可能性はあります。しかし、今回のように「お腹がゴロゴロしにくい」という表現を「乳糖不使用」「植物性」「ホエイアイソレート」などの属性に変換し、さらに「価格を抑えたい」「吸収は早い方が良い」といった条件と組み合わせて候補を絞る場合、検索対象を文章類似度だけに頼ると安定しにくくなります。
一方、今回の方式では、検索時に参照する属性を明示的に設計できます。
そのため、ユーザーの曖昧な表現を、検索可能な属性へ変換しやすいというメリットがあります。
検索項目の追加
ここまでで、検索性能は十分であることが分かったと思います。
ところで、実際にレコメンドAIを運用していると、あとから検索したい項目が増えることがあります。
たとえば、プロテインのデータは保持しつつも、新たに「寝る前に飲んでも目が冴えてしまわないプロテインかどうかを判断したい」という需要が発生するかもしれません。
そのような場合にも、今回の検索インデックスの方法は有効です。
なぜなら、索引フォルダに項目を付け足すだけで対応できるからです。今回の場合であれば、たとえば体質・食事制限フォルダにカフェインフォルダを新たに設け、カフェインあり・なし・少量をあらかじめ分類しておけばよいわけです。
索引
├── 体質・食事制限
│ ├── アレルゲン
│ ├── ...
│ :
│ ├── カフェイン
│ ├── カフェインあり
│ ├── ...
│ :
│ ├── カフェインなし
│ ├── ...
│ :
│ └── カフェイン少量
│ ├── ...
│ :
そのうえで、マスターデータ側にも「カフェイン含有量」や「夜向け適性」のような項目を追加します。
たとえば「 P001_朝霧ホエイ_チョコレート.md 」であれば、以下のようにデータを追加します。
# 朝霧ホエイ チョコレート
## 基本情報
- 製品ID: P001
:
:
## 評価
- おいしさ評価: 5 / 5
:
- リカバリー適性: 4 / 5
- 夜向け適性: 4 / 5
## 属性
- 植物性: いいえ
- 乳糖不使用: いいえ
- カフェイン: なし
:
索引と正規データの両方を拡張すれば、新しい検索条件にも容易に対応ができるわけです。
実際に、以下の質問を試してみました。
Q. 夜、寝る前に飲んでも大丈夫なやつ
回答は以下のようになりました。
寝る前に飲みやすそうなものとして、次のあたりが候補です(いずれもカフェインなし・夜向け評価が高いものだけ挙げています)。
【ミルク系・カゼイン(ゆっくり消化タイプ)】
1. 夜凪カゼイン ココア(P009)
- 種類: カゼイン
- 味: ココア
- 夜向け適性: 5 / 5
- カフェイン: なし
- 特徴: 就寝前の利用を想定した味設計。タンパク質23g、糖質2.7g、カロリー119kcal。
2. 眠りのミルクカゼイン(P010)
- 種類: カゼイン
- 味: ミルク
- 夜向け適性: 5 / 5
- カフェイン: なし
- 特徴: 甘さ控えめで落ち着いた味。タンパク質22g、糖質2.9g、カロリー118kcal。
【植物性がいい場合(乳糖なし)】
3. きなこ大豆ライト(P006)
- 種類: ソイ
- 味: きなこ
- 夜向け適性: 5 / 5
- 植物性: はい / 乳糖不使用 / カフェインなし
- 特徴: 甘さ控えめの和風。夜や間食の置き換えに使いやすい。タンパク質20g、カロリー112kcal。
4. 黒ごま大豆プロテイン(P005)
- 種類: ソイ
- 味: 黒ごま
- 夜向け適性: 5 / 5
- 植物性: はい / 乳糖不使用 / カフェインなし
- 特徴: 香ばしくて腹持ちがよいタイプ。タンパク質21g、カロリー118kcal。
【ベリー味が好きなら】
5. ミックスベリービーガン(P025)
- 種類: 植物性ブレンド
- 味: ミックスベリー
- 夜向け適性: 4 / 5
- 植物性: はい / 乳糖不使用 / カフェインなし
- 特徴: ベリーの酸味で豆っぽさを抑えた味。タンパク質23g、カロリー115kcal。
ミルク・ココア系がよければ「夜凪カゼイン ココア」か「眠りのミルクカゼイン」、
乳製品を避けたい・和風が好きなら「きなこ大豆ライト」か「黒ごま大豆プロテイン」あたりが、寝る前用として使いやすそうです。
良い結果です。
ベクトル検索の場合、文書を更新したら再埋め込み(ベクトル変換)が必要になります。一方、今回の方式では、索引ディレクトリとマスターデータを追加・更新すれば、属性ベースの検索軸を比較的明示的に拡張できます。
考察
今回の方式には、いくつか明確なメリットがあります。
1. 検索条件を構造化しやすい
プロテインのように、商品スペックが明確に存在するデータでは、味、価格、糖質、タンパク質量、乳糖不使用、植物性、溶けやすさ、夜向け適性など属性ベースの検索がかなり効きます。
こうした条件は、文章の意味的な近さだけで探すより、属性として整理したほうが扱いやすいです。
類似した方法に「タグ付け」がありますが、この場合は、全タグ一覧を大量に並べた上でLLMが選択する必要が出てきます。一方で今回の方法は、検索用の階層インデックスになっているため、
・「低糖質でタンパク質が多い」という質問なら、まず 栄養成分フォルダを見ればよいと判断しやすい。
・「お腹がゴロゴロしにくい」なら、体質・食事制限フォルダを見に行きやすい。
これはLLMにとってかなり扱いやすい構造です。
2. 複合条件に強い
・「チョコ系で、溶けやすくて、おいしい」
・「低糖質で、高タンパク」
・「お腹にやさしくて、価格は抑えたい」
このような複合条件では、複数の索引フォルダに共通して出現する製品を探すことで、条件の重なりを表現できます。
実装としては地味な印象を受けますが、今回のようなレコメンド用途ではシンプルかつ強力な方法ですよね。
3. 検索軸をあとから追加しやすい
「夜向け」「カフェイン」「初心者向け」「甘さ控えめ」「水で飲みやすい」など、あとから検索したい軸が増えた場合でも、索引を追加すれば対応できます。
もちろん、マスターデータ側にも対応する情報を追加する必要はあります。
ただ、設計としては非常に素直で、検索軸を増やしたいなら、索引を増やす。説明に使いたい情報を増やしたいなら、正規データを増やす。
この分かりやすさは、人間が運用する面でも大きな利点になるように感じました。
注意点と限界
一方で、この方式にも限界はあります。
1. 索引設計の品質に依存する
この方式は、索引ディレクトリを検索インデックスとして使います。
そのため、どの属性で分類するか、どの粒度で分類するか、どの製品をどのカテゴリに入れるかの設計が非常に重要になります。
たとえば「低価格帯」をいくら以下とするのか。「高タンパク」を何g以上とするのか。「夜向け」を何で判断するのか。
この設計が曖昧だと、検索結果も曖昧になります。
ベクトル検索を使わないからといって、設計が不要になるわけではありません。むしろ、検索軸の設計責任は明確に人間側へ寄ります。
2. 索引と正規データの同期が必要
正規データを更新した場合、索引側も更新しなければなりません。
たとえば、ある商品の糖質が変更された場合、糖質/1g未満 から 糖質/1g以上3g未満 に移動する必要があるかもしれません。この同期が崩れると、候補探索の時点で誤った製品が選ばれる可能性があります。
そのため、実運用では、正規データから索引を自動生成する仕組みを用意したほうが良いでしょう。
まとめ
いかがでしたか?
今回はベクトル検索を使わずに、ファイルシステム上の階層構造を検索インデックスとして利用するRAGを、商品レコメンド用途として試してみました。
やってみた結果としては、想像以上に検索能力が高く、特に商品スペックのような構造化しやすいデータではかなり有効だと感じました。
もともとAgentic Searchは、Claude CodeなどのAIコーディングの分野で注目されている考え方です。固定され、整理されたフォルダ構造の中から、AIが必要な情報を探しに行く。この仕組みは、プログラミングコードのリポジトリや、社内規約のように構造が安定しているデータと相性が良いものだと捉えていました。
しかし今回の検証では、商品データに対しても、検索インデックス用のフォルダ構造を用意することで、Agentic Search的な探索が十分に応用できる可能性が見えてきました。
LLMをベースに検索を考えると、ベクトルDBや埋め込みベースのインデックス化がまず候補に挙がることが多いと思います。しかし、すべての検索にベクトル検索が必要なわけではありません。
ファイルパスによる索引構造だけでも、十分に実用的な検索が可能ですし、今回のようなレコメンド用途では、検索対象を無理にすべてベクトル化するよりも、人間が理解しやすい属性構造をそのまま検索インデックスとして使うほうが、実装も運用も分かりやすくなる可能性があります。
ベクトル検索は強力かつメジャーな手段として浸透していますが、検索したい対象次第では、Agentic Searchも十分に選択肢になりえます。
検索設計も、プロテイン選びも、結局は要件次第。
今日も私は、シェイカーを振りながら考えるのです。
"筋肉は嘘をつかない。データも、できれば嘘をつかせたくない。"
ではまた!






