Microsoft Agent Framework는 모델 호출 전에 검색된 콘텐츠를 추가하는 컨텍스트 공급자를 통해 RAG(검색 보강 생성)를 지원하고 모델이 요청 시 접지 데이터를 검색할 수 있도록 하는 검색 도구를 지원합니다.
검색과 함께 대화/세션 패턴은 대화 및 메모리 개요를 참조하세요. 서비스별 설정은 Azure AI 검색, Microsoft Foundry 및 Neo4j를 참조하세요.
TextSearchProvider 사용
클래스 TextSearchProvider 는 RAG 컨텍스트 공급자의 기본 구현입니다.
채팅 기록을 사용하여 실행되는 각 에이전트에 대한 검색을 수행하거나 검색을 수행하기 위한 광고 기능 도구와 같은 다양한 작업 모드를 지원합니다.
옵션을 사용하여 ChatClientAgent 쉽게 연결할 AIContextProviders 수 있습니다.
// Configure the options for the TextSearchProvider.
TextSearchProviderOptions textSearchOptions = new()
{
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
};
// Create the AI agent with the TextSearchProvider.
AIAgent agent = azureOpenAIClient
.GetChatClient(deploymentName)
.AsAIAgent(new ChatClientAgentOptions
{
ChatOptions = new() { Instructions = "You are a helpful support specialist. Answer questions using the provided context and cite the source document when available." },
AIContextProviders = [new TextSearchProvider(SearchAdapter, textSearchOptions)]
});
쿼리 TextSearchProvider 가 제공된 경우 검색 결과를 제공하는 함수가 필요합니다. Azure AI 검색 또는 웹 검색 엔진과 같은 모든 검색 기술을 사용하여 구현할 수 있습니다.
Tip
검색 결과에 벡터 저장소를 사용하는 방법에 대한 자세한 내용은 Vector 저장소 통합 을 참조하세요.
다음은 쿼리를 기반으로 미리 정의된 결과를 반환하는 모의 검색 함수의 예입니다.
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 chat history for searches.
SearchTime = TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke,
RecentMessageMemoryLimit = 6,
};
클래스는 TextSearchProvider 클래스를 통해 다음 옵션을 지원합니다 TextSearchProviderOptions .
| 옵션 | Type | 설명 | Default |
|---|---|---|---|
| 검색시간 | TextSearchProviderOptions.TextSearchBehavior |
검색을 실행해야 하는 시기를 나타냅니다. 에이전트를 실행할 때마다 또는 함수 호출을 통해 주문형으로 두 가지 옵션이 있습니다. | TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke |
| FunctionToolName | string |
주문형 모드에서 작동할 때 노출된 검색 도구의 이름입니다. | "검색" |
| FunctionToolDescription | string |
주문형 모드에서 작동할 때 노출된 검색 도구에 대한 설명입니다. | "사용자 질문에 대답하는 데 도움이 되는 추가 정보를 검색할 수 있습니다." |
| [문맥 프롬프트] | string |
결과에 접두사로 추가된 컨텍스트 프롬프트입니다. | "## 추가 컨텍스트\n사용자에게 응답할 때 원본 문서에서 다음 정보를 고려합니다." |
| CitationsPrompt | string |
인용을 요청하기 위해 결과 후에 추가된 명령입니다. | "문서 이름과 링크를 사용할 수 있는 경우 문서 이름과 링크가 있는 원본 문서에 인용을 포함합니다." |
| ContextFormatter | Func<IList<TextSearchProvider.TextSearchResult>, string> |
결과 목록의 서식을 완전히 사용자 지정하는 선택적 대리자입니다. 제공된 ContextPromptCitationsPrompt 경우 무시됩니다. |
null |
| RecentMessageMemoryLimit | int |
메모리에 유지하고 검색을 위한 BeforeAIInvoke 검색 입력을 생성할 때 포함할 최근 대화 메시지(사용자 및 도우미 모두)의 수입니다. |
0 (사용 안 함) |
| RecentMessageRolesIncluded | List<ChatRole> |
검색 입력을 생성할 때 포함할 최근 메시지를 결정할 때 최근 메시지를 필터링할 형식 목록 ChatRole 입니다. |
ChatRole.User |
Tip
실행 가능한 전체 예제는 .NET 샘플 참조하세요.
에이전트 프레임워크는 네이티브 벡터 저장소 계약 및 create_vector_search_tool(). 도우미는 모든 SupportsVectorSearch 구현을 함수 도구로 변환하므로 모델이 응답하기 전에 접지 데이터를 검색할 수 있습니다.
네이티브 벡터 검색 도구 만들기
먼저 벡터 저장소 모델을 정의하고, 컬렉션을 만들고, 해당 레코드를 로드합니다. 다음 샘플에서는 사용 InMemoryCollectionOpenAIEmbeddingClient하지만 구현하는 모든 네이티브 Agent Framework 컬렉션을 제공할 수 있습니다 SupportsVectorSearch. 그런 다음 선택적 범주 및 등급 필터를 모델에 노출하고, 각 결과를 접지 텍스트에 매핑하고, 에이전트가 답변하기 전에 검색하도록 지시합니다.
import asyncio
import json
import os
from typing import Annotated, Any, Literal
from urllib.request import urlopen
from agent_framework import (
Agent,
Filter,
FilterGroup,
InMemoryCollection,
Param,
VectorStoreField,
create_vector_search_tool,
vectorstoremodel,
)
from agent_framework.openai import OpenAIChatClient, OpenAIEmbeddingClient
from dotenv import load_dotenv
async def main() -> None:
"""Create an in-memory hotel search tool and give it to an agent."""
api_key = os.environ["OPENAI_API_KEY"]
collection: InMemoryCollection[str, Hotel] = InMemoryCollection(
Hotel,
embedding_generator=OpenAIEmbeddingClient(
model="text-embedding-3-small",
api_key=api_key,
),
)
await collection.ensure_collection_exists()
# 1. Load the hotel records.
hotels = await asyncio.to_thread(load_hotels)
await collection.upsert(hotels)
# 2. Param values become optional model-visible filter arguments.
# When the allowed values are known, use Literal so the tool schema exposes
# them as an enum.
category = Param(
"category",
Literal["Boutique", "Budget", "Extended-Stay", "Luxury", "Resort and Spa", "Suite"],
description="Only return hotels in this category.",
)
min_rating = Param(
"min_rating",
float,
description="The minimum guest rating.",
minimum=0,
maximum=5,
)
tool = create_vector_search_tool(
collection,
description="Search the hotel dataset, optionally filtering by category and minimum rating.",
filter=FilterGroup(
"and",
(
Filter("category", "eq", category),
Filter("rating", "gte", min_rating),
),
),
result_mapper=lambda result: (
f"(hotel_id: {result['record'].hotel_id}) {result['record'].hotel_name} "
f"(rating {result['record'].rating}) - {result['record'].description}. "
f"Address: {result['record'].address.city}, {result['record'].address.country}."
),
)
# 3. The agent chooses whether to supply the exposed category and minimum-rating filters.
async with Agent(
client=OpenAIChatClient(
model="gpt-5.4-nano",
api_key=api_key,
),
name="HotelAgent",
instructions=(
"Always use the search tool to answer hotel questions. "
"Use category and minimum rating filters when the request provides them. "
"Include the hotel_id in the answer."
),
tools=[tool],
) as agent:
result = await agent.run("Find a resort and spa with a rating of at least 4.")
print(result)
전체 샘플은 모델을 정의 Hotel 하고 표시된 컬렉션 설정 전에 원본 레코드를 로드합니다. 실행하기 전에 설정합니다 OPENAI_API_KEY .
검색 동작 사용자 지정
다음 옵션을 사용하여 구성 create_vector_search_tool() 합니다.
| 옵션 | Purpose |
|---|---|
name |
모델에 노출되는 함수 이름을 설정합니다. 여러 검색 도구를 추가할 때 고유한 이름을 사용합니다. |
description |
모델에서 도구를 사용해야 하는 시기와 이유를 설명합니다. |
approval_mode |
도구 승인을 always_require 설정합니다.never_require |
search_type |
선택하거나 keyword_hybrid 검색합니다vector. 컬렉션은 선택한 모드를 지원해야 합니다. |
top 및 skip |
고정 페이징 값을 설정하거나 모델이 제공하는 형식화된 Param 값을 사용합니다. |
filter |
이식 Filter 가능한 또는 FilterGroup.를 적용합니다. 필터는 도구 스키마에 노출되는 형식화된 Param 값을 포함할 수 있습니다. |
result_mapper |
각각 SearchResponse 을 모델의 텍스트 또는 멀티모달 Content 로 변환합니다. |
생성된 도구에는 항상 문자열이 query 포함됩니다. 필터 top또는 skip 설정의 모든 Param 값은 유효성이 검사된 추가 도구 인수가 됩니다.
사용 Literal 및 숫자 제약 조건을 사용하여 애플리케이션에서 허용하는 범위 내에서 모델 제공 값을 유지합니다.
다양한 컬렉션 또는 검색 모드에 대한 여러 도구를 만들 수 있습니다. 각 도구에 고유 name 하게 지정하여 description 모델이 적절한 기술 자료를 선택할 수 있도록 합니다.
네이티브 벡터 저장소 선택
네이티브 Python 구현은 메모리 내 검색, Azure AI 검색, pgvector, Qdrant 및 Redis를 사용하는 PostgreSQL에 사용할 수 있습니다. 검색 모드, 패키지 수명 주기, 설치 명령 및 제한 사항이 다릅니다. 구현을 선택하고 구성하려면 Vector 저장소 통합 을 참조하세요. 또한 이 페이지는 현재 별도의 의미 체계 커널 커넥터만 있는 데이터베이스를 식별합니다.
비고
이 기능에 대한 지원은 곧 제공될 예정입니다. 최신 상태는 에이전트 프레임워크 Go 리포지토리 를 참조하세요.
그래프 RAG
GraphRAG가 Cypher 쿼리와 함께 그래프 순회 보강 검색을 사용하는 경우 Neo4j GraphRAG 공급자를 참조하세요.