Inspiration
Long-distance cyclists regularly decide whether to keep riding or stop for water, food, rest or repairs. On an unfamiliar route, that decision involves checking the map, comparing detours and judging how the ride is going.
We wanted to bring that information together in a companion that offers relevant suggestions during the ride. Our focus is recreational and endurance cycling, including brevets: long-distance rides completed along a set route within a time limit.
What it does
Cycling Companion AI is a native iOS app that combines a planned route, current ride data and previous rides to suggest places to stop.
Riders import a GPX file, follow their progress on a map and choose which stop categories interest them: cafés, food shops, drinking water, shelters, toilets or bicycle repair.
The app can request a recommendation from NVIDIA Nemotron through Nebius Token Factory. The model receives current ride features, candidate stops and retrieved historical examples, then decides whether to suggest a stop and explains its recommendation.
Suggestions appear as cards and notifications. Riders can accept or decline them and open directions in Apple Maps. Local rules limit repeated suggestions and excessive detours. When the remote request fails or takes too long, a local advisor provides fallback recommendations using cached stops.
The current stop database covers the Netherlands. A personal web page provides access to stored rides, routes and account settings.
How we built it
The iOS app uses Swift, SwiftUI, MapKit and CoreLocation. It stores routes and rides locally, computes ride features on the phone and uses Keychain for session credentials.
Our Java 21 and Spring Boot backend runs in Docker on a Nebius VM, with PostgreSQL, pgvector and a Caddy HTTPS gateway. We import OpenStreetMap data from Geofabrik into our own stop database and query it for places near each route.
The backend uses NVIDIA Nemotron 3.5 Lightning through Nebius Token Factory to evaluate the rider’s current situation and return a structured stop recommendation in JSON. To provide historical context, we use Qwen3-Embedding-8B, also through Token Factory, with pgvector to retrieve relevant past ride summaries and feature snapshots. The retrieved context is included in the request to Nemotron
An admin interface exposes request inputs, retrieved context, model responses and linked rider feedback, helping us inspect how the system behaves.
Challenges we ran into
The biggest challenge was connecting AI reasoning to reliable ride data within an interactive time budget.
Outdoor testing produced successful model responses, but frequent timeouts caused the app to fall back to local recommendations. We also discovered that returning to the start could make route progress appear as an almost-zero completed distance.
Other findings included duplicate uploads, repeated or unsuitable historical examples, and messages that confused distance along the route with the detour needed to reach a stop. These remain important prototype limitations and guide our next corrections.
Accomplishments that we're proud of
We built and deployed a complete prototype spanning an iPhone app, authenticated backend, stop-data pipeline, personal web page and admin tools.
We tested it on a physical iPhone during a real outdoor ride, recorded actual NVIDIA model responses through Nebius Token Factory and saved users’ reactions to suggestions.
The trace system made the results inspectable. It helped us distinguish successful model calls, local fallback advice and recommendations that actually reached the rider.
What we learned
Useful personalization requires trustworthy history. Retrieving similar records does not automatically mean they provide useful context.
We also learned that a valid model response can arrive too late or describe a location ambiguously. Data quality, recommendation quality and delivery speed need separate evaluation.
Field testing exposed issues that a successful API call or polished screenshot could not reveal.
What's next for Cycling Companion AI
Our immediate priorities are to:
- Separate accumulated travel distance from position along the planned route.
- Prevent repeated uploads from creating duplicate rides.
- Filter unsuitable and repeated historical examples.
- Reduce latency and verify that remote recommendations reach the phone within its deadline.
- Generate clear distance labels directly from application data.
After these corrections, we will repeat outdoor testing and evaluate whether the suggestions help cyclists choose useful stops. We also plan to expand geographic coverage and make the distinction between AI recommendations and local fallback advice clearer.
Built With
- ai
- boot
- caddy
- cloud
- core-location
- docker
- embedding
- factory
- geofabrik
- ios
- java
- mapkit
- nebius
- nemotron
- nvidia
- openstreetmap
- pgvector
- postgresql
- qwen3
- spring
- swift
- swiftui
- token
Log in or sign up for Devpost to join the conversation.