UnifiedRag.Maui (1.1.3)
Installation
dotnet nuget add source --name logikonline --username your_username --password your_token dotnet add package --source logikonline --version 1.1.3 UnifiedRag.MauiAbout this package
RAG (Retrieval-Augmented Generation) extension for UnifiedData.Maui. Combines document retrieval with LLM generation for AI-powered Q&A.
UnifiedRag.Maui
A comprehensive Retrieval-Augmented Generation (RAG) framework for .NET MAUI applications, built on top of UnifiedData.Maui. This library enables intelligent question-answering systems by combining document retrieval with Large Language Model (LLM) generation capabilities.
Version 1.1.2
Production-ready RAG implementation with support for multiple LLM providers via a unified provider architecture, advanced configuration presets, and extensible plugin architecture.
Features
Core Capabilities
-
🤖 Multiple LLM Providers
- OpenAI (GPT-4, GPT-4o, GPT-3.5)
- Anthropic Claude (Claude 3.5 Sonnet, Claude 3 Opus, Haiku)
- Together.AI (Open-source models)
- LlamaSharp.Ally (Local models for offline/mobile)
-
🎯 Smart Configuration Presets
- 10 pre-configured presets for common use cases
- Automatic validation and normalization
- Model-aware token management
-
📱 Mobile-First Design
- Optimized for iOS and Android
- Support for offline operation with local models
- Memory-efficient context management
-
🔌 Plugin Architecture
- AIPlugin framework integration
- Extensible search, processing, and citation plugins
- Workflow orchestration support
-
🌊 Advanced Features
- Real-time streaming responses
- Multi-turn conversation support with memory
- Progressive summarization for long conversations
- Tool/function calling capability
- Automatic citation generation
- Confidence scoring
Installation
dotnet add package UnifiedRag.Maui
Quick Start
Basic Setup with OpenAI
using UnifiedRag.Maui.Extensions;
using UnifiedRag.Maui.Configuration;
// In MauiProgram.cs
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
// Add UnifiedRag with OpenAI
builder.Services.AddUnifiedRagWithOpenAI(
dataOptions =>
{
dataOptions.DatabaseName = "knowledge.db";
dataOptions.VectorDimensions = 384;
},
apiKey: Environment.GetEnvironmentVariable("OPENAI_API_KEY"),
modelName: "gpt-4o-mini"
);
return builder.Build();
}
}
Using Configuration Presets
using UnifiedRag.Maui.Configuration;
using static UnifiedRag.Maui.Configuration.RAGPresetConfiguration;
public class ChatService
{
private readonly IRAGService _ragService;
public async Task<string> QuickAnswer(string question)
{
// Use the QuickResponse preset for fast answers
var options = RAGOptionsBuilder.Quick.Fast();
var response = await _ragService.AskAsync(question, options);
return response.Answer;
}
public async Task<string> DetailedResearch(string question)
{
// Use the ResearchMode preset for comprehensive analysis
var options = new RAGOptionsBuilder()
.WithPreset(PresetType.ResearchMode)
.WithRetrieval(topK: 15)
.Build();
var response = await _ragService.AskAsync(question, options);
return response.Answer;
}
}
Configuration Presets
UnifiedRag.Maui includes 10 built-in presets optimized for different scenarios:
| Preset | Description | Best For |
|---|---|---|
| QuickResponse | Fast responses with minimal context | Simple Q&A, definitions |
| Balanced | Default balanced configuration | General purpose |
| HighAccuracy | Maximum accuracy with extensive context | Complex questions |
| CodeAssistant | Optimized for code-related queries | Programming help |
| CreativeWriting | High temperature for creative tasks | Content generation |
| ResearchMode | Deep analysis with citations | Academic research |
| MobileOptimized | Minimal resource usage | Mobile devices |
| HighPerformance | Maximum speed with caching | High-traffic apps |
| CostEfficient | Token-limited for cost control | Budget-conscious apps |
Using Presets with Customization
// Start with a preset and customize
var options = new RAGOptionsBuilder()
.WithPreset(PresetType.Balanced)
.WithRetrieval(topK: 10) // Override document count
.WithGeneration(temperature: 0.5f) // Override temperature
.WithStreaming(true) // Enable streaming
.WithToolCalling(enabled: true) // Enable function calling
.Build();
Automatic Preset Recommendation
// Let the system recommend a preset based on requirements
var options = new RAGOptionsBuilder()
.WithRecommendedPreset(
needsSpeed: true,
isCodeRelated: query.Contains("debug"),
isMobile: DeviceInfo.Platform == DevicePlatform.Android
)
.Build();
Provider Configuration
Anthropic Claude
services.AddUnifiedRagWithAnthropic(
dataOptions => { /* ... */ },
apiKey: "your-anthropic-key",
modelName: "claude-3-5-sonnet-20241022" // Latest Claude 3.5
);
Together.AI
services.AddUnifiedRagWithTogetherAI(
dataOptions => { /* ... */ },
apiKey: "your-together-key",
modelName: "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo"
);
Local Models with LlamaSharp.Ally
services.AddUnifiedRagWithLlamaAlly(
dataOptions => { /* ... */ },
modelPath: Path.Combine(FileSystem.AppDataDirectory, "llama-3.2-1b-q4.gguf"),
maxTokens: 512
);
Dynamic Provider Selection
services.AddUnifiedRag(
dataOptions => { /* ... */ },
ragConfig =>
{
// Select provider based on platform or user preference
if (DeviceInfo.Platform == DevicePlatform.iOS ||
DeviceInfo.Platform == DevicePlatform.Android)
{
ragConfig.Provider = "llamaally";
ragConfig.ModelPath = GetLocalModelPath();
}
else
{
ragConfig.Provider = "openai";
ragConfig.ApiKey = GetApiKey();
ragConfig.ModelName = "gpt-4o";
}
}
);
Per-Request Provider Overrides
You can override the provider and model for individual requests without changing app settings:
// Use OpenAI GPT-4 for this specific request
var options = new RAGOptionsBuilder()
.WithOpenAI(model: "gpt-4o", apiKey: "your-api-key")
.Build();
var response = await _ragService.AskAsync(question, options);
// Or use Anthropic Claude 3.5 Sonnet
var claudeOptions = new RAGOptionsBuilder()
.WithAnthropic(model: "claude-3-5-sonnet-20241022")
.Build();
// Or use a local model
var localOptions = new RAGOptionsBuilder()
.WithLocalModel(modelPath: "/path/to/model.gguf")
.Build();
This is useful for:
- A/B testing different models
- Cost optimization (use cheaper models for simple queries)
- Quality control (use better models for important requests)
- Fallback strategies (retry with different provider if one fails)
Advanced Features
Streaming Responses
await foreach (var chunk in _ragService.AskStreamAsync(question))
{
// Update UI progressively
await InvokeAsync(() => ResponseText += chunk);
}
Multi-turn Conversations
var conversationId = Guid.NewGuid().ToString();
// First question
var response1 = await _ragService.AskWithConversationAsync(
"What is machine learning?",
conversationId
);
// Follow-up with context
var response2 = await _ragService.AskWithConversationAsync(
"How does it differ from traditional programming?",
conversationId
);
Tool/Function Calling
var options = new RAGOptionsBuilder()
.WithToolCalling(enabled: true, maxIterations: 5)
.Build();
// The model can now execute registered tools/functions
var response = await _ragService.AskAsync(
"Calculate the compound interest on $1000 at 5% for 10 years",
options
);
Progressive Summarization
var options = new RAGOptionsBuilder()
.WithLongConversations()
.WithConversation(
maxHistory: 30,
enableSummarization: true,
summarizationThreshold: 3000
)
.Build();
Plugin Architecture
UnifiedRag.Maui integrates with the MarketAlly.AIPlugin framework for extensible functionality:
Available Plugins
- RAGSearchPlugin - Advanced document search with multiple modes
- QueryEnhancerPlugin - Query optimization with synonyms and reformulation
- DocumentChunkerPlugin - Intelligent document chunking strategies
- DocumentClassifierPlugin - Automatic document categorization
- CitationGeneratorPlugin - Multi-format citation generation
- HybridSearchPlugin - Combined vector and keyword search
Enabling Plugins
services.AddEnhancedUnifiedRag(
dataOptions => { /* ... */ },
ragConfig =>
{
ragConfig.EnablePlugins = true;
ragConfig.EnableSearchPlugin = true;
ragConfig.EnableQueryEnhancerPlugin = true;
ragConfig.EnableCitationGeneratorPlugin = true;
// Configure security
ragConfig.SecurityConfiguration = new SecurityConfiguration
{
EnableAccessControl = true,
EnableRateLimiting = true,
MaxRequestsPerMinute = 60
};
}
);
Usage Tracking
Track token usage and costs across providers:
// Enable usage tracking with monthly limits
var options = new RAGOptionsBuilder()
.WithCostControls(
monthlyLimit: 100000,
blockOnLimitReached: true
)
.Build();
// Check usage
var usage = response.Usage;
Console.WriteLine($"Tokens used: {usage?.TotalTokens}");
Console.WriteLine($"Estimated cost: ${usage?.Cost:F4}");
Mobile Optimization
Special considerations for mobile deployments:
// Use mobile-optimized preset
var options = new RAGOptionsBuilder()
.WithPreset(PresetType.MobileOptimized)
.Build();
// Or build custom mobile configuration
var options = new RAGOptionsBuilder()
.ForMobile()
.WithRetrieval(topK: 3, maxContextTokens: 512)
.WithGeneration(maxTokens: 256)
.WithShortConversations()
.Build();
Recommended Mobile Models
For LlamaSharp.Ally on mobile devices:
- Phones: Llama-3.2-1B-Q4 (~650MB)
- Tablets: Phi-3-mini-Q4 (~2GB) or Mistral-7B-Q4 (~4GB)
Context Management
UnifiedRag.Maui automatically manages context based on the selected preset:
// Use a preset optimized for your use case
var options = new RAGOptionsBuilder()
.WithPreset(PresetType.HighAccuracy)
.WithRetrieval(topK: 10, maxContextTokens: 8192)
.Build();
Error Handling
try
{
var response = await _ragService.AskAsync(question, options);
}
catch (RateLimitExceededException ex)
{
Console.WriteLine($"Rate limit hit. Retry after: {ex.RetryAfter}");
}
catch (RAGContextLengthException ex)
{
Console.WriteLine($"Context too long: {ex.CurrentTokens} > {ex.MaxTokens}");
}
catch (RAGProviderException ex)
{
Console.WriteLine($"Provider error: {ex.ProviderName} - {ex.Message}");
}
Architecture Overview
UnifiedRag.Maui/
├── Configuration/ # Preset configurations and builders
│ ├── RAGPresetConfiguration # Built-in presets for common use cases
│ └── RAGOptionsBuilder # Fluent configuration API
├── Core/ # Core interfaces
│ ├── IRAGService # Main service interface
│ ├── IGenerationProvider # LLM provider abstraction
│ ├── IRAGClassificationService # Document classification
│ └── ISummarizationService # Content summarization
├── Providers/ # LLM implementations
│ └── UniversalProvider # Unified provider for all LLMs (OpenAI, Claude, Together, LlamaAlly)
├── Services/ # Service implementations
│ ├── UnifiedRAGService # Core RAG service with conversation management
│ ├── AgenticRAGService # Multi-agent workflow orchestration
│ ├── DynamicProviderFactory # Runtime provider creation
│ ├── UsageTracker # Token usage and cost tracking
│ └── SummarizationService # Progressive summarization
├── Plugins/ # AIPlugin implementations
│ ├── Search/ # RAGSearchPlugin, HybridSearchPlugin, BraveSearchPlugin
│ ├── Query/ # QueryEnhancerPlugin
│ ├── Processing/ # DocumentChunkerPlugin, DocumentClassifierPlugin, WebpageSummarizePlugin
│ └── Citations/ # CitationGeneratorPlugin
├── Context/ # Context management
│ └── ContextManager # Document context optimization
├── Models/ # Data models
│ ├── RAGModels # RAGOptions, RAGResponse, etc.
│ ├── ToolCalling # Tool/function calling models
│ └── ProviderSettings # Provider configuration
├── Monitoring/ # Observability
│ ├── IRAGMetricsCollector # Metrics interface
│ └── MonitoredRAGService # Service with metrics
└── Exceptions/ # Custom exceptions
└── RAGExceptions # Typed exceptions (RateLimitExceededException, etc.)
Performance Considerations
- Token Management: Use presets that match your needs to avoid excessive token usage
- Caching: Enable caching for frequently asked questions
- Streaming: Use streaming for better perceived performance
- Local Models: Consider quantized models (Q4, Q5) for mobile devices
- Context Size: Balance context size with response quality and speed
Requirements
- .NET 9.0 or later
- UnifiedData.Maui package
- MarketAlly.AIPlugin package (for enhanced features)
- API keys for cloud providers (OpenAI, Anthropic, Together.AI)
- GGUF model files for local inference (LlamaSharp.Ally)
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
Support
For issues, questions, or suggestions, please open an issue on the GitHub repository.
Built with dedication by the MarketAlly team for the .NET MAUI community.
Dependencies
| ID | Version | Target Framework |
|---|---|---|
| UnifiedData.Maui | 1.3.1 | net9.0 |
| Anthropic.SDK | 5.8.0 | net9.0 |
| LlamaSharp.Ally | 1.0.1-16kb | net9.0 |
| MarketAlly.AIPlugin | 2.8.6 | net9.0 |
| Microsoft.Extensions.Http | 9.0.10 | net9.0 |
| Microsoft.Extensions.Logging.Abstractions | 9.0.10 | net9.0 |
| Microsoft.Maui.Controls | 9.0.120 | net9.0 |
| Microsoft.Maui.Controls.Compatibility | 9.0.120 | net9.0 |
| OpenAI | 2.6.0 | net9.0 |
| System.Memory | 4.6.3 | net9.0 |