A API Qwen tem dois modos comuns de chamada: a interface nativa DashScope do Alibaba Cloud Bailian e a interface compatível com OpenAI. As estruturas de erro não são idênticas, mas a ordem de diagnóstico é a mesma: primeiro o status HTTP, depois o code e a message no corpo da resposta, em seguida o request_id, depois reproduza com uma requisição mínima e só então altere parâmetros ou troque de modelo.
Este artigo separa 401, 404, 429, 400, 5xx e timeout, com tabela de códigos, campos de log, código de retentativa e um checklist para antes de contatar o suporte. Modelos, cotas e cobrança seguem a documentação do fornecedor e a página de preços do site.
Nota: Qwen, Tongyi Qianwen, Alibaba Cloud, Bailian e DashScope são marcas do Alibaba Group e de seus titulares. Este artigo é apenas uma discussão técnica de diagnóstico e não implica vínculo de subordinação, representação ou parceria com essas empresas. Códigos de erro, critérios de limitação e comportamento da interface podem mudar entre versões; prevalecem a documentação do fornecedor e a resposta real.
1. Distinga primeiro o modo de interface e a estrutura de erro
A interface nativa DashScope normalmente retorna code, message e request_id no nível superior da resposta. A interface compatível com OpenAI segue o estilo OpenAI, com corpo de erro no formato {"error": {"message": "...", "type": "...", "code": "..."}}. No modo compatível, o request_id pode aparecer no cabeçalho ou no corpo; o nome do campo depende da resposta real.
Na engenharia, não analise apenas uma estrutura. Grave primeiro o corpo completo da resposta no log, sem alterações, e depois leia na ordem error.code e code de nível superior. Assim, ao trocar de modo de interface, o código de tratamento de erros não precisa ser reescrito.
2. 401: falha de autenticação, verifique primeiro a região
401 indica que a identidade não foi validada e normalmente não tem relação com capacidade do modelo ou saldo. No Bailian, as três falhas mais comuns são:
InvalidApiKeyouinvalid_api_key: Key errada, cópia incompleta, ou Base URL incompatível com a região da Key.invalid access token or token expired: token expirado, ou uso de endereço exclusivo de plano com uma Key comum.NOT AUTHORIZED: WorkspaceId inválido, ou conta fora daquele workspace.
As Keys da Qwen são vinculadas à região. Keys de Pequim e de Singapura não podem ser misturadas. Este é o ponto mais fácil de esquecer: o código não muda, só a Base URL, e o 401 se repete de forma estável.
Diagnostique nesta ordem:
- Confirme se o cabeçalho é
Authorization: Bearer <key>, com um espaço após os dois-pontos. - Imprima o prefixo da variável de ambiente e confirme que não está vazia, desatualizada ou com quebra de linha.
- Verifique se Base URL e Key pertencem à mesma região.
- Confirme se o tipo de Key corresponde à interface: pagamento por uso, plano Coding e plano de tokens têm endereços diferentes.
- Troque por uma Key nova e faça uma requisição mínima para separar problema de Key de problema de proxy ou gateway.
3. 404 e 400: nome do modelo, ativação e contexto
404 na maioria das vezes não é falha do serviço, mas problema de nome ou disponibilidade do modelo. Em ModelNotFound ou model_not_found, verifique três coisas: se o nome está escrito corretamente, se o modelo foi ativado e se está disponível na região atual. model_not_supported indica que o modelo não suporta o modo compatível com OpenAI; é preciso trocar a interface ou o modelo.
As causas de 400 são mais variadas. InvalidParameter é parâmetro fora do intervalo, por exemplo temperature ou top_p fora da faixa. InvalidParameter.NotSupportEnableThinking indica que o modelo não suporta o parâmetro de modo de raciocínio. Contexto excedido geralmente retorna Range of input length should be [1, xxx], com código interno InternalError.Algo.InvalidParameter, ou então o comprimento total das mensagens ultrapassa o limite do modelo. A solução é cortar o histórico, resumir por blocos ou usar um modelo de contexto longo, não repetir a requisição.
4. 429: separe quatro tipos de limite e duas categorias de cota
429 é o erro mais sujeito a tratamento errado. No Bailian, o 429 inclui pelo menos as categorias abaixo; a tabela também lista erros de inadimplência e de serviço não ativado que costumam ser confundidos com limitação:
| HTTP | Código de erro | Significado | Indicado repetir |
|---|---|---|---|
| 429 | Throttling.RateQuota, LimitRequests |
Requisições por minuto (RPM) acima do limite | Sim, com backoff |
| 429 | Throttling.AllocationQuota, insufficient_quota |
Tokens por minuto (TPM) acima do limite | Sim, backoff e reduzir entrada |
| 429 | Throttling.BurstRate |
Proteção contra pico curto de tráfego | Sim, suavizar o ritmo |
| 429 | Throttling.Concurrency |
Concorrência excessiva | Sim, reduzir concorrência |
| 429 | AllocationQuota.FreeTierOnly |
Cota gratuita esgotada com modo "somente gratuito" ativo | Não, recarregar ou desativar o modo |
| 429 | BudgetLimitExceeded |
Orçamento da conta esgotado | Não, ajustar o orçamento |
| 400 | Arrearage |
Conta inadimplente ou em estado anormal | Não, regularizar a conta |
| 403 | AccessDenied.Unpurchased |
Serviço não ativado | Não, ativar primeiro |
A limitação é contabilizada pela conta principal da Alibaba Cloud. Chamadas de subcontas RAM, workspaces e várias Keys são somadas. Portanto, "uma Key por serviço" não contorna a cota total; apenas evita disputa entre serviços. A limitação normalmente se recupera em nível de minuto; durante a espera, não repita em alta frequência.
5. Timeout e 5xx: localize em três segmentos
O timeout deve ser analisado em três partes: timeout de conexão geralmente é DNS, saída de rede ou proxy inacessível; primeiro token lento costuma ser fila no upstream ou entrada longa; timeout de leitura pode ser saída longa ou raciocínio demorado. O tratamento é diferente em cada caso; não basta aumentar o tempo limite.
No Bailian, RequestTimeOut indica requisição expirada, com limite documentado de 300 segundos; GatewayTimeout.InputDownload está relacionado ao download do arquivo de entrada. A interface compatível com OpenAI também pode retornar 503, indicando sobrecarga do motor. Quando um fluxo é interrompido, pode não haver código de erro: registre o conteúdo já recebido, o último trecho de dados e o motivo de encerramento, e só então determinar se foi oscilação de rede, corte do proxy ou timeout do upstream.
6. request_id e logs: a evidência do diagnóstico
A documentação informa que o request_id acompanha a resposta e pode estar no cabeçalho ou no corpo. Recomenda-se registro em duas vias: o cliente gera um trace_id que atravessa todas as retentativas e, ao mesmo tempo, guarda sem alterações o identificador do cabeçalho e o request_id do corpo. Se não houver registro, procure nos logs de monitoramento de modelos do console, desde que o log de inferência esteja ativado.
O log deve conter pelo menos: horário, trace_id, Base URL, região, nome do modelo, status HTTP, código de erro, mensagem, request_id, duração, número de tentativas e se é streaming. Registre apenas os primeiros caracteres da Key ou seu hash; não grave o texto do usuário nem a resposta completa em disco. Ao contatar o suporte, um registro com esses campos é muito mais útil do que "às vezes dá erro".
7. Retentativa e backoff: código de exemplo
O código abaixo desativa a retentativa automática do SDK, repete apenas 429 e 5xx recuperáveis e imprime status, código de erro e request_id juntos. Inadimplência, cota gratuita esgotada e orçamento excedido ficam fora do escopo de retentativa.
import os
import random
import time
import uuid
import httpx
from openai import OpenAI, APIConnectionError, APIStatusError, APITimeoutError
client = OpenAI(
api_key=os.environ["DASHSCOPE_API_KEY"],
base_url=os.environ.get(
"DASHSCOPE_BASE_URL",
"https://dashscope.aliyuncs.com/compatible-mode/v1",
),
timeout=httpx.Timeout(connect=5.0, read=180.0, write=30.0, pool=10.0),
max_retries=0, # desativa a retentativa automática do SDK; a lógica abaixo controla tudo
)
RETRYABLE_429 = {
"Throttling",
"Throttling.RateQuota",
"Throttling.AllocationQuota",
"Throttling.BurstRate",
"Throttling.Concurrency",
"LimitRequests",
"limit_requests",
"ResourceExhausted",
}
def unpack_error(exc: APIStatusError):
body = {}
try:
body = exc.response.json()
except Exception:
pass
err = body.get("error", body) if isinstance(body, dict) else {}
code = err.get("code") if isinstance(err, dict) else None
request_id = None
if isinstance(body, dict):
request_id = body.get("request_id")
request_id = (
request_id
or exc.response.headers.get("x-request-id")
or exc.response.headers.get("x-dashscope-request-id")
)
return code, request_id, exc.response.text[:500]
def ask(prompt: str, model: str, max_attempts: int = 4) -> str:
trace_id = uuid.uuid4().hex[:12]
for attempt in range(1, max_attempts + 1):
try:
resp = client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": prompt}],
)
return resp.choices[0].message.content
except APIStatusError as exc:
code, request_id, body = unpack_error(exc)
print(
f"trace={trace_id} attempt={attempt} "
f"http={exc.status_code} code={code} "
f"request_id={request_id} body={body}"
)
retryable = exc.status_code >= 500 or (
exc.status_code == 429 and code in RETRYABLE_429
)
if not retryable or attempt == max_attempts:
raise
except (APITimeoutError, APIConnectionError) as exc:
print(f"trace={trace_id} attempt={attempt} err={type(exc).__name__}")
if attempt == max_attempts:
raise
wait = min(2 ** (attempt - 1), 30) + random.uniform(0, 1)
time.sleep(wait)
raise RuntimeError("tentativas esgotadas")
Três regras adicionais: se o servidor retornar Retry-After, respeite-o; controle o orçamento de retentativas globalmente para que vários serviços não amplifiquem o tráfego ao mesmo tempo; em requisições com efeitos colaterais, confirme primeiro se já foram executadas antes de reenviar.
8. Governança de concorrência: mais eficaz do que aumentar retentativas
Problemas de limite geralmente não se resolvem com retentativa, mas com governança na entrada:
- Separe Keys por negócio e defina limites de concorrência distintos, para que uma tarefa em lote não derrube o serviço online.
- Fragmente tarefas em lote e distribua horários, evitando picos no minuto cheio.
- Use filas para suavizar picos; tarefas com falha vão para fila com atraso em vez de repetir sem controle.
- Monitore a proporção de 429 e a latência p95; ao ver salto, reduza a concorrência primeiro.
- Para tarefas offline, prefira a interface Batch e evite a limitação em tempo real.
- Tenha um modelo ou entrada alternativa e confirme a compatibilidade de parâmetros antes da troca.
Os limites são configurados por modelo e conta; recarregar não eleva automaticamente RPM ou TPM. Se precisar de cota maior, faça solicitação comercial; não copie números de terceiros.
9. Checklist para antes de contatar o suporte
- Horário e fuso do incidente, e se foi contínuo ou esporádico.
- Base URL, região, caminho da interface, nome do modelo e método da requisição.
- Status HTTP, código de erro e mensagem completa.
request_id; se não houver, informe otrace_idgerado por você.- Uma requisição curl mínima reproduzível, com a Key mascarada.
- Se é streaming, contexto longo, ou se a configuração mudou recentemente.
- Escopo: uma Key, um workspace ou todo o serviço.
10. Perguntas frequentes (FAQ)
1. Todo 429 é limitação de taxa?
Não. O 429 também pode ser cota gratuita esgotada ou orçamento excedido; inadimplência pode retornar 400 Arrearage, e serviço não ativado pode retornar 403. Leia primeiro o código de erro e só então decida entre backoff, recarga ou ajuste de configuração.
2. O 401 continua mesmo com uma Key nova. O que fazer?
Verifique região e tipo de Key. As Keys da Qwen são vinculadas à região: uma Key de Pequim com endereço de Singapura retorna 401; endereço exclusivo de plano com Key comum também falha. Depois, confira cabeçalho, variáveis de ambiente e se o proxy reverso descarta a autenticação.
3. Como tratar contexto excedido?
Corte primeiro as mensagens antigas, remova anexos irrelevantes e parágrafos repetidos; depois resuma documentos longos em blocos ou use recuperação; se ainda não bastar, troque para um modelo de contexto longo. Não tente resolver entrada excessiva aumentando max_tokens.
4. Timeout deve ser repetido?
Faça retentativas limitadas apenas para falha de conexão e timeout de leitura, com backoff exponencial e teto. Em operações com efeitos colaterais, confirme antes se já foram executadas, para evitar pedido ou gravação duplicados.
5. Onde encontrar o request_id?
Primeiro no cabeçalho e no corpo da resposta; o nome do campo depende da interface. Se não houver registro, procure nos logs de monitoramento de modelos do console, com o log de inferência ativado. Ao contatar o suporte, envie também o trace_id e a requisição mínima de reprodução.
Próximos passos
Crie primeiro uma Key de teste no ZSQH AI Gateway, ensaie uma vez cada caso — 401, 404, 429, contexto excedido e timeout — e só então conecte o monitoramento de produção. Modelos disponíveis e formas de cobrança estão na página de preços.
