跳转到主要内容
当你拥有工作区和 API 密钥后(参见 简介),提示词就是下一步。本页是 OrcaRouter 提示词注册表的权威参考——它是什么、 如何使用,以及它如何与网关的其他部分组合。

1. 什么是提示词注册表

提示词注册表是一个工作区级别的可复用系统消息库。 你保存一次提示词,将任意 API 密钥绑定到它(或每个请求发送 prompt_ref),网关会在将请求转发到上游模型之前 将该提示词注入为系统消息。 编辑提示词会在下一次调用时更新所有绑定到它的密钥。 无需重新部署。无需修改代码。无需升级 SDK。绑定关系存在于 网关中,而不是你的应用中。 这与 Langfuse 和 LangSmith 开创的思路一致,但有一个 区别:OrcaRouter 是交付层。你的应用代码像以前一样调用 /v1/chat/completions;网关负责解析并 注入提示词。应用中无需安装任何东西。 提示词是工作区级别的——每个成员都能看到该工作区的提示词; 不会跨租户边界。

2. 快速开始——5 步绑定你的第一个提示词

1

创建提示词

在控制台中前往 /console/prompts,点击 New prompt。 将其命名为 support-agent。粘贴系统消息:
“你是 Acme 的简洁支持代理。请用不超过 2 句话作答。”
保存——这会创建版本 1。
2

绑定密钥

前往 /console/token,创建或编辑一个 API 密钥,从 Prompt 下拉菜单选择 support-agent,从 Label 下拉菜单 选择 production
3

发送请求

使用该密钥,像以前一样调用 OrcaRouter:
curl https://api.orcarouter.ai/v1/chat/completions \
  -H "Authorization: Bearer sk-orca-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [
      {"role": "user", "content": "What are your business hours?"}
    ]
  }'
网关会在转发前预置你保存的系统消息。响应头 X-Orca-Prompt: support-agent@production:v1 确认 注入了哪个提示词。
4

编辑提示词

回到 /console/prompts,编辑 support-agent——更改系统 消息。保存——版本 2 自动创建;production 仍指向 v1。
5

晋级

在提示词行点击 Labels,将 production 移到 v2,确认。 通过你的密钥发出的下一个请求将获得 v2 的系统消息。无需 修改应用。
这就是核心价值。

3. 概念:提示词、版本、标签

概念定义可变性
提示词一个命名的、工作区级别的条目。标识符:name(正则 ^[a-zA-Z0-9._-]{1,128}$)。可软删除(30 天回收站 + 清除)。
版本提示词内容的不可变快照。每次保存时自动创建。标识符:单调递增的 int不可变——永不编辑,永不复用。
标签指向版本的可移动指针(例如 production → v7)。通过晋级原子性地移动;审计日志记录每次移动。

保留标签

  • production 在每个新提示词的第一个版本上自动固定到 v1。 移动它就是生产流量切换——Owner 专属 RBAC。
  • latest 由网关自动维护,始终 指向最新版本。你不能手动移动 latest
