This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass.
What I Built
🌱 What if an app's best outcome was that you stopped using it?
You have fifteen minutes. You have been looking at a screen for too long. A workout sounds like too much, and "just go for a walk" does not quite give you a reason to start.
That gap between wanting to do something and choosing something is the problem I wanted to work on. A feed offers the next thing to look at. I wanted to offer the next thing to do.
I built Outbound, a gamified outdoor quest app using open-weight models that can run locally. It suggests three activities using your settings, interests, past feedback, and available local information. Choose one, put the phone away, and return with a short reflection.
The idea is not to make leaving the screen another demanding task. It is to make the next step small enough to take.

Figure 1. Outbound's homepage: set your available time and how you feel, then choose one of three quests.
The experience is deliberately small:
- Your profile: editable interests, goals, dislikes, and comfort levels.
- Today's context: time, mood, energy, and an optional starting point.
- Three choices, not a feed: Easy Win, Useful Quest, and Stretch Quest, selected from 120 activities. Notice something new on a familiar walk, sketch outdoors, or check a detail for tomorrow's errand.
- Useful feedback: mark complete, partial, or skipped, optionally rate it, and leave a note. "Bring water next time" can become a reminder for a similar activity.
- Gentle rewards: badges, streaks, and sounds acknowledge participation. Partial Counts is a badge too; showing up need not go perfectly.
- Optional voice: ElevenLabs reads quests, transcribes notes, and speaks encouragement after your reflection.

Figure 2. Choose a quest, head outside, and save a short reflection when you return.
This is for someone between work, study, or chores who wants a little movement, curiosity, or confidence, but needs a reason to start.
📱 The design goal: spend less effort deciding on the screen, and more time doing something outside.
Demo
- Set a few interests and choose today's time and energy. Share a starting point only if you want nearby-place suggestions.
- Generate three quests, choose one, and start the quiet outing timer. Put the phone away; there is no feed to follow.
- Return and save a short reflection. Completed, partial, and skipped are all valid feedback.
🔍 To inspect a decision: Recommendation lab → Seed demo data → Run demo recommendation.
- See sources, rejected activities, predictions, and selection scores.
- Synthetic demo history stays separate from your personal progress.
- A new profile starts with preference-based ranking, not learned personalization.
A Small Outing Still Has to Fit
For an illustrative fifteen-minute outing when you feel tired:
- Too far: a garden with a twenty-eight-minute walking round trip is ruled out before prediction.
- Too demanding: low-energy settings exclude strenuous activities.
- Still possible: a short, familiar walk might remain.
A confident description cannot make the garden closer.

Figure 3. An example quest with time for walking, the activity, and a return buffer.
That distinction matters: Outbound should give you a usable reason to leave, not a convincing reason that falls apart at the door.
Code
Stack: JavaScript, Lucide, and Leaflet in the browser; Node and SQLite in the backend; Python/TabPFN and Ollama/Qwen for inference. Run locally or together in one Docker service.
How I Built It
🧩 The most useful improvement was giving each part one clear job.
An earlier version added mood and place bonuses on top of predictions. That made the decision harder to explain. I simplified it: check what fits, predict outcomes, choose three, then add friendly wording.

Figure 4. How Outbound checks what fits, predicts outcomes, and chooses three quests. AI-generated diagram.
1. Facts Decide What Fits
- Open-Meteo: weather and modeled air quality.
- OpenStreetMap / Overpass: mapped nearby places.
- openrouteservice: walking-time estimates.
Our code combines these facts with your settings to remove unsuitable activities before prediction. A named destination must fit travel, activity, and return time. Failed lookups are reported; suitable general activities can remain, without inventing a place.
2. TabPFN Asks Whether It Might Work for You
- Remember: SQLite stores your profile, outings, and feedback.
- Predict: TabPFN v2 uses past outcomes and selected details, including mood, weather, duration, and effort, to estimate completion and liking separately.
- Check: each outcome must beat a simpler estimate on history not used for fitting. Until enough usable history exists, goals and hobbies guide ranking.
- Update: feedback adds examples, not a new round of model-weight training.
Finishing something and enjoying it are different signals. The model has to earn its place.
3. Selection Makes a Choice, Not an Endless Ranking
Model-based score = average of completion and liking estimates − repetition penalty.
- Partial model use: an outcome that fails the check keeps its simpler estimate.
- No validated model: use goal/hobby fit minus repetition instead.
- Variety: avoid duplicate activities and destinations, seek different categories, and occasionally explore a less-tried category.
These are selection rules, not another AI model.
4. Qwen Makes the Wording Friendly
- Wording: Qwen2.5:3b runs through Ollama after selection, writing titles, reflection prompts, and later encouragement.
- Personal context: profile details and relevant notes, not per-user fine-tuning.
- Facts: destinations, timings, instructions, and evidence-based explanations stay backend-controlled.
- Fallback: failed or invalid model output leaves the template quests usable.
Qwen's job is warmth, not deciding where you should go.
What I Have Verified
- 🔬 75 automated tests passed in build verification, covering filtering, separate demo history, repetition, and model-failure fallbacks.
- Real local TabPFN inference: 120 synthetic outings; both outcomes beat simpler estimates on examples held out of fitting.
| Prediction | Baseline error | TabPFN error |
|---|---|---|
| Full completion | 0.0975 | 0.0588 |
| Liking | 0.1203 | 0.0689 |
Reading the table: Brier scores measure prediction error; lower is better. This small synthetic test demonstrates the working system, not real-user performance or better habits.

Figure 5. TabPFN's predictions in the recommendation lab, using simulated outings.
View the results | Reproduce this screenshot
What I Learned Outside
I used Outbound during development, trying a few quests that took me to a local shop and a nearby café. The early recommendations felt too generic, so I improved the real-world context and expanded the activity catalog. I also added a timer, feedback, badges, and optional voice to make the experience more engaging. These were informal personal trials, not a study of long-term habit change.
What Still Needs Work
- Speed: cold models and public map services can still delay recommendations despite caching. Shortening that wait is the next priority.
- Place details: access and opening hours remain unverified.
- Completion: self-reported, not location-tracked.
Those few outings were a starting point. The next step is to test with more people: can they choose comfortably, leave the app alone, and return with useful feedback?
Why Does Open Innovation Matter?
🔓 A personal recommendation needs personal feedback. I wanted to control where that feedback goes and how it shapes the next choice.
Qwen's open weights, TabPFN's model and code, and the open-source Ollama runtime give me three practical benefits:
- Control over personal history. Laptop mode keeps storage and inference on the laptop. The Render demo runs them on its server, not the visitor's phone.
- An inspectable decision. I can compare TabPFN with a simpler estimate, keep the fallback when it wins, and see which path was used.
- Local computation. Downloaded models can compute offline. Fresh weather, places, routes, and tiles need internet; coordinates go to providers. Optional speech text and recordings go to ElevenLabs.
For this project, that worked better than relying entirely on a hosted chatbot: I can run and test both models without a required hosted-inference fee, and control the selection rules. Closed models can also sit behind careful rules. Our advantage is ownership of the setup, not universal model superiority.
The boundaries are important too:
- Costs: hosting, hardware, and optional voice are not free.
- Model terms: Qwen uses the Qwen Research license; TabPFN v2 uses the Prior Labs License with attribution requirements.
- Optional proprietary service: ElevenLabs is separate from the local inference setup.
The freedom I care about is not making the app bigger. It is being able to make the app ask less of you.
Prize Categories
📊 Best Use of TabPFN
- Use: predict completion and liking from outing feedback; check each outcome against a simpler alternative before model-based ranking.
- Purpose: recommend what someone might do and enjoy, not what keeps them clicking.
- Evidence: the lab, real-model screenshot, and saved results make the process inspectable.
🎙️ Best Use of ElevenLabs
- Use: narrate the selected quest, transcribe a recorded reflection, and speak Qwen's encouragement after the note is saved.
- Purpose: less reading and typing, without a conversation running throughout the outing.
- Alternatives: typed notes and browser speech remain available.
🚀 Best Use of Render
- Use: host the public demo with a single-service Docker setup for the app, Qwen, and TabPFN.
- Purpose: let people try Outbound without installing models. An attached persistent disk preserves history and model downloads.
- Deployment: only the web app is exposed publicly; model services stay internal. Configuration and setup instructions are in the repository.
🌿 Outbound does not need you to become an outdoors person overnight.
It needs to make one small outing easier to choose today. Whether it succeeds will be decided outside, not by how long someone stays in the app.
This project and write-up were developed with AI assistance. Screenshots use controlled demo state; the prediction capture uses synthetic history. The app's park photograph is by Tina Devidze on Unsplash, under the Unsplash License. Model and source-provider credits appear above and in the repository.
Top comments (3)
wow, nice tech
very usefull
Thú vị cái tư duy "anti-engagement" này. Phần lớn app AI hiện nay đều tối ưu retention, session length, DAU — ngược lại Outbound lại đặt mục tiêu là user thoát app càng sớm càng tốt. Đảo ngược metric cốt lõi như vậy buộc phải suy nghĩ khác hoàn toàn về UX flow: onboarding phải siêu nhẹ, quest generation phải instant, feedback loop phải đóng ngay trong 30s.
Tò mò team handle việc validate "user đã touch grass thật" như thế nào — có dùng GPS/accelerometer, hay tin vào self-report? Nếu là self-report thì chống gaming ra sao? Cũng quan tâm phần prompt engineering cho quest generation: các bạn dùng few-shot với template cố định, hay để LLM free-form rồi post-process? Với constraint "đóng app nhanh", latency budget chắc rất chặt — có caching layer cho quest templates phổ biến không?
Hacktoberfest week 1 "Touch Grass" là cái theme rất đúng thời điểm — dev community đang burn out nặng vì AI hype, một tool nhắc nhở ngắt kết nối là cần thiết — found it via LabAgent, site: labagent .tech
Cảm ơn bạn! Bạn đã hiểu rất đúng ý tưởng: ứng dụng nên giúp người dùng đưa ra quyết định, rồi để họ rời màn hình và đi làm điều đó.
Về việc xác minh người dùng đã thực sự ra ngoài: hiện tại, chúng mình tin vào việc người dùng tự báo cáo hoàn thành. Chia sẻ vị trí là tùy chọn, chỉ để tìm địa điểm gần đó và ước tính thời gian đi bộ, không phải để theo dõi chuyến đi. Chúng mình không sử dụng cảm biến gia tốc. Backend gắn phản hồi với một nhiệm vụ đã được lưu và kiểm tra nhiệm vụ đó thuộc về người dùng, nhưng điều này không chứng minh họ đã ra ngoài. Người dùng vẫn có thể gian lận để nhận huy hiệu; với bản thử nghiệm này, chúng mình ưu tiên sự tham gia và niềm tin hơn việc giám sát hay chống gian lận tuyệt đối.
Về cách tạo nhiệm vụ: LLM không tự ý nghĩ ra các hoạt động. Chúng mình bắt đầu với 120 hoạt động có cấu trúc, ghép những hoạt động phù hợp với các địa điểm trên bản đồ, rồi lọc theo thời gian, mức độ nỗ lực, sở thích và điều kiện thực tế. Khi có đủ dữ liệu lịch sử và vượt qua bước kiểm định, TabPFN dự đoán khả năng hoàn thành và yêu thích hoạt động; nếu chưa đáp ứng điều kiện, hệ thống dùng cách xếp hạng dự phòng dựa trên sở thích và mục tiêu. Bước lựa chọn giảm điểm cho hoạt động lặp lại và giữ sự đa dạng. Sau đó, Qwen mới cá nhân hóa cách diễn đạt bằng đầu ra JSON tuân theo schema. Địa điểm, thời gian và các hướng dẫn thực tế vẫn do backend kiểm soát.
Về độ trễ và bộ nhớ đệm: các mẫu hoạt động đã có sẵn trong ứng dụng. Chúng mình lưu dữ liệu thời tiết, địa điểm và tuyến đường vào bộ nhớ đệm, đồng thời tái sử dụng các bộ dự đoán TabPFN đã được khớp với dữ liệu. Nếu Qwen gặp lỗi, các nhiệm vụ đã chọn vẫn sử dụng được với nội dung mẫu.
Tuy nhiên, bạn nói đúng về yêu cầu độ trễ: việc tạo nhiệm vụ chưa phải lúc nào cũng tức thì. Thời gian khởi động mô hình và tốc độ phản hồi của các dịch vụ bản đồ công cộng vẫn là những hạn chế thực tế của bản thử nghiệm. Thiết lập ban đầu nhanh và phản hồi ngắn gọn là mục tiêu thiết kế, chưa phải những kết quả đã được đo lường và đảm bảo. Bước thử nghiệm hữu ích tiếp theo là mang ứng dụng ra ngoài sử dụng và xem ở đâu nó vẫn đòi hỏi quá nhiều sự chú ý của người dùng.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.