Перейти к основному содержимому

LLM для креативного письма: конвейер от идеи до критики

LLM для креативного письма

Я разберу конвейер для креативного письма, который превращает идею в одно предложение в структурированный план, написанную сцену и письменную критику. Это полезно писателям-прозаикам и нарративным дизайнерам, которым нужно быстро итерировать, не сражаясь с пустой страницей. Мы подключим каждый этап к Oxlo.ai с помощью OpenAI SDK, так что код станет заменой «под ключ», которую можно запустить сразу же.

Что вам понадобится

  • API-ключ Oxlo.ai из https://portal.oxlo.ai
  • Python 3.10 или новее
  • OpenAI SDK, установленный через pip install openai

1. Инициализация клиента

Сначала мы создаём экземпляр клиента OpenAI, указывая на Oxlo.ai. По умолчанию я использую Llama 3.3 70B для надёжного следования творческим инструкциям. Поскольку Oxlo.ai использует оплату за запросы, отправка длинных планов обратно в модель не раздувает стоимость так, как это делает биллинг по токенам. Детали тарифов смотрите на https://oxlo.ai/pricing.

from openai import OpenAI

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

# Проверяем соединение коротким тестовым запросом
response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Say hello"},
    ],
    max_tokens=10,
)
print(response.choices[0].message.content)

2. Определение системного промпта

Этот промпт задаёт основу для каждого этапа конвейера, чтобы модель оставалась в mindset художественной литературы.

SYSTEM_PROMPT = (
    "You are a fiction writing assistant. "
    "You help the user develop stories from premise to polished prose. "
    "Be concise but vivid. Focus on character motivation, sensory detail, and narrative tension. "
    "When asked for an outline, return a three-act structure with bullet points. "
    "When asked for a scene, write in the present tense with dialogue and interiority. "
    "When asked for a critique, evaluate pacing, voice, and emotional payoff, then suggest one concrete revision."
)

3. Генерация структурированного плана

Далее мы пишем функцию, которая передаёт пользовательскую идею в Llama 3.3 70B и запрашивает план из трёх актов.

def generate_outline(premise: str) -> str:
    user_message = (
        f"Premise: {premise}\n\n"
        "Return a three-act outline with 3 bullet points per act. "
        "Keep each bullet to one sentence."
    )
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
    )
    return response.choices[0].message.content

4. Черновик сцены

Теперь мы выбираем один бит из плана и разворачиваем его в полноценную сцену. Здесь я переключаюсь на Qwen 3 32B, потому что его способности к рассуждению хорошо справляются с повествовательным потоком при генерации длинных текстов.

def draft_scene(outline: str, beat: str, word_count: int = 300) -> str:
    user_message = (
        f"Outline:\n{outline}\n\n"
        f"Write the following beat as a scene of roughly {word_count} words:\n{beat}\n\n"
        "Use present tense, include dialogue, and anchor the moment in a specific sensory detail."
    )
    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
    )
    return response.choices[0].message.content

5. Критика сцены

Наконец, мы запускаем проход самокритики. Я использую DeepSeek V3 2, потому что его сильные стороны в рассуждениях хорошо работают для литературного анализа, и он доступен на бесплатном тарифе Oxlo.ai, если вы хотите экспериментировать без затрат. Если вам нужно ещё более глубокое рассуждение, Kimi K2.6 — ещё один сильный вариант на Oxlo.ai.

def critique_scene(scene: str) -> str:
    user_message = (
        f"Scene:\n{scene}\n\n"
        "Provide a short critique covering pacing, voice, and emotional payoff. "
        "Then suggest one concrete revision."
    )
    response = client.chat.completions.create(
        model="deepseek-v3.2",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": user_message},
        ],
    )
    return response.choices[0].message.content

6. Собираем конвейер вместе

Мы связываем три этапа так, чтобы одна идея проходила путь от плана к сцене и к критике. В этой демонстрации я автоматически беру первый пункт из плана.

def write_story(premise: str) -> dict:
    outline = generate_outline(premise)
    # извлекаем первый пункт как целевой бит
    lines = [line.strip() for line in outline.splitlines() if line.strip().startswith("-")]
    first_beat = lines[0].lstrip("- ").strip() if lines else "The inciting incident"
    scene = draft_scene(outline, first_beat)
    critique = critique_scene(scene)
    return {"outline": outline, "scene": scene, "critique": critique}

if __name__ == "__main__":
    result = write_story(
        "A retired astronaut discovers a radio signal coming from her old lunar landing site."
    )
    print("=== OUTLINE ===")
    print(result["outline"])
    print("\n=== SCENE ===")
    print(result["scene"])
    print("\n=== CRITIQUE ===")
    print(result["critique"])

Запуск

Запуск скрипта против Oxlo.ai выдаёт результат, похожий на этот:

=== OUTLINE ===
Act One:
- Dr. Elena Voss hears a faint beacon during a routine archival sweep.
- She realizes the signal matches the frequency of her old lunar module.
- She decides to hack into the retired observatory to triangulate the source.

Act Two:
...

=== SCENE ===
The radio crackles at 2:47 a.m. Elena leans forward, her coffee gone cold. The frequency is impossible. She checks the timestamp again, then reads the coordinates. Sea of Tranquility. Her boots were there thirty years ago. "Houston," she whispers, though Houston stopped listening years ago. She hits record.

=== CRITIQUE ===
Pacing: The opening hook is strong, but the transition from coffee to coordinates feels abrupt. Voice: The "Houston" line lands well. Emotional payoff: The loneliness reads clearly, but we could deepen it with a tactile memory of the lunar dust. Revision: Add one sentence describing the grit she still finds under her fingernails when she is stressed.

Следующие шаги

Два конкретных способа расширить это. Во-первых, добавьте четвёртый этап, который передаёт критику обратно в функцию draft_scene как заметки для правки, чтобы автоматически генерировать второй проход. Во-вторых, сохраняйте каждый артефакт в лёгкой базе данных SQLite, чтобы со временем построить доступную для поиска «библию истории».

Источникdevto