コンテンツにスキップ

セマンティックなアクション検索を有効にする

reyn chat には、LLM が実行可能なことを発見するための 2 つの手段が同梱されています: 高速な list_actions ブラウザ(= カテゴリ接頭辞による列挙、常時利用可能)と、search_actions セマンティック検索(= 全アクションの埋め込みインデックスに対する自然言語クエリ)です。本ガイドではセマンティックな経路を有効にする手順を説明します。

TL;DR: search_actionsデフォルトで無効(semantic search はプロジェクト全体で opt-in の方針)。すでに埋め込み API キーがある場合は reyn secret set OPENAI_API_KEY のあと reyn.yamlembedding.enabled: true を設定するだけ — proxy も追加インストールも不要です。API キーなしでローカルモデルを使いたい場合は litellm proxy の背後にモデルを立て、reyn からそこを指してください(後述の 経路 B を参照)。

embedding.enabled だけで構築されるのはこのガイドのタイトル通りの範囲だけです。 以前はこのフラグが repo-knowledge index(リポジトリ内のすべてのドキュメント・ソースファイル)の background build も無条件でスケジュールしていました — この結合が search_actions の ~10 件の action catalog だけを望んでいた運用者に実際の 5M-TPM インシデントを起こしました。#4156 がこの 2 つを分離: embedding.enabled は現在 purely provider/cost ゲートで、embedding.index.repo_knowledge(既定 off)が repo 全体 build の独立した opt-in です。このガイド自身の embedding.enabled: true の手順は action catalog だけを構築します(embedding.index.actions は既定 on)— repo-knowledge index も欲しい場合は config reference の embedding.index を参照してください。

どんなときに欲しくなるか

search_actions は次の違いを生みます:

  • 無い場合: LLM はあなたの意図がどのカテゴリ(file / mcp / memory_operation / …)に属するかを推測し、list_actions(category=[...]) を実行して列挙する必要があります。「PDF をテキストに変換するアクションを探して」 のような自然言語の依頼では、すぐに一致が見つからないと LLM が試したうえで断ることもあります。
  • 有る場合: LLM は search_actions(query="PDF to text") を実行し、全カテゴリ横断で関連度順に並んだ top-K のリストを得ます。その後そのまま describe_actioninvoke_action を実行できます。

embedding.enabled のデフォルトは false(無効)です — semantic search は opt-in なので、明示的な reyn.yaml 設定が必要です(FP-0066 §7;廃止された action_retrieval.embedding_class ゲートの clean-break 後継)。無効のままの場合、search_actions は LLM のツールリストから 除外 されます(可視性ゲート を参照)— これは何も試行されないため起動時警告なしで silent に行われます。

Reyn の埋め込みは litellm 専属

Reyn には in-process の埋め込みバックエンドはありません。action retrieval / semantic_search / builtin RAG プラグインを含む、すべての埋め込み呼び出しは litellm を経由します — プロバイダー自身の API に直接、または環境変数 LITELLM_API_BASE が設定されていれば litellm proxy 経由(call_llm が読む変数と同じ — 1 つの proxy がチャットと埋め込みの両方を担います)。組み込みクラス: light / standardopenai/text-embedding-3-smallstrongopenai/text-embedding-3-large

セットアップは 2 通りで、どちらを選ぶかは埋め込み API 契約がすでにあるかどうかで決まります。

Pre-flight: エンドポイントが実際に応答するか確認する(opt-in の前に行う)

opt-in する前に一度 curl で確認します。この確認は transport に依存しない構造です — reyn は常に LITELLM_API_BASE が指す先の OpenAI 互換 /embeddings エンドポイントへ埋め込みリクエストを送るため、litellm proxy でも、直接の埋め込み API でも、ローカルサーバーでも reyn 側からは同じに見え、同じ一行で確認できます:

curl -s "${LITELLM_API_BASE:-<your-endpoint>}/embeddings" \
  -H "Authorization: Bearer ${OPENAI_API_KEY:-dummy}" \
  -H "Content-Type: application/json" \
  -d '{"model": "<the model name your endpoint expects>", "input": "hello"}' \
  | jq '.data[0].embedding | length'

