ROS 2 coding assistant

A retrieval index over the ROS 2 documentation, built to give a local coding assistant current, citable answers β€” offline, on CPU, with every claim traceable to the page it came from.

Why this exists

ROS 2 changes across distributions, and a general coding model will happily give you a Foxy answer for a Rolling question, or reach for a ROS 1 habit that has no ROS 2 equivalent. On robotics work that surfaces late β€” often on hardware.

Retrieval fixes the currency problem without retraining anything. The index is rebuilt from the documentation source, so it is exactly as current as the commit it was built from, and --ref selects the distribution.

Current index

Documents 341
Chunks 5,134
Embedding model sentence-transformers/all-MiniLM-L6-v2 (384-dim)
Index FAISS IndexFlatIP, cosine over normalised vectors
Source ros2/ros2_documentation rolling @ a74c8f1

Quick start

git clone https://github.com/eoinjordan/ros2-coding-assistant
cd ros2-coding-assistant
python -m venv .venv && .venv\Scripts\Activate.ps1
pip install -r requirements.txt

python scripts/fetch_docs.py                  # rolling by default
python scripts/fetch_docs.py --ref jazzy      # or a specific distribution
python scripts/build_index.py
python scripts/ask.py "How do I write a lifecycle node?" --retrieve-only

--retrieve-only skips the generator: no model download, CPU-only, sub-second. Drop the flag to generate with Qwen Coder over the retrieved passages, or run the app:

python app.py       # http://localhost:7860

Shared pipeline

This runs the same chunker, retriever and trainer as the Zephyr build. Everything project-specific lives in scripts/source_config.py: the repository, the doc root, the URL template, the skip rules and the example questions. Adding a third project is a config file, not a fork.

Two things differ from Zephyr and are worth knowing if you adapt this again:

  • Docs live in source/, not doc/, and each distribution is a branch rather than a tag, so --ref picks the distribution.
  • Changelogs are nested under Get-Started/Releases/. A pattern anchored at the start of the path missed them entirely, and a Kilted Kaiju changelog outranked the tutorials until that was fixed.

How the corpus is built

Source is the RST, not the rendered site. Rendered pages carry navigation, the version switcher and generated API listings; all of it lands in chunks and competes with prose during retrieval.

Chunking follows document structure β€” RST section underlines rather than a character count β€” so a chunk stays on one topic and can cite its section. Chunks are bounded at 1,600 characters through three levels: paragraph, then line, then whitespace. The third exists because ROS 2 changelogs put an entire release's bullets on a single 3,223-character line that the first two could not divide.

Changelogs and release pages are down-weighted at query time unless the question is about a version or a change.

Fine-tuning the retriever

scripts/train_embeddings.py adapts the embedding model to ROS 2 vocabulary using pairs mined from heading/body structure, with MultipleNegativesRankingLoss for in-batch negatives. It reports recall@5 on held-out pairs before and after, and refuses to save a model that did not beat the baseline.

python scripts/train_embeddings.py --eval-only    # baseline
python scripts/train_embeddings.py --epochs 1
python scripts/build_index.py --model data/embedding-model

Worth stating plainly: this trains the retriever, not the generator. It does not teach Qwen Coder about ROS 2 β€” it makes the passages Qwen is handed more likely to be the right ones. Both are worth doing; a LoRA on Qwen is separate work.

Offline use

Everything runs locally once fetched. Index ~13 MB, embedding model ~90 MB, Qwen2.5-Coder-1.5B-Instruct ~3 GB. No network calls at query time, no API keys.

Licence

Apache-2.0. Indexed content is ROS 2 documentation, copyright its contributors, under CC-BY-4.0 β€” this repository redistributes derived chunks with their source paths intact so attribution survives retrieval.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Spaces using eoinedge/ros2 2