AI-powered Extensions for DevExpress Office File API | Office File API | DevExpress Documentation (original) (raw)

The DevExpress Office File API includes AI-powered extensions that integrate with language models through Microsoft.Extensions.AI (IChatClient). Extensions are available for the Word Processing Document API, PDF Document API, and Presentation API Library.

The IChatClient interface serves as the central mechanism for language model interaction. Supported AI providers include:

Note

DevExpress AI-powered extensions operate on a “bring your own key” (BYOK) model. We do not provide a proprietary REST API or bundled language models (LLMs/SLMs).

You can either deploy a self-hosted model or connect to a cloud AI provider and obtain necessary connection parameters (endpoint, API key, language model identifier, and so on). These parameters must be configured at application startup to register an AI client and enable extension functionality.

This topic explains how to register and use available AI extensions.

View Example: Office File API – Integrate DevExpress AI-powered Extensions

Prerequisites

For details on prerequisites, see AI Integration.

DevExpress Packages

To access DevExpress packages, you need to have an active Universal Subscription or Office File API Subscription.

AI Runtime and Provider Packages

Register a Document Processing Service

DevExpress AI-powered extensions run inside an AIExtensionsContainer that manages registered AI clients. Use the AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer method to create a container and register a chat client in a .NET console application.

Console Application

Call AIDocProcessingExtensions.CreateAIDocProcessingService to create a document-processing service instance.

The following code snippet registers an Azure Open AI client and creates and extension service:

using DevExpress.AIIntegration;
using Microsoft.Extensions.AI;
using System.Globalization;

// Configure Azure OpenAI endpoint and API key via environment variables.
Environment.SetEnvironmentVariable(
    "AZURE_OPENAI_ENDPOINT",
    "<YOUR_AZURE_OPENAI_ENDPOINT>");
Environment.SetEnvironmentVariable(
    "AZURE_OPENAI_APIKEY",
    "<YOUR_AZURE_OPENAI_KEY>");
var modelName = "gpt-4o-mini";


