تصور کنید میخواهید برای دویدن یا پیکنیک بیرون بروید، اما در اقلیمهای گرمسیری، تفاوت بین یک ورزش لذتبخش و گرمازدگی تنها چند ساعت است. پروژه Janela دقیقاً برای حل همین مسئله ساخته شده تا بهترین «پنجره زمانی» را برای فعالیتهای فضای باز پیدا کند. این پروژه با این پرسش آغاز شد: «بهترین زمان برای ترک خانه جهت اجتناب از یک رعدوبرق ناگهانی گرمسیری یا شاخص UV ۱۱ چه زمانی است؟»
این ابزار که در ۷ اکتبر ۲۰۲۶ برای چالش Hacktoberfest معرفی شد، از یک موتور امتیازدهی قطعی در کنار یک مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن کتابها جواب میدهد — استفاده میکند تا زمانبندیهای دقیقی ارائه دهد.
بسیاری از اپلیکیشنهای آبوهوایی فقط دادههای خام میدهند و تفسیر را به کاربر میسپارند. در مناطقی مثل برزیل، جایی که رعدوبرقهای عصرانه پیشبینیناپذیرند، استراتژی بسیاری از مردم برای فرار از دمای احساسی ۳۸ درجه در ساعت ۲ بعدازظهر یا طوفانی که تقریباً هر عصر تابستان در ساعت ۵ میرسد، این است که بگویند «بعداً میروم». Janela با خودکارسازی تصمیمگیری و نگه داشتن تمام دادههای مکانی روی دستگاه کاربر، این شکاف را پر میکند.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای محلی اشاره کردیم، حذف وابستگی به APIهای ابری، اولین قدم برای تضمین حریم خصوصی است.
زمینه و موارد استفاده
Janela (به معنای پنجره در زبان پرتغالی) برای کسانی طراحی شده که میخواهند از دنیای دیجیتال فاصله بگیرند و به طبیعت برگردند (Touch Grass). این رویکرد یادآور تلاشهای مشابه برای انتقال هوش مصنوعی به روی دستگاه جهت استفاده در هایکینگ است تا وابستگی کاربر به نمایشگرها در طبیعت کاهش یابد. این برنامه طیف متنوعی از فعالیتهای فضای باز را پشتیبانی میکند که هر کدام پارامترهای راحتی خاص خود را دارند:
- ورزشهای بدنی: دویدن، پیادهروی، دوچرخهسواری یا تمرینات ورزشی در باشگاههای فضای باز میدانها.
- تفریحات: پیکنیک و باغبانی.
کاربران شهر مورد نظر، فعالیت انتخابی، مدت زمان مورد نیاز برای خروج و تعداد روزهایی که میخواهند پیشبینی را بررسی کنند، وارد میکنند. سپس برنامه بهترین پنجره زمانی را به همراه دو جایگزین ارائه میدهد که هر کدام امتیازی بین ۰ تا ۱۰۰ دارند. برای اینکه دادهها بصری و بصریتر شوند، میزان راحتی هر روز بهصورت یک نمودار جزر و مدی رسم میشود؛ این کار به کاربران اجازه میدهد در یک نگاه ببینند روز چه زمانی «باز» میشود و چه زمانی «بسته» میگردد.
معماری مبتنی بر قطعیت
توسعهدهنده این پروژه یک قانون سختگیرانه وضع کرده است: مدل هوش مصنوعی هرگز نباید محاسبات ریاضی انجام دهد و هرگز نباید بازه زمانی را انتخاب کند. در این سیستم، یک رویکرد «مغز دوگانه» به کار رفته است که در آن Java 21 و Spring Boot 4 مسئول بخش علمی و محاسباتی هستند و مدل Gemma 3 (4B) تنها وظیفه ارتباط با کاربر را بر عهده دارد. توسعهدهنده جاوا را به «سنکو» (شخصیت علمی انیمه Dr. Stone) این عملیات تشبیه کرده است که کارهای سخت علمی را انجام میدهد، در حالی که Gemma صرفاً نتایج را ارائه میکند.
طبق گزارش وبسایت dev.to، این فرآیند از یک خط لوله (Pipeline) مشخص پیروی میکند:
- جمعآوری دادهها: برنامه دادههای ژئوکدینگ و پیشبینیهای ساعتی را از API Open-Meteo دریافت میکند (دادههای باز که نیازی به کلید API ندارند).
- امتیازدهی قطعی: یک مؤلفه جاوا به نام WindowScorer، امتیازی بین ۰ تا ۱۰۰ برای هر ساعت محاسبه میکند.
- منطق جریمه: هر ساعت از ساعات روز با ۱۰۰ امتیاز شروع میکند و بر اساس احتمال بارش، سرعت باد و انحراف دما از محدوده ایدهآل فعالیت، امتیاز از دست میدهد. برای مثال، برای دویدن، دمای احساسی بین ۱۰ تا ۲۲ درجه ترجیح داده میشود، در حالی که پیکنیک برای دمای ۱۸ تا ۲۸ درجه بهینه شده است.
- انتخاب بازه: سیستم بهترین توالی از ساعتهای متوالی را که مدت زمان مورد نیاز کاربر را پوشش دهد، شناسایی میکند. هر ساعتی که امتیاز آن زیر ۴۰ باشد، بهطور خودکار کل آن پنجره زمانی را از رده خارج میکند.
- منطق زمانی: بهترین پنجره هر روز پیش از تکرار روز انتخاب میشود. علاوه بر این، اگر خورشید غروب کرده باشد، درخواست برای «۳ روز آینده» از فردا شروع به شمارش میکند تا زمان فعلی هدر نرود.
حل مشکل توهم در مدلهای کوچک
استفاده از مدلهای کوچک با ۴ میلیارد پارامتر مثل gemma3:4b از طریق Ollama ریسک «اشتباه با اطمینان بالا» یا همان توهم (Hallucination) را در تحلیل اعداد افزایش میدهد. در تستهای اولیه، مدل زمانهای ISO را اشتباه میفهمید یا شاخص UV پایین ۰.۶ را «بالا» مینامید.
برای رفع این مشکل، توسعهدهنده از الگوی «دادههای پیشهضمشده» (Pre-digested payload) استفاده کرد. بهجای ارسال اعداد خام، جاوا رشتههای فرمتشدهای را میفرستد. سیستم دادهها را به ساختار JSON تبدیل میکند که شامل نام روز، زمانهای فرمتشده و برچسبهای توصیفی (مثل uvLevel: low یا comfort: hot) است.
با ارائه «دلایل» موفقیت یک بازه زمانی که قبلاً در جاوا محاسبه شده، پرامپت به Gemma دستور میدهد که صرفاً این دلایل را بازنویسی کند و هیچ نتیجهگیری مستقلی نگیرد. امتیاز عددی را عمداً از پرامپت حذف کردند چون مدل تمایل داشت آن را عیناً تکرار کند. همچنین از لیستهای رتبهبندی (مثل رتبه ۱، رتبه ۲) پرهیز شد چون مدل مکرراً ترتیب را جابهجا میکرد یا پنجره اشتباهی را تحسین میکرد.
حفاظها و اعتبارسنجی
برای اینکه هوش مصنوعی جزئیاتی را اختراع نکند، یک حلقه اعتبارسنجی سختگیرانه طراحی شده است. این متدولوژی مشابه ترکیب Gemma 3 و سیستمهای اعتبارسنجی برای ساخت راهنمای میدانی آفلاین است که در آن دقت دادهها بر تولید متن اولویت دارد. پرامپت صراحتاً مدل را از خطاهای رایج مشاهده شده در تستها منع میکند؛ مواردی مثل اختراع یک ساحل یا پارک، گفتن کلمه «امروز» برای پنجرهای که دو روز بعد است، یا توصیف دمای ۳۳ درجه بعدازظهر بهعنوان «دلپذیر».
- مکانیزم تلاش مجدد: جاوا پاسخ را پیش از نمایش میخواند. اگر پاسخ حاوی نام فیلدها باشد، ایموجی 🌿 در آن نباشد یا مکانی اختراعی در آن ذکر شده باشد، سیستم آن را رد میکند. Gemma یک فرصت دیگر با ذکر دقیق اشتباه دریافت میکند که معمولاً روی یک لپتاپ محلی ۲ تا ۴ ثانیه زمان میبرد.
- سیستم جایگزین (Fallback): اگر تلاش دوم شکست بخورد، یا اگر Ollama آفلاین باشد یا با تایماوت ۳۰ ثانیهای مواجه شود، یک قالب متنی سختافزاری (Hard-coded) متن را مینویسد. سپس رابط کاربری این متن را بهعنوان «قالب» برچسب میزند تا کاربر بداند این متن توسط AI تولید نشده است.
- تستها: بخش بکاند توسط ۱۱۸ تست JUnit پشتیبانی میشود، از جمله یک Clock تزریقشده (Injected Clock) تا اطمینان حاصل شود منطقهایی مثل «حذف ساعتهایی که گذشتند» کاملاً قابل تست هستند.
استک تکنولوژی
این برنامه برای قابلیت جابهجایی حداکثری و هزینه صفر طراحی شده است. فرانتاند از React 19، TypeScript، Vite، TanStack Query و Tailwind 4 استفاده میکند و از shadcn/ui روی Base UI بهره میبرد.
در بخش بکاند موارد زیر به کار رفته است:
- Spring AI 2.0 با استارتر Ollama.
- Clean Architecture برای اینکه هسته اصلی برنامه مستقل از فریمورکها باقی بماند.
- نسخهبندی API از طریق Spring Framework 7.
- Caffeine caches برای بهینهسازی عملکرد.
به دلیل استفاده از وزنهای باز (Open Weights)، کاربر میتواند بهسادگی مدل را با تغییر یک متغیر محیطی به OLLAMA_MODEL=gemma3:12b ارتقا دهد تا توضیحات با کیفیتتری دریافت کند، بدون اینکه منطق اصلی برنامه تغییر کند.
اهمیت نوآوری باز
این رویکرد نقش هوش مصنوعی را از «تصمیمگیرنده» به «مترجم» تغییر میدهد. با تبدیل LLM به یک رابط دوستانه برای یک موتور قطعی، Janela به پایداریای میرسد که با پرامپتنویسی ساده ممکن نیست.
نکته حیاتی این است که برنامه کاملاً روی لپتاپ اجرا میشود. هیچ کلید API، حساب کاربری یا هزینهای در کار نیست. این یعنی دادههای حساس — اینکه شما کجا زندگی میکنید و چه زمانی خانه را ترک میکنید — هرگز از دستگاه خارج نمیشود. اگرچه درخواست پیشبینی به Open-Meteo مختصات را ارسال میکند، اما هیچ پروفایل کاربری به آن پیوست نمیشود.
با بهرهگیری از وزنهای باز، اپلیکیشن به قیمتگذاری یا برنامه توقف پشتیبانی هیچ فروشندهای وابسته نیست. برنامه حتی بدون AI نیز کاربردی میماند؛ خاموش کردن مدل باعث از دست رفتن «جملات زیبا» و چالشهای «Touch Grass» میشود، اما پنجره زمانی واقعی همچنان دقیق باقی میماند.
اگر در حال ساخت ابزارهای AI محلی هستید، الگوی «پیشهضم کردن دادهها» را بررسی کنید تا ببینید چگونه محدود کردن دامنه مدل میتواند توهمات را در برنامههای دادهمحور حذف کند.
گام بعدی شما
- اگر از Ollama استفاده میکنید، مدل Gemma 3 را نصب کنید و سعی کنید دادههای عددی را پیش از ارسال به مدل، به برچسبهای توصیفی تبدیل کنید.
- معماری Clean Architecture را برای جداسازی منطق ریاضی از لایه تولید متن بررسی کنید.
- برای کاهش توهمات، از مکانیزمهای Retry (تلاش مجدد) در بکاند استفاده کنید تا خروجیهای مدل را اعتبارسنجی کنید.
اما داستان سختافزاری اجرای مدلهای محلی حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای NPU در لپتاپهای جدید مراجعه کنید.




گفتگو