วิธีสร้างแอป character AI: สถาปัตยกรรม โค้ด และคำนวณต้นทุน
Updated 2026-07-15
แอป character AI ประกอบด้วยสี่ส่วนที่เชื่อมกับ chat endpoint แบบ OpenAI-compatible: persona system prompt, ชั้น memory, moderation gate และ model router คุณ ship prototype ที่ใช้งานได้ในโค้ด Python ต่ำกว่า 200 บรรทัด และรันได้ในราคาต่ำกว่าหนึ่งดอลลาร์ต่อผู้ใช้งานต่อเดือนด้วยการเลือกโมเดลที่เหมาะสม
คำตอบด่วน: สถาปัตยกรรมสี่ส่วน
คุณไม่ต้องเทรนหรือ fine-tune โมเดลใดเลย ทุกแอป companion จริงจังในตลาดวันนี้ รวมถึงตัวที่ให้บริการผู้ใช้เป็นล้านคน เป็นชั้น orchestration บางๆ ทับ hosted LLM API ตัวละครอยู่ใน prompt และฐานข้อมูล ไม่ได้อยู่ใน weight ส่วนที่เหลือของคู่มือนี้สร้างแต่ละส่วนด้วยโค้ดใช้งานได้จริงบน endpoint แบบ OpenAI-compatible มาตรฐาน แล้วเดินคำนวณ token เพื่อให้คุณรู้ว่าผู้ใช้งานต่อเดือนหนึ่งคนมีต้นทุนจริงเท่าไหร่ก่อน launch
- Persona prompt: system prompt แบบมีโครงสร้าง (500 ถึง 1,000 token) ที่นิยามว่าตัวละครคือใครและพูดยังไง
- Memory: window แบบหมุนของรอบล่าสุดบวกสรุปที่รีเฟรชเป็นระยะ เพื่อให้บทสนทนารอดพ้น context limit
- Moderation: age gate, input classifier และนโยบายเนื้อหาที่ตรงกับโมเดลที่คุณ route ไป
- Routing: ฟังก์ชันเล็กๆ ที่เลือกโมเดลถูกสำหรับแชทเบาๆ และโมเดลแข็งแกร่งกว่าสำหรับฉากยาว
ส่วนที่ 1: persona prompt
persona prompt คือตัวผลิตภัณฑ์ มันคือ system message ที่ส่งไปพร้อมทุก request และปกติมีห้าส่วน: identity (ชื่อ, อายุ, ประวัติ), personality traits, speech style พร้อมตัวอย่างสองสามบรรทัด, กฎพฤติกรรมที่ตายตัว (ห้ามหลุดคาแรกเตอร์, จำกัดความยาวคำตอบ) และ scenario ปัจจุบัน รักษาให้อยู่ระหว่าง 500 ถึง 1,000 token persona ที่สั้นเกินไปจะหลุด ส่วนที่ยาวเกินไปมากจะเผางบ input ทุกข้อความและแทบไม่ช่วยให้ยึดตามคาแรกเตอร์ดีขึ้น เก็บ persona เป็นแถวในฐานข้อมูลของคุณเพื่อให้ผู้ใช้สร้างและแก้ไขตัวละครได้ ซึ่งคือ core loop ของผลิตภัณฑ์สไตล์ Character.AI นี่คือ request แบบเต็ม รูปแบบเดียวกันใช้ได้กับ backend แบบ OpenAI-compatible ใดๆ ตัวอย่างนี้ใช้ endpoint แบบ multi-model gateway เพื่อให้คุณสลับโมเดลได้ด้วยการเปลี่ยน string ตัวเดียว:
curl https://api.apisrouter.com/v1/chat/completions \
-H "Authorization: Bearer $KEAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash",
"messages": [
{"role": "system", "content": "You are Mira, a sarcastic starship engineer in her 30s. Personality: dry wit, fiercely loyal, hates small talk. Speech style: short technical sentences, occasional teasing. Example: \"The coupling is fried. Again. Did you touch it?\" Rules: never break character, never mention being an AI, keep replies under 120 words."},
{"role": "user", "content": "Mira, the reactor is making that noise again."}
],
"temperature": 0.9,
"max_tokens": 300,
"stream": true
}'ส่วนที่ 2: memory ที่รอดพ้นบทสนทนายาว
เซสชันแอป companion ยาวมาก memory stack สามชั้นรักษา context ให้สอดคล้องกันโดยไม่ต้องส่งประวัติทั้งหมดทุกครั้ง ชั้นที่ 1 คือ rolling window: 10 ถึง 14 รอบล่าสุดแบบดิบ ส่งตามจริง ชั้นที่ 2 คือ running summary: ทุกๆ ราว 20 รอบ โมเดลราคาถูกจะบีบอัดข้อความเก่าเป็นย่อหน้าที่ติดตามชื่อ, สถานะความสัมพันธ์ และเส้นเรื่องที่ยังไม่จบ ชั้นที่ 3 คือ pinned facts: รายละเอียดผู้ใช้ที่คงทน (ชื่อ, ความชอบ, เหตุการณ์ในอดีตที่ตัวละครควรจำ) ที่ดึงออกมาเก็บในฐานข้อมูลและฉีดเป็น system message สั้นๆ นี่คือการ implement ทั้งหมดใน Python ด้วย OpenAI SDK ทางการ:
| ช่อง context | ขนาดทั่วไป | ความถี่ในการรีเฟรช |
|---|---|---|
| Persona system prompt | 500 ถึง 1,000 token | คงที่ต่อตัวละคร |
| Pinned user facts | 100 ถึง 200 token | เมื่อมีเหตุการณ์ extraction |
| Running summary | 300 ถึง 500 token | ทุกๆ ราว 20 รอบ |
| Rolling window (12 รอบ) | ~1,800 ถึง 2,200 token | ทุกข้อความ |
| ข้อความใหม่ของผู้ใช้ | ~100 token | ทุกข้อความ |
from openai import OpenAI
client = OpenAI(
api_key="sk-...",
base_url="https://api.apisrouter.com/v1",
)
def build_context(persona, summary, pinned_facts, recent_turns, user_msg):
facts = "\n".join(f"- {f}" for f in pinned_facts)
return [
{"role": "system", "content": persona},
*([{"role": "system", "content": f"Facts to remember:\n{facts}"}]
if pinned_facts else []),
*([{"role": "system", "content": f"Story so far: {summary}"}]
if summary else []),
*recent_turns[-12:],
{"role": "user", "content": user_msg},
]
def refresh_summary(old_turns, prev_summary):
prompt = (
"Update this running summary of a roleplay chat. Keep names, "
"relationship state, and open plot threads. Max 150 words.\n\n"
f"Current summary: {prev_summary}\n\nNew messages: {old_turns}"
)
resp = client.chat.completions.create(
model="deepseek-v4-flash",
messages=[{"role": "user", "content": prompt}],
max_tokens=400,
)
return resp.choices[0].message.contentส่วนที่ 3: moderation และนโยบายเนื้อหา
Moderation ในแอป companion มีหน้าที่แยกกันสามอย่าง และการปนกันคือความผิดพลาดตอน launch ที่พบบ่อยที่สุด อย่างแรก gate กลุ่มผู้ใช้ของคุณ ถ้าแอปคุณอนุญาตธีมนิยายผู้ใหญ่ ให้ใส่ไว้หลัง age gate ของผู้ใหญ่และมี all-ages default แยกไว้ต่างหาก ทั้ง App Store และ Play Store ตรวจสอบเรื่องนี้ และผู้ให้บริการชำระเงินก็สนใจด้วยเช่นกัน อย่างที่สอง คัดกรอง input รัน classifier ราคาถูกกับข้อความผู้ใช้ก่อนถึงโมเดลตัวละคร บล็อกหมวดที่ไม่มีผู้ให้บริการรายใดอนุญาต: เนื้อหาเกี่ยวกับเด็ก, อันตรายในโลกจริงที่น่าเชื่อถือ และคำสั่งที่ผิดกฎหมาย การเรียก deepseek-v4-flash หนึ่งครั้งด้วย rubric แบบใช่/ไม่ใช่ มีต้นทุนเสี้ยวเซนต์และเพิ่ม latency ต่ำกว่าหนึ่งวินาที อย่างที่สาม จับคู่นโยบายเนื้อหากับโมเดล ผู้ให้บริการมีความเห็นต่างกันเรื่องนิยาย: นโยบายที่ xAI เผยแพร่อนุญาตธีมนิยายผู้ใหญ่อย่างชัดเจน DeepSeek และโมเดลอื่นที่มาจาก open-weight เป็นตัวโปรดของคอมมูนิตี้สำหรับ roleplay เพราะนโยบาย hosted ของมันยืดหยุ่นสำหรับนิยาย ในขณะที่นโยบายของ Anthropic ห้ามเนื้อหาโจ่งแจ้ง ทำให้ Claude เหมาะสมเฉพาะงานเขียนเชิงสร้างสรรค์แบบ all-ages เท่านั้น การเข้าใจนโยบายเหล่านี้ก่อน route traffic ช่วยคุณพ้นจากพายุการปฏิเสธในโปรดักชัน ไม่ว่าคุณจะสร้างอะไร มันต้องเคารพข้อกำหนดการใช้งานของทุกผู้ให้บริการที่คุณเรียก
ส่วนที่ 4: model routing และตารางเลือกโมเดล
ข้อความส่วนใหญ่ในแอป companion เป็นรอบเบาๆ ทั่วไปที่โมเดลราคาประหยัดจัดการได้สบาย ส่วนน้อยเป็นฉากอารมณ์ยาวหรือฉากสร้างสรรค์ที่คุณภาพ prose คือตัวผลิตภัณฑ์ การ route ตามความลึกของฉากลดต้นทุนได้มากโดยผู้ใช้ไม่รู้สึกถึงความต่าง:
| โมเดล | Model ID | ราคาต่อ 1M token (in/out) | ความเหมาะสมกับแอป companion |
|---|---|---|---|
| DeepSeek V4 Flash | deepseek-v4-flash | $0.126 / $0.252 | โมเดลแชท default ตัวโปรดของคอมมูนิตี้สำหรับ roleplay คุ้มค่าที่สุดใน catalog |
| DeepSeek V4 Pro | deepseek-v4-pro | $0.3915 / $0.783 | ฉากที่ยาวกว่า ทำตามคำสั่งดีกว่า ยังคงถูก |
| GLM-5 | glm-5 | $0.514 / $2.314 | ตัวเลือกคุ้มค่าที่มีงานเขียนเชิงสร้างสรรค์แข็งแกร่ง |
| Kimi K2.6 | kimi-k2.6 | ดูที่ /pricing | ตัวเลือกคุ้มค่าสำหรับเซสชัน long-context MiMo เป็นตัวเลือกงบประหยัดคล้ายกัน |
| grok-4.5 | grok-4.5 | $1.60 / $4.80 | ธีมนิยายผู้ใหญ่สำหรับผู้ใช้ผู้ใหญ่ตามนโยบายที่ xAI เผยแพร่ context window 500K |
| Claude Sonnet 4.6 | claude-sonnet-4-6 | $2.40 / $12.00 | คุณภาพ prose สูงสุด งานเขียนเชิงสร้างสรรค์แบบ all-ages เท่านั้น; Anthropic ห้ามเนื้อหาโจ่งแจ้ง |
| Gemini 3.5 Flash | gemini-3.5-flash | $1.20 / $7.20 | ตอบเร็ว เหมาะกับฟีเจอร์ที่รู้จำภาพ เช่น avatar reaction |
ROUTES = {
"casual": "deepseek-v4-flash",
"scene": "deepseek-v4-pro",
"prose": "claude-sonnet-4-6", # all-ages creative writing only
}
def pick_model(user_msg: str, turns_in_scene: int) -> str:
if turns_in_scene > 6 or len(user_msg) > 400:
return ROUTES["scene"]
return ROUTES["casual"]ผู้ใช้งานต่อเดือนหนึ่งคนมีต้นทุนจริงเท่าไหร่
คำนวณ token ก่อน launch ดีกว่าเจอบิลเซอร์ไพรส์ทีหลัง ใช้งบ context จากตาราง memory: ราว 3,300 input token และ 250 output token ต่อข้อความ ผู้ใช้แอป companion หนักมาก ตัวเลขที่คอมมูนิตี้รายงานระบุว่าผู้ใช้ที่ engaged ส่งข้อความหลายสิบครั้งต่อวัน ดังนั้นสมมติราว 40 ข้อความต่อวันตลอด 20 วันที่ active หรือราว 800 ข้อความต่อ MAU ต่อเดือน นั่นให้ 2.64M input token และ 0.2M output token ต่อ MAU ต่อเดือน คูณด้วยอัตรา catalog:
| โมเดล | ต้นทุน input / MAU | ต้นทุน output / MAU | รวม / MAU / เดือน |
|---|---|---|---|
| deepseek-v4-flash | $0.33 | $0.05 | $0.38 |
| deepseek-v4-pro | $1.03 | $0.16 | $1.19 |
| glm-5 | $1.36 | $0.46 | $1.82 |
| gemini-3.5-flash | $3.17 | $1.44 | $4.61 |
| grok-4.5 | $4.22 | $0.96 | $5.18 |
| claude-sonnet-4-6 | $6.34 | $2.40 | $8.74 |
| gpt-5.5 | $10.56 | $4.80 | $15.36 |
endpoint เดียวสำหรับทุกโมเดลในตาราง
การสมัครบัญชี provider ห้าเจ้าเพื่อรัน router เดียวคือภาระจริง: ห้า key, ห้า billing dashboard, ห้าชุด rate limit multi-model gateway ยุบสิ่งนั้นลง APIsRouter เปิดทุกโมเดลด้านบนผ่าน base URL แบบ OpenAI-compatible ตัวเดียวคือ https://api.apisrouter.com/v1 ดังนั้น router snippet ทำงานได้เลยแค่เปลี่ยน model string billing เป็นแบบจ่ายตามการใช้งานจริงไม่มีค่าสมาชิก โมเดล global รันต่ำกว่าราคาทางการ 20% โดยโมเดลจีนต่ำกว่าราคาทางการ และการเช็คเอาต์แบบไม่ต้องสมัครที่ /topup ส่ง key ทางอีเมลหลังชำระเงิน พร้อมโบนัสเติมเงินครั้งแรกอีก +100% GET /v1/models ด้วย key ของคุณคืนรายชื่อโมเดลสด ซึ่งมีประโยชน์สำหรับเติม model picker ใน admin UI ของคุณเองด้วย
เทคนิคใน production ที่ประหยัดเงินและความปวดหัวจริง
- Stream ทุกอย่าง Time-to-first-token คือตัวชี้วัดที่ผู้ใช้รู้สึกได้ คำตอบแบบ stream ที่ 2 วินาทีรู้สึกเร็วกว่าคำตอบเต็มที่ 4 วินาที
- รักษา prefix ที่คงที่ให้คงที่จริงๆ persona และ pinned facts ควรเหมือนกันทุกไบต์ในทุก request เพื่อให้ backend ที่รองรับ prefix caching ใช้ประโยชน์ได้
- จำกัด max_tokens ต่อ route รอบเบาๆ แทบไม่ต้องการ output เกิน 300 token โมเดลที่พูดยืดยาวไม่มีลิมิตเพิ่มบิล output เป็นสองเท่า
- log ต้นทุนต่อผู้ใช้ ไม่ใช่แค่ต่อ request ผู้ใช้หนักส่วนน้อยจะครองงบส่วนใหญ่ คุณต้องเห็นพวกเขาเพื่อออกแบบ tier การใช้งานที่เป็นธรรม
- สร้าง fallback เข้าไปใน router ถ้าโมเดลหลัก timeout หรือปฏิเสธ ให้ retry หนึ่งครั้งกับโมเดลพี่น้องก่อนแสดง error
- ตัด rolling window ตามจำนวน token ไม่ใช่ตามจำนวนรอบ เพื่อไม่ให้การวางข้อความยาวครั้งเดียวเผางบทั้งหมด
- จัดการการปฏิเสธในคาแรกเตอร์ map การปฏิเสธเป็นการเบี่ยงในเรื่องอย่างนุ่มนวลแทนที่จะโชว์ข้อความ API ดิบๆ
- อย่าเก็บแชทดิบนานเกินจำเป็น และระบุไว้ในนโยบายความเป็นส่วนตัวของคุณ log แชท companion อ่อนไหวโดยธรรมชาติ
คำถามที่พบบ่อย
สร้างแอป character AI มีต้นทุนเท่าไหร่?
ต้นทุนพัฒนาส่วนใหญ่คือเวลาของคุณ: prototype ที่ใช้งานได้เป็นงานหนึ่งสุดสัปดาห์เพราะไม่มีการเทรนโมเดลเข้ามาเกี่ยวข้อง ต้นทุนรันคือตัวเลขจริง และมันปรับตามการใช้งาน บนโมเดลราคาประหยัดอย่าง deepseek-v4-flash ผู้ใช้งานต่อเดือนหนักๆ หนึ่งคนมีต้นทุนราว $0.38 ใน token บนโมเดลพรีเมียมอย่าง gpt-5.5 ผู้ใช้คนเดียวกันมีต้นทุนราว $15 การเลือกโมเดล ไม่ใช่โครงสร้างพื้นฐาน คือตัวตัดสินกำไรของคุณ
โมเดล AI ตัวไหนดีที่สุดสำหรับแอป character AI?
ตระกูล DeepSeek V4 เป็นตัวโปรดของคอมมูนิตี้สำหรับ roleplay และคุ้มค่าที่สุด: Flash สำหรับแชทเบาๆ Pro สำหรับฉากยาวกว่า GLM-5, Kimi K2.6 และ MiMo เป็นตัวเลือกคุ้มค่าที่ดี Grok เหมาะกับแอปที่ให้บริการธีมนิยายผู้ใหญ่แก่ผู้ใหญ่ ตามนโยบายที่ xAI เผยแพร่ Claude Sonnet 4.6 เขียน prose ดีที่สุดแต่เหมาะกับงานเขียนเชิงสร้างสรรค์แบบ all-ages เท่านั้น เพราะ Anthropic ห้ามเนื้อหาโจ่งแจ้ง
แอป character AI จำบทสนทนาเก่าได้อย่างไร?
ผ่านการทำ prompt engineering ไม่ใช่ memory ของโมเดล แอปส่ง rolling window ของข้อความล่าสุด สรุปที่บีบอัดเป็นระยะของข้อความเก่า และรายการ pinned facts สั้นๆ ที่ดึงไว้ในฐานข้อมูล ตัวโมเดลเองไม่มีสถานะ ทุก request มีทุกอย่างที่ตัวละคร "จำได้" อยู่ในนั้น
ต้องเทรนโมเดลของตัวเองไหมเพื่อสร้างแอป AI companion?
ไม่ต้อง fine-tuning แพง ทำซ้ำช้า และไม่จำเป็นสำหรับความสม่ำเสมอของคาแรกเตอร์ persona prompt ที่มีโครงสร้างดี 500 ถึง 1,000 token บวกชั้น memory ให้ความยึดคาแรกเตอร์ที่ผู้ใช้แยกไม่ออกจากโมเดลที่เทรนเอง และให้คุณสลับโมเดลเบื้องหลังได้อิสระเมื่อมีตัวที่ดีกว่าออกมา
จัดการเนื้อหาผู้ใหญ่ในแอป companion อย่างไร?
มองเป็นปัญหาการจับคู่นโยบาย ใส่ธีมนิยายผู้ใหญ่ไว้หลัง age gate ของผู้ใหญ่ คัดกรอง input สำหรับหมวดที่ไม่มีผู้ให้บริการรายใดอนุญาต และ route traffic นั้นไปยังโมเดลที่นโยบายเผยแพร่อนุญาตนิยายสำหรับผู้ใหญ่เท่านั้น เช่น Grok ภายใต้นโยบายของ xAI คงเส้นทาง all-ages default ไว้บนโมเดลที่เข้มงวดกว่า และปฏิบัติตามข้อกำหนดการใช้งานของทุกผู้ให้บริการ
ใช้ OpenAI SDK กับแอป character AI ร่วมกับโมเดลอื่นได้ไหม?
ได้ DeepSeek, GLM, Kimi, Gemini, Claude และ Grok เข้าถึงได้ทั้งหมดผ่าน endpoint แบบ OpenAI-compatible ไม่ว่าจากผู้ให้บริการโดยตรงหรือผ่าน gateway โค้ดแอปของคุณยังอยู่บน interface chat.completions มาตรฐานและสลับโมเดลได้ด้วยการเปลี่ยน model string ซึ่งคือสิ่งที่ทำให้ routing ต่อข้อความสร้างได้ถูก