Inspiration
Guest reviews pile up faster than any hotel GM can read them. Most skim the latest few and miss the pattern: check-in queues getting longer, an elevator that keeps breaking, a cleanliness complaint repeating week after week.
Night Audit does that reading overnight. The GM gets one page in the morning: the three things to fix, what's causing each, and the evidence.
What it does
Upload a hotel's recent reviews (or use the built-in sample) and Night Audit produces a newspaper-style morning briefing:
- Issues ranked by impact, each framed as "X is happening, caused by Y, here's the evidence", with the quotes and a trend chart.
- Outside context: for each issue the agent searches the web (Tavily) for external causes such as local events, construction or news around the spike dates. If it finds nothing, it says so instead of inventing a cause.
- Draft replies to affected guests. Anything the model can't know is marked
[GM to confirm: …]so nothing false gets sent. - Under the Hood tab: the pipeline, the model routing, and a per-run cost ledger.
How I built it
Each step uses the Nemotron model that fits it, all through Nebius Token Factory:
- Extract (Nemotron 3 Super, thinking off): tags every review by aspect, sentiment and severity, 10 at a time in parallel.
- Count and trend (pandas): the numbers are computed in code, not by the model.
- Trends (Super, thinking on): picks out what is rising or falling.
- Investigate (Nemotron 3 Ultra, thinking on): uses native tool calling and Tavily, with at most 4 searches per issue.
- Replies (Nemotron 3.5 Lightning): cheap, fast drafts with the guardrails above.
Routing the work this way costs far less than sending everything to the largest model. On a 20-review check, all-Ultra would have cost about $2.18 against $0.32 routed. That all-Ultra figure is extrapolated from the 20 reviews, not measured on a full run.
The stack is FastAPI with server-sent events, a React/Vite/TypeScript front end, Docker on Render, and optional Upstash Redis for a shared spend counter.
Challenges
- Knowing if it's right. I hand-labelled 30 real reviews and compared model choices against them. The pre-set rule picked a different model than the one I shipped, and I ship the cheaper one and explain the deviation in the README. Accuracy is clearly better on my synthetic data than on real reviews, and I say so in the README rather than hide it.
- Information overload. Early versions threw everything at the reader. Feedback said it was too much, so I rebuilt the UI around one sentence per issue with the evidence beneath it, and moved the cost and model details to a separate tab.
- Keeping a free demo safe. Live mode has per-IP and global run limits, an upload cap of 150 reviews and a shared spending cap of $5 in total.
What I learned
Code should count and the model should explain. Letting the model judge severity and cause while pandas does the counting made the briefing both cheaper and more trustworthy. I also learned to treat "no evidence found" as a valid result.
What's next
I plan to pilot it with a real hotel's own review export. Other planned work is limiting what hotel-specific text goes into Tavily queries and requiring a minimum amount of evidence before a cited page counts.
Honest notes
The demo data is synthetic (a fictional hotel, "Hotel Wrenfield"). Evaluation labels come from a single labeller on 30 reviews. Full results and limitations are in the README. The code was written with AI coding assistance (Claude Code).
Live demo: https://night-audit.onrender.com · Video: https://youtu.be/6Orv3PRVxTY· Code (MIT): https://github.com/raaghavdhiman/Night_Audit
Log in or sign up for Devpost to join the conversation.