Skenario Berbasis Teks Roleplay Dengan API LLM
Skenario roleplay berbasis teks bekerja paling baik ketika model memainkan narator dengan aturan, dan kode Anda memiliki status. Artikel ini membahas mesin kecil dalam Python: prompt, streaming, memori, dan estimasi biaya untuk sesi panjang.

Poin utama
- Bagilah pekerjaan: model menulis cerita, kode Anda menyimpan fakta, inventaris, dan aturan.
- Alirkan balasan dan pastikan setiap streaming cukup pendek untuk membebaskan slot konkurensinya dengan cepat.
- Jendela 100.000 token menampung sesi yang sangat panjang, tetapi ringkasan menjaga biaya dan penyimpangan konteks tetap rendah.
- Sesi 200 giliran dengan 6.000 token input dan 400 token output per giliran memiliki biaya sekitar $0.22.
Mulailah dengan narator, bukan alur cerita
Orang yang membuat skenario roleplay berbasis teks sering mulai dengan menulis alur cerita. Itu terbalik. Sebuah skenario adalah siklus antara pemain dan narator, dan narator membutuhkan deskripsi pekerjaan sebelum membutuhkan cerita. Model harus tahu siapa yang berbicara, apa yang dapat diputuskannya untuk pemain, seberapa panjang balasan harusnya, dan apa yang tidak boleh dilakukannya. Sisanya bisa diimprovisasi.
Prompt sistem yang baik untuk mesin skenario memiliki empat bagian. Pertama, peran: master permainan, pewawancara, komputer kapal, atau karakter dalam drama. Kedua, aturan dunia dalam beberapa kalimat sederhana: nada, latar, apa yang ada dan apa yang tidak. Ketiga, aturan format, karena kode Anda mungkin memprosesnya: misalnya, "akhiri setiap balasan dengan satu baris yang dimulai dengan OPTIONS:". Keempat, batas. API teks ini disesuaikan untuk menjawab tanpa penolakan konten untuk penggunaan legal dewasa, sehingga cocok untuk fiksi gelap, penjahat yang benar-benar mengancam, dan alur cerita abu-abu. Masih ada satu batas tegas: tidak ada konten seksual yang melibatkan anak di bawah umur. Masukkan aturan itu dalam syarat dan ketentuan Anda sendiri, dan terapkan gerbang usia di aplikasi Anda jika skenario Anda ditujukan untuk dewasa.
Jaga prompt agar panjangnya sekitar 600 kata. Daftar aturan yang panjang sering kali hanya diikuti sebagian. Jika Anda membutuhkan banyak aturan, urutkan dan buang sepertiga bagian bawah.
Loop kerja dengan streaming
Streaming lebih penting dalam roleplay daripada dalam sebagian besar penggunaan. Pemain yang membaca cerita ingin kata-kata muncul saat model menulis, dan balasan 300 token terasa lebih lambat jika muncul sekaligus. API melakukan streaming melalui server-sent events dengan stream: true, dan SDK OpenAI menangani parsingnya. Endpoint ini kompatibel dengan OpenAI, ID modelnya adalah uncensored, dan Base URL untuk situs ini adalah https://api.sdxlapi.com/v1.
from openai import OpenAI
client = OpenAI(base_url="https://api.sdxlapi.com/v1", api_key="YOUR_KEY")
SYSTEM = """You are the narrator of a noir mystery set in a rainy harbour city.
Write in second person, present tense, 120 to 200 words per reply.
Never decide what the player says or does. Invent details freely, but stay
consistent with the STATE block you are given.
End every reply with one line: OPTIONS: a | b | c"""
state = {"place": "Pier 9 office", "time": "23:40", "inventory": ["brass key"], "facts": []}
history = []
def turn(player_text: str) -> str:
history.append({"role": "user", "content": player_text})
msgs = [{"role": "system", "content": SYSTEM + "\nSTATE: " + str(state)}] + history[-20:]
stream = client.chat.completions.create(
model="uncensored", messages=msgs, stream=True,
temperature=0.9, top_p=0.95, max_tokens=500,
presence_penalty=0.3,
)
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)
history.append({"role": "assistant", "content": reply})
return reply
turn("I check the desk drawer.")Pengaturan disesuaikan untuk fiksi. Suhu sekitar 0,8 hingga 1,0 memberikan prosa yang bervariasi, dan top_p sekitar 0,95 memangkas pilihan kata paling aneh. Penalti kehadiran kecil mencegah narator kembali ke gambar yang sama. Atur max_tokens untuk membatasi panjang balasan; ini opsional, tetapi tanpanya, narator yang banyak bicara dapat menulis jauh lebih banyak dari yang Anda inginkan. Untuk adegan yang ingin Anda putar ulang secara tepat selama pengujian, berikan seed dan biarkan parameter lainnya tetap.
Biarkan kode memiliki fakta
Kegagalan paling umum dalam roleplay panjang adalah drift. Kuncinya ada di saku pemain pada giliran 5 dan di atas meja pada giliran 40. Pemilik penginapan dipanggil Mara, lalu Marta. Model yang membaca 30.000 token riwayat sering kali akan memahami ini dengan benar, tetapi "sering" bukanlah desain. Simpan fakta dalam struktur kecil yang diperbarui oleh program Anda, dan masukkan struktur tersebut ke dalam setiap permintaan, seperti yang dilakukan baris STATE di atas.
Bagaimana Anda memperbarui status? Minta model untuk melaporkan perubahan setelah setiap giliran, dalam panggilan kedua, murah yang menggunakan mode JSON. Panggilan pertama menulis cerita untuk pemain. Panggilan kedua membaca bagian baru dan hanya mengembalikan apa yang berubah.
import json
def extract_changes(passage: str) -> dict:
r = client.chat.completions.create(
model="uncensored",
response_format={"type": "json_object"},
temperature=0,
max_tokens=250,
messages=[
{"role": "system", "content":
'Read the passage. Return JSON: {"place": str|null, "inventory_add": [str], '
'"inventory_remove": [str], "new_facts": [str]}. Only report what the passage states.'},
{"role": "user", "content": passage},
],
)
return json.loads(r.choices[0].message.content)
def apply(ch: dict):
if ch.get("place"):
state["place"] = ch["place"]
for item in ch.get("inventory_add", []):
if item not in state["inventory"]:
state["inventory"].append(item)
state["inventory"] = [i for i in state["inventory"] if i not in ch.get("inventory_remove", [])]
state["facts"] = (state["facts"] + ch.get("new_facts", []))[-30:]Batasi daftar fakta, seperti yang dilakukan irisan, atau blok status akan tumbuh hingga seberat riwayat yang seharusnya digantikannya. Jika balasan JSON gagal diproses, lewati pembaruan untuk giliran itu dan lanjutkan; satu fakta yang terlewat lebih murah daripada gangguan.
Dadu, kesehatan, dan timer lebih baik ditangani dalam kode biasa. Ketika pemain mencoba sesuatu yang berisiko, lempar di Python dan beri tahu narator hasilnya: "Percobaan pemain gagal." Model kemudian menulis konsekuensinya. Ini menjaga model dari secara diam-diam membiarkan pemain menang setiap kali, yang cenderung dilakukan model bahasa.
Memori untuk sesi yang berjalan selama berjam-jam
Jendela konteks adalah 100.000 token, menghitung prompt dan penyelesaian bersama. Balasan khas 250 token ditambah pesan pemain 30 token adalah sekitar 280 token per giliran, sehingga sejarah mentah saja dapat menampung ratusan giliran. Anda dapat mengirimkannya semua. Banyak pembangun masih tidak melakukannya, karena dua alasan: biaya tumbuh dengan setiap giliran, karena seluruh sejarah ditagih sebagai input setiap kali, dan detail lama dapat mengalihkan perhatian model.
Tata letak yang masuk akal menjaga tiga lapisan:
- Tetap: prompt sistem dan blok status. Selalu dikirim.
- Ringkasan: paragraf berjalan atau dua tentang apa yang telah terjadi, ditulis ulang setiap 10 hingga 15 giliran oleh panggilan singkat.
- Giliran terbaru: 10 hingga 20 pesan terakhir secara persis, agar prosa tetap berirama.
Saat jendela giliran terbaru penuh, lipat sepuluh giliran tertua ke dalam ringkasan dan hapus. Panggilan ringkasan dapat menggunakan suhu rendah dan batas 300 token. Pemain jarang memperhatikan kompresi selama nama, janji, dan ancaman yang belum terselesaikan masuk ke dalam ringkasan. Sebutkan secara eksplisit dalam prompt peringkasan: "jaga nama, utang, luka, pertanyaan terbuka".
Jika Anda ingin karakter mempertahankan suara yang stabil, berikan kartu gaya singkat di lapisan terpasang: tiga contoh baris bicaranya dan dua hal yang tidak pernah diucapkannya. Contoh singkat membentuk nada lebih baik daripada kata sifat.
Biaya sesi
Harga adalah $0,15 per 1M token input dan $0,50 per 1M token output, dengan saldo prabayar dan tanpa langganan. Jalankan sesi panjang. Katakan 200 giliran, dengan lapisan terpasang, ringkasan, dan giliran terbaru yang jumlahnya rata-rata 6.000 token input per permintaan, dan 400 token output per balasan (balasan cerita plus bagian kecil untuk panggilan status dan ringkasan).
Input: 200 x 6.000 = 1.200.000 token, yang berarti 1,2 x $0,15 = $0,18. Output: 200 x 400 = 80.000 token, yang berarti 0,08 x $0,50 = $0,04. Sesi ini memakan biaya $0,22.
Bandingkan versi malas yang mengirim ulang seluruh riwayat mentah. Pada giliran 200, riwayat adalah sekitar 56.000 token, dan selama sesi rata-rata input adalah sekitar 28.000 token per permintaan. Itu adalah 200 x 28.000 = 5.600.000 token input, atau 5,6 x $0,15 = $0,84, ditambah $0,04 yang sama untuk output, yang membuat $0,88. Masih terjangkau, tetapi empat kali tagihan tanpa peningkatan kualitas. Untuk aplikasi dengan banyak pemain, kesenjangan itu menentukan margin Anda.
Permintaan yang gagal atau ditolak tidak dikenakan biaya, dan saldo tidak pernah kedaluwarsa, sehingga saldo yang tidak terpakai hanya menunggu. Top up dimulai dari $20 hingga $500 dalam kelipatan dolar penuh, dengan bonus 5% dari $50, 10% dari $100, dan 15% dari $200. Lihat halaman harga untuk daftar lengkap opsi.
Menjalankan banyak pemain sekaligus
Kunci penuh mengizinkan 8 permintaan paralel dan 300 permintaan per menit. Permintaan streaming memegang slotnya hingga streaming berakhir, sehingga dengan 8 slot dan balasan yang memakan waktu sekitar sepuluh detik, Anda dapat melayani sekitar 48 aliran balasan per menit, dengan asumsi tidak ada yang lain berjalan. Itu adalah aturan kasar, bukan angka terukur, karena kecepatan bervariasi tergantung beban dan panjang balasan. Tujuannya adalah untuk merencanakannya: jika permainan Anda memiliki lebih banyak pemain simultan daripada slot, antrikan permintaan di server Anda dan tampilkan status "narrator sedang berpikir" singkat sebagai gantinya daripada menembakkan semuanya sekaligus.
Ketika Anda melebihi batas, API mengembalikan HTTP 429. Kode adalah rate_limited untuk permintaan per menit dan concurrency untuk terlalu banyak sekaligus. Beban berlebih sementara juga memberikan 429, dengan header Retry-After: 5. Retry sederhana yang menunggu lima detik itu cukup untuk permainan kasual. Baca juga header respons: X-RateLimit-Limit-Requests dan X-RateLimit-Limit-Concurrency menunjukkan batas Anda, dan X-Balance-USD menunjukkan sisa yang tersisa, yang dapat Anda tampilkan di layar admin.
Jangan jalankan panggilan ekstraksi status secara paralel dengan giliran pemain berikutnya. Tunggu, atau narator akan menulis berdasarkan fakta usang. Kompromi yang baik adalah memulai ekstraksi segera setelah streaming berakhir dan biarkan pemain membaca saat itu berjalan.
Menghubungkan adegan ke pipeline gambar Anda
Situs ini dibangun untuk orang yang menggunakan model teks di sekitar alur kerja Stable Diffusion, dan skenario cocok dengan itu. API itu sendiri hanya teks: tidak menghasilkan gambar, audio, atau video. Namun, narator dapat menulis deskripsi adegan yang pipa Anda ubah menjadi prompt gambar. Tambahkan satu panggilan JSON lagi setelah perubahan adegan utama, meminta deskripsi visual singkat dari pengaturan dengan pencahayaan, suasana, dan sudut kamera, lalu teruskan string itu ke alat gambar mana pun yang Anda jalankan. halaman dokumentasi menunjukkan bentuk permintaan untuk panggilan penulisan prompt, dan artikel tentang generator prompt SD membahas lebih dalam di sisi itu.
Untuk mencoba mesin, buat akun dan klaim uji coba. Pengguna baru dapat mendapatkan $0,50 kredit uji coba dengan satu klik di halaman kunci API, berlaku selama 7 hari tanpa perlu kartu. Berdasarkan angka di atas, itu cukup untuk beberapa sesi penuh. Kunci uji coba dibatasi menjadi 2 permintaan paralel dan 60 per menit, yang cocok untuk pengujian mandiri.
Jaga fiksi dalam fiksi. Skenario bertema dewasa adalah penggunaan yang sah ketika semua orang yang terlibat adalah orang dewasa; satu aturan yang tidak pernah berubah adalah tidak ada konten seksual yang melibatkan anak di bawah umur. Prompt yang dikirim ke API tidak digunakan untuk pelatihan.
Panduan lainnya
Tanya jawab
Dapatkah model memainkan karakter atau genre apa pun?
Ini adalah model teks umum yang disesuaikan agar tidak menolak permintaan dewasa yang sah, sehingga horor, kejahatan, drama, dan komedi semuanya baik-baik saja. Satu batas tegas adalah konten seksual yang melibatkan anak di bawah umur.
Seberapa lama sesi dapat berlangsung sebelum jendela konteks penuh?
Jendela konteksnya adalah 100.000 token untuk prompt plus completion. Dengan lapisan ringkasan, Anda dapat menjalankan jauh melampaui batas itu dalam praktiknya, karena putaran lama telah dikompresi.
Apakah saya harus melakukan streaming pada balasan?
Ya, untuk apa pun yang dibaca langsung oleh orang. Streaming memberikan Anda penggunaan di akhir, dan stream menempati salah satu slot konkurensi Anda hingga selesai.
Apakah ada cara untuk membuat adegan diulang persis?
Berikan seed yang sama dengan pesan dan pengaturan yang identik. Ini adalah alat pengujian dan tidak menjamin output yang identik byte demi byte.
Kunci Anda hanya selangkah lagi dari satu formulir
Buat akun, salin kunci, ubah URL dasar. Itu saja seluruh proses pengaturannya.