Hướng dẫn API Seedream 5.5: tạo ảnh, chỉnh sửa và di chuyển

Tạo và chỉnh sửa ảnh bằng API Seedream 5.5: ID model, trạng thái tác vụ, tải xuống có xác thực, thăm dò bất đồng bộ và những điểm dễ sai khi di chuyển.

AIHubMixĐọc 10 phút
Hướng dẫn API Seedream 5.5: tạo ảnh, chỉnh sửa và di chuyển

Quy trình di chuyển Seedream 5.5 hữu ích là một quy trình xử lý tệp, chứ không chỉ thay tên model: tạo ảnh, kiểm tra tác vụ được trả về, lưu ảnh, rồi gửi các byte đã lưu làm ảnh tham chiếu để chỉnh sửa.

Seedream 5.5 trên AIHubMix hiện dùng doubao-seedream-5-5 và POST /ai/v1/images/generations. Hướng dẫn này tạo hình ảnh sản phẩm cốc gốm, sau đó yêu cầu chỉnh sửa chỉ đổi màu.

Phạm vi: tài liệu được kiểm tra vào ngày 12 tháng 11, 2026. Mã chỉ được kiểm tra cú pháp cục bộ và các hàm trợ giúp ngoại tuyến; không có yêu cầu tạo ảnh nào được thực thi. Những kiểm tra này không chứng minh chất lượng đầu ra, độ trung thực khi chỉnh sửa, độ trễ hay hóa đơn thực tế.

1. Chuẩn bị một yêu cầu ngắn gọn, rõ ràng

Dùng Python 3.10+ với requests. Trong Bash, cài đặt phần phụ thuộc và nhập khóa mà không để giá trị khóa lưu trong lịch sử shell:

python3 -m pip install requests
read -r -s -p 'AIHubMix API key: ' AIHUBMIX_API_KEY
printf '\n'
export AIHUBMIX_API_KEY

Với mã triển khai, hãy đưa biến môi trường vào thông qua trình quản lý bí mật. Không để khóa trong tệp mã nguồn, ví dụ yêu cầu, nhật ký, sổ tay hay mã phía trình duyệt. Trước khi gửi một trong hai yêu cầu POST, hãy bật tính năng tác vụ cho tài khoản theo yêu cầu trong hướng dẫn tác vụ bất đồng bộ. Điều kiện tiên quyết này áp dụng cho các endpoint tác vụ media gốc /ai/v1, kể cả khi chờ đồng bộ; điều này khác với việc chọn chạy nền.

Đọc lược đồ endpoint model hiện tại, chọn mục theo path, không dựa vào vị trí trong mảng. Các ràng buộc riêng của model được ưu tiên hơn danh sách tham số dùng chung.

Thiết lập Giá trị dùng ở đây
Model doubao-seedream-5-5
Đường dẫn POST /ai/v1/images/generations
Nội dung JSON phẳng
Kích thước 2048x2048
Số lượng ảnh n = 1
Định dạng tệp png
Định dạng phản hồi url

Lược đồ yêu cầu model và prompt không rỗng, giới hạn n ở mức 1, đồng thời liệt kê đầu ra png và jpeg. Lược đồ chấp nhận image dưới dạng URL, đầu vào Base64 hoặc đối tượng {url}; images chấp nhận một mảng có số ảnh tham chiếu tối đa được công bố là 14. Giới hạn này chưa được kiểm thử khi chạy. Ví dụ này dùng một ảnh tham chiếu và nêu rõ kích thước mặc định, không có đối tượng input bên ngoài hay phần mở rộng extra.

2. Tạo ảnh, kiểm tra tác vụ và lưu PNG

Tài liệu API hình ảnh hợp nhất định nghĩa phản hồi tác vụ gồm id, object: image, model, status, output và error. Đừng đọc phản hồi này theo định dạng cũ data[0].url.

Trước tiên, hãy xem quy trình ngắn; phần thiết lập đầy đủ và hàm trợ giúp tải xuống nằm trong Phụ lục thu gọn bên dưới. Trước khi chạy các ví dụ này, hãy nạp khối phụ lục đó một lần vào cùng phiên Python. Khối này định nghĩa settings, api_json và collect mà không gửi yêu cầu tạo ảnh. Sau đó chạy lần lượt các khối ngắn. Mỗi yêu cầu POST là một thao tác tính phí riêng; đừng chạy lại để khắc phục phản hồi bị thiếu hoặc tải xuống thất bại.

Gửi yêu cầu tạo ảnh một lần

generation = {
    **settings,
    "prompt": "Product photograph of one matte blue ceramic mug on a cream tabletop, "
              "soft side lighting, plain warm-gray background, no text or logos.",
}
task = api_json("POST", IMAGES + "/generations", generation)

Kiểm tra tác vụ, rồi lưu PNG

Bỏ qua async có nghĩa là chờ đồng bộ. Phản hồi HTTP 200 vẫn có thể chứa status: failed. Hàm trợ giúp lưu ID tác vụ trước khi kiểm tra trạng thái: chỉ trạng thái completed mới tiếp tục tải xuống; các trạng thái failed, cancelled và trạng thái không xác định sẽ dừng. Các trạng thái pending và in_progress cần được kiểm tra trên tác vụ hiện có, không phải tạo ảnh lần nữa.

collect(task, "mug-blue")

Lệnh gọi đơn này dùng khóa đã tạo tác vụ để lấy đầu ra đã hoàn tất, kiểm tra byte PNG và lưu thành mug-blue.png. Lệnh không tự động thử tạo lại và từ chối các máy chủ tải xuống hoặc chuyển hướng không mong đợi trước khi chuyển tiếp khóa. Phần triển khai đầy đủ nằm trong phụ lục; đây là hành vi dựa trên tài liệu, không phải kết quả tạo ảnh đã được xác minh.

Hướng dẫn model cho biết URL đầu ra tồn tại khoảng 30 phút. Hãy tải xuống sớm bằng cùng tiêu đề Bearer và tự lưu các byte. expires_at: null không phải cam kết lưu trữ vĩnh viễn. Nếu b64_json có dữ liệu, hãy giải mã thay vì tải xuống qua URL.

3. Chỉnh sửa tệp cục bộ, không dùng URL tải xuống được bảo vệ

Hãy tự kiểm tra ảnh đã lưu trước khi tốn phí chỉnh sửa. content_url mà ứng dụng có xác thực của bạn tải xuống được chưa chắc là URL công khai mà nhà cung cấp hình ảnh có thể truy cập. Tải lại PNG cục bộ dưới dạng Data URI:

reference = Path("mug-blue.png").read_bytes()
if not reference.startswith(b"\x89PNG\r\n\x1a\n"):
    raise SystemExit("The editing reference must be the saved PNG.")
edit = {
    **settings,
    "prompt": "Change only the mug color from blue to forest green. Preserve the mug shape, "
              "camera angle, tabletop, background, lighting, and shadows.",
    "image": "data:image/png;base64," + base64.b64encode(reference).decode("ascii"),
}
task = api_json("POST", IMAGES + "/generations", edit)
collect(task, "mug-green")

Yêu cầu này đề nghị giữ nguyên ảnh; nó không chứng minh rằng ảnh đã được giữ nguyên. Hãy xem lại kết quả trước khi thực hiện một lượt tính phí khác. Toàn bộ yêu cầu JSON, bao gồm cả phần mã hóa nội tuyến, phải nằm trong giới hạn 32 MiB; các giới hạn media riêng của model cũng được áp dụng. Một URL ảnh thực sự công khai và nhà cung cấp có thể truy cập cũng là một lựa chọn đầu vào được chấp nhận.

4. Tùy chọn: chờ bất đồng bộ và khôi phục sau gián đoạn

Điều kiện tiên quyết về tài khoản ở mục 1 khác với chế độ thực thi. 403 async_not_enabled có nghĩa là cần kích hoạt tính năng tác vụ trong bảng điều khiển. Chỉ việc chạy nền là tùy chọn.

Nếu muốn tạo ảnh nền, hãy tạo cùng từ điển generation, rồi dùng hai dòng bên dưới thay cho cả dòng đồng bộ task = api_json(...) lẫn lệnh gọi collect(...) riêng biệt. Hãy chọn chế độ trước khi gửi; đừng chạy cả hai phiên bản:

