RagAccelerator 1.3.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package RagAccelerator --version 1.3.0
                    
NuGet\Install-Package RagAccelerator -Version 1.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="RagAccelerator" Version="1.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RagAccelerator" Version="1.3.0" />
                    
Directory.Packages.props
<PackageReference Include="RagAccelerator" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add RagAccelerator --version 1.3.0
                    
#r "nuget: RagAccelerator, 1.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package RagAccelerator@1.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=RagAccelerator&version=1.3.0
                    
Install as a Cake Addin
#tool nuget:?package=RagAccelerator&version=1.3.0
                    
Install as a Cake Tool

RagAccelerator

A stateless RAG processing engine as a NuGet library. Install it, register it, and call the services in-process — no HTTP, no App Service, no API key, and nothing is persisted. You keep your own database and store whatever the calls return.

All model credentials + settings are supplied per call (embeddings, chat, OCR) — the library owns no keys.

Install

dotnet add package RagAccelerator

Register

using RagAccelerator;

builder.Services.AddRagAccelerator(builder.Configuration); // configuration optional

Ingest one document — three modes

Pick the mode that matches how you search:

Mode Call Needs embedding creds? Chunk output
Vector (semantic) ProcessAsync Yes Embedding[]
BM25 / vectorless (keyword) ProcessLexicalAsync No Bm25Text
Both (hybrid) ProcessHybridAsync Yes Embedding[] + Bm25Text
using Rag.Application.Abstractions;
using Rag.Application.DTOs;
using Rag.Application.Common;

public class MyIngest(IDocumentProcessingService processing)
{
    // Content is a Stream — pass a SharePoint/blob download stream or File.OpenRead(path).
    public Task<DocumentProcessingResult> RunAsync(Stream content, string fileName) =>
        processing.ProcessAsync(new DocumentProcessingRequest   // Vector mode
        {
            Content = content,
            FileName = fileName,
            // Chunking (optional; default TopicWise)
            ChunkingStrategy = (int)Rag.Domain.Enums.ChunkingStrategyType.TopicWise,
            OverlapPercentage = 15,
            // Embedding (required for Vector/Both — your vendor + creds)
            EmbeddingSpec = new EmbeddingSpec(
                deployment: "text-embedding-3-large",
                dimensions: 3072,
                endpoint: "https://your-aoai.openai.azure.com/",
                apiKey: "<key>",
                provider: AIProvider.AzureOpenAI)
            // OCR fields (OcrEngine/OcrEndpoint/OcrApiKey/ImageProcessingEnabled) only for images/scanned docs.
        });
    // result.Chunks: [{ Index, Text, Embedding[], Bm25Text, PageNumber }]  → store in YOUR DB.
    // Unsupported type → result.Skipped == true (not an exception).
}

Supported types: pdf, doc, docx, xls, xlsx, ppt, pptx, png, jpg, jpeg, txt, html.

Input forms — stream, bytes, or raw text

Same three modes (Vector / BM25 / Hybrid) are available for each input form:

Input Methods Notes
Stream ProcessAsync / ProcessLexicalAsync / ProcessHybridAsync (DocumentProcessingRequest) file stream from disk/SharePoint/blob
Bytes ProcessBytesAsync / ProcessBytesLexicalAsync / ProcessBytesHybridAsync (DocumentBytesRequest) in-memory byte[]; OCR/extraction still apply
Text ProcessTextAsync / ProcessTextLexicalAsync / ProcessTextHybridAsync (TextIngestionRequest) raw string (e.g. scraped web text); no OCR
// Raw text you already have (e.g. scraped) — Url is REQUIRED (source reference; never fetched).
var result = await processing.ProcessTextAsync(new TextIngestionRequest
{
    Text = scrapedText,
    Url = "https://example.com/policies",   // becomes result.DocumentName / citation
    EmbeddingSpec = embeddingSpec            // omit for ProcessTextLexicalAsync (BM25-only)
});

BM25 / vectorless storage (Postgres)

ProcessLexicalAsync/ProcessHybridAsync set chunk.Bm25Text — the normalized text you store for full-text/BM25 search. Store it once and let Postgres build the index; nothing else to do per insert:

ALTER TABLE chunks ADD COLUMN bm25_text text;
ALTER TABLE chunks ADD COLUMN tsv tsvector
    GENERATED ALWAYS AS (to_tsvector('english', bm25_text)) STORED;
CREATE INDEX chunks_tsv_idx ON chunks USING GIN (tsv);
-- rank at query time with ts_rank(tsv, plainto_tsquery('english', @q))  (or pg_search for true BM25)

BM25-only ingest (ProcessLexicalAsync) needs no embedding credentials.

QnA

// 1) Embed the question, then run vector similarity search in YOUR DB.
float[] qvec = await embedding.EmbedAsync(question, embeddingSpec);

