Skip to main content

GraphSearch: a GraphQL API server for Retrieval-Augmented Generation (RAG) over your documents

Project description

GraphSearch

CI License: MIT Python 3.10+

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 }
  }
}

GraphSearch demo: asking "How do I get my money back?" in GraphiQL and getting the returns policy with ranked sources

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.
  • Composableanswer, 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

Open http://localhost:8000/graphql for the GraphiQL playground and try:

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

MIT

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

graphsearch_rag-0.2.1.tar.gz (19.9 kB view details)

Uploaded Source

Built Distribution

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

graphsearch_rag-0.2.1-py3-none-any.whl (18.2 kB view details)

Uploaded Python 3

File details

Details for the file graphsearch_rag-0.2.1.tar.gz.

File metadata

  • Download URL: graphsearch_rag-0.2.1.tar.gz
  • Upload date:
  • Size: 19.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for graphsearch_rag-0.2.1.tar.gz
Algorithm Hash digest
SHA256 727111bdc85ec4cecd7e287a7a86b0d906aea29cdbad20d3daa4fbac3abcae20
MD5 855c44c6e160bb9500839a7ed30dfb74
BLAKE2b-256 9271e5c16b292f7001cb84771d01ad2aeb8a5c890230d9bf4e1d84fa14d9d21e

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.2.1.tar.gz:

Publisher: release.yml on mohithgowdak/graphsearch

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

File details

Details for the file graphsearch_rag-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for graphsearch_rag-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d2d867bb87e3656a8cef8726a4dadae9f7456d99c1a3d2e8ab5eb90a1ec2caef
MD5 4344b23f76b2da41e9abffe503b21083
BLAKE2b-256 c99009ed1510af646217b7a860c749fe9d06f50fe708587b3f0ea7a2c744a87e

See more details on using hashes here.

Provenance

The following attestation bundles were made for graphsearch_rag-0.2.1-py3-none-any.whl:

Publisher: release.yml on mohithgowdak/graphsearch

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