RAG

O Microsoft Agent Framework suporta a Geração Aumentada de Recuperação (RAG) através de fornecedores de contexto que adicionam conteúdo recuperado antes da invocação do modelo e ferramentas de pesquisa que permitem ao modelo recuperar dados de grounding a pedido.

Para padrões de conversa/sessão juntamente com a recuperação, veja Visão Geral de Conversas e Memória. Para configuração específica de serviço, veja Pesquisa de IA do Azure, Microsoft Foundry e Neo4j.

Usando TextSearchProvider

A TextSearchProvider classe é uma implementação pronta para uso de um provedor de contexto RAG. Suporta diferentes modos de operação, por exemplo, fazer uma pesquisa para cada agente com histórico de chat, ou ferramentas de publicidade para realizar pesquisas.

Pode ser facilmente ligado a um ChatClientAgent usando a opção 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)]
    });

O TextSearchProvider requer uma função que fornece os resultados da pesquisa dada uma consulta. Isto pode ser implementado utilizando qualquer tecnologia de pesquisa, por exemplo, Pesquisa de IA do Azure ou um motor de busca web.

Tip

Consulte as integrações de armazenamento vetorial para mais informações sobre como usar um armazenamento vetorial para resultados de pesquisa.

Aqui está um exemplo de uma função de pesquisa simulada que retorna resultados predefinidos com base na consulta. SourceName e SourceLink são opcionais, mas se fornecidos serão usados pelo agente para citar a fonte da informação ao responder à pergunta do usuário.

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

Opções de TextSearchProvider

O TextSearchProvider pode ser personalizado através da TextSearchProviderOptions classe. Aqui está um exemplo de como criar opções para executar a pesquisa antes de cada invocação de modelo e manter uma curta janela móvel de histórico de chat para pesquisas.

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

A TextSearchProvider classe suporta as seguintes opções através da TextSearchProviderOptions classe.

Option Tipo Descrição Default
Tempo de Pesquisa TextSearchProviderOptions.TextSearchBehavior Indica quando a pesquisa deve ser executada. Existem duas opções: cada vez que o agente é executado, ou on-demand via chamada de funções. TextSearchProviderOptions.TextSearchBehavior.BeforeAIInvoke
FunctionToolName string O nome da ferramenta de pesquisa exposta ao operar no modo sob demanda. "Pesquisar"
FunctionToolDescription string A descrição da ferramenta de pesquisa exposta ao operar no modo sob demanda. "Permite pesquisar informações adicionais para ajudar a responder à pergunta do usuário."
ContextPrompt string O enunciado de contexto antecede os resultados. "## Contexto adicional\nConsidere as seguintes informações dos documentos de origem ao responder ao usuário:"
CitaçõesPrompt string A instrução foi acrescentada após os resultados para pedir citações. "Inclua citações ao documento de origem com o nome do documento e o link se o nome e o link do documento estiverem disponíveis."
Formatador de Contexto Func<IList<TextSearchProvider.TextSearchResult>, string> Delegado opcional para personalizar totalmente a formatação da lista de resultados. Se fornecido, ContextPrompt e CitationsPrompt são ignorados. null
RecentMessageMemoryLimit int O número de mensagens de conversação recentes (usuário e assistente) a serem mantidas na memória e incluídas ao construir a entrada de pesquisa para BeforeAIInvoke pesquisas. 0 (desativado)
RecentMessageRolesIncluded List<ChatRole> A lista de ChatRole tipos para filtrar mensagens recentes ao decidir quais mensagens recentes incluir ao construir a entrada de pesquisa. ChatRole.User

Tip

Consulte os exemplos do .NET para exemplos completos executáveis.

O Agent Framework fornece contratos nativos de armazenamento vetorial e create_vector_search_tool(). O ajudante transforma qualquer SupportsVectorSearch implementação numa ferramenta funcional, para que o modelo possa recuperar dados de aterramento antes de responder.

Criar uma ferramenta nativa de pesquisa vetorial

Primeiro, defina o seu modelo de armazenamento vetorial, crie uma coleção e carregue os seus registos. O exemplo seguinte usa InMemoryCollection com OpenAIEmbeddingClient, mas pode fornecer qualquer coleção nativa de Agent Framework que implemente SupportsVectorSearch. De seguida, expõe filtros opcionais de categorias e classificações ao modelo, mapeia cada resultado para texto de aterramento e instrui o agente a pesquisar antes de responder:

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)

A amostra completa define o Hotel modelo e carrega os registos de origem antes da configuração da coleção mostrada. Define OPENAI_API_KEY antes de o executares.

Personalizar o comportamento de pesquisa

Configure create_vector_search_tool() com as seguintes opções:

Option Purpose
name Define o nome da função exposto ao modelo. Use um nome único quando adicionar várias ferramentas de pesquisa.
description Explica quando e por que razão o modelo deve usar a ferramenta.
approval_mode Define a aprovação da ferramenta como always_require ou never_require.
search_type Selecionar vector ou keyword_hybrid pesquisar. A coleção deve suportar o modo selecionado.
top e skip Defina valores fixos de paginação ou use valores tipados Param fornecidos pelo modelo.
filter Aplica um portátil Filter ou FilterGroup. Um filtro pode conter valores tipados Param expostos no esquema da ferramenta.
result_mapper Converte cada um SearchResponse em texto ou multimodal Content para o modelo.

A ferramenta gerada inclui sempre uma query cadeia. Quaisquer Param valores no filtro, top, ou skip definições tornam-se argumentos validados adicionais da ferramenta. Use Literal e restrições numéricas para manter os valores fornecidos pelo modelo dentro do intervalo que a sua aplicação aceita.

Pode criar várias ferramentas para diferentes coleções ou modos de pesquisa. Dê a cada ferramenta uma distinção name para description que o modelo possa selecionar a fonte de conhecimento apropriada.

Escolha um armazenamento vetorial nativo

Implementações nativas de Python estão disponíveis para pesquisa em memória, Pesquisa de IA do Azure, PostgreSQL com pgvector, Qdrant e Redis. Os seus modos de pesquisa, ciclo de vida do pacote, comandos de instalação e limitações diferem. Consulte as integrações de armazenamento vetorial para selecionar e configurar uma implementação. Essa página também identifica bases de dados que atualmente possuem apenas um conector Kernel Semântico separado.

Observação

O suporte para esta funcionalidade do go está a chegar em breve. Consulte o repositório Agent Framework Go para o estado mais recente.

Gráfico RAG

Para o GraphRAG usando pesquisa enriquecida em atravessamento de grafos com consultas Cypher, veja o Provedor Neo4j GraphRAG.

Passos seguintes