यह है भाग 5 DocSummarizer श्रृंखला के ',' और यह''' भी के चरमोत्कर्ष ग्राफ आर ए जी श्रृङ्खला और अर्थ खोज श्रृङ्खलाहम सब कुछ एक विस्थापित वेब अनुप्रयोग में सम्मिलित कर रहे हैं
पूर्वावलोकन अनुच्छेद 🚨🚨 अभी भी कुछ kinks का निर्माण कर रहा है और विशेषताओं को जोड़ने के लिए।
RAG अवसंरचना का निर्माण करने की पूरी बात यह है कि उसे किसी वास्तविक चीज़ के लिए उपयोग करना।
पिछले कुछ सप्ताहों के दौरान हम
अब हम उन में एक साथ तार सुस्पष्टRAG बहुविध के लिए एक स्टैंडलोन वेब अनुप्रयोग
वेबसाइट lucidrag.com | स्रोत: जिटहब
दस्तावेजों को अपलोड करें. प्रश्न पूछें
प्रमुख विशेषताएँ
डिजाइन प्रतिबंध
किसी भी बिंदु में LLMs chunking के लिए प्रयोग नहीं किया जाता है।
एकल सदिश खोज कुछ क्वेरी प्रकारों के लिए टूटती है
Query Type |------------|----------------------|----------------| | क्रॉस | Entity-centric | | "Docker के बारे में क्या है? | वैश्विक सारांश
lucidRAG precision के लिए दोनों सदिशों का उपयोग करता है
एप्लिकेशन लेयर हम पहले से ही बनाया है तीन परियोजनाओं के लिए-' स्टिलियोफ्लो एक सिग्नल
lucidRAG
├── Controllers/Api/ # REST endpoints
├── Services/ # Business logic
│ ├── DocumentProcessingService # Wraps DocSummarizer
│ ├── EntityGraphService # Wraps GraphRAG
│ └── Background/ # Async queue processing (StyloFlow waves)
└── Views/ # HTMX + Alpine.js UI
क्यों StyloFlow हार्डकोड पाइपलाइनों के बजाय प्रत्येक प्रक्रमण चरण एक "वाव्वाव" है जो संकेत जारी करता है। स्टिलियोफ्लो: सिग्नल क्रियान्वयन विवरण के लिए
जब आप एक दस्तावेज़ अपलोड करते हैं तो यह तीन चरणों के माध्यम से प्रवाहित होता है
अपलोड अंतबिंदु फ़ाइल को वैध करता है
public async Task<Guid> QueueDocumentAsync(Stream fileStream, string fileName)
{
// Compute hash to detect duplicates
var contentHash = ComputeHash(fileStream);
var existing = await _db.Documents
.FirstOrDefaultAsync(d => d.ContentHash == contentHash);
if (existing != null)
return existing.Id; // Already processed
कुंजी अंतर्दृष्टि
// Save to disk, create DB record
var docId = Guid.NewGuid();
await SaveFileToDiskAsync(fileStream, docId, fileName);
// Queue for background processing
await _queue.EnqueueAsync(new DocumentProcessingJob(docId, filePath));
return docId;
}
पृष्ठभूमि प्रोसेसर लामबद्ध दस्तावेज उठाता है और उन्हें DocSummarizer के माध्यम से चलाता है
var result = await _summarizer.SummarizeFileAsync(job.FilePath, progressChannel);
यह एकल लाइन बहुत काम करता है DocSummarizer भाग 1):
chunking के बाद हम GraphRAG का उपयोग कर इकाइयां निकालते हैं
var segments = await _vectorStore.GetDocumentSegmentsAsync(documentId);
var entityResult = await _entityGraph.ExtractAndStoreEntitiesAsync(documentId, segments);
यह IDF स्कोरिंग और संरचनात्मक संकेतों के बजाय per -chunk LLM कॉल्स का उपयोग करता है GraphRAG भाग 2 विवरण के लिए.
एक naiv implementation would use unbounded queues
private readonly Channel<DocumentProcessingJob> _queue =
Channel.CreateBounded<DocumentProcessingJob>(new BoundedChannelOptions(100)
{
FullMode = BoundedChannelFullMode.Wait
});
जब कतार भरी जाती है Wait मोड खाली स्थान खोलने तक नए लेखन को रोकता है
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
timeoutCts.CancelAfter(TimeSpan.FromMinutes(5));
try {
await _queue.Writer.WriteAsync(job, timeoutCts.Token);
} catch (OperationCanceledException) when (!ct.IsCancellationRequested) {
throw new InvalidOperationException("Queue full. Try again later.");
}
बड़े दस्तावेजों को प्रक्रिया करने में मिनट लग सकते हैं।
while (!stoppingToken.IsCancellationRequested)
{
var job = await _queue.DequeueAsync(stoppingToken);
// 30-minute timeout per document
using var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken);
timeoutCts.CancelAfter(TimeSpan.FromMinutes(30));
try {
await ProcessDocumentAsync(job, timeoutCts.Token);
} catch (OperationCanceledException) when (!stoppingToken.IsCancellationRequested) {
await MarkDocumentFailedAsync(job.DocumentId, "Processing timed out");
}
}
लिंक टोकन यह सुनिश्चित करता है कि हम अभी भी अनुप्रयोग बंद करने का सम्मान करते हैं जब पर per जोड़ें
प्रत्येक प्रक्रमण दस्तावेज को एसईएस अद्यतन के लिए प्रगति चैनल मिलता है।
private readonly ConcurrentDictionary<Guid, ProgressChannelEntry> _progressChannels = new();
public int CleanupAbandonedChannels()
{
var cutoff = DateTimeOffset.UtcNow - TimeSpan.FromHours(1);
var cleaned = 0;
foreach (var kvp in _progressChannels.Where(x => x.Value.CreatedAt < cutoff))
{
if (_progressChannels.TryRemove(kvp.Key, out var entry))
{
entry.Channel.Writer.TryComplete();
cleaned++;
}
}
return cleaned;
}
ए PeriodicTimer पृष्ठभूमि प्रोसेसर में हर 15 मिनट यह कॉल करता है
हम विभिन्न प्रयोजनों के लिए दो डेटाबेस का उपयोग करते हैं
PostgreSQL/SQLite (EF Core दस्तावेज़ मेटाडेटा भंडारित करता है - क्या मौजूद है, प्रक्रमण स्थिति
डक डीबी सदिशों और अस्तित्व ग्राफ को भंडारित करता है
// Metadata in PostgreSQL
public class DocumentEntity
{
public Guid Id { get; set; }
public string Name { get; set; }
public string ContentHash { get; set; }
public DocumentStatus Status { get; set; }
}
// Vectors in DuckDB (managed by DocSummarizer)
// Entities in DuckDB (managed by GraphRAG)
उत्प्रेरक खोज पाइपलाइन के माध्यम से प्रश्न प्रवाहित होते हैं
[HttpPost]
public async Task<IActionResult> ChatAsync([FromBody] ChatRequest request)
{
// 1. Get or create conversation for memory
var conversation = await GetOrCreateConversationAsync(request.ConversationId);
// 2. Search with hybrid retrieval
var searchResult = await _search.SearchAsync(request.Query, new SearchOptions
{
TopK = 10,
IncludeGraphData = request.IncludeGraphData
});
खोज सेवा आवश्यकता पड़ने पर क्वेरी विघटन को नियंत्रित करता है
// 3. Generate answer with LLM
var answer = await _summarizer.SummarizeAsync(
request.Query,
searchResult.Segments,
new SummarizeOptions { IncludeCitations = true });
// 4. Save to conversation history
await SaveToConversationAsync(conversation.Id, request.Query, answer);
return Ok(new ChatResponse
{
Answer = answer.Text,
Sources = answer.Citations,
GraphData = searchResult.GraphData
});
}
यूआई एक एकल पृष्ठ है जिसमें दस्तावेज बाएँ पर हैं
┌──────────────────┬─────────────────────────────────────┐
│ 📁 Documents │ 💬 Chat │
│ ───────────── │ [Answer] [Evidence] [Graph] │
│ [+ Upload] │ │
│ 📄 api-docs.pdf │ Q: How does auth work? │
│ 📝 readme.md │ A: JWT tokens stored... [1][2] │
│ ───────────── │ │
│ 🕸️ Graph: 168 │ ┌─────────────────────────────┐ │
│ │ │ Ask about your documents... │ │
└──────────────────┴──┴─────────────────────────────┴───┘
Alpine.js राज्य को प्रबंधित करता है
function ragApp() {
return {
messages: [],
isTyping: false,
async sendMessage() {
const query = this.currentMessage.trim();
this.messages.push({ role: 'user', content: query });
this.isTyping = true;
const result = await fetch('/api/chat', {
method: 'POST',
body: JSON.stringify({ query })
}).then(r => r.json());
this.messages.push({
role: 'assistant',
content: result.answer,
sources: result.sources
});
this.isTyping = false;
}
};
}
Lucidrag जैसे सार्वजनिक विनियोजनों के लिए डेमो मोड अक्षम करता है और पूर्व प्रयोग करता है।
public class DemoModeConfig
{
public bool Enabled { get; set; } = false;
public string ContentPath { get; set; } = "./demo-content";
public string BannerMessage { get; set; } = "Demo Mode: Pre-loaded RAG articles";
}
ए DemoContentSeeder पृष्ठभूमि सेवा सामग्री निर्देशिका को देखता है और किसी भी छोड़े गए फ़ाइलों को प्रक्रमित करता है
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
if (!_config.DemoMode.Enabled) return;
await SeedExistingContentAsync();
StartFileWatcher(_config.DemoMode.ContentPath);
}
यह आपको सिर्फ फ़ाइलों को प्रतिलिपि करके डेमो सामग्री अद्यतन करने देता है
dotnet run --project Mostlylucid.RagDocuments -- --standalone
SQLite का उपयोग करता है + DuckDB स्थानीय रूप से. खोलें http://localhost:5080.
services:
lucidrag:
build: .
ports: ["5080:8080"]
depends_on: [postgres, ollama]
घटक |-----------|--------|---------| दस्तावेज विश्लेषण | DocSummarizer | ONNX अंतःस्थापित करें | | | DocSummarizer इकाई निष्कर्षण | ग्राफ आरएग | | | IDF |+ | संरचनात्मक संकेत | हाइब्रिड खोज अतुल्य प्रक्रमण वेब यूआई
शून्य API लागत अनुक्रमण के लिए - एम्बेडिंग ONNX हैं | , | इकाइयां हेयूरिस्टिक है |. | आप केवल क्वेरी समय पर LLM संश्लेषण का भुगतान करते हैं \ , | और यह स्थानीय ओललामा से काम करता है
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.