ZYREXdocs

[ docs · Iryx API v1 ]

Documentação

Tudo para mandar um contexto e receber decisões tipadas do Iryx by Zyrex: receitas curtas no Cookbook e cada campo, limite e erro na Referência da API.

[ acesso ]

A API ainda não está aberta ao público. O acesso vem com a pré-reserva: você recebe o endereço da API e a sua chave.

Pré-reserva ↗
Nesta página

Antes do primeiro pedido

O Iryx by Zyrex transforma um contexto em decisões tipadas. Você manda o que sabe (uma mensagem, um registro, um estado pequeno) e as perguntas que precisa responder. Cada resposta volta com um valor e o espectro inteiro de probabilidades por trás dele. O Iryx não escreve texto.

Esta documentação descreve a versão 1 da API ("Espectro", por causa do espectro que toda resposta traz), como o serviço funciona hoje. Todos os valores dos exemplos são ilustrativos, não medições.

  • O acesso vem com a pré-reserva: o endereço da API e a sua chave.
  • Nos exemplos, o endereço fica na variável IRYX_URL e a chave, em IRYX_KEY.
  • A chave vai só no cabeçalho Authorization: Bearer <key>, nunca na URL nem no corpo.
  • Os nomes da API são em inglês: context, decisions, pick, check, scale, spectrum.
bash
export IRYX_URL="<o endereço que vem com o acesso>"
export IRYX_KEY="<a sua chave>"
PowerShell
$env:IRYX_URL = "<o endereço que vem com o acesso>"
$env:IRYX_KEY = "<a sua chave>"

[ parte 1 ]

Cookbook

Receitas curtas para os usos mais comuns. Os campos e as regras completas estão na Referência da API.

Primeira decisão

Um pedido POST /v1/decide leva o contexto e as decisões. Este leva três, uma de cada tipo, sobre a mesma mensagem.

bash
curl -s "$IRYX_URL/v1/decide" \
  -H "Authorization: Bearer $IRYX_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "context": {"message": "API down since 9am, our checkout is failing"},
    "decisions": {
      "team":   {"kind": "pick",  "prompt": "Which team should handle this ticket?",
                 "options": {"billing": "charges, invoices, refunds", "tech": "bugs, API, outages"}},
      "urgent": {"kind": "check", "prompt": "Needs a reply within hours"},
      "mood":   {"kind": "scale", "prompt": "Customer frustration",
                 "levels": ["calm", "annoyed", "angry"]}
    }
  }'

No Windows PowerShell, o curl é outro comando: chame o curl.exe e deixe o corpo num arquivo, para evitar problema com aspas.

PowerShell
curl.exe -s "$env:IRYX_URL/v1/decide" -H "Authorization: Bearer $env:IRYX_KEY" -H "Content-Type: application/json" --data-binary "@request.json"

A resposta (valores ilustrativos):

json
{"id": "dec_5b1e0c9a7d2f4e6a8c3b1d0f",
 "object": "decision",
 "model": "<model-id>",
 "results": {
   "team":   {"kind": "pick",  "value": "tech", "confidence": 0.95, "spectrum": {"billing": 0.05, "tech": 0.95}},
   "urgent": {"kind": "check", "value": 0.91},
   "mood":   {"kind": "scale", "value": 1.4, "level": "annoyed", "spectrum": {"calm": 0.1, "annoyed": 0.4, "angry": 0.5}}},
 "usage": {"decisions": 3},
 "latency_ms": 120}
  • results traz uma entrada por decisão, com os nomes do pedido, na ordem do pedido.
  • usage.decisions conta as decisões respondidas: é a unidade de uso.
  • id identifica a resposta: dec_ e 24 caracteres hexadecimais, o mesmo hex do cabeçalho X-Request-Id.
  • model é o id do modelo que respondeu, como aparece em GET /v1/models.
  • latency_ms é o tempo que o servidor gastou no pedido, da chegada à resposta, em milissegundos. Inclui a espera atrás de pedidos anteriores; o tempo de rede não entra.

pick, check e scale

Cada decisão tem um kind, um prompt e, conforme o tipo, options ou levels. A decisão é sempre sobre o contexto que você manda.

pick: escolher uma opção

Use quando exatamente uma opção de um conjunto fechado vale. As descrições fazem parte da pergunta: diga o que cada opção cobre.

json
"team": {"kind": "pick", "prompt": "Which team should handle this ticket?",
         "options": {"billing": "charges, invoices, refunds", "tech": "bugs, API, outages", "sales": "prices, plans, upgrades"}}
json
"team": {"kind": "pick", "value": "tech", "confidence": 0.88,
         "spectrum": {"billing": 0.07, "tech": 0.88, "sales": 0.05}}
  • value: a opção com a maior probabilidade. No empate, vence a opção listada primeiro.
  • confidence: a probabilidade de value (o mesmo número que spectrum[value]).
  • spectrum: todas as opções, cada uma com a sua probabilidade, na ordem do pedido.

check: esta afirmação é verdadeira?

Escreva o prompt como uma afirmação sobre o contexto, que pode ser verdadeira ou falsa ("Needs a reply within hours"), e não como pergunta.

json
"urgent": {"kind": "check", "prompt": "Needs a reply within hours"}
json
"urgent": {"kind": "check", "value": 0.91}
  • value: a probabilidade, de 0 a 1, de a afirmação ser verdadeira. A de ser falsa é 1 - value. Não há spectrum.

scale: onde fica numa escala em ordem?

Liste os níveis do mais baixo ao mais alto.

json
"mood": {"kind": "scale", "prompt": "Customer frustration", "levels": ["calm", "annoyed", "angry"]}
json
"mood": {"kind": "scale", "value": 1.4, "level": "annoyed",
         "spectrum": {"calm": 0.1, "annoyed": 0.4, "angry": 0.5}}
  • spectrum: a probabilidade de cada nível, pelo nome, na ordem do pedido.
  • value: a posição esperada na escala, contando o primeiro nível como 0 e o último como n - 1: 0 × 0.1 + 1 × 0.4 + 2 × 0.5 = 1.4. Três casas decimais.
  • level: o nome do nível mais perto de value (uma fração de exatamente 0,5 arredonda para cima). Aqui, 1,4 arredonda para 1, "annoyed".

Perguntas sobre o próprio serviço não são aceitas: uma decisão cujo prompt, opções ou níveis perguntem sobre o serviço volta 422 self_reference_not_supported.

Várias decisões num pedido

Um pedido leva de 1 a 32 decisões sobre o mesmo contexto (um servidor pode ter um limite menor). Cada decisão respondida conta uma em usage.decisions. Vários contextos num mesmo pedido não existem na v1: mande um pedido por contexto.

Em Python, só com a biblioteca padrão, e tratando o erro pelo type:

Python
import json
import os
import urllib.error
import urllib.request

URL = os.environ["IRYX_URL"] + "/v1/decide"
KEY = os.environ.get("IRYX_KEY")            # your key

body = {
    "context": {"message": "API down since 9am, our checkout is failing"},
    "decisions": {
        "team": {"kind": "pick", "prompt": "Which team should handle this ticket?",
                 "options": {"billing": "charges, invoices, refunds", "tech": "bugs, API, outages"}},
        "urgent": {"kind": "check", "prompt": "Needs a reply within hours"},
    },
}
headers = {"Content-Type": "application/json"}
if KEY:
    headers["Authorization"] = "Bearer " + KEY

request = urllib.request.Request(URL, data=json.dumps(body).encode("utf-8"), headers=headers, method="POST")
try:
    with urllib.request.urlopen(request, timeout=60) as response:
        answer = json.load(response)
except urllib.error.HTTPError as error:
    problem = json.load(error)
    raise SystemExit("%d %s: %s (param=%s, request id %s)" % (
        error.code, problem["error"]["type"], problem["error"]["message"],
        problem["error"].get("param"), problem["id"]))

team = answer["results"]["team"]
print(team["value"], team["confidence"], answer["results"]["urgent"]["value"])

Quanto cabe num pedido

Cada decisão é lida junto com o contexto inteiro. Quanto maior o contexto e quanto mais decisões no pedido, mais cedo chega o limite. Para prosa comum, com um prompt curto e poucas opções curtas por decisão, o contexto cabe em cerca de:

decisões no pedidocontexto, cerca de
1 a 46.000 caracteres
83.000 caracteres
161.300 caracteres
32500 caracteres
  • Passou do limite: volta 422 context_too_long e nada foi decidido. Mande o mesmo contexto com menos decisões por pedido, ou um contexto menor.
  • Servidor no limite: volta 503 overloaded com o cabeçalho Retry-After. Espere esses segundos e mande o mesmo pedido de novo; nada foi decidido.
  • Contexto estruturado funciona: chaves e valores fazem parte do que o Iryx lê, então nomes de chave claros ajudam.

Ler a confiança e o espectro

Cada tipo diz o quanto confiar na resposta de um jeito:

  • pick: confidence é a probabilidade da opção escolhida, e o spectrum mostra as outras, inclusive a segunda colocada.
  • check: value é a probabilidade de a afirmação ser verdadeira. Para ler sim ou não, compare com 0,5, ou com um limite mais rígido quando um "sim" errado custa caro.
  • scale: value guarda a incerteza (1,4 fica entre "annoyed" e "angry", mais perto de "annoyed"); level é o nível com nome mais próximo, para mostrar ou encaminhar.
json
"team": {"kind": "pick", "value": "tech", "confidence": 0.88,
         "spectrum": {"billing": 0.07, "tech": 0.88, "sales": 0.05}}

Aqui, tech sai com 0,88 e a segunda colocada é billing, com 0,07. Os números podem variar um pouco entre dois pedidos iguais: veja Como ler os números.

Tratar a faixa baixa

A resposta não traz uma faixa pronta: traz a probabilidade. A faixa baixa é você quem define: abaixo de um limite que você escolhe, a decisão vai para uma pessoa.

  1. Escolha um limite para cada decisão. Acima dele, o software age sozinho; abaixo, uma pessoa decide.
  2. Mande para a pessoa o espectro junto: ele mostra a segunda colocada.
  3. Num check, use um limite mais rígido que 0,5 quando um "sim" errado custa caro.
  4. Uma resposta quase empatada pode mudar de lado entre dois pedidos iguais: é mais um motivo para uma pessoa conferir.
Python
import os
import requests

URL = os.environ["IRYX_URL"] + "/v1/decide"
headers = {"Authorization": "Bearer " + os.environ["IRYX_KEY"]} if os.environ.get("IRYX_KEY") else {}

body = {
    "context": {"temperature_c": 31, "co2_ppm": 1800, "someone_home": True},
    "decisions": {
        "action": {"kind": "pick", "prompt": "What should the home system do now?",
                   "options": ["nothing", "turn_on_ventilation", "alert_resident", "call_emergency"]},
        "severity": {"kind": "scale", "prompt": "How serious is the situation?",
                     "levels": ["normal", "attention", "serious", "emergency"]},
    },
}

response = requests.post(URL, json=body, headers=headers, timeout=60)
if response.status_code != 200:
    problem = response.json()
    raise SystemExit(f"{response.status_code} {problem['error']['type']}: {problem['error']['message']}")

result = response.json()["results"]
action = result["action"]
if action["confidence"] >= 0.8:        # illustrative threshold: pick your own
    print("do it:", action["value"])
else:
    print("ask a person; spectrum:", action["spectrum"])
print("severity:", result["severity"]["level"], result["severity"]["value"])

O limite de 0,8 do exemplo é ilustrativo: escolha o seu. O requests manda Content-Type: application/json sozinho quando você passa json=.

[ parte 2 ]

Referência da API

