Skip to content
Merged
147 changes: 147 additions & 0 deletions doc/multi-backend-configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
# Multi-Backend Configuration Example

This example demonstrates how to configure and use the multi-backend retrieval architecture in NLWebNet.

## Single Backend (Default/Legacy)

```csharp
// Traditional single backend setup - still works
services.AddNLWebNet<MockDataBackend>(options =>
{
options.DefaultMode = QueryMode.List;
options.MaxResultsPerQuery = 20;
});
```

## Multi-Backend Configuration

```csharp
// New multi-backend setup
services.AddNLWebNetMultiBackend(
options =>
{
options.DefaultMode = QueryMode.List;
options.MaxResultsPerQuery = 50;
},
multiBackendOptions =>
{
multiBackendOptions.Enabled = true;
multiBackendOptions.EnableParallelQuerying = true;
multiBackendOptions.EnableResultDeduplication = true;
multiBackendOptions.MaxConcurrentQueries = 3;
multiBackendOptions.BackendTimeoutSeconds = 30;
multiBackendOptions.WriteEndpoint = "primary_backend";
});
```

## Configuration via appsettings.json

```json
{
"NLWebNet": {
"DefaultMode": "List",
"MaxResultsPerQuery": 50,
"MultiBackend": {
"Enabled": true,
"EnableParallelQuerying": true,
"EnableResultDeduplication": true,
"MaxConcurrentQueries": 3,
"BackendTimeoutSeconds": 30,
"WriteEndpoint": "primary_backend",
"Endpoints": {
"primary_backend": {
"Enabled": true,
"BackendType": "azure_ai_search",
"Priority": 10,
"Properties": {
"ConnectionString": "your-connection-string",
"IndexName": "your-index"
}
},
"secondary_backend": {
"Enabled": true,
"BackendType": "mock",
"Priority": 5,
"Properties": {}
}
}
}
}
}
```

## Usage Example

```csharp
public class ExampleController : ControllerBase
{
private readonly INLWebService _nlWebService;
private readonly IBackendManager _backendManager;

public ExampleController(INLWebService nlWebService, IBackendManager backendManager)
{
_nlWebService = nlWebService;
_backendManager = backendManager;
}

[HttpPost("search")]
public async Task<IActionResult> Search([FromBody] NLWebRequest request)
{
// Multi-backend search automatically handled
var response = await _nlWebService.ProcessRequestAsync(request);
return Ok(response);
}

[HttpGet("backend-info")]
public IActionResult GetBackendInfo()
{
// Get information about configured backends
var backendInfo = _backendManager.GetBackendInfo();
return Ok(backendInfo);
}

[HttpGet("write-backend-capabilities")]
public IActionResult GetWriteBackendCapabilities()
{
// Access the designated write backend
var writeBackend = _backendManager.GetWriteBackend();
if (writeBackend == null)
{
return NotFound("No write backend configured");
}

var capabilities = writeBackend.GetCapabilities();
return Ok(capabilities);
}
}
```

## Key Features

### Parallel Querying
- Queries execute simultaneously across all enabled backends
- Configurable concurrency limits and timeouts
- Graceful handling of backend failures

### Result Deduplication
- Automatic deduplication based on URL
- Higher scoring results from different backends take precedence
- Can be disabled for scenarios requiring all results

### Write Endpoint
- Designate one backend as the primary write endpoint
- Other backends remain read-only for queries
- Useful for hybrid architectures

### Backward Compatibility
- Existing single-backend configurations continue to work
- No breaking changes to existing APIs
- Gradual migration path available

## Migration from Single Backend

1. Replace `AddNLWebNet<T>()` with `AddNLWebNetMultiBackend()`
2. Set `MultiBackend.Enabled = false` initially to maintain existing behavior
3. Configure additional backends in the `Endpoints` section
4. Enable multi-backend mode by setting `MultiBackend.Enabled = true`
5. Test and adjust concurrency and timeout settings as needed
8 changes: 4 additions & 4 deletions samples/AspireDemo/AspireHost/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
options.AddFilter("Aspire.Hosting.ApplicationModel", LogLevel.Information);
options.AddFilter("Aspire.Hosting", LogLevel.Information);
options.AddFilter("Aspire", LogLevel.Warning);

// Reduce OpenTelemetry noise
options.AddFilter("OpenTelemetry", LogLevel.Warning);

// Keep basic hosting messages
options.AddFilter("Microsoft.Extensions.Hosting.Internal.Host", LogLevel.Information);
options.AddFilter("Microsoft.Extensions.Hosting", LogLevel.Warning);

// Reduce ASP.NET Core noise but keep startup messages
options.AddFilter("Microsoft.AspNetCore.Hosting.Diagnostics", LogLevel.Information);
options.AddFilter("Microsoft.AspNetCore", LogLevel.Warning);

// Reduce DI and HTTP noise
options.AddFilter("Microsoft.Extensions.DependencyInjection", LogLevel.Warning);
options.AddFilter("System.Net.Http", LogLevel.Warning);
Expand Down
Loading