task = api_json("POST", IMAGES + "/generations", {**generation, "async": True})
collect(task, "mug-blue", poll=True)

Hàm trợ giúp truy vấn GET /ai/v1/images/{id} khoảng 15 giây một lần cho đến khi tác vụ đạt trạng thái kết thúc. Đây là khuyến nghị thăm dò được ghi trong tài liệu, không phải khoảng thời gian do máy chủ bắt buộc. Webhook yêu cầu async: true; việc thiết lập bộ nhận nằm ngoài phạm vi hướng dẫn này.

Nếu quá trình thu thập bị dừng, khi cần thì chỉ nạp lại khối thiết lập/hàm trợ giúp dùng chung trong phụ lục vào phiên mới, không nạp khối tạo ảnh. Nếu đã lưu ID, hãy tiếp tục mà không gửi POST nào:

task_id = Path("mug-blue.task-id").read_text(encoding="utf-8").strip()
task = api_json("GET", IMAGES + "/" + quote(task_id, safe=""))
collect(task, "mug-blue", poll=True)

Dùng phần tên tương ứng mug-green để khôi phục tác vụ chỉnh sửa. Nếu phản hồi tạo ảnh biến mất trước khi lưu ID, hãy kiểm tra các tác vụ gần đây thay vì gửi lại:

recent = api_json("GET", IMAGES + "?limit=20&order=desc")
for row in recent.get("data", []):
    print(row.get("id"), row.get("model"), row.get("status"), row.get("created_at"))

Đối chiếu model và thời điểm tạo; đừng mặc định chọn tác vụ mới nhất. Nếu cần, dùng next_after làm con trỏ after cho yêu cầu tiếp theo. Nếu không thể xác định chắc chắn tác vụ phù hợp, hãy liên hệ bộ phận hỗ trợ thay vì gửi lại. Danh sách chỉ là ảnh chụp tại một thời điểm; hãy dùng chi tiết tác vụ để thăm dò. output_error trong một hàng có nghĩa là không đọc được đầu ra, không phải quá trình tạo không tạo ra gì hoặc khoản phí đã thay đổi.

Tiếp tục dùng khóa đã tạo tác vụ. Cụ thể, quyền truy cập vào danh sách tác vụ, chi tiết tác vụ và nội dung trong API hợp nhất được cô lập theo token: khóa khác trên cùng tài khoản không thể đọc các tác vụ đó. Việc gián đoạn cục bộ không chứng minh tác vụ thất bại hay không phát sinh phí.

5. Lỗi thường gặp khi di chuyển và các lỗi hiện tại

Tài liệu bộ chuyển đổi Doubao cũ liệt kê các ID đời cũ dưới dạng /v1/models/doubao/<id>/predictions với đối tượng bao input. Danh sách này không có phiên bản 5.5. Hãy dùng đường dẫn 5.5 có thể tra cứu và nội dung phẳng ở đây; chưa có lỗi tạo ảnh bằng phiên bản cũ nào được kiểm thử. Hãy sao chép chính xác ID hiện tại có dấu gạch nối, đừng cho rằng cách viết có dấu chấm là bí danh.

Đừng giữ lại các trường cấp cao nhất quality, background, aspect_ratio hay seed: chúng không có trong lược đồ hiện tại của model này. Thông báo ra mắt của ByteDance mô tả đầu ra RGBA trong suốt nguyên bản, nhưng lược đồ gateway không có background hay layer_decomposition. Chỉ chọn PNG không phải là công thức tạo ảnh trong suốt đã được xác minh.

Đây là các lỗi hình ảnh hợp nhất được ghi trong tài liệu, không phải phản hồi 5.5 đã quan sát được. Hãy kiểm tra trạng thái HTTP riêng với trạng thái tác vụ và phân nhánh theo code, không dựa vào toàn bộ chuỗi thông báo.

Vị trí Mã lỗi Hành động tiếp theo
HTTP 400 schema_violation Sửa các trường trong lược đồ
HTTP 400 capability_not_supported Xóa các tùy chọn không được hỗ trợ
HTTP 504 sync_timeout Khôi phục; liên hệ bộ phận hỗ trợ
HTTP 502 task_status_unavailable Đừng gửi lại
HTTP 422 output_blocked Điều chỉnh nội dung
HTTP 403 async_not_enabled Kích hoạt tính năng tác vụ
Tác vụ thất bại result_delivery_failed Kiểm tra kết quả hiện có

Với HTTP 502 task_status_unavailable, hướng dẫn nêu:

Không thể xác nhận trạng thái tác vụ của nhà cung cấp model. Đừng gửi lại. Liên hệ bộ phận hỗ trợ và cung cấp ID tác vụ hoặc ID yêu cầu.

Với lỗi cấp tác vụ result_delivery_failed, hướng dẫn nêu:

Không thể chuyển giao kết quả đã tạo. Đừng tự động gửi lại. Liên hệ bộ phận hỗ trợ và cung cấp ID tác vụ.

sync_timeout không xác định rằng quá trình thực thi chưa từng diễn ra. Hãy giữ lại error.tid, chỉ dùng ID tác vụ nếu thực sự có ID được trả về, và yêu cầu bộ phận hỗ trợ xử lý kết quả chưa rõ. Nếu lỗi tải xuống có thể khắc phục, hãy thử lấy lại kết quả thay vì tạo ảnh lần nữa. 410 artifact_expired là trường hợp khác: không thể lấy lại tệp đó nữa. Trước tiên, hãy kiểm tra các tệp đã lưu; nếu vẫn cần ảnh thay thế, hãy chủ động cho phép một lần tạo ảnh mới có tính phí. Với 429 too_many_downloads, hãy kiểm tra bản sao đã lưu hoặc liên hệ bộ phận hỗ trợ; chỉ chờ không đảm bảo quyền truy cập sẽ được cấp lại.

Hướng dẫn nêu rõ sẽ miễn phí tạo ảnh đối với output_blocked, kể cả khi lỗi này được báo trong một tác vụ thất bại. Đừng áp dụng ngoại lệ đó cho mọi yêu cầu thất bại hoặc bị kiểm duyệt; output_policy_violation tuân theo quy tắc tính phí kiểm duyệt hiện hành.

6. Dự trù chi phí cho cả quy trình, không chỉ một ảnh đầu ra

Báo cáo ra mắt của Sina Technology cho biết chi phí khoảng CNY 0.28 cho một lần chỉnh sửa ảnh vuông 2K, bao gồm đầu vào và đầu ra hình ảnh, còn token văn bản được miễn phí. Đây là thông tin báo chí, không phải bảng giá chính thức đã xác minh hay báo giá từ AIHubMix.

Ví dụ minh họa: hai lượt chỉnh sửa ảnh hiện có có tính phí, mỗi lượt tương đương với kịch bản làm tròn nói trên, sẽ tốn khoảng 2 × CNY 0.28 = CNY 0.56. Mức này không bao gồm lần tạo ảnh ban đầu từ văn bản, ảnh tham chiếu bổ sung, các ảnh đầu ra bổ sung hay những lần thử lại. Đây không phải hóa đơn đã ghi nhận.

Với ví dụ tạo ảnh rồi chỉnh sửa này, hãy tính tổng = phí tạo ảnh ban đầu + phí chỉnh sửa có ảnh tham chiếu. Các trang được xem xét không xác lập được bảng giá chính thức đầy đủ của 5.5, vì vậy hướng dẫn này không đưa ra tổng chi phí cố định hay tỷ lệ tiết kiệm chính xác giữa phiên bản cũ và mới.

Trước khi gửi:

  • Xác nhận ID, đường dẫn, nội dung phẳng và lược đồ model hiện tại.
  • Giữ khóa trong biến môi trường; lưu ID tác vụ để khôi phục.
  • Coi mỗi yêu cầu POST là một thao tác tính phí riêng, không bao giờ gửi lại để thử tải xuống.
  • Kiểm tra trạng thái tác vụ và ảnh đã lưu trước khi chỉnh sửa.
  • Tải lại dữ liệu cục bộ với MIME type chính xác.
  • Khôi phục các tác vụ chưa rõ kết quả trước khi cân nhắc tạo ảnh khác.

Bắt đầu với một ảnh và một lần chỉnh sửa có chủ đích; chỉ thêm các lượt chỉnh sửa sau khi xem lại tệp.

Phụ lục: thiết lập dùng chung và hàm tải xuống

Bỏ qua phụ lục này khi đọc quy trình. Trước khi chạy các ví dụ ngắn, hãy mở rộng và tải khối này một lần vào cùng phiên Python. Khối này cấu hình phiên và định nghĩa các hàm mà không tạo ảnh. Để khôi phục một tác vụ bị gián đoạn trong phiên mới, chỉ tải lại khối này — không tải khối tạo ảnh hay chỉnh sửa ảnh.

Mở rộng toàn bộ phần trợ giúp — tải một lần trước các ví dụ ngắn; không gửi yêu cầu tạo ảnh
import base64
import os
import time
from pathlib import Path
from urllib.parse import quote, urlsplit

import requests

BASE = "https://aihubmix.com"
IMAGES = "/ai/v1/images"
settings = {
    "model": "doubao-seedream-5-5",
    "size": "2048x2048",
    "n": 1,
    "output_format": "png",
    "response_format": "url",
}
client = requests.Session()
client.headers["Authorization"] = "Bearer " + os.environ["AIHUBMIX_API_KEY"]


def api_json(method, path, body=None):
    try:
        response = client.request(
            method, BASE + path, json=body,
            timeout=(15, 600), allow_redirects=False,
        )
    except requests.RequestException:
        raise SystemExit(
            "Connection interrupted. Recover the existing task before another POST."
        ) from None
    try:
        data = response.json()
    except ValueError:
        raise SystemExit(
            f"HTTP {response.status_code}: non-JSON response; recover before another POST."
        ) from None
    if not isinstance(data, dict):
        raise SystemExit("Unexpected response; recover before another POST.")
    if not 200 <= response.status_code < 300:
        error = data.get("error") or {}
        raise SystemExit(
            f"HTTP {response.status_code}: code={error.get('code')}, "
            f"tid={error.get('tid')}. No automatic generation retry."
        )
    return data


def collect(task, stem, poll=False):
    task_id = task.get("id")
    if not isinstance(task_id, str) or not task_id:
        raise SystemExit("No task ID returned. Recover from the task list; do not resubmit.")
    Path(stem + ".task-id").write_text(task_id + "\n", encoding="utf-8")
    while True:
        status = task.get("status")
        print("Task:", task_id, "status:", status)
        if status == "completed":
            break
        if status not in {"pending", "in_progress"}:
            error = task.get("error") or {}
            raise SystemExit(
                f"Stopped: status={status}, code={error.get('code')}; task={task_id}."
            )
        if not poll:
            raise SystemExit("Task still active. Query the saved ID; do not recreate it.")
        time.sleep(15)
        task = api_json("GET", IMAGES + "/" + quote(task_id, safe=""))

    output = task.get("output") or []
    if not output:
        raise SystemExit("Completed without readable output; investigate the saved task.")
    item = output[0]
    if item.get("b64_json"):
        image_bytes = base64.b64decode(item["b64_json"], validate=True)
    else:
        url = item.get("content_url")
        if not isinstance(url, str):
            raise SystemExit("Missing content_url; investigate the saved task.")
        parsed = urlsplit(url)
        if (parsed.scheme, parsed.netloc) != ("https", "aihubmix.com"):
            raise SystemExit("Unexpected download origin; key was not forwarded.")
        try:
            response = client.get(url, timeout=(15, 120), allow_redirects=False)
        except requests.RequestException:
            raise SystemExit("Download interrupted; recover this task, not a new generation.") from None
        if not 200 <= response.status_code < 300:
            try:
                detail = response.json()
            except ValueError:
                detail = {}
            error = detail.get("error", {}) if isinstance(detail, dict) else {}
            code = error.get("code") if isinstance(error, dict) else None
            if response.status_code == 410 or code == "artifact_expired":
                raise SystemExit("Artifact expired; retrieval cannot recover it. Check saved files first.")
            if code == "too_many_downloads":
                raise SystemExit("Download allowance exhausted; check saved files or contact support.")
            raise SystemExit(
                f"Download HTTP {response.status_code}, code={code}; "
                "inspect the saved task. Retry retrieval only if recoverable."
            )
        image_bytes = response.content
    if not image_bytes.startswith(b"\x89PNG\r\n\x1a\n"):
        raise SystemExit("Expected PNG bytes; stopped before saving or reusing the result.")
    destination = Path(stem + ".png")
    destination.write_bytes(image_bytes)
    print("Saved:", destination)
    return destination

