1. プロンプトレジストリとは
プロンプトレジストリはワークスペーススコープの再利用可能なシステムメッセージ ライブラリです。プロンプトを一度保存し、任意の API キーをそれにバインドするか (あるいはリクエストごとにprompt_ref を送信し)、ゲートウェイはアップストリーム
モデルへリクエストを転送する前に、そのプロンプトをシステムメッセージとして注入します。
プロンプトを編集すると、バインドされたすべてのキーが次の呼び出しで更新されます。
再デプロイ不要。コード変更不要。SDK アップグレード不要。バインディングは
ゲートウェイに存在し、アプリケーションには存在しません。
これは Langfuse や LangSmith が切り開いたのと同じ発想ですが、ひとつ
違いがあります:OrcaRouter は配信レイヤーです。アプリコードは以前と全く同様に
/v1/chat/completions を呼び出します。ゲートウェイがプロンプトを解決し
注入します。アプリケーションに何かをインストールする必要はありません。
プロンプトはワークスペーススコープです — すべてのメンバーがそのワークスペースの
プロンプトを参照でき、テナント境界を越えることはありません。
2. クイックスタート — 5 ステップで最初のプロンプトをバインド
プロンプトを作成する
コンソールで
/console/prompts に移動し、New prompt をクリックします。
名前を support-agent にします。システムメッセージを貼り付けます:「あなたは Acme の簡潔なサポートエージェントです。2 文以内で回答してください。」保存 — これでバージョン 1 が作成されます。
キーをバインドする
/console/token に移動し、API キーを作成または編集し、Prompt
ドロップダウンから support-agent を、Label ドロップダウンから
production を選択します。リクエストを送信する
そのキーを使って、以前と全く同様に OrcaRouter を呼び出します:ゲートウェイは転送前に保存されたシステムメッセージを先頭に追加します。レスポンス
ヘッダー
X-Orca-Prompt: support-agent@production:v1 が、注入された
プロンプトを確認します。プロンプトを編集する
/console/prompts に戻り、support-agent を編集 — システムメッセージを
変更します。保存 — バージョン 2 が自動的に作成されます。production は
まだ v1 を指しています。3. 概念:プロンプト、バージョン、ラベル
| 概念 | 定義 | 可変性 |
|---|---|---|
| プロンプト | 名前付きの、ワークスペーススコープのエントリ。識別子:name(正規表現 ^[a-zA-Z0-9._-]{1,128}$)。 | ソフト削除可能(30 日のゴミ箱 + パージ)。 |
| バージョン | プロンプト内容の不変のスナップショット。保存のたびに自動的に作成されます。識別子:単調増加する int。 | 不変 — 編集されず、再利用されません。 |
| ラベル | バージョンを指す可動ポインタ(例:production → v7)。 | プロモートによりアトミックに移動。監査ログがすべての移動を記録します。 |
予約ラベル
productionは新しいプロンプトの最初のバージョンで自動的に v1 にピン留めされます。 これを移動するのは本番トラフィックの切り替え — Owner 専用の RBAC です。latestはゲートウェイによって自動的に維持され、常に最新の バージョンを指します。latestを手動で移動することはできません。
staging、
canary、eu-prod)を追加してキーをそれにバインドできます。ラベルが
バージョンにピン留めされるまでは、name@<そのラベル> にバインドされた
キーは注入なしでフェイルオープンします。
なぜこの形か
不変バージョンと可動ラベルの分離は、 コード変更なしでデプロイするためのプリミティブです。アプリケーションコードはラベルを 参照します(キーバインディング経由で暗黙的に、またはprompt_ref 経由で明示的に)。
プロモートはラベルを動かす — アプリケーションは次の呼び出しで新しい内容を、
コード変更なしに参照します。ロールバックは古いバージョンをラベルにプロモートするだけです。
4. プロダクションパターン:プロモート、ロールバック、段階的リリース
プロモート
プロンプト行の Labels を開き、ターゲットバージョンを選び、Promote をクリック。 ラベル移動はアトミックで監査されます(監査ログには、誰がどのラベルを どのバージョンからどのバージョンへ、いつ移動したかが表示されます)。name@<label>
にバインドされたすべてのキーは、次のリクエストで新しいバージョンを取得します。
Owner 専用。 プロモートは本番トラフィックの変更であり、ワークスペースの
Owner にゲートされています(
POST /api/prompt/:id/label)。Developer と Viewer は
ラベル一覧と監査履歴を見られますが、Promote ボタンは見られません。
ダイアログは「Owner に依頼してください」というインラインヒントを表示し、ゲートが
サイレントではなく可視であることを示します。ロールバック
History ドロワーで古いバージョンの Restore。Restore はそのバージョンの 内容を新しいバージョンとして前進コピーし(履歴は決して変更されません)、latest をそこに移動します。トラフィックを実際にフォールバックさせるには、
関連するラベルを復元したバージョンに Promote してください。
段階的リリース
カナリアキーをname@staging に、本番キーを name@production に
バインドします。staging を新バージョンにプロモートし、Insights で
観察し、満足したら production をプロモートします。キーの編集不要、
デプロイ不要、SDK 更新不要。
A/B トラフィック分割
Label ダイアログには Split traffic トグルがあります。これを有効にすると、 単一のラベルを重み配分付きで複数バージョンに向けることができます (例:v7: 60%、v8: 40%)。バケッティングは(workspace, token, request-id) ごとに
決定的に行われるため、単一の会話はリトライ全体で同じバケットに
留まります。
5. テンプレート:{{var}} 置換
プロンプト内容は Mustache スタイルの {{var}} プレースホルダーをサポートします。呼び出し側の
値は prompt_ref.variables から来ます(§6 を参照)。
ルール:
- シングルパス置換。 変数値はリテラルテキストとして出力されます。
テンプレートとして再評価されることは NOT ありません — これにより、呼び出し側が
提供した値が更なる
{{...}}ディレクティブを注入しようとするプロンプト インジェクションを防ぎます。 - 未知のプレースホルダーはそのまま残ります。 プレースホルダー
{{foo}}に 一致する変数がなければ、リテラル{{foo}}が出力されます(そして警告が 記録されます)。変数欠落でリクエストが失敗することは決してありません。 - ドットアクセス。 呼び出し側がネストされたマップを渡すと、
{{user.name}}は ネストされたオブジェクトを辿ります。 - セクション。
{{#flag}}...{{/flag}}はflagが真の場合のみブロックを 表示します。反転セクション({{^flag}}...)はflagが欠落/偽の場合に ブロックを表示します。 - レンダリング後のサイズ上限:256 KiB。 最終的にレンダリングされたテキストが
この閾値を超えた場合、注入全体がスキップされ(レスポンスは
X-Orca-Promptヘッダーを持ちません)、リクエストはそのまま転送されます ——変数膨張による増幅への防御です。
- Langfuse プロンプトは同じ
{{var}}Mustache 構文を使います。 - LangSmith プロンプトは、マニフェストで
template_format: f-string | mustacheを 宣言します。ゲートウェイはその宣言を尊重します。
6. リクエスト毎のオーバーライド:prompt_ref
キーバインディングを変更せずに、リクエスト毎にプロンプトをオーバーライドまたは
選択します。リクエストボディにトップレベルの prompt_ref フィールドを追加します:
prompt_ref > キーバインディング(ネイティブ
PromptId/PromptLabel または PromptProviderId)> チャネル SystemPrompt
なし。
prompt_ref はゲートウェイによって消費され、アップストリームに転送される前に
取り除かれます — 厳格なプロバイダは未知のフィールドを決して目にしません。
形:
7. チャット形式のプロンプト(システム + few-shot)
ほとんどのプロンプトは単一のシステム文字列です。しかし、時にはゲートウェイに より豊かなテンプレート — システムメッセージと user/assistant ターンの few-shot シーケンス — を注入してほしい場合があります。レジストリはこれをkind: 'chat' としてサポートします。
コンソールの Create prompt モーダルは Text / Chat トグルを公開します。Chat
を選ぶと、コンテンツエディタは {role, content} 行のリスト(system、user、assistant)に
なります — 必要なだけ追加します。保存時、行は messages_json として永続化されます。
作成後、kind は不変です。
注入時の挙動:
- リクエストにシステムメッセージなし ⇒ ゲートウェイはテンプレートの システムメッセージを先頭に追加し、テンプレートの few-shot ターンは呼び出し側の メッセージの前に現れます。
- リクエストにシステムメッセージあり ⇒ 注入はフォーマット
アダプタのデフォルトに従います。OpenAI 形式のリクエストでは、
テンプレートのシステムメッセージが先頭に追加されます。Claude 形式の
リクエストでは、テンプレートのシステムはネイティブの
systemパラメータに入ります。
8. ゲートウェイの他部分との関係
| 面 | プロンプトとどう組み合わさるか? |
|---|---|
| Models | プロンプトはモデル非依存です。同じプロンプトが GPT-5、Claude、Gemini 上で動作します。ルーティングはリクエストの model とキーのグループに基づきアップストリームモデルを選びます — プロンプトはそれをオーバーライドしません。 |
| Routing | ルーティングが先に走り、プロンプトリゾルバはその後に走ります。したがって解決されたプロンプトは、ルーターが選んだどのチャネルにも乗り、フォールバックチェーンを跨ぐ場合も含みます。 |
| Guardrails | Guardrails はコンテンツを検査・リダクトする独立したゲートです。プロンプトはシステムメッセージを注入しますが、ポリシーをバイパスしません。リクエストは両方を持てます — guardrails は常に走ります。 |
| API Keys | キーはラベル(例:support-agent@production)でプロンプトにバインドされます。バインディングはゲートウェイのキー上にあるため、新バージョンへのプロモートはそのラベル上の全キーを一度にシフトします。 |
| Insights | すべてのリクエストはログ行に prompt_id、prompt_version、prompt_label をスタンプします。Insights はプロンプトでスライス — 使用量、エラー率、レイテンシ、コスト。 |
config を宣言する
外部プロンプト(Langfuse config.model、LangSmith
model_config)であっても — ゲートウェイはそれらのフィールドを無視します。プロンプトは
テキストのみを注入し、モデル選択はルーターの仕事です。
9. 外部ソース:Langfuse、LangSmith、Generic HTTP
フェデレーション:外部プロンプトソースを一度接続し、その後はそこにホストされた 名前に対してキーをバインドするかprompt_ref を送信します。ネイティブと外部
プロンプトは同一にバインド・サーブされます — 異なるのはリゾルババックエンドのみです。
サポートされているソース:
- Langfuse —
GET {base}/api/public/v2/prompts/{name}?label=...、public:secretペアによる Basic auth。テキストおよびチャットプロンプト。 - LangSmith —
GET {base}/commits/{owner}/{name}/{tag|hash|latest}、x-api-keyヘッダー。ゲートウェイはシリアライズされたマニフェストを解析し、 messages/text とtemplate_format宣言を抽出します。埋め込まれたmodel_config/model_providerフィールドは取り除かれます(多層防御: レジストリはテキストのみを提供します)。 - Generic HTTP — フェッチごとに単一の HTTP 呼び出しを公開するプロンプトレジストリ のためのオペレータ設定型コネクタ。設定可能なフィールドは下記参照。
Generic HTTP コネクタフィールド
Generic HTTP ソースは「ひとつの HTTP 呼び出しとひとつのレスポンス形状を記述する」 アダプタです。セルフホストのプロンプトストアにも、独自のバックエンド統合を 必要としないサードパーティプラットフォーム(PromptLayer、簡易なカスタム API など)にも使われます。フィールドは意図的に小さく — 複数ステップフローや プロバイダ固有プロトコルはスコープ外です。| フィールド | デフォルト | 役割 |
|---|---|---|
| URL template | 必須 | {name} / {label} / {version} プレースホルダー付きの完全なリクエスト URL。パス内のプレースホルダーは PathEscape を、クエリ文字列内のプレースホルダーは QueryEscape を使うため、プロンプト名内の &/= が余分なクエリパラメータを注入することはできません。 |
| HTTP method | GET | GET または POST。プラットフォームがリクエストボディを必要とする場合に POST を選びます。 |
| Auth header name | Authorization | シークレットが送られる HTTP ヘッダー。カスタムヘッダーを使うプロバイダ向けには X-API-KEY(または類似)に設定します。 |
| Auth scheme prefix | Bearer (末尾スペース付き) | ヘッダー値内でシークレットの前に付加される文字列。プラットフォームが生の API キーを期待する場合は空に、または Token / その他のカスタムプレフィックスに設定します。 |
| Body template | 空 | POST 専用。2 つのプレースホルダーファミリーを持つ生のリクエストボディ。逐語:{name} / {label} / {version} はリテラル値で置換(form-encoded、XML、テンプレートボディに使う — エスケープは自分の責任)。JSON-safe:{name_json} / {label_json} / {version_json} は完全に引用された JSON 文字列リテラル(例 "hello")で置換 — JSON ボディの中で使うことで、" / \ / 制御文字を含むリクエスト側プロンプト名が上流に兄弟フィールドを注入できないようにします。 |
| Response JSON path | 空 | プロンプトペイロードが存在するレスポンス JSON へのオプションのドットパス(例 data.0.template.messages)。空 = トップレベルの text / prompt / messages 形状を自動検出。 |
回復力
- TTL キャッシュ(デフォルト 60 秒)により、プロンプト編集が 1 分以内に伝播します。
- Stale-while-revalidate — キャッシュ値が提供される間、次の更新が バックグラウンドで走ります。
- Stale-on-error — 外部ソースが 5xx を返したりタイムアウトしたりした場合、 ゲートウェイは最後の既知の良好なレスポンスを提供します。ユーザートラフィックが プロバイダの障害で硬的に失敗することは決してありません。
10. 可観測性
プロンプトが注入されたすべてのリクエストは 4 つのパンくずを残します。レスポンスヘッダー
- ネイティブ:
name@label:vN (native)(バージョン int が不明な場合はname@label (native))。 - 外部:
name@label:<provider-version-tag> (langfuse)など。 - ラベル省略 ⇒
@labelセグメントなし。
ログ列
Log.PromptId、Log.PromptVersion、Log.PromptLabel — 型付き列、
Insights クエリ用にインデックス付けされています。
Insights ドリルダウン
/console/insights で、フィルター行に Prompt ファセットがあります — プロンプトを
選ぶと、すべてのタブ(レイテンシ、エラー、コスト)がその prompt_id で
フィルタされます。これは「プロンプトを編集した — トラフィックの何が変わったか?」
のループ閉鎖です。
監査
ラベル移動とロールバックはすべて、プロンプトの Promote history に アクター user id、タイムスタンプ、from-version、to-version とともに記録されます。 すべてのメンバーに可視。変更は Owner ロールにゲートされます。11. API リファレンス
すべてのルートはX-Workspace-Id ヘッダーでワークスペーススコープです。RBAC は
一貫して強制されます:読み取りはすべてのメンバーに開放、書き込みは
Developer+、本番トラフィック変更(ラベル移動、ロールバック、プロバイダ設定、
webhook)は Owner 専用。
プロンプト
| メソッドとパス | ロール | 目的 |
|---|---|---|
GET /api/prompt/ | Member | プロンプト一覧(ページング、?tag= サポート)。 |
GET /api/prompt/?in_trash=true | Owner | ソフト削除されたプロンプトを一覧(Owner 専用 — 回復クラス)。 |
GET /api/prompt/search | Member | キーワード + タグ検索(レート制限あり)。 |
GET /api/prompt/tags | Member | ワークスペース用タグ typeahead。 |
GET /api/prompt/:id | Member | 単一プロンプト詳細。 |
GET /api/prompt/:id/versions | Member | バージョン履歴(新しい順)。 |
GET /api/prompt/:id/labels | Member | 現在のラベル → バージョンマップ。 |
GET /api/prompt/:id/tags | Member | 単一プロンプトのタグセット。 |
GET /api/prompt/:id/label_history | Member | プロモート監査ログ。 |
GET /api/prompt/:id/analytics | Member | プロンプトごとの使用量チャートデータ。 |
GET /api/prompt/analytics/top | Member | ワークスペース全体で最も使用されたプロンプト。 |
POST /api/prompt/ | Developer+ | プロンプト作成(text または chat)。 |
PUT /api/prompt/ | Developer+ | プロンプト更新(新バージョン作成)。 |
POST /api/prompt/:id/tags | Developer+ | タグセットの置換。 |
POST /api/prompt/:id/run | Developer+ | Playground「Try it」(30/分/ワークスペースのレート制限)。 |
DELETE /api/prompt/:id | Developer+ | ゴミ箱へソフト削除(デフォルト)。?purge=true は Owner 専用のハード削除。 |
POST /api/prompt/:id/restore | Owner | ゴミ箱から復元。 |
POST /api/prompt/:id/rollback | Owner | 古いバージョンを新バージョンとして復元。 |
POST /api/prompt/:id/label | Owner | ラベルをバージョンに移動(アトミック、監査。A/B 用の split ペイロードも受け付け)。 |
プロンプトプロバイダ(フェデレーション)
| メソッドとパス | ロール | 目的 |
|---|---|---|
GET /api/prompt_provider/ | Member | 接続済みソースを一覧(シークレットはマスク)。 |
POST /api/prompt_provider/ | Owner | ソースを接続。 |
PUT /api/prompt_provider/ | Owner | ソースを更新。 |
DELETE /api/prompt_provider/:id | Owner | 切断。 |
POST /api/prompt_provider/test | Owner | 保存前にドライ解決。 |
GET /api/prompt_provider/:id/prompts | Member | 外部ソースで利用可能なプロンプトを一覧。 |
POST /api/prompt_provider/:id/prompts/import | Developer+ | 外部プロンプトをローカルレジストリにインポート。 |
プロンプト webhook
| メソッドとパス | ロール | 目的 |
|---|---|---|
GET /api/prompt_webhook/ | Member | webhook 一覧。 |
POST /api/prompt_webhook/ | Owner | webhook 追加(シークレットは一度だけ返却)。 |
PUT /api/prompt_webhook/:id | Owner | 編集。 |
DELETE /api/prompt_webhook/:id | Owner | 削除。 |
POST /api/prompt_webhook/:id/test | Owner | サンプルイベントを送信。 |
Webhook イベント配信
各配信では、設定した URL に対して JSON エンベロープを POST します:prompt.created、prompt.updated、prompt.deleted、
label.promoted、version.rolled_back。
各配信には次のヘッダーが付きます:
X-Orca-Webhook-Id— この webhook の id(重複排除に利用)。X-Orca-Event— エンベロープのeventフィールドと同じ。X-Orca-Signature—sha256=<hex>形式で、<hex>は生のリクエスト ボディに対する HMAC-SHA256(鍵は webhook secret)。比較は定数時間で 行ってください。
リクエストペイロード追加
12. FAQ
リクエストでプロンプトが解決されなかった場合は?
リクエストでプロンプトが解決されなかった場合は?
挙動は機能を一度も有効化していないワークスペースとバイト単位で同一です。
キーがバインドされておらず、
prompt_ref も存在せず、チャネルデフォルトも
設定されていない場合、ゲートウェイは一切の修正を行いません。レスポンスは
X-Orca-Prompt ヘッダーを持ちません。ログ列は NULL です。これは回帰保証です:何もバインドされていない場合、リゾルバは検証済みの
no-op です。SystemPromptOverride はレジストリとどう相互作用しますか?
SystemPromptOverride はレジストリとどう相互作用しますか?
SystemPromptOverride は既存のチャネルレベルのシステムプロンプト
デフォルトです。バインドされたレジストリプロンプトはチャネルデフォルトを
オーバーライドします — ドキュメント化され、意図的です。何も解決されない場合、
チャネルデフォルトは以前と全く同様に機能します。呼び出し側のリクエストにすでにシステムメッセージが含まれている場合、
挙動はフォーマットアダプタによって決定されます。OpenAI 形式の
リクエストでは、テンプレートのシステムメッセージが先頭に追加され
ます。Claude 形式のリクエストでは、テンプレートのシステムが
ネイティブの system パラメータに配置されます。特定のキーが使えるプロンプトを制限できますか?
特定のキーが使えるプロンプトを制限できますか?
v1 ではできません。任意のキーは自身のワークスペース内の任意のプロンプトを
prompt_ref できます。これは Langfuse と LangSmith のワークスペース
スコープキーモデルに合致します。クロスワークスペースアクセスはリゾルバ
レイヤーで拒否されます(リレーパスで再チェック。古いバインディングからは
決して信用されません)。キーごとのプロンプト許可リストは将来追加される可能性があります。注入されたプロンプトトークンは課金されますか?
注入されたプロンプトトークンは課金されますか?
はい。注入されたシステムプロンプトトークンは、他のシステムメッセージと
全く同様に使用量 / クォータ / 課金にカウントされます。モデルのコンテキスト
ウィンドウを超える過長プロンプトは、上流の通常エラーを返します —
ゲートウェイは事前トランケートを行いません。
レジストリはモデルをオーバーライドしますか?
レジストリはモデルをオーバーライドしますか?
いいえ。外部プロバイダの
config.model / model_config フィールドは
無視されます。モデル選択はルーターの単独権威であり続けます — プロンプトは
テキストのみを注入します。削除されたプロンプトにバインドされたキーはどうなりますか?
削除されたプロンプトにバインドされたキーはどうなりますか?
リゾルバは欠落 / 削除 / 未承認のプロンプトをフェイルセーフ スキップ
として扱います — リクエストは変更されずに転送され、呼び出し側にエラーは
返りません。Edit と Promote モーダルは「N 個のキーが使用中」バッジを
表示するので、削除またはプロモート前に爆発半径を確認できます。
ラベル移動はどれくらい速く伝播しますか?
ラベル移動はどれくらい速く伝播しますか?
ネイティブラベル移動はほぼ即時です(ゲートウェイは秒単位の有界間隔で
DB から同期し、加えてコントローラの書き込みパスでローカルマップ書き込みも
行います)。外部ラベル移動は設定されたキャッシュ TTL 内で現れます
(デフォルト 60 秒)。両者ともドキュメント化された期待であり、欠陥では
ありません。
UI でチャットプロンプトを編集できますか?
UI でチャットプロンプトを編集できますか?
はい。Create prompt モーダルは
Text / Chat トグルを公開します。
chat モードは構造化された {role, content} エディタを表示します。プロンプトが
作成されると、その kind は不変です(形を変えるには新しいプロンプトを
作成します)。プロンプトスタンプのパンくずはどこに行きますか?
プロンプトスタンプのパンくずはどこに行きますか?
- ユーザー向けレスポンスのレスポンスヘッダー
X-Orca-Prompt。 - リクエストログ行の
Log.PromptId/PromptVersion/PromptLabel列。 - Insights の Prompt フィルターファセット — プロンプトを選ぶと、すべての
Insights タブがその
prompt_idでフィルタされます。
webhook シークレットをローテーションするには?
webhook シークレットをローテーションするには?
PUT /api/prompt_webhook/:id 経由で webhook を編集し、新しい
secret 値を指定します。新しいシークレットはレスポンスで一度
表示されます — その時にコピーしてください。その後シークレットは
マスクされます。(専用のローテーションエンドポイントはありません。
ローテーションは通常の編集です。)