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"
|
@page "/documents"
|
||||||
@using MimeMapping
|
@using MimeMapping
|
||||||
|
|
||||||
@inject IServiceProvider ServiceProvider
|
@inject IServiceScopeFactory ServiceScopeFactory
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
|
|
||||||
<ConfirmDialog @ref="dialog" />
|
<ConfirmDialog @ref="dialog" />
|
||||||
@@ -127,7 +127,7 @@ else
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await using var scope = ServiceProvider.CreateAsyncScope();
|
await using var scope = ServiceScopeFactory.CreateAsyncScope();
|
||||||
await LoadDocumentsAsync(scope.ServiceProvider);
|
await LoadDocumentsAsync(scope.ServiceProvider);
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@@ -173,7 +173,7 @@ else
|
|||||||
await using var inputStream = Model.File.OpenReadStream(20 * 1024 * 1024); // 20 MB
|
await using var inputStream = Model.File.OpenReadStream(20 * 1024 * 1024); // 20 MB
|
||||||
await using var stream = await inputStream.GetMemoryStreamAsync();
|
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 vectorSearchService = scope.ServiceProvider.GetRequiredService<VectorSearchService>();
|
||||||
|
|
||||||
var documentId = string.IsNullOrWhiteSpace(Model.DocumentId) ? null : (Guid?)Guid.Parse(Model.DocumentId);
|
var documentId = string.IsNullOrWhiteSpace(Model.DocumentId) ? null : (Guid?)Guid.Parse(Model.DocumentId);
|
||||||
@@ -223,7 +223,7 @@ else
|
|||||||
{
|
{
|
||||||
deleteButton.ShowLoading();
|
deleteButton.ShowLoading();
|
||||||
|
|
||||||
await using var scope = ServiceProvider.CreateAsyncScope();
|
await using var scope = ServiceScopeFactory.CreateAsyncScope();
|
||||||
var documentService = scope.ServiceProvider.GetRequiredService<DocumentService>();
|
var documentService = scope.ServiceProvider.GetRequiredService<DocumentService>();
|
||||||
|
|
||||||
await documentService.DeleteAsync(selectedDocumentIds);
|
await documentService.DeleteAsync(selectedDocumentIds);
|
||||||
|
|||||||
@@ -159,24 +159,23 @@ var textSearchOptions = new TextSearchProviderOptions()
|
|||||||
sb.AppendLine("Use the excerpts below to answer the user.");
|
sb.AppendLine("Use the excerpts below to answer the user.");
|
||||||
sb.AppendLine("Citation rules:");
|
sb.AppendLine("Citation rules:");
|
||||||
sb.AppendLine("- Do NOT add inline citations.");
|
sb.AppendLine("- Do NOT add inline citations.");
|
||||||
sb.AppendLine("- At the END of your answer, add a single line exactly like:");
|
sb.AppendLine("- At the END of your answer, add a sources label translated in the same language as the user's question.");
|
||||||
sb.AppendLine(" Sources: [SourceName](SourceLink), [SourceName](SourceLink)");
|
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("- Include ONLY sources you actually used. No duplicates.");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
|
|
||||||
sb.AppendLine("### Sources (copy/paste-ready)");
|
sb.AppendLine("### Sources (copy/paste-ready)");
|
||||||
foreach (var (i, r) in results.Index())
|
foreach (var (i, r) in results.Index())
|
||||||
{
|
{
|
||||||
var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
|
sb.AppendLine($"- {GetSourceName(r, i)}");
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(r.SourceLink))
|
|
||||||
{
|
|
||||||
sb.AppendLine($"- [{name}]({r.SourceLink})");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.AppendLine($"- {name}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
@@ -184,14 +183,21 @@ var textSearchOptions = new TextSearchProviderOptions()
|
|||||||
sb.AppendLine("### Excerpts");
|
sb.AppendLine("### Excerpts");
|
||||||
foreach (var (i, r) in results.Index())
|
foreach (var (i, r) in results.Index())
|
||||||
{
|
{
|
||||||
var name = string.IsNullOrWhiteSpace(r.SourceName) ? $"Source {i + 1}" : r.SourceName;
|
sb.AppendLine($"[{i + 1}] {GetSourceName(r, i)}");
|
||||||
|
|
||||||
sb.AppendLine($"[{i + 1}] {name}");
|
|
||||||
sb.AppendLine(r.Text);
|
sb.AppendLine(r.Text);
|
||||||
sb.AppendLine();
|
sb.AppendLine("---");
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.ToString();
|
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(),
|
SourceLink = c.Id.ToString().ToLowerInvariant(),
|
||||||
SourceName = c.Document.Name,
|
SourceName = c.Document.Name,
|
||||||
Text = c.Content,
|
Text = c.Content,
|
||||||
RawRepresentation = new { c.Id, c.DocumentId, c.PageNumber, c.IndexOnPage, c.Content }
|
RawRepresentation = c.PageNumber
|
||||||
})
|
})
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user