모든 벡터 저장소 커넥터를 텍스트 검색에 사용할 수 있습니다.
- Vector Store 커넥터를 사용하여 검색하려는 레코드 컬렉션을 검색합니다.
- 레코드 컬렉션을 으로 래핑합니다
VectorStoreTextSearch. - RAG 및/또는 함수 호출 시나리오에서 사용할 플러그 인으로 변환합니다.
해당 설명이 레코드 컬렉션에서 사용할 수 있는 데이터 형식을 반영하도록 플러그 인 검색 함수를 사용자 지정하려고 할 가능성이 큽니다. 예를 들어 레코드 컬렉션에 호텔에 대한 정보가 포함되어 있으면 플러그 인 검색 함수 설명에서 이를 언급해야 합니다. 이렇게 하면 여러 플러그 인을 등록할 수 있습니다(예: 호텔을 검색하는 플러그 인, 다른 플러그 인은 레스토랑, 다른 플러그 인은 할 일).
텍스트 검색 추상화에는 정규화된 검색 결과 즉, 인스턴스TextSearchResult를 반환하는 함수가 포함됩니다.
이 정규화된 검색 결과에는 값과 선택적으로 이름 및 링크가 포함됩니다.
텍스트 검색 추상화에는 문자열 값을 반환하는 함수가 포함됩니다. 예를 들어 데이터 모델 속성 중 하나가 검색 결과로 반환됩니다.
텍스트 검색이 올바르게 작동하려면 Vector Store 데이터 모델에서 인스턴스 TextSearchResult로 매핑하는 방법을 제공해야 합니다.
다음 섹션에서는 이 매핑을 수행하는 데 사용할 수 있는 두 가지 옵션에 대해 설명합니다.
팁
이 페이지에 표시된 샘플을 실행하려면 GettingStartedWithTextSearch/Step4_Search_With_VectorStore.cs 이동합니다.
텍스트 검색에서 벡터 저장소 모델 사용
벡터 저장소 데이터 모델에서 a TextSearchResult 로의 매핑은 특성을 사용하여 선언적으로 수행할 수 있습니다.
-
[TextSearchResultValue]- AI 모델이 질문에 대답하는 데 사용할 텍스트 데이터와 같은 값TextSearchResult이 될 데이터 모델의 속성에 이 특성을 추가합니다. -
[TextSearchResultName]- 이 특성을 데이터 모델의 이름TextSearchResult인 속성에 추가합니다. -
[TextSearchResultLink]- 에 대한 링크TextSearchResult가 될 데이터 모델의 속성에 이 특성을 추가합니다.
다음 샘플에서는 텍스트 검색 결과 특성이 적용된 데이터 모델을 보여줍니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
public sealed class DataModel
{
[VectorStoreKey]
[TextSearchResultName]
public Guid Key { get; init; }
[VectorStoreData]
[TextSearchResultValue]
public string Text { get; init; }
[VectorStoreData]
[TextSearchResultLink]
public string Link { get; init; }
[VectorStoreData(IsFilterable = true)]
public required string Tag { get; init; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> Embedding { get; init; }
}
벡터 저장소 데이터 모델에서 a 또는 a stringTextSearchResult 로의 매핑은 각각 구현 ITextSearchStringMapperITextSearchResultMapper 을 제공하여 수행할 수도 있습니다.
다음 시나리오에 대한 사용자 지정 매퍼를 만들 수 있습니다.
- 값을 제공하기 위해 여러 속성을 결합해야 하는 경우와 같이 데이터 모델의 여러 속성을 함께 결합해야 합니다.
- 링크 속성을 데이터 모델 속성에서 계산해야 하는 경우와 같이 속성 중 하나를 생성하려면 추가 논리가 필요합니다.
다음 샘플에서는 데이터 모델과 데이터 모델에서 사용할 수 있는 두 가지 예제 매퍼 구현을 보여 줍니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
protected sealed class DataModel
{
[VectorStoreKey]
public Guid Key { get; init; }
[VectorStoreData]
public required string Text { get; init; }
[VectorStoreData]
public required string Link { get; init; }
[VectorStoreData(IsFilterable = true)]
public required string Tag { get; init; }
[VectorStoreVector(1536)]
public ReadOnlyMemory<float> Embedding { get; init; }
}
/// <summary>
/// String mapper which converts a DataModel to a string.
/// </summary>
protected sealed class DataModelTextSearchStringMapper : ITextSearchStringMapper
{
/// <inheritdoc />
public string MapFromResultToString(object result)
{
if (result is DataModel dataModel)
{
return dataModel.Text;
}
throw new ArgumentException("Invalid result type.");
}
}
/// <summary>
/// Result mapper which converts a DataModel to a TextSearchResult.
/// </summary>
protected sealed class DataModelTextSearchResultMapper : ITextSearchResultMapper
{
/// <inheritdoc />
public TextSearchResult MapFromResultToTextSearchResult(object result)
{
if (result is DataModel dataModel)
{
return new TextSearchResult(value: dataModel.Text) { Name = dataModel.Key.ToString(), Link = dataModel.Link };
}
throw new ArgumentException("Invalid result type.");
}
}
아래와 같이 매퍼 구현을 만들 VectorStoreTextSearch 때 매개 변수로 제공할 수 있습니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel.Data;
// Create custom mapper to map a <see cref="DataModel"/> to a <see cref="string"/>
var stringMapper = new DataModelTextSearchStringMapper();
// Create custom mapper to map a <see cref="DataModel"/> to a <see cref="TextSearchResult"/>
var resultMapper = new DataModelTextSearchResultMapper();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var result = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration, stringMapper, resultMapper);
텍스트 검색과 함께 벡터 저장소 사용
아래 샘플에서는 Vector Store 레코드 컬렉션을 사용하는 인스턴스 VectorStoreTextSearch 를 만드는 방법을 보여 줍니다.
팁
다음 샘플에는 인스턴스 및 VectorStoreCollection.의 ITextEmbeddingGenerationService 인스턴스가 필요합니다.
인스턴스 VectorStoreCollection 를 만들려면 각 커넥터에 대한 설명서를 참조하세요.
사용하려는 서비스(예: Azure OpenAI, OpenAI, ...)의 ITextEmbeddingGenerationService 인스턴스를 만들려면... 또는 로컬 모델 ONNX, Ollama, ... 해당 구현의 인스턴스를 ITextEmbeddingGenerationService 만듭니다.
팁
의 인스턴스VectorStoreTextSearch에서 A IVectorizableTextSearch 를 생성할 수도 있습니다. 이 경우 필요하지 않습니다 ITextEmbeddingGenerationService .
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Search and return results as TextSearchResult items
var query = "What is the Semantic Kernel?";
KernelSearchResults<TextSearchResult> textResults = await textSearch.GetTextSearchResultsAsync(query, new() { Top = 2, Skip = 0 });
Console.WriteLine("\n--- Text Search Results ---\n");
await foreach (TextSearchResult result in textResults.Results)
{
Console.WriteLine($"Name: {result.Name}");
Console.WriteLine($"Value: {result.Value}");
Console.WriteLine($"Link: {result.Link}");
}
벡터 저장소에서 검색 플러그 인 만들기
아래 샘플에서는 인스턴스SearchPlugin에서 명명 VectorStoreTextSearch 된 플러그 인을 만드는 방법을 보여 줍니다.
사용 하 여 기본 Vector Store 레코드 컬렉션 검색 구현을 호출 하는 단일 CreateWithGetTextSearchResults 함수를 사용 하 여 GetTextSearchResults 새 플러그 인을 만듭니다.
SearchPlugin 프롬프트 렌더링 중에 호출할 수 있도록 하는 값에 추가 Kernel 됩니다.
프롬프트 템플릿에는 현재 쿼리와 관련된 결과를 검색하기 위해 호출 {{SearchPlugin.Search $query}} 하는 호출 SearchPlugin 이 포함되어 있습니다.
그러면 결과가 렌더링된 프롬프트에 삽입된 후 모델로 전송됩니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin");
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
var query = "What is the Semantic Kernel?";
string promptTemplate = """
{{#with (SearchPlugin-GetTextSearchResults query)}}
{{#each this}}
Name: {{Name}}
Value: {{Value}}
Link: {{Link}}
-----------------
{{/each}}
{{/with}}
{{query}}
Include citations to the relevant information where it is referenced in the response.
""";
KernelArguments arguments = new() { { "query", query } };
HandlebarsPromptTemplateFactory promptTemplateFactory = new();
Console.WriteLine(await kernel.InvokePromptAsync(
promptTemplate,
arguments,
templateFormat: HandlebarsPromptTemplateFactory.HandlebarsTemplateFormat,
promptTemplateFactory: promptTemplateFactory
));
함수 호출과 함께 벡터 저장소 사용
아래 샘플에서는 .의 SearchPlugin인스턴스에서도 만듭니다VectorStoreTextSearch.
이 플러그 인은 프롬프트 실행 설정에서 자동 함수 호출 FunctionChoiceBehavior 에 사용하기 위해 모델에 보급됩니다.
이 샘플을 실행하면 모델은 검색 함수를 호출하여 질문에 응답하는 추가 정보를 검색합니다.
전체 쿼리가 아닌 "의미 체계 커널"만 검색할 수 있습니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin");
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
KernelArguments arguments = new(settings);
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel?", arguments));
검색 함수 사용자 지정
아래 샘플에서는 에 추가되는 검색 함수에 대한 설명을 사용자 지정하는 SearchPlugin방법을 설명합니다.
수행할 수 있는 몇 가지 작업은 다음과 같습니다.
- 연결된 레코드 컬렉션에 있는 내용을 반영하도록 검색 함수의 이름을 변경합니다. 예를 들어 레코드 컬렉션에 호텔 정보가 포함된 경우 함수
SearchForHotels의 이름을 지정할 수 있습니다. - 함수에 대한 설명을 변경합니다. 정확한 함수 설명은 AI 모델이 호출할 가장 적합한 함수를 선택하는 데 도움이 됩니다. 이는 여러 검색 함수를 추가하는 경우에 특히 중요합니다.
- 검색 함수에 추가 매개 변수를 추가합니다. 레코드 컬렉션에 호텔 정보가 포함되어 있고 속성 중 하나가 도시 이름인 경우 검색 함수에 속성을 추가하여 도시를 지정할 수 있습니다. 필터가 자동으로 추가되고 도시별로 검색 결과가 필터링됩니다.
팁
아래 샘플에서는 검색의 기본 구현을 사용합니다. 기본 벡터 저장소 레코드 컬렉션을 호출하는 고유한 구현에 추가 옵션을 제공하여 검색을 미세 조정할 수 있습니다.
using Microsoft.Extensions.VectorData;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using Microsoft.SemanticKernel.Data;
using Microsoft.SemanticKernel.PromptTemplates.Handlebars;
// Create a kernel with OpenAI chat completion
IKernelBuilder kernelBuilder = Kernel.CreateBuilder();
kernelBuilder.AddOpenAIChatCompletion(
modelId: TestConfiguration.OpenAI.ChatModelId,
apiKey: TestConfiguration.OpenAI.ApiKey);
Kernel kernel = kernelBuilder.Build();
// Add code to create instances of VectorStoreCollection and ITextEmbeddingGenerationService
// Create a text search instance using the vector store collection.
var textSearch = new VectorStoreTextSearch<DataModel>(vectorStoreCollection, textEmbeddingGeneration);
// Create options to describe the function I want to register.
var options = new KernelFunctionFromMethodOptions()
{
FunctionName = "Search",
Description = "Perform a search for content related to the specified query from a record collection.",
Parameters =
[
new KernelParameterMetadata("query") { Description = "What to search for", IsRequired = true },
new KernelParameterMetadata("top") { Description = "Number of results", IsRequired = false, DefaultValue = 2 },
new KernelParameterMetadata("skip") { Description = "Number of results to skip", IsRequired = false, DefaultValue = 0 },
],
ReturnParameter = new() { ParameterType = typeof(KernelSearchResults<string>) },
};
// Build a text search plugin with vector store search and add to the kernel
var searchPlugin = textSearch.CreateWithGetTextSearchResults("SearchPlugin", "Search a record collection", [textSearch.CreateSearch(options)]);
kernel.Plugins.Add(searchPlugin);
// Invoke prompt and use text search plugin to provide grounding information
OpenAIPromptExecutionSettings settings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto() };
KernelArguments arguments = new(settings);
Console.WriteLine(await kernel.InvokePromptAsync("What is the Semantic Kernel?", arguments));
서비스 예정
더 곧 출시될 예정입니다.
서비스 예정
더 곧 출시될 예정입니다.