Microsoft Agent Framework では、AI コンテキスト プロバイダーをエージェントに追加することで、エージェントに取得拡張生成 (RAG) 機能を簡単に追加できます。
TextSearchProvider の使用
TextSearchProvider クラスは、RAG コンテキスト プロバイダーのすぐに使用する実装です。
ChatClientAgent オプションを使用して、エージェントに RAG 機能を提供することで、AIContextProviderFactoryに簡単にアタッチできます。
// Create the AI agent with the TextSearchProvider as the AI context provider.
AIAgent agent = azureOpenAIClient
.GetChatClient(deploymentName)
.CreateAIAgent(new ChatClientAgentOptions
{
Instructions = "You are a helpful support specialist for Contoso Outdoors. Answer questions using the provided context and cite the source document when available.",
AIContextProviderFactory = ctx => new TextSearchProvider(SearchAdapter, ctx.SerializedState, ctx.JsonSerializerOptions, textSearchOptions)
});
TextSearchProviderには、クエリに指定された検索結果を提供する関数が必要です。 これは、Azure AI Search や Web 検索エンジンなど、任意の検索テクノロジを使用して実装できます。
クエリに基づいて定義済みの結果を返すモック検索機能の例を次に示します。
SourceName および SourceLink は省略可能ですが、指定された場合は、エージェントがユーザーの質問に答えるときに情報のソースを引用するために使用されます。
static Task<IEnumerable<TextSearchProvider.TextSearchResult>> SearchAdapter(string query, CancellationToken cancellationToken)
{
// The mock search inspects the user's question and returns pre-defined snippets
// that resemble documents stored in an external knowledge source.
List<TextSearchProvider.TextSearchResult> results = new();
if (query.Contains("return", StringComparison.OrdinalIgnoreCase) || query.Contains("refund", StringComparison.OrdinalIgnoreCase))
{
results.Add(new()
{
SourceName = "Contoso Outdoors Return Policy",
SourceLink = "https://contoso.com/policies/returns",
Text = "Customers may return any item within 30 days of delivery. Items should be unused and include original packaging. Refunds are issued to the original payment method within 5 business days of inspection."
});
}
return Task.FromResult<IEnumerable<TextSearchProvider.TextSearchResult>>(results);
}
TextSearchProvider オプション
TextSearchProviderは、TextSearchProviderOptions クラスを使用してカスタマイズできます。 次に、すべてのモデル呼び出しの前に検索を実行し、会話コンテキストの短いローリング ウィンドウを保持するオプションを作成する例を示します。
TextSearchProviderOptions textSearchOptions = new()
{
// Run the search prior to every model invocation and keep a short rolling window of conversation context.
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
RecentMessageMemoryLimit = 6,
};
TextSearchProvider クラスは、TextSearchProviderOptions クラスを介して次のオプションをサポートしています。
| Option | タイプ | Description | 既定値 |
|---|---|---|---|
| SearchTime | TextSearchProviderOptions.TextSearchBehavior |
検索を実行するタイミングを示します。 エージェントが呼び出されるたびに、または関数呼び出しを介したオンデマンドの 2 つのオプションがあります。 | TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke |
| FunctionToolName | string |
オンデマンド モードで動作する場合に公開される検索ツールの名前。 | "検索" |
| FunctionToolDescription | string |
オンデマンド モードで動作する場合に公開される検索ツールの説明。 | "ユーザーの質問に答えるのに役立つ追加情報を検索できます。" |
| ContextPrompt | string |
BeforeAIInvoke モードで動作しているときに、結果のプレフィックスが付いたコンテキスト プロンプト。 |
"## 追加コンテキスト\nユーザーに応答するときに、ソース ドキュメントからの次の情報を考慮してください。" |
| CitationsPrompt | string |
BeforeAIInvokeモードで動作しているときに引用を要求する結果の後に追加された命令。 |
"ドキュメント名とリンクを使用できる場合は、ドキュメント名とリンクを使用して、ソース ドキュメントへの引用を含めます。" |
| ContextFormatter | Func<IList<TextSearchProvider.TextSearchResult>, string> |
BeforeAIInvoke モードで動作する場合に結果一覧の書式を完全にカスタマイズする省略可能なデリゲート。 指定した場合、 ContextPrompt と CitationsPrompt は無視されます。 |
null |
| RecentMessageMemoryLimit | int |
メモリ内に保持し、 BeforeAIInvoke 検索の検索入力を構築するときに含める最近の会話メッセージ (ユーザーとアシスタントの両方) の数。 |
0 (無効) |
| RecentMessageRolesIncluded | List<ChatRole> |
検索入力の作成時に含める最近のメッセージを決定するときに、最近使用したメッセージをフィルター処理する ChatRole の種類の一覧。 |
ChatRole.User |
エージェント フレームワークでのセマンティック カーネル ベクターストアの使用
Agent Framework では、セマンティック カーネルの VectorStore コレクションを使用して、エージェントに RAG 機能を提供できます。 これは、セマンティック カーネル検索関数を Agent Framework ツールに変換するブリッジ機能によって実現されます。
Important
この機能には、 semantic-kernel バージョン 1.38 以降が必要です。
VectorStore から検索ツールを作成する
セマンティック カーネル ベクターストア コレクションのcreate_search_function メソッドは、KernelFunctionを使用して Agent Framework ツールに変換できる.as_agent_framework_tool()を返します。
ベクター ストア コネクタのドキュメントを使用して、さまざまなベクター ストア コレクションを設定する方法について説明します。
from semantic_kernel.connectors.ai.open_ai import OpenAITextEmbedding
from semantic_kernel.connectors.azure_ai_search import AzureAISearchCollection
from semantic_kernel.functions import KernelParameterMetadata
from agent_framework.openai import OpenAIResponsesClient
# Define your data model
class SupportArticle:
article_id: str
title: str
content: str
category: str
# ... other fields
# Create an Azure AI Search collection
collection = AzureAISearchCollection[str, SupportArticle](
record_type=SupportArticle,
embedding_generator=OpenAITextEmbedding()
)
async with collection:
await collection.ensure_collection_exists()
# Load your knowledge base articles into the collection
# await collection.upsert(articles)
# Create a search function from the collection
search_function = collection.create_search_function(
function_name="search_knowledge_base",
description="Search the knowledge base for support articles and product information.",
search_type="keyword_hybrid",
parameters=[
KernelParameterMetadata(
name="query",
description="The search query to find relevant information.",
type="str",
is_required=True,
type_object=str,
),
KernelParameterMetadata(
name="top",
description="Number of results to return.",
type="int",
default_value=3,
type_object=int,
),
],
string_mapper=lambda x: f"[{x.record.category}] {x.record.title}: {x.record.content}",
)
# Convert the search function to an Agent Framework tool
search_tool = search_function.as_agent_framework_tool()
# Create an agent with the search tool
agent = OpenAIResponsesClient(model_id="gpt-4o").create_agent(
instructions="You are a helpful support specialist. Use the search tool to find relevant information before answering questions. Always cite your sources.",
tools=search_tool
)
# Use the agent with RAG capabilities
response = await agent.run("How do I return a product?")
print(response.text)
検索動作のカスタマイズ
検索機能は、さまざまなオプションを使用してカスタマイズできます。
# Create a search function with filtering and custom formatting
search_function = collection.create_search_function(
function_name="search_support_articles",
description="Search for support articles in specific categories.",
search_type="keyword_hybrid",
# Apply filters to restrict search scope
filter=lambda x: x.is_published == True,
parameters=[
KernelParameterMetadata(
name="query",
description="What to search for in the knowledge base.",
type="str",
is_required=True,
type_object=str,
),
KernelParameterMetadata(
name="category",
description="Filter by category: returns, shipping, products, or billing.",
type="str",
type_object=str,
),
KernelParameterMetadata(
name="top",
description="Maximum number of results to return.",
type="int",
default_value=5,
type_object=int,
),
],
# Customize how results are formatted for the agent
string_mapper=lambda x: f"Article: {x.record.title}\nCategory: {x.record.category}\nContent: {x.record.content}\nSource: {x.record.article_id}",
)
create_search_functionで使用できるパラメーターの詳細については、セマンティック カーネルのドキュメントを参照してください。
複数の検索機能の使用
さまざまなナレッジ ドメインのエージェントに複数の検索ツールを提供できます。
# Create search functions for different knowledge bases
product_search = product_collection.create_search_function(
function_name="search_products",
description="Search for product information and specifications.",
search_type="semantic_hybrid",
string_mapper=lambda x: f"{x.record.name}: {x.record.description}",
).as_agent_framework_tool()
policy_search = policy_collection.create_search_function(
function_name="search_policies",
description="Search for company policies and procedures.",
search_type="keyword_hybrid",
string_mapper=lambda x: f"Policy: {x.record.title}\n{x.record.content}",
).as_agent_framework_tool()
# Create an agent with multiple search tools
agent = chat_client.create_agent(
instructions="You are a support agent. Use the appropriate search tool to find information before answering. Cite your sources.",
tools=[product_search, policy_search]
)
また、同じコレクションから複数の検索機能を作成し、さまざまな説明とパラメーターを使用して、特殊な検索機能を提供することもできます。
# Create multiple search functions from the same collection
# Generic search for broad queries
general_search = support_collection.create_search_function(
function_name="search_all_articles",
description="Search all support articles for general information.",
search_type="semantic_hybrid",
parameters=[
KernelParameterMetadata(
name="query",
description="The search query.",
type="str",
is_required=True,
type_object=str,
),
],
string_mapper=lambda x: f"{x.record.title}: {x.record.content}",
).as_agent_framework_tool()
# Detailed lookup for specific article IDs
detail_lookup = support_collection.create_search_function(
function_name="get_article_details",
description="Get detailed information for a specific article by its ID.",
search_type="keyword",
top=1,
parameters=[
KernelParameterMetadata(
name="article_id",
description="The specific article ID to retrieve.",
type="str",
is_required=True,
type_object=str,
),
],
string_mapper=lambda x: f"Title: {x.record.title}\nFull Content: {x.record.content}\nLast Updated: {x.record.updated_date}",
).as_agent_framework_tool()
# Create an agent with both search functions
agent = chat_client.create_agent(
instructions="You are a support agent. Use search_all_articles for general queries and get_article_details when you need full details about a specific article.",
tools=[general_search, detail_lookup]
)
この方法により、エージェントはユーザーのクエリに基づいて最適な検索戦略を選択できます。
サポートされている VectorStore コネクタ
このパターンは、次のようなセマンティック カーネル VectorStore コネクタで動作します。
- Azure AI Search (
AzureAISearchCollection) - Qdrant (
QdrantCollection) - Pinecone (
PineconeCollection) - Redis (
RedisCollection) - Weaviate (
WeaviateCollection) - In-Memory (
InMemoryVectorStoreCollection) - その他
各コネクタには、Agent Framework ツールにブリッジできる同じ create_search_function メソッドが用意されており、ニーズに最適なベクター データベースを選択できます。
完全な一覧については、こちらをご覧ください。