圖靈機(jī)器人相關(guān)接口
圖靈機(jī)器人是一個(gè)中文語(yǔ)境下的對(duì)話機(jī)器人,免費(fèi)的機(jī)器人每天有5000次調(diào)用的,如果放在群聊中是完全夠用的(如果只有@的消息才使用機(jī)器人回復(fù)的)。圖靈機(jī)器人也包括一些簡(jiǎn)單的能力,比如講笑話、故事大全、成語(yǔ)接龍、新聞資訊等,我們將介紹如何簡(jiǎn)單調(diào)用圖靈機(jī)器人接口。
前期準(zhǔn)備
前往注冊(cè)圖靈機(jī)器人,增加一個(gè)機(jī)器人,并記錄機(jī)器人的APIKey。具體注冊(cè)方法可以前往圖靈API查看。(如果你覺得很麻煩, 也可以暫時(shí)使用itchat提供的幾個(gè)key)
-
# 從 pip 安裝 () pip install requests
并在機(jī)器人中導(dǎo)入Requests包(寫在程序最初):
import requests
調(diào)用接口
wxpy提供了圖靈的接口,使用方法:
tuling = Tuling(api_key='Your API Key') # 剛才申請(qǐng)的key
@bot.register(my_friend) # 注冊(cè)消息
def reply_my_friend(msg):
tuling.do_reply(msg)
為了讓大家了解HTTP協(xié)議在python中的使用方式,我接下來會(huì)介紹如何使用請(qǐng)求獲取信息。
本節(jié)中內(nèi)容如果沒有特殊提示,都應(yīng)寫在你希望處理的某種注冊(cè)了的消息方法中以保證它的正常運(yùn)作。
首先,將圖靈API寫入程序中:
TULING_TOKEN = 'Your API Key'
然后,定義接口鏈接和需要傳輸?shù)臄?shù)據(jù):
url_api = 'http://www.tuling123.com/openapi/api'
data = {
'key' : TULING_TOKEN,
'info' : msg.text, # 收到消息的文字內(nèi)容
}
根據(jù)文檔,通過HTTP請(qǐng)求,我們將會(huì)得到一個(gè)json格式的文件。使用Requests包,我們可以簡(jiǎn)單的獲得調(diào)用接口所返回的信息:
s = requests.post(url_api, data=data).json()
print s # 打印所獲得的json查看如何使用
# {u'text': u'回復(fù)的內(nèi)容', u'code': 100000}
我們發(fā)現(xiàn)經(jīng)過請(qǐng)求,我們一般會(huì)得到一個(gè)字典內(nèi)容,其中包括text和code兩項(xiàng):text是圖靈機(jī)器人回復(fù)的文本,而code是返回的編號(hào)。詳細(xì)的返回?cái)?shù)據(jù)格式也可以在圖靈API中看到,除了文字類還有新聞?lì)悺D片類、鏈接類等返回類型。在這里我們以文字類為例,介紹如何處理:
if s['code'] == 100000:
print s['text'] # 查看回復(fù)消息的內(nèi)容,可省略
msg.reply(s['text']) # 回復(fù)消息
如果需要回復(fù)其他類型的消息,也完全可以通過判斷code確定消息類型,再?zèng)Q定如何回復(fù)。這里給出我的回復(fù)方法供大家參考(也可以選擇不處理這一類內(nèi)容):
if s['code'] == 200000: # 鏈接類:回復(fù)文字和鏈接
msg.reply(s['text'] + s['url'])
至此,我們已經(jīng)成功調(diào)用了圖靈機(jī)器人的API接口進(jìn)行回復(fù),完整程序如下:
# -*- coding: utf-8 -*-
from wxpy import *
import requests
TULING_TOKEN = 'Your API Key'
bot = Bot()
@bot.register(Group, TEXT) # 這里注冊(cè)了群聊中的文字消息,測(cè)試時(shí)可以設(shè)置為自己(上篇中提到過)
def group_msg(msg):
if msg.is_at:
url_api = 'http://www.tuling123.com/openapi/api'
data = {
'key' : TULING_TOKEN,
'info' : msg.text, # 收到消息的文字內(nèi)容
}
s = requests.post(url_api, data=data).json()
print s # 打印所獲得的json查看如何使用
if s['code'] == 100000:
print s['text'] # 查看回復(fù)消息的內(nèi)容,可省略
msg.reply(s['text']) # 回復(fù)消息
embed()
以下內(nèi)容更加進(jìn)階,而文末有一些簡(jiǎn)單問題的解答。如果遇到其他問題,我也會(huì)在之后更新。
番外:使用上下文
wxpy給每個(gè)用戶定義了一個(gè)相對(duì)穩(wěn)定的對(duì)象/用戶id,為puid,可以始終被獲取到并有唯一的穩(wěn)定性(根據(jù)文檔),我們可以使用這個(gè)id來作為userid傳給圖靈機(jī)器人,以方便識(shí)別機(jī)器人或航班/列成信息的上下文。
bot.enable_puid() # puid 需要手動(dòng)開啟,請(qǐng)將這句話寫在登陸登錄之后
這樣傳送給接口的數(shù)據(jù)也要同時(shí)修改為:
data = {
'key' : TULING_TOKEN,
'info' : msg.text, # 收到消息的文字內(nèi)容
'userid' : msg.member.puid, # 使用群聊中發(fā)送者的 puid 作為 userid 傳送給圖靈接口, 如果是私聊可以使用 msg.sender.puid
}
這樣做的好處是,圖靈機(jī)器人可以根據(jù)得userid來獲取上下文信息。例如你詢問『天氣』,它會(huì)回復(fù)『親愛的,悄悄地告訴我你在哪個(gè)城市?』。在這種情況下,如果你不使用userid參數(shù),你再次回復(fù)城市,圖靈機(jī)器人也無法正確找到天氣;如果你使用了這一參數(shù),且兩次回復(fù)使用的userid相同,圖靈機(jī)器人會(huì)為你回復(fù)你回復(fù)的城市的天氣情況,完成這一對(duì)話。
使用api.ai
api.ai是一家被谷歌收購(gòu)的人機(jī)交互系統(tǒng),主要著重于對(duì)話機(jī)器人的開發(fā)。圖靈機(jī)器人雖然包括一個(gè)知識(shí)庫(kù),但其語(yǔ)義識(shí)別的能力較差。我所需要的機(jī)器人主要用于新生群,很多問題人與人之間會(huì)有相當(dāng)多不同的表達(dá),圖靈機(jī)器人無法滿足我對(duì)于群聊機(jī)器人的要求。因此,我嘗試使用api.ai進(jìn)行回復(fù)有針對(duì)性的一些問題。
如果你的英語(yǔ)相對(duì)糟糕,我不建議使用api.ai。api.ai的配置大多需要使用英語(yǔ),雖然接口簡(jiǎn)單,但是后臺(tái)設(shè)置相對(duì)復(fù)雜,如果沒有英文背景不推薦使用。
這一部分內(nèi)容相對(duì)進(jìn)階,如果沒有特殊需要,完全可以跳過不看。這里只作一個(gè)對(duì)api.ai使用方式上大體的介紹,希望能幫助大家了解這一網(wǎng)站。
前期準(zhǔn)備
前往api.ai注冊(cè),創(chuàng)建機(jī)器人,并獲得APIkey。雖然被谷歌收購(gòu),但是這個(gè)網(wǎng)站是不需要翻墻的哦!
-
安裝api.ai官方提供的Python SDK
pip install apiai
-
在文件頭部加入(處理返回的消息時(shí)使用)
import json
調(diào)用接口
首先,我們需要設(shè)置api.ai的Token,
APIAI_TOKEN = 'Your API Key'
而后我們發(fā)起一個(gè)最簡(jiǎn)單的請(qǐng)求,一下內(nèi)容都可以通過例子找到:
ai = apiai.ApiAI(APIAI_TOKEN)
request = ai.text_request()
request.lang = 'zh-CN' # 使用中文
request.session_id = msg.member.puid # api.ai 中用 session id 來區(qū)分對(duì)話對(duì)象,必須
request.query = msg.text # 消息文字內(nèi)容
然后通過接口得到傳回的json:
response = request.getresponse()
s = json.loads(response.read(), encoding='UTF-8') # 講傳回的json轉(zhuǎn)換為python字典
print s
# {u'lang': u'zh-cn', u'status': {u'errorType': u'success', u'code': 200}, u'timestamp': u'20}
我們發(fā)現(xiàn),api.ai傳回的json相對(duì)于圖靈機(jī)器人更加復(fù)雜。參考api.ai的query文檔,我對(duì)對(duì)這部分回復(fù)進(jìn)行了如下處理:
if s['result']['action'] == 'input.unknown': #
raise Exception('api.ai cannot reply this message') # 拋出異常:使用 try 語(yǔ)句捕捉后使用圖靈機(jī)器人回復(fù)
if s['status']['code'] == 200:
msg.reply(s['result']['fulfillment']['speech']) # 回復(fù) api.ai 返回的內(nèi)容
api.ai的設(shè)置和調(diào)試
在進(jìn)入api.ai的機(jī)器人后,你將會(huì)看到左邊的多個(gè)菜單。
如果你只是簡(jiǎn)單的需要特定語(yǔ)句回復(fù)的功能,只需要?jiǎng)?chuàng)建并設(shè)置Intents就可以實(shí)現(xiàn)。在User Says一欄中填寫消息可能是什么,在下方Response處填寫可能回復(fù)的內(nèi)容,然后保存即可。
api.ai自帶機(jī)器學(xué)習(xí)功能,它的參數(shù)可以在機(jī)器人設(shè)置中的ML settings里找到。可以通過調(diào)整參數(shù)和方式讓你的機(jī)器人回復(fù)更加準(zhǔn)確。
在進(jìn)入機(jī)器人后,api.ai的右側(cè)會(huì)出現(xiàn)一個(gè)對(duì)話框。你可以使用它進(jìn)行一些基礎(chǔ)調(diào)試。在上方輸入你的消息后,下方會(huì)給出機(jī)器人的回復(fù),你可以通過這個(gè)對(duì)話框來了解是否正確設(shè)置了機(jī)器人。(需要翻墻)
你可能會(huì)遇到的一些問題
報(bào)錯(cuò):No handlers could be found for logger "wxpy.api.bot"
有報(bào)錯(cuò)但是無法顯示,可以選擇在代碼頭部加入:
import logging
logging.basicConfig()
消息處理:刪除@內(nèi)容
如果不刪除消息中@部分的內(nèi)容,圖靈機(jī)器人的回復(fù)可能會(huì)受到昵稱內(nèi)容的影響,導(dǎo)致回復(fù)不準(zhǔn)確,或是識(shí)別不出一些應(yīng)當(dāng)識(shí)別出的內(nèi)容。我們可以用一段簡(jiǎn)單的代碼刪除@到空格之間的內(nèi)容并去除首尾多余的空格。
content = re.sub('@[^\s]*', '', unicodedata.normalize('NFKC', msg.text)).strip().encode('utf-8')
這里使用了正則表達(dá)式,匹配@以及它之后所有不為空的字符。如果你的微信昵稱中沒有空白字符,這條代碼是可行的。(需要在代碼開頭添加import re
)
機(jī)器人代碼
我的微信機(jī)器人的代碼在GitHub托管,歡迎查看(づ ̄3 ̄)づ╭?~