Cara menyesuaikan bagaimana pekerja diberi peringkat untuk mode distribusi pekerja terbaik

Penting

Fungsionalitas yang dijelaskan pada bagian ini saat ini dalam pratinjau pribadi. Pratinjau pribadi mencakup akses ke SDK dan dokumentasi untuk tujuan pengujian yang belum tersedia untuk umum. Daftar untuk menjadi pengadopsi awal dengan mengisi formulir untuk akses pratinjau ke Azure Communication Services.

best-worker Mode distribusi memilih pekerja yang paling mampu menangani pekerjaan terlebih dahulu. Logika untuk memberi peringkat Pekerja dapat disesuaikan, dengan ekspresi atau fungsi Azure untuk membandingkan dua pekerja. Contoh berikut menunjukkan cara mengkustomisasi logika ini dengan Azure Function Anda sendiri.

Skenario: Aturan penilaian kustom dalam mode distribusi pekerja terbaik

Kami ingin mendistribusikan penawaran di antara pekerja mereka yang terkait dengan antrean. Para pekerja akan diberikan skor berdasarkan label dan set keterampilan mereka. Pekerja dengan skor tertinggi harus mendapatkan penawaran pertama (Mode Distribusi BestWorker).

Diagram showing Best Worker Distribution Mode problem statement

Situasi

  • Pekerjaan telah dibuat dan diklasifikasikan.
    • Job memiliki label berikut yang terkait dengannya
      • ["CommunicationType"] = "Obrolan"
      • ["IssueType"] = "XboxSupport"
      • ["Bahasa"] = "en"
      • ["HighPriority"] = true
      • ["SubIssueType"] = "ConsoleMalfunction"
      • ["ConsoleType"] = "XBOX_SERIES_X"
      • ["Model"] = "XBOX_SERIES_X_1TB"
    • Job memiliki WorkerSelectors berikut yang terkait dengannya
      • ["Inggris"] > = 7
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
  • Pekerjaan saat ini dalam status 'Antrean'; diantrekan dalam Antrean Dukungan Perangkat Keras Xbox yang menunggu untuk dicocokkan dengan pekerja.
  • Beberapa pekerja tersedia secara bersamaan.
    • Pekerja 1 telah dibuat dengan label berikut
      • ["HighPrioritySupport"] = true
      • ["HardwareSupport"] = true
      • ["Support_XBOX_SERIES_X"] = true
      • ["English"] = 10
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
    • Pekerja 2 telah dibuat dengan label berikut
      • ["HighPrioritySupport"] = true
      • ["HardwareSupport"] = true
      • ["Support_XBOX_SERIES_X"] = true
      • ["Support_XBOX_SERIES_S"] = true
      • ["Bahasa Inggris"] = 8
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true
    • Pekerja 3 telah dibuat dengan label berikut
      • ["HighPrioritySupport"] = false
      • ["HardwareSupport"] = true
      • ["Support_XBOX"] = true
      • ["English"] = 7
      • ["ChatSupport"] = true
      • ["XboxSupport"] = true

Harapan

Kami ingin perilaku berikut saat menilai pekerja untuk memilih pekerja mana yang mendapatkan penawaran pertama.

Decision flow diagram for scoring worker

Alur keputusan (seperti yang ditunjukkan di atas) adalah sebagai berikut:

  • Jika pekerjaan BUKAN HighPriority:

    • Pekerja dengan label: ["Support_XBOX"] = true; mendapatkan skor 100
    • Jika tidak, dapatkan skor 1
  • Jika pekerjaan adalah HighPriority:

    • Pekerja dengan label: ["HighPrioritySupport"] = false; dapatkan skor 1
    • Jika tidak, jika ["HighPrioritySupport"] = true:
      • Apakah Worker mengkhususkan diri dalam jenis konsol -> Apakah pekerja memiliki label: ["Support_<jobLabels.ConsoleType>"] = true? Jika true, pekerja mendapatkan skor 200
      • Jika tidak, dapatkan skor 100

Membuat fungsi Azure

Sebelum melanjutkan lebih jauh dalam prosesnya, mari kita terlebih dahulu menentukan fungsi Azure yang menilai pekerja.

Catatan

Fungsi Azure berikut menggunakan JavaScript. Untuk informasi selengkapnya, silakan merujuk ke Mulai Cepat: Membuat fungsi JavaScript di Azure menggunakan Visual Studio Code

Contoh input untuk Pekerja 1

{
  "job": {
    "CommunicationType": "Chat",
    "IssueType": "XboxSupport",
    "Language": "en",
    "HighPriority": true,
    "SubIssueType": "ConsoleMalfunction",
    "ConsoleType": "XBOX_SERIES_X",
    "Model": "XBOX_SERIES_X_1TB"
  },
  "selectors": [
    {
      "key": "English",
      "operator": "GreaterThanEqual",
      "value": 7,
      "ttl": null
    },
    {
      "key": "ChatSupport",
      "operator": "Equal",
      "value": true,
      "ttl": null
    },
    {
      "key": "XboxSupport",
      "operator": "Equal",
      "value": true,
      "ttl": null
    }
  ],
  "worker": {
    "Id": "e3a3f2f9-3582-4bfe-9c5a-aa57831a0f88",
    "HighPrioritySupport": true,
    "HardwareSupport": true,
    "Support_XBOX_SERIES_X": true,
    "English": 10,
    "ChatSupport": true,
    "XboxSupport": true
  }
}

Implementasi sampel:

module.exports = async function (context, req) {
    context.log('Best Worker Distribution Mode using Azure Function');

    let score = 0;
    const jobLabels = req.body.job;
    const workerLabels = req.body.worker;

    const isHighPriority = !!jobLabels["HighPriority"];
    context.log('Job is high priority? Status: ' + isHighPriority);

    if(!isHighPriority) {
        const isGenericXboxSupportWorker = !!workerLabels["Support_XBOX"];
        context.log('Worker provides general xbox support? Status: ' + isGenericXboxSupportWorker);

        score = isGenericXboxSupportWorker ? 100 : 1;

    } else {
        const workerSupportsHighPriorityJob = !!workerLabels["HighPrioritySupport"];
        context.log('Worker provides high priority support? Status: ' + workerSupportsHighPriorityJob);

        if(!workerSupportsHighPriorityJob) {
            score = 1;
        } else {
            const key = `Support_${jobLabels["ConsoleType"]}`;
            
            const workerSpecializeInConsoleType = !!workerLabels[key];
            context.log(`Worker specializes in consoleType: ${jobLabels["ConsoleType"]} ? Status: ${workerSpecializeInConsoleType}`);

            score = workerSpecializeInConsoleType ? 200 : 100;
        }
    }
    context.log('Final score of worker: ' + score);

    context.res = {
        // status: 200, /* Defaults to 200 */
        body: score
    };
}

Output untuk Pekerja 1

200

Dengan implementasi tersebut, untuk pekerjaan yang diberikan, kita akan mendapatkan skor berikut untuk pekerja:

Worker Skor
Pekerja 1 200
Pekerja 2 200
Pekerja 3 1

Mendistribusikan penawaran berdasarkan mode pekerja terbaik

Sekarang setelah aplikasi fungsi Azure siap, mari kita buat instans mode BestWorkerDistribution menggunakan Router SDK.

    // ----- initialize router client
    // Setup Distribution Policy
    var bestWorkerDistributionMode = new BestWorkerMode(
        scoringRule: new AzureFunctionRule(
            functionAppUrl: "<insert function url>");

    var distributionPolicy = await client.SetDistributionPolicyAsync(
        id: "BestWorkerDistributionMode",
        mode: bestWorkerDistributionMode,
        name: "XBox hardware support distribution",
        offerTTL: TimeSpan.FromMinutes(5));

    // Setup Queue
    var queue = await client.SetQueueAsync(
        id: "XBox_Hardware_Support_Q",
        distributionPolicyId: distributionPolicy.Value.Id,
        name: "XBox Hardware Support Queue");

    // Setup Channel
    var channel = await client.SetChannelAsync("Xbox_Chat_Channel");

    // Create workers

    var worker1Labels = new LabelCollection()
    {
        ["HighPrioritySupport"] = true,
        ["HardwareSupport"] = true,
        ["Support_XBOX_SERIES_X"] = true,
        ["English"] = 10,
        ["ChatSupport"] = true,
        ["XboxSupport"] = true
    };
    var worker1 = await client.RegisterWorkerAsync(
        id: "Worker_1",
        totalCapacity: 100,
        queueIds: new[] {queue.Value.Id},
        labels: worker1Labels,
        channelConfigurations: new[] {new ChannelConfiguration(channel.Value.Id, 10)});

    var worker2Labels = new LabelCollection()
    {
        ["HighPrioritySupport"] = true,
        ["HardwareSupport"] = true,
        ["Support_XBOX_SERIES_X"] = true,
        ["Support_XBOX_SERIES_S"] = true,
        ["English"] = 8,
        ["ChatSupport"] = true,
        ["XboxSupport"] = true
    };
    var worker2 = await client.RegisterWorkerAsync(
        id: "Worker_2",
        totalCapacity: 100,
        queueIds: new[] { queue.Value.Id },
        labels: worker2Labels,
        channelConfigurations: new[] { new ChannelConfiguration(channel.Value.Id, 10) });

    var worker3Labels = new LabelCollection()
    {
        ["HighPrioritySupport"] = false,
        ["HardwareSupport"] = true,
        ["Support_XBOX"] = true,
        ["English"] = 7,
        ["ChatSupport"] = true,
        ["XboxSupport"] = true
    };
    var worker3 = await client.RegisterWorkerAsync(
        id: "Worker_3",
        totalCapacity: 100,
        queueIds: new[] { queue.Value.Id },
        labels: worker3Labels,
        channelConfigurations: new[] { new ChannelConfiguration(channel.Value.Id, 10) });

    // Create Job
    var jobLabels = new LabelCollection()
    {
        ["CommunicationType"] = "Chat",
        ["IssueType"] = "XboxSupport",
        ["Language"] = "en",
        ["HighPriority"] = true,
        ["SubIssueType"] = "ConsoleMalfunction",
        ["ConsoleType"] = "XBOX_SERIES_X",
        ["Model"] = "XBOX_SERIES_X_1TB"
    };
    var workerSelectors = new List<LabelSelector>()
    {
        new LabelSelector("English", LabelOperator.GreaterThanEqual, 7),
        new LabelSelector("ChatSupport", LabelOperator.Equal, true),
        new LabelSelector("XboxSupport", LabelOperator.Equal, true)
    };
    var job = await client.CreateJobAsync(
        channelId: channel.Value.Id,
        queueId: queue.Value.Id,
        priority: 100,
        channelReference: "ChatChannel",
        labels: jobLabels,
        workerSelectors: workerSelectors);

    var getJob = await client.GetJobAsync(job.Value.Id);
    Console.WriteLine(getJob.Value.Assignments.Select(assignment => assignment.Value.WorkerId).First());

Output

Worker_1 // or Worker_2

Since both workers, Worker_1 and Worker_2, get the same score of 200,
the worker who has been idle the longest will get the first offer.