Available for: UI for ASP.NET MVC | UI for ASP.NET AJAX | UI for Blazor | UI for WPF | UI for WinForms | UI for Silverlight | UI for Xamarin | UI for WinUI | UI for ASP.NET Core | UI for .NET MAUI

New to Telerik Document Processing? Download free 30-day trial

Custom PartialContextQuestionProcessor

Minimum Version: Q4 2025

This article explains how to create a custom PartialContextQuestionProcessor configuration by supplying your own IContextRetriever and related interface implementations. You can tailor every step: splitting text, producing embeddings, ranking relevance, enforcing token limits, formatting context, and retrieving it efficiently to optimize performance, cost, accuracy, or compliance.

When you need full control over fragmentation, embedding, similarity ranking, and retrieval, use the constructor that accepts an IContextRetriever:

PartialContextQuestionProcessor(
    IChatClient chatClient,
    IContextRetriever contextRetriever,
    IEmbeddingSettings settings,
    SimpleTextDocument document)

This constructor gives you end‑to‑end control over how document text is fragmented, embedded, stored, and later selected (ranked) as context for a question, forming your custom PartialContextQuestionProcessor pipeline.

Interfaces

All extension points live in Telerik.Documents.AI.Core (as abstractions) with their default implementations in Telerik.Documents.AI.RAG:

Interface Responsibility Used By
IContextFragmentsManager Splits raw document text into token-bounded semantic fragments (pages, sections, paragraphs) Fragmentation stage
IEmbedder Converts fragments into embeddings/vectors for similarity comparison Embedding stage
ISimilarityCalculator Scores fragment relevance against a question/prompt Ranking stage
ITokensCounter Counts tokens for limits enforcement (fragment size, total context) Throughout pipeline
IEmbeddingSettings Provides token & size limits + formatting hints Configuration source
IContextRetriever Orchestrates loading text, preparing embeddings, and returning best context Retrieval stage
ISupportJsonEmbeddings / ISupportPlainTextEmbeddings Control how context is formatted for the model (JSON vs plain text) Formatting stage
IFragments / IFragment Data structures representing chunk collections and individual chunks Shared across stages

Life Cycle

  1. SetContextAsync(text, embeddingTokenSize) - Text is fragmented (IContextFragmentsManager), tokens checked (ITokensCounter), embeddings generated (IEmbedder), and stored.
  2. Question time (GetContextAsync(question)) - Similarity scores computed (ISimilarityCalculator), top fragments selected within limits, context formatted (plain or JSON).
  3. Processor sends formatted context + question via IChatClient and returns model answer.

Custom Implementation

The example below constructs a custom PartialContextQuestionProcessor by supplying a DefaultContextRetriever that mixes user implementations (custom IContextFragmentsManager and IEmbedder) with default components (DefaultSimilarityCalculator, DefaultTokensCounter, and the retriever's own orchestration). This hybrid approach lets you optimize the most impactful stages (fragmentation + embedding) without rewriting the entire retrieval pipeline.

DefaultEmbedder is only available on net8-windows and higher. On other target frameworks you must supply your own IEmbedder (as shown below with CustomOpenAIEmbedder).

// Load the XLSX document
string filePath = @"path\to\your\document.xlsx";
XlsxFormatProvider formatProvider = new XlsxFormatProvider();
Workbook workbook;

using (FileStream fs = File.OpenRead(filePath))
{
    workbook = formatProvider.Import(fs, TimeSpan.FromSeconds(10));
}

// Convert the document to a simple text representation
SimpleTextDocument plainDoc = workbook.ToSimpleTextDocument(TimeSpan.FromSeconds(10));

// Set up the AI client (Azure OpenAI in this example)
string key = "AZUREOPENAI_KEY";
string endpoint = "AZUREOPENAI_ENDPOINT";
string model = "gpt-4o-mini";

Azure.AI.OpenAI.AzureOpenAIClient azureClient = new AzureOpenAIClient(
    new Uri(endpoint),
    new Azure.AzureKeyCredential(key),
    new Azure.AI.OpenAI.AzureOpenAIClientOptions());
ChatClient chatClient = azureClient.GetChatClient(model);

IChatClient iChatClient = new OpenAIChatClient(chatClient);
int maxTokenCount = 128000;
int maxNumberOfEmbeddingsSent = 20;
int embeddingTokenSize = 500;

IEmbeddingSettings settings = EmbeddingSettingsFactory.CreateSettingsForSpreadDocuments(maxTokenCount, produceJsonFormattedContext: false);
IContextFragmentsManager customContextFragmentsManager = new CustomOpenAIContextFragmentsManager(new DefaultTokensCounter(settings)); // Implemented by the user
IEmbedder customEmbedder = new CustomOpenAIEmbedder();
DefaultContextRetriever defaultContextRetriever = new DefaultContextRetriever(
    customContextFragmentsManager,
    customEmbedder,
    new DefaultSimilarityCalculator(customEmbedder),
    new DefaultTokensCounter(settings),
    settings);

using (PartialContextQuestionProcessor partialContextQuestionProcessor =
    new PartialContextQuestionProcessor(
        iChatClient,
        defaultContextRetriever,
        settings,
        plainDoc))
{
    string question = "What is the main topic of the document?";
    string answer = await partialContextQuestionProcessor.AnswerQuestion(question);
    Console.WriteLine("Answer: " + answer);
}

See Also

In this article