Обновлено
Китайская веб-проза и приложения для ролевой игры: контекст, персонажи и стоимость
Сериализованная китайская веб-проза и чат от лица персонажа — две из самых требовательных текстовых нагрузок: тысячи символов на главу, состав, который должен оставаться неизменным месяцами, и читатели, которые замечают малейшие ошибки. Это руководство показывает, как структурировать промпты, управлять контекстным окном на 100 000 токенов и оценивать стоимость на основе заявленных предположений.
Как выглядят эти нагрузки
Сериалы веб-прозы пишутся главами по 2 000–4 000 символов, часто публикуются ежедневно, а сюжет охватывает сотни глав. Ролевые приложения — это разговорный аналог: персонаж, сценарий и длинная история. И тем, и другим нужен API модели: достаточно контекста для запоминания, достаточно бюджета вывода для длинного текста и стиль, который не плывёт.
Сервис предоставляет совместимый с OpenAI эндпоинт для чата по адресу https://api.chinesellmapi.com/v1 с одной текстовой моделью с идентификатором uncensored. Контекстное окно составляет 100 000 токенов, которые делятся между промптом и завершением; значение max_tokens по умолчанию равно 2 048 и может достигать 32 000, а стандартные поля выборки, такие как temperature, top_p и stop, передаются без изменений. Поддерживается потоковая передача, что удобно для чата. Основные сведения по настройке и кодировке приведены в разделе app quickstart.
Правила контента, заявленные заранее
Это сервис только для взрослых. Допустимая взрослая проза, зрелые темы и спорные вопросы не отклоняются как таковые, сервис предназначен для пользователей старше 18 лет. Сексуальный контент с участием несовершеннолетних всегда блокируется и возвращает ошибку 403 content_blocked, даже если он подан как проза или ролевая игра. Настроек, меняющих это, нет.
Закладывайте это с самого начала. Укажите в карточках персонажей, что каждый персонаж взрослый, и укажите точный возраст. Добавьте проверку возраста в ваш продукт. Считайте 403 окончательным ответом для этого запроса: покажите нейтральное сообщение и не повторяйте запрос с перефразированными промптами. Эти шаги — хорошая практика продукта независимо от правил платформы.
Карточки персонажей и блоки стиля
Согласованность достигается за счёт вынесения стабильных фактов в одно место и их повторения в каждом запросе. Карточка персонажа — это компактная запись имени, возраста, роли, манеры речи, отношений и строгих ограничений, включая секреты, которые персонаж не должен раскрывать пока что. Отдельный блок стиля фиксирует точку зрения, темп, соотношение диалога, длину главы и привычный финал. Оба блока помещаются в системное сообщение, чтобы они стояли в начале каждого запроса.
CHARACTER_SHEET = """\
【人物卡】
姓名:沈清禾(女,28岁)
身份:江城古籍修复师,性格沉静,嘴硬心软
口头禅:“先别急,东西不会跑。”
说话方式:短句,少用感叹号,偶尔引用旧书里的句子
关系:与顾远舟(男,31岁,旧书商)是多年好友,彼此有未说出口的好感
禁忌:不提及她离开出版社的真正原因(第40章才揭晓)
"""
STYLE = """\
【文风】第三人称限知视角,贴近沈清禾;节奏舒缓,多写物件与天气的细节;
对话占比约四成;每章 2500 到 3000 字;结尾留一个小悬念。"""
Пишите их на китайском языке. Манеры речи, выраженные китайскими примерами, такими как фирменная фраза или длина предложения, передаются гораздо надежнее, чем английское описание. Держите каждую карточку в пределах нескольких сотен токенов и дайте каждому повторяющемуся персонажу одну; состав из десяти персонажей — это все еще всего несколько тысяч токенов. Когда ситуация персонажа меняется, обновляйте саму карточку, а не полагайтесь на историю для передачи изменений.
Длинный контекст для сериализованных глав
Искушение — вставить в промпт все предыдущие главы. Сначала сделайте арифметику. При окне в 100 000 токенов и главах примерно по 4 500 токенов всё окно вмещает около четырнадцати глав без места для вывода, а сериал длится сотни глав. Рабочий паттерн — многослойная память:
- Карточка персонажа и блок стиля, всегда присутствующие.
- Скользящая сводка истории, несколько сотен символов на главу, объединённые в одну накопительную сводку, которую вы обновляете каждые несколько глав.
- Полный текст предыдущей главы, чтобы проза соединялась на стыке.
- План главы, которая пишется.
После каждой главы просите модель создать краткую сводку, сохраняющую изменения в отношениях и открытые сюжетные линии, и добавляйте её к сводке. Код ниже пишет главу и создаёт следующую сводку. Он также возвращает usage, чтобы вы могли логировать реальные количества токенов:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.chinesellmapi.com/v1", api_key=os.environ["API_KEY"])
def write_chapter(sheet, style, story_so_far, last_chapter, outline):
messages = [
{"role": "system", "content": "你是一位连载网络小说的作者,所有人物均为成年人。严格遵守人物卡和文风设定。\n" + sheet + "\n" + style},
{"role": "user", "content": (
"【前情提要】\n" + story_so_far +
"\n\n【上一章全文】\n" + last_chapter +
"\n\n【本章大纲】\n" + outline +
"\n\n请直接写出本章正文,不要写标题以外的说明。")},
]
r = client.chat.completions.create(
model="uncensored",
messages=messages,
max_tokens=5000, # ~3,000 characters needs roughly 4,500 tokens under our assumption
temperature=0.9,
top_p=0.95,
)
return r.choices[0].message.content, r.usage
def summarize(chapter_text):
r = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "用 200 字以内概括下面这一章的剧情,保留人物关系的变化和未解的伏笔:\n" + chapter_text}],
max_tokens=400,
temperature=0.3,
)
return r.choices[0].message.content
Ролевые игры: личность, форма хода и последовательности остановки
Ролевая игра требует той же дисциплины в работе с листами и стилями, а также нескольких специфичных для чата настроек. Укажите персонажа в системном сообщении, определите, кто кем играет, установите диапазон длины ответа и укажите модели не описывать действия персонажа пользователя. Используйте stop, чтобы прервать вывод, если модель начнёт писать за пользователя, и используйте потоковую передачу, чтобы текст появлялся по мере его генерации.
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.chinesellmapi.com/v1", api_key=os.environ["API_KEY"])
PERSONA = (
"你扮演顾远舟,31岁的旧书商,说话随和,爱开玩笑,但在重要的事上很认真。"
"用户扮演沈清禾。所有角色均为成年人。保持第一人称,每次回复 80 到 200 字,"
"用(括号)写简短的动作描写,不要替用户的角色做决定。"
)
history = [{"role": "system", "content": PERSONA}]
def turn(user_text):
history.append({"role": "user", "content": user_text})
stream = client.chat.completions.create(
model="uncensored",
messages=history,
max_tokens=400,
temperature=1.0,
stop=["\n用户:"], # keep the model from writing the user's next line
stream=True,
)
reply = ""
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
piece = chunk.choices[0].delta.content
reply += piece
print(piece, end="", flush=True)
print()
history.append({"role": "assistant", "content": reply})
turn("(推开书店的门)这场雨下得真不是时候。")
История растёт на одно сообщение пользователя и одно сообщение ассистента за ход. Когда она приближается к вашему лимиту, суммируйте самую старую часть в одно сообщение и сохраняйте последние ходы без изменений. Температура около 0,9–1,0 даёт живой диалог для персонажей; снижайте её до 0,5, когда нужно, чтобы персонаж строго следовал сценарию.
Контроль стиля, выживающий в длинном сериале
Потеря стиля — это то, о чём читатели жалуются чаще всего: рассказчик постепенно становится более разговорчивым, диалоги становятся формальными, темп ускоряется. Боритесь с этим конкретикой. Вместо «пишите в элегантном стиле» опишите измеримые привычки: длину предложений, частоту использования идиом, сколько деталей погоды и предметов включать, заканчиваются ли главы на крючке или на тихом финале. Два-три коротких образца текста в целевом стиле, помещённые в блок стиля, стоят больше, чем страница прилагательных.
Разные жанры требуют разных настроек. Сериалу культивации или фэнтези помогает глоссарий выдуманных терминов, таких как миры, секты и техники, чтобы одно имя никогда не писалось двумя способами. Современная романтическая история опирается на ритм диалога и мелкие физические детали. Детективу нужна книга подсказок: список фактов, которые читатель видел, чтобы модель не противоречила им. Держите каждый из этих списков в системном промпте и обновляйте его по мере продвижения истории.
Наконец, держите температуру и top_p фиксированными в рамках сериала. Если вы меняете сэмплирование между главами, голос меняется. Повышайте температуру только для мозгового штурма планов, а не для самой прозы.
Математика стоимости с заявленными предположениями
Все цифры используют опубликованные тарифы: $0,25 за миллион входных токенов и $1,00 за миллион выходных токенов, и предположение 1,5 токена на китайский символ. Замените предположения числами из ваших собственных журналов usage.
| Сценарий | Предполагаемые входные токены | Предполагаемые выходные токены | Стоимость за вызов |
|---|---|---|---|
| Сериальная глава (3 000 символов на выходе) | 8 000 | 4 500 | $0.0020 + $0.0045 = $0.0065 |
| Ход ролевой игры, история на 20 000 токенов | 20 000 | 300 | $0.0050 + $0.0003 = $0.0053 |
| Ход ролевой игры, полная история на 60 000 токенов | 60 000 | 500 | $0.0150 + $0.0005 = $0.0155 |
В строке главы 8 000 входных токенов распределяются так: 1 200 токенов на карточку персонажа и блок стиля, 2 000 токенов на сводку, 4 500 токенов на предыдущую главу и 300 токенов на план. Сто таких глав обошлись бы примерно в $0,65. Сто ходов ролевой игры при размере истории в 20 000 токенов стоят примерно $0,53. Вывод: длина истории определяет стоимость чата, поэтому сокращение и суммирование быстро окупаются.
Пробный кредит $0,50, действительный в течение семи дней, покрывает примерно 76 глав при предположениях первой строки. Проверьте тарифы для актуальных ставок и посмотрите FAQ по пробному периоду для деталей аккаунта.
Эксплуатационные заметки для продакшена
Генерация глав — это долгий запрос, поэтому используйте большие таймауты или потоковую передачу с последующей сборкой текста. Обработайте 429 с короткой задержкой, так как каждый API-ключ позволяет 300 запросов в минуту, а 503 с upstream_busy обрабатывайте как событие для повторной попытки через несколько секунд. 402 означает, что предоплаченный баланс исчерпан или пробный баланс использован, что должно вас предупредить, а не заставить повторить попытку.
Сохраняйте каждую сгенерированную главу и ее сводку в свою базу данных перед генерацией следующей. Если вызов прерывается посреди ночного пакета, вы можете возобновить с последней сохраненной главы, и вы никогда не платите дважды за один и тот же текст. Храните версию промпта и данные об использовании рядом с каждой главой, чтобы стоимость главы была запросом, а не догадкой.
Для продуктов ролевых игр держите бюджет на сессию. Ограничьте количество ходов или общее количество токенов, которые может потребить одна сессия, и покажите пользователям ясное сообщение при достижении лимита. Поскольку промпты включают историю, очень длинная сессия стоит гораздо дороже за ход, чем новая, поэтому суммирование старых ходов важно не только для вписывания в окно. Промпты не используются для обучения, что вы можете указать в заметках о конфиденциальности вашего продукта наряду с вашей собственной политикой хранения.
Вопросы и ответы
Какой может быть длина главы в одном запросе?
Вывод ограничен 32 000 токенов на запрос и делит контекстное окно на 100 000 токенов с промптом. Глава на 3 000 символов помещается с запасом, поэтому установите max_tokens немного выше вашей оценки.
Как сохранять согласованность персонажей на протяжении сотен глав?
Держите карточку персонажа и блок стиля в системном промпте при каждом вызове, а сюжет передавайте через накопительное резюме и предыдущую главу.
Допускается ли взрослая проза?
Допустимая взрослая проза между взрослыми персонажами не отклоняется, сервис предназначен для пользователей старше 18 лет. Сексуальный контент с участием несовершеннолетних всегда блокируется кодом 403, включая прозу и ролевые игры.
Можно ли использовать потоковую передачу для ответов в ролевых играх?
Да. Установите stream в true для получения событий SSE и используйте последовательности остановки, чтобы модель не писала реплики пользователя.
Ваш ключ — в одной форме от вас
Создайте аккаунт, скопируйте ключ, измените базовый URL. Это вся настройка.