Qwen API có hai cách gọi phổ biến: giao diện DashScope gốc của Alibaba Cloud Bailian, và giao diện tương thích OpenAI. Cấu trúc lỗi của hai bên không hoàn toàn giống nhau, nhưng thứ tự điều tra thì thống nhất: trước hết xem mã trạng thái HTTP, sau đó đọc code và message trong phần thân phản hồi, tiếp theo tìm request_id, dùng yêu cầu tối thiểu để tái hiện, cuối cùng mới sửa tham số hoặc đổi mô hình.

Bài viết tách riêng 401, 404, 429, 400, 5xx và quá thời gian, đưa ra bảng đối chiếu mã lỗi, trường nhật ký, mã thử lại và danh sách kiểm tra trước khi liên hệ hỗ trợ. Mô hình, hạn mức và cách tính phí căn cứ theo tài liệu chính thức và giá mô hình trên trang.

Lưu ý: Qwen, Tongyi Qianwen, Alibaba Cloud, Bailian và DashScope là nhãn hiệu của Tập đoàn Alibaba và các chủ sở hữu tương ứng. Bài viết chỉ thảo luận kỹ thuật, không có quan hệ liên kết, đại lý hay hợp tác với các công ty trên. Mã lỗi, quy tắc giới hạn tốc độ và hành vi giao diện có thể điều chỉnh theo phiên bản; cuối cùng căn cứ theo tài liệu chính thức và phản hồi thực tế.

1. Phân biệt chế độ giao diện và cấu trúc lỗi trước

Giao diện DashScope gốc thường trả code, message và request_id ở tầng trên cùng của phản hồi; giao diện tương thích OpenAI theo phong cách OpenAI, phần thân lỗi có dạng {"error": {"message": "...", "type": "...", "code": "..."}}. request_id của chế độ tương thích có thể nằm trong header hoặc phần thân phản hồi; tên trường căn cứ theo phản hồi thực tế.

Về mặt kỹ thuật, đừng chỉ phân tích một cấu trúc. Trước hết ghi nguyên phần thân phản hồi vào nhật ký, rồi lấy giá trị theo thứ tự error.code và code tầng trên. Như vậy khi chuyển chế độ giao diện, mã xử lý lỗi không phải viết lại.

2. 401: xác thực thất bại, kiểm tra khu vực trước

401 nghĩa là danh tính chưa được xác minh, thường không liên quan đến năng lực mô hình hay số dư. Ba loại lỗi phổ biến ở Bailian:

  • InvalidApiKey hoặc invalid_api_key: Key sai, sao chép không đầy đủ, hoặc Base URL không khớp khu vực của Key.
  • invalid access token or token expired: Token đã hết hạn, hoặc dùng địa chỉ dành riêng cho gói nhưng cấu hình Key thường.
  • NOT AUTHORIZED: WorkspaceId không hợp lệ, hoặc tài khoản không thuộc workspace đó.

API Key của Qwen gắn với khu vực; Key Bắc Kinh và Singapore không dùng lẫn được. Đây là điểm dễ bỏ sót nhất: mã không đổi, chỉ đổi Base URL, sẽ tái hiện 401 một cách ổn định.

Điều tra theo thứ tự:

  1. Xác nhận header là Authorization: Bearer <key>, có một dấu cách sau dấu hai chấm.
  2. In phần đầu biến môi trường, xác nhận không rỗng, không phải giá trị cũ hoặc có ký tự xuống dòng.
  3. Đối chiếu Base URL và khu vực của Key.
  4. Xác nhận loại Key khớp giao diện: địa chỉ trả theo lượng dùng, gói Coding và gói Token khác nhau.
  5. Đổi một Key mới làm yêu cầu tối thiểu, phân biệt vấn đề ở Key hay ở proxy, cổng.

3. 404 và 400: tên mô hình, trạng thái kích hoạt và ngữ cảnh

404 phần lớn không phải sự cố dịch vụ mà là vấn đề tên mô hình hoặc khả dụng. Với ModelNotFound hoặc model_not_found, kiểm tra ba việc trước: tên mô hình có gõ sai không, mô hình đã được kích hoạt chưa, mô hình có khả dụng ở khu vực hiện tại không. model_not_supported nghĩa là mô hình không hỗ trợ chế độ tương thích OpenAI, cần đổi giao diện hoặc đổi mô hình.

Nguyên nhân 400 đa dạng hơn. InvalidParameter là tham số vượt phạm vi, ví dụ temperature hoặc top_p ngoài khoảng; InvalidParameter.NotSupportEnableThinking là mô hình không hỗ trợ tham số chế độ suy nghĩ. Vượt ngữ cảnh thường trả Range of input length should be [1, xxx], mã tầng dưới là InternalError.Algo.InvalidParameter, cũng có thể do tổng độ dài tin nhắn vượt giới hạn mô hình. Cách xử lý là cắt lịch sử, tóm tắt theo khối hoặc đổi sang mô hình ngữ cảnh dài, không phải thử lại nhiều lần.

4. 429: phân biệt bốn loại giới hạn tốc độ và hai loại hạn mức

429 là lỗi dễ bị xử lý sai nhất. 429 ở Bailian ít nhất gồm các loại sau; bảng cũng liệt kê lỗi nợ phí và chưa kích hoạt dễ bị nhầm với giới hạn tốc độ:

HTTP Mã lỗi Ý nghĩa Có nên thử lại
429 Throttling.RateQuota, LimitRequests Vượt số yêu cầu mỗi phút (RPM) Có, lùi rồi thử lại
429 Throttling.AllocationQuota, insufficient_quota Vượt số token mỗi phút (TPM) Có, lùi và giảm đầu vào
429 Throttling.BurstRate Lưu lượng tăng đột biến ngắn hạn kích hoạt bảo vệ Có, làm đều nhịp gửi
429 Throttling.Concurrency Quá nhiều yêu cầu đồng thời Có, giảm đồng thời
429 AllocationQuota.FreeTierOnly Hết hạn mức miễn phí và đang bật chế độ chỉ dùng miễn phí Không, nạp tiền hoặc tắt công tắc
429 BudgetLimitExceeded Ngân sách tài khoản đã dùng hết Không, điều chỉnh ngân sách
400 Arrearage Tài khoản nợ phí hoặc trạng thái bất thường Không, khôi phục tài khoản trước
403 AccessDenied.Unpurchased Dịch vụ chưa được kích hoạt Không, kích hoạt trước

Giới hạn tốc độ được thống kê theo tài khoản chính Alibaba Cloud; lệnh gọi của tài khoản RAM phụ, workspace và nhiều Key được cộng gộp. Vì vậy "mỗi dịch vụ một Key" không thể lách tổng hạn mức, chỉ tránh chiếm dụng lẫn nhau. Giới hạn thường hồi phục trong vài phút; trong thời gian chờ đừng thử lại với tần suất cao.

5. Quá thời gian và 5xx: định vị theo ba đoạn

Quá thời gian cần chia ba đoạn: quá thời gian kết nối thường do DNS, đường ra hoặc proxy không tới được; token đầu chậm phần lớn do xếp hàng phía thượng nguồn hoặc đầu vào quá dài; quá thời gian đọc có thể do đầu ra quá dài hoặc suy luận lâu. Cách xử lý ba trường hợp khác nhau, không thể chỉ tăng thời gian chờ.

RequestTimeOut của Bailian nghĩa là yêu cầu quá thời gian, giới hạn chính thức là 300 giây; GatewayTimeout.InputDownload liên quan đến tải tệp đầu vào. Giao diện tương thích OpenAI còn có thể trả 503, nghĩa là engine quá tải. Khi yêu cầu truyền phát bị ngắt, có thể không có mã lỗi; hãy ghi lại nội dung đã nhận, đoạn cuối và lý do kết thúc, rồi xác định là mạng chập chờn, proxy cắt luồng hay thượng nguồn quá thời gian.

6. request_id và nhật ký: bằng chứng điều tra

Tài liệu chính thức nêu request_id được trả cùng phản hồi, có thể ở header hoặc phần thân. Về kỹ thuật nên ghi hai đường: máy khách tạo trace_id xuyên suốt mọi lần thử lại, đồng thời lưu nguyên định danh yêu cầu trong header và request_id trong phần thân. Nếu chưa ghi, có thể tìm trong nhật ký giám sát mô hình ở bảng điều khiển, với điều kiện đã bật nhật ký suy luận.

Nhật ký tối thiểu gồm: thời gian, trace_id, Base URL, khu vực, tên mô hình, mã trạng thái HTTP, mã lỗi, thông tin lỗi, request_id, thời gian xử lý, số lần thử lại, có truyền phát hay không. Key chỉ ghi vài ký tự đầu hoặc giá trị băm; nội dung gốc của người dùng và phản hồi đầy đủ không nên ghi cả đoạn xuống đĩa. Khi liên hệ hỗ trợ, một bản ghi có các trường này hữu ích hơn nhiều so với "thỉnh thoảng báo lỗi".

7. Thử lại và lùi: mã ví dụ

Đoạn mã dưới đây tắt tự động thử lại của SDK, chỉ thử lại với 429 và 5xx có thể phục hồi, đồng thời in mã trạng thái, mã lỗi và request_id. Nợ phí, hết hạn mức miễn phí và vượt ngân sách không nằm trong phạm vi thử lại.

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,  # Tắt tự động thử lại của SDK, giao cho logic bên dưới
)

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("Đã dùng hết số lần thử lại")

Bổ sung ba quy tắc: khi máy chủ trả Retry-After thì ưu tiên tuân theo; ngân sách thử lại phải kiểm soát toàn cục, tránh nhiều dịch vụ cùng lúc khuếch đại lưu lượng; yêu cầu có tác dụng phụ phải xác nhận đã thực thi chưa rồi mới quyết định gửi lại.

8. Quản trị đồng thời: hiệu quả hơn tăng số lần thử lại

Vấn đề giới hạn tốc độ thường không giải quyết bằng thử lại mà bằng quản trị điểm vào:

  • Tách Key theo nghiệp vụ và đặt giới hạn đồng thời riêng, tránh một tác vụ hàng loạt kéo sập dịch vụ trực tuyến.
  • Chia nhỏ và giãn tác vụ hàng loạt, tránh xung lưu lượng đúng giờ tròn.
  • Dùng hàng đợi cắt đỉnh, tác vụ thất bại vào hàng đợi trễ thay vì quay vòng tại chỗ.
  • Giám sát tỷ lệ 429 và độ trễ p95, khi tăng đột biến thì giảm đồng thời trước.
  • Tác vụ ngoại tuyến ưu tiên giao diện Batch, tránh giới hạn tốc độ thời gian thực.
  • Chuẩn bị mô hình hoặc điểm vào dự phòng, xác nhận tham số tương thích trước khi chuyển.

Ngưỡng giới hạn tốc độ cấu hình theo mô hình và tài khoản; nạp tiền không tự động nâng RPM hoặc TPM. Khi cần hạn mức cao hơn, hãy đi đường xin thương mại, đừng sao chép con số của người khác.

9. Danh sách trước khi liên hệ hỗ trợ

  1. Thời điểm xảy ra, múi giờ, và sự cố có tập trung bùng phát không.
  2. Base URL, khu vực, đường dẫn giao diện, tên mô hình và phương thức yêu cầu.
  3. Mã trạng thái HTTP, mã lỗi và thông tin lỗi đầy đủ.
  4. request_id; nếu không có thì cung cấp trace_id do bạn tạo.
  5. Một yêu cầu curl tối thiểu có thể tái hiện, Key đã khử nhận dạng.
  6. Có truyền phát không, có ngữ cảnh dài không, có vừa đổi cấu hình không.
  7. Phạm vi ảnh hưởng: một Key, một workspace hay toàn bộ dịch vụ.

10. Câu hỏi thường gặp (FAQ)

1. 429 có chắc chắn là giới hạn tốc độ không?

Không nhất thiết. 429 còn có thể do hết hạn mức miễn phí hoặc vượt ngân sách; nợ phí có thể trả 400 Arrearage, dịch vụ chưa kích hoạt có thể trả 403. Hãy đọc mã lỗi trước, rồi quyết định lùi, nạp tiền hay đổi cấu hình.

2. 401 đã đổi Key mới vẫn thất bại thì làm sao?

Tập trung kiểm tra khu vực và loại Key. Key Qwen gắn với khu vực; Key Bắc Kinh cấu hình địa chỉ Singapore sẽ trả 401; địa chỉ dành riêng cho gói cấu hình Key thường cũng thất bại. Sau đó kiểm tra header, biến môi trường và reverse proxy có làm mất thông tin xác thực không.

3. Vượt ngữ cảnh thì xử lý thế nào?

Trước hết cắt tin nhắn lịch sử, bỏ tệp đính kèm không liên quan và đoạn lặp; sau đó tóm tắt hoặc truy xuất tài liệu dài; nếu vẫn không đủ thì đổi sang mô hình ngữ cảnh dài. Đừng tăng max_tokens để giải quyết vượt ngữ cảnh đầu vào.

4. Quá thời gian có nên thử lại không?

Chỉ thử lại có giới hạn với lỗi kết nối và quá thời gian đọc, đồng thời đặt lùi cấp số nhân và giới hạn trên. Nghiệp vụ có tác dụng phụ phải xác nhận đã thực thi chưa, tránh đặt hàng hoặc ghi dữ liệu lặp.

5. Tìm request_id ở đâu?

Xem header và phần thân phản hồi trước, tên trường căn cứ theo giao diện thực tế; nếu đều không có, tìm trong nhật ký giám sát mô hình ở bảng điều khiển, với điều kiện đã bật nhật ký suy luận. Khi liên hệ hỗ trợ, cung cấp đồng thời trace_id và yêu cầu tái hiện tối thiểu.

Bước tiếp theo

Trước hết tạo Key kiểm thử tại ZSQH AI Gateway, diễn tập lần lượt 401, 404, 429, vượt ngữ cảnh và quá thời gian, rồi kết nối giám sát sản xuất. Mô hình khả dụng và cách tính phí xem tại giá mô hình.

Bài viết liên quan