Cách xây app character AI: kiến trúc, code, và phép tính chi phí
Updated 2026-07-15
Một app character AI là bốn thành phần kết nối với một endpoint chat tương thích OpenAI: một persona system prompt, một lớp bộ nhớ, một cổng kiểm duyệt, và một bộ định tuyến model. Bạn có thể ra mắt một prototype hoạt động trong dưới 200 dòng Python và chạy nó với chi phí dưới một đô la mỗi người dùng hoạt động hàng tháng với lựa chọn model phù hợp.
Câu trả lời nhanh: kiến trúc bốn thành phần
Bạn không cần train hay fine-tune một model. Mọi app đồng hành nghiêm túc trên thị trường hiện nay, kể cả những cái phục vụ hàng triệu người dùng, là một lớp orchestration mỏng trên các LLM API hosted. Nhân vật sống trong prompt và database, không phải trong weight. Phần còn lại của hướng dẫn này xây từng thành phần với code chạy được trên một endpoint tương thích OpenAI tiêu chuẩn, sau đó đi qua phép tính token để bạn biết một người dùng hoạt động hàng tháng thực sự tốn bao nhiêu trước khi bạn ra mắt.
- Persona prompt: một system prompt có cấu trúc (500 đến 1.000 token) định nghĩa nhân vật là ai và nói chuyện như thế nào.
- Bộ nhớ: một cửa sổ xoay vòng các lượt gần đây cộng với một bản tóm tắt được làm mới định kỳ, để cuộc trò chuyện sống sót qua giới hạn context.
- Kiểm duyệt: một age gate, một bộ phân loại input, và các chính sách nội dung khớp với model bạn định tuyến tới.
- Định tuyến: một hàm nhỏ chọn một model rẻ cho chat thông thường và một model mạnh hơn cho các cảnh dài.
Thành phần 1: persona prompt
Persona prompt chính là sản phẩm. Đó là một system message đi kèm mọi request và thường chứa năm phần: danh tính (tên, tuổi, backstory), đặc điểm tính cách, phong cách nói chuyện với hai hoặc ba câu ví dụ, quy tắc hành vi cứng (không bao giờ phá vỡ tính cách, giữ phản hồi dưới một giới hạn độ dài), và kịch bản hiện tại. Giữ nó trong khoảng 500 đến 1.000 token. Persona ngắn hơn dễ lệch; dài hơn nhiều đốt ngân sách input trên mỗi tin nhắn và hiếm khi cải thiện độ bám sát. Lưu persona như các dòng trong database để người dùng có thể tạo và chỉnh sửa nhân vật, đây là vòng lặp cốt lõi của các sản phẩm kiểu Character.AI. Đây là một request đầy đủ. Cùng hình dạng này hoạt động với bất kỳ backend tương thích OpenAI nào; ví dụ này dùng một endpoint gateway đa model để bạn có thể đổi model chỉ bằng cách đổi một chuỗi:
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
}'Thành phần 2: bộ nhớ sống sót qua các cuộc trò chuyện dài
Phiên app đồng hành chạy dài. Một stack bộ nhớ ba lớp giữ context mạch lạc mà không cần gửi toàn bộ lịch sử mỗi lần: Lớp 1 là cửa sổ xoay vòng: 10 đến 14 lượt thô gần nhất, gửi nguyên văn. Lớp 2 là bản tóm tắt đang chạy: cứ khoảng 20 lượt, một model rẻ nén các tin nhắn cũ hơn thành một đoạn văn theo dõi tên, trạng thái mối quan hệ, và các mạch truyện đang mở. Lớp 3 là các sự kiện đã ghim: chi tiết người dùng lâu dài (tên, sở thích, sự kiện quá khứ mà nhân vật nên nhớ) được trích xuất vào database của bạn và chèn vào như một system message ngắn. Đây là toàn bộ triển khai bằng Python với OpenAI SDK chính thức:
| Vị trí context | Kích thước điển hình | Tần suất làm mới |
|---|---|---|
| Persona system prompt | 500 đến 1.000 token | Tĩnh theo từng nhân vật |
| Sự kiện người dùng đã ghim | 100 đến 200 token | Khi có sự kiện trích xuất |
| Bản tóm tắt đang chạy | 300 đến 500 token | Mỗi khoảng 20 lượt |
| Cửa sổ xoay vòng (12 lượt) | ~1.800 đến 2.200 token | Mỗi tin nhắn |
| Tin nhắn người dùng mới | ~100 token | Mỗi tin nhắn |
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.contentThành phần 3: kiểm duyệt và chính sách nội dung
Kiểm duyệt trong một app đồng hành có ba nhiệm vụ riêng biệt, và nhầm lẫn chúng là lỗi ra mắt phổ biến nhất. Thứ nhất, chặn đối tượng của bạn. Nếu app của bạn cho phép chủ đề hư cấu trưởng thành, đặt chúng sau một age gate người lớn và giữ một mặc định mọi lứa tuổi riêng biệt. App Store và Play Store đều kiểm tra điều này, và các bên xử lý thanh toán cũng quan tâm. Thứ hai, sàng lọc input. Chạy một lượt phân loại rẻ trên tin nhắn người dùng trước khi chúng chạm tới model nhân vật, chặn các danh mục mà không nhà cung cấp nào cho phép: nội dung liên quan đến trẻ vị thành niên, tổn hại thực tế đáng tin, và hướng dẫn bất hợp pháp. Một lệnh gọi deepseek-v4-flash duy nhất với một rubric có/không tốn một phần nhỏ của cent và thêm dưới một giây độ trễ. Thứ ba, khớp chính sách nội dung với model. Nhà cung cấp khác nhau về hư cấu: chính sách công khai của xAI cho phép rõ ràng chủ đề hư cấu trưởng thành cho người dùng trưởng thành, DeepSeek và các model dẫn xuất open-weight khác được cộng đồng ưa chuộng cho roleplay vì chính sách hosted của chúng linh hoạt với hư cấu, trong khi chính sách của Anthropic cấm nội dung explicit, khiến Claude là lựa chọn đúng chỉ cho viết sáng tạo mọi lứa tuổi. Hiểu các chính sách này trước khi định tuyến traffic giúp bạn tránh các cơn bão từ chối trong production. Bất cứ gì bạn xây, nó phải tôn trọng điều khoản dịch vụ của mọi nhà cung cấp bạn gọi.
Thành phần 4: định tuyến model và ma trận lựa chọn
Hầu hết tin nhắn trong một app đồng hành là các lượt thông thường ngắn mà một model ngân sách xử lý hoàn hảo. Một số ít là các cảnh cảm xúc dài hoặc các đoạn sáng tạo nơi chất lượng văn xuôi chính là sản phẩm. Định tuyến theo độ sâu cảnh cắt giảm chi phí đáng kể mà người dùng không nhận ra:
| Model | API model ID | Giá mỗi 1M token (in/out) | Độ phù hợp cho app đồng hành |
|---|---|---|---|
| DeepSeek V4 Flash | deepseek-v4-flash | $0.126 / $0.252 | Model chat mặc định. Được cộng đồng ưa chuộng cho roleplay, giá trị tốt nhất trong catalog. |
| DeepSeek V4 Pro | deepseek-v4-pro | $0.3915 / $0.783 | Cảnh dài hơn, theo hướng dẫn tốt hơn, vẫn rẻ. |
| GLM-5 | glm-5 | $0.514 / $2.314 | Lựa chọn giá trị với khả năng viết sáng tạo mạnh. |
| Kimi K2.6 | kimi-k2.6 | Xem /pricing | Lựa chọn giá trị cho phiên context dài. MiMo là lựa chọn ngân sách tương tự. |
| grok-4.5 | grok-4.5 | $1.60 / $4.80 | Chủ đề hư cấu trưởng thành cho người dùng trưởng thành theo chính sách công khai của xAI. Context window 500K. |
| Claude Sonnet 4.6 | claude-sonnet-4-6 | $2.40 / $12.00 | Chất lượng văn xuôi cao nhất. Chỉ viết sáng tạo mọi lứa tuổi; Anthropic cấm nội dung explicit. |
| Gemini 3.5 Flash | gemini-3.5-flash | $1.20 / $7.20 | Nhanh, tốt cho các tính năng nhận biết hình ảnh như phản ứng avatar. |
ROUTES = {
"casual": "deepseek-v4-flash",
"scene": "deepseek-v4-pro",
"prose": "claude-sonnet-4-6", # chỉ viết sáng tạo mọi lứa tuổi
}
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"]Một người dùng hoạt động hàng tháng thực sự tốn bao nhiêu
Phép tính token trước khi ra mắt tốt hơn một bất ngờ hóa đơn sau đó. Dùng ngân sách context từ bảng bộ nhớ: khoảng 3.300 input token và 250 output token mỗi tin nhắn. Người dùng app đồng hành dùng nặng; số liệu cộng đồng báo cáo đặt người dùng gắn bó ở hàng chục tin nhắn mỗi ngày, nên giả định khoảng 40 tin nhắn mỗi ngày qua 20 ngày hoạt động, hay khoảng 800 tin nhắn mỗi MAU mỗi tháng. Điều đó cho ra 2.64M input token và 0.2M output token mỗi MAU mỗi tháng. Nhân với giá catalog:
| Model | Chi phí input / MAU | Chi phí output / MAU | Tổng / MAU / tháng |
|---|---|---|---|
| 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 |
Một endpoint cho mọi model trong ma trận
Đăng ký năm tài khoản nhà cung cấp để chạy một bộ định tuyến là chi phí thực: năm key, năm dashboard thanh toán, năm bộ rate limit. Một gateway đa model thu gọn điều đó. APIsRouter cho phép truy cập mọi model bên trên qua một base URL tương thích OpenAI duy nhất https://api.apisrouter.com/v1, nên đoạn code router hoạt động nguyên vẹn chỉ bằng cách đổi chuỗi model. Thanh toán theo lượng dùng không subscription, model toàn cầu chạy thấp hơn 20% so với giá chính thức với model Trung Quốc dưới giá chính thức, và checkout không cần đăng ký tại /topup gửi một key tới email của bạn sau khi thanh toán, với lần nạp đầu tiên cộng thêm +100% số dư. GET /v1/models với key của bạn trả về danh sách model trực tiếp, cũng tiện cho việc điền một bộ chọn model trong admin UI của riêng bạn.
Mẹo production tiết kiệm tiền và đau đầu thực sự
- Stream mọi thứ. Time-to-first-token là chỉ số người dùng cảm nhận được; một phản hồi stream ở 2 giây cảm thấy nhanh hơn một phản hồi hoàn chỉnh ở 4 giây.
- Giữ tiền tố ổn định luôn ổn định. Persona và sự kiện đã ghim nên giống hệt từng byte qua các request để backend hỗ trợ prefix caching có thể tận dụng nó.
- Giới hạn max_tokens theo từng route. Các lượt thông thường hiếm khi cần hơn 300 output token; một model không giới hạn lan man sẽ nhân đôi hóa đơn output của bạn.
- Log chi phí theo từng người dùng, không chỉ theo từng request. Một phần nhỏ người dùng nặng sẽ chiếm phần lớn chi tiêu; bạn cần thấy họ để thiết kế các tier sử dụng công bằng.
- Xây fallback vào bộ định tuyến. Nếu model chính timeout hoặc từ chối, thử lại một lần trên một model anh em trước khi hiện lỗi.
- Cắt cửa sổ xoay vòng theo token, không theo lượt, để một đoạn paste dài không thổi bay ngân sách.
- Xử lý từ chối trong tính cách. Ánh xạ một từ chối thành một chuyển hướng trong truyện mượt mà thay vì hiện text API thô.
- Đừng lưu chat thô lâu hơn mức cần thiết, và nói rõ điều đó trong chính sách quyền riêng tư của bạn. Log chat đồng hành nhạy cảm theo bản chất.
Câu hỏi thường gặp
Xây một app character AI tốn bao nhiêu?
Chi phí phát triển chủ yếu là thời gian của bạn: một prototype hoạt động là một dự án cuối tuần vì không có train model liên quan. Chi phí vận hành là con số thực sự, và nó tăng theo lượng dùng. Trên một model ngân sách như deepseek-v4-flash, một người dùng hoạt động hàng tháng nặng tốn khoảng $0.38 tiền token; trên một model cao cấp như gpt-5.5, cùng người dùng đó tốn khoảng $15. Lựa chọn model, không phải hạ tầng, quyết định biên lợi nhuận của bạn.
Model AI nào tốt nhất cho một app character AI?
Dòng DeepSeek V4 là lựa chọn được cộng đồng ưa chuộng cho roleplay và giá trị tốt nhất: Flash cho chat thông thường, Pro cho các cảnh dài hơn. GLM-5, Kimi K2.6, và MiMo là các lựa chọn giá trị vững chắc. Grok phù hợp với app phục vụ chủ đề hư cấu trưởng thành cho người lớn, theo chính sách công khai của xAI. Claude Sonnet 4.6 viết văn hay nhất nhưng chỉ phù hợp cho viết sáng tạo mọi lứa tuổi vì Anthropic cấm nội dung explicit.
Các app character AI nhớ các cuộc trò chuyện trước như thế nào?
Qua kỹ thuật prompt, không phải bộ nhớ model. App gửi lại một cửa sổ xoay vòng các tin nhắn gần đây, một bản tóm tắt được nén định kỳ của các tin nhắn cũ hơn, và một danh sách ngắn các sự kiện đã ghim được trích xuất vào database. Bản thân model không có trạng thái; mỗi request chứa mọi thứ nhân vật "nhớ".
Tôi có cần train model riêng để xây một app đồng hành AI không?
Không. Fine-tuning tốn kém, chậm lặp lại, và không cần thiết cho tính nhất quán nhân vật. Một persona prompt được cấu trúc tốt 500 đến 1.000 token cộng với một lớp bộ nhớ đạt được độ bám sát nhân vật mà người dùng không thể phân biệt với một model tùy chỉnh, và cho phép bạn đổi model nền tự do khi có model tốt hơn ra mắt.
Làm sao xử lý nội dung trưởng thành trong một app đồng hành?
Coi đó là một vấn đề khớp chính sách. Đặt chủ đề hư cấu trưởng thành sau một age gate người lớn, sàng lọc input cho các danh mục không nhà cung cấp nào cho phép, và chỉ định tuyến traffic đó tới các model có chính sách công khai cho phép hư cấu cho người lớn, như Grok theo chính sách xAI. Giữ một track mặc định mọi lứa tuổi trên các model nghiêm ngặt hơn, và tuân thủ điều khoản dịch vụ của mọi nhà cung cấp.
Tôi có thể dùng OpenAI SDK cho một app character AI với model khác không?
Có. DeepSeek, GLM, Kimi, Gemini, Claude, và Grok đều có thể truy cập qua các endpoint tương thích OpenAI, từ chính nhà cung cấp hoặc qua một gateway. Code app của bạn giữ nguyên trên interface chat.completions tiêu chuẩn và đổi model bằng cách đổi chuỗi model, đây chính xác là điều khiến định tuyến theo từng tin nhắn rẻ để xây dựng.