// Register an Azure OpenAI client and obtain the
// default AI extensions container.
AIExtensionsContainerDefault defaultAIExtensionsContainer =
    RegisterAzureOpenAIClient(
        Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
        Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY"));

// Create a document processing service instance
// from the AI extensions container.
var docProcessingService =
    defaultAIExtensionsContainer.CreateAIDocProcessingService();

// Helper method that creates and configures an Azure OpenAI chat client
// and wraps it in a default AI extensions container.
AIExtensionsContainerDefault RegisterAzureOpenAIClient(
    string azureOpenAIEndpoint,
    string azureOpenAIKey)
{
    IChatClient client =
        new Azure.AI.OpenAI.AzureOpenAIClient(
            new Uri(azureOpenAIEndpoint),
            new System.ClientModel.ApiKeyCredential(azureOpenAIKey))
        .GetChatClient(modelName)
        .AsIChatClient();

    return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}

You can also instantiate the AIDocProcessingService class (the IAIDocProcessingService implementation) directly instead of the CreateAIDocProcessingService method call.

ASP.NET Core, Blazor

Call the RegisterAIDocProcessingService(AIExtensionsContainerSettings) method to register document-processing AI extensions in your dependency injection container:

using System.Globalization;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using Microsoft.Extensions.AI;

var azureOpenAIEndpoint = "<YOUR_AZURE_OPENAI_ENDPOINT>";
var azureOpenAIKey = "<YOUR_AZURE_OPENAI_API_KEY>";
var modelName = "<YOUR_MODEL_NAME>";

var builder = WebApplication.CreateBuilder(args);

// Create an Azure OpenAI client with endpoint and API key from helper.
var azureOpenAIClient = new Azure.AI.OpenAI.AzureOpenAIClient(
    new Uri(azureOpenAIEndpoint),
    new System.ClientModel.ApiKeyCredential(azureOpenAIKey));

// Get a model-specific chat client and adapt it to IChatClient.
IChatClient chatClient = azureOpenAIClient
    .GetChatClient(modelName)
    .AsIChatClient();

// Register the chat client as a singleton in the dependency injection container.
builder.Services.AddSingleton(chatClient);

// Add DevExpress AI services and register the document-processing extensions.
builder.Services.AddDevExpressAIConsole((config) => {
    config.RegisterAIDocProcessingService();
});

// Build the configured web application instance.
var app = builder.Build();

AI-powered Extensions

Extension Supported Products Description Registration Method
Proofread Word Processing Document APIPresentation API Library Reviews text (grammar, spelling, style) in real time. Available for an entire document/presentation or selected parts (slides, ranges, areas). ProofreadAsync
Translate Word Processing Document APIPDF Document APIPresentation API Library Translates full document/presentation content or selected parts (slides, ranges, areas). Preserves formatting. TranslateAsync
Summarize Word Processing Document APIPDF Document APIPresentation API Library Produces a concise summary for an entire document/presentation or selected parts (slides, ranges, areas). SummarizeAsync
Contextual Q&A (Ask AI) Word Processing Document APIPDF Document APIPresentation API Library Answers contextual questions about document content. Uses retrieval‑augmented generation (RAG). AskAIAsync

Proofread Word Documents and Presentations

Use ProofreadAsync to review a document or presentation and apply AI-generated corrections.

Example: Proofread a Word Document

The following code snippet proofreads an entire document. Code to proofread only the second paragraph is included as commented code.

using DevExpress.AIIntegration.Docs;
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
using System.Diagnostics;

var docProcessingService = defaultAIExtensionsContainer.CreateAIDocProcessingService();

using (var wordProcessor = new RichEditDocumentServer())
{
    // Load source document (ensure file exists in relative Documents folder)
    wordProcessor.LoadDocument("Documents/FirstLookShortened.docx");

    // Proofread entire document (culture en-US)
    await docProcessingService.ProofreadAsync(wordProcessor, new System.Globalization.CultureInfo("en-US"));

    // Proofread a single paragraph
    // Paragraph paragraph = wordProcessor.Document.Paragraphs[1];
    // await docProcessingService.ProofreadAsync(paragraph.Range, new System.Globalization.CultureInfo("en-US"));

    // Prepare output directory & file path
    string targetDir = @"C:\Test Documents";
    Directory.CreateDirectory(targetDir); // Safe if already exists
    string outputPath = Path.Combine(targetDir, "Proofread.docx");

    // Save the proofread document
    using (FileStream outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
    {
        wordProcessor.SaveDocument(outputStream, DocumentFormat.OpenXml);
    }
}

Example: Proofread a Presentation

The following code snippet proofreads an entire presentation. Code to proofread only the second slide is included as commented code.

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.Docs.Presentation;

var docProcessingService = defaultAIExtensionsContainer.CreateAIDocProcessingService();

using (var presentation = new Presentation(File.ReadAllBytes("Documents/Presentation.pptx")))  
{
    // Proofread entire document (culture en-US)
    await docProcessingService.ProofreadAsync(presentation, new System.Globalization.CultureInfo("en-US"));

    // Proofread a single slide (e.g., slide 2)
    // Slide slide = presentation.Slides[1];
    // await docProcessingService.ProofreadAsync(slide, new System.Globalization.CultureInfo("en-US"));

    // Prepare output directory & file path
    string targetDir = @"C:\Test Documents";
    Directory.CreateDirectory(targetDir); // Safe if already exists
    string outputPath = Path.Combine(targetDir, "Proofread.pptx");

    // Save the proofread presentation
    using (FileStream outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
    {
        presentation.SaveDocument(outputStream, DocumentFormat.Pptx);
    }
}

Translate Word Documents, PDF Files, and Presentations

Use TranslateAsync to translate entire documents/presentations or specified ranges. Formatting is preserved.

Note

TranslateAsync method overloads that use PdfDocumentProcessor as a parameter return translated content instead of replacing original content in the PDF file on the fly.

Example: Translate a Word Document

The following code snippet translates the second paragraph in a Word document:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
using Microsoft.Extensions.AI;

// See "Register AI extension service" section for implementation code
var docProcessingService = 
    defaultAIExtensionsContainer.CreateAIDocProcessingService();

using (var wordProcessor = new RichEditDocumentServer()) {

    FileStream fs = File.OpenRead(
        Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory, 
            "Documents/FirstLookShortened.docx"));
    wordProcessor.LoadDocument(fs);
    fs.Close();
    Paragraph paragraph = wordProcessor.Document.Paragraphs[1];
    await docProcessingService.TranslateAsync(
        paragraph.Range, 
        new System.Globalization.CultureInfo("DE-DE"));

    // Save the modified document
    string outputFilePath =
        Path.Combine(Environment.CurrentDirectory, $"Document1_translated.docx");
    wordProcessor.SaveDocument(outputFilePath, DocumentFormat.Docx);
}

Example: Translate a PDF File

The following code snippet translates the first page in a PDF document and appends the translation as a new page:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.Drawing;
using DevExpress.Pdf;
using Microsoft.Extensions.AI;
using System.Drawing;

// Check "Register Service" section for implementation code
var docProcessingService = 
    defaultAIExtensionsContainer.CreateAIDocProcessingService();

using var pdfDocumentProcessor = new PdfDocumentProcessor();
pdfDocumentProcessor.LoadDocument("Documents/FirstLookExported.pdf");

// Obtain the first page area
var pageBox = pdfDocumentProcessor.Document.Pages[0].CropBox;
PdfDocumentPosition pagePosition1 = new PdfDocumentPosition(1, pageBox.TopLeft);
PdfDocumentPosition pagePosition2 = new PdfDocumentPosition(1, pageBox.BottomRight);
var pageContentArea = PdfDocumentArea.Create(pagePosition1, pagePosition2);

// Translate the page content to Spanish
string translation = await docProcessingService.TranslateAsync(
    pdfDocumentProcessor, 
    pageContentArea, 
    new System.Globalization.CultureInfo("es-ES"));

// Insert a new page and add the translated text
PdfPage page = pdfDocumentProcessor.InsertNewPage(1, PdfPaperSize.Letter);
PdfRectangle pageSize = page.CropBox;
AddContentToPage(pdfDocumentProcessor, page, pageSize, translation);

// Save the modified document
pdfDocumentProcessor.SaveDocument("result.pdf");

// This method draws text on the inserted page
void AddContentToPage(
    PdfDocumentProcessor pdfDocumentProcessor, 
    PdfPage page,
    PdfRectangle pageSize, 
    string text)
{
    using (PdfGraphics graphics = pdfDocumentProcessor.CreateGraphicsWorldSystem())
    {
        using (var textBrush = new DXSolidBrush(Color.FromArgb(255, Color.DarkOrange)))
        {
            DXFont font = new DXFont("Segoe UI", 12, DXFontStyle.Regular);

            // Calculate text size
            SizeF textSize = graphics.MeasureString(
                text, 
                font, 
                new PdfStringFormat());

            // Calculate an area to draw the text
            PointF textPoint = new PointF(0, (float)(pageSize.Height - 10));
            RectangleF rectangle = new RectangleF(
                0, 10,
                (float)pageSize.Width,
                (float)(pageSize.Height / 2));

            // Draw text at the calculated area
            graphics.DrawString(text, font, textBrush, rectangle);
            graphics.AddToPageForeground(page);
        }
    }
}

Example: Translate a Presentation

The following code snippet translates the first slide in a presentation:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.Docs.Presentation;
using Microsoft.Extensions.AI;

// See "Register AI extension service" section for implementation code
docProcessingService docProcessingService = 
        defaultAIExtensionsContainer.CreateAIDocProcessingService();

var presentation = 
        new Presentation(File.ReadAllBytes("Documents/Presentation.pptx"));

await docProcessingService.TranslateAsync(
        presentation.Slides[0], 
        new System.Globalization.CultureInfo("DE-DE"));

// Save the modified document
FileStream outputStream = File.OpenWrite(
        Path.Combine(
                Path.Combine(
                        Environment.CurrentDirectory, 
                        $"presentation_translated.pptx")));
presentation.SaveDocument(outputStream, DocumentFormat.Pptx);
outputStream.Close();

Summarize Word Documents, PDF Files, and Presentations

Call SummarizeAsync to obtain a short summary (entire document/presentation or selected part). The following summarization modes are available:

Abstractive Summarization

Understands original text context and rephrases it in a new, concise form. The AI “writes” a new summary based on its understanding and generates new sentences (instead of reusing the original wording).

Extractive Summarization

Selects and extracts key sentences/phrases from the original text. The AI identifies the most important content parts and combines them into a summary without altering the original wording.

Example: Summarize a Word Document

The following code snippet obtains an AI-generated summary of a Word document and inserts it at the start:

using DevExpress.AIIntegration.Docs;
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;

// See "Register AI extension service" section for implementation code
var docProcessingService = defaultAIExtensionsContainer.CreateAIDocProcessingService();

var wordProcessor = new RichEditDocumentServer();
wordProcessor.LoadDocument("Documents/FirstLookShortened.docx");
string summary = await docProcessingService.SummarizeAsync(
    wordProcessor,
    SummarizationMode.Extractive,
    CancellationToken.None);

wordProcessor.Document.Paragraphs.Insert(wordProcessor.Document.Paragraphs[0].Range.Start);

Paragraph summaryParagraph = wordProcessor.Document.Paragraphs[0];

// This method resets formatting for the inserted paragraph
ClearFormatting(summaryParagraph);

wordProcessor.Document.InsertText(
    summaryParagraph.Range.Start,
    "Document Summary:\n" + summary);
wordProcessor.SaveDocument("Documents/SummarizationResult.docx", DocumentFormat.Docx);

void ClearFormatting(Paragraph paragraph)
{
    CharacterProperties cp = wordProcessor.Document.BeginUpdateCharacters(paragraph.Range);
    cp.Reset();
    cp.Style = wordProcessor.Document.CharacterStyles["Normal"];
    wordProcessor.Document.EndUpdateCharacters(cp);
    ParagraphProperties pp = wordProcessor.Document.BeginUpdateParagraphs(paragraph.Range);
    pp.Reset();
    pp.Style = wordProcessor.Document.ParagraphStyles["Normal"];
    wordProcessor.Document.EndUpdateParagraphs(pp);
}

Example: Summarize a PDF Document

The following code snippet retrieves a summary and inserts it into a newly added first page:

using DevExpress.AIIntegration.Docs;
using DevExpress.Drawing;
using DevExpress.Pdf;
using System.Drawing;

// See "Register AI extension service" section for implementation code
var docProcessingService = defaultAIExtensionsContainer.CreateAIDocProcessingService();

using var pdfDocumentProcessor = new PdfDocumentProcessor();
pdfDocumentProcessor.LoadDocument("Documents/FirstLookExported.pdf");
string summary = await docProcessingService.SummarizeAsync(
    pdfDocumentProcessor,
    SummarizationMode.Extractive,
    CancellationToken.None);

PdfPage page = pdfDocumentProcessor.InsertNewPage(1, PdfPaperSize.Letter);
    PdfRectangle pageSize = page.CropBox;
AddContentToPage(pdfDocumentProcessor, page, pageSize, summary);

pdfDocumentProcessor.SaveDocument("result.pdf");


// This method draws text on the inserted page
void AddContentToPage(PdfDocumentProcessor pdfDocumentProcessor, PdfPage page, 
    PdfRectangle pageSize, string text) {
    using (PdfGraphics graphics = pdfDocumentProcessor.CreateGraphicsWorldSystem())
    {
        using (var textBrush = new DXSolidBrush(Color.FromArgb(255, Color.DarkOrange)))
        {
            DXFont font = new DXFont("Segoe UI", 12, DXFontStyle.Regular);

            // Calculate text size
            SizeF textSize = graphics.MeasureString(text, font, new PdfStringFormat());

            // Calculate an area to draw the text
            PointF textPoint = new PointF(0, (float)(pageSize.Height - 10));
            RectangleF rectangle = new RectangleF(
                0, 10,
                (float)pageSize.Width,
                (float)(pageSize.Height / 2));

            // Draw text at the calculated area
            graphics.DrawString(text, font, textBrush, rectangle);
            graphics.AddToPageForeground(page);
        }
    }
}

Example: Summarize a Presentation

The following code snippet obtains an AI-generated summary and adds it to the first slide:

using DevExpress.AIIntegration.Docs;
using DevExpress.Docs.Presentation;
using System.Drawing;

// See "Register AI extension service" section for implementation code
var docProcessingService = defaultAIExtensionsContainer.CreateAIDocProcessingService();

var presentation = new Presentation(File.ReadAllBytes("Documents/Presentation.pptx"));
string summary = await docProcessingService.SummarizeAsync(
    presentation,
    SummarizationMode.Extractive,
    CancellationToken.None);
Slide slide = new Slide(new SlideLayout(layoutType: SlideLayoutType.Blank, name: "slide"));
AddTextToSlide(slide, summary);

presentation.Slides.Insert(0, slide);

string targetDir = @"C:\Test Documents";
Directory.CreateDirectory(targetDir); // Safe if already exists
string outputPath = Path.Combine(targetDir, "presentation.pptx");

using (FileStream outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
{
    presentation.SaveDocument(outputStream, DocumentFormat.Pptx);
}

void AddTextToSlide(Slide slide, string text)
{
    Shape shape = new Shape(ShapeType.Rectangle);
    shape.X = 0; shape.Y = 0;
    shape.Width = presentation.SlideSize.Width;
    shape.Height = presentation.SlideSize.Height;
    shape.TextArea = new TextArea
    {
        Text = $"Summary by DevExpress AI Extensions:\r\n{text}",
        ParagraphProperties = new ParagraphProperties
        {
            TextProperties = new TextProperties {
                Fill = new SolidFill(Color.FromArgb(168, 177, 184)),
                FontSize = 24
            }
        },
        Properties = new TextAreaProperties
        {
            AutoFit = TextAutoSize.Shape
        }
    };
    shape.Fill = new SolidFill(Color.FromArgb(21, 25, 28));
    shape.Outline = new LineStyle { Fill = new SolidFill(Color.FromArgb(21, 25, 28)) };

    slide.Shapes.Add(shape);
}

Ask Contextual Questions about Document Content

Use AskAIAsync to submit a natural language question about the loaded document or presentation.

The Ask AI extension retrieves relevant content chunks (RAG) and generates a grounded response. Use the RagOptions settings to fine-tune response generation. You can pass this RagOptions object as the AskAIAsync method parameter. The following options are available:

Property Description Default Value
ChunkSize Sets the maximum number of characters in each content chunk. 1000
AugmentationChunkCount Sets the number of most relevant chunks. 5
RebuildEmbeddings Specifies whether to regenerate vector embeddings for document chunks.Regeneration may be required if the document content was changed. true
VectorDimensions Sets the dimensionality of vector embeddings. 1536
VectorCollectionName Sets the logical name of the vector collection (index) that stores embeddings. "default_collection"

Register Embedding Generator and Vector Store

Register an embedding generator and a vector store before using a specific vector collection. You can use any vector store that implements the IVectorStore interface to store embeddings. Refer to the following topics for more information: Available vector database solutions

The following code snippet registers an embedding generator and a vector store in the AI container. This code snippet uses API from the Microsoft.SemanticKernel.Connectors.InMemory NuGet package.

using Azure.AI.OpenAI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using Microsoft.Extensions.AI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Connectors.InMemory;

string openAiKey = "<AZURE_OPENAI_API_KEY>";
string openAiEndpoint = "<YOUR_AZURE_OPENAI_ENDPOINT>";
var clientModel = "gpt-4o-mini";
var embeddingClientName = "text-embedding-3-small";
AIIntegration.ChunkMaxLength = 6000;

var azureClient = new AzureOpenAIClient(
    new Uri(openAiEndpoint),
    new System.ClientModel.ApiKeyCredential(openAiKey));
var chatClient = azureClient.GetChatClient(clientModel).AsIChatClient();

// Create an in-memory vector store.
VectorStore store = new InMemoryVectorStore();

// Get the embedding client for the specified model
// and wrap it as an IEmbeddingGenerator.
var embeddingClient = azureClient.GetEmbeddingClient(embeddingClientName).AsIEmbeddingGenerator();

// Configure the dependency injection container.
var serviceProvider = new ServiceCollection()

// Register the chat client, embedding generator
// and a vector store as a singleton.
.AddSingleton(chatClient)
.AddSingleton<IEmbeddingGenerator>(embeddingClient)
.AddSingleton(store)

.AddDevExpressAIConsole() // Add DevExpress AI Console services.
.BuildServiceProvider(); // Build the service provider.
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.XtraRichEdit;
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel.Connectors.InMemory;

AIIntegration.ChunkMaxLength = 6000;
string openAiKey = "<AZURE_OPENAI_API_KEY>";
string openAiEndpoint = "<YOUR_AZURE_OPENAI_ENDPOINT>";
var clientModel = "gpt-4o-mini";
var embeddingClientName = "text-embedding-3-small";

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents();

var azureOpenAIClient = new Azure.AI.OpenAI.AzureOpenAIClient(
    new Uri(openAiEndpoint), new System.ClientModel.ApiKeyCredential(openAiKey));
IChatClient chatClient = azureOpenAIClient.GetChatClient(clientModel).AsIChatClient();
builder.Services.AddSingleton(chatClient);

// Get the embedding client for the specified model
// and wrap it as an IEmbeddingGenerator.
IEmbeddingGenerator embeddingClient = azureOpenAIClient
    .GetEmbeddingClient(embeddingClientName)
    .AsIEmbeddingGenerator();

// Register the embedding generator
// and a vector store as a singleton.
builder.Services.AddSingleton(embeddingClient);
builder.Services.AddSingleton<Microsoft.Extensions.VectorData.VectorStore>(new InMemoryVectorStore());

var app = builder.Build();

Example: Ask Questions about Word Document

The following code snippet asks a question about the document content, configures RAG options (chunk size, collection name, chunk count), and inserts the AI‑generated answer as a comment about the first paragraph:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.XtraRichEdit;
using Microsoft.Extensions.AI;

// See "Register AI extension service" section for implementation code
var docProcessingService = 
    defaultAIExtensionsContainer.CreateAIDocProcessingService();

var options = new RagOptions {
    VectorCollectionName = "document_embeddings",
    ChunkSize = 800,
    AugmentationChunkCount = 8
};

using (var wordProcessor = new RichEditDocumentServer()) {
    wordProcessor.LoadDocument(@"Documents/Document1.docx");
    string answer = await docProcessingService.AskAIAsync(
        wordProcessor,
        "Does this document contain any confidential information?",
        options
    );

    wordProcessor.Document.Comments.Create(
        wordProcessor.Document.Paragraphs[0].Range, 
        "AI Summary:\n" + answer);
    wordProcessor.SaveDocument("Documents/Document_commented.docx", DocumentFormat.Docx);
}

Example: Ask Questions about PDF Document

The following code snippet asks a contextual question about the PDF file, configures RAG options (chunk size, collection name, chunk count), and adds the answer as a sticky note annotation:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.Pdf;
using Microsoft.Extensions.AI;

// See "Register AI extension service" section for implementation code
var docProcessingService = 
    defaultAIExtensionsContainer.CreateAIDocProcessingService();

var options = new RagOptions {
    VectorCollectionName = "knowledge_base_vectors",
    ChunkSize = 600,
    AugmentationChunkCount = 7
}; 

using (var pdfDocumentProcessor = new PdfDocumentProcessor()) {
    FileStream fs = File.OpenRead(
        Path.Combine(
            AppDomain.CurrentDomain.BaseDirectory, 
            @"Documents/Document1.pdf")); 
        pdfDocumentProcessor.LoadDocument(fs, true);
    fs.Close();

    string result = 
        await docProcessingService.AskAIAsync(
            pdfDocumentProcessor, 
            "What terms does this document contain?",
            options);

    // Access the first page properties
    PdfPageFacade page = pdfDocumentProcessor.DocumentFacade.Pages[0];

    // Add sticky note at the specified point
    PdfTextAnnotationFacade textAnnotation =
       page.AddTextAnnotation(
           new PdfPoint(64, 65), 
           PdfTextAnnotationIconName.Comment);

    // Specify annotation parameters
    textAnnotation.Author = "AI-Generated";
    textAnnotation.Color = new PdfRGBColor(0.8, 0.2, 0.1);
    textAnnotation.Contents = result;

    // Save the modified document
    string outputFilePath = 
        Path.Combine(Environment.CurrentDirectory, $"Document1_Annotated.pdf");
    pdfDocumentProcessor.SaveDocument(outputFilePath);
}

Example: Ask Questions about Presentation Content

The following code snippet asks a question about the document content, configures RAG options (chunk size, collection name, chunk count), and inserts the AI‑generated answer as content in the first slide:

using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Docs;
using DevExpress.Docs.Presentation;
using Microsoft.Extensions.AI;

// Create a document processing service instance
// from the AI extensions container.
var docProcessingService = new AIDocProcessingService(defaultAIExtensionsContainer);

var options = new RagOptions
{
    VectorCollectionName = "document_embeddings",
    ChunkSize = 800,
    AugmentationChunkCount = 8
};

var presentation = new Presentation(File.ReadAllBytes("Documents/Presentation.pptx"));
string summary = await docProcessingService.AskAIAsync(
    presentation,
    "Does this document contain any confidential information?",
    options);
Slide slide = new Slide(new SlideLayout(layoutType: SlideLayoutType.Blank, name: "slide"));
AddTextToSlide(slide, summary);

presentation.Slides.Insert(0, slide);

string targetDir = @"C:\Test Documents";
Directory.CreateDirectory(targetDir);
string outputPath = Path.Combine(targetDir, "presentation.pptx");

using (FileStream outputStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
{
    presentation.SaveDocument(outputStream, DocumentFormat.Pptx);
}

void AddTextToSlide(Slide slide, string text)
{
    Shape shape = new Shape(ShapeType.Rectangle);
    shape.X = 0; shape.Y = 0;
    shape.Width = presentation.SlideSize.Width;
    shape.Height = presentation.SlideSize.Height;
    shape.TextArea = new TextArea
    {
        Text = $"Summary by DevExpress AI Extensions:\r\n{text}",
        ParagraphProperties = new ParagraphProperties
        {
            TextProperties = new TextProperties
            {
                Fill = new SolidFill(Color.FromArgb(168, 177, 184)),
                FontSize = 24
            }
        },
        Properties = new TextAreaProperties
        {
            AutoFit = TextAutoSize.Shape
        }
    };
    shape.Fill = new SolidFill(Color.FromArgb(21, 25, 28));
    shape.Outline = new LineStyle { Fill = new SolidFill(Color.FromArgb(21, 25, 28)) };

    slide.Shapes.Add(shape);
}

Limitations

AI-powered extensions for DevExpress Office File API ship with the following limitations: