Pontos principais
- O rótulo cobre caminhos de URL, formatos de requisição e resposta JSON, autenticação Bearer e streaming SSE.
- Não diz nada sobre qual modelo responde, como ele se comporta ou quanto custa.
- A troca geralmente significa alterar dois valores: base URL e chave de API.
- Teste streaming, ferramentas, modo JSON e códigos de erro antes de confiar em um provedor.
A resposta curta
Quando um provedor diz que sua API é openai-compatible, significa que ela aceita as mesmas requisições HTTP que as bibliotecas cliente da OpenAI enviam e retorna respostas no mesmo formato. Você mantém seu código, altera a base URL e a chave, e a chamada vai para um servidor diferente.
Essa é toda a promessa. É uma declaração sobre a interface, como dizer que dois carregadores usam a mesma tomada. Não diz o que está na outra ponta do cabo. O modelo, suas regras de segurança, seu preço e seus limites são todos decididos pelo provedor e variam muito.
O que o rótulo realmente cobre
Na prática, a compatibilidade com OpenAI é uma lista curta de coisas concretas. Se um provedor suportar todas elas, a maioria do código cliente roda sem alterações.
- Caminhos. Requisições de chat vão para
POST /v1/chat/completionse a lista de modelos vem deGET /v1/models. - Autenticação. A chave viaja em um cabeçalho
Authorization: Bearer. - Corpo da requisição. Uma string
model, um arraymessagesde objetos comroleecontent, e campos de amostragem opcionais comotemperature,top_p,stopeseed. - Corpo da resposta. Um array
choicescontendo a mensagem do assistente, umfinish_reasone um objetousagecom contagens de tokens. - Streaming. Com
stream: trueo servidor envia Server-Sent Events, cada um carregando um pequeno delta JSON, terminando com um marcador final. - Funcionalidades opcionais. Chamada de funções, modo JSON e campos semelhantes, onde o provedor escolhe suportá-los.
Como muitas ferramentas foram escritas contra esse formato, ele se tornou um alvo comum. Editores, frameworks de agentes, interfaces de roleplay e scripts simples permitem que você insira uma base URL personalizada, e isso é tudo o que eles precisam.
Por que um formato se tornou o alvo comum
O formato de chat completion se espalhou porque era simples e chegou cedo. Um autor de ferramentas que o suporta uma vez pode alcançar muitos backends, e um autor de backend que o suporta uma vez pode alcançar muitas ferramentas. É um bom negócio para ambos os lados, então o formato permaneceu, mesmo entre serviços que não têm nada a ver com a empresa que o projetou.
Para você como desenvolvedor, isso tem um significado prático. Seu código não precisa de uma integração diferente para cada provedor. Você pode mover um protótipo entre endpoints em uma tarde, comparar dois modelos nos mesmos prompts ou manter um segundo provedor como fallback quando o primeiro estiver lento. O custo de mudar de ideia é baixo, e isso facilita tentar um novo serviço sem se comprometer com ele.
O lado oposto é que a superfície compartilhada esconde diferenças reais. Como a troca é tão fácil, é tentador assumir que tudo por trás da URL é equivalente. Não é, e as seções abaixo mostram onde as lacunas geralmente aparecem.
O que ele não diz a você
Aqui é onde as pessoas se surpreendem. O rótulo deixa de fora tudo o que determina se a API é útil para o seu trabalho.
O modelo por trás disso
Um endpoint compatível pode servir qualquer modelo. Alguns servem modelos de pesos abertos, alguns roteiam para vários fornecedores, alguns envolvem um modelo proprietário. A compatibilidade não significa que o serviço é executado pela OpenAI, nem que o modelo se comporte como um deles. O nome do modelo que você passa em model é apenas uma string definida pelo provedor.
Comportamento de recusa
Regras de conteúdo pertencem ao modelo e ao provedor, não ao protocolo. Duas APIs compatíveis podem responder ao mesmo prompt de maneiras opostas. Se o seu caso de uso é ficção, roleplay ou outro conteúdo adulto lícito, verifique o que o provedor diz sobre recusas antes de conectar qualquer coisa.
Profundidade de recursos
Alguns provedores implementam apenas chat. Outros adicionam ferramentas, modo JSON, logprobs ou endpoints extras. Um cliente que envia um campo que o servidor ignora nem sempre falhará visivelmente, então uma incompatibilidade silenciosa é possível.
Limites, preços e erros
Limites de requisições, comprimento do contexto, tamanho máximo do corpo e preço por token são todas escolhas do provedor. Os corpos de erro também diferem em detalhes mesmo quando os códigos de status HTTP correspondem, então a lógica de retry deve usar códigos de status e cabeçalhos em vez de texto de mensagem.
Um teste rápido de compatibilidade
Você pode verificar um provedor em alguns minutos com três requisições. Substitua a chave pela sua. Este exemplo usa a base URL deste site.
curl https://api.kimicode.top/v1/models \
-H "Authorization: Bearer YOUR_API_KEY"
curl https://api.kimicode.top/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [{"role": "user", "content": "Reply with the word ready."}]
}'
A primeira chamada confirma a chave e lista IDs de modelos. A segunda verifica o formato de chat. Depois teste as partes das quais sua aplicação depende: adicione "stream": true e observe os chunks incrementais, passe um array tools se usar chamada de funções e defina response_format para {"type":"json_object"} se precisar de saída analisável.
Também dispare um erro propositalmente, como uma chave inválida. Você quer ver um status HTTP limpo e um corpo de erro JSON que seu cliente possa lidar.
A mesma chamada em Node
O SDK JavaScript usa os mesmos dois valores. Aqui está uma chamada de streaming, que é o formato que a maioria das interfaces de chat usa.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.kimicode.top/v1",
apiKey: process.env.API_KEY,
});
const stream = await client.chat.completions.create({
model: "uncensored",
stream: true,
messages: [{ role: "user", content: "Name three uses of SSE." }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Se isso imprimir texto palavra por palavra, o caminho de streaming funciona de ponta a ponta. O mesmo loop funciona contra qualquer provedor compatível, que é o ponto inteiro do formato.
Como parece a troca no código
Com o SDK Python oficial, a mudança são dois argumentos do construtor. O resto do seu programa permanece como era.
from openai import OpenAI
client = OpenAI(
base_url="https://api.kimicode.top/v1",
api_key="YOUR_API_KEY",
)
resp = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Summarize SSE in one sentence."}],
)
print(resp.choices[0].message.content)
O SDK Node é a mesma ideia com as opções baseURL e apiKey. Muitas ferramentas leem OPENAI_BASE_URL e OPENAI_API_KEY do ambiente, então às vezes você pode trocar sem tocar no código.
Lembre-se de alterar a string do modelo também. Uma requisição que nomeia um modelo que o novo servidor não hospeda falhará, e esse é o primeiro erro mais comum.
Onde a API deste site se encaixa
Este serviço é uma API hospedada, apenas texto, que segue o formato OpenAI. Executa um modelo de pesos abertos, operado por um provedor independente e ajustado para responder sem recusas de conteúdo para uso adulto lícito. Não é a API oficial de nenhum fornecedor de modelo e não roteia entre fornecedores. O ID do modelo é uncensored.
Suporta streaming sobre SSE com uso relatado no final, chamada de funções, modo JSON, e passa-through de temperature, top_p, stop, seed e penalidades. A janela de contexto é de 100.000 tokens para prompt e conclusão juntos. Não gera imagens ou áudio, e não oferece embeddings ou fine-tuning. Uma regra é fixa: sem conteúdo sexual envolvendo menores de idade.
A cobrança é pré-paga e medida: $0,15 por 1M tokens de entrada e $0,50 por 1M tokens de saída, sem assinatura. Você pode ver os números na página de preços, e a documentação passa por uma primeira requisição. Se quiser experimentar sem pagar, novas contas podem reivindicar um crédito de teste de $0,50 com um clique na página da chave de API.
Armadilhas comuns de compatibilidade
- URL base incorreta. A URL deve terminar em
/v1. Os clientes adicionam/chat/completionspor conta própria; incluí-la na URL base gera erro 404. - Parâmetros não suportados. Se uma biblioteca enviar um campo que o servidor não conhece, verifique se ele é rejeitado ou descartado silenciosamente e, em seguida, remova-o.
- Streaming e concorrência. Uma requisição em streaming ocupa uma vaga de concorrência até o fim do fluxo. Se seu aplicativo abrir muitos streams, você pode atingir o limite de 429 com o código
concurrency, mesmo que sua contagem por minuto seja baixa. - Tente novamente em caso de 429. Trate 429 como um sinal para aguardar. Quando o cabeçalho
Retry-Afterestiver presente, honre-o. - Contagem de tokens. Não assuma que o tokenizador de outro provedor é igual. Leia o objeto
usagena resposta para obter os números pelos quais você será cobrado.
Nenhum desses é difícil de corrigir assim que você sabe procurá-los, e a maioria se resume a ler atentamente a primeira mensagem de erro.
