GraphSearch: a GraphQL API server for Retrieval-Augmented Generation (RAG) over your documents
Project description
GraphSearch
A GraphQL API server for Retrieval-Augmented Generation (RAG) over your documents.
Upload documents through a GraphQL mutation, then ask questions through a GraphQL query. GraphSearch chunks and embeds your documents, retrieves the most relevant passages with vector similarity search, and feeds them to an LLM to generate a grounded answer — all behind a single, typed, introspectable GraphQL endpoint.
query {
answer(question: "How do I reset my password?") {
text # cites sources as [1], [2], ...
sources { documentTitle text score }
}
}
Semantic retrieval with the offline local backend: "How do I get my money back?" finds the returns policy — no shared keywords needed.
Why GraphQL for RAG?
- One endpoint, typed schema — clients ask for exactly the fields they need (answer text, source chunks, scores) instead of juggling REST routes.
- Introspection & tooling for free — GraphiQL, codegen'd TypeScript clients, and schema docs come with the ecosystem.
- Composable —
answer,search, and document management live in one schema and can be combined in a single request.
Quickstart
Install
pip install graphsearch-rag # from PyPI (imports as `graphsearch`)
# or run the prebuilt image:
docker run -p 8000:8000 ghcr.io/mohithgowdak/graphsearch:latest
# or from source:
git clone https://github.com/mohithgowdak/graphsearch && cd graphsearch
pip install -e ".[dev]"
Run locally (no API keys needed)
The default configuration is fully offline: a hashing-trick embedder plus an extractive answer mode. It exercises the entire pipeline and is perfect for kicking the tires, tests, and CI.
# Ingest some documents (bundled examples shown; any .md/.txt works)
graphsearch-ingest data/example_docs
# Start the server
graphsearch
Then open:
- http://localhost:8000/ — the Playground: drop in your own documents and ask questions from the browser, no GraphQL knowledge needed. Every action has a "Show the GraphQL" toggle revealing the exact query it runs, so you can copy it straight into your app.
- http://localhost:8000/graphql — GraphiQL, for writing queries by hand:
query {
answer(question: "What is the return policy?") {
text
sources { text score }
}
}
Run with Docker
docker compose up --build
Semantic search without any API key
The local backend runs sentence-transformers
on your CPU — real semantic retrieval ("How do I get my money back?" finds
the refund policy), still zero keys and zero external services:
pip install -e ".[local]"
export GRAPHSEARCH_EMBEDDINGS=local # $env:GRAPHSEARCH_EMBEDDINGS='local' on Windows
graphsearch-ingest data/example_docs # re-ingest: embeddings are created at ingest time
graphsearch
The default model (all-MiniLM-L6-v2, ~80 MB) downloads on first use.
Generated answers with citations
Point the LLM stage at OpenAI or Anthropic and answers become generated
text that cites its sources — [1], [2], … map 1:1 to the sources
list returned alongside the answer:
export GRAPHSEARCH_LLM=anthropic # or openai
export ANTHROPIC_API_KEY=sk-ant-...
pip install -e ".[anthropic]"
graphsearch
| Setting | Options | Default |
|---|---|---|
GRAPHSEARCH_EMBEDDINGS |
hash (offline), local (offline, semantic), openai |
hash |
GRAPHSEARCH_LLM |
extractive (offline), openai, anthropic |
extractive |
Note: documents are embedded at ingest time, so re-ingest after switching embedding backends.
GraphQL API
Queries
answer(question: String!, topK: Int): Answer! # RAG: retrieve + generate
search(query: String!, topK: Int): [Chunk!]! # raw semantic search
documents(limit: Int = 20, offset: Int = 0): [Document!]!
document(id: ID!): Document
Mutations
uploadDocument(content: String!, title: String, source: String): Document!
deleteDocument(id: ID!): Boolean!
Example: ingest and ask in one session
mutation {
uploadDocument(
content: "Support hours are 9am-5pm PST, Monday through Friday."
title: "support-hours"
) { id chunkCount }
}
query {
answer(question: "When is support available?") {
text
sources { documentId score }
}
}
Architecture
Client ── GraphQL (FastAPI + Strawberry) ── RagService
├─ chunking (paragraph-aware splitter)
├─ Embedder (hash | sentence-transformers | OpenAI)
├─ VectorStore (SQLite-backed, in-memory cosine search)
├─ Database (SQLite: documents, chunks, vectors)
└─ LLM (extractive | OpenAI | Anthropic)
Every pipeline stage is an abstract interface (Embedder, VectorStore, LLM),
so new backends are drop-in additions — see Contributing.
Development
pip install -e ".[dev]"
ruff check . # lint
pytest -v # tests run fully offline
Roadmap / good first issues
- Additional vector store backends: Qdrant, Weaviate, Redis/Valkey, pgvector, FAISS
- Additional embedding backends: Cohere, Voyage
- Streaming answers via GraphQL subscriptions
- Metadata filters on
search(tags, date ranges) and hybrid keyword+vector search - Auth (API keys / JWT) and rate limiting
- Query/embedding caching
- Auto-generated TypeScript client (GraphQL Code Generator)
- Evaluation harness with known Q&A pairs; Prometheus metrics
- Advanced RAG: query rewriting, multi-hop retrieval, citation spans
Contributing
Contributions are welcome! See CONTRIBUTING.md for setup,
style, and PR guidelines, and the issue tracker for good first issue labels.
License
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
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 graphsearch_rag-0.3.0.tar.gz.
File metadata
- Download URL: graphsearch_rag-0.3.0.tar.gz
- Upload date:
- Size: 24.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a789736c7ad0c992d38290420dfbf8ae612c4a48e89f5fb031ea74303ede5e2d
|
|
| MD5 |
b6631ef4da4a3570e627a6b26a2c3efd
|
|
| BLAKE2b-256 |
ac6f0b5fea1aef7e262b1cb5f78e88eedc3068fa874215fff02b9ba031b1b7bc
|
Provenance
The following attestation bundles were made for graphsearch_rag-0.3.0.tar.gz:
Publisher:
release.yml on mohithgowdak/graphsearch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphsearch_rag-0.3.0.tar.gz -
Subject digest:
a789736c7ad0c992d38290420dfbf8ae612c4a48e89f5fb031ea74303ede5e2d - Sigstore transparency entry: 2082640124
- Sigstore integration time:
-
Permalink:
mohithgowdak/graphsearch@7e7d6f767c90e019563f72704c20de5d6b0fdd14 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/mohithgowdak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7e7d6f767c90e019563f72704c20de5d6b0fdd14 -
Trigger Event:
push
-
Statement type:
File details
Details for the file graphsearch_rag-0.3.0-py3-none-any.whl.
File metadata
- Download URL: graphsearch_rag-0.3.0-py3-none-any.whl
- Upload date:
- Size: 22.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07ba46e31d404f2e583ac89cc88c936672582ca0cc362be6d97a3fd0861fd45a
|
|
| MD5 |
82ac0fa53a340cd173afd581cfc88007
|
|
| BLAKE2b-256 |
f5c5c7a82c06b62c63c730c9819ad00fbc15c839bd3571473c2ac1f4f5a0c5f4
|
Provenance
The following attestation bundles were made for graphsearch_rag-0.3.0-py3-none-any.whl:
Publisher:
release.yml on mohithgowdak/graphsearch
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
graphsearch_rag-0.3.0-py3-none-any.whl -
Subject digest:
07ba46e31d404f2e583ac89cc88c936672582ca0cc362be6d97a3fd0861fd45a - Sigstore transparency entry: 2082640154
- Sigstore integration time:
-
Permalink:
mohithgowdak/graphsearch@7e7d6f767c90e019563f72704c20de5d6b0fdd14 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/mohithgowdak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@7e7d6f767c90e019563f72704c20de5d6b0fdd14 -
Trigger Event:
push
-
Statement type: