Botframework-solutions: [TypeScript] Kelas "SkillMiddleware" harus menerima tiga parameter, bukan dua.

Dibuat pada 17 Okt 2019  ·  13Komentar  ·  Sumber: microsoft/botframework-solutions

Proyek apa yang terpengaruh?

Microsoft botframework V4, Keterampilan Kustom.

Bahasa apa ini?

Naskah Ketik

Apa yang terjadi?

Skill tidak dapat menerima informasi yang dikirimkan dari Asisten Virtual melalui SkillContext

Apa langkah-langkah untuk mereproduksi masalah ini?

Langkah 1: Hasilkan VA menggunakan " https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-solutions "
Langkah 2: Hasilkan keterampilan menggunakan perintah generator keterampilan
" https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-skills "
Langkah 3: Menambahkan file manifes keterampilan dengan parameter slot
Langkah 4: Atur SkillContext dengan nilai parameter slot.
Langkah 5: coba akses nilai SkillContext di Skill.

Apa yang Anda harapkan terjadi?

Objek yang diatur dalam SkillContext harus dapat diakses oleh keterampilan jika atribut "slot" cocok.
Namun skill tersebut tidak bisa mendapatkan SkillContext.
"SkillMiddleware" harus mendukung skillContextAccessor dan mengisi SkillContext dengan parameter slot.

Bisakah Anda membagikan log, keluaran kesalahan, dll.?

Setelah melakukan beberapa pekerjaan menemukan bahwa CustomSkillAdapter diisi dengan nilai "skillContextAccessor".

Kode saat ini:
kelas ekspor CustomSkillAdapter memperluas SkillHttpBotAdapter {
konstruktor (
telemetriKlien: TelemetriKlien,
status percakapan: Status Percakapan,
skillContextAccessor: StatePropertyAccessor,
dialogStateAccessor: StatePropertyAccessor,
...
) {
super(Klien telemetri);
[...]
this.use(SkillMiddleware baru(conversationState, dialogStateAccessor));
[...]
}
}

Kode yang Diharapkan sesuai ini " https://microsoft.github.io/botframework-solutions/howto/skills/skillenablingav4bot/ "

kelas ekspor CustomSkillAdapter memperluas SkillHttpBotAdapter {
konstruktor (
telemetriKlien: TelemetriKlien,
status percakapan: Status Percakapan,
skillContextAccessor: StatePropertyAccessor,
dialogStateAccessor: StatePropertyAccessor,
...
) {
super(Klien telemetri);
[...]
this.use(SkillMiddleware baru(conversationState, skillContextAccessor, dialogStateAccessor));
[...]
}
}

Terima kasih,
Edward

Bug

Komentar yang paling membantu

Luar biasa mendengarnya! Senang saya bisa membantu Anda dengan ini

Semua 13 komentar

Hai @Edwardfelix08 , mohon maaf atas keterlambatan jawabannya.
Kami meninjau dokumentasi untuk mengaktifkan Bot V4 sebagai Keterampilan (struktur dokumen berubah, tautan sebelumnya dikembalikan 404) dan menyadari bahwa itu tidak diperbarui dengan benar mengikuti beberapa perubahan dalam kode, jadi kami akan memperbarui dokumentasi itu.

Mengikuti langkah repro Anda, kami memahami bahwa Anda memiliki beberapa informasi tentang Asisten Virtual Anda dan Anda menyimpan informasi ini di SkillContext di Asisten Virtual, dan ketika Keterampilan menerima pesan, Anda ingin mengambil informasi ini dari SkillContext . Apakah ini benar?

Hai @dfavretto.
ya itu benar.

Hai @Edwardfelix08 , kami telah menguji skenario ini, dan membuat panduan tentang cara membuatnya bekerja. Memperhitungkan bahwa sampel-asisten tidak siap out-of-the-box untuk digunakan dalam skenario ini, jadi kami menyediakan tiga langkah untuk beberapa modifikasi kecil yang diperlukan untuk mencapai hal ini:

  1. [Asisten Virtual] Simpan informasi di SkillContext
  2. [keterampilan pembuat bot] Informasi SkillContext difilter dan disimpan ke dalam SemanticAction Aktivitas
  3. [Keterampilan] Isi Status Keterampilan dengan informasi SemanticAction Aktivitas

[Asisten Virtual] Simpan informasi di SkillContext

Pertama-tama, Anda harus menyimpan informasi yang diinginkan di dalam Konteks Keterampilan untuk mengambilnya nanti. Ini harus dilakukan sebelum meneruskan pesan Anda ke Skill. Tidak perlu melakukannya segera sebelumnya, informasi ini bisa saja disimpan pada tahap lain.

  1. Di dalam mainDialog Anda harus menggunakan skillContextAccessor untuk mengambil SkillContext yang sesuai dengan konteks Anda. Ini dapat dilakukan dengan baris berikut:

    const sc: SkillContext = await this.skillContextAccessor.get(dc.context, new SkillContext());
    const skillContext: SkillContext = Object.assign(new SkillContext(), sc);
    
  2. Sekarang setelah SkillContext Anda disimpan dalam variabel, Anda bisa mendapatkan atau menetapkan nilai apa pun. Jangan lupa nilai di dalam SkillContext adalah pasangan nilai kunci, jadi pastikan kunci Anda unik jika Anda tidak ingin menimpa nilai Anda. Sekarang Anda dapat menyimpan apa saja, yaitu nilai lokasi:

    skillContext.setObj('location', locationObj);
    
  3. Terakhir, atur SkillContext Anda menggunakan skillContextAccessor sehingga informasi ini disimpan di userState Anda :

    await this.skillContextAccessor.set(dc.context, skillContext);
    

[keterampilan pembuat bot] Informasi SkillContext difilter dan disimpan ke dalam SemanticAction Aktivitas

Setelah menyimpan informasi di SkillContext , SkillDialog di dalam botbuilder-skills akan memproses SkillContext selama metode onBeginDialog , yang hanya dijalankan sekali saat Skill dipanggil untuk pertama kalinya.

Metode ini secara otomatis akan melakukan langkah-langkah berikut:

  1. Dapatkan SkillContext dengan cara yang sama seperti yang kita lakukan di langkah pertama kita.
  2. SkillManifest digunakan untuk mendapatkan slot , dan kemudian informasi ini dikirim ke metode matchSkillContextToSlots .
  3. Di dalam metode matchSkillContextToSlots , SkillContext dievaluasi untuk menemukan kunci yang cocok dengan kunci Slot . Setiap kunci yang cocok digunakan untuk menyimpan pasangan nilai kunci SkillContext itu ke dalam SemanticAction .
  4. Aktivitas dengan SemanticAction (informasi yang diambil dari SkillContext yang cocok dengan Slot ) diteruskan ke Skill yang sesuai.

[Keterampilan] Isi Status Keterampilan dengan informasi SemanticAction Aktivitas

Langkah ketiga dan terakhir adalah mengisi SkillState dengan informasi yang dikirim dari Asisten Virtual dengan langkah-langkah ini:

  1. Di Skill, di dalam mainDialog , ada metode yang disebut populateStateFromSemanticAction . Metode ini dikomentari, dan agak ketinggalan jaman. Kami membuat [PR #2669] (sudah digabungkan) untuk memperbarui metode ini.
  2. Pastikan untuk memperbarui SkillState Anda, menambahkan properti yang diperlukan.
  3. Ubah populateStateFromSemanticAction seperlunya untuk mengambil semua properti dari SemanticAction dan menyimpannya di SkillState . Saat ini, metode sedang mencari properti 'Lokasi' sebagai contoh, ini dapat diubah ke properti apa pun yang ingin Anda akses:
    typescript if (semanticAction !== undefined && Object.keys(semanticAction.entities) .find((key: string) => key === "location"))
  4. Sekarang Anda dapat mengakses SkillState Anda di dalam Skill Anda dari mana saja.

Semoga langkah-langkah ini bermanfaat

Hai @lauren-mills dapatkah Anda memeriksa apakah pendekatan ini tampaknya benar? 😁

Terima kasih @dfavretto akan mencoba ini untuk melihat apakah itu berhasil.

Hai @dfavretto Saya sudah mencoba solusi di atas tetapi tidak berhasil. Saya masih melihat bahwa tidak ada pembaruan atau perubahan kode di kelas "CustomSkillAdapter"

@ Edwardfelix08 bisa Anda berbagi dengan kami apa adalah masalah yang Anda hadapi? Juga, berikut adalah beberapa pertanyaan panduan untuk menentukan dengan lebih baik bagaimana kami dapat membantu Anda:

  1. Bisakah Anda berhasil menyimpan informasi di SkillContext di Asisten Virtual Anda?
  2. Apakah SkillManifest diperbarui dengan Slot yang diperlukan?
  3. Apakah kunci Slot cocok dengan kunci yang digunakan untuk menyimpan informasi di SkillContext ?
  4. Apakah metode populateStateFromSemanticAction di Skill Anda tidak dikomentari?

Juga, mengenai CustomSkillAdapter , tidak perlu mengubah kelas itu untuk skenario kasus ini.

Hai @dfavretto ,
Di bawah ini adalah kode yang digunakan

  1. Bisakah Anda berhasil menyimpan informasi di SkillContext di Asisten Virtual Anda?

    Dialog Utama VA.
    const sk: SkillContext = menunggu this.skillContextAccessor.get(dc.context, new SkillContext());
    const skillContext: SkillContext = Object.assign(new SkillContext(), sk);
    skillContext.setObj('userState', userProfile);
    tunggu this.skillContextAccessor.set(dc.context, skillContext);

  2. Apakah SkillManifest Anda diperbarui dengan Slot yang diperlukan?
    skill.json di VA
    "slot": [{
    "nama": "negara pengguna",
    "ketik": ["IUserState"]
    }],

    SkillManifest
    "slot": [{
    "nama": "negara pengguna",
    "ketik": ["IUserState"]
    }],

  3. Apakah kunci Slot cocok dengan kunci yang digunakan untuk menyimpan informasi di SkillContext?
    kode di dalam populateStateFromSemanticAction
    if (skillContext.ContainsKey('userState')) {
    ......
    ......
    }

  4. Apakah metode populateStateFromSemanticAction di Skill Anda tidak dikomentari?
    ya, saya telah menghapus komentar pada formulir kode metode populateStateFromSemanticAction di dalam botSkill.

Apa yang akan menjadi versi bingkai bot yang harus kita gunakan?
Kami menggunakan paket di bawah ini.

    "botbuilder": "^4.5.3",
    "botbuilder-ai": "^4.5.3",
    "botbuilder-applicationinsights": "^4.5.3",
    "botbuilder-azure": "^4.5.3",
    "botbuilder-core": "^4.5.3",
    "botbuilder-dialogs": "^4.5.3",
    "botbuilder-skills": "^4.4.6",
    "botbuilder-solutions": "^4.4.6",
    "botframework-config": "^4.5.3",
    "botframework-connector": "^4.5.3",
    "botframework-schema": "^4.5.3",

@Edwardfelix08 , saya melihat Anda mencoba untuk mendapatkan nilai userState dari skillContext dalam metode populateStateFromSemanticAction . Saya ingin menunjukkan bahwa skillContext Anda isi di Asisten Virtual tidak lagi sama dengan yang Anda miliki di Skill Anda.

Untuk memanfaatkan situasi ini, data dari skillContext Asisten Virtual disalin ke semanticAction Aktivitas. Aktivitas adalah satu-satunya elemen yang dikirim dari Asisten Virtual ke Keterampilan , dan kemudian dapat dievaluasi untuk mendapatkan informasi ini.

Berikut adalah contoh populateStateFromSemanticAction yang akan mendapatkan nilai userState dari semanticAction Aktivitas:

protected async populateStateFromSemanticAction(context: TurnContext): Promise<void> {
        // Example of populating local state with data passed through semanticAction out of Activity
        const activity: Activity = context.activity;
        const semanticAction: SemanticAction | undefined = activity.semanticAction;
        if (semanticAction !== undefined && Object.keys(semanticAction.entities).find((key: string) => key === "userState")) {

            const userState: any = semanticAction.entities["userState"];
            const userStateObj = userState.properties["userState"];
            const state: SkillState = await this.stateAccessor.get(context, new SkillState());
            state.userState = userStateObj !== undefined ? userStateObj : userState;
            await this.stateAccessor.set(context, state);
        }
    }

@dfavretto maaf terlambat membalas.
Saya telah mencoba hal yang sama tetapi saya masih tidak bisa mendapatkan nilainya.
Nilai untuk activity.semanticAction tidak ditentukan.

Hai @Edwardfelix08 , kami membuat beberapa validasi dan kami tidak dapat mengulangi skenario Anda, karena SemanticAction selalu default dengan beberapa nilai, jadi tidak boleh tidak ditentukan.

image

Hanya untuk mengonfirmasi, di Asisten Virtual Anda, apakah Anda menggunakan Keterampilan Anda sebagai berikut?

image

@darrenj - haruskah kami menambahkan tim Dukungan sehingga mereka dapat membantu mendekati masalah ini dari perspektif lain? Karena sepertinya tidak ada hubungannya dengan implementasi TypeScript itu sendiri, tetapi dengan skenario spesifik itu diterapkan di sini.

Hai @dfavretto ,
Maaf terlambat membalas. Kami dapat menjalankan ini, Terima kasih. Kami merujuk ke versi lama kerangka kerja setelah diperbarui dan diperiksa silang dengan kode Anda dan ada perbedaan dalam "populateStateFromSemanticAction", Memperbarui kode ke yang diusulkan dan mulai bekerja seperti pesona.

Terima kasih telah membantu kami dalam hal ini.

Luar biasa mendengarnya! Senang saya bisa membantu Anda dengan ini

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

tommyJimmy87 picture tommyJimmy87  ·  4Komentar

VladPapacostea-SM picture VladPapacostea-SM  ·  3Komentar

nestoralonsovina picture nestoralonsovina  ·  4Komentar

lauren-mills picture lauren-mills  ·  4Komentar

hansmbakker picture hansmbakker  ·  3Komentar