Skip to content

Repository files navigation

OpenStack RAG Bot

A RAG (Retrieval-Augmented Generation) agent that answers questions about OpenStack internals — Nova, Cinder, Neutron, and Keystone. It searches documentation, bug reports, source code, and mailing list archives simultaneously, fuses the results with Reciprocal Rank Fusion (RRF), and generates answers with a local LLM.

Data sources

Source Projects Format
RST documentation nova, cinder, neutron, keystone git clone → .rst
Specs (design docs) same + -specs repos git clone → .rst
Release notes all releasenotes/notes/*.yaml
Launchpad bugs all REST API → JSON
Source code all AST parsing → functions/classes
Mailing list openstack-discuss (since 2022) .mbox.gz archives

Quick start

# 1. Install dependencies
pip install -r requirements.txt

# 2. Collect docs, specs, release notes, and bugs (git clone + Launchpad API)
#    Takes ~20-40 minutes, creates openstack_data/
bash collect_openstack.sh

# 3. Split docs and bugs into chunks
python preprocess.py

# 4. Extract functions and classes from source code (AST)
python collect_code.py

# 5. Download and parse openstack-discuss mailing list archives
python collect_mailinglist.py

# 6. Build the vector index (four ChromaDB collections)
python build_index.py

# 7a. Ask questions from the CLI
python agent.py "Why does Nova raise NoValidHost?"

# 7b. Or launch the Gradio web UI at http://localhost:7860
python app.py

Pipeline

collect_openstack.sh ──► preprocess.py ──────────┐
collect_code.py ─────────────────────────────────┼──► build_index.py ──► agent.py / app.py
collect_mailinglist.py ──────────────────────────┘

How the agent works

  1. The query is embedded with all-MiniLM-L6-v2 (on CPU, to keep VRAM free for the LLM).
  2. Four ChromaDB collections are searched in parallel: openstack_docs, openstack_bugs, openstack_code, openstack_mail (top-5 from each).
  3. Results are merged with Reciprocal Rank Fusion: score += 1 / (60 + rank + 1) per collection.
  4. The top-5 fused hits become the context for the LLM (Qwen/Qwen2.5-1.5B-Instruct, 4-bit quantized on GPU — fits in 4 GB VRAM; float32 on CPU).

File layout

openstack_data/
├── nova_docs.json            # RST docs + specs + release notes
├── cinder_docs.json
├── neutron_docs.json
├── keystone_docs.json
├── all_docs.json             # everything combined
├── nova_bugs.json            # Launchpad bugs
├── cinder_bugs.json
├── neutron_bugs.json
├── keystone_bugs.json
├── all_bugs.json
├── chunks.json               # docs + bugs chunks (from preprocess.py)
├── code_chunks.json          # code chunks (from collect_code.py)
├── mailinglist_chunks.json   # mailing list chunks (from collect_mailinglist.py)
└── mbox/                     # cached .mbox.gz archives

chroma_db/                    # vector DB (after build_index.py)
openstack_repos/              # git clones (safe to delete after collection)

Chunk format

{
  "id": "nova_documentation_000042",
  "project": "nova",
  "type": "documentation",
  "source": "doc/source/admin/resize.rst",
  "text": "Resizing an instance changes the flavor...",
  "chunk_n": 2,
  "char_len": 487
}

Chunk types: documentation, spec, release_notes, bug_report, code_function, code_class, mailing_list.

Code chunks additionally carry module, name, line_start, line_end; mailing list chunks carry subject.

Configuration

In collect_openstack.sh:

  • MAX_BUGS_PER_PROJECT=500 — raise to 5000 for the full dataset

In preprocess.py:

  • CHUNK_SIZE=512 — chunk size in characters
  • OVERLAP=64 — overlap between chunks

In collect_code.py:

  • MIN_CHARS=100 — shorter code chunks are dropped; tests and migrations are skipped

In collect_mailinglist.py:

  • START_YEAR=2022 — how far back to download archives
  • KEYWORDS — only messages matching OpenStack-related keywords are kept

In build_index.py:

  • EMBED_MODEL — embedding model (default: sentence-transformers/all-MiniLM-L6-v2)
  • BATCH_SIZE=256 — embedding batch size

In agent.py:

  • LLM_GPU / LLM_CPU — LLM model id (default: Qwen/Qwen2.5-1.5B-Instruct)
  • TOP_K=5 — results per collection
  • TOP_FINAL=5 — fused results used as LLM context
  • RRF_K=60 — RRF constant

About

RAG agent for OpenStack internals — answers questions about Nova, Cinder, Neutron & Keystone by fusing search over docs, Launchpad bugs, source code and mailing lists (ChromaDB + RRF + local LLM)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages