iAct

Act on Ai

تبدیل یه اپ موبایل به وب با Real-Time Voice Agent + دستور /goal (Fable)


تبدیل یه اپ موبایل به وب با Real-Time Voice Agent + دستور /goal (Fable)

ایده: کپی کردن یه اپ موبایل و ساختنش به‌صورت وب

قضیه از اینجا شروع می‌شه که من یه اپ موبایل ساخته بودم برای یادگیری اسپانیایی، با الهام از یه دوره مکالمه فشرده که خودم قبلاً برای یادگیری انگلیسی ازش استفاده کرده بودم و واقعاً بهم کمک کرد. اون دوره یه متدولوژی ساده داشت: معلم یه جمله می‌گفت، تو تکرار می‌کردی، و همین تکرار کردن انگلیسی به فارسی و فارسی به انگلیسی بود که زبان رو تو ذهنت جا می‌انداخت. حالا که خودم دارم اسپانیایی یاد می‌گیرم، همون ساختار رو با هوش مصنوعی بازسازی کردم و یه اپ اندروید ساختم که همین کار رو با صدا انجام می‌ده.

مشکل اپ موبایلم این بود که از یه مدل قدیمی‌تر ریل‌تایم استفاده می‌کرد و تأخیر زیادی داشت؛ وسط مکالمه یهو از دستور خارج می‌شد و می‌رفت رو فاز خودش. حالا که یه مدل ریل‌تایم جدیدتر اومده که بهتر به دستورالعمل‌ها پایبند می‌مونه، تصمیم گرفتم کل اپ رو کپی کنم و نسخه وبش رو با یه Real-Time Voice Agent جدید بسازم.

اول کانتکست بده، بعد سراغ کد برو

قبل از اینکه یک خط کد بزنم، پروژه اندروید قدیمی رو باز کردم و از فیبل (که روی Claude اجرا می‌شه) خواستم اول پروژه رو بخونه و بفهمه. نکته مهم اینجاست که نپریدم مستقیم سراغ نوشتن فیچر؛ اول گفتم درباره پروژه بهم توضیح بده:

tell me about the project

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

قبل از نوشتن کد، درباره مدل ریل‌تایم تحقیق کن

مرحله بعدی این بود که یه سرچ جدا درباره مدل GPT Realtime انجام دادم و مستندات جدیدش رو کپی کردم و به همون چت دادم. هنوز به AI نگفته بودم که چیزی بسازه؛ فقط داشتم ذهنش رو آماده می‌کردم که هم پروژه قدیمی رو بشناسه، هم مدل جدید رو بشناسه.

نوشتن PRD قبل از هر خط کد

وقتی کانتکست آماده بود، وقتش رسید که برم سراغ طراحی PRD. پرامپتی که دادم تقریباً این بود:

I want to use the same lesson script and structure.
I want to keep the database and track user progress.
I want it to be real-time, since the current project is so laggy —
real-time should feel like a real teacher, reacting exactly as the
student speaks.

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

نکته مهم اینجا اینه که همیشه از AI می‌خوام قبل از تکمیل کردن سند، ازم سؤال بپرسه، نه اینکه خودسرانه فرض کنه:

Ask me questions before we complete this. Don't switch to plan mode yet.

اینجا AI حداکثر چهار تا سؤال از من پرسید. بعد از جواب دادن به سؤال‌ها، خودم صریح گفتم برو تو Plan Mode و پلن رو کامل کن.

انتخاب زیرساخت: Next.js، Vercel و Supabase

یکی از سؤال‌های مهم که باید قبل از پلن جواب می‌دادم این بود که دیتابیس رو کجا نگه دارم:

I need a database solution for Next.js on Vercel

برای کسایی که تازه‌کارن: Next.js یه فریمورک روی React هست که کمک می‌کنه اپلیکیشن‌های وب سریع و مدرن بسازی. Vercel هم شرکتیه که خودِ Next.js رو ساخته و یه سرویس هاستینگ می‌ده که برای پروژه‌های شخصی و تست، یه سهمیه رایگان داره.

Vercel خودش مستقیم دیتابیس نمی‌ده، ولی چند تا سرویس شریک داره که می‌تونی بهشون وصل بشی — مثل Postgres سرورلس، Neon، و Supabase. من از AI خواستم راهنماییم کنه، و پیشنهادش Supabase بود چون هم دیتابیس می‌ده و هم سیستم Authentication آماده داره. همین انتخاب باعث شد بعداً لاگین با گوگل و مجیک‌لینک هم راحت‌تر پیاده بشه.

دستور /goal چیه و چرا این کار رو عوض کرد