Thời gian chờ đọc 600 giây là lựa chọn của phía client, không phải cam kết về độ trễ của dịch vụ. Kiểm tra PNG phù hợp với định dạng đầu ra được chỉ định rõ trong hướng dẫn này; hãy điều chỉnh nếu bạn chọn JPEG.

Câu hỏi thường gặp

Nên dùng ID model và endpoint nào cho Seedream 5.5?
Dùng doubao-seedream-5-5 với POST /ai/v1/images/generations và JSON dạng phẳng. Đừng cho rằng cách viết khác hoặc adapter cũ là tương đương.

Hướng dẫn này có bao gồm kết quả tạo ảnh đã được kiểm thử không?
Không. Mã được xây dựng dựa trên tài liệu, chỉ kiểm tra cú pháp cục bộ và hàm trợ giúp ngoại tuyến. Không thực hiện yêu cầu suy luận, đo chất lượng ảnh, đo độ trễ hay kiểm thử tính phí nào.

Có bắt buộc dùng async không?
Không; mặc định là chờ đồng bộ. Thực thi nền sử dụng giá trị Boolean async: true. Cần kích hoạt tính năng tác vụ ở cấp tài khoản để dùng các endpoint tác vụ media gốc, kể cả khi chờ đồng bộ.

HTTP 200 có nghĩa là tạo ảnh thành công không?
Không. Hãy kiểm tra trạng thái tác vụ và lỗi đi kèm. Tác vụ có thể thất bại dù yêu cầu HTTP thành công; chỉ tải xuống khi tác vụ đã hoàn tất.

URL tải kết quả có thể dùng làm ảnh tham chiếu cho lần chỉnh sửa tiếp theo không?
Đừng mặc định là có. Hãy tải ảnh xuống bằng khóa đã dùng để tạo ảnh, sau đó mã hóa ảnh cục bộ thành Data URI hoặc cung cấp URL ảnh thực sự công khai.

Nên làm gì sau khi hết thời gian chờ hoặc mất phản hồi?
Đừng tự động gửi lại yêu cầu tạo ảnh. Kiểm tra ID tác vụ đã lưu hoặc khôi phục tác vụ từ danh sách ảnh bằng khóa đã dùng để tạo ảnh. Lưu ID yêu cầu và liên hệ bộ phận hỗ trợ khi chưa rõ kết quả.

Chọn PNG có đảm bảo đầu ra trong suốt hoặc hóa đơn CNY 0.28 không?
Không điều nào được đảm bảo. Schema không cung cấp tùy chọn kiểm soát độ trong suốt đã được xác minh. CNY 0.28 là mức chi phí xấp xỉ cho một tình huống chỉnh sửa 2K được báo chí đưa tin, không phải báo giá của AIHubMix hay mức giá cố định cho quy trình tạo ảnh từ văn bản rồi chỉnh sửa.

Đọc tiếp: dòng Seedream 5.5

Nguồn

  1. Thông báo ra mắt Seedream 5.5 — ByteDance Seed; các tuyên bố về năng lực từ nhà cung cấp.
  2. Schema endpoint Seedream 5.5 hiện tại — AIHubMix; các trường yêu cầu và giới hạn riêng của model.
  3. API tạo ảnh hợp nhất — AIHubMix; tác vụ, tải xuống và lỗi hiện tại.
  4. Hướng dẫn model Seedream 5.5 — AIHubMix; ID model và liên kết tải xuống có xác thực, hiệu lực ngắn; dùng tài liệu API hợp nhất để xem lỗi theo từng route.
  5. Tin tức về màn ra mắt Seedream 5.5 — Sina Technology; tình huống chi phí chỉnh sửa ước tính, không phải biểu phí chính thức.

Một cổng duy nhất tới nhiều nhà cung cấp AI. Sẵn sàng cho môi trường production.

Truy cập AIHubMix