askme - Codebase RAG CLI
A Command Line Interface (CLI) tool for local Retrieval-Augmented Generation (RAG) over your codebase. It scans, indexes and lets you chat with your project using local LLMs (via an OpenAI-compatible API) and a Qdrant vector database, returning context-aware answers with source citations.
The Python package is named askme and exposes a single askme console script.
Key Features
- Local-first architecture
- Runs against any OpenAI-compatible LLM/embedding endpoint (e.g. Ollama) and a Qdrant instance you control.
- Code never has to leave your machine if you self-host the services.
- Hybrid retrieval (dense + sparse)
- Dense vectors are produced by the configured embedding model.
- Sparse vectors are computed locally with a built-in BM25 encoder (
src/askme/sparse.py) for keyword/identifier recall.
- Smart incremental indexing
- MD5 hashing of files detects changes, so only new or modified files are re-embedded.
/reindexforces a full rebuild on demand.
- Source citations
- Answers include inline
[File: ...]citations and a citation list, backed by chunk metadata stored in Qdrant.
- Answers include inline
- Conversation history
- Sessions are auto-saved as JSON in
.cfg/history/and can be listed, loaded or deleted via/history.
- Sessions are auto-saved as JSON in
- Rich interactive prompt
- Powered by
prompt-toolkitwith multiline and paste modes.
- Powered by
Technology Stack
- Language: Python 3.11+
- Vector Database: Qdrant (1.x; remote, via Docker, or local file-based)
- LLM / Embeddings: any OpenAI-compatible API (tested with Ollama)
- Key libraries:
qdrant-client- Qdrant access (dense + sparse vectors).openai- client for the OpenAI-compatible LLM and embedding APIs.rich- terminal UI, panels, markdown rendering.prompt-toolkit- interactive prompt with multiline support.python-dotenv- environment variable loading.
Project Layout
src/askme/
config.py # ConfigManager - .cfg/settings.json and chat history
scanner.py # FileScanner - traversal, filtering, MD5 hashing
vector_db.py # VectorDBConnector - chunking, embeddings, Qdrant I/O
sparse.py # BM25SparseEncoder - local sparse vector generation
llm.py # LLMInterface - prompt building and chat completion
list_files.py # /index command helpers
ui.py # rich-based UI helpers
utils.py # shared utilities
models.py # data models
main.py # entry point and interactive loop
tests/ # pytest test suite
Data Flow
Codebase -> FileScanner (hash + filter) -> VectorDBConnector (chunk + dense embed + BM25 sparse) ->
Qdrant (hybrid index) -> LLMInterface (query + retrieved context) -> User
Setup
Prerequisites
- Python 3.11+
- A Qdrant vector database, in one of two modes:
server- a running Qdrant instance (local Docker or remote).local- a file-based store on disk, no server or Docker required (quick start).
- An OpenAI-compatible LLM and embeddings endpoint (e.g. Ollama).
1. Start Qdrant (optional)
In local mode you can skip this step entirely - the index is stored on disk under
qdrant_local_path (default ./data/vector_store) and persists between runs.
For server mode, run Qdrant locally via Docker:
docker run -p 6333:6333 -p 6334:6334 \
-v $(pwd)/qdrant_storage:/qdrant/storage:z \
qdrant/qdrant
If you start in server mode but the server is unreachable, askme offers to fall back to local file-based mode
(default answer: yes) and remembers the choice in
.cfg/settings.json.
2. Prepare models (example with Ollama)
ollama pull llama3
ollama pull embeddinggemma:300m
3. Install
Using uv (recommended for development):
uv sync
uv run askme
Or with pip from the project root:
pip install .
askme
Or directly from GitHub:
pip install git+https://github.com/varsey/codebase-rag.git
Configuration
On the first run inside a project directory, askme prompts for configuration and stores it in ./.cfg/settings.json.
Conversation histories are stored next to it under ./.cfg/history/.
| Option | Default | Description |
|---|---|---|
qdrant_mode |
server |
Connection mode: server (remote/Docker) or local (file-based). |
qdrant_local_path |
./data/vector_store |
On-disk path for the local file-based store (used in local mode). |
qdrant_host |
localhost |
Hostname of the Qdrant service (used in server mode). |
qdrant_port |
6333 |
Port of the Qdrant service (used in server mode). |
llm_api_base |
http://localhost:11434/v1 |
Base URL of the OpenAI-compatible LLM API. |
llm_api_base_cert |
`` | Optional path to custom cert/CA bundle for LLM API TLS verification. |
vdb_api_base |
http://localhost:11434/v1 |
Base URL of the OpenAI-compatible embeddings API. |
api_key |
sk-... |
API key passed to the OpenAI-compatible client. |
llm_model |
llama3 |
LLM model name. |
embedding_model |
embeddinggemma:300m |
Embedding model name. |
chunk_size |
750 |
Chunk size in characters. |
chunk_overlap |
250 |
Overlap between chunks in characters. |
buffer_size |
1048576 |
Read buffer size for file scanning. |
top_n |
10 |
Number of chunks retrieved per query. |
collection_name |
auto-generated | Qdrant collection used for this project. |
file_extensions |
.py, .md, .js, .ts, .go, .java, ... |
File types to index. |
excluded_dirs |
.git, .venv, node_modules, ... |
Directories skipped during scanning. |
A real example lives in .cfg/settings.json.
Usage
Inside the codebase you want to query:
askme
On first launch the tool guides you through configuration, scans the project and builds the Qdrant collection. Subsequent runs reuse the existing index and only re-embed changed files.
Interactive commands
/new- start a fresh conversation (resets the context window)./history- list, load or delete saved sessions in.cfg/history/./reindex- clear the collection and re-embed the codebase from scratch./index- show the files currently indexed./multilineor/m- toggle persistent multiline input (submit with Alt+Enter)./paste- one-shot multiline input for a single query./exitor/quit- end the session.
Storage Schema
Each point in the Qdrant collection holds a dense vector, a BM25 sparse vector and the following payload:
{
"path": "string (relative path to file)",
"content": "string (the actual code chunk)",
"hash": "string (MD5 hash of the original file)",
"chunk_index": "int",
"total_chunks": "int"
}
Development
-
Install dev dependencies and run tests with
uv:uv sync uv run pytest
-
The test suite covers config defaults, connection checks, scanner behaviour, sparse BM25 encoding, history/context handling and the main module wiring.
Known Limitations
- Very large files can be memory-heavy during scanning and embedding.
- Answer quality is bounded by the local LLM's context window.
- Only text-based source files are supported; binaries are skipped.
- Hybrid search quality depends on the corpus the BM25 encoder was fit on (the current project).
Contributing
- Fork the repository.
- Create a feature branch (
git checkout -b feature/your-change). - Keep changes focused and follow the existing code style.
- Add or update tests under
tests/and make sureuv run pytestpasses. - Open a Pull Request with a clear description.
License
MIT License - see the LICENSE file for details (or standard MIT terms if the file is missing).
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file askme_rag-0.1.1.tar.gz.
File metadata
- Download URL: askme_rag-0.1.1.tar.gz
- Upload date:
- Size: 38.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3bce3a760c86b9b929b5623981c352ac3d0bc2b429f33b25dc7cf22083270d2
|
|
| MD5 |
5a94f332d10180cfd0fe94cad9c24c7f
|
|
| BLAKE2b-256 |
e5cbe8a20795fd762a274f138094a12abc95faf2d7acbd23abfccbda7f55f06d
|
File details
Details for the file askme_rag-0.1.1-py3-none-any.whl.
File metadata
- Download URL: askme_rag-0.1.1-py3-none-any.whl
- Upload date:
- Size: 26.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.11 {"installer":{"name":"uv","version":"0.10.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d805d9842162d3998c988a2dec2f889a3e30fa521384cb88c56e5d8c814a338
|
|
| MD5 |
fcb5e18e80a93cddf426e107a0459749
|
|
| BLAKE2b-256 |
57fb54f272dd28594889a4cee4b0681e5e83279be1bb89f7452d9be0e6e7833b
|