Saltar para o conteúdo principal
Depois de ter um workspace e uma chave de API (veja Introdução), os prompts são o próximo passo. Esta página é a referência canônica para o registro de prompts do OrcaRouter — o que é, como usá-lo e como ele se compõe com o resto do gateway.

1. O que é o registro de prompts

O registro de prompts é uma biblioteca com escopo de workspace de mensagens de sistema reutilizáveis. Você salva um prompt uma vez, vincula qualquer chave de API a ele (ou envia um prompt_ref por requisição), e o gateway injeta esse prompt como mensagem de sistema antes de encaminhar a requisição ao modelo upstream. Editar um prompt atualiza cada chave vinculada a ele já na próxima chamada. Sem redeploy. Sem mudança de código. Sem upgrade de SDK. O vínculo vive no gateway, não na sua aplicação. Essa é a mesma ideia que Langfuse e LangSmith introduziram, com uma diferença: o OrcaRouter é a camada de entrega. O código da sua aplicação chama /v1/chat/completions exatamente como antes; o gateway resolve e injeta o prompt. Não há nada para instalar na aplicação. Prompts têm escopo de workspace — cada membro vê os prompts do workspace; nada atravessa fronteiras de tenant.

2. Início rápido — vincule seu primeiro prompt em 5 passos

1

Criar um prompt

No console, vá em /console/prompts e clique em New prompt. Nomeie-o support-agent. Cole a mensagem de sistema:
“Você é um agente de suporte conciso para a Acme. Responda em 2 frases ou menos.”
Salve — isso cria a versão 1.
2

Vincular uma chave

Vá em /console/token, crie ou edite uma chave de API, escolha support-agent no menu Prompt e production no menu Label.
3

Enviar uma requisição

Usando essa chave, chame o OrcaRouter exatamente como antes:
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?"}
    ]
  }'
O gateway antepõe sua mensagem de sistema salva antes de encaminhar. O header de resposta X-Orca-Prompt: support-agent@production:v1 confirma qual prompt foi injetado.
4

Editar o prompt

De volta em /console/prompts, edite support-agent — altere a mensagem de sistema. Salve — a versão 2 é criada automaticamente; production ainda aponta para v1.
5

Promover

Clique em Labels na linha do prompt, mova production para v2, confirme. A próxima requisição através da sua chave já recebe a mensagem de sistema da v2. Nenhuma mudança na aplicação.
Esse é o valor principal.

3. Conceitos: prompts, versões, rótulos

ConceitoDefiniçãoMutabilidade
PromptUma entrada nomeada, com escopo de workspace. Identificador: name (regex ^[a-zA-Z0-9._-]{1,128}$).Soft-deletável (lixeira de 30 dias + purge).
VersãoUm snapshot imutável do conteúdo do prompt. Criada automaticamente a cada salvamento. Identificador: int monotônico.Imutável — nunca editada, nunca reutilizada.
RótuloUm ponteiro móvel para uma versão (ex.: production → v7).Movível atomicamente via Promote; o log de auditoria registra cada movimentação.

Rótulos reservados

  • production é fixado automaticamente em v1 na primeira versão de cada novo prompt. Movê-lo é uma troca de tráfego de produção — RBAC apenas para Owners.
  • latest é mantido automaticamente pelo gateway e sempre aponta para a versão mais recente. Você não pode mover latest manualmente.
Você pode adicionar rótulos personalizados (ex.: staging, canary, eu-prod) depois via o diálogo Labels e vincular chaves a eles. Até que um rótulo esteja fixado em uma versão, uma chave vinculada a name@<esse-rótulo> falha aberta sem injeção.

Por que esta forma

A separação entre versões imutáveis e rótulos móveis é a primitiva de deploy-sem-código. O código da aplicação se refere a um rótulo (implicitamente, via o vínculo da chave, ou explicitamente via prompt_ref). Promover move o rótulo — a aplicação vê o novo conteúdo na próxima chamada sem mudança de código. Fazer rollback é apenas promover uma versão mais antiga para o rótulo.

4. Padrões de produção: promote, rollback, release escalonado

Promote

Abra Labels na linha de um prompt, escolha a versão alvo, clique em Promote. A movimentação de rótulo é atômica e auditada (o log de auditoria mostra quem moveu qual rótulo, de qual versão para qual versão, quando). Cada chave vinculada a name@<label> pega a nova versão na próxima requisição.
Apenas Owner. Promote é uma mudança de tráfego de produção e é restrito aos Owners do workspace (POST /api/prompt/:id/label). Developers e Viewers veem a lista de rótulos e o histórico de auditoria mas não o botão Promote; o diálogo exibe uma dica inline “ask an Owner” para que a restrição seja visível em vez de silenciosa.

Rollback

Restore em uma versão mais antiga na gaveta History. Restaurar copia o conteúdo dessa versão para frente como uma nova versão (o histórico nunca é mutado) e move latest para ela. Para que o tráfego de fato volte, Promote o rótulo relevante para a versão restaurada.

Release escalonado

Vincule suas chaves canary a name@staging, suas chaves de produção a name@production. Promova staging para uma nova versão, observe no Insights, depois promova production quando estiver satisfeito. Sem edições de chave, sem deploy, sem atualização de SDK.

Divisão de tráfego A/B

O diálogo Label tem um toggle Split traffic. Ative-o para apontar um único rótulo para múltiplas versões com distribuição ponderada (ex.: v7: 60 %, v8: 40 %). O bucketing é determinístico por (workspace, token, request-id) para que uma única conversa permaneça no mesmo bucket através das retentativas.

5. Templating: substituição {{var}}

O conteúdo do prompt suporta placeholders {{var}} no estilo Mustache. Os valores do chamador vêm de prompt_ref.variables (veja §6). Regras:
  • Substituição em passagem única. Os valores das variáveis são emitidos como texto literal. Eles NÃO são reavaliados como template — isso previne injeção de prompt onde um valor fornecido pelo chamador tenta injetar mais diretivas {{...}}.
  • Placeholders desconhecidos permanecem verbatim. Se um placeholder {{foo}} não tiver variável correspondente, o literal {{foo}} é emitido (e um aviso é registrado). Requisições nunca falham por causa de uma variável faltando.
  • Acesso com ponto. {{user.name}} percorre objetos aninhados quando o chamador passa um mapa aninhado.
  • Seções. {{#flag}}...{{/flag}} mostra o bloco apenas quando flag é truthy. Seções invertidas ({{^flag}}...) mostram o bloco quando flag está ausente/falsy.
  • Limite de tamanho renderizado: 256 KiB. Se o texto final renderizado exceder esse limite, toda a injeção é pulada (a resposta não carrega o cabeçalho X-Orca-Prompt) e a requisição é encaminhada sem alterações — proteção contra amplificação por explosão de variáveis.
Provedores externos honram sua sintaxe nativa:
  • Prompts Langfuse usam a mesma sintaxe Mustache {{var}}.
  • Prompts LangSmith declaram template_format: f-string | mustache em seu manifesto. O gateway honra essa declaração.

6. Substituição por requisição: prompt_ref

Sobrescreva ou selecione um prompt por requisição sem mudar o vínculo da chave. Adicione um campo prompt_ref de nível superior ao corpo da requisição:
{
  "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"
    }
  }
}
Precedência (vence o mais alto): prompt_ref da requisição > vínculo da chave (PromptId/PromptLabel nativo ou PromptProviderId) > SystemPrompt do canal > nenhum. prompt_ref é consumido pelo gateway e removido antes do encaminhamento upstream — provedores estritos nunca veem o campo desconhecido. Forma:
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
};
Casos de uso: testes A/B de diferentes versões de prompt para a mesma chave; rollout canary do lado do chamador; interpolação de variáveis por requisição.

7. Prompts em formato chat (system + few-shot)

A maioria dos prompts é uma única string de sistema. Mas às vezes você quer que o gateway injete um template mais rico — uma mensagem de sistema mais uma sequência few-shot de turnos user/assistant. O registro suporta isso como kind: 'chat'. O modal Create prompt do console expõe um toggle Text / Chat. Quando você escolhe Chat, o editor de conteúdo se torna uma lista de linhas {role, content} (system, user, assistant) — adicione quantas precisar. Ao salvar, as linhas são persistidas como messages_json. Uma vez criado, kind é imutável. Comportamento na injeção:
  • Sem mensagem de sistema na requisição ⇒ o gateway antepõe a mensagem de sistema do template e os turnos few-shot do template aparecem antes das mensagens do chamador.
  • Mensagem de sistema na requisição ⇒ a injeção segue o padrão do adaptador de formato. Para requisições no formato OpenAI, a mensagem de sistema do template é anteposta; para requisições no formato Claude, o system do template vai para o parâmetro nativo system.
Para prompts chat externos (Langfuse, LangSmith), o gateway achata o template na mesma forma.

8. Relacionamento com o resto do gateway

SuperfícieComo se compõe com os Prompts?
ModelosPrompts são agnósticos a modelo. O mesmo prompt anda sobre GPT-5, Claude, Gemini. O roteamento escolhe o modelo upstream baseado no model da requisição e no grupo da chave — Prompts nunca sobrescreve isso.
RoteamentoO roteamento roda primeiro; o resolvedor de prompt roda depois. Então o prompt resolvido anda no canal que o roteador escolheu, inclusive através de uma cadeia de fallback.
GuardrailsGuardrails são um gate independente que inspeciona e redige conteúdo. Prompts injetam uma mensagem de sistema; não burlam a política. Uma requisição pode carregar ambos — guardrails sempre rodam.
Chaves de APIUma chave se vincula a um prompt em um rótulo (ex.: support-agent@production). O vínculo vive na chave dentro do gateway, então promover uma nova versão desloca todas as chaves desse rótulo de uma vez.
InsightsCada requisição estampa prompt_id, prompt_version, prompt_label em sua linha de log. Insights segmenta por prompt — uso, taxa de erro, latência, custo.
O roteador permanece a única autoridade de modelo. Mesmo prompts externos que declaram um config (Langfuse config.model, LangSmith model_config) — o gateway ignora esses campos. Prompts injetam apenas texto; a seleção de modelo é trabalho do roteador.

9. Fontes externas: Langfuse, LangSmith, HTTP genérico

Federação: conecte uma fonte externa de prompts uma vez, depois vincule chaves ou envie prompt_ref contra nomes hospedados lá. Prompts nativos e externos vinculam e servem de forma idêntica — apenas o backend do resolvedor difere. Fontes suportadas:
  • LangfuseGET {base}/api/public/v2/prompts/{name}?label=..., autenticação Basic do seu par public:secret. Prompts text e chat.
  • LangSmithGET {base}/commits/{owner}/{name}/{tag|hash|latest}, header x-api-key. O gateway analisa o manifesto serializado para extrair mensagens/texto e a declaração template_format. Os campos embutidos model_config / model_provider são removidos (defesa em profundidade: o registro serve apenas texto).
  • HTTP genérico — conector configurado pelo operador para qualquer registro de prompts que exponha uma única chamada HTTP por fetch. Veja abaixo os campos configuráveis.
Conecte uma fonte em Integrations → Prompt sources (configuração apenas Owner; segredos são armazenados criptografados, mascarados na leitura). O fluxo Test & Save resolve a seco um prompt conhecido antes de persistir e rejeita URLs bloqueadas por SSRF (loopback, privadas, link-local, faixas de metadata).

Campos do conector HTTP genérico

Uma fonte HTTP genérica é um adaptador “descreva uma chamada HTTP e uma forma de resposta”. Usada para repositórios de prompts self-hosted E para plataformas de terceiros que não precisam de sua própria integração de backend (PromptLayer, APIs personalizadas simples, etc.). Os campos são deliberadamente reduzidos — fluxos multi-etapa ou protocolos específicos de provedor estão fora do escopo.
CampoPadrãoO que faz
URL templateobrigatórioA URL completa da requisição com placeholders {name} / {label} / {version}. Placeholders no path usam PathEscape; placeholders na query string usam QueryEscape para que &/= em um nome de prompt não possam injetar parâmetros de query extras.
HTTP methodGETGET ou POST. Escolha POST quando a plataforma exigir um corpo de requisição.
Auth header nameAuthorizationO header HTTP em que o segredo é enviado. Defina como X-API-KEY (ou similar) para provedores que usam um header personalizado.
Auth scheme prefixBearer (com espaço final)String anteposta ao segredo no valor do header. Defina como vazio se a plataforma esperar uma chave de API bruta, ou como Token / outro prefixo personalizado.
Body templatevazioApenas POST. O corpo bruto da requisição com duas famílias de placeholders. Verbatim: {name} / {label} / {version} substituem o valor literal (use para corpos form-encoded, XML ou template — você cuida do escaping). JSON-safe: {name_json} / {label_json} / {version_json} substituem um literal de string JSON totalmente entre aspas (ex.: "hello") — use estes DENTRO de corpos JSON para que um nome de prompt do lado da requisição contendo " / \ / caracteres de controle não possa injetar campos irmãos upstream.
Response JSON pathvazioCaminho com ponto opcional no JSON de resposta onde fica o payload do prompt (ex.: data.0.template.messages). Vazio = autodetecção de formas de nível superior text / prompt / messages.
Exemplo — conectando o PromptLayer manualmente:
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>

Resiliência

  • Cache TTL (padrão 60s) para que as edições de prompt se propaguem em menos de um minuto.
  • Stale-while-revalidate — o valor em cache serve enquanto o próximo refresh roda em segundo plano.
  • Stale-on-error — se a fonte externa retornar 5xx ou der timeout, o gateway serve a última resposta conhecida como boa. O tráfego de usuário nunca é hard-failed por uma indisponibilidade do provedor.

10. Observabilidade

Cada requisição com prompt injetado deixa quatro migalhas.

Header de resposta

X-Orca-Prompt: support-agent@production:v7 (native)
Formato:
  • Nativo: name@label:vN (native) (ou name@label (native) quando o inteiro de versão é desconhecido).
  • Externo: name@label:<provider-version-tag> (langfuse) etc.
  • Rótulo omitido ⇒ sem segmento @label.

Colunas de log

Log.PromptId, Log.PromptVersion, Log.PromptLabel — colunas tipadas, indexadas para consultas do Insights.

Drilldown no Insights

Em /console/insights, a linha de filtros tem uma faceta Prompt — escolha um prompt e cada aba (latência, erros, custo) filtra por aquele prompt_id. Esse é o fechamento de loop para “editei um prompt — o que mudou no tráfego?”.

Auditoria

Toda movimentação de rótulo e rollback é registrada no histórico Promote do prompt com id do usuário ator, timestamp, versão de origem e versão de destino. Visível para cada membro; a mutação é restrita ao papel Owner.

11. Referência da API

Todas as rotas têm escopo de workspace via o header X-Workspace-Id. RBAC é aplicado de maneira consistente: leituras são abertas a cada membro; escritas são Developer+; mudanças de tráfego de produção (movimentações de rótulo, rollbacks, configuração de provedor, webhooks) são apenas Owner.

Prompts

Método e pathPapelPropósito
GET /api/prompt/MemberLista prompts (paginado, suporta ?tag=).
GET /api/prompt/?in_trash=trueOwnerLista prompts soft-deletados (apenas Owner — classe de recuperação).
GET /api/prompt/searchMemberBusca por palavra-chave + tag (rate-limited).
GET /api/prompt/tagsMemberTypeahead de tags para o workspace.
GET /api/prompt/:idMemberDetalhe de um único prompt.
GET /api/prompt/:id/versionsMemberHistórico de versões (mais nova primeiro).
GET /api/prompt/:id/labelsMemberMapa atual rótulo → versão.
GET /api/prompt/:id/tagsMemberConjunto de tags para um prompt.
GET /api/prompt/:id/label_historyMemberLog de auditoria de promoções.
GET /api/prompt/:id/analyticsMemberDados de gráfico de uso por prompt.
GET /api/prompt/analytics/topMemberPrompts mais usados em todo o workspace.
POST /api/prompt/Developer+Cria prompt (texto ou chat).
PUT /api/prompt/Developer+Atualiza prompt (cria uma nova versão).
POST /api/prompt/:id/tagsDeveloper+Substitui o conjunto de tags.
POST /api/prompt/:id/runDeveloper+“Try it” do Playground (rate-limited 30/min/workspace).
DELETE /api/prompt/:idDeveloper+Soft-delete para a lixeira (padrão); ?purge=true é hard delete apenas Owner.
POST /api/prompt/:id/restoreOwnerRestaurar da lixeira.
POST /api/prompt/:id/rollbackOwnerRestaurar uma versão mais antiga como nova versão.
POST /api/prompt/:id/labelOwnerMove um rótulo para uma versão (atômico, auditado; também aceita um payload split para A/B).

Provedores de prompts (federação)

Método e pathPapelPropósito
GET /api/prompt_provider/MemberLista fontes conectadas (segredos mascarados).
POST /api/prompt_provider/OwnerConectar uma fonte.
PUT /api/prompt_provider/OwnerAtualizar uma fonte.
DELETE /api/prompt_provider/:idOwnerDesconectar.
POST /api/prompt_provider/testOwnerResolução a seco antes do salvamento.
GET /api/prompt_provider/:id/promptsMemberLista prompts disponíveis em uma fonte externa.
POST /api/prompt_provider/:id/prompts/importDeveloper+Importa um prompt externo para o registro local.

