Botframework-solutions: [TypeScript] "SkillMiddleware" ํด๋ž˜์Šค๋Š” 2๊ฐœ๊ฐ€ ์•„๋‹Œ 3๊ฐœ์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ—ˆ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2019๋…„ 10์›” 17์ผ  ยท  13์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: microsoft/botframework-solutions

์–ด๋–ค ํ”„๋กœ์ ํŠธ๊ฐ€ ์˜ํ–ฅ์„ ๋ฐ›๋‚˜์š”?

๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ ๋ด‡ํ”„๋ ˆ์ž„์›Œํฌ V4, ์ปค์Šคํ…€ ์Šคํ‚ฌ.

์ด๊ฒƒ์€ ์–ด๋–ค ์–ธ์–ด๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?

ํƒ€์ดํ”„์Šคํฌ๋ฆฝํŠธ

๋ฌด์Šจ ์ผ์ด์•ผ?

Skill์ด SkillContext๋ฅผ ํ†ตํ•ด Virtual Assistant์—์„œ ์ „๋‹ฌ๋œ ์ •๋ณด๋ฅผ ์ˆ˜์‹ ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ์žฌํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ๊ณ„๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

1๋‹จ๊ณ„: " https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-solutions "๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ VA ์ƒ์„ฑ
2๋‹จ๊ณ„: ์Šคํ‚ฌ ์ƒ์„ฑ๊ธฐ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šคํ‚ฌ ์ƒ์„ฑ
" https://botbuilder.myget.org/feed/aitemplates/package/npm/botbuilder-skills "
3๋‹จ๊ณ„: ์Šฌ๋กฏ ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋Š” ์Šคํ‚ฌ ๋งค๋‹ˆํŽ˜์ŠคํŠธ ํŒŒ์ผ ์ถ”๊ฐ€
4๋‹จ๊ณ„: ์Šฌ๋กฏ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐ’์œผ๋กœ SkillContext๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
5๋‹จ๊ณ„: Skill์—์„œ SkillContext ๊ฐ’์— ์•ก์„ธ์Šค๋ฅผ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค.

๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚  ๊ฒƒ์ด๋ผ๊ณ  ์˜ˆ์ƒํ–ˆ์Šต๋‹ˆ๊นŒ?

SkillContext์— ์„ค์ •๋œ ๊ฐœ์ฒด๋Š” "slot" ์†์„ฑ์ด ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ ๊ธฐ์ˆ ์—์„œ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์Šคํ‚ฌ์€ SkillContext๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
"SkillMiddleware"๋Š” SkillContextAccessor๋ฅผ ์ง€์›ํ•˜๊ณ  SkillContext๋ฅผ ์Šฌ๋กฏ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ฑ„์›Œ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ, ์˜ค๋ฅ˜ ์ถœ๋ ฅ ๋“ฑ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

๋ช‡ ๊ฐ€์ง€ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ˆ˜ํ–‰ํ•œ ํ›„ CustomSkillAdapter๊ฐ€ "skillContextAccessor" ๊ฐ’์œผ๋กœ ์ฑ„์›Œ์ ธ ์žˆ์Œ์„ ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์ฝ”๋“œ:
๋‚ด๋ณด๋‚ด๊ธฐ ํด๋ž˜์Šค CustomSkillAdapter๋Š” SkillHttpBotAdapter๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. {
๊ฑด์„ค์ž(
์›๊ฒฉ ์ธก์ • ํด๋ผ์ด์–ธํŠธ: ์›๊ฒฉ ์ธก์ • ํด๋ผ์ด์–ธํŠธ,
๋Œ€ํ™” ์ƒํƒœ: ๋Œ€ํ™” ์ƒํƒœ,
SkillContextAccessor: StatePropertyAccessor,
dialogStateAccessor: StatePropertyAccessor,
...
) {
์Šˆํผ(์›๊ฒฉ ํด๋ผ์ด์–ธํŠธ);
[...]
this.use(new SkillMiddleware(conversationState, dialogStateAccessor));
[...]
}
}

์ด " https://microsoft.github.io/botframework-solutions/howto/skills/skillenablingav4bot/ "์— ๋”ฐ๋ฅธ ์˜ˆ์ƒ ์ฝ”๋“œ

๋‚ด๋ณด๋‚ด๊ธฐ ํด๋ž˜์Šค CustomSkillAdapter๋Š” SkillHttpBotAdapter๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. {
๊ฑด์„ค์ž(
์›๊ฒฉ ์ธก์ • ํด๋ผ์ด์–ธํŠธ: ์›๊ฒฉ ์ธก์ • ํด๋ผ์ด์–ธํŠธ,
๋Œ€ํ™” ์ƒํƒœ: ๋Œ€ํ™” ์ƒํƒœ,
SkillContextAccessor: StatePropertyAccessor,
dialogStateAccessor: StatePropertyAccessor,
...
) {
์Šˆํผ(์›๊ฒฉ ํด๋ผ์ด์–ธํŠธ);
[...]
this.use(์ƒˆ๋กœ์šด SkillMiddleware(conversationState, SkillContextAccessor, dialogStateAccessor));
[...]
}
}

๊ฐ์‚ฌ ํ•ด์š”,
์—๋“œ์›Œ๋“œ

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๊ทธ ๋ง์„ ๋“ค์œผ๋‹ˆ ๋Œ€๋‹จํ•ด! ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์–ด์„œ ๊ธฐ์ฉ๋‹ˆ๋‹ค ๐Ÿ˜Š

๋ชจ๋“  13 ๋Œ“๊ธ€

@Edwardfelix08๋‹˜ , ๋‹ต๋ณ€์ด ๋Šฆ์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.
V4 Bot์„ ๊ธฐ์ˆ ๋กœ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์„œ๋ฅผ ๊ฒ€ํ† ํ–ˆ์œผ๋ฉฐ(๋ฌธ์„œ ๊ตฌ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋จ, ์ด์ „ ๋งํฌ์—์„œ 404๋ฅผ ๋ฐ˜ํ™˜ํ•จ) ์ฝ”๋“œ์˜ ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š์•˜์Œ์„ ๊นจ๋‹ฌ์•˜์œผ๋ฏ€๋กœ ํ•ด๋‹น ๋ฌธ์„œ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.

์žฌํ˜„ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ๊ฐ€์ƒ ๋„์šฐ๋ฏธ์— ๋Œ€ํ•œ ์ผ๋ถ€ ์ •๋ณด๊ฐ€ ์žˆ๊ณ  ์ด ์ •๋ณด๋ฅผ ๊ฐ€์ƒ ๋„์šฐ๋ฏธ์˜ SkillContext ์— ์ €์žฅํ•˜๊ณ  Skill์ด ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์‹ ํ•  ๋•Œ ์ด ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๊ธฐ๋ฅผ ์›ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค. SkillContext . ์ด ์˜ฌ๋ฐ”๋ฅธ์ง€?

์•ˆ๋…•ํ•˜์„ธ์š” @dfavretto์ž…๋‹ˆ๋‹ค.
๋„ค ๋งž์Šต๋‹ˆ๋‹ค.

@Edwardfelix08๋‹˜ , ์•ˆ๋…•ํ•˜์„ธ์š”, ์šฐ๋ฆฌ๋Š” ์ด ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ํ…Œ์ŠคํŠธํ–ˆ์œผ๋ฉฐ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒƒ์„ ๊ณ ๋ ค ์ƒ˜ํ”Œ ๋น„์„œ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ์ด๋Ÿฌํ•œ ๋ชฉํ‘œ๋ฅผ ๋‹ฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ช‡ ๊ฐ€์ง€ ์‚ฌ์†Œํ•œ ์ˆ˜์ •์œผ๋กœ ์„ธ ๋‹จ๊ณ„๋ฅผ ์ œ๊ณตํ•˜๊ณ , ๊ทธ๋ž˜์„œ ์ค€๋น„๊ฐ€ ์•„์›ƒ - ์˜ค๋ธŒ - ๋ฐ•์Šค ์‚ฌ์šฉ์—์ด ์‹œ๋‚˜๋ฆฌ์˜ค๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค :

  1. [Virtual Assistant] SkillContext์— ์ •๋ณด ์ €์žฅ
  2. [botbuilder-skills] SkillContext ์ •๋ณด๊ฐ€ ํ•„ํ„ฐ๋ง๋˜์–ด Activity์˜ SemanticAction์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  3. [Skill] ํ™œ๋™์˜ SemanticAction ์ •๋ณด๋กœ SkillState ์ฑ„์šฐ๊ธฐ

[Virtual Assistant] SkillContext์— ์ •๋ณด ์ €์žฅ

๋จผ์ € ์›ํ•˜๋Š” ์ •๋ณด๋ฅผ ๋‚˜์ค‘์— ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”์‹œ์ง€๋ฅผ Skill์— ์ „๋‹ฌ ํ•˜๊ธฐ ์ „์— ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋กœ ์ง์ „์— ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋Š” ๋‹ค๋ฅธ ๋‹จ๊ณ„์—์„œ ์ €์žฅ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  1. ๋‚ด๋ถ€ mainDialog ๋‹น์‹ ์€ ์‚ฌ์šฉํ•  ํ•„์š”๊ฐ€ skillContextAccessor์„ ๋‹น์‹ ์˜ ์ปจํ…์ŠคํŠธ์— ํ•ด๋‹นํ•˜๋Š” SkillContext๋ฅผ ๊ฒ€์ƒ‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋‹ค์Œ ์ค„์„ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    constย sc:ย SkillContextย =ย awaitย this.skillContextAccessor.get(dc.context,ย newย SkillContext());
    constย skillContext:ย SkillContextย =ย Object.assign(newย SkillContext(),ย sc);
    
  2. ์ด์ œ SkillContext ๊ฐ€ ๋ณ€์ˆ˜์— ์ €์žฅ SkillContext ๋‚ด์˜ ๊ฐ’์€ ํ‚ค-๊ฐ’ ์Œ

    skillContext.setObj('location',ย locationObj);
    
  3. ์ด ์ •๋ณด๊ฐ€ userState์— ์ €์žฅ๋˜๋„๋ก ๋งˆ์ง€๋ง‰์œผ๋กœ, skillContextAccessor๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ SkillContext์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค :

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

[botbuilder-skills] SkillContext ์ •๋ณด๊ฐ€ ํ•„ํ„ฐ๋ง๋˜์–ด Activity์˜ SemanticAction์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

SkillContext์˜ ์ •๋ณด๋ฅผ ์ €์žฅ ํ•œ ํ›„, ๊ทธ๊ฒƒ์˜ ๋ฒŒ๊ธˆ ์Šคํ‚ฌ์— ๋ฉ”์‹œ์ง€๋ฅผ ์ „๋‹ฌ ๋งŒํ•˜๋Š” ๋ฉ”์‹œ์ง€๋Š” ์Šคํ‚ฌ์˜์— ๋„๋‹ฌํ•˜๊ธฐ ์ „์— SkillDialog ๋‚ด๋ถ€ botbuilder-skills ๋™์•ˆ SkillContext์„ ์ฒ˜๋ฆฌ ํ•  onBeginDialog ๋ฐฉ๋ฒ• ์—๋งŒ ํ•œ ๋ฒˆ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค, ์Šคํ‚ฌ์ด ์ฒ˜์Œ์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์ด ๋ฐฉ๋ฒ•์€ ์ž๋™์œผ๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„์—์„œ ์ˆ˜ํ–‰ ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ
  2. SkillManifest ๋Š” ์Šฌ๋กฏ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ ์ด ์ •๋ณด๋Š” matchSkillContextToSlots ๋ฉ”์„œ๋“œ๋กœ ์ „์†ก๋ฉ๋‹ˆ๋‹ค.
  3. matchSkillContextToSlots ๋ฐฉ๋ฒ• ๋‚ด๋ถ€์—์„œ SkillContext๋Š” ์Šฌ๋กฏ ํ‚ค ์ผ์น˜ํ•˜๋Š” ๋ชจ๋“  ํ‚ค๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ํ‰๊ฐ€๋œ๋‹ค. ์ผ์น˜ํ•˜๋Š” ๊ฐ ํ‚ค๋Š” ํ•ด๋‹น SkillContext ์˜ ํ‚ค-๊ฐ’ ์Œ์„ SemanticAction ์— ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
  4. SemanticAction ์ด ์žˆ๋Š” ํ™œ๋™ ( Slots ์™€ ์ผ์น˜ํ•˜๋Š” SkillContext ์—์„œ ๊ฒ€์ƒ‰๋œ ์ •๋ณด)์€ ํ•ด๋‹น Skill๋กœ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

[Skill] ํ™œ๋™์˜ SemanticAction ์ •๋ณด๋กœ SkillState ์ฑ„์šฐ๊ธฐ

