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
IChatClientimplementation 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.
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.
- DevExpress.AIIntegration
DevExpress.AIIntegration.Docs- DevExpress.Document.Processor
- DevExpress.Docs.Presentation
AI Runtime and Provider Packages
- .NET 8 SDK or .NET Framework v4.7.2
- OpenAI
- An active OpenAI subscription
- OpenAI API key
- OpenAI .NET SDK (Version=”2.2.0”)
- Microsoft.Extensions.AI.OpenAI (Version=”9.7.1-preview.1.25365.4”)
- Azure OpenAI
- Semantic Kernel
- Microsoft.SemanticKernel
- An active account/subscription for the AI service of your choice
- Microsoft.SemanticKernel.Connectors.* NuGet package (a connector to the AI service of your choice)
- Ollama (self-hosted models)
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.