ТРЯПКА

Microsoft Agent Framework поддерживает извлечение дополненного поколения (RAG) через поставщиков контекстов, которые добавляют полученное содержимое перед вызовом модели и средствами поиска, которые позволяют модели получать данные о основе по запросу.

Общие сведения о шаблонах бесед и сеансов вместе с получением см. в разделе "Беседы и память". Сведения о настройке для конкретной службы см. в разделе Поиск с использованием ИИ Azure, Microsoft Foundry и Neo4j.

Использование TextSearchProvider

Класс TextSearchProvider является внестандартной реализацией поставщика контекста RAG. Она поддерживает различные режимы работы, например поиск каждого агента, выполняемого с помощью журнала чата, или средств рекламной функции для выполнения поиска.

Его можно легко подключить к параметру ChatClientAgentAIContextProviders .

// 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 или веб-поисковой системы.

Tip

Дополнительные сведения об использовании векторного хранилища для результатов поиска см. в разделе интеграции хранилища векторов .

Ниже приведен пример функции поиска макета, которая возвращает предварительно определенные результаты на основе запроса. 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 Описание предоставленного средства поиска при работе в режиме по запросу. "Позволяет искать дополнительную информацию, чтобы помочь ответить на вопрос пользователя".
ContextPrompt string Запрос контекста, префиксированного в результаты. "## Дополнительный контекст\nУчитывайте следующие сведения из исходных документов при реагировании на пользователя:"
СсылкиPrompt string Инструкция, добавленная после результатов для запроса ссылок. "Включите ссылки на исходный документ с именем документа и ссылкой, если имя документа и ссылка доступны".
ContextFormatter Func<IList<TextSearchProvider.TextSearchResult>, string> Необязательный делегат для полной настройки форматирования списка результатов. Если указано, ContextPrompt и CitationsPrompt игнорируются. null
RecentMessageMemoryLimit int Количество последних сообщений бесед (как пользователя, так и помощника), которые хранятся в памяти и включаются при создании входных данных поиска для BeforeAIInvoke поиска. 0 (отключено)
RecentMessageRolesIncluded List<ChatRole> Список типов для фильтрации последних ChatRole сообщений при принятии решения о том, какие последние сообщения следует включить при создании входных данных поиска. ChatRole.User

Tip

Полные примеры запуска см. в примерах .NET .

Agent Framework предоставляет собственные контракты векторного хранилища и create_vector_search_tool(). Вспомогательный инструмент преобразует любую SupportsVectorSearch реализацию в средство функции, чтобы модель может получить данные о заземления перед ответами.

Создание собственного средства поиска векторов

Сначала определите модель векторного хранилища, создайте коллекцию и загрузите ее записи. В следующем примере используется InMemoryCollection , OpenAIEmbeddingClientно можно указать любую собственную коллекцию 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_requirenever_require.
search_type Выбирает или keyword_hybrid выполняет vector поиск. Коллекция должна поддерживать выбранный режим.
top и skip. Задайте фиксированные значения разбиения по страницам или используйте типизированные Param значения, предоставляемые моделью.
filter Применяет переносимую Filter или FilterGroup. Фильтр может содержать типизированные Param значения, предоставляемые в схеме средства.
result_mapper Преобразует каждый из них SearchResponse в текст или мультимодальный Content для модели.

Созданное средство всегда включает query строку. Все Param значения в фильтре topили skip параметры становятся дополнительными проверенными аргументами средства. Используйте Literal и числовые ограничения, чтобы сохранить предоставленные моделью значения в диапазоне, который принимает приложение.

Вы можете создать несколько инструментов для различных коллекций или режимов поиска. Присвойте каждому инструменту отдельный namedescription и поэтому модель может выбрать соответствующий источник знаний.

Выбор собственного векторного хранилища

Собственные реализации Python доступны для поиска в памяти, Поиск с использованием ИИ Azure, PostgreSQL с pgvector, Qdrant и Redis. Их режимы поиска, жизненный цикл пакета, команды установки и ограничения отличаются. Чтобы выбрать и настроить реализацию, см. сведения об интеграции с хранилищем векторов . Эта страница также определяет базы данных, которые в настоящее время имеют только отдельный соединитель Semantic Kernel.

Замечание

Поддержка Go для этой функции скоро появится. Сведения о последнем состоянии см. в репозитории Agent Framework Go .

Граф RAG

Сведения о GraphRAG с помощью обхода графа с запросами Cypher см. в разделе "Поставщик GraphRAG Neo4j".

Дальнейшие действия