Giving a local tool-calling LLM a "skill" in drone RF protocols
I’ve been running a tool-calling LLM locally — Gemma in this case, though the approach doesn’t depend on which model — to reason about FPV drone systems: pick a sane video channel, flag a control-link/video-link conflict, explain why a 1.3 GHz analog setup needs an amateur license. None of that requires the model to know RF engineering. It requires the model to have just enough drone-specific vocabulary in its context to reason correctly and call the right tools with the right arguments. Figuring out how much “just enough” actually is turned out to be the real problem.
Context engineering, briefly
Context engineering is the part of building an LLM application that isn’t prompting or fine-tuning: deciding what information actually goes into the context window for a given task, and in what form. It sits next to prompt engineering rather than replacing it — the prompt says what to do, the context supplies what the model needs to know to do it.
With a frontier hosted model, the instinct is often “just give it everything” — dump the whole spec, the whole doc, and let a huge context window and strong instruction-following sort it out. That instinct breaks down fast on a local model. A model in the Gemma weight class has a real context budget, weaker long-context attention than a frontier model, and noticeably worse instruction-following once the context fills with text that isn’t directly load-bearing for the task. Feed it a full RF engineering reference — propagation models, regulatory history, modulation theory — and the signal you actually need (channel center frequencies, which bands collide) gets diluted enough that tool-call accuracy drops. Too little context and it hallucinates band plans instead of citing them. The useful range in between is narrow, and it’s specific to the model, the task, and the tool schema — there’s no formula, just iteration.
For this project that meant treating the reference material less like documentation and more like a skill: a small, dense, purpose-built artifact that hands the model exactly the facts it needs to ground its tool calls, and nothing it has to spend attention filtering out.
What went in, and what got cut
FPV drones run two independent RF links — a control/telemetry uplink (ExpressLRS, TBS Crossfire, FrSky, DSMX) and a video downlink that’s either analog (5.8 GHz, 40 channels across five overlapping bands) or digital (DJI O3/O4, HDZero, Walksnail). Each has a band, a set of channel centers or a hopping range, an occupied bandwidth, and a few notes that matter for reasoning about interference or legality.
That’s the whole skill. No prose explaining what FHSS is, no history of why Raceband uses 37 MHz spacing, no citations. Just tables: protocol, band, frequencies, bandwidth, and the one-line note that actually changes an answer (license required, legacy/abandoned, adaptive bitrate). Every table row is something the model might need to state or compare against when deciding on a tool call — anything that only explains why the fact is true got left out, because it costs tokens without improving the model’s ability to act on the fact.
The test was practical, not academic: give the model a query like “is Raceband channel 4 safe to fly next to someone on Boscam band A near 5825?” and see whether it converges on the right channel-center comparison consistently, across several context sizes, rather than drifting into plausible-sounding but wrong RF trivia. The version below is what held up.
The dataset
This is the actual reference file, dropped into the model’s context as a static skill rather than retrieved per-query — small enough that it’s cheaper to always include than to run a retrieval step for.
# FPV Communication Protocols — Frequencies & Bandwidths
FPV drones run at least two independent RF links — a control/telemetry
uplink and a video downlink — so they are treated separately below.
## Control / Telemetry Uplink
| Protocol | Band | Center Freq(s) | Modulation | Occupied BW (per hop) | Notes |
|---|---|---|---|---|---|
| **ExpressLRS (ELRS) 900** | 868 MHz (EU) / 915 MHz (US ISM) | ~868.0 / ~915.5 MHz | LoRa | ~500 kHz–800 kHz | FHSS across 902–928 (US); 25–200 Hz packet rates |
| **ExpressLRS (ELRS) 2.4** | 2.4 GHz ISM | 2400–2483.5 MHz | LoRa / FLRC | ~800 kHz (LoRa) to ~2.4 MHz (FLRC) | FHSS; up to 1000 Hz (F1000) modes |
| **TBS Crossfire** | 868/915 MHz | ~868 / ~915 MHz | LoRa | ~250–500 kHz | FHSS; long-range, ~50–250 Hz |
| **FrSky ACCST/ACCESS** | 2.4 GHz ISM | 2400–2483.5 MHz | FHSS (GFSK) | ~1.5 MHz | Legacy/standard-range |
| **Spektrum DSMX** | 2.4 GHz ISM | 2400–2483.5 MHz | DSSS/FHSS | ~1.5 MHz | Consumer standard-range |
Control links are narrowband and frequency-hopping, so instantaneous
occupied bandwidth is small; the *span* they hop over is the full ISM
allocation (26 MHz at 900 MHz US, ~83.5 MHz at 2.4 GHz).
## Video Downlink — Analog (5.8 GHz)
Analog FPV uses 40 channels across five bands, ~5645–5945 MHz. FM video
occupies **~20 MHz at −3 dB, up to ~27 MHz** including audio subcarriers
and sidebands.
| Band | Channel Centers (MHz) |
|---|---|
| **A** (Boscam A) | 5725, 5745, 5765, 5785, 5805, 5825, 5845, 5865 |
| **B** (Boscam B) | 5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866 |
| **E** (DJI/Boscam E) | 5645, 5665, 5685, 5705, 5885, 5905, 5925, 5945 |
| **F** (Fatshark/Airwave) | 5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880 |
| **R** (Raceband) | 5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917 |
Raceband uses 37 MHz spacing to minimize adjacent-channel splatter; the
other bands overlap heavily, so channel coordination matters in
multi-pilot environments.
## Video Downlink — Digital
| System | Band(s) | Occupied BW | Notes |
|---|---|---|---|
| **DJI O3/O4 Air Unit** | 5.725–5.850 GHz + 2.4 GHz ISM | 10 / 20 / 40 MHz (selectable) | OFDM; adaptive bitrate |
| **HDZero** | 5.8 GHz (raceband channels) | ~27 MHz | Low-latency, fixed-rate digital |
| **Walksnail Avatar** | 5.8 GHz (+ 2.4 GHz on some) | ~20 MHz | OFDM |
## Legacy / Long-Range Analog Video
- **1.2/1.3 GHz** (1080–1360 MHz, amateur allocation ~1240–1300 MHz): older
long-range analog, ~20+ MHz occupied. Requires amateur license;
interferes with GPS front-ends if poorly filtered.
- **2.4 GHz** analog video: largely abandoned due to conflict with control
links.
---
**Regulatory note:** US operation on much of 5.8 GHz FPV and the 900 MHz /
2.4 GHz ISM control bands falls under Part 15 unlicensed rules at low
power, but higher-power VTX and the 1.2/1.3 GHz and some 900 MHz uses cross
into amateur-license territory.
Feel free to reuse it as-is for your own local agent, or as a starting point for tuning the too-much/too-little balance for your model and task.