Freigeben über


Verwenden von Plug-Ins für die erweiterte Generation (Retrieval Augmented Generation, RAG)

Häufig müssen Ihre KI-Agents Daten aus externen Quellen abrufen, um geerdete Antworten zu generieren. Ohne diesen zusätzlichen Kontext können Ihre KI-Agents falsche Informationen halluzieren oder bereitstellen. Um dies zu beheben, können Sie Plug-Ins verwenden, um Daten aus externen Quellen abzurufen.

Wenn Sie Plug-Ins für Retrieval Augmented Generation (RAG) in Betracht ziehen, sollten Sie sich zwei Fragen stellen:

  1. Wie werden Sie (oder Ihr KI-Agent) nach den erforderlichen Daten suchen? Benötigen Sie semantische Suche oder klassische Suche?
  2. Kennen Sie bereits die Daten, die der KI-Agent vorab benötigt (vorab abgerufene Daten), oder muss der KI-Agent die Daten dynamisch abrufen?
  3. Wie behalten Sie Ihre Daten sicher und verhindern, dass vertrauliche Informationen freigegeben werden?

Bei der Entwicklung von Plug-Ins für die "Retrieval Augmented Generation" (RAG) können Sie zwei Suchtypen verwenden: semantische Suche und klassische Suche.

Die semantische Suche verwendet Vektordatenbanken, um Informationen basierend auf der Bedeutung und dem Kontext der Abfrage zu verstehen und abzurufen, anstatt nur übereinstimmende Schlüsselwörter. Diese Methode ermöglicht es der Suchmaschine, die Nuancen der Sprache zu erfassen, z. B. Synonyme, verwandte Konzepte und die allgemeine Absicht hinter einer Abfrage.

Die semantische Suche excels in Umgebungen, in denen Benutzerabfragen komplex, geöffnet sind oder ein tieferes Verständnis des Inhalts erfordern. Beispielsweise würde die Suche nach "besten Smartphones für Fotografie" Ergebnisse liefern, die den Kontext von Fotografiefeatures in Smartphones berücksichtigen, anstatt nur die Wörter "am besten", "Smartphones" und "Fotografie" zuzuordnen.

Wenn Sie eine LLM-Funktion mit einer semantischen Suchfunktion bereitstellen, müssen Sie in der Regel nur eine Funktion mit einer einzelnen Suchabfrage definieren. Die LLM verwendet dann diese Funktion, um die erforderlichen Informationen abzurufen. Nachfolgend finden Sie ein Beispiel für eine semantische Suchfunktion, die Azure AI Search verwendet, um Dokumente ähnlich einer bestimmten Abfrage zu finden.

using System.ComponentModel;
using System.Text.Json.Serialization;
using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Models;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.Embeddings;

public class InternalDocumentsPlugin
{
    private readonly ITextEmbeddingGenerationService _textEmbeddingGenerationService;
    private readonly SearchIndexClient _indexClient;

    public AzureAISearchPlugin(ITextEmbeddingGenerationService textEmbeddingGenerationService, SearchIndexClient indexClient)
    {
        _textEmbeddingGenerationService = textEmbeddingGenerationService;
        _indexClient = indexClient;
    }

    [KernelFunction("Search")]
    [Description("Search for a document similar to the given query.")]
    public async Task<string> SearchAsync(string query)
    {
        // Convert string query to vector
        ReadOnlyMemory<float> embedding = await _textEmbeddingGenerationService.GenerateEmbeddingAsync(query);

        // Get client for search operations
        SearchClient searchClient = _indexClient.GetSearchClient("default-collection");

        // Configure request parameters
        VectorizedQuery vectorQuery = new(embedding);
        vectorQuery.Fields.Add("vector");

        SearchOptions searchOptions = new() { VectorSearch = new() { Queries = { vectorQuery } } };

        // Perform search request
        Response<SearchResults<IndexSchema>> response = await searchClient.SearchAsync<IndexSchema>(searchOptions);

        // Collect search results
        await foreach (SearchResult<IndexSchema> result in response.Value.GetResultsAsync())
        {
            return result.Document.Chunk; // Return text from first result
        }

        return string.Empty;
    }

    private sealed class IndexSchema
    {
        [JsonPropertyName("chunk")]
        public string Chunk { get; set; }

        [JsonPropertyName("vector")]
        public ReadOnlyMemory<float> Vector { get; set; }
    }
}

Die klassische Suche, auch als attributbasierte oder kriterienbasierte Suche bezeichnet, basiert auf dem Filtern und Abgleichen exakter Ausdrücke oder Werte innerhalb eines Datasets. Es ist besonders effektiv für Datenbankabfragen, Bestandssuchen und jede Situation, in der das Filtern nach bestimmten Attributen erforderlich ist.

Wenn ein Benutzer beispielsweise alle Bestellungen finden möchte, die von einer bestimmten Kunden-ID getätigt oder Produkte innerhalb eines bestimmten Preisbereichs und einer bestimmten Kategorie abgerufen werden, bietet die klassische Suche präzise und zuverlässige Ergebnisse. Die klassische Suche ist jedoch durch ihre Unfähigkeit eingeschränkt, Kontext oder Variationen in der Sprache zu verstehen.

Tipp

In den meisten Fällen unterstützen Ihre vorhandenen Dienste bereits die klassische Suche. Überlegen Sie vor der Implementierung einer semantischen Suche, ob Ihre vorhandenen Dienste den erforderlichen Kontext für Ihre KI-Agents bereitstellen können.

Nehmen Sie beispielsweise ein Plug-In, das Kundeninformationen aus einem CRM-System mithilfe der klassischen Suche abruft. Hier muss die KI einfach die GetCustomerInfoAsync Funktion mit einer Kunden-ID aufrufen, um die erforderlichen Informationen abzurufen.

using System.ComponentModel;
using Microsoft.SemanticKernel;

public class CRMPlugin
{
    private readonly CRMService _crmService;

    public CRMPlugin(CRMService crmService)
    {
        _crmService = crmService;
    }

    [KernelFunction("GetCustomerInfo")]
    [Description("Retrieve customer information based on the given customer ID.")]
    public async Task<Customer> GetCustomerInfoAsync(string customerId)
    {
        return await _crmService.GetCustomerInfoAsync(customerId);
    }
}

Das Erreichen derselben Suchfunktion mit der semantischen Suche wäre aufgrund der nicht deterministischen Natur semantischer Abfragen wahrscheinlich unmöglich oder unpraktisch.

Wann verwendet werden soll

Die Auswahl zwischen semantischer und klassischer Suche hängt von der Art der Abfrage ab. Es eignet sich ideal für umgebungen mit hoher Inhaltsbelastung wie Wissensdatenbank s und Kundensupport, bei denen Benutzer Fragen stellen oder nach Produkten suchen können, die natürliche Sprache verwenden. Die klassische Suche sollte dagegen eingesetzt werden, wenn Präzision und genaue Übereinstimmungen wichtig sind.

In einigen Szenarien müssen Sie möglicherweise beide Ansätze kombinieren, um umfassende Suchfunktionen bereitzustellen. Beispielsweise kann ein Chatbot, der Kunden in einem E-Commerce-Store unterstützt, die semantische Suche verwenden, um Benutzerabfragen und die klassische Suche zu verstehen, um Produkte basierend auf bestimmten Attributen wie Preis, Marke oder Verfügbarkeit zu filtern.

Nachfolgend finden Sie ein Beispiel für ein Plug-In, das semantische und klassische Suche kombiniert, um Produktinformationen aus einer E-Commerce-Datenbank abzurufen.

using System.ComponentModel;
using Microsoft.SemanticKernel;

public class ECommercePlugin
{
    [KernelFunction("search_products")]
    [Description("Search for products based on the given query.")]
    public async Task<IEnumerable<Product>> SearchProductsAsync(string query, ProductCategories category = null, decimal? minPrice = null, decimal? maxPrice = null)
    {
        // Perform semantic and classic search with the given parameters
    }
}

Dynamischer datenabruf im Vergleich zum vorab abgerufenen Datenabruf

Bei der Entwicklung von Plug-Ins für die Augmented Generation (Retrieval Augmented Generation, RAG) müssen Sie auch überlegen, ob der Datenempfangsprozess statisch oder dynamisch ist. Auf diese Weise können Sie die Leistung Ihrer KI-Agents optimieren, indem Sie Daten nur bei Bedarf abrufen.

Dynamischer Datenabruf

In den meisten Fällen bestimmt die Benutzerabfrage die Daten, die der KI-Agent abrufen muss. Beispielsweise kann ein Benutzer nach dem Unterschied zwischen zwei verschiedenen Produkten fragen. Der KI-Agent muss dann die Produktinformationen dynamisch aus einer Datenbank oder API abrufen, um eine Antwort mithilfe von Funktionsaufrufen zu generieren. Es wäre unpraktisch, alle möglichen Produktinformationen vorab abzurufen und dem KI-Agenten zu geben.

