Picnix: Your Verified Weekend Trip Planner
nvm the rick roll, i couldn't get the video done :) but the project is cool, I promise - use it at picnix.aswinpradeepc.com
Inspiration
I'm a dev working away from home in Kochi. Every Friday, the same ritual: someone in the flat asks "so… anywhere this weekend?" and we all open forty browser tabs. Half the places are closed Sundays. A third are too far for a day trip. The "hidden gem" from a 2019 blog post is permanently shut. By the time anyone has a plan, it's Saturday afternoon and we're ordering biryani in.
I tried asking a chatbot once. It confidently invented a waterfall and told me a 3-hour drive took 45 minutes. That was the moment: I didn't need an AI that talks about trips. I needed one that builds them — and proves its work.
What it does
Picnix turns one short conversation into a verified, mapped, minute-by-minute day trip. It extracts your constraints (max 3 questions), computes the area you can actually reach, pulls live Google Places candidates, and validates every single one against real opening hours, closure flags, and actual Routes API travel times — you're never shown a place the agent can't prove you can visit.
You pick 1–3 stops from a validated gallery (human-in-the-loop, always), and it builds a multi-waypoint round trip with real ETAs, reasoned dwell times, and food planned along your actual route geometry. Want a change? Say "swap the beach for the museum and leave at 9" — it re-plans through the same validation gauntlet. One tap exports to Google Maps for turn-by-turn.
And because agents fail in interesting ways, Picnix ships a second agent: the Trip Auditor, built on the Arize Phoenix MCP server, that answers "why did my plan drop a destination?" by reading the planner's own traces.
How I built it
- Core Architecture: An 8-node LangGraph state machine powered by Gemini 3.1 Pro (reasoning: intent, routing, validation, editing) and Gemini 2.5 Flash (prose) on Vertex AI.
- Ground Truth Layer: Google Maps Platform (Places, Routes, Geocoding).
- Observability: Every node, LLM call, and tool invocation streams to a self-hosted Arize Phoenix collector via OpenInference auto-instrumentation.
- Storage: PostgreSQL backs both user accounts and LangGraph checkpoints, so interrupted plans survive restarts.
- Deployment: The whole stack — app, Phoenix, Postgres — deploys to a GCP Compute Engine VM with one
docker compose up. - Engineering Quality: 175 tests, 13 ADRs.
Challenges I ran into
- Hallucination doesn't die quietly: My first composer invented place names. The fix became the architecture: validate the structured plan before prose exists (Python checks + a Gemini semantic pass), then force the composer to emit a claim audit — every sentence traced to a verified data field, unverified claims stripped. I even swapped two graph nodes mid-build (ADR-006) to make validation come first.
- Privacy for a trace-reading agent: Phoenix API keys grant org-wide access, and traces contain user locations and chats. Prompt-level "please only look at your own data" isn't security. So I made the tool surface the boundary: regular users get exactly two database-validated tools scoped server-side to their own trips via
session.idspan attributes. Prompt injection can't widen a toolset that was never there. - Production papercuts: Gemini 3.1 Pro is global-endpoint-only; JSON mode without a response schema lets keys drift; quota spikes needed centralized retry/backoff. Each one is now an ADR.
Accomplishments that I'm proud of
- An agent that refuses to lie — the claim-audit pipeline means hallucinations structurally can't reach the user.
- An agent that audits the agent — real MCP integration, not a dashboard screenshot.
- Per-user trace scoping that treats security as architecture.
- A genuinely shippable product: auth, email verification, durable checkpoints, one-command deploy — built solo, with every architectural decision documented.
What I learned
- Observability isn't an afterthought: Phoenix traces found my bugs before users did, and then became a feature.
- Human-in-the-loop is a design principle, not a checkbox: The graph never silently swaps a destination.
- The best guardrail against hallucination isn't a better prompt: It's a pipeline where unverified facts have nowhere to go.
What's next for Picnix
- Multi-day trip planning (the graph already routes around it).
- User-driven stop removal and edit-time place additions.
- Arize AX for production monitoring at scale.
- Traffic-aware re-planning.
- WhatsApp itinerary sharing — because the group chat is where every Kochi weekend actually starts.
Built With
- arize-phoenix
- docker-compose
- gemini
- google-compute-engine
- google-maps
- google-places
- google-routes-api
- langchain
- langgraph
- mapbox
- mcp
- node.js
- openinference
- opentelemetry
- postgresql
- pydeck
- pytest
- python
- resend
- streamlit
- uv
- vertex-ai
Log in or sign up for Devpost to join the conversation.