// 2) Answer over the chunks you retrieved.
AnswerResult answer = await answering.AnswerAsync(new AnswerRequest
{
    Question = question,
    Chunks = topChunks.Select(c => new AnswerChunk { Text = c.Text, DocumentName = c.Name }).ToList(),
    ChatSpec = new ChatModelSpec(AIProvider.AzureOpenAI, "https://your-aoai.openai.azure.com/", "<key>", "gpt-4o"),
    Persona = "You are a helpful HR assistant.",
    IncludeSuggestedQuestions = true
});
// answer.Answer, answer.References, answer.SuggestedQuestions, answer.Summary

(IEmbeddingService embedding, IAnswerService answering injected.)

Answer options (all optional)

  • CustomSystemPrompt — supply your own answer prompt (adds to the built-in grounding prompt / Persona / Instructions). The mandatory security preamble is always applied on top — overriding the prompt never removes injection guardrails.
  • IncludeSuggestedQuestions (+ SuggestedQuestionsPrompt) — return 2 follow-ups; custom prompt optional.
  • IncludeSummary (+ SummaryPrompt) — return a short summary of the answer; custom prompt optional.
  • SanitizeOutput — strip markdown links/images + bare URLs from outputs (anti-exfiltration). Default off.

Rule for every prompt field: you supply one → it's used; you don't → our default.

Multiturn: rewrite a follow-up (IQuestionRewriteService)

Turn "what about 2024?" into a standalone question using the last few turns, before you retrieve:

var r = await rewriting.RewriteAsync(new RewriteQuestionRequest
{
    Question = "what about 2024?",
    History = last5.Select(t => new ConversationTurn { Question = t.Q, Answer = t.A }).ToList(),
    ChatSpec = chatSpec           // CustomPrompt optional
});
// r.RewrittenQuestion → embed / search / AnswerAsync

Composite questions: split into sub-queries (IQuerySplitService)

var s = await splitting.SplitAsync(new SplitQueryRequest { Question = q, ChatSpec = chatSpec });
// s.IsComposite, s.SubQueries  → retrieve + answer each, then merge (CustomPrompt optional)

Security (prompt injection)

The attacker surface is the end-user question and poisoned document content (indirect injection) — not you, the developer. Enforced automatically (no setup):

  • A mandatory anti-injection preamble on every system prompt (can't be removed by a custom prompt).
  • Untrusted context is spotlighted in a random per-request fence and sanitized (chunk text, source labels, and conversation history can't forge prompt structure).
  • Input length caps (SecurityOptions; generous defaults — normal top-N chunks pass untouched) guard context-stuffing and cost/DoS.
  • Structural calls (split/rewrite/summary/suggested) run at temperature 0; content-filter rejections aren't blindly retried.

Opt-in:

  • AnswerRequest.SanitizeOutput = true — strip exfiltration links from outputs.
  • IContentSafety hook (default no-op). Register AzurePromptShieldsContentSafety to screen questions/context/output with Azure AI Content Safety Prompt Shields:
    services.AddScoped<IContentSafety>(sp => new AzurePromptShieldsContentSafety(
        sp.GetRequiredService<IHttpClientFactory>(), "<content-safety-endpoint>", "<key>"));
    

Honest limits — injection can't be 100% solved in a stateless library. Also do: enable model-side Prompt Shields, use least-privilege keys, don't auto-render links from Answer/SuggestedQuestions/Summary, treat OCR/GPT-Vision text and conversation history as untrusted, and never paste raw end-user text into CustomSystemPrompt (the trusted zone).

Token usage / cost

Every LLM call reports token usage (input/output/total + model) so you can attribute cost. The library returns tokens only — dollar cost is derived downstream (e.g. Langfuse maps model + tokens → $).

Where usage shows up:

  • AnswerResult.AnswerUsage, .SuggestedQuestionsUsage, .SummaryUsage, and .TotalUsage (combined).
  • SplitQueryResult.Usage, RewriteQuestionResult.Usage (null when rewrite is skipped).
  • DocumentProcessingResult.EmbeddingUsage (null in BM25-only mode).
  • Granular: IChatCompletionService.CompleteWithUsageAsync(...) and IEmbeddingService.EmbedWithUsageAsync(...) / EmbedBatchWithUsageAsync(...).

Combine across a whole request and feed it to your tracing tool:

var total = TokenUsage.Combine(rewrite.Usage, split.Usage, queryEmbed.Usage, answer.TotalUsage);
// e.g. tag an OpenTelemetry span so Langfuse computes cost:
span?.SetTag("gen_ai.request.model", total.Model);
span?.SetTag("gen_ai.usage.input_tokens", total.InputTokens);
span?.SetTag("gen_ai.usage.output_tokens", total.OutputTokens);

Notes: all counts are nullable — AWS Titan reports input tokens only, Cohere reports none. TopicWise chunking's boundary-detection embeddings are not counted in EmbeddingUsage (only the stored-chunk embeddings are).

Notes

  • Providers: embeddings — Azure OpenAI, OpenAI, AWS Bedrock; chat — Azure OpenAI, OpenAI; OCR — Azure Document Intelligence, GptVision.
  • One document per call (bounded response). You enumerate/fetch your own documents.
  • HTTPS is your responsibility — credentials travel in the call arguments.
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated