1. 什麼是提示詞註冊表
提示詞註冊表是一個工作區層級的可重用系統訊息庫。 你儲存一次提示詞,將任意 API 金鑰綁定到它(或每個請求傳送prompt_ref),閘道會在將請求轉送到上游模型之前
將該提示詞注入為系統訊息。
編輯提示詞會在下次呼叫時更新所有綁定到它的金鑰。
無需重新部署。無需修改程式碼。無需升級 SDK。綁定關係存在於
閘道中,而不是你的應用程式中。
這與 Langfuse 和 LangSmith 首創的思路一致,但有一個
差別:OrcaRouter 是交付層。你的應用程式程式碼像以前一樣呼叫
/v1/chat/completions;閘道負責解析並
注入提示詞。應用程式中無需安裝任何東西。
提示詞是工作區層級的——每個成員都能看到該工作區的提示詞;
不會跨租戶邊界。
2. 快速開始——5 步綁定你的第一個提示詞
建立提示詞
在主控台中前往
/console/prompts,按一下 New prompt。
將其命名為 support-agent。貼上系統訊息:“你是 Acme 的簡潔支援代理。請用不超過 2 句話作答。”儲存——這會建立版本 1。
傳送請求
使用該金鑰,像以前一樣呼叫 OrcaRouter:閘道會在轉送前預置你儲存的系統訊息。回應標頭
X-Orca-Prompt: support-agent@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)
大多數提示詞是單個系統字串。但有時你希望 閘道注入更豐富的範本——系統訊息加上 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 等)。 這些欄位被刻意保持精簡——多步流程或 provider 特定協定不在範圍內。| 欄位 | 預設值 | 作用 |
|---|---|---|
| URL template | 必填 | 完整請求 URL,帶 {name} / {label} / {version} 預留位置。路徑中的預留位置使用 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。原始請求本文,帶兩族預留位置。逐字:{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 秒),讓提示詞編輯在一分鐘內傳播。
- Stale-while-revalidate——快取值繼續提供服務,同時 下一次重新整理在背景進行。
- Stale-on-error——如果外部來源傳回 5xx 或逾時, 閘道提供上次已知的良好回應。使用者流量 永不會因 provider 故障而硬性失敗。
10. 可觀測性
每個注入提示詞的請求都會留下四條麵包屑。回應標頭
- 原生:
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 facet——選擇一個
提示詞,每個分頁(延遲、錯誤、成本)都會篩選到該
prompt_id。這就是「我編輯了一個提示詞——流量發生了什麼變化?」
的閉環。
稽核
每次標籤移動和回滾都記錄在提示詞的 Promote history 中,包含操作者使用者 id、時間戳、起始版本、目標版本。 每個成員可見;變更受 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 | 將標籤移到某個版本(原子、稽核;也接受 split 酬載用於 A/B)。 |
提示詞提供方(聯邦)
| 方法與路徑 | 角色 | 用途 |
|---|---|---|
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 | 儲存前 dry-resolve。 |
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 POST 一個 JSON 信封: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 的工作區層級金鑰模型一致。跨工作區存取在解析器
層被拒絕(在中繼路徑中重新檢查;絕不信任陳舊的
綁定)。每個金鑰的提示詞白名單是可能的未來功能。注入的提示詞 token 會計費嗎?
注入的提示詞 token 會計費嗎?
會。注入的系統提示詞 token 像任何其他系統訊息一樣
計入用量 / 配額 / 計費。超長提示詞
超出模型上下文視窗時,傳回上游的一般
錯誤——閘道不會預先截斷。
註冊表會覆寫模型嗎?
註冊表會覆寫模型嗎?
不會。外部提供方的
config.model / model_config 欄位
會被忽略。模型選擇仍由路由器獨占決定——提示詞
僅注入文字。綁定到已刪除提示詞的金鑰會發生什麼?
綁定到已刪除提示詞的金鑰會發生什麼?
解析器將遺失 / 已刪除 / 未授權的提示詞視為
fail-safe 略過——請求按原樣轉送,
不向呼叫方傳回錯誤。編輯和晉升強制回應視窗會顯示「被 N 個
金鑰使用」徽章,這樣你在刪除或晉升前
可以看到爆炸半徑。
標籤移動傳播多快?
標籤移動傳播多快?
原生標籤移動近乎即時(閘道以秒級有界間隔
從 DB 同步,加上控制器寫入路徑上的本機對應寫入)。
外部標籤移動在設定的快取 TTL 內出現(預設 60 秒)。
兩者都是有文件記載的預期,而非
缺陷。
我可以在 UI 中編輯聊天提示詞嗎?
我可以在 UI 中編輯聊天提示詞嗎?
可以。Create prompt 強制回應視窗暴露了
Text / Chat 切換;
chat 模式顯示結構化的 {role, content} 編輯器。一旦
提示詞建立完成,其 kind 即不可變(要更改形態需
建立新提示詞)。提示詞戳印的麵包屑出現在哪裡?
提示詞戳印的麵包屑出現在哪裡?
- 使用者面向回應上的回應標頭
X-Orca-Prompt。 - 請求日誌列上的
Log.PromptId/PromptVersion/PromptLabel欄。 - Insights 的 Prompt 篩選 facet——選擇一個提示詞;每個
Insights 分頁都會篩選到該
prompt_id。
如何輪換 webhook 密鑰?
如何輪換 webhook 密鑰?
透過
PUT /api/prompt_webhook/:id 編輯 webhook,並提供新的
secret 值。新密鑰在回應中顯示一次——那時複製;之後密鑰會被
遮罩。(沒有專用的輪換端點;輪換就是普通的編輯。)