Doubao API cung cấp giao diện tương thích OpenAI, nhưng “tương thích” không đồng nghĩa “sao chép nguyên xi”. Ba chỗ dễ mắc kẹt nhất là: Base URL bị viết thành /v1, model điền tên hiển thị thay vì model ID hoặc endpoint ID, và lần gọi đầu đã bật suy luận sâu khiến đầu ra bị cắt. Bài viết chạy thông curl và Python theo thứ tự, sau đó nói về truyền phát, gọi công cụ, lỗi thường gặp và danh sách kiểm tra di chuyển.
Lưu ý: Doubao, Volcengine Ark, Volcengine và ByteDance là nhãn hiệu hoặc tên sản phẩm của ByteDance và các công ty liên kết; OpenAI là nhãn hiệu của chủ sở hữu tương ứng. Bài viết chỉ nhằm giải thích kỹ thuật tích hợp, không có quan hệ trực thuộc, đại lý hay bảo chứng với các công ty trên. Giao diện, mô hình và hạn mức có thể điều chỉnh; vui lòng căn cứ tài liệu chính thức và bảng giá mô hình trên site.
1. Xác nhận ba việc trước khi tích hợp
| Hạng mục | Kết nối trực tiếp Volcengine Ark | Cổng thống nhất |
|---|---|---|
| Base URL | https://ark.cn-beijing.volces.com/api/v3 |
https://ai.zhongshangqihang.com/v1 |
| Xác thực | Authorization: Bearer <ARK_API_KEY> |
Authorization: Bearer <khóa cổng> |
| model | Model ID hoặc endpoint ID ep- |
Theo danh sách mô hình trên site |
| Phù hợp | Chỉ dùng Doubao, tự định danh thật và nạp tiền xuất hóa đơn | Nhiều mô hình, hóa đơn và hạn mức thống nhất |
Khóa và Base URL phải dùng thành cặp. Khóa chính thức đi với địa chỉ cổng, hoặc khóa cổng đi với địa chỉ chính thức, thường trả về 401 ngay. Khi đổi điểm vào, hãy đổi cả hai cùng lúc.
2. Base URL và đường dẫn yêu cầu: /api/v3 không phải /v1
Địa chỉ mặt phẳng dữ liệu chính thức là https://ark.cn-beijing.volces.com/api/v3; đường dẫn chat completions là /chat/completions; địa chỉ đầy đủ là https://ark.cn-beijing.volces.com/api/v3/chat/completions. Nó không có tiền tố /v1 quen thuộc của OpenAI; ghép thêm một /v1 sẽ nhận 404.
Khu vực nằm trong tên miền (cn-beijing). Nếu tài nguyên ở khu vực khác, căn cứ địa chỉ trong bảng điều khiển và tài liệu. Tài liệu chính thức còn lưu ý: các trường hợp như Coding Plan dùng Base URL khác, điền sai có thể phát sinh phí bổ sung; trước khi đổi gói hãy đối chiếu.
3. model điền gì: model ID hay endpoint ID
Tài liệu chính thức đưa ra hai cách gọi:
- Suy luận đặt sẵn: điền thẳng model ID, ví dụ
doubao-seed-2-1-pro-260915, không cần tạo endpoint trước. - Endpoint suy luận tùy chỉnh: điền endpoint ID, thường bắt đầu bằng
ep-, phù hợp triển khai cố định, quản lý chi tiết hoặc mô hình tinh chỉnh LoRA.
Model ID có ngày phiên bản; đừng viết tên hiển thị kiểu “Doubao 2.1 Pro”, cũng đừng tự thêm hậu tố theo trí nhớ. Khi dùng chữ ký Access Key (AK/SK), model bắt buộc điền endpoint ID; khi dùng API Key, có thể điền model ID hoặc endpoint ID theo tài liệu. Nếu trả về InvalidEndpointOrModel.ModelIDAccessDisabled, nghĩa là tài khoản hiện tại không hỗ trợ gọi thẳng model ID, cần tạo endpoint.
4. Chạy thông yêu cầu tối thiểu bằng curl
Trước hết tắt suy luận sâu để giảm biến số. Ví dụ với điểm vào chính thức:
export ARK_API_KEY="API Key Volcengine Ark của bạn"
export ARK_MODEL_ID="doubao-seed-2-1-pro-260915"
curl "https://ark.cn-beijing.volces.com/api/v3/chat/completions" \
-H "Authorization: Bearer $ARK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "'"$ARK_MODEL_ID"'",
"messages": [{"role": "user", "content": "Chỉ trả lời OK"}],
"thinking": {"type": "disabled"},
"max_tokens": 32
}'
Trả về 200 và choices[0].message.content có nội dung nghĩa là khóa, địa chỉ và mô hình đều đúng. Nếu 404, trước hết kiểm tra model có hậu tố phiên bản không, có cần đổi sang endpoint ep- không; nếu 401, kiểm tra khóa và header trước, đừng vội nghi số dư.
5. Gọi Python bằng SDK OpenAI
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ARK_API_KEY"],
base_url="https://ark.cn-beijing.volces.com/api/v3",
)
resp = client.chat.completions.create(
model=os.environ.get("ARK_MODEL_ID", "doubao-seed-2-1-pro-260915"),
messages=[
{"role": "system", "content": "Bạn là trợ lý kỹ thuật tiếng Việt, trả lời ngắn gọn."},
{"role": "user", "content": "Giải thích endpoint suy luận là gì trong ba câu."},
],
max_tokens=512,
extra_body={"thinking": {"type": "disabled"}},
)
print(resp.choices[0].message.content)
print(resp.usage)
SDK OpenAI không nhận trường thinking, nên truyền qua extra_body; nếu cổng hoặc mô hình không hỗ trợ, bỏ trường này là được. Sau khi chạy thông, xem Token đầu vào và đầu ra trong usage trước, rồi mới quyết định thời gian chờ, mức đồng thời và ngân sách chi phí.
6. Truyền phát: delta, reasoning_content và [DONE]
Sau khi đặt stream=True, máy chủ trả về từng khối qua SSE; đối tượng phản hồi là chat.completion.chunk; nội dung chính ở choices[0].delta.content, nội dung suy nghĩ ở delta.reasoning_content; finish_reason chỉ xuất hiện ở khối cuối, khi kết thúc gửi data: [DONE].
stream = client.chat.completions.create(
model=os.environ["ARK_MODEL_ID"],
messages=[{"role": "user", "content": "Viết một ví dụ Python đọc tệp CSV"}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
Khối suy nghĩ có thể có content rỗng; đừng giả định mỗi khối đều có nội dung chính. max_tokens quá nhỏ sẽ cắt đầu ra. Khi mạng đứt, nội dung đã nhận vẫn còn; client cần lưu được kết quả một phần và quyết định có thử lại hay không.
7. Gọi công cụ: tools, tool_calls và thứ tự gửi lại
Cách viết tools gần với OpenAI: mỗi công cụ gồm type: "function" và function, trong đó name, description, parameters là bắt buộc; parameters dùng JSON Schema. Khi mô hình quyết định gọi, finish_reason của phản hồi là tool_calls; message.tool_calls[i].function.arguments là chuỗi JSON, cần tự phân tích.
Thứ tự gửi lại không được sai: trước hết thêm tin nhắn assistant mang tool_calls vào hội thoại, sau đó với mỗi lời gọi thêm một tin nhắn role: "tool" kèm tool_call_id tương ứng và kết quả, rồi yêu cầu mô hình lần nữa cho đến khi finish_reason không còn là tool_calls. parallel_tool_calls mặc định là true; đặt false có thể giới hạn mỗi lần chỉ gọi một công cụ. Trong tình huống truyền phát, phần tăng dần của gọi công cụ có index; phải cộng dồn arguments theo index.
8. Lỗi thường gặp: xác định 401, 404, 429
| HTTP | Mã lỗi điển hình | Ý nghĩa | Xử lý |
|---|---|---|---|
| 401 | AuthenticationError |
Thiếu khóa, khóa không hợp lệ, hoặc header không có Bearer |
Sao chép lại khóa, kiểm tra header Authorization |
| 404 | InvalidEndpointOrModel.NotFound |
Mô hình hoặc endpoint không tồn tại, hoặc không gian hiện tại không có quyền | Sao chép ID đầy đủ từ bảng điều khiển, đối chiếu khu vực và không gian |
| 404 | ModelNotOpen |
Mô hình chưa được mở trong tài khoản | Mở mô hình tương ứng trong bảng điều khiển Ark |
| 404 | InvalidEndpointOrModel.ModelIDAccessDisabled |
Tài khoản không hỗ trợ gọi thẳng model ID | Tạo endpoint tùy chỉnh, đổi sang ID ep- |
| 400 | InvalidParameter, MissingParameter |
Thiếu tham số, sai kiểu hoặc mô hình không hỗ trợ tham số đó | Đối chiếu tài liệu để xóa/sửa trường, chạy yêu cầu tối thiểu trước |
| 403 | AccessDenied, AccountOverdueError |
Không có quyền, hoặc số dư tài khoản âm | Kiểm tra khóa và quyền không gian, xử lý chậm thanh toán |
| 429 | RateLimitExceeded.* |
Vượt RPM/TPM hoặc lưu lượng tăng vọt | Giảm đồng thời, lùi hàm mũ, xin tăng hạn mức nếu cần |
| 500/503 | InternalServiceError, ServerOverloaded |
Thượng nguồn bất thường hoặc quá tải | Chờ ngắn rồi thử lại, chuẩn bị kênh dự phòng |
9. Danh sách kiểm tra di chuyển
Khi chuyển từ kết nối chính thức sang cổng, hoặc từ cổng này sang cổng khác, kiểm tra theo thứ tự sau:
- Cố định một bộ lời nhắc thật, ghi lại đầu ra, thời gian và
usagehiện tại làm nền so sánh. - Đổi đồng thời
base_urlvàapi_key, không chỉ đổi một trong hai. - Xác nhận lại ánh xạ tên mô hình theo bảng giá mô hình trên site, không dùng tên cũ.
- Kiểm chứng truyền phát: thời gian Token đầu tiên,
delta.content,finish_reasonvà[DONE]. - Kiểm chứng gọi công cụ:
tools,tool_calls, gửi lạitool_call_idvà thứ tự nhiều lượt. - Kiểm chứng các tham số mở rộng như
thinking,reasoning_effortcó được hỗ trợ không, giá trị mặc định có khác không. - Đặt thời gian chờ kết nối và đọc; chỉ thử lại với 429, 5xx và quá thời gian; giữ thao tác ghi có tính lũy đẳng.
- Trước hết chuyển 5%–10% lưu lượng, quan sát 3–7 ngày, giữ kết nối chính thức làm kênh quay lui.
Khi cần đầu mối thống nhất, có thể tạo khóa thử nghiệm tại trang đăng ký; độ phủ mô hình và cách tính phí xem tại bảng giá mô hình. ZSQH AI Gateway là dịch vụ bên thứ ba độc lập, không có quan hệ trực thuộc với ByteDance.
Đọc thêm:
- Bảng giá và cách tính phí Doubao API
- Phương án thay thế OpenAI API: Azure, Claude, Gemini hay cổng
- Xem bảng giá mô hình và cách tính chi phí
Câu hỏi thường gặp
Base URL có cần thêm /v1 không?
Không. Điểm vào tương thích OpenAI của Volcengine Ark là https://ark.cn-beijing.volces.com/api/v3, đường dẫn chat là /chat/completions; ghép thêm /v1 sẽ nhận 404. Địa chỉ cổng thường kết thúc bằng /v1; không được trộn hai bên.
model điền model ID hay endpoint ID bắt đầu bằng ep-?
Suy luận đặt sẵn điền model ID; endpoint tùy chỉnh điền ID ep-; khi dùng chữ ký Access Key bắt buộc điền endpoint ID. Nếu trả về ModelIDAccessDisabled, nghĩa là cần tạo endpoint chứ không phải đổi khóa.
Lần gọi đầu có nên bật suy luận sâu?
Nên tắt trước, dùng yêu cầu ngắn nhất xác nhận đường truyền. Một số mô hình Doubao mặc định bật suy luận sâu; khi bật, đầu ra sẽ sinh nội dung suy nghĩ trước, max_tokens quá nhỏ dễ cắt mất phần chính. Xác nhận đường truyền rồi mới bật theo nhiệm vụ.
Vì sao truyền phát không có nội dung?
Trước hết xác nhận stream=True, sau đó kiểm tra có phải chỉ đọc delta.content mà bỏ qua khối rỗng không; nội dung suy nghĩ nằm ở delta.reasoning_content. Còn phải kiểm tra max_tokens, bộ đệm mạng và việc proxy có gom SSE thành một phản hồi duy nhất không.
Vì sao phải gửi lại tool_calls của assistant khi gọi công cụ?
Giao thức yêu cầu tin nhắn assistant mang tool_calls, sau đó mỗi tin nhắn role: "tool" dùng tool_call_id để khớp kết quả. Bỏ qua bước này, mô hình có thể gọi công cụ lặp lại hoặc trả về 400. Khi truyền phát còn phải cộng dồn tham số theo index.
