Skip to main content

Semantic embedding validation tool for ADRs and code

This project has been archived.

The maintainers of this project have marked this project as archived. No new releases are expected.

Project description

gundog

PyPI Python Release License CI Ruff

Gundog is a local semantic retrieval engine for your high volume corpus. It finds relevant code and documentation by understanding what you mean, not just matching keywords.

Point it at your docs and code. It embeds everything into vectors, builds a similarity graph connecting related files, and combines semantic search with keyword matching. Ask "how does auth work?" and it retrieves the login handler, session middleware, and the ADR that explains why you chose JWT even if none of them contain the word "auth".

Use it for LLM context retrieval, exploring unfamiliar codebases, or as a dynamic documentation explorer. Runs entirely on your machine.

gundog web UI

The Problem

Your codebase is full of implicit connections that aren't explicit. The ADR explaining your auth strategy relates to the login handler, which relates to the session middleware but nothing links them. Docs drift from implementation. Knowledge lives in silos.

There are some tools that solves this problem. Especially, credit where it's due - the core idea of gundog is based on the much more mature SeaGOAT project. But my particular needs were ever so slightly different. I wanted a clean map of data chunks from wide spread data sources and their correlation based on a natural language query. SeaGOAT provides rather a flat but more accurate pointer to a specific data chunk from a single git repository. Basically, I wanted a Obsidian graph view of my docs controlled based on a natural language query without having to go through the pain of using.. well.. Obsidian. And wrapping SeaGOAT with some scripts was limiting and also hard to distribute.

Gundog builds these connections automatically. Vector search finds semantically related content, BM25 catches exact keyword matches, and graph expansion surfaces files you didn't know to look for.

Install

pip install gundog

Optional extras:

pip install gundog[viz]    # for query graph visualization
pip install gundog[lance]  # for larger codebases (10k+ files)
pip install gundog[serve]  # for web UI server

Or from source

git clone https://github.com/adhityaravi/gundog.git
cd gundog
uv sync
uv run gundog --help

Quick Start

1. Create a config file (default: .gundog/config.yaml):

sources:
  - path: ./docs
    glob: "**/*.md"
  - path: ./src
    glob: "**/*.py"

storage:
  backend: numpy
  path: .gundog/index

2. Index your stuff:

gundog index

First run downloads the embedding model (~130MB for the default). You can use any sentence-transformers model. Subsequent runs are incremental—only re-indexes changed files.

3. Search:

gundog query "database connection pooling"

Returns ranked results with file paths and relevance scores.

Commands

You can use gundog with a config file OR with CLI flags directly. but config files are recommended:

# With config file (default: .gundog/config.yaml)
gundog index
gundog index -c /path/to/config.yaml

# Without config file
gundog index --source ./docs:*.md --source ./src:*.py
gundog query "auth" --index .gundog/index

gundog index

Scans your configured sources, embeds the content, and builds a searchable index.

gundog index                                      # uses config file
gundog index --rebuild                            # fresh index from scratch
gundog index -s ./docs:*.md -s ./src:*.py         # no config needed
gundog index -s ./docs -i ./my-index              # custom index location
gundog index -s ./src:*.py -e '**/test_*'         # exclude test files

Source format: path, path:glob, or path:type:glob

Exclude patterns use fnmatch syntax (e.g., **/test_*, **/__pycache__/*).

Exclusion templates provide predefined patterns for common languages:

gundog index -s ./src:*.py --exclusion-template python  # ignores __pycache__, .venv, etc.
gundog index -s ./src:*.ts --exclusion-template typescript

Available templates: python, javascript, typescript, go, rust, java

gundog query

Finds relevant files for a natural language query.

gundog query "error handling strategy"
gundog query "authentication" --top 5        # limit results
gundog query "caching" --no-expand           # skip graph expansion
gundog query "auth" --index .gundog/index    # specify index directly
gundog query "api design" --type docs        # filter by type (if sources have types)
gundog query "auth flow" --graph             # opens visual graph of results

gundog serve

Starts a web UI for interactive queries with a visual graph.

gundog serve                              # starts at http://127.0.0.1:8000
gundog serve --port 3000                  # custom port
gundog serve --title "My Project"         # custom title
gundog serve --github https://github.com/user/repo  # adds links to files

Requires the serve extra: pip install gundog[serve]

How It Works

  1. Embedding: Files are converted to vectors using sentence-transformers. Similar concepts end up as nearby vectors.

  2. Hybrid Search: Combines semantic (vector) search with keyword (BM25) search using Reciprocal Rank Fusion. Queries like "UserAuthService" find exact matches even when embeddings might miss them.

  3. Storage: Vectors stored locally via numpy+JSON (default) or LanceDB for scale. No external services.

  4. Graph: Documents above a similarity threshold get connected, enabling traversal from direct matches to related files.

  5. Query: Your query gets embedded, compared against stored vectors, fused with keyword results, and ranked. Scores are rescaled so 0% = baseline, 100% = perfect match. Irrelevant queries return nothing.

Configuration

Full config options:

sources:
  - path: ./docs
    glob: "**/*.md"
  - path: ./src
    glob: "**/*.py"
    type: code                    # optional - for filtering with --type
    exclusion_template: python    # optional - predefined excludes
    exclude:                      # optional - additional patterns to skip
      - "**/test_*"

embedding:
  # Any sentence-transformers model works: https://sbert.net/docs/sentence_transformer/pretrained_models.html
  model: BAAI/bge-small-en-v1.5  # default (~130MB), good balance of speed/quality

storage:
  backend: numpy      # or "lancedb" for larger corpora
  path: .gundog/index

graph:
  similarity_threshold: 0.7  # min similarity to create edge
  expand_threshold: 0.5      # min edge weight for query expansion
  max_expand_depth: 2        # how far to traverse during expansion

hybrid:
  enabled: true       # combine vector + keyword search (default: on)
  bm25_weight: 0.5    # keyword search weight
  vector_weight: 0.5  # semantic search weight

chunking:
  enabled: false      # split files into chunks (opt-in)
  max_tokens: 512     # tokens per chunk
  overlap_tokens: 50  # overlap between chunks

The type field is optional. If you want to filter results by category (e.g., --type code), assign types to your sources. Any string works. To use a type without a config file, use the format path:type:glob when specifying sources.

Chunking

For large files, enable chunking to get better search results. Instead of embedding whole files (which dilutes signal), chunking splits files into overlapping segments:

chunking:
  enabled: true
  max_tokens: 512   # ~2000 characters per chunk
  overlap_tokens: 50

Results are automatically deduplicated by file, showing the best-matching chunk.

What Gundog Doesn't Do

  • Chat: It's retrieval, not generation. Feed results to your LLM of choice.
  • Cloud anything: Everything runs locally. Your code stays on your machine.

Why "Gundog"?

Gundogs retrieve things. That's the whole job. Point at what you want, they fetch it. Small, focused, good at one thing.

Development

uv sync --extra dev      # install dev dependencies
uv run ruff check .      # lint
uv run ruff format .     # format
uv run pyright src       # type check
uv run pytest            # test
uv run tox               # run all checks

Small. Lightweight. Ferocious.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gundog-0.1.1.tar.gz (316.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gundog-0.1.1-py3-none-any.whl (48.3 kB view details)

Uploaded Python 3

File details

Details for the file gundog-0.1.1.tar.gz.

File metadata

  • Download URL: gundog-0.1.1.tar.gz
  • Upload date:
  • Size: 316.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gundog-0.1.1.tar.gz
Algorithm Hash digest
SHA256 06c032770dc04f6a68029c2e1853562bbcc1e72463e3cb864d2b0fbc2e039886
MD5 dd397c8d1c7ac391426e5b462e019e14
BLAKE2b-256 e556834d3d0250e1d63e4bbdb846c8574ea6d7c27d93886889b471c7df77124c

See more details on using hashes here.

Provenance

The following attestation bundles were made for gundog-0.1.1.tar.gz:

Publisher: release.yaml on adhityaravi/gundog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gundog-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: gundog-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 48.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for gundog-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d669c74443fdecf7d04480318f49ee2c03d411340a915c01ce27e6c33ebdc230
MD5 2919ee3198ee36a21d1b4af2542f7fdc
BLAKE2b-256 6f598068edbeb5779b9f35c3a70ebe01c69a60cd76d4698b2e137e8a778cdbd2

See more details on using hashes here.

Provenance

The following attestation bundles were made for gundog-0.1.1-py3-none-any.whl:

Publisher: release.yaml on adhityaravi/gundog

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page