بعد از اینکه پلن آماده شد و بهش گفتم اجرا کن، AI شروع کرد به پیاده‌سازی. اما اینجا یه مشکل همیشگی هست: خیلی وقت‌ها یه کدی می‌زنی، انتظار داری تموم بشه، ولی وقتی برمی‌گردی می‌بینی کار واقعاً کامل نشده یا خودش فکر کرده تموم شده در حالی که نشده. برای همین چیزی به اسم /goal ساخته شده.

/goal یعنی «هدف تعیین کن». وقتی این دستور رو می‌زنی، قبل از اینکه Claude کارش رو تموم اعلام کنه، مجبورش می‌کنی یه سری چیز رو چک کنه، تست کنه، و فقط وقتی واقعاً شرطی که تعیین کردی برقرار شد، متوقف بشه. این دقیقاً همون چیزیه که بهش می‌گن «loop» — یعنی به‌جای اینکه فقط یه پرامپت بنویسی، داری یه حلقه تعریف می‌کنی که خودش تا رسیدن به نتیجه نهایی، تکرار می‌شه.

من تو گل نوشتم که چند تا چیز رو حتماً چک کنه:

- Don't hardcode my own API key for real-time voice usage;
  add a settings page so each user enters their own OpenAI API key
  (real-time voice usage is expensive).
- Make sure all lessons can be added easily later.
- Verify every connection actually works end to end.
- This should behave like the complete mobile app, not an MVP —
  just powered by real-time voice.

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

چرا /goal برای این پروژه صددرصد جواب نداد

یه محدودیت مهم هم هست: چون این یه Real-Time Voice Agent هست، تست کردنش نیاز به صحبت کردن واقعی داره، و AI نمی‌تونه خودش با صداش با اپ حرف بزنه و نتیجه رو بررسی کنه. برای همین اینجا loop به‌طور کامل بسته نشد. اما برای پروژه‌های دیگه، مثلاً یه اپ اندروید معمولی، این روش فوق‌العاده جواب می‌ده: بهش می‌گی برو اپلیکیشن رو روی امولاتور یا گوشی اجرا کن، خودت کلیک کن، تست کن، و اگه نتیجه‌ای که انتظار داری اتفاق نیفتاد، دوباره تلاش کن.

دیپلوی روی Vercel و اتصال به Supabase

وقتی گل تموم شد و AI اعلام کرد که بیلد شده، ریویو شده، کامیت و پوش شده، رفتم سراغ دیپلوی:

  • اول یه ریپازیتوری خالی روی گیت‌هاب ساختیم (پرایوت، بدون README و gitignore اضافه).
  • بعد پروژه رو به Vercel وصل کردیم؛ Vercel خودش پروژه گیت‌هاب رو شناسایی و دیپلوی کرد.
  • بعد از Integration خود Vercel، Supabase رو بهش وصل کردیم؛ اکثر تنظیمات مثل ساختن دیتابیس و ست کردن Storage به‌صورت خودکار انجام شد.
  • توی Supabase رفتیم سراغ Table Editor و دیدیم که جدول‌های LearnerMemory، UserProgress و UserSettings به‌درستی ساخته شدن.

راه‌اندازی لاگین با گوگل

آخرین مرحله، پیاده‌سازی Google Sign-In بود. برای این کار باید توی Google Cloud Console یه Credential از نوع «Web Application» می‌ساختی، Client ID و Client Secret رو می‌گرفتی، و توی بخش Auth Providers در Supabase، گوگل رو فعال می‌کردی و این دو مقدار رو وارد می‌کردی. نکته مهم اینجا این بود که آدرس Redirect/Callback باید دقیقاً با چیزی که Supabase تولید کرده یکی باشه، وگرنه لاگین خطا می‌ده.

نتیجه نهایی

بعد از این مراحل، اپ وب بالا اومد و واقعاً سریع و روون بود، خیلی بهتر از نسخه موبایلی که تأخیر زیاد داشت. طبیعتاً چون از مدل ریل‌تایم استفاده می‌کنه، هزینه اجراش هم بیشتره؛ برای همین بود که از اول تصمیم گرفتم به‌جای هاردکد کردن API Key خودم، هر یوزر از کلید خودش استفاده کنه.

نکته‌ای که از این تجربه می‌مونه اینه که خیلی وقت‌ها بخش سخت کار، دونستن این نیست که چطور به AI دستور بدی؛ دونستن اینه که اصلاً چه ابزارهایی وجود دارن. اگه ندونی Vercel یا Supabase وجود داره، نمی‌تونی از AI بخوای ازشون استفاده کنه. ولی خبر خوب اینه که اگه ندونی هم، می‌تونی مستقیم از خودِ AI بپرسی و همون‌جا یاد بگیری.

اگه دوست داری ویدئوش رو هم ببینی، لینکش پایین صفحه‌ست.


دیدگاهتان را بنویسید