چگونه یک اپ Character AI بسازیم: معماری، کد و محاسبه هزینه

Updated 2026-07-15

یک اپ character AI چهار جزء است که به یک endpoint چت سازگار با OpenAI متصل می‌شوند: یک پرامپت شخصیت، یک لایه حافظه، یک دروازه نظارت محتوا، و یک مسیریاب مدل. می‌توانید یک نمونه اولیه کارکردی را در کمتر از 200 خط Python عرضه کنید و آن را با انتخاب درست مدل به‌ازای هر کاربر فعال ماهانه با کمتر از یک دلار اجرا کنید.

پاسخ سریع: معماری چهارجزئی

نیازی به آموزش یا fine-tune کردن یک مدل ندارید. هر اپ همدم جدی در بازار امروز، شامل آن‌هایی که به میلیون‌ها کاربر خدمت می‌دهند، یک لایه سازمان‌دهی نازک روی API های LLM میزبانی‌شده است. شخصیت در پرامپت و پایگاه داده زندگی می‌کند، نه در وزن‌ها. بقیه این راهنما هر جزء را با کد قابل‌اجرا در برابر یک endpoint استاندارد سازگار با OpenAI می‌سازد، سپس محاسبه توکن را طی می‌کند تا پیش از راه‌اندازی بدانید یک کاربر فعال ماهانه واقعاً چقدر هزینه دارد.

  • پرامپت شخصیت: یک system prompt ساختاریافته (500 تا 1,000 توکن) که تعریف می‌کند شخصیت کیست و چطور صحبت می‌کند.
  • حافظه: یک پنجره در حال حرکت از نوبت‌های اخیر به‌علاوه یک خلاصه که به‌طور دوره‌ای تازه می‌شود، تا مکالمات از محدودیت context عبور کنند.
  • نظارت محتوا: یک دروازه سنی، یک طبقه‌بند ورودی، و سیاست‌های محتوایی متناسب با مدلی که به آن مسیریابی می‌کنید.
  • مسیریابی: یک تابع کوچک که برای چت معمولی یک مدل ارزان و برای صحنه‌های طولانی مدلی قوی‌تر انتخاب می‌کند.

جزء 1: پرامپت شخصیت

پرامپت شخصیت خود محصول است. این یک پیام system است که با هر درخواست ارسال می‌شود و معمولاً پنج بخش دارد: هویت (نام، سن، پیشینه)، ویژگی‌های شخصیتی، سبک گفتار با دو یا سه نمونه جمله، قوانین رفتاری سخت (هرگز از نقش خارج نشو، پاسخ‌ها را زیر یک سقف طول نگه‌دار)، و سناریوی فعلی. بین 500 تا 1,000 توکن نگهش دارید. شخصیت‌های کوتاه‌تر منحرف می‌شوند؛ خیلی طولانی‌تر بودجه ورودی را در هر پیام می‌سوزانند و به‌ندرت پیروی را بهبود می‌دهند. شخصیت‌ها را به‌صورت ردیف در پایگاه داده خود ذخیره کنید تا کاربران بتوانند شخصیت بسازند و ویرایش کنند، که همان حلقه اصلی محصولات سبک Character.AI است. این یک درخواست کامل است. همان شکل با هر backend سازگار با OpenAI کار می‌کند؛ این مثال از یک endpoint گیت‌وی چندمدله استفاده می‌کند تا مدل‌ها را با تغییر یک رشته عوض کنید:

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: حافظه‌ای که در مکالمات طولانی زنده می‌ماند

جلسات اپ همدم طولانی اجرا می‌شوند. یک استک حافظه سه‌لایه context را منسجم نگه می‌دارد بدون اینکه هر بار کل تاریخچه را بفرستد: لایه 1 پنجره در حال حرکت است: 10 تا 14 نوبت خام اخیر، فرستاده‌شده عیناً. لایه 2 خلاصه در حال اجراست: هر حدود 20 نوبت، یک مدل ارزان پیام‌های قدیمی‌تر را در یک پاراگراف فشرده می‌کند که نام‌ها، وضعیت رابطه و رشته‌های داستانی باز را دنبال می‌کند. لایه 3 حقایق سنجاق‌شده است: جزئیات پایدار کاربر (نام، ترجیحات، رویدادهای گذشته‌ای که شخصیت باید به یاد داشته باشد) که به پایگاه داده شما استخراج و به‌عنوان یک پیام system کوتاه تزریق می‌شود. این کل پیاده‌سازی در Python با SDK رسمی OpenAI است:

بودجه واقعی ورودی هر درخواست حدود 3,300 توکن است.
بخش contextاندازه معمولدوره تازه‌سازی
system prompt شخصیت500 تا 1,000 توکنثابت به‌ازای هر شخصیت
حقایق سنجاق‌شده کاربر100 تا 200 توکندر رویدادهای استخراج
خلاصه در حال اجرا300 تا 500 توکنهر ~20 نوبت
پنجره در حال حرکت (12 نوبت)~1,800 تا 2,200 توکنهر پیام
پیام جدید کاربر~100 توکنهر پیام
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: نظارت محتوا و سیاست‌های محتوایی

نظارت محتوا در یک اپ همدم سه وظیفه متمایز دارد، و قاطی کردن آن‌ها رایج‌ترین اشتباه راه‌اندازی است. اول، مخاطبان خود را گیت کنید. اگر اپ شما مضامین داستانی بزرگسالانه را مجاز می‌داند، آن‌ها را پشت یک دروازه سنی بزرگسال بگذارید و یک پیش‌فرض جداگانه برای همه‌سنین نگه دارید. App Store و Play Store هر دو این را بررسی می‌کنند، و پردازشگرهای پرداخت هم اهمیت می‌دهند. دوم، ورودی‌ها را غربال کنید. یک پاس طبقه‌بند ارزان روی پیام‌های کاربر پیش از رسیدن به مدل شخصیت اجرا کنید که رده‌هایی را مسدود می‌کند که هیچ ارائه‌دهنده‌ای مجاز نمی‌داند: محتوای مربوط به کودکان، آسیب واقعی معتبر، و دستورالعمل‌های غیرقانونی. یک فراخوانی deepseek-v4-flash با یک قاعده بله/نه کسری از یک سنت هزینه دارد و کمتر از یک ثانیه تأخیر اضافه می‌کند. سوم، سیاست محتوا را با مدل تطبیق دهید. ارائه‌دهندگان درباره داستان فرق دارند: سیاست منتشرشده xAI صراحتاً مضامین داستانی بزرگسالانه را برای کاربران بزرگ‌سال مجاز می‌داند، DeepSeek و مدل‌های دیگر مشتق از open-weight برای رول‌پلی مورد علاقه جامعه هستند چون سیاست‌های میزبانی‌شده‌شان برای داستان منعطف است، درحالی‌که سیاست Anthropic محتوای صریح را ممنوع می‌کند و Claude را فقط برای نگارش خلاقانه همه‌سنین انتخاب درستی می‌کند. فهمیدن این سیاست‌ها پیش از مسیریابی ترافیک شما را از طوفان‌های رد در تولید نجات می‌دهد. هر چیزی که می‌سازید باید شرایط خدمات هر ارائه‌دهنده‌ای که فراخوانی می‌کنید را محترم بشمارد.

جزء 4: مسیریابی مدل و ماتریس انتخاب

بیشتر پیام‌ها در یک اپ همدم نوبت‌های کوتاه معمولی هستند که یک مدل اقتصادی کاملاً به آن‌ها رسیدگی می‌کند. اقلیتی صحنه‌های احساسی طولانی یا قطعات خلاقانه هستند که کیفیت نثر خود محصول است. مسیریابی بر اساس عمق صحنه هزینه‌ها را چشمگیر کاهش می‌دهد بدون اینکه کاربران متوجه شوند:

هر مسیر را به مدلی تطبیق دهید که سیاست محتوایش با مخاطبی که خدمت می‌دهد تناسب دارد.
مدلشناسه مدل در APIنرخ به ازای 1M توکن (ورودی/خروجی)تناسب با اپ همدم
DeepSeek V4 Flashdeepseek-v4-flash$0.126 / $0.252مدل چت پیش‌فرض. مورد علاقه جامعه برای رول‌پلی، بهترین ارزش در کاتالوگ.
DeepSeek V4 Prodeepseek-v4-pro$0.3915 / $0.783صحنه‌های طولانی‌تر، پیروی قوی‌تر از دستور، هنوز ارزان.
GLM-5glm-5$0.514 / $2.314انتخاب ارزشی با نگارش خلاقانه قوی.
Kimi K2.6kimi-k2.6/pricing را ببینیدانتخاب ارزشی برای جلسات با context طولانی. MiMo گزینه اقتصادی مشابهی است.
grok-4.5grok-4.5$1.60 / $4.80مضامین داستانی بزرگسالانه برای کاربران بزرگ‌سال طبق سیاست منتشرشده xAI. پنجره context با اندازه 500K.
Claude Sonnet 4.6claude-sonnet-4-6$2.40 / $12.00بالاترین کیفیت نثر. فقط نگارش خلاقانه همه‌سنین؛ Anthropic محتوای صریح را ممنوع می‌کند.
Gemini 3.5 Flashgemini-3.5-flash$1.20 / $7.20سریع، خوب برای ویژگی‌های تصویرآگاه مثل واکنش‌های آواتار.
ROUTES = {
    "casual": "deepseek-v4-flash",
    "scene": "deepseek-v4-pro",
    "prose": "claude-sonnet-4-6",  # فقط نگارش خلاقانه همه‌سنین
}

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"]

یک کاربر فعال ماهانه واقعاً چقدر هزینه دارد

محاسبه توکن پیش از راه‌اندازی بهتر از یک شگفتی صورت‌حساب بعد از آن است. با استفاده از بودجه context از جدول حافظه: تقریباً 3,300 توکن ورودی و 250 توکن خروجی به‌ازای هر پیام. کاربران اپ همدم سنگین‌اند؛ ارقام گزارش‌شده جامعه کاربران درگیر را ده‌ها پیام در روز می‌دانند، پس فرض کنید تقریباً 40 پیام در روز در 20 روز فعال، یا حدود 800 پیام به ازای هر MAU در ماه. این 2.64M توکن ورودی و 0.2M توکن خروجی به ازای هر MAU در ماه می‌دهد. با ضرب در نرخ‌های کاتالوگ:

فرض بر 3,300 توکن ورودی + 250 توکن خروجی به ازای هر پیام، ~800 پیام به ازای هر MAU در ماه.
مدلهزینه ورودی / MAUهزینه خروجی / 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 برای هر مدل روی ماتریس

ثبت‌نام برای پنج حساب ارائه‌دهنده برای اجرای یک مسیریاب، سربار واقعی است: پنج کلید، پنج داشبورد صورت‌حساب، پنج مجموعه محدودیت نرخ. یک گیت‌وی چندمدله این را جمع می‌کند. APIsRouter هر مدل بالا را از طریق یک base URL واحد سازگار با OpenAI در https://api.apisrouter.com/v1 نشان می‌دهد، پس قطعه‌کد مسیریاب همان‌طور که هست کار می‌کند و فقط با تغییر رشته مدل. صورت‌حساب پرداخت بر اساس مصرف و بدون اشتراک است، مدل‌های جهانی 20% پایین‌تر از قیمت رسمی اجرا می‌شوند و مدل‌های چینی زیر نرخ رسمی خودشان هستند، و checkout بدون ثبت‌نام در /topup پس از پرداخت یک کلید به ایمیل شما می‌فرستد، با اولین شارژی که +100% موجودی اضافه می‌کند. GET /v1/models با کلید شما فهرست زنده مدل‌ها را برمی‌گرداند، که برای پر کردن یک انتخاب‌گر مدل در پنل مدیریتی خودتان هم مفید است.

نکات تولیدی که پول و دردسر واقعی صرفه‌جویی می‌کنند

  • همه‌چیز را استریم کنید. زمان تا اولین توکن معیاری است که کاربران احساس می‌کنند؛ یک پاسخ استریم‌شده در 2 ثانیه سریع‌تر از یک پاسخ کامل در 4 ثانیه احساس می‌شود.
  • پیشوند ثابت را ثابت نگه دارید. شخصیت و حقایق سنجاق‌شده باید بایت‌به‌بایت در همه درخواست‌ها یکسان باشند تا backendهایی که از prefix caching پشتیبانی می‌کنند از آن بهره‌مند شوند.
  • max_tokens را به‌ازای هر مسیر سقف بگذارید. نوبت‌های معمولی به‌ندرت به بیش از 300 توکن خروجی نیاز دارند؛ مدلی بدون سقف که پرگویی می‌کند صورت‌حساب خروجی شما را دوبرابر می‌کند.
  • هزینه را به‌ازای هر کاربر ثبت کنید، نه فقط به‌ازای هر درخواست. بخش کوچکی از کاربران سنگین بر مخارج غالب خواهند بود؛ برای طراحی رده‌های استفاده منصفانه باید آن‌ها را ببینید.
  • fallback را در مسیریاب بسازید. اگر مدل اصلی timeout می‌کند یا رد می‌کند، پیش از نمایش خطا یک‌بار روی یک مدل خواهر تلاش مجدد کنید.
  • پنجره در حال حرکت را بر اساس توکن کوتاه کنید، نه نوبت، تا یک چسباندن طولانی بودجه را نترکاند.
  • ردها را در نقش مدیریت کنید. یک رد را به یک انحراف درون‌داستانی ملایم نگاشت کنید به‌جای نمایش متن خام API.
  • چت‌های خام را بیشتر از حد لازم ذخیره نکنید، و این را در سیاست حریم خصوصی خود بگویید. گزارش‌های چت اپ همدم ذاتاً حساس‌اند.