์„ธ ๋ฒˆ์งธ์ด์ž ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„๋Š” ๋‹ค์Œ ๋‹จ๊ณ„์— ๋”ฐ๋ผ ๊ฐ€์ƒ ๋„์šฐ๋ฏธ์—์„œ ๋ณด๋‚ธ ์ •๋ณด๋กœ SkillState ๋ฅผ ์ฑ„์šฐ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  1. Skill์˜ mainDialog ๋‚ด๋ถ€์—๋Š” populateStateFromSemanticAction ์ด๋ผ๋Š” ๋ฉ”์„œ๋“œ
  2. SkillState ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ณ  ํ•„์š”ํ•œ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  3. ํ•„์š”์— ๋”ฐ๋ผ populateStateFromSemanticAction ์„ ์ˆ˜์ •ํ•˜์—ฌ SemanticAction ์—์„œ ๋ชจ๋“  ์†์„ฑ์„ ๊ฐ€์ ธ์™€ SkillState์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์ง€๊ธˆ ์ด ๋ฉ”์„œ๋“œ๋Š” 'Location' ์†์„ฑ์„ ์˜ˆ๋กœ ์ฐพ๊ณ  ์žˆ์œผ๋ฉฐ ์•ก์„ธ์Šคํ•˜๋ ค๋Š” ์†์„ฑ์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    typescript ifย (semanticActionย !==ย undefinedย &&ย Object.keys(semanticAction.entities) .find((key:ย string)ย =>ย keyย ===ย "location"))
  4. ์ด์ œ ์–ด๋””์—์„œ๋‚˜ Skill ๋‚ด๋ถ€์˜ SkillState์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋‹จ๊ณ„๊ฐ€ ์œ ์šฉํ•˜๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค ๐Ÿ˜Š

@lauren-mills ์ด ์ ‘๊ทผ ๋ฐฉ์‹์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๐Ÿ˜

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค @dfavretto ๊ฐ€ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @dfavretto ์œ„์˜ ์†”๋ฃจ์…˜์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์ž‘๋™ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์—ฌ์ „ํžˆ "CustomSkillAdapter" ํด๋ž˜์Šค์— ์—…๋ฐ์ดํŠธ ๋˜๋Š” ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ์—†๋Š” ๊ฒƒ์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

@Edwardfelix08 ๋‹น์‹ ์ด ์ง๋ฉดํ•œ ๋ฌธ์ œ๊ฐ€ ์ •ํ™•ํžˆ ๋ฌด์—‡์ธ์ง€ ์•Œ๋ ค ์ฃผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋˜ํ•œ ๋‹ค์Œ์€ ๊ท€ํ•˜๋ฅผ ๋„์šธ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ๋” ์ž˜ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์•ˆ๋‚ด ์งˆ๋ฌธ์ž…๋‹ˆ๋‹ค.

  1. Virtual Assistant ์˜ SkillContext ์— ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
  2. SkillManifest ๊ฐ€ ํ•„์š”ํ•œ ์Šฌ๋กฏ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?
  3. Slot ์˜ ํ‚ค๊ฐ€ SkillContext ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ํ‚ค์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๊นŒ?
  4. ์Šคํ‚ฌ์˜ populateStateFromSemanticAction ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ?

๋˜ํ•œ CustomSkillAdapter ์™€ ๊ด€๋ จํ•˜์—ฌ ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ํ•ด๋‹น ํด๋ž˜์Šค๋ฅผ ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @dfavretto ,
์•„๋ž˜๋Š” ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

  1. Virtual Assistant์˜ SkillContext์— ์ •๋ณด๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?

    VA ๋ฉ”์ธ ๋‹ค์ด์–ผ๋กœ๊ทธ.
    const sk: SkillContext = this.skillContextAccessor.get(dc.context, new SkillContext())์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
    const ๊ธฐ์ˆ  ์ปจํ…์ŠคํŠธ: SkillContext = Object.assign(new SkillContext(), sk);
    SkillContext.setObj('userState', userProfile);
    this.skillContextAccessor.set(dc.context, SkillContext)๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

  2. SkillManifest๊ฐ€ ํ•„์š”ํ•œ ์Šฌ๋กฏ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์Šต๋‹ˆ๊นŒ?
    ๋ฒ„์ง€๋‹ˆ์•„์˜ Skill.json
    "์Šฌ๋กฏ": [{
    "์ด๋ฆ„": "์‚ฌ์šฉ์ž ์ƒํƒœ",
    "์œ ํ˜•": ["IUserState"]
    }],

    ์Šคํ‚ฌ๋งค๋‹ˆํŽ˜์ŠคํŠธ
    "์Šฌ๋กฏ": [{
    "์ด๋ฆ„": "์‚ฌ์šฉ์ž ์ƒํƒœ",
    "์œ ํ˜•": ["IUserState"]
    }],

  3. ์Šฌ๋กฏ์˜ ํ‚ค๊ฐ€ SkillContext์— ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ํ‚ค์™€ ์ผ์น˜ํ•ฉ๋‹ˆ๊นŒ?
    populateStateFromSemanticAction ๋‚ด๋ถ€์˜ ์ฝ”๋“œ
    if (skillContext.ContainsKey('userState')) {
    ......
    ......
    }

  4. Skill์˜ populateStateFromSemanticAction ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฃผ์„ ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๊นŒ?
    ์˜ˆ, botSkill ๋‚ด๋ถ€์—์„œ ์ฝ”๋“œ ์–‘์‹ populateStateFromSemanticAction ๋ฉ”์†Œ๋“œ์˜ ์ฃผ์„ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ฑฐํ–ˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๋ด‡ ํ”„๋ ˆ์ž„ ๋ฒ„์ „์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?
