My friend's notes were scattered across a dozen files, so I built him a private search-and-answer tool A developer built NotesBuddy, a single-file Python study assistant that lets users drop .txt/.md notes into a folder and ask questions in plain language, returning short answers with citations to the exact source passage. The tool uses BM25 retrieval with Gemma 3 running locally via Ollama for generation, and is designed to state plainly when the notes don't contain an answer rather than guessing. The developer's friend Alekh, for whom it was built, said the cited passages and honest "not in your notes" responses were the most useful features. This is a submission for the Hacktoberfest Weekend Challenge: Build for a Friend https://dev.to/challenges/hacktoberfest-weekend-2026-10-01 NotesBuddy is a study assistant I built for my friend Alekh . His problem was simple: his notes were scattered across many different files, and finding one small concept took forever. NotesBuddy fixes that. You drop your notes into a folder, ask a question in plain language, and get a short answer along with the exact passage of your notes it came from. If the notes don't contain the answer, it says so instead of guessing. A study tool that confidently makes things up is worse than no tool at all, so that behavior was non-negotiable. Live demo: https://notebuddy-lnka.onrender.com/ https://notebuddy-lnka.onrender.com/ This hosted version is a retrieval-only demo on sample notes , because the free hosting tier can't run an LLM. It shows the real search and the cited passages. The full version, with Gemma generating the answers, runs locally. The free tier sleeps when idle, so the first load can take up to a minute. Run the full version yourself: git clone https://github.com/KunalKushwaha1806/NoteBuddy cd NoteBuddy ollama pull gemma3:4b python notesbuddy.py serve then open http://localhost:8000 Put your own .txt / .md notes in ./notes first. https://github.com/KunalKushwaha1806/NoteBuddy https://github.com/KunalKushwaha1806/NoteBuddy The whole project is a single Python file with no dependencies beyond the standard library. operating-systems.md 1 . file n , and say plainly when the notes don't cover the question. The heart of it is one function: python def ask llm question, hits : ctx = "\n\n".join f" {l} {t}" for l, t in hits sys p = "You are a study buddy. Answer ONLY from the notes below. Cite sources like file n . " "If the notes don't contain the answer, say so plainly. Keep it short and clear." body = {"model": MODEL, "stream": False, "messages": {"role": "system", "content": sys p}, {"role": "user", "content": f"NOTES:\n{ctx}\n\nQUESTION: {question}"} } req = urllib.request.Request f"{OLLAMA}/api/chat", json.dumps body .encode , {"Content-Type": "application/json"} with urllib.request.urlopen req, timeout=120 as r: return json.load r "message" "content" I gave Alekh NotesBuddy and asked him to try it on his own notes. His reaction: "Honestly, NotesBuddy is exactly what I needed. I've got so many notes scattered across different files that finding one small concept takes forever. Now I can just ask a question and get the answer along with the exact part of my notes it came from. And the fact that it tells me when something isn't in my notes instead of making up an answer is actually really useful. It feels like having a study assistant that works directly with my own material." The two things he singled out, seeing the exact source passage and getting an honest "that's not in your notes," are the two design decisions I cared about most. NOTESBUDDY MODEL , so swapping Gemma for another Ollama model needs no code change. And because I control the prompt and the retrieval, I could build the "admit when you don't know" behavior directly into the pipeline. What's next: swapping BM25 for local embeddings to handle paraphrased questions, and a quiz mode that turns notes into practice questions. Best Use of Gemma : Gemma 3 runs locally via Ollama as the generation model that answers every question.