Webhooks de prompts

Método e pathPapelPropósito
GET /api/prompt_webhook/MemberLista webhooks.
POST /api/prompt_webhook/OwnerAdicionar um webhook (segredo retornado uma vez).
PUT /api/prompt_webhook/:idOwnerEditar.
DELETE /api/prompt_webhook/:idOwnerRemover.
POST /api/prompt_webhook/:id/testOwnerEnviar um evento de amostra.

Entrega de eventos do webhook

Cada entrega faz um POST de um envelope JSON para a URL configurada:
{
  "event": "label.promoted",
  "workspace_id": "ws_...",
  "occurred_at": "2025-01-15T08:30:00Z",
  "data": { "...": "event-specific fields" }
}
Tipos de evento: prompt.created, prompt.updated, prompt.deleted, label.promoted, version.rolled_back. Cabeçalhos presentes em toda entrega:
  • X-Orca-Webhook-Id — o id do seu webhook (use para deduplicar).
  • X-Orca-Event — igual ao campo event do envelope.
  • X-Orca-Signature — no formato sha256=<hex>, em que <hex> é o HMAC-SHA256 do corpo bruto da requisição, assinado com o webhook secret. Compare em tempo constante.

Adição ao payload da requisição

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

12. FAQ

O comportamento é byte-idêntico ao de um workspace que nunca habilitou o recurso. Se a chave não estiver vinculada, nenhum prompt_ref estiver presente e nenhum padrão de canal estiver configurado, o gateway não faz modificações. A resposta não carrega o header X-Orca-Prompt. As colunas de log são NULL.Esta é a garantia de não regressão: o resolvedor é um no-op verificado quando nada está vinculado.
SystemPromptOverride é o padrão existente de system-prompt no nível do canal. Um prompt vinculado do registro sobrescreve o padrão do canal — documentado e intencional. Quando nada se resolve, o padrão do canal continua funcionando exatamente como antes.Quando a requisição do chamador já inclui uma mensagem de sistema, o comportamento é decidido pelo adaptador de formato: requisições no formato OpenAI recebem a mensagem de sistema do template anteposta; requisições no formato Claude colocam o system do template no parâmetro nativo system.
Não em v1. Qualquer chave pode usar prompt_ref para qualquer prompt no seu próprio workspace. Isso corresponde ao modelo de chave com escopo de workspace do Langfuse e LangSmith. Acesso entre workspaces é negado no nível do resolvedor (reverificado no caminho de relay; nunca confiado a partir de um vínculo obsoleto).Allowlists de prompts por chave são uma possível adição futura.
Sim. Tokens de system-prompt injetados contam para uso / cota / cobrança exatamente como qualquer outra mensagem de sistema. Prompts excessivamente longos que excedem a janela de contexto do modelo retornam o erro normal do upstream — o gateway não pré-trunca.
Não. Os campos config.model / model_config dos provedores externos são ignorados. A seleção do modelo permanece como única autoridade do roteador — Prompts injeta apenas texto.
O resolvedor trata prompts ausentes / deletados / não autorizados como skip fail-safe — a requisição é encaminhada inalterada sem erro para o chamador. Os modais Edit e Promote mostram um badge “Used by N keys” para que você veja o raio de impacto antes de deletar ou promover.
Movimentações de rótulo nativas são ~imediatas (o gateway sincroniza a partir do DB em um intervalo limitado em segundos, mais uma escrita no mapa local no caminho de escrita do controlador). Movimentações de rótulo externas aparecem dentro do TTL de cache configurado (padrão 60s). Ambas são expectativas documentadas, não defeitos.
Sim. O modal Create prompt expõe um toggle Text / Chat; o modo chat mostra um editor estruturado {role, content}. Uma vez criado um prompt, seu kind é imutável (você criaria um novo prompt para mudar de forma).
  • Header de resposta X-Orca-Prompt na resposta voltada ao usuário.
  • Colunas Log.PromptId / PromptVersion / PromptLabel na linha de log da requisição.
  • Faceta de filtro Prompt do Insights — escolha um prompt; cada aba do Insights filtra por aquele prompt_id.
Edite o webhook via PUT /api/prompt_webhook/:id e forneça um novo valor de secret. O novo segredo é mostrado uma vez na resposta — copie-o naquele momento; depois o segredo é mascarado. (Não há um endpoint dedicado de rotação; rotação é uma edição normal.)