Every generic AI chatbot answers the same question the same way: "What should I do?" You paste in a hard decision, it gives you a confident paragraph, and you're left trusting a black box that sounds sure of itself whether it has good reason to be or not.
We kept noticing that the actual hard part of a decision was never "what's the answer" — it was what am I not seeing. Hidden costs, opportunity costs, assumptions we hadn't questioned, risks we'd half-noticed and moved past. A chatbot can talk about those things, but the conversation is unstructured and impossible to compare option-by-option, and there's no way to ask "okay, but how much does this depend on me being right about X?"
So the founding question became: what if an AI's job wasn't to answer the decision, but to structure it — turn a messy paragraph into options, weighted criteria, risks, and assumptions you can actually interrogate — and then get out of the way and let deterministic math do the comparing?
What it does
You describe a real decision in plain language — "buy a $1,200 laptop or keep my current one for two years", "take the job offer or stay put", anything. DecisionLens then:
Parses it into a structured model — options, criteria, known facts, unknowns, assumptions, risks — without inventing anything you didn't say or imply. Asks a few adaptive questions, not a giant form, to fill in whatever's most likely to change the analysis. Scores every option against every criterion, weighted, using a deterministic engine — the AI proposes the qualitative inputs, but it never computes the final number itself. Surfaces risks per option with probability × impact → severity, plus mitigations and opportunity costs. Lets you simulate "what if" — drag a criterion's weight up or down and watch every score recompute live. Disagree with a rating the AI gave? Edit it directly and recalculate. Stress-tests the result — a breakeven analysis that answers "how far off would I have to be about this criterion before my top choice flips?" and flags which ones are fragile. Generates a Decision Report — the whole analysis distilled into one readable, printable page. Journals the outcome — months later, record what actually happened and see the gap between the predicted score and how it really went.
Every single value on screen — from a fact you typed to a risk the AI proposed to a number the engine calculated — carries a small provenance tag, because the whole premise of the product falls apart the moment it starts presenting an assumption as a fact.
How we built it
Backend — FastAPI + SQLite. A deliberately boring, heavily-tested deterministic engine (weighted scoring, risk severity derivation, breakeven/sensitivity analysis) that has zero AI dependency and zero randomness — same inputs always produce the same outputs. Sitting next to it, an AI layer that talks to the Anthropic API, but only ever to propose qualitative inputs (criteria names, 0–10 ratings, risk probability/impact) — never a final score. Every AI response is parsed into a strict Pydantic schema; anything malformed automatically falls back to deterministic demo data rather than surfacing a silent bad result.
Frontend — React + Vite + Tailwind. A left-hand rail that mirrors the actual sequence of one decision — Structure → Compare → Simulate → Stress Test → Report — because the product is that loop, not a generic dashboard. The visual system centers on four provenance colors (fact / assumption / calculated / uncertain) applied consistently everywhere a value appears, which turned into the project's real signature element: the "don't act like an oracle" philosophy made into a literal, reusable UI component instead of a paragraph of disclaimer text.
Design principle we held to throughout: AI reasoning and deterministic calculation never touch. The AI layer can be swapped, degraded, or entirely absent (no API key → automatic, clearly-labeled demo mode) and the product still works end-to-end, because the math never depended on it being right.
Challenges we ran into Keeping the AI honest without a human in the loop. It's easy to ask an LLM for a weighted score directly — it's much harder to force it to only ever hand over raw ingredients (ratings, weights, risk levels) and make a separate, boring, testable engine do the arithmetic. We had to be strict about never letting a prompt ask for a number that mattered. Demo mode silently lying to itself. Early on, the offline fallback for "analyze this decision" used one hardcoded example (a laptop purchase) regardless of what the user actually typed — so a decision about anything else came back with mismatched options and zeroed-out scores. Caught it by actually running the full flow end-to-end against a live server instead of trusting the code by inspection, and rebuilt the fallback to generate options-and-criteria-aware mock data for any decision. Finding what "acting as an oracle" quietly sneaks back in as. A weighted score with a decimal point feels objective even when you've labeled it "calculated." The Stress Test and the editable-ratings table both exist specifically to undercut that false confidence — showing exactly how fragile a "winning" option is, and letting the person overrule a rating they think the AI got wrong. Sensitivity analysis is deceptively fiddly. A naive breakeven search has to renormalize every other criterion's weight proportionally while scanning one criterion from 0→1, or the numbers quietly stop meaning anything. Got this wrong once, wrote a test around a case designed to catch it, and fixed it before it shipped. Accomplishments that we're proud of A deterministic engine with full test coverage that a judge — or a future contributor — can trust without reading a single AI prompt. A demo mode good enough that the whole product is explorable in one click, with zero setup and zero API key, and never pretends the mock output is real. A UI where the core philosophy isn't a line in the README — it's a color you see on every number, every time. What we learned
That "don't act like an oracle" is a genuinely hard design constraint to hold onto — it's much easier to build a slightly-fancier chatbot than to build something that keeps reminding the user, gently and constantly, that it doesn't have the answer. The moments we're most proud of in this build are the ones where we caught ourselves quietly sliding toward false confidence and pulled back: separating AI output from computed scores, building the Stress Test, tagging every value with where it came from.
Built With
- anthropic
- css3
- fastapi
- grotesk
- html5
- javascript
- json
- node.js
- pydantic
- pytest
- python
- react
- rest
- router
- sqlalchemy
- sqlite
- tailwindcss
- uvicorn
- vite
Log in or sign up for Devpost to join the conversation.