Chat with your documents using 100% local Ollama models, Docling parsing, and a LangGraph multi-agent workflow.
DocChat is a privacy-focused, fully local document Question-Answering (QA) application. It ingests complex document formats (PDF, DOCX, TXT, MD), splits them using header-aware Markdown parsing, indexes them with a hybrid BM25 + ChromaDB vector retriever, and uses a multi-agent LangGraph workflow to generate and verify factual answers strictly anchored in source content.
- 📄 Multi-Format Document Ingestion: Employs Docling (
DocumentConverter) for robust document parsing into Markdown, followed by header-aware splitting (MarkdownHeaderTextSplitter). - ⚡ Hash-Based Caching & Deduplication: Generates SHA-256 content hashes to cache parsed document chunks in
document_cache/(with configurable expiration, default 7 days), preventing redundant parsing across queries. Deduplicates identical chunks across multiple uploaded files. - 🔍 Hybrid Retrieval System: Blends lexical search (BM25Retriever) and dense vector search (ChromaDB with
OllamaEmbeddings) via anEnsembleRetriever(weighted 40% BM25 / 60% Chroma vector). - 🤖 Multi-Agent LangGraph Pipeline:
- Relevance Checker: Classifies document coverage (
CAN_ANSWER,PARTIAL,NO_MATCH) to reject off-topic questions early. - Research Agent: Synthesizes clear, factual draft answers using local Ollama LLMs (e.g.,
llama3:latest). - Verification Agent: Audits generated answers against original source documents for factual alignment, flags unsupported claims or contradictions, and automatically routes back for re-research if validation fails.
- Relevance Checker: Classifies document coverage (
- 🎨 Interactive Gradio Web UI: Features document upload, pre-configured example questions/files, real-time draft answer generation, and explicit verification reports.
flowchart TD
A[Upload Documents] --> B[Docling Conversion & MD Splitting]
B --> C[SHA-256 Hash Caching & Deduplication]
C --> D[Hybrid Retriever: BM25 + ChromaDB]
D --> E[Relevance Checker Node]
E -->|NO_MATCH| F[Return Off-Topic Notice]
E -->|CAN_ANSWER / PARTIAL| G[Research Agent Node]
G --> H[Verification Agent Node]
H -->|Supported / Verified| I[Final Draft Answer & Verification Report]
H -->|Unsupported / Irrelevant| G
chat_docs/
├── app.py # Main Gradio application entry point
├── config/
│ ├── constants.py # Upload limits and supported file extensions
│ └── settings.py # Pydantic Settings & environment variables
├── document_processor/
│ └── file_handler.py # Docling document conversion, MD splitting, hashing & cache manager
├── retriever/
│ └── builder.py # Hybrid EnsembleRetriever builder (ChromaDB + BM25)
├── agents/
│ ├── workflow.py # LangGraph state machine & multi-agent pipeline
│ ├── relevance_checker.py # Document-question relevance classification agent
│ ├── research_agent.py # RAG answer generation agent
│ └── verification_agent.py # Answer verification & fact-auditing agent
├── utils/
│ └── logging.py # Loguru logging configuration
├── test/
│ └── test1.py # Docling vs LangChain PDF parser benchmarks
├── pyproject.toml # Dependencies & project metadata (uv / pip)
├── requirements.txt # Dependency manifest
└── README.md # Project documentation
- Python:
>= 3.12 - Ollama: Installed and running locally (ollama.com)
DocChat requires an LLM for reasoning and an embedding model for vector retrieval:
ollama pull llama3
ollama pull nomic-embed-textClone the repository and install dependencies using uv (recommended) or pip:
Using uv:
uv syncUsing pip:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtAll application settings are defined in config/settings.py and can be customized via a .env file in the project root:
| Environment Variable | Default Value | Description |
|---|---|---|
OLLAMA_BASE_URL |
http://localhost:11434 |
URL of the local Ollama instance |
LLM_MODEL |
llama3:latest |
Local LLM model name for research & verification |
EMBEDDING_MODEL |
nomic-embed-text:latest |
Embedding model for ChromaDB vector store |
CHROMA_DB_PATH |
./chroma_db |
Path to persistent ChromaDB storage |
CHROMA_COLLECTION_NAME |
documents |
Chroma collection identifier |
VECTOR_SEARCH_K |
10 |
Top-K document chunks to retrieve via vector search |
HYBRID_RETRIEVER_WEIGHTS |
[0.4, 0.6] |
Weights for BM25 and Vector search [bm25_weight, vector_weight] |
MAX_FILE_SIZE |
52428800 (50MB) |
Max single file size limit (bytes) |
MAX_TOTAL_SIZE |
209715200 (200MB) |
Max total batch file size limit (bytes) |
CACHE_DIR |
document_cache |
Cache directory for processed document chunks |
CACHE_EXPIRE_DAYS |
7 |
Document chunk cache expiration period (days) |
Launch the Gradio web interface:
python app.pyOnce running, access the web interface in your browser at:
http://127.0.0.1:5000
- Upload Documents: Select one or more
.pdf,.docx,.txt, or.mdfiles (up to 200MB total). - Enter Question: Type your query into the question text area.
- Submit: Click Submit 🚀 to run the multi-agent pipeline.
- View Results:
- Draft Answer: Factually grounded answer generated from your uploaded files.
- Verification Report: Breakdown showing whether claims are supported, any unsupported claims or contradictions, and relevance status.
Run document parsing benchmark tests (comparing Docling and LangChain PDF loaders):
python test/test1.pyThis project is open-source software under the project license.