
Надежной интеграции комикса из четырех панелей недостаточно одного запроса на генерацию. Минимальный продакшен-цикл выглядит так:
загрузка референса персонажа -> создание четырех панелей -> опрос до терминального статуса -> проверка каждой панели -> восстановление только проблемной панели
Этот быстрый старт реализует такой цикл на TypeScript. Он хранит API-ключ на сервере, передает стабильную запись персонажа, использует ключ идемпотентности для запроса на создание, фиксирует прошедшее время и сбои и нацеливается на одну панель, когда нарушается непрерывность.
Начните с LlamaGen.AI Comic API, затем используйте полный пример ниже как базовую серверную интеграцию.
Эта статья была сверена по контракту с актуальной документацией Comic API 10 октября 2026 года.
| Проверка | Подтвержденное поведение |
|---|---|
| Аутентификация | Bearer-токен в каждом запросе |
| Базовый URL для продакшена | https://api.llamagen.ai |
| Загрузка | POST /v1/comics/upload возвращает переиспользуемый fileUrl |
| Создание | POST /v1/comics/generations принимает fixPanelNum: 4 и comicRoles |
| Статус |
GET /v1/comics/generations/{generationId} возвращает статус и результат по панелям |
| Восстановление | PATCH /v1/comics/generations/{generationId} может перегенерировать одну панель с нумерацией от нуля |
| Использование | Ответы на создание и восстановление содержат данные об использовании для ваших собственных логов |
Мы не придумывали показатели задержки или успешности. Эти значения зависят от аккаунта, очереди, конфигурации модели и входных данных. Пример фиксирует ваше фактическое время выполнения, использование API, терминальный статус и детали ошибок, чтобы вы могли получить обоснованные метрики в своей собственной среде.
Промпт сообщает модели, что происходит. Референс персонажа сообщает ей, с кем происходит история.
Для повторяющейся роли держите эти поля стабильными:
В этом примере роль — курьер с короткими темными волосами, желтым дождевиком и красной сумкой через плечо. Эти детали достаточно компактны, чтобы их повторять, и достаточно различимы, чтобы их можно было проверять.
Обзор последних релизов функций LlamaGen, улучшений продукта, обновлений дизайна и важных исправлений ошибок.

Используйте Node.js 20 или новее, чтобы были доступны fetch, FormData и Blob. Храните ключ в серверной переменной окружения.
export LLAMAGEN_API_KEY="your_server_side_key"
Не раскрывайте этот ключ в браузерной сборке, мобильном приложении, публичном репозитории или клиентском запросе. Если у вашего продукта есть фронтенд, отправляйте краткое описание пользователя на ваш собственный бэкенд, а уже этот бэкенд должен вызывать LlamaGen.AI.
Workflow включает четыре сетевые операции:

Сохраните следующий файл как comic-quickstart.ts, поместите изображение персонажа по пути ./courier-reference.png и запустите его из своего серверного окружения.
import { basename } from "node:path";
import { readFile } from "node:fs/promises";
import { randomUUID } from "node:crypto";
const API_BASE = "https://api.llamagen.ai";
const API_KEY = process.env.LLAMAGEN_API_KEY;
if (!API_KEY) {
throw new Error("Set LLAMAGEN_API_KEY before running this script.");
}
type UploadResponse = {
code?: number;
fileUrl: string;
};
type Usage = {
total_comics?: number;
redraw_panels?: number;
amount?: number;
};
type Generation = {
id: string;
status: "LOADING" | "PROCESSED" | "FAILED" | "CANCELLED" | string;
usage?: Usage;
comics?: Array<{
page?: number;
panels?: Array<{
panel?: number;
image?: string;
assetUrl?: string;
caption?: string;
}>;
}>;
error?: unknown;
};
async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
const response = await fetch(`${API_BASE}${path}`, {
...init,
headers: {
Authorization: `Bearer ${API_KEY}`,
...init.headers,
},
});
const text = await response.text();
const body = text ? JSON.parse(text) : null;
if (!response.ok) {
throw new Error(
`Comic API ${response.status}: ${JSON.stringify(body)}`,
);
}
return body as T;
}
async function uploadReference(filePath: string) {
const bytes = await readFile(filePath);
const form = new FormData();
form.set("file", new Blob([bytes]), basename(filePath));
return api<UploadResponse>("/v1/comics/upload", {
method: "POST",
body: form,
});
}
async function waitForGeneration(
generationId: string,
timeoutMs = 10 * 60_000,
) {
const startedAt = Date.now();
while (Date.now() - startedAt < timeoutMs) {
const job = await api<Generation>(
`/v1/comics/generations/${generationId}`,
);
console.log(
JSON.stringify({
generationId,
status: job.status,
elapsedMs: Date.now() - startedAt,
usage: job.usage,
}),
);
if (job.status === "PROCESSED") return job;
if (job.status === "FAILED" || job.status === "CANCELLED") {
throw new Error(
`Generation ended as ${job.status}: ${JSON.stringify(job.error)}`,
);
}
await new Promise((resolve) => setTimeout(resolve, 4_000));
}
throw new Error(`Generation ${generationId} timed out.`);
}
async function main() {
const startedAt = Date.now();
try {
const reference = await uploadReference("./courier-reference.png");
const created = await api<Generation>("/v1/comics/generations", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": randomUUID(),
},
body: JSON.stringify({
prompt: [
"Create one four-panel comic page in a restrained cinematic manga style.",
"Panel 1: Ren enters a rain-soaked station and notices a golden key.",
"Panel 2: Close view as Ren lifts the key and studies it.",
"Panel 3: Ren runs toward an old locked service door.",
"Panel 4: Ren opens the door and warm light spills into the station.",
"Keep the same face, haircut, yellow jacket, and red messenger bag.",
"Leave clean space for later lettering.",
].join("\n"),
preset: "japanese_manga",
size: "1024x1024",
fixPanelNum: 4,
language: "en",
comicRoles: [
{
name: "Ren",
age: 22,
gender: "male",
dress: "yellow rain jacket, black trousers, red messenger bag",
image: reference.fileUrl,
},
],
}),
});
const firstPass = await waitForGeneration(created.id);
console.log("first_pass_complete", {
id: firstPass.id,
elapsedMs: Date.now() - startedAt,
usage: firstPass.usage,
pages: firstPass.comics?.length ?? 0,
});
// Example review result: panel 3 lost the red bag.
const repairQueued = await api<Generation>(
`/v1/comics/generations/${created.id}`,
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
page: 0,
panel: 2,
panelPrompt:
"Ren runs toward the service door. Preserve his exact face, short dark hair, yellow rain jacket, and visible red messenger bag.",
images: [reference.fileUrl],
}),
},
);
console.log("repair_queued", {
id: repairQueued.id,
usage: repairQueued.usage,
});
const repaired = await waitForGeneration(created.id);
console.log("workflow_complete", {
id: repaired.id,
totalElapsedMs: Date.now() - startedAt,
finalStatus: repaired.status,
});
} catch (error) {
console.error("comic_workflow_failed", {
elapsedMs: Date.now() - startedAt,
message: error instanceof Error ? error.message : String(error),
});
process.exitCode = 1;
}
}
await main();
Запустите командой:
npx tsx comic-quickstart.ts
Пример намеренно пишет структурированные объекты в лог. В продакшене отправляйте те же поля в вашу систему наблюдаемости и добавляйте собственный идентификатор запроса или проекта.
Не утверждайте страницу только потому, что она красиво выглядит в виде миниатюры. Проверяйте каждую панель по фиксации персонажа:
| Проверка | Условие прохождения |
|---|---|
| Лицо | Один и тот же возраст, черты и пропорции |
| Волосы | Один и тот же силуэт, длина и цвет |
| Костюм | Желтая куртка остается желтой и сохраняет ту же конструкцию |
| Реквизит | Красная сумка через плечо остается на месте и расположена корректно |
| Последовательность | Ключ, дверь, погода и направление движения остаются непрерывными |
| Композиция | У каждой панели своя четкая сюжетная функция |
| Место для текста | Лица и ключевые действия не перекрыты |
Считайте это машиночитаемым контролем качества, если вы строите более крупный pipeline. Сохраняйте причину прохождения/непрохождения для каждой панели, а не только общее одобрение страницы.
Самый быстрый промпт для восстановления называет и новое действие, и элементы, которые нельзя менять.
Восстановление панели 3:
Рен бежит к служебной двери.
Сохрани его точное лицо, короткие темные волосы, желтый дождевик
и видимую красную сумку через плечо.
Сохрани дождливую станцию и движение слева направо.
Индексы панелей нумеруются с нуля, поэтому видимая третья панель — это panel: 2. Эндпоинт обновления может принимать panelPrompt, референсные images или заменяющий caption.

Это важно с операционной точки зрения. Пересборка всех четырех панелей может внести три новых риска непрерывности, пока вы исправляете одну старую проблему. Точечное восстановление сужает поверхность проверки.
Перед выпуском интеграции добавьте эти меры контроля:
Для более длинных последовательностей переключайтесь с fixPanelNum на pagination.totalPages и pagination.panelsPerPage. Не отправляйте оба режима в одном запросе на создание.
Используйте Comic API, когда комиксы генерируются внутри вашего собственного продукта, batch-задачи, образовательного инструмента, издательского pipeline или клиентского workflow.
Используйте визуальный редактор, когда автор хочет интерактивно исследовать историю, сравнивать альтернативы или вручную задавать художественное направление для каждой страницы. Многие команды используют оба варианта: API создает и логирует воспроизводимый первый проход, а редактор обрабатывает исключительные правки.
Если структура вашей истории еще меняется, спланируйте ее до создания финальных панелей. Следующее руководство, Storyboard First or Comic Panels First?, показывает, как измерить разницу в объеме переделок.
Да. Отправьте fixPanelNum: 4 для одностраничного запроса на четыре панели. Для нескольких страниц вместо этого используйте объект pagination.
Загрузите чистое референсное изображение, передайте возвращенный fileUrl в comicRoles[].image, держите имя роли и описание костюма стабильными и проверяйте каждую возвращенную панель перед продолжением последовательности.
Да. Отправьте запрос PATCH с индексами страницы и панели, нумеруемыми с нуля, а также новым panelPrompt, необязательными референсными изображениями или подписью.
Используйте поведение идемпотентности, задокументированное LlamaGen.AI, чтобы сетевые повторы случайно не создавали дублирующую работу. Используйте новый ключ только тогда, когда вы намеренно хотите новую генерацию.
Нет. Он показывает инструментацию, необходимую для сбора ваших реальных показателей. Публикуйте задержку, использование и частоту сбоев только после многократного запуска одного и того же входа в вашем аккаунте и фиксации условий.
Текст написан Jay и технически проверен по контракту актуального эндпоинта контент-командой LlamaGen.AI. Поведение продукта может измениться; источником истины остается связанная документация.
Готовы собрать workflow? Откройте LlamaGen.AI Comic API, создайте серверный ключ и запустите быстрый старт с собственным референсом персонажа.
Popular creator tools
Go from comics and storyboards to stylized photos with LlamaGen.
Visualize every scene before production starts.
© 2026 LlamaGen.Ai Все права защищены
Лидеры будущего AI-генерации комиксов