Nachfolgend finden Sie ein Beispiel für einen Back-and-Forth-Chat zwischen einem Benutzer und einem KI-Agent, bei dem ein dynamischer Datenabruf erforderlich ist.

Role `Message`
🔵Benutzer Können Sie mir über die besten Matratzen erzählen?
🔴Assistent (Funktionsaufruf) Products.Search("mattresses")
🟢Tool [{"id": 25323, "name": "Cloud Nine"},{"id": 63633, "name": "Best Sleep"}]
🔴Assistent Ja, natürlich. Wir verfügen sowohl über Cloud Nine als auch über den besten Schlaf
🔵Benutzer Worin besteht der Unterschied?
🔴Assistent (Funktionsaufruf) Products.GetDetails(25323) Products.GetDetails(63633)
🟢Tool { "id": 25323, "name": "Cloud Nine", "price": 1000, "material": "Memory foam" }
🟢Tool { "id": 63633, "name": "Best Sleep", "price": 1200, "material": "Latex" }
🔴Assistent Cloud Nine besteht aus Speicherschaum und kostet $ 1000. Best Sleep ist ausLatex und kostet $ 1200.

Vorab abgerufene Datenabrufe

Statische Datenabrufe beinhalten das Abrufen von Daten aus externen Quellen und die Bereitstellung immer für den KI-Agent. Dies ist nützlich, wenn die Daten für jede Anforderung erforderlich sind oder wenn die Daten relativ stabil sind und sich nicht häufig ändern.

Nehmen Sie beispielsweise einen Agenten, der immer Fragen zum lokalen Wetter beantwortet. Vorausgesetzt, Sie können WeatherPluginWetterdaten aus einer Wetter-API vorab abrufen und im Chatverlauf bereitstellen. Auf diese Weise kann der Agent Antworten über das Wetter generieren, ohne zeitlos die Daten aus der API anzufordern.

using System.Text.Json;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;

IKernelBuilder builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(deploymentName, endpoint, apiKey);
builder.Plugins.AddFromType<WeatherPlugin>();
Kernel kernel = builder.Build();

// Get the weather
var weather = await kernel.Plugins.GetFunction("WeatherPlugin", "get_weather").InvokeAsync(kernel);

// Initialize the chat history with the weather
ChatHistory chatHistory = new ChatHistory("The weather is:\n" + JsonSerializer.Serialize(weather));

// Simulate a user message
chatHistory.AddUserMessage("What is the weather like today?");

// Get the answer from the AI agent
IChatCompletionService chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
var result = await chatCompletionService.GetChatMessageContentAsync(chatHistory);

Schützen von Daten

Beim Abrufen von Daten aus externen Quellen ist es wichtig sicherzustellen, dass die Daten sicher sind und dass vertrauliche Informationen nicht verfügbar gemacht werden. Um die Weitergabe vertraulicher Informationen zu verhindern, können Sie die folgenden Strategien verwenden:

Strategie Beschreibung
Verwenden des Authentifizierungstokens des Benutzers Vermeiden Sie das Erstellen von Dienstprinzipalen, die vom KI-Agent zum Abrufen von Informationen für Benutzer verwendet werden. Dadurch wird es schwierig zu überprüfen, ob ein Benutzer Zugriff auf die abgerufenen Informationen hat.
Vermeiden der Neuerstellen von Suchdiensten Bevor Sie einen neuen Suchdienst mit einem Vektor-DB erstellen, überprüfen Sie, ob bereits ein Suchdienst mit den erforderlichen Daten vorhanden ist. Indem Sie vorhandene Dienste wiederverwenden, können Sie vermeiden, vertrauliche Inhalte zu duplizieren, vorhandene Zugriffssteuerungen nutzen und vorhandene Filtermechanismen verwenden, auf die nur Daten zurückgegeben werden, auf die der Benutzer zugriff hat.
Speicherreferenz in Vektor-DBs anstelle von Inhalten Anstatt vertrauliche Inhalte auf Vektor-DBs zu duplizieren, können Sie Verweise auf die tatsächlichen Daten speichern. Damit ein Benutzer auf diese Informationen zugreifen kann, muss sein Authentifizierungstoken zuerst verwendet werden, um die tatsächlichen Daten abzurufen.

Nächste Schritte

Nachdem Sie nun wissen, wie Sie Ihre KI-Agents mit Daten aus externen Quellen verknüpfen, können Sie jetzt erfahren, wie Sie KI-Agents zum Automatisieren von Geschäftsprozessen verwenden. Weitere Informationen finden Sie unter Verwendung von Aufgabenautomatisierungsfunktionen.