JA ▾

Chinese LLM APIフィクション

API キーを取得

更新日:

中国のウェブ小説(网文)とロールプレイアプリ:コンテキスト、キャラクター、コスト

シリアル化された中国のウェブ小説とキャラクターチャットは、最も負荷の高いテキスト処理の2つです:章ごとの数千文字、数ヶ月にわたって一貫性を保つ必要があるキャスト、そしてわずかなミスも見逃さない読者。このガイドでは、プロンプトの構成方法、100,000トークンのコンテキストウィンドウの管理方法、および記載された前提条件に基づくコストの見積もり方法を示します。

これらのワークロードの概要

ウェブ小説のシリアルは、2,000〜4,000文字の章で書かれ、毎日公開され、プロットは数百章にわたります。ロールプレイアプリは会話の親戚のようなものです:ペルソナ、シナリオ、長い履歴が必要です。両方とも、モデルAPIから同じ3つのものを必要とします:記憶するための十分なコンテキスト、長文を書くための十分な出力予算、そして逸脱しないスタイルです。

サービスは、OpenAI互換のチャットエンドポイントhttps://api.chinesellmapi.com/v1を提供しており、テキストモデルは1つ、idはuncensoredです。コンテキストウィンドウはプロンプトと補完で共有される100,000トークンで、max_tokensのデフォルトは2,048で最大32,000まで拡張可能、temperature、top_p、stopなどの標準的なサンプリングフィールドはそのまま渡されます。ストリーミングがサポートされており、チャットに適しています。基本的なセットアップとエンコーディングに関するノートはアプリクイックスタートにあります。

コンテンツルール(事前明示)

これは成人限定のサービスです。合法的な成人向け小説、成熟したテーマ、論争的な主題はそれ自体では拒否されず、サービスは18歳以上のユーザーを対象としています。未成年者を含む性的コンテンツは常にブロックされ、小説やロールプレイとして構成されていても403content_blockedエラーを返します。これを変更する設定はありません。

最初からそれに合わせて構築してください。キャラクターシートで、すべてのキャラクターが成人であり、明確な年齢であることを明記してください。ご自身の製品に年齢制限を追加してください。403エラーはそのリクエストに対する最終的な回答として扱い、中立なメッセージを表示し、プロンプトを言い換えて再試行しないでください。これらの手順は、プラットフォームのルールがどうであれ、優れた製品衛生管理です。

キャラクターシートとスタイルブロック

一貫性は、安定した事実を1か所にまとめ、すべての呼び出しでそれを繰り返すことで得られます。キャラクターシートは、名前、年齢、役割、話し方の癖、関係、そしてまだ明かしてはいけない秘密を含むハードな制約などの、コンパクトな記録です。別のスタイルブロックは、視点、ペース、会話の比率、章の長さ、そして結び方の習慣を固定します。これら両方をシステムメッセージに含め、すべてのリクエストの先頭に配置します。

CHARACTER_SHEET = """\
【人物卡】
姓名:沈清禾(女,28岁)
身份:江城古籍修复师,性格沉静,嘴硬心软
口头禅:“先别急,东西不会跑。”
说话方式:短句,少用感叹号,偶尔引用旧书里的句子
关系:与顾远舟(男,31岁,旧书商)是多年好友,彼此有未说出口的好感
禁忌:不提及她离开出版社的真正原因(第40章才揭晓)
"""

STYLE = """\
【文风】第三人称限知视角,贴近沈清禾;节奏舒缓,多写物件与天气的细节;
对话占比约四成;每章 2500 到 3000 字;结尾留一个小悬念。"""

これらを中国語で記述してください。お決まりのフレーズや文の長さなど、中国語の例で表現される話し方の癖は、それらを英語で説明するよりもはるかに確実に移行されます。各シートは数百トークン以内に収め、繰り返し登場するキャラクターにはそれぞれ1つずつ割り当ててください。10人のキャストでも、合計で数千トークン程度です。キャラクターの状況が変わった場合は、履歴に依存するのではなく、シート自体を更新してください。

シリアル化された章のための長文コンテキスト

誘惑は、すべての過去の章をプロンプトに貼り付けることです。まず計算してください。100,000トークンのウィンドウと、約4,500トークンの章がある場合、ウィンドウ全体には出力の余地を残さずに約14章しか収まらず、シリアルは数百章にわたって続きます。実用的なパターンは階層型メモリです:

  1. 常に存在するキャラクターシートとスタイルブロック。
  2. ローリングストーリーサマリー:章ごとに数百文字で、数章ごとに更新される単一の継続的な要約にマージ。
  3. 直前の章の全文:文章が継ぎ目で接続されるように。
  4. 現在書かれている章のアウトライン。

各章の後に、関係の変化や開かれたプロットスレッドを保持する短いサマリーをモデルに依頼し、要約に追加します。以下のコードは章を生成し、次のサマリーを生成します。また、実際のトークン数をログに記録できるように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("(推开书店的门)这场雨下得真不是时候。")

履歴は1つのユーザーメッセージと1つのアシスタントメッセージで1ターンごとに成長します。予算に近づいたら、最も古い部分を単一のメッセージに要約し、最新のターンはそのまま保持します。キャラクターに生き生きとした会話を与えるには温度を0.9〜1.0に、ペルソナを厳密に脚本通りに保つ必要がある場合は0.5に下げます。

長編シリアルでも持続するスタイル制御

スタイルのドリフトは、読者が最も不満を訴える失敗です。語り手が徐々に口数が増え、対話が形式的になり、ペースが速くなります。具体的な指示でこれに対抗してください。「エレガントな文体で書く」ではなく、測定可能な癖を記述します。文の長さ、慣用句の使用頻度、天気や物の詳細をどの程度含めるか、章の終わりをフックにするか静かな結末にするか。ターゲットの文体での短いサンプル段落を2〜3個、スタイルブロックに配置することは、1ページ分の形容詞よりも価値があります。

異なるジャンルには異なる調整が必要です。修仙やファンタジーのシリアルは、次元、宗派、技法などの発明された用語の用語集があると役立ち、同じ名前が2つの方法で綴られることがなくなります。現代のロマンスは会話のリズムと小さな身体的詳細に依存します。ミステリーには、読者が見た事実のリストであるヒントの台帳が必要で、モデルがそれらと矛盾しないようにします。これらのリストをすべてシステムプロンプトに保持し、ストーリーが進むにつれて更新してください。

最後に、シリーズ内では温度とtop_pを固定してください。章間でサンプリングを変更すると、書き手の声(スタイル)が変わります。プロンプトのブレストには温度を上げますが、文章そのものには上げないでください。

記載された前提条件に基づくコスト計算

すべての数値は、入力トークン100万あたり0.25ドル、出力トークン100万あたり1.00ドルの公開料率と、中国語1文字あたり1.5トークンという前提に基づいています。これらの前提を、ご自身の usage ログの数値に置き換えてください。

シナリオ想定される入力トークン想定される出力トークン1呼び出しあたりのコスト
シリアルの章(出力3,000文字)8,0004,500$0.0020 + $0.0045 = $0.0065
ロールプレイのターン、20,000トークンの履歴20,000300$0.0050 + $0.0003 = $0.0053
ロールプレイのターン、60,000トークンのフル履歴60,000500$0.0150 + $0.0005 = $0.0155

チャプター行では、8,000の入力トークンは、1,200トークンのキャラクターシートとスタイルブロック、2,000トークンの要約、4,500トークンの前章、300トークンのアウトラインに内訳されます。このようなチャプター100個で約0.65ドルかかります。20,000トークンの履歴サイズでのロールプレイターン100回で約0.53ドルかかります。重要な点は、履歴の長さがチャットコストを左右するため、トリミングと要約はすぐに元が取れるということです。

7日間有効な0.50ドルのトライアルクレジットは、最初の行の前提に基づくと、約76チャプターをカバーできます。現在の料率は pricing で確認し、アカウントの詳細は trial FAQ を参照してください。

本番環境のための運用ノート

チャプターの生成は長時間のリクエストとなるため、余裕のあるタイムアウトを使用するか、ストリーミングしてテキストを自分で組み立ててください。429エラーは、各キーが1分あたり300リクエストを許可するため、短いバックオフで処理し、503エラーは upstream_busy として数秒後に再試行するイベントとして扱ってください。402エラーは、前払いクレジットの残高が尽きたかトライアルが期限切れになったことを意味し、再試行するのではなく通知すべきです。

次の章を生成する前に、生成された章とその要約を独自のデータベースに保存してください。バッチ処理の途中で呼び出しが失敗した場合、最後に保存された章から再開でき、同じテキストに対して2回課金されることはありません。プロンプトのバージョンと使用量数値を各章の隣に保存し、章ごとのコストを推測ではなくクエリとして扱えるようにしてください。

ロールプレイ製品の場合、セッションごとの予算を保持してください。1つのセッションが消費できるターンの数またはトークンの合計数を制限し、制限に達したときにユーザーに明確なメッセージを表示してください。プロンプトには履歴が含まれるため、非常に長いセッションは新しいセッションよりもターンあたりのコストがはるかに高いため、ウィンドウに収めるだけでなく、古いターンを要約することが重要です。プロンプトはトレーニングに使用されないため、これは自社製品のプライバシーノートと自身のストレージポリシーの両方で明記できます。

質問と回答

1つのリクエストで章をどれほど長くできますか?

出力はリクエストあたり32,000トークンに制限され、プロンプトと合わせて100,000トークンのコンテキストウィンドウを共有します。3,000文字のチャプターは余裕を持って収まるため、max_tokens は推定値より少し高く設定してください。

何百章にもわたってキャラクターの一貫性を保つにはどうすればよいですか?

すべての呼び出しでシステムプロンプトにキャラクターシートとスタイルブロックを保持し、プロットはローリングサマリーと直前の章を継続して渡してください。

アダルトフィクションは許可されていますか?

成人キャラクター間の法的なアダルトフィクションは拒否されず、サービスは18歳以上のユーザー向けです。未成年者を含む性的コンテンツは、フィクションやロールプレイでも常に403でブロックされます。

ロールプレイの応答をストリーミングできますか?

はい。streamをtrueに設定してサーバー送信イベントを受け取り、stop sequencesを設定してモデルがユーザーのセリフを書き出さないようにしてください。

キーはフォーム 1 つで手に入ります

アカウントを作成し、キーをコピーし、base URLを変更します。これだけですべてのセットアップは完了です。

API キーを取得