ros2 / README.md
eoinedge's picture
ROS 2 docs RAG index and tooling
d79a152 verified
|
Raw
History Blame Contribute Delete
4.76 kB
---
license: apache-2.0
language:
- en
tags:
- ros2
- ros
- robotics
- rag
- retrieval
- faiss
- documentation
- qwen
- offline
pipeline_tag: sentence-similarity
library_name: sentence-transformers
---
# 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.
- **Space:** https://huggingface.co/spaces/eoinedge/ros2
- **Model repo:** https://huggingface.co/eoinedge/ros2
- **Source:** https://github.com/eoinjordan/ros2-coding-assistant
- **Companion build for Zephyr RTOS:** https://github.com/eoinjordan/zephyrproject-rag
## 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
```bash
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:
```bash
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`](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.
```bash
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.