A .NET 9 real-time, file-driven RAG (Retrieval-Augmented Generation) engine that watches a folder, ingests documents, and serves fast answers over an HTTP API (with Qdrant vector search).
Click to watch the demo video
- Real-time ingestion: watches a folder and keeps your index up to date
- Formats:
.pdf,.docx,.txt,.md,.html,.png,.jpg,.jpeg,.webp - Providers: OpenAI / Azure OpenAI / Anthropic / Ollama (local)
- Vector store: Qdrant
- API:
/api/query,/api/documents,/api/health - Example UI: mock company landing page + popup help chat (
examples/HelpChat)
- Tutorial 1: Local dev (recommended): Ollama + Qdrant +
dotnet run(fastest to try) - Tutorial 2: HelpChat demo UI: run a static page that calls your local API
- Tutorial 3: Docker deploy:
docker-compose up -d(self-contained stack) - Tutorial 4: Testing: fast vs integration tests
- Tutorial 5: Production tips: hardening checklist
This uses the defaults in src/DNFileRAG/appsettings.Development.json:
- API on
http://localhost:8181 ApiSecurity:RequireApiKey = false(no key needed)- Embeddings + LLM via Ollama
- Qdrant vector size 1024 (matches
mxbai-embed-large)
docker run -p 6333:6333 -p 6334:6334 qdrant/qdrantollama pull mxbai-embed-large
ollama pull llama3.2:3b
ollama pull llavaImages: Vision extraction is enabled by default in Development via
Vision:Enabled=trueand uses the Ollama modelllava(configurable).
dotnet run --project ./src/DNFileRAGPut files into:
src/DNFileRAG/data/documents/
If you want to watch a different folder, change FileWatcher:WatchPath in:
src/DNFileRAG/appsettings.Development.json
curl http://localhost:8181/api/documents- cURL
curl -X POST http://localhost:8181/api/query \
-H "Content-Type: application/json" \
-d "{\"query\":\"What are our support hours?\"}"- PowerShell
Invoke-RestMethod http://localhost:8181/api/query -Method Post -ContentType "application/json" -Body (@{ query = "What are our support hours?" } | ConvertTo-Json)HelpChat is a static mock company page under examples/HelpChat/ that opens a popup chat and calls your local DNFileRAG API.
Follow Tutorial 1 so the API is running at http://localhost:8181.
cd examples/HelpChat
python -m http.server 3000Open http://localhost:3000 and click Help.
You can open
examples/HelpChat/index.htmldirectly, but some browsers restrictfile://pages from callinghttp://localhost.
This uses docker-compose.yml to run:
- Qdrant
- Ollama
- DNFileRAG API on
http://localhost:8080
docker-compose up -dFiles in ./documents are mounted into the container at /app/data/documents:
mkdir -p documents
cp /path/to/your/files/* documents/curl -X POST http://localhost:8080/api/query \
-H "Content-Type: application/json" \
-d '{"query":"What are our support hours?"}'docker-compose down
docker-compose down -v # also removes Qdrant + Ollama volumes- Windows (PowerShell)
dotnet test .\DNFileRAG.sln -c Release --filter "Category!=Integration"- macOS/Linux (bash/zsh)
dotnet test ./DNFileRAG.sln -c Release --filter "Category!=Integration"Integration tests may start Docker containers (Testcontainers) and will run slower.
- Windows (PowerShell)
dotnet test .\DNFileRAG.sln -c Release- macOS/Linux (bash/zsh)
dotnet test ./DNFileRAG.sln -c ReleaseTests use FluentAssertions. If you plan commercial use, you may need a commercial license (see the warning emitted during test runs).
- Enable API keys: set
ApiSecurity:RequireApiKey = trueand configureApiSecurity:ApiKeys. - Run behind HTTPS: terminate TLS at a reverse proxy (or configure Kestrel HTTPS). Ensure forwarded headers are configured if applicable.
- CORS: lock down origins (avoid
AllowAnyOrigin()for production).
- Persist Qdrant: store Qdrant data on durable storage (volumes/backups).
- Health checks: use
/api/healthand/api/health/detailedfor monitoring. - Resource sizing: embeddings + parsing can be CPU/RAM heavy; size accordingly.
- Vector size must match your embedding model (e.g.,
mxbai-embed-large→ 1024). - Tune chunking:
Chunking:ChunkSizeandChunking:ChunkOverlap. - Tune retrieval:
Rag:DefaultTopKandRag:MinRelevanceScore.
- Logging: keep Production log levels at Info/Warn (Debug is noisy).
- Documents path: ensure your
FileWatcher:WatchPathpoints to the mounted directory in your environment.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/query |
Query the RAG engine |
GET |
/api/documents |
List indexed documents |
POST |
/api/documents/reindex |
Trigger full reindex |
DELETE |
/api/documents?filePath=... |
Remove a document from the index |
GET |
/api/health |
Basic health check |
GET |
/api/health/detailed |
Detailed component health status |
dotnet add package DNFileRAG.InfrastructureThen register services:
using DNFileRAG;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddDNFileRAGServices(builder.Configuration);DNFileRAG/
├── src/
│ ├── DNFileRAG/ # Web API host
│ ├── DNFileRAG.Core/ # Domain models & interfaces
│ └── DNFileRAG.Infrastructure/ # External service implementations
├── tests/
│ └── DNFileRAG.Tests/ # Test suite
└── examples/
└── HelpChat/ # Mock landing page + popup support chat
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT License — see LICENSE.
- Qdrant - Vector database
- Serilog - Structured logging
- PdfPig - PDF parsing
- DocumentFormat.OpenXml - DOCX parsing