Bagikan melalui


Menggunakan plugin untuk Pengambilan Augmented Generation (RAG)

Seringkali, agen AI Anda harus mengambil data dari sumber eksternal untuk menghasilkan respons beralasan. Tanpa konteks tambahan ini, agen AI Anda dapat berhalusinasi atau memberikan informasi yang salah. Untuk mengatasi hal ini, Anda dapat menggunakan plugin untuk mengambil data dari sumber eksternal.

Saat mempertimbangkan plugin untuk Retrieval Augmented Generation (RAG), Anda harus mengajukan dua pertanyaan pada diri sendiri:

  1. Bagaimana Anda (atau agen AI Anda) "mencari" data yang diperlukan? Apakah Anda memerlukan pencarian semantik atau pencarian klasik?
  2. Apakah Anda sudah mengetahui data yang dibutuhkan agen AI sebelumnya (data yang diambil sebelumnya), atau apakah agen AI perlu mengambil data secara dinamis?
  3. Bagaimana Anda akan menjaga data Anda tetap aman dan mencegah oversharing informasi sensitif?

Saat mengembangkan plugin untuk Retrieval Augmented Generation (RAG), Anda dapat menggunakan dua jenis pencarian: pencarian semantik dan pencarian klasik.

Pencarian semantik menggunakan database vektor untuk memahami dan mengambil informasi berdasarkan arti dan konteks kueri daripada hanya mencocokkan kata kunci. Metode ini memungkinkan mesin pencari untuk memahami nuansa bahasa, seperti sinonim, konsep terkait, dan niat keseluruhan di balik kueri.

Pencarian semantik unggul di lingkungan di mana kueri pengguna kompleks, terbuka, atau memerlukan pemahaman yang lebih mendalam tentang konten. Misalnya, mencari "smartphone terbaik untuk fotografi" akan menghasilkan hasil yang mempertimbangkan konteks fitur fotografi di smartphone, daripada hanya mencocokkan kata "terbaik," "smartphone," dan "fotografi."

Saat menyediakan LLM dengan fungsi pencarian semantik, Anda biasanya hanya perlu menentukan fungsi dengan satu kueri pencarian. LLM kemudian akan menggunakan fungsi ini untuk mengambil informasi yang diperlukan. Di bawah ini adalah contoh fungsi pencarian semantik yang menggunakan Pencarian Azure AI untuk menemukan dokumen yang mirip dengan kueri tertentu.

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

Pencarian klasik, juga dikenal sebagai pencarian berbasis atribut atau berbasis kriteria, bergantung pada pemfilteran dan pencocokan istilah atau nilai yang tepat dalam himpunan data. Ini sangat efektif untuk kueri database, pencarian inventaris, dan situasi apa pun di mana pemfilteran berdasarkan atribut tertentu diperlukan.

Misalnya, jika pengguna ingin menemukan semua pesanan yang ditempatkan oleh ID pelanggan tertentu atau mengambil produk dalam rentang harga dan kategori tertentu, pencarian klasik memberikan hasil yang tepat dan dapat diandalkan. Namun, pencarian klasik dibatasi oleh ketidakmampuannya untuk memahami konteks atau variasi dalam bahasa.

Tip

Dalam kebanyakan kasus, layanan Anda yang ada sudah mendukung pencarian klasik. Sebelum menerapkan pencarian semantik, pertimbangkan apakah layanan Anda yang ada dapat memberikan konteks yang diperlukan untuk agen AI Anda.

Misalnya, plugin yang mengambil informasi pelanggan dari sistem CRM menggunakan pencarian klasik. Di sini, AI hanya perlu memanggil GetCustomerInfoAsync fungsi dengan ID pelanggan untuk mengambil informasi yang diperlukan.

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

Mencapai fungsionalitas pencarian yang sama dengan pencarian semantik kemungkinan tidak mungkin atau tidak praktis karena sifat kueri semantik yang tidak deterministik.

Kapan Menggunakan Masing-masing

Memilih antara pencarian semantik dan klasik tergantung pada sifat kueri. Ini sangat ideal untuk lingkungan konten-berat seperti basis pengetahuan dan dukungan pelanggan di mana pengguna mungkin mengajukan pertanyaan atau mencari produk menggunakan bahasa alami. Pencarian klasik, di sisi lain, harus digunakan ketika presisi dan kecocokan yang tepat penting.

Dalam beberapa skenario, Anda mungkin perlu menggabungkan kedua pendekatan untuk memberikan kemampuan pencarian yang komprehensif. Misalnya, chatbot yang membantu pelanggan di toko e-niaga mungkin menggunakan pencarian semantik untuk memahami kueri pengguna dan pencarian klasik untuk memfilter produk berdasarkan atribut tertentu seperti harga, merek, atau ketersediaan.

