Kimi K2.7 Code is now on CometAPI — Kimi's most intelligent coding model to date, reliably follows instructions in long contexts and completes programming tasks with a higher success rate. Try it now

Cara menyahpepijat penjanaan API AI yang gagal

CometAPI
AnnaJun 4, 2026
Cara menyahpepijat penjanaan API AI yang gagal

Kegagalan API AI berbeza daripada kegagalan API biasa. Respons 200 tidak bermaksud penjanaan anda berjaya. Medan content yang null tidak semestinya satu ralat. Dan gesaan yang berjaya semalam mungkin gagal hari ini kerana penyedia mengemas kini dasar kandungan mereka.

Panduan ini merangkumi cara membaca ralat API AI, maksud setiap mod kegagalan, dan cara membina pengendalian ralat yang memberitahu anda apa yang rosak dan bukannya sekadar sesuatu telah rosak.

Nota: Nama model seperti gpt-5.4 dan gpt-5.4-mini yang digunakan dalam artikel ini ialah pengecam platform CometAPI. Ia berfungsi melalui https://api.cometapi.com/v1 sahaja — bukan terus melalui API OpenAI atau Anthropic. Lihat senarai model penuh.

Mengapa nyahpepijat API AI lebih sukar berbanding nyahpepijat API biasa

Dengan API REST lazim, 200 bermaksud berjaya dan 4xx bermaksud anda melakukan sesuatu yang salah. API AI menambah kategori ketiga: kegagalan lembut — respons yang memulangkan 200 tetapi tidak mengandungi kandungan yang boleh digunakan.

Tiga perkara boleh berlaku:

  1. Kegagalan keras — ralat HTTP (4xx, 5xx). Permintaan tidak selesai.
  2. Kegagalan lembut — HTTP 200, tetapi finish_reason ialah content_filter atau length, atau content ialah null.
  3. Kegagalan senyap — HTTP 200, kandungan kelihatan baik, tetapi output salah dengan cara yang hanya dapat anda kesan di lapisan aplikasi.

Kebanyakan pengendalian ralat hanya merangkumi kes 1. Kes 2 dan 3 ialah tempat kebanyakan pepijat produksi wujud.

Fahami format respons ralat

Titik akhir penyempurnaan teks memulangkan struktur ralat yang konsisten:

{  "error": {    "message": "human-readable description (often includes request id)",    "type": "comet_api_error",    "param": "the_problematic_parameter_or_null",    "code": "error_code_or_null"  }}

Titik akhir imej dan video memulangkan format ralat yang berbeza — sentiasa hurai badan respons mentah dan jangan menganggap struktur tetap merentas titik akhir.

Medan message biasanya memberitahu anda tepat apa yang salah. Medan param memberitahu anda parameter mana yang menyebabkannya. Sentiasa log kedua-duanya.

Ketahui maksud setiap kod status HTTP

StatusMaksudPunca biasaPenyelesaian
400Permintaan tidak sahModel hilang, parameter salah untuk model iniSemak error.param dalam respons
401Tidak dibenarkanKunci API salah atau tiadaSahkan format Authorization: Bearer <key>
429Dihadkan kadarTerlalu banyak permintaanPenundaan eksponen (rujuk Langkah 4)
500Ralat pelayanIsu pihak penyedia, atau badan permintaan salah bentukCuba semula dengan penundaan; semak format permintaan
504Habisan masa pintu masukPenyedia mengambil masa terlalu lamaCuba semula; pertimbangkan model lebih pantas

Sumber**:** Dokumentasi chat completions CometAPI

Perbezaan 400 vs 500 penting untuk logik cuba semula. 400 bermaksud permintaan anda salah — mencuba semula permintaan yang sama tidak akan membantu. 500 atau 504 bermaksud pelayan mempunyai masalah — mencuba semula masuk akal.

Semak finish_reason — medan yang paling kerap terlepas pandang

Respons 200 dengan finish_reason: "content_filter" bermaksud penjanaan anda disekat. Medan content akan null atau kosong. Jika anda tidak menyemaknya, aplikasi anda akan diam-diam mengembalikan tiada apa-apa.

finish_reasonMaksudApa yang perlu dibuatPenyelesaian
stopPenyempurnaan normalTiada — ini kejayaanSemak error.param dalam respons
lengthMencapai had tokenTambahkan max_tokens atau pendekkan gesaanSahkan format Authorization: Bearer <key>
content_filterDisekat oleh dasar keselamatanUbah ayat gesaan; elakkan nama/topik tertentuPenundaan eksponen (rujuk Langkah 4)
tool_callsModel memanggil alat dan bukannya memulangkan teksTangani panggilan alat; content akan nullCuba semula dengan penundaan; semak format permintaan
504Habisan masa pintu masukPenyedia mengambil masa terlalu lamaCuba semula; pertimbangkan model lebih pantas

Sumber**:** Dokumentasi chat completions CometAPI

import osimport loggingfrom openai import OpenAI, APIStatusError, APIConnectionError, APITimeoutErrorfrom dotenv import load_dotenv​load_dotenv()​api_key = os.environ.get("COMETAPI_KEY")if not api_key:    raise ValueError("COMETAPI_KEY tidak ditetapkan")​client = OpenAI(    base_url="https://api.cometapi.com/v1",    api_key=api_key,)​def safe_complete(messages: list, model: str = "gpt-5.4-mini", **kwargs) -> dict:    """    Lengkapkan permintaan chat dengan pengendalian ralat dan finish_reason penuh.    Memulangkan {"content": str, "finish_reason": str, "tool_calls": list | None}    Naikkan pengecualian pada ralat API.    """    try:        response = client.chat.completions.create(            model=model,            messages=messages,            **kwargs        )    except APIStatusError as e:        error_body = {}        try:            error_body = e.response.json().get("error", {})        except Exception:            pass        logging.error(            f"Ralat API status={e.status_code} "            f"mesej={error_body.get('message')} "            f"param={error_body.get('param')}"        )        raise    except (APIConnectionError, APITimeoutError) as e:        logging.error(f"Ralat rangkaian/tamat masa: {e}")        raise​    choice = response.choices[0]    finish_reason = choice.finish_reason​    if finish_reason == "content_filter":        raise ValueError(            f"Penjanaan disekat oleh penapis kandungan. "            f"Model: {model}. Ubah ayat gesaan."        )​    if finish_reason == "length":        used = response.usage.completion_tokens if response.usage else "unknown"        logging.warning(f"Output dipotong pada had token. Digunakan {used} token.")​    # Pulangkan hasil berstruktur supaya pemanggil boleh mengendalikan tool_calls secara eksplisit    return {        "content": choice.message.content or "",        "finish_reason": finish_reason,        "tool_calls": choice.message.tool_calls,    }​# Penggunaanresult = safe_complete(    messages=[{"role": "user", "content": "Ringkaskan artikel ini: [text]"}],    model="gpt-5.4-mini")​if result["finish_reason"] == "tool_calls":    # Tangani panggilan alat — content akan kosong    print("Model mahu memanggil alat:", result["tool_calls"])else:    print(result["content"])

Kesan kegagalan senyap di lapisan aplikasi

Kegagalan senyap paling sukar ditangkap. API memulangkan 200, finish_reason ialah stop, tetapi output salah dari segi semantik. Anda hanya boleh mengesannya di lapisan aplikasi.

Corak biasa:

def validate_completion(result: dict, task: str) -> str:    """    Pengesahan pada lapisan aplikasi untuk kegagalan senyap.    Naikkan ValueError jika output tidak memenuhi jangkaan asas.    """    content = result["content"].strip()​    # Output kosong yang bukan panggilan alat    if not content and result["finish_reason"] != "tool_calls":        raise ValueError(f"Output kosong untuk tugasan '{task}' dengan finish_reason='{result['finish_reason']}'")​    # Semakan khusus tugasan    if task == "classify":        valid_labels = {"positive", "negative", "neutral"}        if content.lower() not in valid_labels:            logging.warning(                f"Output pengelasan tidak dijangka: '{content}'. "                f"Jangka salah satu daripada {valid_labels}. "                f"Model mungkin mengembalikan penjelasan dan bukannya label."            )​    if task == "json_extract":        import json        try:            json.loads(content)        except json.JSONDecodeError:            raise ValueError(                f"Menjangka output JSON tetapi mendapat: '{content[:100]}...'. "                f"Cuba tambah 'balas dengan JSON sah sahaja' pada gesaan, "                f"atau gunakan response_format={{\"type\": \"json_object\"}}."            )​    if task == "summarize" and len(content.split()) < 10:        logging.warning(            f"Ringkasan terlalu pendek ({len(content.split())} perkataan). "            f"Semak sama ada input terlalu pendek atau model tersalah faham tugasan."        )​    return content​​# Aliran penuh dengan pengesanan kegagalan senyapresult = safe_complete(    messages=[{"role": "user", "content": "Kelaskan sebagai positive/negative/neutral: 'Great product!'"}],    model="claude-haiku-4-5")label = validate_completion(result, task="classify")