你可以稍后通过 Labels 对话框添加自定义标签(例如 stagingcanaryeu-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 字段:
{
  "model": "openai/gpt-4o-mini",
  "messages": [
    {"role": "user", "content": "Who is on call tonight?"}
  ],
  "prompt_ref": {
    "name": "support-agent",
    "label": "staging",
    "variables": {
      "product_name": "Orca"
    }
  }
}
优先级(最高获胜):请求 prompt_ref > 密钥绑定(原生 PromptId/PromptLabelPromptProviderId)> 通道 SystemPrompt
无。
prompt_ref 由网关消费并在转发到上游之前剥离——严格的 提供方永远看不到这个未知字段。 形态:
type PromptRef = {
  provider?: string;   // omit for native; or the provider's configured name for external
  name: string;        // required
  label?: string;      // mutually exclusive with `version`
  version?: string;    // pin to a specific version
  variables?: { [key: string]: string };  // mustache substitution
};
用例:对同一个密钥的不同提示词版本进行 A/B 测试; 从调用方一侧进行金丝雀发布;按请求进行变量插值。

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 参数里。
对于外部聊天提示词(Langfuse、LangSmith),网关将 模板扁平化为相同形态。

8. 与网关其他部分的关系

模块如何与提示词组合?
Models提示词与模型无关。同一个提示词可以在 GPT-5、Claude、Gemini 上运行。路由根据请求的 model 和密钥的分组选择上游模型——提示词永不覆盖该选择。
Routing路由先运行;提示词解析器随后运行。所以解析出的提示词会跟随路由器选择的任何通道,包括跨越回退链。
GuardrailsGuardrails 是独立的关卡,用于检查和脱敏内容。提示词注入系统消息;它们不绕过策略。请求可以同时携带两者——guardrails 始终运行。
API Keys密钥在某个标签上绑定到提示词(例如 support-agent@production)。绑定存在于网关的密钥上,所以晋级新版本会一次性切换该标签上的每个密钥。
Insights每个请求都会在其日志行上打上 prompt_idprompt_versionprompt_label。Insights 按提示词切片——用量、错误率、延迟、成本。
路由器仍然是唯一的模型权威。即使外部提示词 声明了 config(Langfuse config.model、LangSmith model_config)——网关也会忽略这些字段。提示词仅注入文本; 模型选择是路由器的工作。

9. 外部源:Langfuse、LangSmith、Generic HTTP

联邦:一次性连接外部提示词源,然后绑定密钥或针对那里托管的名称 发送 prompt_ref。原生和外部 提示词的绑定和服务方式完全一致——只有解析器后端不同。 支持的源:
  • LangfuseGET {base}/api/public/v2/prompts/{name}?label=..., 使用 public:secret 对的 Basic auth。支持文本和聊天提示词。
  • LangSmithGET {base}/commits/{owner}/{name}/{tag|hash|latest}, 使用 x-api-key 头。网关解析序列化的清单以 提取 messages/text 以及 template_format 声明。嵌入的 model_config / model_provider 字段会被剥离(纵深 防御:注册表仅提供文本)。
  • Generic HTTP — 运营方配置的连接器,适用于任何通过单次 HTTP 调用 完成获取的提示词注册表。可配置字段见下文。
Integrations → Prompt sources 下连接源(仅 Owner 可 配置;密钥加密存储,读取时被屏蔽)。Test & Save 流程在持久化前对已知提示词进行 dry-resolve,并拒绝 SSRF 阻止的 URL(环回、私有、链路本地、元数据范围)。

Generic HTTP 连接器字段

Generic HTTP 源是一个”描述一次 HTTP 调用和一种响应形状”的 适配器。用于自托管的提示词存储以及不需要专用后端集成的 第三方平台(PromptLayer、简单的自定义 API 等)。 这些字段被有意保持精简——多步流程或 provider 特定协议不在范围内。
字段默认值作用
URL template必填完整请求 URL,带 {name} / {label} / {version} 占位符。路径中的占位符使用 PathEscape;查询字符串中的占位符使用 QueryEscape,这样提示词名称中的 &/= 就不能注入额外的查询参数。
HTTP methodGETGETPOST。当平台需要请求体时选择 POST。
Auth header nameAuthorization发送密钥所用的 HTTP 头。对于使用自定义头的提供方,设为 X-API-KEY(或类似)。
Auth scheme prefixBearer (带尾部空格)放在头部值密钥前的字符串。如果平台期望原始 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 形态。
示例——手动连接 PromptLayer:
URL template:        https://api.promptlayer.com/rest/get-prompt-template?prompt_name={name}&label={label}&version={version}
HTTP method:         GET
Auth header name:    X-API-KEY
Auth scheme prefix:  (empty)
Body template:       (empty)
Response JSON path:  prompt_template.messages
Secret:              <your PromptLayer API key>

弹性

  • TTL 缓存(默认 60 秒),让提示词编辑在一分钟内传播。
  • Stale-while-revalidate——缓存值继续提供服务,同时 下一次刷新在后台进行。
  • Stale-on-error——如果外部源返回 5xx 或超时, 网关提供上次已知的良好响应。用户流量 永不会因 provider 故障而硬性失败。

10. 可观测性

每个注入提示词的请求都会留下四条面包屑。

响应头

X-Orca-Prompt: support-agent@production:v7 (native)
格式:
  • 原生:name@label:vN (native)(当版本 int 未知时, 为 name@label (native))。
  • 外部:name@label:<provider-version-tag> (langfuse) 等。
  • 省略标签 ⇒ 无 @label 段。

日志列

Log.PromptIdLog.PromptVersionLog.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=trueOwner列出软删除的提示词(仅 Owner——恢复类)。
GET /api/prompt/searchMember关键字 + 标签搜索(限速)。
GET /api/prompt/tagsMember工作区标签 typeahead。
GET /api/prompt/:idMember单个提示词详情。
GET /api/prompt/:id/versionsMember版本历史(最新优先)。
GET /api/prompt/:id/labelsMember当前标签 → 版本映射。
GET /api/prompt/:id/tagsMember单个提示词的标签集。
GET /api/prompt/:id/label_historyMember晋级审计日志。
GET /api/prompt/:id/analyticsMember单提示词用量图表数据。
GET /api/prompt/analytics/topMember工作区范围内使用最多的提示词。
POST /api/prompt/Developer+创建提示词(text 或 chat)。
PUT /api/prompt/Developer+更新提示词(创建新版本)。
POST /api/prompt/:id/tagsDeveloper+替换标签集。
POST /api/prompt/:id/runDeveloper+Playground “Try it”(限速 30/分钟/工作区)。
DELETE /api/prompt/:idDeveloper+软删除到回收站(默认);?purge=true 仅 Owner 可硬删除。
POST /api/prompt/:id/restoreOwner从回收站恢复。
POST /api/prompt/:id/rollbackOwner将旧版本恢复为新版本。
POST /api/prompt/:id/labelOwner将标签移到某个版本(原子、审计;也接受 split 载荷用于 A/B)。

提示词提供方(联邦)

方法与路径角色用途
GET /api/prompt_provider/Member列出已连接的源(屏蔽密钥)。
POST /api/prompt_provider/Owner连接一个源。
PUT /api/prompt_provider/Owner更新一个源。
DELETE /api/prompt_provider/:idOwner断开连接。
POST /api/prompt_provider/testOwner保存前 dry-resolve。
GET /api/prompt_provider/:id/promptsMember列出外部源中可用的提示词。
POST /api/prompt_provider/:id/prompts/importDeveloper+将外部提示词导入到本地注册表。

提示词 webhook

方法与路径角色用途
GET /api/prompt_webhook/Member列出 webhook。
POST /api/prompt_webhook/Owner添加 webhook(密钥仅返回一次)。
PUT /api/prompt_webhook/:idOwner编辑。
DELETE /api/prompt_webhook/:idOwner移除。
POST /api/prompt_webhook/:id/testOwner发送示例事件。

Webhook 事件投递

每次投递会向你配置的 URL POST 一个 JSON 信封:
{
  "event": "label.promoted",
  "workspace_id": "ws_...",
  "occurred_at": "2025-01-15T08:30:00Z",
  "data": { "...": "事件相关字段" }
}
事件类型:prompt.createdprompt.updatedprompt.deletedlabel.promotedversion.rolled_back 每次投递都会带这些请求头:
  • X-Orca-Webhook-Id —— 你这个 webhook 的 id(用于去重)。
  • X-Orca-Event —— 与信封中 event 字段相同。
  • X-Orca-Signature —— 格式为 sha256=<hex>,其中 <hex> 是对原始 请求体计算的 HMAC-SHA256(密钥为 webhook secret)。请使用常量时间 比较。

请求载荷新增

type ChatCompletionsRequest = {
  // ... all existing OpenAI-compatible fields ...
  prompt_ref?: PromptRef;  // gateway-only; stripped before upstream
};

12. FAQ

行为与从未启用该功能的工作区完全字节一致。如果密钥 没有绑定,没有 prompt_ref,也没有设置通道 默认值,网关不做任何修改。响应 不携带 X-Orca-Prompt 头。日志列为 NULL。这是回归保证:当什么都没绑定时,解析器 是经过验证的 no-op。
SystemPromptOverride 是现有的通道级系统提示词 默认值。绑定的注册表提示词会覆盖通道默认值—— 这是有文档记录且故意为之的。当什么都没解析出来时, 通道默认值仍按原样工作。当调用方请求已包含系统消息时,行为由格式适配器决定: OpenAI 形态的请求会把模板的系统消息预置到前面;Claude 形态的请求会把模板的系统消息放进原生的 system 参数里。
v1 中不能。任何密钥都可以 prompt_ref 其所在 工作区中的任何提示词。这与 Langfuse 和 LangSmith 的工作区级密钥模型一致。跨工作区访问在解析器 层被拒绝(在中继路径中重新检查;绝不信任陈旧的 绑定)。每个密钥的提示词白名单是可能的未来功能。
会。注入的系统提示词 token 像任何其他系统消息一样 计入用量 / 配额 / 计费。超长提示词 超出模型上下文窗口时,返回上游的常规 错误——网关不会预先截断。
不会。外部提供方的 config.model / model_config 字段 会被忽略。模型选择仍由路由器独占决定——提示词 仅注入文本。
解析器将缺失 / 已删除 / 未授权的提示词视为 fail-safe 跳过——请求按原样转发, 不向调用方返回错误。编辑和晋级模态框会显示”被 N 个 密钥使用”徽章,这样你在删除或晋级前 可以看到爆炸半径。
原生标签移动近乎即时(网关以秒级有界间隔 从 DB 同步,加上控制器写入路径上的本地映射写入)。 外部标签移动在配置的缓存 TTL 内出现(默认 60 秒)。 两者都是有文档记录的预期,而非 缺陷。
可以。Create prompt 模态框暴露了 Text / Chat 切换; chat 模式显示结构化的 {role, content} 编辑器。一旦 提示词创建完成,其 kind 即不可变(要更改形态需 创建新提示词)。
  • 用户面向响应上的响应头 X-Orca-Prompt
  • 请求日志行上的 Log.PromptId / PromptVersion / PromptLabel 列。
  • Insights 的 Prompt 过滤 facet——选择一个提示词;每个 Insights 标签页都会过滤到该 prompt_id
通过 PUT /api/prompt_webhook/:id 编辑 webhook,并提供一个新的 secret 值。新密钥仅在响应中返回一次——那时复制;之后 密钥会被屏蔽。(没有专门的轮换端点;轮换就是一次普通编辑。)