繁中 ▾

Chinese LLM API小說

取得 API 金鑰

更新於

中文網路小說與角色扮演應用程式:上下文、角色與成本

序列化中文網路小說與角色扮演聊天是兩種最耗費資源的文字工作負載:每章數千個字元、角色必須在數月內保持設定一致,以及讀者會注意任何失誤。本指南將說明如何結構化提示詞、管理 100,000 token 的上下文視窗,以及根據既定假設計算成本。

這些工作負載的外觀

網路小說連載通常以每章 2,000 至 4,000 個字元的長度撰寫,且經常每日更新,劇情橫跨數百個章節。角色扮演應用程式則是其對話式親戚:包含角色設定、情境以及長期歷史記錄。兩者都需要模型 API 提供相同的三項要素:足夠的上下文以維持記憶、足夠的輸出預算以進行長篇寫作,以及不會偏離的風格。

該服務提供 OpenAI 相容的聊天端點 https://api.chinesellmapi.com/v1,含單一文字模型,id 為 uncensored。上下文視窗為 100,000 token,提示詞與補完內容共享;max_tokens 預設為 2,048,最高可達 32,000;標準採樣欄位如 temperature、top_p 與 stop 均會傳遞。支援串流輸出,適合聊天。基本設定與編碼說明位於 應用程式快速入門。

內容規則,事先聲明

此為成人專屬服務。合法的成人小說、成熟主題與爭議性主題不會因此被拒絕,服務對象為 18 歲以上使用者。涉及未成年人的性內容一律會遭到封鎖,並回傳 403 content_blocked 錯誤,無論是以小說或角色扮演形式呈現。無任何設定可變更此規則。

從一開始就為此進行設計。在角色設定中聲明每個角色均為成年人並給出明確年齡。在你的產品中加入年齡驗證。將 403 視為該請求的最終答案:顯示中性訊息,不要使用重新表述的提示詞進行重試。無論平台規則為何,這些步驟都是良好的產品衛生措施。

角色設定與風格區塊

一致性來自於將穩定事實集中在一處並在每次呼叫時重複。角色設定是一份簡短的記錄,包含姓名、年齡、角色、說話習慣、人際關係與硬性限制,包含角色尚未揭露的秘密。獨立的風格區塊固定視角、節奏、對話比例、章節長度與結尾習慣。兩者皆放入系統訊息,使其位於每個請求的開頭。

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

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

以中文撰寫這些內容。以中文範例表達的說話習慣(如口頭禪或句子長度)比英文描述更可靠地傳遞。每個設定保持在數百 token 以內,為每個常駐角色提供一個設定;十個角色的陣容僅需數千 token。當角色狀況改變時,請更新設定本身,而非依賴歷史記錄來帶入變更。

用於連載章節的長上下文

誘惑是將所有前序章節貼入提示詞。先進行計算。在 100,000 token 上下文視窗下,每章約 4,500 token,整個視窗僅能容納約十四章,且無剩餘空間用於輸出,而連載通常持續數百章。可行的模式是分層記憶:

  1. 角色設定與風格區塊,始終存在。
  2. 滾動式故事摘要:每章數百個字元,合併為一個持續更新的摘要,每幾章更新一次。
  3. 前一章的完整文字,讓行文在銜接處保持連貫。
  4. 正在撰寫章節的大綱。

每章結束後,請模型提供簡短摘要,保留關係變化與懸念,並將其附加至摘要中。以下程式碼會寫入一章並產生下一個摘要。它也會回傳 usage 以便你記錄實際 token 計數:

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 左右。

能貫穿長連載的風格控制

風格漂移是讀者抱怨最多的問題:敘述者逐漸變得健談,對話變得正式,節奏加快。用具體細節對抗。不要說「以優雅風格撰寫」,而是描述可衡量的習慣:句子長度、成語使用頻率、包含多少天氣與物體細節、章節是懸念結尾還是平靜結尾。兩三段目標語氣的範例段落放在風格區塊中,比一頁形容詞更有價值。