Kegagalan senyap biasanya berpunca daripada salah satu daripada tiga sumber: gesaan adalah samar, model mengabaikan arahan format anda, atau input terlalu pendek/panjang untuk tugasan. Merekodkan output penuh apabila pengesahan gagal ialah cara terpantas untuk mendiagnosis yang mana satu.

Tambah penundaan eksponen untuk had kadar

Ralat had kadar (429) adalah sementara. Tindakan yang betul ialah menunggu dan cuba semula dengan sela yang meningkat — amalan standard untuk mana-mana API yang mempunyai had kadar:

import timeimport randomfrom openai import RateLimitError​def complete_with_retry(    messages: list,    model: str = "gpt-5.4-mini",    max_retries: int = 3,    **kwargs) -> dict:    """Cuba semula pada had kadar dan ralat pelayan dengan penundaan eksponen."""    last_error = None​    for attempt in range(max_retries):        try:            return safe_complete(messages, model=model, **kwargs)​        except APIStatusError as e:            if e.status_code < 500:                raise  # 4xx: jangan cuba semula, permintaan adalah salah            last_error = e​        except RateLimitError as e:            last_error = e​        except (APIConnectionError, APITimeoutError) as e:            last_error = e​        if attempt < max_retries - 1:            wait = (2 ** attempt) + random.random()  # jitter mengelakkan fenomena 'thundering herd'            logging.warning(f"Cubaan {attempt + 1} gagal. Menunggu {wait:.1f}s sebelum cuba semula.")            time.sleep(wait)​    raise RuntimeError(f"Semua {max_retries} cubaan gagal") from last_error

Jangan cuba semula pada 400 atau 401 — itu ralat klien yang tidak akan selesai sendiri.

Nyahpepijat kegagalan penjanaan imej

Penjanaan imej mempunyai mod kegagalan tersendiri di atas ralat HTTP standard:

import base64import requests​def generate_image_safe(prompt: str, model: str = "dall-e-3") -> dict:    """    Jana imej dengan pengendalian ralat penuh.    Memulangkan {"url": str | None, "bytes": bytes | None, "blocked": bool}    """    api_key = os.environ.get("COMETAPI_KEY")    if not api_key:        raise ValueError("COMETAPI_KEY tidak ditetapkan")​    BASE64_MODELS = {"gpt-image-2", "qwen-image"}​    headers = {        "Authorization": f"Bearer {api_key}",        "Content-Type": "application/json"    }​    payload = {"model": model, "prompt": prompt, "size": "1024x1024"}    if model in BASE64_MODELS:        payload["output_format"] = "png"    else:        payload["response_format"] = "url"​    try:        response = requests.post(            "https://api.cometapi.com/v1/images/generations",            json=payload,            headers=headers,            timeout=60        )        response.raise_for_status()    except requests.exceptions.HTTPError as e:        logging.error(f"Ralat HTTP penjanaan imej: {e.response.status_code} {e.response.text}")        raise    except requests.exceptions.Timeout:        logging.error("Penjanaan imej tamat masa selepas 60s")        raise​    data = response.json().get("data", [])​    if not data:        logging.warning("Penjanaan imej memulangkan data kosong — gesaan mungkin telah ditapis.")        return {"url": None, "bytes": None, "blocked": True}​    item = data[0]​    if "revised_prompt" in item:        logging.info(f"Penyedia menyemak semula gesaan kepada: {item['revised_prompt']}")​    if "url" in item:        return {"url": item["url"], "bytes": None, "blocked": False}​    return {        "url": None,        "bytes": base64.b64decode(item["b64_json"]),        "blocked": False    }

Isu khusus imej yang perlu diperhatikan:

SimptomPuncaPenyelesaian
Tatasusunan data kosongGesaan ditapisSemak revised_prompt; ubah ayat
ralat response_format pada GPT Image 2Parameter tidak disokongGuna output_format sebagai ganti
n > 1 ralat pada Qwen ImageHad modelUlang permintaan dalam gelung
URL memulangkan 403 kemudianURL tamat tempohMuat turun serta-merta selepas penjanaan

Sumber**:** Dokumentasi penjanaan imej CometAPI

Nyahpepijat kegagalan penjanaan video

Penjanaan video gagal dengan cara berbeza kerana ia asinkron. Mulakan pembolehubah status sebelum gelung supaya mesej ralat tamat masa sentiasa terbentuk elok:

def submit_and_poll_video(    prompt: str,    model: str = "veo3-fast",    max_wait: int = 600) -> str:    """Hantar tugasan video dan tinjau hingga siap. Memulangkan URL video."""    api_key = os.environ.get("COMETAPI_KEY")    if not api_key:        raise ValueError("COMETAPI_KEY tidak ditetapkan")​    headers = {"Authorization": f"Bearer {api_key}"}​    try:        response = requests.post(            "https://api.cometapi.com/v1/videos",            headers=headers,            files={                "prompt": (None, prompt),                "model": (None, model),                "size": (None, "16x9")            },            timeout=30        )        response.raise_for_status()    except requests.exceptions.HTTPError as e:        logging.error(f"Penyerahan video gagal: {e.response.status_code} {e.response.text}")        raise​    task_id = response.json()["id"]    logging.info(f"Tugasan video dihantar: {task_id}")​    poll_url = f"https://api.cometapi.com/v1/videos/{task_id}"    elapsed = 0    interval = 10    status = "unknown"   # inisialisasi sebelum gelung    progress = 0         # inisialisasi sebelum gelung​    while elapsed < max_wait:        try:            poll_response = requests.get(poll_url, headers=headers, timeout=30)            poll_response.raise_for_status()        except requests.exceptions.HTTPError as e:            logging.error(f"Permintaan tinjauan gagal: {e.response.status_code}")            raise​        result = poll_response.json()        status = result.get("status", "unknown")        progress = result.get("progress", 0)​        logging.info(f"Tugasan {task_id}: status={status} progress={progress}%")​        if status == "succeeded":            return result["output"][0]        elif status in ("failed", "cancelled"):            error_detail = result.get("error", "tiada butiran ralat dipulangkan")            raise RuntimeError(f"Tugasan video {task_id} gagal: {error_detail}")​        time.sleep(interval)        elapsed += interval​    raise TimeoutError(        f"Tugasan video {task_id} tidak selesai dalam {max_wait}s. "        f"Status terakhir: {status}, kemajuan: {progress}%"    )

Isu khusus video:

SimptomPuncaPenyelesaian
Tugas tersekat dalam queued >10 minBeban pelayanCuba model lain
failed tanpa butiran ralatGesaan ditapis atau ralat modelUbah ayat gesaan
URL video memulangkan 403URL tamat tempohMuat turun serta-merta
task_not_exist pada tinjauan Runway pertamaTugas masih memulakan (tingkah laku didokumenkan CometAPI)Tunggu 5s dan cuba semula
Kling memulangkan "succeed" bukan "succeeded"API Kling menggunakan rentetan status tidak piawaiTangani kedua-duanya dalam logik tinjauan

Sumber**:** Dokumentasi video CometAPI untuk veo3, Dokumentasi Kling Video

Versi Node.js