์šฐ๋ฆฌ๋Š” ์•„๋ž˜ ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

    "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 , populateStateFromSemanticAction ๋ฉ”์„œ๋“œ์˜ skillContext ์—์„œ userState ๊ฐ’์„ ์–ป์œผ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. Virtual Assistant์— ๊ธฐ์ž…ํ•œ skillContext ๋Š” ๋” ์ด์ƒ Skill ์— ์žˆ๋Š” ๊ฒƒ๊ณผ ๊ฐ™์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ์ƒํ™ฉ์„ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด Virtual Assistant์˜ skillContext ๊ฐ€ ํ™œ๋™์˜ semanticAction ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค. Activity๋Š” Virtual Assistant ์—์„œ Skill๋กœ ์ „์†ก๋˜๋Š” ์œ ์ผํ•œ ์š”์†Œ์ด๋ฉฐ ์ด ์ •๋ณด๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์˜ ์˜ˆ์ž…๋‹ˆ๋‹ค populateStateFromSemanticAction ๋‹น์‹  ์–ป์„ ๊ฒƒ์ด๋‹ค userState ํ™œ๋™์˜์—์„œ ๊ฐ’ semanticAction :

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 ๋‹ต๋ณ€์ด ๋Šฆ์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค.
๋‚˜๋Š” ๊ฐ™์€ ๊ฒƒ์„ ์‹œ๋„ํ–ˆ์ง€๋งŒ ์—ฌ์ „ํžˆ ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
activity.semanticAction ์ด ์ •์˜๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

@Edwardfelix08๋‹˜ , ์•ˆ๋…•ํ•˜์„ธ์š”. SemanticAction ๋Š” ํ•ญ์ƒ ์ผ๋ถ€ ๊ฐ’์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์ด ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ถ€ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์ˆ˜ํ–‰ ํ–ˆ์ง€๋งŒ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์žฌํ˜„ํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ •์˜๋˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

image

ํ™•์ธ์„ ์œ„ํ•ด ๊ฐ€์ƒ ์–ด์‹œ์Šคํ„ดํŠธ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šคํ‚ฌ์„ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

image

@darrenj - ๋‹ค๋ฅธ ๊ด€์ ์—์„œ ์ด ๋ฌธ์ œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์› ํŒ€์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๊นŒ? TypeScript ๊ตฌํ˜„ ์ž์ฒด์™€ ์•„๋ฌด ๊ด€๋ จ์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์ง€๋งŒ ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ์—ฌ๊ธฐ์—์„œ ๊ตฌํ˜„๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š” @dfavretto ,
๋‹ต๋ณ€์ด ๋Šฆ์–ด ์ฃ„์†กํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„ ๋•๋ถ„์— ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ์˜ ์ด์ „ ๋ฒ„์ „์„ ์ฐธ์กฐํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•˜๊ณ  ์ฝ”๋“œ์™€ ๊ต์ฐจ ํ™•์ธํ–ˆ์œผ๋ฉฐ "populateStateFromSemanticAction"์— ์ฐจ์ด๊ฐ€ ์žˆ์—ˆ๊ณ  ์ œ์•ˆ๋œ ์ฝ”๋“œ๋กœ ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ–ˆ๊ณ  ๋งค๋ ฅ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋„์™€์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๋ง์„ ๋“ค์œผ๋‹ˆ ๋Œ€๋‹จํ•ด! ๋„์›€์ด ๋  ์ˆ˜ ์žˆ์–ด์„œ ๊ธฐ์ฉ๋‹ˆ๋‹ค ๐Ÿ˜Š

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