Qwen API Proxy поддерживает три типа генерации контента через параметр chatType:
- Текстовый чат (t2t) — обычный диалоговый AI, потоковый ответ (по умолчанию)
- Генерация изображений (t2i) — text-to-image, потоковый ответ (~10–30 сек.)
- Генерация видео (t2v) — text-to-video, система задач с polling (~30–120 сек.)
| Функция | Текст (t2t) | Изображение (t2i) | Видео (t2v) |
|---|---|---|---|
| Тип запроса | stream: true |
stream: true |
stream: false |
| Способ ответа | Streaming SSE | Streaming SSE | Polling задачи |
| Время выполнения | ~2–5 сек. | ~10–30 сек. | ~30–120 сек. |
| Где лежит URL | N/A (текст) | choices[0].message.content |
video_url / content |
| Polling на сервере | Нет | Нет | Да (автоматически) |
| Task ID | Нет | Нет | Да |
- Клиент отправляет POST-запрос с
chatType: "t2i" - Сервер создаёт чат с
stream: true - Сервер получает потоковый SSE-ответ с URL изображения
- URL изображения приходит в поле
contentпотоковых chunks - Сервер возвращает клиенту готовый URL
POST /api/chat
Content-Type: application/json
{
"message": "Описание изображения, которое нужно сгенерировать",
"model": "qwen3-vl-plus",
"chatType": "t2i",
"size": "16:9"
}
| Параметр | Обязательный | Описание | Примеры значений |
|---|---|---|---|
message |
Да | Текстовое описание изображения | "Закат над океаном с фиолетовыми облаками" |
model |
Нет | Модель для генерации (по умолчанию qwen-max-latest) | qwen-max-latest, qwen3-vl-plus |
chatType |
Да | Должно быть "t2i" |
"t2i" |
size |
Нет | Соотношение сторон | "16:9", "9:16", "1:1", "4:3" |
chatId |
Нет | ID существующего чата для продолжения контекста | UUID из предыдущего ответа |
parentId |
Нет | ID родительского сообщения | UUID из предыдущего ответа |
{
"id": "response-uuid-here",
"object": "chat.completion",
"created": 1771318618,
"model": "qwen3-vl-plus",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "https://cdn.qwenlm.ai/output/.../t2i/.../image.png?key=***"
},
"finish_reason": "stop"
}
],
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"characters": 0,
"width": 2688,
"image_count": 1,
"height": 1536
},
"response_id": "response-uuid-here",
"chatId": "chat-uuid-here",
"parentId": "parent-uuid-here"
}Поле content содержит прямой URL на сгенерированное изображение. Обычно такие URL размещаются на cdn.qwenlm.ai.
JavaScript (fetch):
const response = await fetch("http://localhost:3264/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "Красивый пейзаж: горы и озеро на рассвете",
model: "qwen3-vl-plus",
chatType: "t2i",
size: "16:9"
}),
});
const data = await response.json();
const imageUrl = data.choices[0].message.content;
console.log("Сгенерированное изображение:", imageUrl);cURL:
curl -X POST http://localhost:3264/api/chat \
-H "Content-Type: application/json" \
-d '{
"message": "Футуристический город ночью с неоновыми огнями",
"model": "qwen3-vl-plus",
"chatType": "t2i",
"size": "16:9"
}'PowerShell:
$body = @{
message = "Милый кот сидит на книжной полке"
model = "qwen3-vl-plus"
chatType = "t2i"
size = "1:1"
} | ConvertTo-Json
$response = Invoke-RestMethod -Uri "http://localhost:3264/api/chat" `
-Method Post -Body $body -ContentType "application/json"
$imageUrl = $response.choices[0].message.content
Write-Host "URL изображения: $imageUrl"Генерация видео поддерживает два режима polling:
Лучше для простых интеграций и коротких видео (<2 мин.).
- Клиент отправляет запрос с
chatType: "t2v"иwaitForCompletion: true(по умолчанию) - Сервер создаёт задачу — Qwen API возвращает
task_id - Сервер автоматически проверяет статус каждые 2 секунды (до 90 попыток = 3 мин.)
- Когда задача завершена, сервер возвращает клиенту URL видео
Плюсы: просто, один запрос, логика polling на клиенте не нужна.
Минусы: длинное HTTP-соединение, фиксированный таймаут 3 минуты.
Лучше для длинных видео (>2 мин.), кастомных таймаутов и отображения прогресса в UI.
- Клиент отправляет запрос с
chatType: "t2v"иwaitForCompletion: false - Сервер сразу возвращает
task_id(~1–2 сек.) - Клиент проверяет
GET /api/tasks/status/:taskIdкаждые 2–5 секунд - Когда задача завершена, клиент получает URL видео
Плюсы: гибкий таймаут, отслеживание прогресса, лучше для долгих операций.
Минусы: нужна логика polling на клиенте.
POST /api/chat
Content-Type: application/json
{
"message": "Описание видео, которое нужно сгенерировать",
"model": "qwen3-vl-plus",
"chatType": "t2v",
"size": "16:9"
}
| Параметр | Обязательный | Описание | Примеры значений |
|---|---|---|---|
message |
Да | Текстовое описание видео | "Волны океана на песчаном пляже на закате" |
model |
Да | Модель для генерации | qwen3-vl-plus, qwen-max-latest |
chatType |
Да | Должно быть "t2v" |
"t2v" |
size |
Нет | Соотношение сторон (по умолчанию "16:9") |
"16:9", "9:16", "1:1", "4:3" |
waitForCompletion |
Нет | Сервер ждёт завершения задачи (по умолчанию true) |
true / false |
chatId |
Нет | ID существующего чата | UUID из предыдущего ответа |
parentId |
Нет | ID родительского сообщения | UUID из предыдущего ответа |
Важно: размер видео указывается как соотношение сторон (например, "16:9"), а не как разрешение в пикселях.
{
"id": "task-uuid-here",
"object": "chat.completion",
"created": 1771318618,
"model": "qwen3-vl-plus",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "https://cdn.qwenlm.ai/output/.../t2v/.../video.mp4?key=***"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 0,
"output_tokens": 0,
"total_tokens": 0
},
"task_id": "task-uuid-here",
"video_url": "https://cdn.qwenlm.ai/output/.../t2v/.../video.mp4?key=***",
"chatId": "chat-uuid-here",
"parentId": "task-uuid-here"
}Polling на стороне сервера (по умолчанию):
const response = await fetch("http://localhost:3264/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "Спокойный океан с мягкими волнами на закате",
model: "qwen3-vl-plus",
chatType: "t2v",
size: "16:9"
}),
});
const data = await response.json();
if (data.error) {
console.error("Не удалось сгенерировать видео:", data.error);
} else {
const videoUrl = data.video_url || data.choices[0].message.content;
console.log("Сгенерированное видео:", videoUrl);
}Polling на стороне клиента:
// Шаг 1: создаём задачу (ответ приходит сразу)
const taskResponse = await fetch("http://localhost:3264/api/chat", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
message: "Тихий лес, солнечные лучи проходят сквозь деревья",
model: "qwen3-vl-plus",
chatType: "t2v",
size: "16:9",
waitForCompletion: false
}),
});
const taskData = await taskResponse.json();
console.log("Задача создана:", taskData.task_id);
// Шаг 2: проверяем статус до завершения
const taskId = taskData.task_id;
let videoUrl = null;
let attempts = 0;
const maxAttempts = 90; // максимум 3 минуты
while (attempts < maxAttempts && !videoUrl) {
attempts++;
await new Promise(resolve => setTimeout(resolve, 2000));
const statusResponse = await fetch(`http://localhost:3264/api/tasks/status/${taskId}`);
const statusData = await statusResponse.json();
const status = statusData.task_status || statusData.status;
console.log(`Попытка ${attempts}: ${status}`);
if (status === 'completed' || status === 'succeeded') {
videoUrl = statusData.content || statusData.data?.content;
console.log("Видео готово:", videoUrl);
} else if (status === 'failed' || status === 'error') {
console.error("Задача завершилась ошибкой");
break;
}
}cURL (polling на стороне сервера):
curl -X POST http://localhost:3264/api/chat \
--max-time 200 \
-H "Content-Type: application/json" \
-d '{
"message": "Птица летит над лесом",
"model": "qwen3-vl-plus",
"chatType": "t2v",
"size": "16:9"
}'cURL (polling на стороне клиента):
# Шаг 1: создаём задачу
TASK_ID=$(curl -s -X POST http://localhost:3264/api/chat \
-H "Content-Type: application/json" \
-d '{
"message": "Волны океана на закате",
"model": "qwen3-vl-plus",
"chatType": "t2v",
"size": "16:9",
"waitForCompletion": false
}' | jq -r '.task_id')
echo "Task ID: $TASK_ID"
# Шаг 2: проверяем статус
while true; do
STATUS=$(curl -s "http://localhost:3264/api/tasks/status/$TASK_ID" | jq -r '.task_status')
echo "Статус: $STATUS"
[ "$STATUS" = "completed" ] && break
sleep 2
done| Функция | Изображение (t2i) | Видео (t2v) |
|---|---|---|
| Тип чата | "t2i" |
"t2v" |
| Способ ответа | Streaming | Polling задачи |
| Обычная длительность | 10–30 секунд | 30–120 секунд |
| Поле ответа | choices[0].message.content |
video_url или content |
| Формат файла | .jpg / .png |
.mp4 |
| Stream | true (автоматически) |
false (автоматически) |
| Polling | N/A | 90 попыток × 2 сек. = максимум 3 мин. |
| Таймаут клиента | 30–60 секунд | 120–200 секунд |
- Подробные prompts — указывайте стиль, цвета, настроение и композицию
- Рекомендованные модели —
qwen3-vl-plus(быстро, хорошее качество),qwen-max-latest - Соотношения сторон —
"1:1","16:9","9:16","4:3","3:4" - Таймаут клиента — минимум 60 секунд
- Описывайте движение — пишите про движение и изменения, а не только статичную сцену
- Не усложняйте — фокусируйтесь на одном главном действии/движении
- Соотношения сторон —
"16:9"(по умолчанию),"9:16","1:1","4:3" - Таймаут клиента — минимум 200 секунд
- Терпение — обычно генерация занимает 1–2 минуты
{ "error": "Task polling timeout exceeded", "status": "timeout", "task_id": "..." }Повторите запрос или переключитесь на polling на стороне клиента с большим числом попыток.
{ "error": "Task ID not found in response" }Проверьте статус Qwen API — это может быть временная проблема.
{ "error": "RateLimited", "detail": "You've reached the upper limit for today's usage." }Дождитесь сброса дневного лимита или добавьте больше аккаунтов.
Запустите встроенные тестовые скрипты:
# Проверить все три типа генерации (чат, изображение, видео)
npm run test:features
# Сравнить server-side и client-side polling для видео
npm run test:video-polling- Сгенерированные URL временные — скачивайте файлы, если они нужны надолго
- Более высокие разрешения генерируются дольше
- Несколько параллельных запросов работают через систему нескольких аккаунтов
- Используйте
chatIdиparentId, чтобы генерировать связанные изображения/видео в контексте
POST /api/chat— текстовый чат (chatType: "t2t", по умолчанию), изображение ("t2i"), видео ("t2v")GET /api/tasks/status/:taskId— проверить статус задачи генерации видеоGET /api/models— получить список доступных моделейPOST /api/files/upload— загрузить файлы для анализа