Dela via


Förhöjd generering av agenthämtning (RAG)

Microsoft Agent Framework har stöd för att lägga till RAG-funktioner (Retrieval Augmented Generation) till agenter på ett enkelt sätt genom att lägga till AI-kontextprovidrar i agenten.

Använda TextSearchProvider

Klassen TextSearchProvider är en out-of-the-box-implementering av en RAG-kontextprovider.

Det kan enkelt kopplas till en ChatClientAgent med hjälp av AIContextProviderFactory alternativet för att tillhandahålla RAG-funktioner till agenten.

// Create the AI agent with the TextSearchProvider as the AI context provider.
AIAgent agent = azureOpenAIClient
    .GetChatClient(deploymentName)
    .CreateAIAgent(new ChatClientAgentOptions
    {
        ChatOptions = new() { 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)
    });

Kräver TextSearchProvider en funktion som ger sökresultaten som ges en fråga. Detta kan implementeras med valfri sökteknik, t.ex. Azure AI Search eller en webbsökmotor.

Här är ett exempel på en modellsökningsfunktion som returnerar fördefinierade resultat baserat på frågan. SourceName och SourceLink är valfria, men om de tillhandahålls kommer att användas av agenten för att citera källan till informationen när användarens fråga besvaras.

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);
}

Alternativ för TextSearchProvider

TextSearchProvider Kan anpassas via TextSearchProviderOptions klassen. Här är ett exempel på hur du skapar alternativ för att köra sökningen före varje modellanrop och hålla ett kort rullande fönster med konversationskontext.

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,
};

Klassen TextSearchProvider stöder följande alternativ via TextSearchProviderOptions klassen.

Option Typ Description Förinställning
SearchTime TextSearchProviderOptions.TextSearchBehavior Anger när sökningen ska köras. Det finns två alternativ, varje gång agenten anropas eller på begäran via funktionsanrop. TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke
FunctionToolName string Namnet på det exponerade sökverktyget när du arbetar i läget på begäran. "Sök"
FunctionToolDescription string Beskrivningen av det exponerade sökverktyget när du arbetar i läget på begäran. "Tillåter sökning efter ytterligare information för att besvara användarfrågan."
ContextPrompt string Kontextprompten föregås av resultat vid drift i BeforeAIInvoke läge. "## Ytterligare kontext\nÖverväg följande information från källdokumenten när du svarar användaren:"
CitatPrompt string Instruktionen som läggs till efter resultaten för att begära citat när du arbetar i BeforeAIInvoke läge. "Inkludera citat till källdokumentet med dokumentnamn och länk om dokumentnamn och länk är tillgängliga."
ContextFormatter Func<IList<TextSearchProvider.TextSearchResult>, string> Valfritt ombud för att helt anpassa formatering av resultatlistan när du arbetar i BeforeAIInvoke läge. Om detta anges ContextPrompt och CitationsPrompt ignoreras. null
RecentMessageMemoryLimit int Antalet konversationsmeddelanden (både användare och assistent) som ska sparas i minnet och inkludera när du skapar sökindata för BeforeAIInvoke sökningar. 0 (inaktiverad)
RecentMessageRolesIncluded List<ChatRole> Listan över ChatRole typer att filtrera de senaste meddelandena till när du bestämmer vilka nya meddelanden som ska inkluderas när du skapar sökindata. ChatRole.User

Använda Semantic Kernel VectorStore med Agent Framework

Agent Framework stöder användning av Semantic Kernels VectorStore-samlingar för att tillhandahålla RAG-funktioner till agenter. Detta uppnås genom bryggfunktionen som konverterar semantiska kernelsökningsfunktioner till Agent Framework-verktyg.

Viktigt!

Den här funktionen kräver semantic-kernel version 1.38 eller senare.

Skapa ett sökverktyg från VectorStore

Metoden create_search_function från en Semantic Kernel VectorStore-samling returnerar en KernelFunction som kan konverteras till ett Agent Framework-verktyg med ..as_agent_framework_tool() Använd dokumentationen för anslutningsprogram för vektorarkiv för att lära dig hur du konfigurerar olika vektorlagersamlingar.

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)

Anpassa sökbeteende

Du kan anpassa sökfunktionen med olika alternativ:

# 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}",
)

Fullständig information om de parametrar som är tillgängliga för create_search_functionfinns i dokumentationen om semantisk kernel.

Använda flera sökfunktioner

Du kan tillhandahålla flera sökverktyg till en agent för olika kunskapsdomäner:

# 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]
)

Du kan också skapa flera sökfunktioner från samma samling med olika beskrivningar och parametrar för att tillhandahålla specialiserade sökfunktioner:

# 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]
)

Med den här metoden kan agenten välja den lämpligaste sökstrategin baserat på användarens fråga.

VectorStore-anslutningsappar som stöds

Det här mönstret fungerar med alla Semantic Kernel VectorStore-anslutningsappar, inklusive:

  • Azure AI Search (AzureAISearchCollection)
  • Qdrant (QdrantCollection)
  • Pinecone (PineconeCollection)
  • Redis (RedisCollection)
  • Weaviate (WeaviateCollection)
  • In-Memory (InMemoryVectorStoreCollection)
  • Och mera

Varje anslutningsapp har samma create_search_function metod som kan överbryggas till Agent Framework-verktyg, så att du kan välja den vektordatabas som bäst passar dina behov. Se hela listan här.

Nästa steg