New to Telerik Document ProcessingStart a free 30-day trial

Custom PartialContextQuestionProcessor

Updated on Jun 16, 2026

This article explains how to create a custom PartialContextQuestionProcessor configuration by supplying your own IContextRetriever and related interface implementations. You can tailor every step—text splitting, embedding production, relevance ranking, token limit enforcement, context formatting, and retrieval—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:

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

This constructor gives you end-to-end control over how the pipeline fragments, embeds, stores, and selects document text as context for a question.

Interfaces

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

InterfaceResponsibilityUsed By
IContextFragmentsManagerSplits raw document text into token-bounded semantic fragments (pages, sections, paragraphs)Fragmentation stage
IEmbedderConverts fragments into embeddings/vectors for similarity comparisonEmbedding stage
ISimilarityCalculatorScores fragment relevance against a question/promptRanking stage
ITokensCounterCounts tokens for limits enforcement (fragment size, total context)Throughout pipeline
IEmbeddingSettingsProvides token and size limits plus formatting hintsConfiguration source
IContextRetrieverOrchestrates loading text, preparing embeddings, and returning best contextRetrieval stage
ISupportJsonEmbeddings / ISupportPlainTextEmbeddingsControls how context is formatted for the model (JSON versus plain text)Formatting stage
IFragments / IFragmentData structures representing chunk collections and individual chunksShared across stages

Life Cycle

  1. SetContextAsync(text, embeddingTokenSize)—The IContextFragmentsManager fragments the text, ITokensCounter checks tokens, and IEmbedder generates and stores embeddings.
  2. GetContextAsync(question)—The ISimilarityCalculator computes similarity scores, selects top fragments within limits, and formats context (plain text or JSON).
  3. The processor sends the formatted context and the question through IChatClient and returns the model answer.

Custom Implementation

The following example 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 and embedding) without the need to rewrite the entire retrieval pipeline.

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

C#
// Load the DOCX document
string filePath = @"path\to\your\document.docx";
DocxFormatProvider formatProvider = new DocxFormatProvider();
RadFlowDocument flowDocument;

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

// Convert the document to a simple text representation
SimpleTextDocument plainDoc = flowDocument.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 = (IChatClient)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