STRACCIO

Microsoft Agent Framework supporta il recupero della generazione aumentata (RAG) tramite provider di contesto che aggiungono contenuto recuperato prima della chiamata del modello e degli strumenti di ricerca che consentono al modello di recuperare i dati a terra su richiesta.

Per i modelli di conversazione/sessione insieme al recupero, vedere Panoramica delle conversazioni e della memoria. Per la configurazione specifica del servizio, vedere Azure AI Search, Microsoft Foundry e Neo4j.

Uso di TextSearchProvider

La TextSearchProvider classe è un'implementazione predefinita di un provider di contesto RAG. Supporta diverse modalità di funzionamento, ad esempio l'esecuzione di una ricerca di ogni agente con cronologia chat o strumenti di funzione pubblicitari per l'esecuzione di ricerche.

Può essere facilmente collegato a un ChatClientAgent utilizzando l'opzione 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)]
    });

richiede TextSearchProvider una funzione che fornisce i risultati della ricerca in base a una query. Questa operazione può essere implementata usando qualsiasi tecnologia di ricerca, ad esempio Azure AI Search o un motore di ricerca Web.

Tip

Per altre informazioni su come usare un archivio vettoriale per i risultati della ricerca, vedere Integrazioni dell'archivio vettoriale .

Di seguito è riportato un esempio di una funzione di ricerca fittizia che restituisce risultati predefiniti basati sulla query. SourceName e SourceLink sono facoltativi, ma se forniti verranno usati dall'agente per citare l'origine delle informazioni quando risponde alla domanda dell'utente.

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

Opzioni TextSearchProvider

Può TextSearchProvider essere personalizzato tramite la TextSearchProviderOptions classe . Di seguito è riportato un esempio di creazione di opzioni per eseguire la ricerca prima di ogni chiamata al modello e mantenere una breve finestra di sequenza della cronologia delle chat per le ricerche.

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

La TextSearchProvider classe supporta le opzioni seguenti tramite la TextSearchProviderOptions classe .

Option Type Descrizione Default
Tempo di Ricerca TextSearchProviderOptions.TextSearchBehavior Indica quando deve essere eseguita la ricerca. Sono disponibili due opzioni, ogni volta che l'agente viene eseguito o su richiesta tramite chiamata di funzione. TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke
FunctionToolName string Nome dello strumento di ricerca esposto quando si opera in modalità su richiesta. "Cerca"
FunctionToolDescription string Descrizione dello strumento di ricerca esposto quando si opera in modalità su richiesta. "Consente la ricerca di informazioni aggiuntive per rispondere alla domanda dell'utente."
ContextPrompt string Richiesta di contesto preceduta da un prefisso per i risultati. "## Contesto aggiuntivo\nPrendere in considerazione le informazioni seguenti dai documenti di origine quando rispondono all'utente:"
CitazioniPrompt string L'istruzione è stata aggiunta dopo i risultati per richiedere citazioni. "Includi citazioni al documento di origine con il nome del documento e collega se il nome e il collegamento del documento sono disponibili".
ContextFormatter Func<IList<TextSearchProvider.TextSearchResult>, string> Delegato facoltativo per personalizzare completamente la formattazione dell'elenco risultati. Se specificato, ContextPrompt e CitationsPrompt vengono ignorati. null
RecentMessageMemoryLimit int Numero di messaggi di conversazione recenti (sia utente che assistente) da mantenere in memoria e includere quando si costruisce l'input di ricerca per BeforeAIInvoke le ricerche. 0 (disabilitato)
RecentMessageRolesIncluded List<ChatRole> Elenco di ChatRole tipi a cui filtrare i messaggi recenti quando si decide quali messaggi recenti includere quando si costruisce l'input di ricerca. ChatRole.User

Agent Framework fornisce contratti di archivio vettoriali nativi e create_vector_search_tool(). L'helper trasforma qualsiasi SupportsVectorSearch implementazione in uno strumento di funzione, in modo che il modello possa recuperare i dati di base prima di rispondere.

Creare uno strumento di ricerca vettoriale nativo

Prima di tutto, definire il modello di archivio vettoriale, creare una raccolta e caricarne i record. L'esempio seguente usa InMemoryCollection con OpenAIEmbeddingClient, ma è possibile fornire qualsiasi raccolta nativa di Agent Framework che implementa SupportsVectorSearch. Espone quindi i filtri facoltativi di categoria e classificazione al modello, esegue il mapping di ogni risultato al testo di base e indica all'agente di eseguire la ricerca prima che risponda:

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)

L'esempio completo definisce il Hotel modello e carica i record di origine prima dell'installazione della raccolta mostrata. Impostare OPENAI_API_KEY prima di eseguirlo.

Personalizzare il comportamento della ricerca

Configurare create_vector_search_tool() con le opzioni seguenti:

Option Purpose
name Imposta il nome della funzione esposto al modello. Usare un nome univoco quando si aggiungono più strumenti di ricerca.
description Illustra quando e perché il modello deve usare lo strumento.
approval_mode Imposta l'approvazione dello strumento su always_require o never_require.
search_type vector Seleziona o keyword_hybrid cerca. La raccolta deve supportare la modalità selezionata.
top e skip Impostare valori fissi di paging o usare valori tipizzati Param forniti dal modello.
filter Applica un oggetto portatile Filter o FilterGroup. Un filtro può contenere valori tipizzati Param esposti nello schema dello strumento.
result_mapper Converte ogni SearchResponse oggetto in testo o multimodelli Content per il modello.

Lo strumento generato include sempre una query stringa. Tutti Param i valori nel filtro, topo skip nelle impostazioni diventano argomenti aggiuntivi dello strumento convalidati. Usare Literal i vincoli numerici e per mantenere i valori forniti dal modello all'interno dell'intervallo accettato dall'applicazione.

È possibile creare più strumenti per raccolte o modalità di ricerca diverse. Assegnare a ogni strumento un elemento distinto name e description in modo che il modello possa selezionare l'origine delle conoscenze appropriata.

Scegliere un archivio vettoriale nativo

Le implementazioni di Python native sono disponibili per la ricerca in memoria, Azure AI Search, PostgreSQL con pgvector, Qdrant e Redis. Le modalità di ricerca, il ciclo di vita dei pacchetti, i comandi di installazione e le limitazioni variano. Vedere Integrazioni dell'archivio vettoriali per selezionare e configurare un'implementazione. Tale pagina identifica anche i database che attualmente dispongono solo di un connettore Kernel semantico separato.

Annotazioni

Il supporto per questa funzionalità sarà presto disponibile. Vedere il repository di Agent Framework Go per lo stato più aggiornato.

Graph RAG

Per GraphRAG usando la ricerca arricchita a grafo con query di crittografia, vedere Il provider GraphRAG Neo4j.

Passaggi successivi