藉助 Python 的 AIML 包,我們很容易實現人工智慧聊天機器人。AIML 指的是 Artificial Intelligence Markup Language (人工智慧標記語言),它不過是簡單的可 XML (擴充套件標記語言)形式。本文的示例程式碼將帶你初步領略如何藉助 Python 建立屬於你的人工智慧聊天機器人。
AIML 是什麼?
AIML由Richard Wallace發明。他設計了一個名為 A.L.I.C.E. (Artificial Linguistics Internet Computer Entity 人工語言網計算機實體) 的機器人,並獲得了多項人工智慧大獎。有趣的是,圖靈測試的其中一項就在尋找這樣的人工智慧:人與機器人通過文字介面展開數分鐘的交流,以此檢視機器人是否會被當作人類。AIML是一種為了匹配模式和確定響應而進行規則定義的 XML 格式。
關於 AIML 詳細的初級讀物,可翻閱 Alice Bot’s AIML Primer。你同樣可以在 AIML Wikipedia page瞭解更多 AIML 的內容以及它能夠做什麼。我們首先將建立 AIML 檔案,並用 Python 賦予它生命。
建立標準的啟動檔案
建立一個啟動檔案 std-startup.xml 作為讀取AIML檔案的主入口點是標準做法。在這裡,將建立了一個初始檔案用來匹配一種模式和進行一個動作。我們想匹配模式 load aiml b ,並且使它載入我們的 aiml 大腦作為響應。我們將即時建立 basic_chat.aiml 檔案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<aiml version="1.0.1" encoding="UTF-8"> <!-- std-startup.xml --> <!-- <category> 作為AIML的原子級單元 --> <category> <!-- 匹配使用者輸入的模式 --> <!-- 如果使用者輸入 "LOAD AIML B" --> <pattern>LOAD AIML B</pattern> <!-- <Template> 用來響應模式 --> <!-- <learn>是一個aiml檔案 --> <template> <learn>basic_chat.aiml</learn> <!-- 在這下面你能新增更多的aiml檔案 --> <!--<learn>more_aiml.aiml</learn>--> </template> </category> </aiml> |
建立 AIML 檔案
上面我們已經建立了只有一種模式控制程式碼的 AIML 檔案,load aiml b。當我們通過命令列執行這個機器人,它會嘗試讀取 basic_chat.aiml。除非我們已經完成建立,否則載入失敗。下面的示例程式碼將告訴你 basic_chat.aiml 檔案可以加入什麼。我們將匹配兩種基礎的模式和響應。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<aiml version="1.0.1" encoding="UTF-8"> <!-- basic_chat.aiml --> <category> <pattern>HELLO</pattern> <template> Well, hello! </template> </category> <category> <pattern>WHAT ARE YOU</pattern> <template> I'm a bot, silly! </template> </category> </aiml> |
隨機響應
你同樣可以像下面的示例程式碼一樣新增隨機響應。當接收到“One time I”開頭的資訊(message),萬用字元“*”可以進行模糊匹配。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<category> <pattern>ONE TIME I *</pattern> <template> <random> <li>Go on.</li> <li>How old are you?</li> <li>Be more specific.</li> <li>I did not know that.</li> <li>Are you telling the truth?</li> <li>I don't know what that means.</li> <li>Try to tell me that another way.</li> <li>Are you talking about an animal, vegetable or mineral?</li> <li>What is it?</li> </random> </template> </category> |
藉助已有的 AIML 檔案
編寫屬於自己的 AIML 檔案當然充滿樂趣,但工作量也不小。我認為在它(機器人)能感知現實之前至少需要 10,000 中模式。所幸,ALICE基金會已經免費提供了部分 AIML 檔案。Alice Bot website 可瀏覽這些檔案。有一種說法是 std-65-percent.xml 包含了 65% 最常用的短語。還有一種說法是它可以讓你和機器人玩二十一點。
運用 Python
目前為止,所有 XML 格式的 AIML 檔案都準備好了。作為機器人大腦的組成部分,它們都很重要,不過目前它們只是資訊(information)而已。機器人需要活過來。你可以藉助任何語言定製 AIML,但某些好心人已經用 Python 這麼做了。
首先用 pip 安裝 aiml 包。
1 |
pip install aiml |
注意,aiml 包只能在 Python2 環境下執行。也可以選擇 Py3kAiml on GitHub
最簡單的 Python 程式
我們可以用如下最簡單程式入門。它建立了 aiml 類,學習啟動檔案,然後讀取其餘 aiml 檔案。接下來,它已經準備好聊天了,我們也進入了一個不斷提示使用者輸入資訊的死迴圈。你需要輸入一個機器人能識別的模式。模式的識別取決於你載入的 AIML 檔案。
因為我們建立啟動檔案作為獨立實體,所以我們稍後可以對機器人新增更多 aiml 檔案而不需要除錯任何程式的原始碼。只有在 xml 格式的 starup 下,我們才能新增更多檔案。
1 2 3 4 5 6 7 8 9 10 |
import aiml # 建立Kernel()和 AIML 學習檔案 kernel = aiml.Kernel() kernel.learn("std-startup.xml") kernel.respond("load aiml b") # 按組合鍵 CTRL-C 停止迴圈 while True: print kernel.respond(raw_input("Enter your message >> ")) |
加速大腦載入
當你漸漸有了許多 AIML 檔案,機器人就需要很多時間去學習。這就需要大腦檔案的介入了。在機器人學習完所有 AIML 檔案後,它可以直接以檔案形式儲存大腦,再次執行時可以大大提升載入時間。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import aiml import os kernel = aiml.Kernel() if os.path.isfile("bot_brain.brn"): kernel.bootstrap(brainFile = "bot_brain.brn") else: kernel.bootstrap(learnFiles = "std-startup.xml", commands = "load aiml b") kernel.saveBrain("bot_brain.brn") # kernel()已經等待使用了 while True: print kernel.respond(raw_input("Enter your message >> ")) |
執行時過載 AIML
執行時,你可以傳送載入資訊給機器人,接著將會過載 AIML 檔案。注意你是否像上文那樣使用了大腦方式,飛速過載不會造成大腦有新的變化。你要麼刪除大腦檔案,以便下次啟動時重建;要麼修改程式碼,以便過載後的某一時刻能夠儲存大腦。下一節將利用新建 Python 命令來讓機器人執行這些操作。
1 |
load aiml b |
新增 Python 命令
如果你想通過執行 Python 函式來為機器人新增一些特別的命令,那麼你應該在傳送 kernel.respond() 函式前擷取輸入資訊並處理。在上述的例子中,我們藉助 raw_input 函式獲取使用者的輸入。由此我們無論如何都能獲取我們的輸入資訊。可能好似一個 TCP 套接字(socket),或者使聲源轉換成文字源。你也許不想 AIML 處理對於某些資訊。因此在它們傳遞給 AIML 時處理。
1 2 3 4 5 6 7 8 9 |
while True: message = raw_input("Enter your message to the bot: ") if message == "quit": exit() elif message == "save": kernel.saveBrain("bot_brain.brn") else: bot_response = kernel.respond(message) # bot_response() 回覆某些資訊 |
會話和謂詞(Predicates)
通過指定會話,AIML 能根據不同對話者隨機應變。舉個例子,如果某人告訴機器人他們叫 Alice,另一個人則告訴機器人它叫 Bob,機器人可以分清他們。指定你需要的會話,將它作為第二個引數傳遞給 respond()。
1 2 |
sessionId = 12345 kernel.respond(raw_input(">>>"), sessionId) |
和每個客戶都能有個性化的對話——這棒極了。你不得不生成你特有的會話ID並追蹤。記住儲存大腦檔案不要儲存所有的會話值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
sessionId = 12345 # 將會話資訊作為字典 # 包含輸入輸出的歷史像已知謂詞那樣 sessionData = kernel.getSessionData(sessionId) # 每個會話ID需要一個唯一的值 # 用會話中機器人已知的人或事給謂詞命名 # 機器人已經知道你叫"Billy"而你的狗叫"Brandy" kernel.setPredicate("dog", "Brandy", sessionId) clients_dogs_name = kernel.getPredicate("dog", sessionId) kernel.setBotPredicate("hometown", "127.0.0.1") bot_hometown = kernel.getBotPredicate("hometown") |
在AIML中,我們可以在 <template> 項中設定謂詞。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<aiml version="1.0.1" encoding="UTF-8"> <category> <pattern>MY DOGS NAME IS *</pattern> <template> That is interesting that you have a dog named <set name="dog"><star/></set> </template> </category> <category> <pattern>WHAT IS MY DOGS NAME</pattern> <template> Your dog's name is <get name="dog"/>. </template> </category> </aiml> |
通過以上 AIML 你可以告訴機器人:
1 |
My dogs name is Max |
機器人會回答:
1 |
That is interesting that you have a dog named Max |
另外如果問機器人:
1 |
What is my dogs name? |
機器人會這麼回應你:
1 |
Your dog's name is Max. |
其它參考資料
打賞支援我翻譯更多好文章,謝謝!
打賞譯者
打賞支援我翻譯更多好文章,謝謝!
任選一種支付方式