# iamnikhil-adev/clinsearch architecture

> Architecture diagram of the GitHub repository iamnikhil-adev/clinsearch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/iamnikhil-adev/clinsearch
- Repository: https://github.com/iamnikhil-adev/clinsearch

## Overview

ClinSearch is a biomedical literature search and evidence-grounded RAG platform. Its main user workflow accepts a query through the CLI, REST API, or dashboard; embeds it, runs hybrid retrieval and reranking, then resolves and packages passages for citation-checked answer generation or deterministic abstention. A separate corpus workflow ingests PubMed records, persists canonical documents, chunks them, and builds a searchable index. The README documents evaluation and offline demo seeding as additional capabilities. Some subsystem links reflect that documented architecture; unsampled implementation details are not inferred.

Main entry points: [`src/clinsearch/generation/pipeline.py`](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/pipeline.py) (RAG Pipeline), [`src/clinsearch/retrieval/pipeline.py`](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/pipeline.py) (Retrieval Pipeline), [`src/clinsearch/service/app_service.py`](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/service/app_service.py) (Application Service), [`src/clinsearch/data/embeddings/service.py`](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/embeddings/service.py) (Embedding Service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["User Interfaces"]
  node_cli["CLI<br/>[cli.py]"]
  node_api["REST API<br/>[routes.py]"]
  node_dashboard["Dashboard<br/>[app.js]"]
  node_facade["Application Service<br/>[app_service.py]"]
end

subgraph group_ingest["Corpus Ingestion"]
  node_pubmed_flow["PubMed Ingestion<br/>[pipeline.py]"]
  node_raw_store[("Raw XML Store<br/>[raw_store.py]")]
  node_corpus_ingest["Corpus Ingestion<br/>[ingest.py]"]
  node_corpus[("Document Corpus<br/>[repository.py]")]
  node_demo["Demo Seed<br/>[seed.py]"]
end

subgraph group_index["Index Construction"]
  node_chunker["Biomedical Chunking<br/>[chunker.py]"]
  node_embed_service["Embedding Service<br/>[service.py]"]
  node_medcpt["MedCPT Encoder<br/>[medcpt.py]"]
  node_index_service["Hybrid Index Builder<br/>[service.py]"]
  node_index_repo[("Persistent Index<br/>[persistence.py]")]
end

subgraph group_search["Retrieval"]
  node_retrieval["Retrieval Pipeline<br/>[pipeline.py]"]
  node_dense["Dense Search<br/>[dense.py]"]
  node_lexical["BM25 Search<br/>[lexical.py]"]
  node_fusion["Rank Fusion<br/>[fusion.py]"]
  node_reranker["MedCPT Reranker<br/>[medcpt_reranker.py]"]
end

subgraph group_answer["Grounded Answers"]
  node_resolver["Chunk Resolver"]
  node_rag["RAG Pipeline<br/>[pipeline.py]"]
  node_evidence["Evidence Packer<br/>[evidence.py]"]
  node_prompt["Prompt Builder<br/>[prompt.py]"]
  node_generator["Generation Provider<br/>[hf_provider.py]"]
  node_parser["Output Parser<br/>[parser.py]"]
  node_citation["Citation Validator<br/>[citation.py]"]
  node_evaluation["RAG Evaluation<br/>[rag_evaluator.py]"]
end

node_researcher(("Researcher"))
node_pubmed(("PubMed API"))

node_researcher -->|"runs commands"| node_cli
node_researcher -->|"uses dashboard"| node_dashboard
node_researcher -->|"sends requests"| node_api
node_dashboard -->|"calls REST"| node_api
node_cli -->|"invokes"| node_facade
node_api -->|"dispatches"| node_facade
node_pubmed_flow -->|"fetches records"| node_pubmed
node_pubmed_flow -->|"archives XML"| node_raw_store
node_corpus_ingest -->|"runs ingestion"| node_pubmed_flow
node_corpus_ingest -->|"adds documents"| node_corpus
node_corpus -->|"supplies snapshot"| node_chunker
node_chunker -->|"provides chunks"| node_embed_service
node_embed_service -->|"requests embeddings"| node_medcpt
node_chunker -->|"provides chunks"| node_index_service
node_embed_service -->|"provides vectors"| node_index_service
node_index_service -->|"persists indexes"| node_index_repo
node_facade -->|"embeds query"| node_embed_service
node_facade -->|"runs retrieval"| node_retrieval
node_retrieval -->|"searches vectors"| node_dense
node_retrieval -->|"searches terms"| node_lexical
node_retrieval -->|"fuses candidates"| node_fusion
node_retrieval -->|"reranks candidates"| node_reranker
node_facade -->|"runs answering"| node_rag
node_rag -->|"retrieves passages"| node_retrieval
node_rag -->|"resolves chunks"| node_resolver
node_rag -->|"packs evidence"| node_evidence
node_rag -->|"builds prompt"| node_prompt
node_rag -->|"generates answer"| node_generator
node_rag -->|"parses output"| node_parser
node_rag -->|"validates claims"| node_citation
node_evaluation -.->|"evaluates answers"| node_facade
node_demo -.->|"seeds corpus"| node_corpus
node_demo -.->|"seeds index"| node_index_repo

click node_cli "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/cli.py"
click node_api "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/api/routes.py"
click node_dashboard "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/ui/static/app.js"
click node_facade "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/service/app_service.py"
click node_pubmed_flow "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/pubmed/pipeline.py"
click node_raw_store "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/pubmed/raw_store.py"
click node_corpus_ingest "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/corpus/ingest.py"
click node_corpus "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/corpus/repository.py"
click node_chunker "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/chunking/chunker.py"
click node_embed_service "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/embeddings/service.py"
click node_medcpt "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/embeddings/medcpt.py"
click node_index_service "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/service.py"
click node_index_repo "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/persistence.py"
click node_retrieval "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/pipeline.py"
click node_dense "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/dense.py"
click node_lexical "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/lexical.py"
click node_fusion "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/fusion.py"
click node_reranker "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/reranking/medcpt_reranker.py"
click node_resolver "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/persistent_resolver.py"
click node_rag "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/pipeline.py"
click node_evidence "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/evidence.py"
click node_prompt "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/prompt.py"
click node_generator "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/hf_provider.py"
click node_parser "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/parser.py"
click node_citation "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/citation.py"
click node_evaluation "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/evaluation/rag_evaluator.py"
click node_demo "https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/demo/seed.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_cli,node_api,node_dashboard,node_facade toneBlue
class node_pubmed_flow,node_raw_store,node_corpus_ingest,node_corpus,node_demo toneAmber
class node_chunker,node_embed_service,node_medcpt,node_index_service,node_index_repo,node_pubmed toneMint
class node_retrieval,node_dense,node_lexical,node_fusion,node_reranker toneRose
class node_resolver,node_rag,node_evidence,node_prompt,node_generator,node_parser,node_citation,node_evaluation,node_researcher toneIndigo
```

## Components

### User Interfaces

- [CLI](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/cli.py): `src/clinsearch/cli.py`
- [REST API](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/api/routes.py): `src/clinsearch/api/routes.py`
- [Dashboard](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/ui/static/app.js): `src/clinsearch/ui/static/app.js`
- [Application Service](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/service/app_service.py): `src/clinsearch/service/app_service.py`

### Corpus Ingestion

- [PubMed Ingestion](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/pubmed/pipeline.py): `src/clinsearch/data/pubmed/pipeline.py`
- [Raw XML Store](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/pubmed/raw_store.py): `src/clinsearch/data/pubmed/raw_store.py`
- [Corpus Ingestion](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/corpus/ingest.py): `src/clinsearch/data/corpus/ingest.py`
- [Document Corpus](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/corpus/repository.py): `src/clinsearch/data/corpus/repository.py`
- [Demo Seed](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/demo/seed.py): `src/clinsearch/demo/seed.py`

### Index Construction

- [Biomedical Chunking](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/chunking/chunker.py): `src/clinsearch/data/chunking/chunker.py`
- [Embedding Service](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/embeddings/service.py): `src/clinsearch/data/embeddings/service.py`
- [MedCPT Encoder](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/embeddings/medcpt.py): `src/clinsearch/data/embeddings/medcpt.py`
- [Hybrid Index Builder](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/service.py): `src/clinsearch/data/indexing/service.py`
- [Persistent Index](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/persistence.py): `src/clinsearch/data/indexing/persistence.py`

### Retrieval

- [Retrieval Pipeline](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/pipeline.py): `src/clinsearch/retrieval/pipeline.py`
- [Dense Search](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/dense.py): `src/clinsearch/data/indexing/dense.py`
- [BM25 Search](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/data/indexing/lexical.py): `src/clinsearch/data/indexing/lexical.py`
- [Rank Fusion](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/fusion.py): `src/clinsearch/retrieval/fusion.py`
- [MedCPT Reranker](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/reranking/medcpt_reranker.py): `src/clinsearch/reranking/medcpt_reranker.py`

### Grounded Answers

- [Chunk Resolver](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/retrieval/persistent_resolver.py): `src/clinsearch/retrieval/persistent_resolver.py`
- [RAG Pipeline](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/pipeline.py): `src/clinsearch/generation/pipeline.py`
- [Evidence Packer](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/evidence.py): `src/clinsearch/generation/evidence.py`
- [Prompt Builder](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/prompt.py): `src/clinsearch/generation/prompt.py`
- [Generation Provider](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/hf_provider.py): `src/clinsearch/generation/hf_provider.py`
- [Output Parser](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/parser.py): `src/clinsearch/generation/parser.py`
- [Citation Validator](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/generation/citation.py): `src/clinsearch/generation/citation.py`
- [RAG Evaluation](https://github.com/iamnikhil-adev/clinsearch/blob/main/src/clinsearch/evaluation/rag_evaluator.py): `src/clinsearch/evaluation/rag_evaluator.py`

### Other components

- **Researcher**
- **PubMed API**

## Connections

- Researcher → CLI: runs commands
- Researcher → Dashboard: uses dashboard
- Researcher → REST API: sends requests
- Dashboard → REST API: calls REST
- CLI → Application Service: invokes
- REST API → Application Service: dispatches
- PubMed Ingestion → PubMed API: fetches records
- PubMed Ingestion → Raw XML Store: archives XML
- Corpus Ingestion → PubMed Ingestion: runs ingestion
- Corpus Ingestion → Document Corpus: adds documents
- Document Corpus → Biomedical Chunking: supplies snapshot
- Biomedical Chunking → Embedding Service: provides chunks
- Embedding Service → MedCPT Encoder: requests embeddings
- Biomedical Chunking → Hybrid Index Builder: provides chunks
- Embedding Service → Hybrid Index Builder: provides vectors
- Hybrid Index Builder → Persistent Index: persists indexes
- Application Service → Embedding Service: embeds query
- Application Service → Retrieval Pipeline: runs retrieval
- Retrieval Pipeline → Dense Search: searches vectors
- Retrieval Pipeline → BM25 Search: searches terms
- Retrieval Pipeline → Rank Fusion: fuses candidates
- Retrieval Pipeline → MedCPT Reranker: reranks candidates
- Application Service → RAG Pipeline: runs answering
- RAG Pipeline → Retrieval Pipeline: retrieves passages
- RAG Pipeline → Chunk Resolver: resolves chunks
- RAG Pipeline → Evidence Packer: packs evidence
- RAG Pipeline → Prompt Builder: builds prompt
- RAG Pipeline → Generation Provider: generates answer
- RAG Pipeline → Output Parser: parses output
- RAG Pipeline → Citation Validator: validates claims
- RAG Evaluation → Application Service: evaluates answers
- Demo Seed → Document Corpus: seeds corpus
- Demo Seed → Persistent Index: seeds index
