小愛技能開發大賽-抽籤技能開發分享

“抽籤”技能的開發流程基本沿襲官方給出的Hello World的開發方式。

首先明確技能的功能,一般而言,抽籤包括兩個步驟,設置抽籤人數,依次開始抽籤。此外還需要支持查看已經抽籤的結果。再看應用場景,因爲技能的對象面向於智能音箱,而音箱的人機交互方式只有通過語音進行,所以對於給用戶的交互過程既要保證功能的準確傳達,又要保證其簡潔與穩定。

針對上述要求,小愛開發平臺使用意圖與詞表的交互模型,意圖基於詞表,平臺內置了常見的詞表,如顏色、數字、國家等。本技能爲了追求開發準確與高效,未自定義詞表,使用內置詞表完成意圖構建。

本技能的意圖針對其功能劃分爲三部分,分別是抽籤人數的設置,籤號的抽取,查看抽籤結果,其中抽籤人數的設置需要使用數字詞表。構建的意圖如下。

意圖名稱 意圖描述 槽位
random_sum 抽籤人數 1
random_select 隨機抽取籤號 0
all_selected_info 抽取的籤號 0

接下來小愛平臺會根據用戶輸入信息整合成服務器-客戶端常見的JSON形式的request發向服務器,接下來就是開發者要完成的主體部分了。

from xiaoai import *
import random

def outputJson(toSpeakText, is_session_end, attribute=None, openMic=True):
    xiaoAIResponse=XiaoAIResponse(to_speak=XiaoAIToSpeak(type_=0, text=toSpeakText), open_mic=openMic)
    response = xiaoai_response(XiaoAIOpenResponse(version="1.0",is_session_end=is_session_end,response=xiaoAIResponse,session_attributes=attribute))
    return response

def main(event):
    req = xiaoai_request(event)
    sum_person = 0
    selected_num = 0
    rand =0
    count = 0
    dictionary = {}
    attribute = {"sum_person":0}
    if req.request.type == 0:
        attribute['sum_person'] = 200
        attribute['dictionary'] = dictionary
        attribute["selected_num"] = 0
        return outputJson("歡迎進入抽籤小工具,請先向小愛說明抽籤人數,如 一共10個人", False, attribute)
    elif req.request.type == 1:
        if ((not hasattr(req.request, "slot_info")) or (not hasattr(req.request.slot_info, "intent_name"))):
            return outputJson("抱歉,我還沒有聽懂。請先說明抽籤人數或者直接對小愛說抽籤。", False, None)
        else:
            if req.request.slot_info.intent_name == 'random_sum':
                slotsList = req.request.slot_info.slots
                sum_person = [item for item in slotsList if item['name'] == 'random_sum'][0]['value']
                if int(sum_person) > 200:
                    sum_person = 200
                elif int(sum_person) < 1:
                    sum_person = 1
                attribute["sum_person"] = int(sum_person)
                attribute["selected_num"] = int(selected_num)
                attribute['dictionary'] = dictionary
                return outputJson("已設置參與人數" + str(sum_person) + "人,請大家依次對小愛說 抽籤 抽取自己的籤號", False,attribute)
            elif req.request.slot_info.intent_name == 'random_select':
                if hasattr(req.session, "attributes"):
                    sum_person = int(req.session.attributes["sum_person"])
                    selected_num = int(req.session.attributes["selected_num"])
                    dictionary = req.session.attributes["dictionary"]
                    attribute["sum_person"] = int(sum_person)

                if selected_num == sum_person:
                    attribute['dictionary'] = dictionary
                    attribute["sum_person"] = selected_num
                    attribute["selected_num"] = selected_num
                    return outputJson("籤號都被抽完了,您可以向小愛說 所有人 來查看抽籤信息或者重新設置人數哦", False,attribute)
                else:
                    rand = random.randint(1,sum_person)
                    print("dictionary: "+ str(dictionary))
                    #略
                    dictionary.setdefault(str(rand),1)
                attribute['dictionary'] = dictionary
                attribute["selected_num"] = int(selected_num+1)
                #selected_num = selected_num+1
                return outputJson("籤號:"+str(rand)+",還剩"+str(sum_person-selected_num-1)+"個籤位", False, attribute) 
            elif req.request.slot_info.intent_name == 'all_selected_info':
                if hasattr(req.session, "attributes"):
                    sum_person = int(req.session.attributes["sum_person"])
                    selected_num = int(req.session.attributes["selected_num"])
                    dictionary = req.session.attributes["dictionary"]
                    attribute = req.session.attributes

                str_output = "已經選擇的籤號依次爲:"
                j = 1
                for i in dictionary.keys():
                    str_output += str(j)+"號籤:"+ str(i) +", "
                    j+=1
                str_output +="還剩"+ str(sum_person-selected_num)+"個籤位未選擇。"
                print(str_output)
                return outputJson(str_output, False, attribute)
            else:
                return outputJson("抱歉,我沒有聽懂呢", False,None)
    else:
        return outputJson("感謝使用抽籤小工具,下次再見哦~", True, None, False)

直接看代碼吧,可以根據中文看出分發的流程,intent_name就是上文表格的意圖名稱,接下來的邏輯並不是很複雜,這裏對應用場景做了一些限制,如最大(默認)抽籤人數爲200人,可以直接跳過設置人數這個環節,這些都是爲了減少用戶不必要的往復交互。

由於每一次請求都是獨立的,所以抽籤人數和抽籤結果的儲存是必須要考慮的。這裏採用了小米的開放雲,所以平臺也限制了一些其他的實現方案,在請教了小愛工程師之後採用小愛request中自帶的session字段保存信息,由於數據量不大所以不會形成太重數據傳輸壓力,python的小愛包是不開源的,可以到這個鏈接查看字段定義,剛開始都不知道JSON該怎麼傳輸,後來發現只要用默認的dictionary就可以了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章