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_URLe a chave, emIRYX_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.
export IRYX_URL="<o endereço que vem com o acesso>"
export IRYX_KEY="<a sua chave>"$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.
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.
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):
{"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}resultstraz uma entrada por decisão, com os nomes do pedido, na ordem do pedido.usage.decisionsconta as decisões respondidas: é a unidade de uso.ididentifica a resposta:dec_e 24 caracteres hexadecimais, o mesmo hex do cabeçalhoX-Request-Id.modelé o id do modelo que respondeu, como aparece emGET /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.
"team": {"kind": "pick", "prompt": "Which team should handle this ticket?",
"options": {"billing": "charges, invoices, refunds", "tech": "bugs, API, outages", "sales": "prices, plans, upgrades"}}"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 devalue(o mesmo número quespectrum[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.
"urgent": {"kind": "check", "prompt": "Needs a reply within hours"}"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.
"mood": {"kind": "scale", "prompt": "Customer frustration", "levels": ["calm", "annoyed", "angry"]}"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 comon - 1:0 × 0.1 + 1 × 0.4 + 2 × 0.5 = 1.4. Três casas decimais.level: o nome do nível mais perto devalue(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:
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 pedido | contexto, cerca de |
|---|---|
| 1 a 4 | 6.000 caracteres |
| 8 | 3.000 caracteres |
| 16 | 1.300 caracteres |
| 32 | 500 caracteres |
- Passou do limite: volta
422 context_too_longe nada foi decidido. Mande o mesmo contexto com menos decisões por pedido, ou um contexto menor. - Servidor no limite: volta
503 overloadedcom o cabeçalhoRetry-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 ospectrummostra 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:valueguarda 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.
"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.
- Escolha um limite para cada decisão. Acima dele, o software age sozinho; abaixo, uma pessoa decide.
- Mande para a pessoa o espectro junto: ele mostra a segunda colocada.
- Num
check, use um limite mais rígido que 0,5 quando um "sim" errado custa caro. - Uma resposta quase empatada pode mudar de lado entre dois pedidos iguais: é mais um motivo para uma pessoa conferir.
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
| Protocolo | HTTP/1.1, corpo JSON em UTF-8 |
|---|---|
| Endereço | vem com o acesso (IRYX_URL nos exemplos) |
| Versão | prefixo /v1 no caminho; GET /v1/health informa "api_version": "1" |
| Autenticação | Authorization: Bearer <key> |
| Unidade de uso | a decisão: toda resposta informa usage.decisions |
| método | caminho | o que faz | chave |
|---|---|---|---|
POST | /v1/decide | responde de 1 a 32 decisões sobre um contexto | sim |
GET | /v1/models | lista os ids de modelo com que o servidor responde | sim |
GET | /v1/health | se o serviço está vivo e pronto | não |
GET | /health | o mesmo que /v1/health | não |
OPTIONS | qualquer caminho | preflight de CORS | não |
Autenticação
- Todo pedido leva
Authorization: Bearer <key>, salvoGET /v1/health,GET /healtheOPTIONS. A palavraBearernão diferencia maiúsculas de minúsculas. - Chave ausente ou errada:
401 unauthorized, com o cabeçalhoWWW-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
| campo | tipo | obrigatório | regras |
|---|---|---|---|
model | string | não | um 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 |
context | objeto | sim | qualquer objeto JSON, até 65.536 bytes quando serializado como JSON compacto em UTF-8. Para um único texto livre, use {"message": "<text>"} |
decisions | objeto | sim | de 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
| campo | tipos | tipo | obrigatório | regras |
|---|---|---|---|---|
kind | todos | string | sim | pick, check ou scale |
prompt | todos | string | sim | não vazio nem em branco, até 2.000 caracteres |
options | pick | objeto ou array | sim | de 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 |
levels | scale | array | sim | de 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 devalue(o mesmo número quespectrum[value]).spectrumtraz todas as opções, na ordem do pedido.check: escreva opromptcomo 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.spectrumtraz 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 comon - 1, com três casas decimais.levelé o nome do nível mais perto devalue(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)
| campo | tipo | o que é |
|---|---|---|
id | string | dec_ + 24 caracteres hexadecimais. O mesmo hex do cabeçalho X-Request-Id (req_...) |
object | string | sempre "decision" |
model | string | o 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 |
results | objeto | uma entrada por decisão, com os nomes do pedido, na ordem do pedido |
usage | objeto | {"decisions": n}: quantas decisões foram respondidas |
latency_ms | inteiro | tempo 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:
| campo | pick | check | scale |
|---|---|---|---|
kind | "pick" | "check" | "scale" |
value | string: a opção escolhida | número de 0 a 1 | número de 0 a n - 1 |
confidence | número de 0 a 1 | não vem | não vem |
level | não vem | não vem | string: o nível mais próximo |
spectrum | objeto: opção → probabilidade | não vem | objeto: 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
valuenumcheckou numscale). A opção escolhida numpick, olevelde umscalee o lado de 0,5 numcheckficam os mesmos, salvo quando a resposta está quase empatada. - Use
confidence(pick) evalue(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, comparevaluecom 0,5, ou com um limite mais rígido quando um "sim" errado custa caro. - Num
scale,valueguarda 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
{"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
{"status": "ok", "model": "<model-id>", "api_version": "1"}modelé o modelo padrão do servidor, usado quando o pedido não dizmodel.- 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:
{"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 porparam), não pormessage.message: em inglês, para pessoas. Pode mudar.param: aparece quando um campo causou o erro.id: o id do pedido, igual ao cabeçalhoX-Request-Id. Cite-o ao relatar um problema.
| status | type | quando |
|---|---|---|
| 400 | invalid_json | o 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, 505 | bad_request | o 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) |
| 401 | unauthorized | o pedido não tem um Authorization: Bearer <key> válido |
| 404 | not_found | caminho desconhecido |
| 404 | model_not_found | model não é um dos ids de GET /v1/models (param: model) |
| 405 | method_not_allowed | mé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) |
| 413 | payload_too_large | o corpo passa do limite do servidor (1.048.576 bytes por padrão). A mensagem diz o limite |
| 422 | invalid_request | JSON 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 |
| 422 | self_reference_not_supported | uma 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 |
| 422 | context_too_long | o 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 |
| 500 | internal_error | uma falha inesperada. A mensagem é genérica; o id do pedido permite a quem opera o serviço achar o caso |
| 503 | overloaded | o 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
param | aponta para |
|---|---|
model | o campo model |
context | o campo context (ausente, não é objeto, grande demais), e todo context_too_long |
decisions | o campo decisions, ou um nome de decisão inválido |
decisions.team.kind, decisions.team.prompt | um campo de uma decisão |
decisions.team.options, decisions.mood.levels | a lista ou o objeto inteiro |
decisions.team.options[1], decisions.mood.levels[0] | um item de uma lista |
decisions.team.options.billing | a descrição de uma opção |
| qualquer outro nome | um campo desconhecido no nível de cima |
Cabeçalhos
Mande:
| cabeçalho | quando |
|---|---|
Content-Type: application/json | em todo POST |
Content-Length | em 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çalho | valor |
|---|---|
Content-Type | application/json; charset=utf-8 |
X-Request-Id | req_ + 24 caracteres hexadecimais |
Cache-Control | no-store |
X-Content-Type-Options | nosniff |
Server | iryx |
Access-Control-Allow-Origin | a 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: Bearer | no 401 |
Allow | no 405 de um caminho conhecido |
Retry-After | no 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 pedido | 1.048.576 bytes por padrão |
context | 65.536 bytes, serializado como JSON compacto em UTF-8 |
| decisões por pedido | de 1 a 32 |
| nome de decisão | de 1 a 64 caracteres entre A-Z a-z 0-9 _ . - |
prompt | de 1 a 2.000 caracteres |
| opções (pick), níveis (scale) | de 2 a 26 |
| nome de opção ou de nível | de 1 a 200 caracteres |
| descrição de opção | de 0 a 2.000 caracteres |
| silêncio numa conexão | 60 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 vez | veja 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 pedido | contexto, cerca de |
|---|---|
| 1 a 4 | 6.000 caracteres |
| 8 | 3.000 caracteres |
| 16 | 1.300 caracteres |
| 32 | 500 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 emGET /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, omitamodel.
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.