不同類型需要不同的調節。修仙或奇幻連載受益于術語詞典(如境界、宗派、技巧),確保同一名稱不會有兩種拼寫。現代浪漫依賴對話節奏與細微身體細節。懸疑小說需要線索帳簿:讀者已見事實的列表,以防模型與之矛盾。將這些列表保留在系統提示詞中,並隨故事推進進行更新。

最後,在連載期間保持 temperature 和 top_p 固定。如果你在章節之間改變採樣設定,語氣就會隨之改變。僅在腦力激盪大綱時提高 temperature,而非用於正文本身。

成本計算與既定假設

所有數值均採用已公布的費率:每百萬輸入 token 為 $0.25,每百萬輸出 token 為 $1.00,並假設每個中文字元為 1.5 個 token。請將假設值替換為你自己的 usage 日誌中的數值。

情境假設輸入 token假設輸出 token每次請求成本
連載章節(輸出 3,000 個字元)8,0004,500$0.0020 + $0.0045 = $0.0065
角色扮演回合,20,000 token 歷史20,000300$0.0050 + $0.0003 = $0.0053
角色扮演回合,完整 60,000 token 歷史60,000500$0.0150 + $0.0005 = $0.0155

在章節行中,8,000 輸入 token 分解為:1,200 token 的角色設定與風格區塊、2,000 token 的摘要、4,500 token 的前一章與 300 token 的大綱。一百章的成本約為 $0.65。一百個角色扮演回合(20,000 token 歷史)成本約為 $0.53。結論是歷史長度驅動聊天成本,因此修剪與摘要能迅速收回成本。

$0.50 試用額度有效期七天,在第一個行的假設下可涵蓋約 76 章。請查看 定價 以獲取當前費率,並查看 試用常見問題 以獲取帳戶詳情。

生產環境的運作注意事項

章節生成是長請求,因此請使用寬鬆的超時時間或自行串流並組裝文本。處理 429 錯誤時使用短延遲,因為每個金鑰允許每分鐘 300 次請求;將 503 視為 upstream_busy 事件,在幾秒後重試。402 表示預付餘額已用完或試用已過期,這應觸發警報而非重試。

在生成下一章之前,將每個生成的章節及其摘要保存到你的資料庫中。如果呼叫在夜間批次處理中途失敗,你可以從最後儲存的章節恢復,且不會為相同文本支付兩次費用。將提示詞版本與使用數據儲存在每章旁邊,以便每章成本成為查詢而非猜測。

對於角色扮演產品,請保持每會話預算。限制單一會話可消耗的回合數或總 token 數,並在達到上限時向使用者顯示明確訊息。由於提示詞包含歷史記錄,非常長的會話每回合成本遠高於全新會話,這就是為什麼總結舊回合不僅是為了適應上下文視窗。提示詞不用於訓練,你可以在產品的隱私聲明中聲明此點,並附上你自己的儲存政策。

問答

單一請求中章節可以有多長?

每次請求輸出上限為 32,000 token,並與提示詞共享 100,000 token 的上下文視窗。3,000 個字元的章節可以輕鬆容納,因此請將 max_tokens 設定為略高於你的估算值。

如何在數百個章節間保持角色一致性?

在每次請求的系統提示詞中保留角色設定表與風格區塊,並以滾動摘要加上前一章的內容來延續劇情。

允許成人小說嗎?

成人角色之間的合法成人小說不會被拒絕,且服務對象為 18 歲以上使用者。涉及未成年人的性內容一律會遭到封鎖(403 錯誤),無論是在小說還是角色扮演中。

我可以串流輸出角色扮演的回覆嗎?

是的。將 stream 設為 true 以接收伺服器發送的事件(SSE),並使用 stop sequences 以防止模型寫入使用者的行。

只差一張表單,即可取得金鑰

建立帳號、複製金鑰、更改基礎 URL。這就是完整的設定流程。

取得 API 金鑰