<your-endpoint> / モデル名 / キーは実際の値に置き換えてください — これはそのまま使うコマンドではなく、調整すべき形です。正常: 正の整数(埋め込み次元、例 1536)が出力される — data[0].embedding が空でない float 配列として返っています。典型的な失敗パターン:

  • 401 — キーが誤り、または未設定。
  • 404 / "model not found" — そのモデル名がこのエンドポイントに登録されていない(proxy の model_list 不一致、または直接 API のモデル文字列が誤り)。
  • 400, unsupported paramproxy 経由のときのみ関連(経路 B を参照): proxy に litellm_settings.drop_params: true が設定されていません(#1616)。
  • connection refused — そのエンドポイントに何も listen していない、または LITELLM_API_BASE が誤ったアドレスを指しています。

経路 A — 埋め込み API キーがある場合 — proxy 不要

これが最短経路で、proxy を一切経由 しません:

reyn secret set OPENAI_API_KEY
# プロンプトが出たら sk-... キーを入力

続けて reyn.yaml で明示的に opt-in します(デフォルトは false / 無効):

embedding:
  enabled: true
  # default_class: standard   # デフォルト; = openai/text-embedding-3-small

LITELLM_API_BASE が未設定の場合、reyn の litellm クライアントはプロバイダーの API を 直接 呼び出すため、standardproxy も drop_params 設定も不要で動作します — クライアントはすべての呼び出しで既に drop_params=True を渡しており、これは proxy が間に入っているときにのみ意味を持ちます(経路 B を参照)。上記の pre-flight curl をプロバイダー自身のエンドポイント(例: https://api.openai.com/v1)に対して実行して確認し、チャットセッションを開始してください — search_actions は次のコールドスタートでインデックスを eager に構築します。

すでに組織の LLM トラフィックが共有 litellm proxy を経由している場合、キーを持っていても実質的には下記の経路 B の状況(経路に proxy が入っている)です — proxy の drop_params の注意点はあなたにも当てはまります。

経路 B — 埋め込み API 契約なし → litellm proxy + ローカルモデル

キーがなく、取得もしたくない場合 — またはオフライン / エアギャップ環境が必要な場合: litellm proxy の背後でローカル埋め込みモデルを動かします。proxy がそのローカルモデルを reyn が既に期待する OpenAI 互換エンドポイントに変換します。reyn 自身はローカルサーバーと直接会話することはありません。ローカルモデルをキャッシュ済みにしておけば、これは search_actions を完全オフラインで動かす方法でもあります — reyn は常に proxy としか話さないため、reyn から Hugging Face への到達は一切発生しません。

Step 1 — ローカル埋め込みサーバーを起動する。 Ollama が最も軽量なセットアップです(openai 互換の埋め込みを標準搭載)。参考コマンドは以下、自分のマシンで検証してください。バージョン/ポートは異なる場合があります:

ollama pull nomic-embed-text
ollama serve   # バックグラウンドサービスとしてまだ動いていなければ
curl http://localhost:11434/api/embeddings -d '{"model": "nomic-embed-text", "prompt": "hello"}'

(代替、それぞれ一行: HuggingFace text-embeddings-inference、または infinity — どちらも OpenAI 互換の埋め込みエンドポイントを公開します。)

Step 2 — litellm proxy の config.yaml に登録する。 構文は litellm 自身のドキュメントで確認済み(https://docs.litellm.ai/docs/proxy/embedding、https://docs.litellm.ai/docs/proxy/configs):

model_list:
  - model_name: text-embedding-3-small   # 下記の命名ルールを参照
    litellm_params:
      model: ollama/nomic-embed-text
      api_base: http://localhost:11434

litellm_settings:
  drop_params: true   # 必須 -- 上記の 400 失敗パターンを参照(#1616)

編集後は proxy を再起動してください。

Step 3 — reyn を proxy に向ける:

export LITELLM_API_BASE=http://localhost:4000   # あなたの proxy のアドレス

命名ルール(モデル名を選ぶ前に読む): LITELLM_API_BASE が設定されている場合、reyn は解決済みモデル文字列の先頭 provider/ セグメントを proxy へ送る前に取り除きます — openai/foo は proxy には単なる foo として届きます。そのため proxy の model_list[].model_name は、使用する reyn 側モデル文字列の最初の / より後ろすべてと一致させる必要があります:

  • (a) 最もシンプル — クラス変更は不要、有効化するだけ。 組み込みの standard クラス(openai/text-embedding-3-small、デフォルトの embedding.default_class)をそのまま使い、proxy の model_nametext-embedding-3-small(上記 Step 2 のとおり)として登録します — これでローカルモデルが reyn のデフォルトクラス名で応答するようになります:
    embedding:
      enabled: true
    
  • (b) または明示的なクラスを追加、例えば reyn.yaml に:
    embedding:
      enabled: true
      default_class: local
      classes:
        local:
          model: openai/nomic-embed-text
    
    ここでは proxy の model_namenomic-embed-textopenai/ より後ろすべて)である必要があります。

Step 4 — end-to-end で確認する。 まず上記の pre-flight curl を再実行し(最も安価な確認)、その後チャットセッションを開始して search_actions がツールリストに現れるか(または後述の reyn embeddings status)確認してください。空でないインデックス(ACTIONS > 0)が本物の signal です。

ローカルモデルを選ぶ(経路 B) — 一度決めると変更コストが高い

後で埋め込みモデルを切り替えると、そのモデルが生成した埋め込み(アクションインデックス、および同じクラスを使う RAG ソース)はすべて無効になり再埋め込みが必要になります — 本格的に使う前に以下の軸で決めてください:

  • 言語。 英語のみの利用なら、小さな英語専用モデルで十分です。日本語・中国語・混在言語のプロンプトなら多言語モデルを使ってください。英語専用モデルのクロス言語再現率は低くなります。
  • サイズ対再現率。 小さいモデルはクエリごとの埋め込みが速く計算コストも低い一方、大きいモデルは再現率で優位です。参考値(計測済み、ベンダー公称値ではない): all-MiniLM-L6-v2(22 MB、384 次元、英語専用、最速)対 multilingual-e5-small(118 MB、50 言語、クロス言語再現率が良い)対 OpenAI の text-embedding-3-small API(multilingual-e5-small より MTEB で約 5 pp 高い、API コストあり)。これらの数値は モデル自体 の特性を表しています — proxy の背後で Ollama/TEI/infinity 経由でローカルに提供する場合でも、経路 A の OpenAI 自身の API として使う場合でも同じで、reyn 固有のバックエンドではありません。
  • サーバーのエコシステム。 Ollama(上記 Step 1)で提供する場合、最も簡単な openai 互換の選択肢は nomic-embed-text です。HuggingFace text-embeddings-inferenceinfinity で提供する場合は bge-* / e5-* ファミリーがよく選ばれます。正確なサイズ / 次元 / 言語の数値はモデル自身のカードで確認してください。

まとめると: 英語利用で速さ重視 → 小さな英語モデル(nomic-embed-text は Ollama での妥当なデフォルト)。日本語 / 多言語 → 多言語モデル。最良の再現率が欲しく、すでに API キーがある → 経路 B ではなく経路 A を使う。

未設定のときに Reyn がどう知らせるか

経路 A・B の両方をスキップしたまま LLM に「…のアクションを探して」と依頼すると、list_actions からの応答に、本ガイドを指す構造化された hint フィールドが付きます。LLM がそのヒントをあなたに伝えるため、チャットの途中でインストールが自己発見可能になります。本ガイドを暗記する必要はありません。ヒントは search_actions が利用可能になった瞬間に消えます。

トラブルシューティング

search_actions が LLM のツールリストに現れないembedding.enabled がまだ false のままか、インデックスの構築がまだ終わっていません(= コールドスタート、数秒程度)。reyn embeddings status を確認してください。設定済みクラスで ACTIONS = 0 かつ LAST_BUILT = (never) なら、構築が完了していません:

$ reyn embeddings status

NAME      BACKEND  MODEL                           CACHE_PATH                  SIZE_MB  ACTIONS  LAST_BUILT
────────────────────────────────────────────────────────────────────────────────────────────────────────────
light     litellm  openai/text-embedding-3-small   .reyn/cache/index/actions      0.31       87  (never)
standard  litellm  openai/text-embedding-3-small   .reyn/cache/index/actions      0.31       87  2026-05-27T19:02:00+00:00
strong    litellm  openai/text-embedding-3-large   .reyn/cache/index/actions      0.31        0  (never)

Pre-flight curl が失敗する — 上記 § Pre-flight の失敗パターンを参照してください: 401(キー誤り)、404(モデル名 / proxy model_list 不一致)、400 unsupported-param(proxy の drop_params: true 未設定、#1616)、connection refused(何も listen していない / LITELLM_API_BASE が誤り)。

クラスを切り替えても古い結果が返る — Reyn のアクションインデックスは一度に 1 つの埋め込みクラスを保持します。クラスの切り替えは次セッションで自動的に再埋め込みをトリガーしますが、reyn embeddings rebuild で先行して強制できます。

LLM が古い mcp.server / agent.peer カテゴリに言及する — LLM の学習データが Reyn の collapse リファクタより前である可能性があります。Reyn 0.4 以降の list_actions(category=["mcp.server"])レガシー → 現行のマッピングを含む明示的なエラー を返すため、LLM は 1 回のリトライで自己修正します。

関連情報