This is a submission for the Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass
What I Built
Field Notes turns a short walk into a bird log. You record a few minutes of sound outside, run one command, and an open model names the birds while a small local LLM writes the journal entry. The screen is only for reading the result at the end.
It's for anyone who wants a reason to stand still outside and listen: students, hikers, casual birders. I built it for my own campus walks.
Testing So Far
I haven't field-tested this outdoors yet, so I'm not claiming results I don't have. What I did verify: the page builder, the BirdNET result parser, and the fallback when Ollama isn't running all work on sample data. The two entries on the demo page are labeled "Sample" for that reason.
What I plan to check on my first real walk: whether BirdNET's top species match what I can see or hear, how it handles traffic and campus noise, and whether the local model ever adds details that weren't in the detections. I built the page to show BirdNET's percentages separately from the model's prose so those errors would be easy to spot.
Code
<!doctype html>
<br> :root{--paper:#e4e9d8;--ink:#1d2a21;--muted:#55645a;--rule:#b9c4a8;--bar:#9db35a;--link:#2a5a86;--tag:#d3dbc2}<br> @media (prefers-color-scheme:dark){:root{--paper:#14201a;--ink:#dde6d4;--muted:#9fb0a2;--rule:#2f4034;--bar:#7f9a45;--link:#8fbbe4;--tag:#22332a}}<br> *{box-sizing:border-box}<br> body{margin:0;background:var(--paper);color:var(--ink);font:1.0625rem/1.65 Georgia,"Iowan Old Style","Palatino Linotype",serif}<br> main{max-width:42rem;margin:0 auto;padding:2.5rem 1.25rem 4rem}<br> h1{font-size:2.4rem;line-height:1.1;margin:0 0 .5rem;letter-spacing:-.01em}<br> .lede{color:var(--muted);margin:0 0 2.5rem;max-width:34rem}<br> .walk{border-top:2px solid var(--ink);padding:1.25rem 0 2rem}<br> .walk header{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;flex-wrap:wrap}<br> .walk h2{font-size:1.4rem;margin:0}<br> time,.meta{font:.9rem/1.4 system-ui,-apple-system,"Segoe UI",sans-serif;color:var(--muted)}<br> .sample{background:var(--tag);padding:.1rem .5rem;border-radius:.25rem;font:.8rem system-ui,sans-serif;margin-left:.5rem}<br> .note{white-space:pre-line;margin:1rem 0}<br> .birds{list-style:none;margin:1.25rem 0;padding:0;font-family:system-ui,-apple-system,"Segoe UI",sans-serif;font-size:.95rem}<br> .birds li{display:grid;grid-template-columns:minmax(9rem,14rem) 1fr 3rem;gap:.75rem;align-items:center;padding:.3rem 0;border-bottom:1px solid var(--rule)}<br> .birds em{display:block;color:var(--muted);font-size:.8rem}<br> .bar{height:.55rem;background:var(--tag);border-radius:.3rem;overflow:hidden}<br> .bar span{display:block;height:100%;background:var(--bar)}<br> .pct{text-align:right;font-variant-numeric:tabular-nums}<br> .outside{border-left:3px solid var(--bar);padding-left:1rem;margin:1.25rem 0 0}<br> footer{margin-top:3rem;border-top:1px solid var(--rule);padding-top:1rem;color:var(--muted);font:.9rem/1.5 system-ui,sans-serif}<br> a{color:var(--link)}a:focus-visible{outline:3px solid var(--link);outline-offset:2px}<br> @media (max-width:30rem){.birds li{grid-template-columns:1fr 3rem}.bar{grid-column:1 / -1;order:3}}<br>
Field Notes
Bird calls from walks outside, identified by an open model on a laptop and written up by another one. No signal needed, and the recordings never leave the machine.
Sample: lake path, eveningSample
At Sample: lake path, evening the clearest call was Asian Koel (88% confidence). Also picked up: Eurasian Collared-Dove.
- Asian KoelEudynamys scolopaceus88%
- Eurasian Collared-DoveStreptopelia decaocto72%
Identified by BirdNET, written by template (sample data). Percent is BirdNET's best confidence.
Sample: hostel garden, morningSample
At Sample: hostel garden, morning the clearest call was Rose-ringed Parakeet (91% confidence). Also picked up: Common Myna, Red-vented Bulbul, Oriental Magpie-Robin.
- Rose-ringed ParakeetPsittacula krameri91%
- Common MynaAcridotheres tristis84%
- Red-vented BulbulPycnonotus cafer67%
- Oriental Magpie-RobinCopsychus saularis46%
Identified by BirdNET, written by template (sample data). Percent is BirdNET's best confidence.
Made with BirdNET and Ollama. The bird names come from BirdNET; the prose comes from the local model and can be wrong, so check the percentages.How I Built It
- BirdNET-Analyzer identifies bird calls from audio, fully offline. It returns species, a confidence score, and timestamps.
-
Ollama with an open-weight model (
llama3.2:3bby default, swappable with--model) writes a short first-person journal entry. It only sees BirdNET's detections, and the prompt tells it to use only those birds and to call anything under 50% confidence "possible". -
A small Python script (
fieldnotes.py, standard library only) connects them and generates a static HTML page, hosted on GitHub Pages. - If Ollama isn't running, it falls back to a plain template entry so the log still works.
The bird names and percentages come straight from BirdNET. The LLM only writes the prose, and the page says so.
Why Does Open Innovation Matter?
- It works with no signal. Both models run on a laptop, so the whole pipeline works on a trail or in a hostel room with no internet.
- My recordings stay mine. Audio is processed locally and git-ignored. Location only narrows BirdNET's species list and is never saved.
- It costs nothing to run. No API key and no per-call fee.
- I can swap the writer. Changing the model is one flag, so I can compare how different open models write up the same detections.
A closed API could have written the prose, but it couldn't have done it offline or kept the audio on my machine.
Top comments (0)