mirror of
https://github.com/marcominerva/SqlDatabaseVectorSearch.git
synced 2026-08-04 09:48:57 +00:00
Improve DI, citation formatting, and search result output
- Inject IServiceScopeFactory in Documents.razor for better DI and async scope creation. - Update citation formatting in Program.cs: sources now appear as a localized, numbered Markdown list with block quotes. - Use a helper for consistent source/page formatting in TextSearchProviderOptions. - Simplify RawRepresentation in VectorSearchService to just the page number.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
@page "/documents"
|
||||
@using MimeMapping
|
||||
|
||||
@inject IServiceProvider ServiceProvider
|
||||
@inject IServiceScopeFactory ServiceScopeFactory
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
<ConfirmDialog @ref="dialog" />
|
||||
@@ -127,7 +127,7 @@ else
|
||||
return;
|
||||
}
|
||||
|
||||
await using var scope = ServiceProvider.CreateAsyncScope();
|
||||
await using var scope = ServiceScopeFactory.CreateAsyncScope();
|
||||
await LoadDocumentsAsync(scope.ServiceProvider);
|
||||
|
||||
StateHasChanged();
|
||||
@@ -173,7 +173,7 @@ else
|
||||
await using var inputStream = Model.File.OpenReadStream(20 * 1024 * 1024); // 20 MB
|
||||
await using var stream = await inputStream.GetMemoryStreamAsync();
|
||||
|
||||
await using var scope = ServiceProvider.CreateAsyncScope();
|
||||
await using var scope = ServiceScopeFactory.CreateAsyncScope();
|
||||
var vectorSearchService = scope.ServiceProvider.GetRequiredService<VectorSearchService>();
|
||||
|
||||
var documentId = string.IsNullOrWhiteSpace(Model.DocumentId) ? null : (Guid?)Guid.Parse(Model.DocumentId);
|
||||
@@ -223,7 +223,7 @@ else
|
||||
{
|
||||
deleteButton.ShowLoading();
|
||||
|
||||
await using var scope = ServiceProvider.CreateAsyncScope();
|
||||
await using var scope = ServiceScopeFactory.CreateAsyncScope();
|
||||
var documentService = scope.ServiceProvider.GetRequiredService<DocumentService>();
|
||||
|
||||
await documentService.DeleteAsync(selectedDocumentIds);
|
||||
|
||||
@@ -159,24 +159,23 @@ var textSearchOptions = new TextSearchProviderOptions()
|
||||
sb.AppendLine("Use the excerpts below to answer the user.");
|
||||
sb.AppendLine("Citation rules:");
|
||||
sb.AppendLine("- Do NOT add inline citations.");
|
||||
sb.AppendLine("- At the END of your answer, add a single line exactly like:");
|
||||
sb.AppendLine(" Sources: [SourceName](SourceLink), [SourceName](SourceLink)");
|
||||
sb.AppendLine("- At the END of your answer, add a sources label translated in the same language as the user's question.");
|
||||
sb.AppendLine("- The sources label MUST be standard-size italic Markdown text, not a heading and not bold. For example: *Sources* or *Fonti*.");
|
||||
sb.AppendLine("- The citation list MUST be a numbered Markdown list.");
|
||||
sb.AppendLine("- Format each citation with the source name and the localized page label, followed by a Markdown block quote of about 20-30 words from the excerpt that supports the answer.");
|
||||
sb.AppendLine("- The block quote MUST start on a new line with the '>' Markdown character.");
|
||||
sb.AppendLine("- Format each source exactly like:");
|
||||
sb.AppendLine(" *Sources*");
|
||||
sb.AppendLine(" 1. SourceName, localized-page-label PageNumber");
|
||||
sb.AppendLine(" > Supporting excerpt quote of about 20-30 words.");
|
||||
sb.AppendLine("- Do NOT format source names as links.");
|
||||
sb.AppendLine("- Include ONLY sources you actually used. No duplicates.");
|
||||
sb.AppendLine();
|
||||
|
||||
sb.AppendLine("### Sources (copy/paste-ready)");
|
||||
foreach (var (i, r) in results.Index())
|
||||
{
|
||||
var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(r.SourceLink))
|
||||
{
|
||||
sb.AppendLine($"- [{name}]({r.SourceLink})");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.AppendLine($"- {name}");
|
||||
}
|
||||
sb.AppendLine($"- {GetSourceName(r, i)}");
|
||||
}
|
||||
|
||||
sb.AppendLine();
|
||||
@@ -184,14 +183,21 @@ var textSearchOptions = new TextSearchProviderOptions()
|
||||
sb.AppendLine("### Excerpts");
|
||||
foreach (var (i, r) in results.Index())
|
||||
{
|
||||
var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
|
||||
|
||||
sb.AppendLine($"[{i + 1}] {name}");
|
||||
sb.AppendLine($"[{i + 1}] {GetSourceName(r, i)}");
|
||||
sb.AppendLine(r.Text);
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("---");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
static string GetSourceName(TextSearchProvider.TextSearchResult result, int index)
|
||||
{
|
||||
var name = string.IsNullOrWhiteSpace(result.SourceName) ? $"Source {index + 1}" : result.SourceName;
|
||||
var pageNumber = result.RawRepresentation is int number ? number : (int?)null;
|
||||
var pageText = pageNumber.HasValue ? $", page {pageNumber}" : string.Empty;
|
||||
|
||||
return $"{name}{pageText}";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class ContextProvider(ApplicationDbContext dbContext, IEmbeddingGenerator
|
||||
SourceLink = c.Id.ToString().ToLowerInvariant(),
|
||||
SourceName = c.Document.Name,
|
||||
Text = c.Content,
|
||||
RawRepresentation = new { c.Id, c.DocumentId, c.PageNumber, c.IndexOnPage, c.Content }
|
||||
RawRepresentation = c.PageNumber
|
||||
})
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user