Bagikan melalui


Pemilihan Fungsi Kontekstual dengan Agen

Penting

Fitur ini dalam tahap eksperimental. Fitur pada tahap ini sedang dalam pengembangan aktif dan dapat berubah secara signifikan sebelum maju ke tahap pratinjau atau kandidat rilis.

Gambaran Umum

Pemilihan Fungsi Kontekstual adalah kemampuan lanjutan dalam Kerangka Kerja Agen Kernel Semantik yang memungkinkan agen untuk memilih dan mengiklankan fungsi yang paling relevan secara dinamis hanya berdasarkan konteks percakapan saat ini. Alih-alih mengekspos semua fungsi yang tersedia ke model AI, fitur ini menggunakan Retrieval-Augmented Generation (RAG) untuk memfilter dan hanya menyajikan fungsi tersebut yang paling berkaitan dengan permintaan pengguna.

Pendekatan ini mengatasi tantangan pemilihan fungsi saat berhadapan dengan sejumlah besar fungsi yang tersedia, di mana model AI dapat berjuang untuk memilih fungsi yang sesuai, yang menyebabkan kebingungan dan performa suboptimal.

Peringatan

Saat menggunakan ContextualFunctionProvider, UseImmutableKernel pengaturan pada agen harus diatur ke true karena fitur memerlukan kloning kernel saat memanggil agen. Perhatikan bahwa pengaturan UseImmutableKernel ke true akan berarti bahwa setiap modifikasi data kernel yang dilakukan selama pemanggilan agen misalnya plugin, tidak akan dipertahankan setelah pemanggilan selesai.

Cara Kerja Pemilihan Fungsi Kontekstual

Ketika agen dikonfigurasi dengan pemilihan fungsi kontekstual, agen memanfaatkan penyimpanan vektor dan generator penyematan untuk secara semantik mencocokkan konteks percakapan saat ini (termasuk pesan sebelumnya dan input pengguna) dengan deskripsi dan nama fungsi yang tersedia. Fungsi yang paling relevan, hingga batas yang ditentukan, kemudian diiklankan ke model AI untuk pemanggilan.

Mekanisme ini sangat berguna untuk agen yang memiliki akses ke serangkaian plugin atau alat yang luas, memastikan bahwa hanya tindakan yang sesuai secara kontekstual yang dipertimbangkan di setiap langkah.

Contoh Penggunaan

Contoh berikut menunjukkan bagaimana agen dapat dikonfigurasi untuk menggunakan pemilihan fungsi kontekstual. Agen disiapkan untuk meringkas ulasan pelanggan, tetapi hanya fungsi yang paling relevan yang diiklankan ke model AI untuk setiap pemanggilan. Metode ini GetAvailableFunctions sengaja mencakup fungsi yang relevan dan tidak relevan untuk menyoroti manfaat pemilihan kontekstual.

// Create an embedding generator for function vectorization
var embeddingGenerator = new AzureOpenAIClient(new Uri("<endpoint>"), new ApiKeyCredential("<api-key>"))
    .GetEmbeddingClient("<deployment-name>")
    .AsIEmbeddingGenerator();

// Create kernel and register AzureOpenAI chat completion service
var kernel = Kernel.CreateBuilder()
    .AddAzureOpenAIChatCompletion("<deployment-name>", "<endpoint>", "<api-key>");
    .Build();

// Create a chat completion agent
ChatCompletionAgent agent = new()
{
    Name = "ReviewGuru",
    Instructions = "You are a friendly assistant that summarizes key points and sentiments from customer reviews. For each response, list available functions.",
    Kernel = kernel,
    Arguments = new(new PromptExecutionSettings { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(options: new FunctionChoiceBehaviorOptions { RetainArgumentTypes = true }) }),
    // This setting must be set to true when using the ContextualFunctionProvider
    UseImmutableKernel = true
};

// Create the agent thread and register the contextual function provider
ChatHistoryAgentThread agentThread = new();

agentThread.AIContextProviders.Add(
    new ContextualFunctionProvider(
        vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions() { EmbeddingGenerator = embeddingGenerator }),
        vectorDimensions: 1536,
        functions: AvailableFunctions(),
        maxNumberOfFunctions: 3, // Only the top 3 relevant functions are advertised
        loggerFactory: LoggerFactory
    )
);


// Invoke the agent
ChatMessageContent message = await agent.InvokeAsync("Get and summarize customer review.", agentThread).FirstAsync();
Console.WriteLine(message.Content);

// Output
/*
    Customer Reviews:
    -----------------
    1. John D. - ★★★★★
       Comment: Great product and fast shipping!
       Date: 2023-10-01

    Summary:
    --------
    The reviews indicate high customer satisfaction,
    highlighting product quality and shipping speed.

    Available functions:
    --------------------
    - Tools-GetCustomerReviews
    - Tools-Summarize
    - Tools-CollectSentiments
*/

IReadOnlyList<AIFunction> GetAvailableFunctions()
{
    // Only a few functions are directly related to the prompt; the majority are unrelated to demonstrate the benefits of contextual filtering.
    return new List<AIFunction>
    {
        // Relevant functions
        AIFunctionFactory.Create(() => "[ { 'reviewer': 'John D.', 'date': '2023-10-01', 'rating': 5, 'comment': 'Great product and fast shipping!' } ]", "GetCustomerReviews"),
        AIFunctionFactory.Create((string text) => "Summary generated based on input data: key points include customer satisfaction.", "Summarize"),
        AIFunctionFactory.Create((string text) => "The collected sentiment is mostly positive.", "CollectSentiments"),

        // Irrelevant functions
        AIFunctionFactory.Create(() => "Current weather is sunny.", "GetWeather"),
        AIFunctionFactory.Create(() => "Email sent.", "SendEmail"),
        AIFunctionFactory.Create(() => "The current stock price is $123.45.", "GetStockPrice"),
        AIFunctionFactory.Create(() => "The time is 12:00 PM.", "GetCurrentTime")
    };
}

Penyimpanan Vektor

Penyedia ini terutama dirancang untuk bekerja dengan penyimpanan vektor dalam memori, yang menawarkan kesederhanaan. Namun, jika jenis penyimpanan vektor lain digunakan, penting untuk dicatat bahwa tanggung jawab untuk menangani sinkronisasi dan konsistensi data jatuh pada aplikasi hosting.

Sinkronisasi diperlukan setiap kali daftar fungsi berubah atau ketika sumber penyematan fungsi dimodifikasi. Misalnya, jika agen awalnya memiliki tiga fungsi (f1, f2, f3) yang di-vektorisasi dan disimpan di penyimpanan vektor cloud, dan kemudian f3 dihapus dari daftar fungsi agen, penyimpanan vektor harus diperbarui untuk hanya mencerminkan fungsi saat ini yang dimiliki agen (f1 dan f2). Gagal memperbarui penyimpanan vektor dapat mengakibatkan fungsi yang tidak relevan dikembalikan sebagai hasil. Demikian pula, jika data yang digunakan untuk vektorisasi seperti nama fungsi, deskripsi, dll. perubahan, penyimpanan vektor harus dihapus menyeluruh dan diisi ulang dengan penyematan baru berdasarkan informasi yang diperbarui.

Mengelola sinkronisasi data di penyimpanan vektor eksternal atau terdistribusi dapat menjadi kompleks dan rentan terhadap kesalahan, terutama dalam aplikasi terdistribusi di mana layanan atau instans yang berbeda dapat beroperasi secara independen dan memerlukan akses yang konsisten ke data yang sama. Sebaliknya, menggunakan penyimpanan dalam memori menyederhanakan proses ini: ketika daftar fungsi atau sumber vektorisasi berubah, penyimpanan dalam memori dapat dengan mudah dibuat ulang dengan serangkaian fungsi baru dan penyematannya, memastikan konsistensi dengan upaya minimal.

Menentukan Fungsi

Penyedia fungsi kontekstual harus disediakan dengan daftar fungsi dari mana ia dapat memilih yang paling relevan berdasarkan konteks saat ini. Ini dicapai dengan memberikan daftar fungsi sebagai parameter functions dalam konstruktor ContextualFunctionProvider.

Selain fungsi, Anda juga harus menentukan jumlah maksimum fungsi yang relevan untuk dikembalikan menggunakan maxNumberOfFunctions parameter . Parameter ini menentukan berapa banyak fungsi yang akan dipertimbangkan penyedia saat memilih yang paling relevan untuk konteks saat ini. Angka yang ditentukan tidak dimaksudkan untuk tepat; sebaliknya, ini berfungsi sebagai batas atas yang tergantung pada skenario tertentu.

Mengatur nilai ini terlalu rendah dapat mencegah agen mengakses semua fungsi yang diperlukan untuk skenario, yang berpotensi menyebabkan kegagalan skenario. Sebaliknya, mengaturnya terlalu tinggi dapat membebani agen dengan terlalu banyak fungsi, yang dapat mengakibatkan halusinasi, konsumsi token input yang berlebihan, dan performansi suboptimal.

// Create the provider with a list of functions and a maximum number of functions to return
ContextualFunctionProvider provider = new (
    vectorStore: new InMemoryVectorStore(new InMemoryVectorStoreOptions { EmbeddingGenerator = embeddingGenerator }),
    vectorDimensions: 1536,
    functions: [AIFunctionFactory.Create((string text) => $"Echo: {text}", "Echo"), <other functions>]
    maxNumberOfFunctions: 3 // Only the top 3 relevant functions are advertised
);

Opsi Penyedia Fungsi Kontekstual

Penyedia dapat dikonfigurasi menggunakan ContextualFunctionProviderOptions kelas , yang memungkinkan Anda untuk menyesuaikan berbagai aspek tentang cara penyedia beroperasi:

// Create options for the contextual function provider
ContextualFunctionProviderOptions options = new ()
{
    ...
};

// Create the provider with options
ContextualFunctionProvider provider = new (
    ...
    options: options // Pass the options
);

Ukuran Konteks

Ukuran konteks menentukan berapa banyak pesan terbaru dari pemanggilan agen sebelumnya yang disertakan saat membentuk konteks untuk pemanggilan baru. Penyedia mengumpulkan semua pesan dari pemanggilan sebelumnya, hingga angka yang ditentukan, dan menambahkannya ke pesan baru untuk membentuk konteks.

Menggunakan pesan terbaru bersama dengan pesan baru sangat berguna untuk tugas yang memerlukan informasi dari langkah-langkah sebelumnya dalam percakapan. Misalnya, jika agen menyediakan sumber daya dalam satu pemanggilan dan menyebarkannya di pemanggilan berikutnya, langkah penyebaran dapat mengakses detail dari langkah provisi untuk mendapatkan informasi sumber daya yang disediakan untuk penyebaran.

Nilai default untuk jumlah pesan terbaru dalam konteks adalah 2, tetapi ini dapat dikonfigurasi sesuai kebutuhan dengan menentukan NumberOfRecentMessagesInContext properti di ContextualFunctionProviderOptions:

ContextualFunctionProviderOptions options = new ()
{
    NumberOfRecentMessagesInContext = 1 // Only the last message will be included in the context
};

Nilai Sumber Penyematan Konteks

Untuk melakukan pemilihan fungsi kontekstual, penyedia perlu mem-vektorisasi konteks saat ini sehingga dapat dibandingkan dengan fungsi yang tersedia di penyimpanan vektor. Secara default, penyedia membuat penyematan konteks ini dengan menggabungkan semua pesan terbaru yang tidak kosong dan baru ke dalam satu string, yang kemudian di-vektorisasi dan digunakan untuk mencari fungsi yang relevan.

Dalam beberapa skenario, Anda mungkin ingin menyesuaikan perilaku ini untuk:

  • Fokus pada jenis pesan tertentu (misalnya, hanya pesan pengguna)
  • Mengecualikan informasi tertentu dari konteks
  • Pra-proses atau ringkas konteks sebelum vektorisasi (misalnya, terapkan penulisan ulang arahan)

Untuk melakukan ini, Anda dapat menetapkan delegasi kustom ke ContextEmbeddingValueProvider. Delegasi ini menerima pesan terbaru dan baru, dan mengembalikan nilai string yang akan digunakan sebagai sumber untuk penyematan konteks:

ContextualFunctionProviderOptions options = new()
{
    ContextEmbeddingValueProvider = async (recentMessages, newMessages, cancellationToken) =>
    {
        // Example: Only include user messages in the embedding
        var allUserMessages = recentMessages.Concat(newMessages)
            .Where(m => m.Role == "user")
            .Select(m => m.Content)
            .Where(content => !string.IsNullOrWhiteSpace(content));
        return string.Join("\n", allUserMessages);
    }
};

Menyesuaikan penyematan konteks dapat meningkatkan relevansi pemilihan fungsi, terutama dalam skenario agen yang kompleks atau sangat khusus.

Nilai Penyematan Sumber Fungsi

Penyedia perlu mem-vektorisasi setiap fungsi yang tersedia untuk membandingkannya dengan konteks dan memilih yang paling relevan. Secara default, penyedia membuat penyematan fungsi dengan menggabungkan nama dan deskripsi fungsi ke dalam satu string, yang kemudian di-vektorisasi dan disimpan di penyimpanan vektor.

Anda dapat menyesuaikan perilaku ini menggunakan properti EmbeddingValueProviderContextualFunctionProviderOptions. Properti ini memungkinkan Anda menentukan panggilan balik yang menerima fungsi dan token pembatalan, dan mengembalikan string yang akan digunakan sebagai sumber untuk penyematan fungsi. Ini berguna jika Anda ingin:

  • Menambahkan metadata fungsi tambahan ke sumber penyematan
  • Pra-pemrosesan, filter, atau format ulang informasi fungsi sebelum vektorisasi
ContextualFunctionProviderOptions options = new()
{
    EmbeddingValueProvider = async (function, cancellationToken) =>
    {
        // Example: Use only the function name for embedding
        return function.Name;
    }
};

Menyesuaikan nilai sumber penyematan fungsi dapat meningkatkan akurasi pemilihan fungsi, terutama ketika fungsi Anda memiliki metadata yang kaya dan relevan konteks atau ketika Anda ingin memfokuskan pencarian pada aspek tertentu dari setiap fungsi.

Langkah selanjutnya

Menjelajahi sampel pemilihan fungsi kontekstual

Segera datang

Informasi lebih lanjut akan segera hadir.

Segera datang

Informasi lebih lanjut akan segera hadir.