import OpenAI from 'openai';​const apiKey = process.env.COMETAPI_KEY;if (!apiKey) throw new Error('COMETAPI_KEY tidak ditetapkan');​const client = new OpenAI({  baseURL: 'https://api.cometapi.com/v1',  apiKey,});​async function safeComplete(messages, model = 'gpt-5.4-mini', options = {}) {  let response;​  try {    response = await client.chat.completions.create({ model, messages, ...options });  } catch (err) {    if (err.status && err.status < 500) {      console.error(`Ralat klien ${err.status}: ${err.message}`);    } else {      console.error(`Ralat pelayan/rangkaian: ${err.message}`);    }    throw err;  }​  const choice = response.choices[0];  const finishReason = choice.finish_reason;​  if (finishReason === 'content_filter') {    throw new Error(`Penjanaan disekat oleh penapis kandungan. Model: ${model}`);  }​  if (finishReason === 'length') {    console.warn(`Output dipotong. Digunakan ${response.usage?.completion_tokens ?? 'unknown'} token.`);  }​  return {    content: choice.message.content ?? '',    finishReason,    toolCalls: choice.message.tool_calls ?? null,  };}​async function completeWithRetry(messages, model = 'gpt-5.4-mini', maxRetries = 3) {  let lastError;​  for (let attempt = 0; attempt < maxRetries; attempt++) {    try {      return await safeComplete(messages, model);    } catch (err) {      // Jangan cuba semula ralat klien 4xx      if (err.status && err.status < 500) throw err;​      lastError = err;      if (attempt < maxRetries - 1) {        const wait = (2 ** attempt + Math.random()) * 1000;        console.warn(`Cubaan ${attempt + 1} gagal. Mencuba semula dalam ${(wait / 1000).toFixed(1)}s`);        await new Promise(r => setTimeout(r, wait));      }    }  }​  throw new Error(`Semua ${maxRetries} cubaan gagal: ${lastError?.message}`);}​// Penggunaanconst result = await safeComplete(  [{ role: 'user', content: 'Kelaskan sebagai positive/negative/neutral: "Great product!"' }],  'claude-haiku-4-5');​if (result.finishReason === 'tool_calls') {  console.log('Panggilan alat diminta:', result.toolCalls);} else {  console.log(result.content);}

Senarai semak nyahpepijat

Apabila penjanaan gagal dan anda tidak pasti di mana hendak bermula:

Untuk penjanaan teks:

  • Adakah kunci API ditetapkan dan dalam format Authorization: Bearer <key>?
  • Adakah finish_reason selain stop?
  • Adakah content null? Semak sama ada finish_reason ialah tool_calls
  • Adakah output dipotong? Semak finish_reason: "length" dan usage.completion_tokens
  • Adakah ralat 4xx (betulkan permintaan) atau 5xx (cuba semula)?
  • Adakah output lulus pengesahan lapisan aplikasi anda? (kegagalan senyap)

Untuk penjanaan imej:

  • Adakah tatasusunan data kosong? (penapis kandungan)
  • Adakah anda menggunakan response_format pada GPT Image 2? (tidak disokong — guna output_format)
  • Adakah anda menetapkan n > 1 pada Qwen Image? (tidak disokong)
  • Adakah anda memuat turun imej sebelum URL tamat tempoh?

Untuk penjanaan video:

  • Adakah tugas tersekat dalam queued? (cuba model lain)
  • Adakah anda menyemak medan error dalam respons tugas yang gagal?
  • Adakah anda memuat turun video sebelum URL tamat tempoh?
  • Adakah anda mengendalikan kedua-dua "succeed" (Kling) dan "succeeded" (Veo, Runway)?

Soalan Lazim

S: Permintaan saya mengembalikan 200 tetapi tiada kandungan. Apa yang berlaku?

Semak finish_reason. Jika content_filter, penjanaan telah disekat — permintaan berjaya tetapi output ditindas. Jika tool_calls, model memanggil alat dan bukannya memulangkan teks, dan content adalah null secara reka bentuk. Jika finish_reason ialah stop tetapi kandungan masih kosong, itu kegagalan senyap — log keseluruhan respons dan semak gesaan anda.

S: Bagaimana saya tahu jika gesaan saya ditapis?

Untuk teks: semak finish_reason === "content_filter". Untuk imej: semak sama ada tatasusunan data kosong. Untuk video: semak sama ada tugas mencapai status failed sejurus selepas penyerahan tanpa butiran ralat. Dalam semua kes, cuba ubah ayat gesaan supaya lebih neutral.

S: Bila patut saya mencuba semula permintaan yang gagal?

Cuba semula pada 429 dan 5xx menggunakan penundaan eksponen. Jangan cuba semula pada 4xx — permintaan yang tidak sah tidak akan pulih sendiri. Pengecualian ialah 401 jika anda memutar kunci API.

S: Apa itu penundaan eksponen dan mengapa ia penting?

Daripada mencuba semula serta-merta, anda menunggu semakin lama: 1s, 2s, 4s. Menambah jitter (+ random.random()) mengelakkan berbilang klien mencuba semula serentak. Ini amalan standard untuk mana-mana API dengan had kadar — bukan khusus kepada CometAPI.

S: Tugas video tersekat dalam queued selama 10 minit. Adakah ia gagal?

Tidak semestinya — baris giliran boleh sesak apabila beban tinggi. Tunggu sehingga ambang max_wait anda, kemudian naikkan TimeoutError dan cuba semula dengan model berbeza. Log ID tugas supaya anda boleh menyemak status secara manual jika perlu.

S: Bagaimana saya menangkap kegagalan senyap?

Kegagalan senyap memerlukan pengesahan pada lapisan aplikasi — API tidak akan memberitahu anda bahawa output salah dari segi semantik. Semak bahawa output sepadan format yang dijangka (JSON sah, label dijangka, panjang minimum). Log output penuh apabila pengesahan gagal. Punca paling biasa ialah gesaan samar, arahan format diabaikan, atau input terlalu pendek/panjang untuk tugasan.

Bersedia untuk mengurangkan kos pembangunan AI sebanyak 20%?

Mulakan secara percuma dalam beberapa minit. Kredit percubaan percuma disertakan. Tiada kad kredit diperlukan.

Baca Lagi