Inspiration
Every morning, thousands of Michiganders drive the same roads, alone β Flint to Ann Arbor, Novi to Detroit, everyone to DTW. Michigan is built around the car: transit between cities is thin, commutes are long, and Uber is far too expensive to use every day. Renting a truck to move is expensive alone too.
The frustrating part is that the person going your way almost always exists β you just have no trusted way to find them. We wanted one place where you can find a ride, offer your empty seats, split a cab, or share a rental car, and where the matching is smart enough to only show people who genuinely make sense.
Our one-line pitch became: Not Uber. Not U-Haul. Better.
What it does
- Say it in plain English. "Grand Blanc to Ann Arbor by 9 every weekday" β a Gemini-powered Trip Assistant turns that sentence into a full journey: places, arrive-by vs. leave-at, commute vs. one-time, seats, vehicle, even preferences like "women only" or "I don't drive".
- Find a ride β or split a cab. Same trip, one tap to switch.
- Offer a ride. Drivers see riders along their route, ranked by how little detour they add.
- Share a rental. Real rental counters near your pickup and drop-off (Google Places), vehicles chosen by cargo space, and a "I need someone to drive" option.
- Two-ride trips. If nobody drives your whole route, Along chains two drivers and picks a safe, public handoff spot.
- Post a request. Searches are private by default; post one and get a π notification the moment someone fitting posts.
- Trust built in. Anonymous handles, identity revealed only by mutual consent, age & gender preferences matched both ways, share-my-trip, report, block, and editable anonymous ratings.
How we built it
Along is written in Jac β about 84% of the codebase β for both the backend and the React-based frontend (.cl.jac client components). Data lives in MongoDB Atlas; maps, routes and places come from the Google Maps Platform; language understanding comes from Gemini.
An agentic architecture on a graph
Every journey in Michigan is a node in one shared graph. Each agent is a walker β a small program that travels the graph with one job β and they run as a pipeline:
| Agent | Job |
|---|---|
| Trip Assistant (Gemini) | Turns a sentence into a structured journey, with a rule-based fallback |
| Route Scout | Walks every posted journey; keeps only people genuinely heading your way |
| Schedule Agent | Scores timing from your point of view |
| Trust Agent | Weighs ratings, reviews and preferences |
| Cost Agent | Estimates what each match saves |
| Coordinator | Combines everything into one ranking β and learns from real choices |
Two helpers extend the pipeline: the Relay Agent builds two-ride trips (Gemini chooses the handoff spot from real nearby places), and the Matchmaker notifies people when a newly posted journey fits theirs.
Realistic data
We generated ~370 journeys across 20 Michigan cities β commutes to real employers (GM, Ford, Stellantis, Michigan Medicineβ¦), airport and train-station cab shares, moving-day truck rentals and weekend road trips β with realistic departure windows (commutes 7β9 AM and 4β6 PM, airports all day), so every search has something meaningful to find.
Challenges we ran into
- Relevance. Our first cab search showed a "#1 match" going the opposite direction. The fix was a shift in philosophy: hard gates first (direction, detour, time, preferences both ways), scores second.
- Timing that makes sense. "Arrive by 9" and "leave at 8:20" are the same trip. Comparing departure times naively produced a 62% match for a driver who would get you there perfectly on time. We rebuilt timing around the moments that matter: when the driver reaches your pickup, and whether you arrive before your deadline.
- Speed. Two-ride search originally fetched Google road routes for every driver on every search (~20 s, plus rate limits). A cheap straight-line pre-filter and "only look for two rides when no direct ride is good" brought typical searches to 2β4 seconds.
- LLM reliability. Our first Gemini model was frequently overloaded and timed out. We added model fallback, shorter timeouts, keyword signals that override uncertain guesses, and a full rule-based parser β so the assistant degrades gracefully instead of failing.
- Privacy in two-ride trips. The second driver must never see anything about the first; only the rider sees both. Getting per-leg visibility right across chat, notifications and share links took careful design.
- Deployment. Our first host ran out of memory; our second exposed a version mismatch between the platform's Jac runtime and a published plugin. We learned to keep hard dependencies minimal and import optional ones lazily.
What we learned
- Modeling the problem as a graph with walkers made the agentic design natural: each agent is small, testable and has one responsibility, and adding a new one (Relay, Matchmaker) didn't disturb the others.
- LLMs are best at the edges β understanding messy language, choosing a sensible meeting place β while deterministic, explainable scoring should decide who you ride with.
- Trust is a feature, not a policy. Anonymous-by-default chat, mutual reveal and two-way preferences shaped nearly every screen.
- Small details β "a bit early beats a bit late", "two non-drivers can't share a car" β matter more to users than a fancier model.
What's next
- Real ID and email verification (currently marked coming soon).
- In-app cost splitting and payments for shared rides and rentals.
- A pilot on one commuter corridor β Flint β Ann Arbor β with a university or employer.
- Native mobile builds and live trip tracking.
Along β Michigan, moving together.
Built With
- ai-agents
- css
- fastapi
- gemini
- github
- google-gemini
- google-geocoding-api
- google-maps
- google-places
- google-routes-api
- jac
- jac-client
- jac-scale
- jachammer
- jaseci
- javascript
- llm
- mongodb
- mongodb-atlas
- python
- react
- vite
Log in or sign up for Devpost to join the conversation.