Skip to main content
All docs
V25.2
  • AI-powered Extensions for DevExpress Office File API

    • 21 minutes to read

    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:

    • OpenAI (through Microsoft’s reference implementation)
    • Azure OpenAI (through Microsoft’s reference implementation)
    • Self-hosted Ollama (through the OllamaSharp library)
    • Google Gemini, Claude, and other major AI services through Semantic Kernel AI Connectors
    • Custom IChatClient implementation for unsupported providers or private language models

    The Microsoft.Extensions.AI framework allows developers to integrate support for AI language models and services without modifying the core library. This means you can leverage third-party libraries for new AI providers or create your own custom implementation for in-house language models.

    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 API
    Presentation 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 API
    PDF Document API
    Presentation API Library
    Translates full document/presentation content or selected parts (slides, ranges, areas). Preserves formatting. TranslateAsync
    Summarize Word Processing Document API
    PDF Document API
    Presentation 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 API
    PDF Document API
    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.
    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);
    }
    

    Limitations

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

    • The Ask AI extension may produce inaccurate answers for questions that require exact counts of elements (pages, tables, images, etc.).
    • Extensions for PDF Document API work only with text content. Field values, annotations, comments, and bookmarks are ignored.