پرسش‌های پرتکرار

ساخت یک اپ character AI چقدر هزینه دارد؟

هزینه توسعه بیشتر زمان شماست: یک نمونه اولیه کارکردی یک پروژه آخر هفته است چون هیچ آموزش مدلی درگیر نیست. هزینه اجرا عدد واقعی است، و با استفاده مقیاس می‌گیرد. روی یک مدل اقتصادی مثل deepseek-v4-flash، یک کاربر فعال ماهانه سنگین حدود $0.38 در توکن هزینه دارد؛ روی یک مدل پرمیوم مثل gpt-5.5 همان کاربر حدود $15 هزینه دارد. انتخاب مدل، نه زیرساخت، حاشیه سود شما را تعیین می‌کند.

کدام مدل هوش مصنوعی برای یک اپ character AI بهترین است؟

خانواده DeepSeek V4 مورد علاقه جامعه برای رول‌پلی و بهترین ارزش است: Flash برای چت معمولی، Pro برای صحنه‌های طولانی‌تر. GLM-5، Kimi K2.6 و MiMo انتخاب‌های ارزشی محکمی هستند. Grok برای اپ‌هایی که به مضامین داستانی بزرگسالانه خدمت می‌دهند مناسب است، طبق سیاست منتشرشده xAI. Claude Sonnet 4.6 بهترین نثر را می‌نویسد اما چون Anthropic محتوای صریح را ممنوع می‌کند فقط برای نگارش خلاقانه همه‌سنین مناسب است.

اپ‌های character AI چطور مکالمات گذشته را به یاد می‌آورند؟

از طریق مهندسی پرامپت، نه حافظه مدل. اپ یک پنجره در حال حرکت از پیام‌های اخیر، یک خلاصه فشرده‌شده دوره‌ای از پیام‌های قدیمی‌تر، و فهرست کوتاهی از حقایق سنجاق‌شده استخراج‌شده به یک پایگاه داده را دوباره می‌فرستد. خود مدل بی‌حالت است؛ هر درخواست حاوی هر چیزی است که شخصیت «به یاد می‌آورد».

آیا باید مدل خودم را برای ساخت یک اپ همدم هوش مصنوعی آموزش دهم؟

نه. fine-tuning گران، کند برای تکرار و برای انسجام شخصیت غیرضروری است. یک پرامپت شخصیت خوب‌ساخته با 500 تا 1,000 توکن به‌علاوه یک لایه حافظه انسجامی از شخصیت به دست می‌دهد که کاربران نمی‌توانند از یک مدل سفارشی تشخیص دهند، و به شما اجازه می‌دهد مدل‌های زیربنایی را آزادانه با مدل‌های بهتر بعدی عوض کنید.

چطور محتوای بزرگسالانه را در یک اپ همدم مدیریت کنم؟

آن را یک مسئله تطبیق سیاست در نظر بگیرید. مضامین داستانی بزرگسالانه را پشت یک دروازه سنی بزرگسال بگذارید، ورودی‌ها را برای رده‌هایی که هیچ ارائه‌دهنده‌ای اجازه نمی‌دهد غربال کنید، و آن ترافیک را فقط به مدل‌هایی مسیریابی کنید که سیاست‌های منتشرشده‌شان داستان را برای بزرگ‌سالان مجاز می‌داند، مثل Grok طبق سیاست xAI. یک مسیر پیش‌فرض همه‌سنین روی مدل‌های سخت‌گیرانه‌تر نگه دارید، و با شرایط خدمات هر ارائه‌دهنده مطابقت داشته باشید.

آیا می‌توانم از SDK رسمی OpenAI برای یک اپ character AI با مدل‌های دیگر استفاده کنم؟

بله. DeepSeek، GLM، Kimi، Gemini، Claude و Grok همگی از طریق endpoint های سازگار با OpenAI در دسترس‌اند، چه مستقیم از ارائه‌دهنده‌شان چه از طریق یک گیت‌وی. کد اپ شما روی همان رابط استاندارد chat.completions می‌ماند و مدل‌ها را با تغییر رشته مدل عوض می‌کند، که دقیقاً همان چیزی است که مسیریابی به‌ازای هر پیام را ارزان می‌سازد.