Cada campo, limite, erro e cabeçalho da API v1, como o serviço funciona hoje. Todos os valores dos exemplos são ilustrativos.

Visão geral

ProtocoloHTTP/1.1, corpo JSON em UTF-8
Endereçovem com o acesso (IRYX_URL nos exemplos)
Versãoprefixo /v1 no caminho; GET /v1/health informa "api_version": "1"
AutenticaçãoAuthorization: Bearer <key>
Unidade de usoa decisão: toda resposta informa usage.decisions
métodocaminhoo que fazchave
POST/v1/decideresponde de 1 a 32 decisões sobre um contextosim
GET/v1/modelslista os ids de modelo com que o servidor respondesim
GET/v1/healthse o serviço está vivo e prontonão
GET/healtho mesmo que /v1/healthnão
OPTIONSqualquer caminhopreflight de CORSnão

Autenticação

  • Todo pedido leva Authorization: Bearer <key>, salvo GET /v1/health, GET /health e OPTIONS. A palavra Bearer não diferencia maiúsculas de minúsculas.
  • Chave ausente ou errada: 401 unauthorized, com o cabeçalho WWW-Authenticate: Bearer. Sem chave válida, um caminho desconhecido também volta 401, e não 404.
  • Mande a chave só no cabeçalho, nunca na URL nem no corpo.

POST /v1/decide

Responde de 1 a 32 decisões sobre um contexto. Exemplo completo em Primeira decisão.

Corpo do pedido

campotipoobrigatórioregras
modelstringnãoum id de modelo de GET /v1/models, ou um apelido que o servidor aceite para um deles (veja GET /v1/models). Omitido: o modelo padrão do servidor (o que /v1/health informa). Id desconhecido: 404 model_not_found
contextobjetosimqualquer objeto JSON, até 65.536 bytes quando serializado como JSON compacto em UTF-8. Para um único texto livre, use {"message": "<text>"}
decisionsobjetosimde 1 a 32 entradas (um servidor pode ter um limite menor): nome da decisão → objeto de decisão. Os nomes seguem ^[A-Za-z0-9_.-]{1,64}$

Qualquer outro campo no nível de cima volta 422 invalid_request, com param igual a esse campo. O corpo inteiro tem limite de 1.048.576 bytes por padrão (413 acima disso).

O contexto é lido como chega. Contexto estruturado funciona: chaves e valores fazem parte do que o Iryx lê, então nomes de chave claros ajudam ({"temperature_c": 31, "co2_ppm": 1800} em vez de {"t": 31, "c": 1800}).

Objeto de decisão

campotipostipoobrigatórioregras
kindtodosstringsimpick, check ou scale
prompttodosstringsimnão vazio nem em branco, até 2.000 caracteres
optionspickobjeto ou arraysimde 2 a 26 opções. Objeto: nome → descrição (uma string, "" aceito, até 2.000 caracteres). Array: só os nomes. Os nomes são strings não vazias, até 200 caracteres, sem repetição
levelsscalearraysimde 2 a 26 nomes de nível, do mais baixo ao mais alto. Não vazios, até 200 caracteres, sem repetição

Um campo que não pertence ao tipo (por exemplo, levels num pick) volta 422 invalid_request com param = decisions.<name>.<field>.

As decisões são sobre o contexto que você manda. Perguntas sobre o próprio serviço não são aceitas: uma decisão cujo prompt, opções ou níveis perguntem sobre o serviço volta 422 self_reference_not_supported.

Regras de cada tipo

  • pick: value é a opção com a maior probabilidade; no empate, vence a listada primeiro. confidence é a probabilidade de value (o mesmo número que spectrum[value]). spectrum traz todas as opções, na ordem do pedido.
  • check: escreva o prompt como afirmação, não como pergunta. value é a probabilidade, de 0 a 1, de a afirmação ser verdadeira; a de ser falsa é 1 - value. Não há spectrum.
  • scale: os níveis vão do mais baixo ao mais alto. spectrum traz a probabilidade de cada nível, na ordem do pedido. value é a posição esperada, contando o primeiro nível como 0 e o último como n - 1, com três casas decimais. level é o nome do nível mais perto de value (uma fração de exatamente 0,5 arredonda para cima).

Os exemplos de cada tipo estão em pick, check e scale.

Corpo da resposta (200)

campotipoo que é
idstringdec_ + 24 caracteres hexadecimais. O mesmo hex do cabeçalho X-Request-Id (req_...)
objectstringsempre "decision"
modelstringo id do modelo que respondeu, como aparece em GET /v1/models. Um pedido que usou um apelido recebe aqui o id listado, não o apelido
resultsobjetouma entrada por decisão, com os nomes do pedido, na ordem do pedido
usageobjeto{"decisions": n}: quantas decisões foram respondidas
latency_msinteirotempo que o servidor gastou no pedido, em milissegundos, da chegada à resposta. Inclui a espera atrás de pedidos anteriores; o tempo de rede não entra

O objeto de resultado, por tipo:

campopickcheckscale
kind"pick""check""scale"
valuestring: a opção escolhidanúmero de 0 a 1número de 0 a n - 1
confidencenúmero de 0 a 1não vemnão vem
levelnão vemnão vemstring: o nível mais próximo
spectrumobjeto: opção → probabilidadenão vemobjeto: nível → probabilidade

Como ler os números

  • As probabilidades têm 4 casas decimais e ficam entre 0 e 1. Um espectro soma 1, salvo o arredondamento, e uma probabilidade pequena pode arredondar para 0.
  • As respostas não dependem de sorteio, mas não se repetem até a última casa: o mesmo pedido mandado duas vezes pode voltar com probabilidades um pouco diferentes, em até cerca de 0,02 (o mesmo vale para value num check ou num scale). A opção escolhida num pick, o level de um scale e o lado de 0,5 num check ficam os mesmos, salvo quando a resposta está quase empatada.
  • Use confidence (pick) e value (check) como probabilidades. Um jeito comum: agir sozinho acima de um limite que você escolhe e mandar o resto para uma pessoa. O espectro mostra a segunda colocada.
  • Para ler sim ou não num check, compare value com 0,5, ou com um limite mais rígido quando um "sim" errado custa caro.
  • Num scale, value guarda a incerteza (1,4 fica entre "annoyed" e "angry", mais perto de "annoyed"); level é o nível com nome mais próximo, para mostrar ou encaminhar.

GET /v1/models

json
{"data": [{"id": "<model-id>", "object": "model"}]}

Lista os ids de modelo com que este servidor responde. Qualquer um deles pode ir no campo model de /v1/decide.

O servidor também pode aceitar um apelido: outro id que responde exatamente como um dos modelos listados, por exemplo um id antigo mantido para clientes que ainda o mandam. Apelidos não aparecem na lista. Um pedido com apelido é respondido pelo modelo para o qual ele aponta, e a resposta traz o id listado. Um apelido que o servidor não conhece volta 404 model_not_found, como qualquer id desconhecido.

GET /v1/health e /health

json
{"status": "ok", "model": "<model-id>", "api_version": "1"}
  • model é o modelo padrão do servidor, usado quando o pedido não diz model.
  • Não precisa de chave.
  • O servidor só começa a escutar depois de carregar o modelo: um 200 aqui quer dizer que o serviço está pronto.

OPTIONS preflight de CORS

Qualquer caminho responde 204 sem chave, com Access-Control-Allow-Methods: GET, POST, OPTIONS, Access-Control-Allow-Headers: Authorization, Content-Type e Access-Control-Max-Age: 600. A origem permitida é definida por quem opera o serviço; por padrão não há nenhuma, então uma página de outra origem, no navegador, não consegue ler as respostas.

Erros

Todo erro é JSON, com o mesmo formato:

json
{"error": {"type": "invalid_request",
           "message": "\"options\" must have between 2 and 26 items.",
           "param": "decisions.team.options"},
 "id": "req_5b1e0c9a7d2f4e6a8c3b1d0f"}
  • type: estável e para máquina. Decida por ele (e por param), não por message.
  • message: em inglês, para pessoas. Pode mudar.
  • param: aparece quando um campo causou o erro.
  • id: o id do pedido, igual ao cabeçalho X-Request-Id. Cite-o ao relatar um problema.
statustypequando
400invalid_jsono corpo está vazio, não é JSON válido em UTF-8, começa com uma marca de ordem de bytes (BOM), usa NaN ou Infinity, tem aninhamento fundo demais, tem um número fora da faixa (1e999) ou um escape de surrogate sem par ("\ud800"), é menor que o Content-Length, vem com transferência em partes (chunked), tem um Content-Length inválido, ou demora demais para chegar
400, 414, 431, 505bad_requesto próprio pedido HTTP está malformado: linha de pedido ruim (400), URL longa demais (414), cabeçalhos demais ou grandes demais (431), versão de HTTP não aceita (505)
401unauthorizedo pedido não tem um Authorization: Bearer <key> válido
404not_foundcaminho desconhecido
404model_not_foundmodel não é um dos ids de GET /v1/models (param: model)
405method_not_allowedmétodo errado para um caminho conhecido (o cabeçalho Allow lista os certos), ou um método que o servidor nem conhece (sem cabeçalho Allow)
413payload_too_largeo corpo passa do limite do servidor (1.048.576 bytes por padrão). A mensagem diz o limite
422invalid_requestJSON válido que quebra uma regra desta referência: campo ausente ou desconhecido, tipo errado, limite ultrapassado, nomes de opção ou de nível repetidos
422self_reference_not_supporteduma decisão pergunta sobre o próprio serviço, e não sobre o contexto (param: o prompt, as options ou os levels dessa decisão). Nada foi decidido
422context_too_longo pedido é válido, mas o contexto e as decisões passam do que o modelo lê de uma vez (veja Limites). param é sempre context e a mensagem é sempre context too long for this model. Nada foi decidido: encurte o contexto ou divida as decisões em vários pedidos
500internal_erroruma falha inesperada. A mensagem é genérica; o id do pedido permite a quem opera o serviço achar o caso
503overloadedo servidor está no limite e não conseguiu responder agora. O cabeçalho Retry-After diz quantos segundos esperar antes de tentar de novo. Nada foi decidido; o pedido pode ser repetido igual

Mensagens de 400

mensagem
Request body is empty. Send a JSON object.
Request body is not valid JSON.
Numbers must be finite (a number in the body is out of range).
Request body has an unpaired surrogate escape (invalid Unicode).
Send the body with a Content-Length header (chunked transfer is not supported).
Invalid Content-Length header.
Request body ended before Content-Length bytes.
Timed out reading the request body.

Formas de param

paramaponta para
modelo campo model
contexto campo context (ausente, não é objeto, grande demais), e todo context_too_long
decisionso campo decisions, ou um nome de decisão inválido
decisions.team.kind, decisions.team.promptum campo de uma decisão
decisions.team.options, decisions.mood.levelsa lista ou o objeto inteiro
decisions.team.options[1], decisions.mood.levels[0]um item de uma lista
decisions.team.options.billinga descrição de uma opção
qualquer outro nomeum campo desconhecido no nível de cima

Cabeçalhos

Mande:

cabeçalhoquando
Content-Type: application/jsonem todo POST
Content-Lengthem todo pedido com corpo. Transferência em partes (chunked) não é aceita
Authorization: Bearer <key>em todo pedido que pede chave (veja Autenticação)

Toda resposta JSON (todos os status, salvo o 204 de OPTIONS) traz:

cabeçalhovalor
Content-Typeapplication/json; charset=utf-8
X-Request-Idreq_ + 24 caracteres hexadecimais
Cache-Controlno-store
X-Content-Type-Optionsnosniff
Serveriryx
Access-Control-Allow-Origina origem permitida, quando o CORS está ligado (com Access-Control-Expose-Headers: X-Request-Id, Retry-After, e Vary: Origin quando a origem não é *)
WWW-Authenticate: Bearerno 401
Allowno 405 de um caminho conhecido
Retry-Afterno 503: os segundos de espera antes de tentar de novo

A resposta 204 a OPTIONS não tem corpo: traz X-Request-Id, Server, Allow e os cabeçalhos de CORS acima.

As conexões são HTTP/1.1 keep-alive. O servidor fecha a conexão depois de um erro que deixou parte do corpo sem ler.

Limites

o quêlimite
corpo do pedido1.048.576 bytes por padrão
context65.536 bytes, serializado como JSON compacto em UTF-8
decisões por pedidode 1 a 32
nome de decisãode 1 a 64 caracteres entre A-Z a-z 0-9 _ . -
promptde 1 a 2.000 caracteres
opções (pick), níveis (scale)de 2 a 26
nome de opção ou de nívelde 1 a 200 caracteres
descrição de opçãode 0 a 2.000 caracteres
silêncio numa conexão60 s: uma conexão que não manda nada por 60 s é fechada (no meio de um corpo, com 400 invalid_json)
o que o modelo lê de uma vezveja abaixo; acima disso, 422 context_too_long

Quanto o modelo lê de uma vez

Cada decisão é lida junto com o contexto inteiro. Quanto maior o contexto e quanto mais decisões no pedido, mais cedo chega o limite. Para prosa comum, com um prompt curto e poucas opções curtas por decisão, o contexto cabe em cerca de:

decisões no pedidocontexto, cerca de
1 a 46.000 caracteres
83.000 caracteres
161.300 caracteres
32500 caracteres

Os números são aproximados de propósito. prompt e descrições longos também contam, e texto que não é prosa comum (números, código, JSON com muitas chaves curtas, emoji, algumas escritas não latinas) chega ao limite antes. Se vier context_too_long, mande o mesmo contexto com menos decisões por pedido, ou um contexto menor. O limite em bytes do context, na tabela acima, é outro teto, maior, sobre o próprio pedido.

Pedidos que chegam com o servidor ocupado esperam a vez; a espera aparece em latency_ms. Quando o servidor está no limite, responde 503 overloaded com Retry-After: espere esses segundos e mande o mesmo pedido de novo. A v1 não tem cabeçalhos de limite de taxa.

Versões

  • A versão da API está no caminho (/v1) e em GET /v1/health ("api_version": "1"). Uma mudança que quebraria clientes da v1 vai para um caminho novo.
  • Dentro da v1, as respostas podem ganhar campos opcionais novos. O cliente deve ignorar os campos que não conhece.
  • Ids de modelo são fixos: um id sempre nomeia o mesmo modelo, e cada apelido dele também. Um modelo novo ganha um id novo, listado em GET /v1/models. Para seguir o modelo padrão do servidor em vez de fixar um, omita model.

Dados

  • O servidor não guarda o que você manda nem o que ele responde. Lê o pedido, decide na memória e responde. Como o conteúdo não fica guardado, não é reusado para nada.
  • O registro do servidor tem uma linha por pedido: hora, id do pedido, método, rota, status, número de decisões e duração. Nunca o contexto, os prompts, as opções ou os resultados.
  • Um erro inesperado acrescenta ao registro o tipo do erro e o lugar no código, sem a mensagem do erro, que poderia repetir conteúdo do cliente.
  • As respostas levam Cache-Control: no-store.

O serviço hospedado ainda não está no ar; as regras dele vão estar nos termos de uso antes do primeiro cliente.

Fora da v1

  • Geração de texto, streaming, ou vários contextos num pedido (mande um pedido por contexto).
  • Chaves de idempotência, cabeçalhos de limite de taxa e envio em partes (chunked).
  • Qualquer campo que diga como uma resposta foi produzida: a resposta traz a decisão, as probabilidades e a contagem de uso, nada mais.