Di bawah ini adalah contoh plugin yang menggabungkan pencarian semantik dan klasik untuk mengambil informasi produk dari database e-niaga.

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

Pengambilan data dinamis vs yang telah diambil sebelumnya

Saat mengembangkan plugin untuk Retrieval Augmented Generation (RAG), Anda juga harus mempertimbangkan apakah proses pengambilan data statis atau dinamis. Ini memungkinkan Anda untuk mengoptimalkan performa agen AI Anda dengan mengambil data hanya jika diperlukan.

Pengambilan data dinamis

Dalam kebanyakan kasus, kueri pengguna akan menentukan data yang perlu diambil agen AI. Misalnya, pengguna mungkin meminta perbedaan antara dua produk yang berbeda. Agen AI kemudian perlu mengambil informasi produk secara dinamis dari database atau API untuk menghasilkan respons menggunakan panggilan fungsi. Tidak praktis untuk mengambil semua informasi produk yang mungkin sebelumnya dan memberikannya kepada agen AI.

Di bawah ini adalah contoh obrolan bolak-balik antara pengguna dan agen AI di mana pengambilan data dinamis diperlukan.

Peran Pesan
🔵Pengguna Dapatkah Anda ceritakan tentang kasur terbaik?
🔴Asisten (panggilan fungsi) Products.Search("mattresses")
🟢Alat [{"id": 25323, "name": "Cloud Nine"},{"id": 63633, "name": "Best Sleep"}]
🔴Asisten Yakin! Kami memiliki Cloud Nine dan Tidur Terbaik
🔵Pengguna Apa perbedaan di antara keduanya?
🔴Asisten (panggilan fungsi) Products.GetDetails(25323) Products.GetDetails(63633)
🟢Alat { "id": 25323, "name": "Cloud Nine", "price": 1000, "material": "Memory foam" }
🟢Alat { "id": 63633, "name": "Best Sleep", "price": 1200, "material": "Latex" }
🔴Asisten Cloud Nine terbuat dari busa memori dan harganya $1000. Tidur Terbaik terbuat dari lateks dan biaya $ 1200.

Pengambilan data yang diambil sebelumnya

Pengambilan data statis melibatkan pengambilan data dari sumber eksternal dan selalu memberikannya kepada agen AI. Ini berguna ketika data diperlukan untuk setiap permintaan atau ketika data relatif stabil dan tidak sering berubah.

Misalnya, agen yang selalu menjawab pertanyaan tentang cuaca lokal. Dengan asumsi Anda memiliki WeatherPlugin, Anda dapat mengambil data cuaca sebelumnya dari API cuaca dan menyediakannya dalam riwayat obrolan. Ini memungkinkan agen untuk menghasilkan respons tentang cuaca tanpa membuang-buang waktu meminta data dari API.

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

Menjaga keamanan data

Saat mengambil data dari sumber eksternal, penting untuk memastikan bahwa data aman dan informasi sensitif tersebut tidak terekspos. Untuk mencegah pembagian informasi sensitif secara berlebihan, Anda dapat menggunakan strategi berikut:

Strategi Deskripsi
Menggunakan token autentikasi pengguna Hindari membuat perwakilan layanan yang digunakan oleh agen AI untuk mengambil informasi bagi pengguna. Melakukannya menyulitkan untuk memverifikasi bahwa pengguna memiliki akses ke informasi yang diambil.
Hindari membuat ulang layanan pencarian Sebelum membuat layanan pencarian baru dengan DB vektor, periksa apakah sudah ada untuk layanan yang memiliki data yang diperlukan. Dengan menggunakan kembali layanan yang ada, Anda dapat menghindari duplikasi konten sensitif, memanfaatkan kontrol akses yang ada, dan menggunakan mekanisme pemfilteran yang ada yang hanya mengembalikan data yang dapat diakses pengguna.
Simpan referensi dalam DB vektor alih-alih konten Alih-alih menduplikasi konten sensitif ke DB vektor, Anda dapat menyimpan referensi ke data aktual. Agar pengguna dapat mengakses informasi ini, token autentikasi mereka harus terlebih dahulu digunakan untuk mengambil data nyata.

Langkah berikutnya

Sekarang setelah Anda sekarang cara membumikan agen AI Anda dengan data dari sumber eksternal, Anda sekarang dapat mempelajari cara menggunakan agen AI untuk mengotomatiskan proses bisnis. Untuk mempelajari selengkapnya, lihat menggunakan fungsi otomatisasi tugas.