How I Built a Carbon Footprint Tracker with Django + NVIDIA NIM A developer built Carbon.Ledger, a full-stack Django web app that logs user activities, computes CO₂ impact using database-stored emission factors, and provides AI-powered reduction tips via NVIDIA NIM's Mistral Large model. The app features a hallucination guard that checks LLM-generated numbers against provided context to prevent misinformation, and uses htmx for dynamic dropdowns without custom JavaScript. Deployed on Render, the project highlights the importance of separating LLM text generation from data calculations. I wanted to build something that mattered. Climate change is one of those topics where awareness is the first barrier — most people don't know their actual footprint. So I built Carbon.Ledger : a full-stack web app that lets you log activities, see your CO₂ impact, and get AI-powered tips to cut back. Here's how I built it, what went wrong, and the one engineering decision I'm most proud of. mistralai/mistral-large-3-675b-instruct-2512 The app is built around one simple loop: Understand → Track → Reduce Users can read lesson articles, browse a glossary CO₂e, Scope 1/2/3, Net Zero , and ask free-text climate questions via an LLM-powered Q&A — rate limited to 10 questions/day. An activity logging form lets users log transport, energy, food, and goods. CO₂ is auto-computed on save using emission factors stored in the database — no LLM involved here. The dashboard shows a 30-day breakdown with a Chart.js donut chart and progress against a monthly goal. Rule-based insights compare the user's totals against national average benchmarks. The top emission category drives filtered recommendations. And once per day, the LLM generates a personalized tip — cached 24h per user. This is the part I'm most proud of. LLMs make up numbers. That's a real problem when you're talking about emissions data — if the model says "beef produces 5 kg CO₂ per kg" when the real figure is 27, that's actively harmful misinformation. My solution in services/llm.py : php def contains hallucinated numbers response: str, context: str - bool: """ Extract all numbers from the LLM response. Check every one of them exists in the context we provided. If not → hallucination detected. """ import re response numbers = set re.findall r'\d+\.?\d ', response context numbers = set re.findall r'\d+\.?\d ', context return not response numbers.issubset context numbers The flow: timeout=10.0 and max retries=1 are explicitly set to prevent hung Gunicorn worker threads on slow LLM responses. Key principle: the LLM is never used for calculations. All math is Python/DB. The activity log form has a dependent dropdown — selecting a category dynamically loads the relevant emission factors. I used htmx for this instead of writing custom JavaScript: