如何使用OLAMI自然語言理解開放平臺API製作自己的智能對話助手小程式

来源:http://www.cnblogs.com/huangmeimao/archive/2017/07/18/7203097.html
-Advertisement-
Play Games

告訴你如何使用OLAMI自然語言理解開放平臺API製作自己的智能對話助手 我們經常在電影中看到機器和人對答如流,隨著越來越多自然語言開放平臺的出現,IT愛好者製作一個自己的APP或者小玩具等逐漸可以變為現實。 自然語言對話即你的APP或者你製作的工具、機器人等能夠對用戶輸入的語音或者文字做... ...


我們經常在電影中看到機器和人對答如流,隨著越來越多自然語言開放平臺的出現,IT愛好者製作一個自己的APP或者小玩具等逐漸可以變為現實。
自然語言對話即你的APP或者你製作的工具、機器人等能夠對用戶輸入的語音或者文字做出準確的回應。

比如,在微信公眾號中,經常要求用戶通過輸入1、2或者其他關鍵字來獲取相應的服務,而對於句子卻無法正確理解。比如,你輸入“中秋活動”,這個幾個字如果符合關鍵字的要求,那就會彈出相應的服務。但如果你輸入的是“我想參加今年的中秋活動”,“參加中秋活動”等可能就無法進入活動網頁了。

再比如,很多智能玩具,你只能跟它進行簡單的對話,因為它也是只能抓取簡單的關鍵字。

實際上,我們希望的是做到像許多語音助手一樣,能夠正確識別用戶說的話,並做出對應回覆,甚至希望能夠理解上下文。

比如,用戶問:今天上海的天氣

應用回答:今天上海的天氣為。。。。。

如果用戶接著問: 那北京呢

你的應用能直接回答:今天北京的天氣。。。。。

而不需要輸入完整的句子“今天北京的天氣”。

目前提供智能語音語義理解的API介面不少,使得自己製作語義語音小助手成為現實。各開放平臺的情況可以看我的另一篇博客:熱門自然語言理解和語音API開發平臺對比

我選擇了歐拉蜜人工智慧開放平臺來完成我的快遞小助手。

要使用OLAMI開放平臺首先要了平臺的提供的功能和我們需要做的事情
我使用微信小程式開發工具寫了一個工具類的小程式,可以參考我的另一篇博客 微信小程式+OLAMI自然語言API介面製作智能查詢工具--快遞、聊天、日曆等

代碼下載 CSDN代碼

語法文件下載CSDN語法文件下載
代碼測試和體驗
智能生活寶小助手

下圖簡單描述了OLAMI語言理解開放平臺的工作過程,我們要做的工作其實就是圖中紅色的標誌1和標誌2,即寫語法和寫自己的應用程式。而你的應用程式用戶只需要輸入想說的話,即自然語言句子,就可以得到你的應用程式處理的結果。

OLAMI語義理解流程圖
************

一.瞭解幾個關鍵詞的含義

  1. 語法,我的理解就是描述自然語言句子的一套規則,看官方文檔也確實是這樣。比如:“幫我查個快遞”,你用一堆符號描述出來,這個組合起來的符號就叫語法。
  2. 自然語言,也叫語料。這個不用多說,我們平時說的話是什麼,那就是什麼。
  3. 語料的有效信息,即輸入的句子中包含的關鍵信息,你的應用程式獲取到這些這些關鍵信息之後,可以做相應的處理。比如:‘請你幫我查個快遞’,其實這句話隱藏的含義是“查快遞”,其他的辭彙信息不需要關心。
  4. Answer---這個在OLAMI平臺中指你寫的語法的預設回覆,不需要應用程式做深度處理的,這個暫時可以忽略。
  5. 應用程式----這就是你自己的APP了。
  6. 結果----就是用戶輸入一句話,你的APP回覆結果。比如,用戶輸入’查快遞1234’,你應該回覆‘1234這個快遞的物流信息’。再比如“今天的天氣”,你應該列出今天的天氣狀況,而不是昨天的天氣,也不是今天的日期。

二 寫語法

   調用API介面之前,首先要寫自己的語法,也就是你要支持哪些句子,當然你也可以直接使用OLAMI平臺提供的內置語法,如果它的語法符合你的要求的話。在這裡,我說說怎麼寫自己的語法。

  1. 首先在官網上註冊,然後進入開發系統中“我的應用”。

應用界面

2.確定自己的模塊

   在正式寫語法之前,首先得弄明白怎麼寫語法,寫什麼樣的語法。

   第一步得選擇你的應用程式支持的模塊,比如是查天氣、播放音樂、還是智能家控制。
這個模塊,其實可以稱之為領域,因為你不可能把人類所有的語言都涵蓋,你的APP一般都是針對某個或者某幾個領域。我選擇的是快遞APP。所以我要支持的都是快遞的說法。

   確定好模塊之後,你要思考一下你的應用程式希望從用戶的說法中得到哪些有用信息,以及用戶會有哪些操作。比如快遞查詢,我需要有“運單號”,“快遞公司名稱”這兩個有效信息,另外,我的應用程式僅提供快遞的查詢業務。

   我大致知道如果用戶說“幫我查一下圓通快遞12344”的時候,包含的有效信息很全,我可以直接輸出物流信息給他。但如果用戶僅僅說“我想查快遞”,這時他僅表達了想查的意願,我的應用程式應該提示用戶輸入快遞單號。

   在OALMI的語法中,使用”Slot”來抓取有效信息,它就像一個函數的參數,它的內容由用戶決定。比如運單號和快遞公司名稱,每個用戶的內容都是不同的。
   因此進入OLAMI的NLI系統之後,我首先“新增”一個模塊,名字為”expressage”,然後進入這個模塊開始寫語法。

3.確定有效信息Slot

   就如上面所述,我需要“運單號”和“快遞公司名稱”這兩個關鍵信息,因此,我定義了”expnumber”和”expname”這兩個Slot.

   我選擇的類型均為’ext’,因為用戶有可能會直接輸入運單號,而運單號的格式無法確定,所以我選擇ext來抓取。
    快遞公司的名稱也是有限的,其實選擇internal格式的就可以了,但是我選擇後面通過ext賦值的方式給slot賦值,這樣有利於語法維護。(很拗口是吧?可以暫時不管)

4.確認APP的功能

    你的APP準備提供什麼功能呢?查詢?顯示?打開?關閉?OLAMI語法需要用Modifier來描述操作信息。其實也就是一個標誌來告訴應用程式這句話的意圖是什麼。
比如“打開燈”,意圖是打開,可以定義一個modifier “open”.
“打開空調”的意圖同樣是打開,你只要用沿用已經定義的“open”即可。
我的快遞APP很簡單,我就是提供查詢功能,因此我定義一個global modifier ‘query’.

5.瞭解Grammar,Rule,Template.

   其實剛開始只要知道Grammar和Rule就可以了。

   Rule即同義辭彙的集合,辭彙之間用’|’隔開,表示或的關係。

   Grammar即描述你要匹配的句子的語法。

   比如你希望匹配句子”查詢快遞”,可以將“查詢”的同義詞定義一個Rule, “快遞”同義辭彙定義一個Rule,我建議名稱能使用中文就使用中文,這樣看起來比較直觀。下表中是可以匹配”查詢快遞”這句話的Grammar相關定義。
***

名稱 類型 內容
查詢_動詞 Rule 查詢\
快遞_名詞 Rule 快遞\
expname Ext Slot
expnumber Ext Slot
查快遞1 Grammar <查詢_動詞><快遞_名詞>{@=query}
查快遞_名稱_運單號1 Grammar <查詢_動詞>< expname ><快遞_名詞>{@=query_name_num}

   你在寫Grammar之前要確保Grammar中需要的Rule,Slot,Template已經定義好,並且想好自己的操作modifier.
   每寫好一個Grammar可以通過“例句測試”檢查你要支持的句子是不是被當前的Grammar匹配,這個Grammar希望支持的句子都包含進去了,你再提交,然後發佈。
發佈之後你才能通過API介面進行訪問。

三 開發自己的APP

  1. 你需要從語義理解API介面獲取什麼信息?

   https的返回,比如status就不再介紹了。

   說白了,開發平臺解析你的語法之後,就是會告訴你這句話中的Slot和modifier,以及你的模塊名稱。
   Slot根據你選擇的類型不同,你獲取的內容不同。比如ext類型的,你可以拿到slot的名稱和slot的值。

   Datetime類型,即你的Slot是時間,你還可以拿到時間的毫秒數,起始時間等。

   Number類型,表示你只會抓取數字,會得到數字的計算值等。

   Modifier就是你自己定義的要支持的操作,只要按照他們規定的格式命名就好。

   2.創建應用

   應用可以包含多個模塊,具體包含哪些模塊也是由你自己決定。OLAMI預設支持了“聊天”,“百科”,“查詢日期”三個模塊。如果你不需要可以去掉。內置模塊的說明見

   點擊下圖中的配置模塊添加自己寫的模塊和你希望添加的內置模塊。比如對話系統模塊中的nonsense就是聊天用的。你可以點配置模塊右邊的”測試”,輸入要查詢的句子就可以看到結果。

   如果測試結果能正確返回,就表明API介面也可以獲取同樣的結果。

   比如我在輸入框中“查快遞”就可以看到JSON格式的輸出,如下圖顯示:

3.查看應用的key

   這個key就是你訪問API 介面的鑰匙,在你的應用中點擊”查看key”就可以看到了。

4.訪問自然語言解析API介面

   API介面是https協議,相關說明,我就不再贅述了。

   我使用的是小程式訪問,相關代碼如下,你代碼下載包的input.js里可以看到:

function parseCorpus(corpus,object) {
    var usekey = Appkey;
    var usesecret = Appsecret;
    if (object.data.dialogtype == chat_type){
    usekey = ChatAppkey;
    usesecret = ChatAppsecret;
    }

  //獲取sign的MD5值
  object.setData({
    text: '請稍後......'
  })
  var timestamp = new Date().getTime();

  var originalSign = usesecret + "api=" + api + "appkey=" + usekey + "timestamp=" + timestamp + usesecret;
  var sign = MD5.md5(originalSign);

  var rqdata = { "data": { "input_type": 1, "text": corpus }, "data_type": "stt" };
  console.log(JSON.stringify(rqdata))
  console.log('\r\n')
  wx.request({
    url: requestUrl,
    data: {
      appkey: usekey,
      api: api,
      timestamp: timestamp,
      sign: sign,
      rq: JSON.stringify(rqdata),
      cusid: userId,
      changebuttoncolor: "#d0e0e3"
    },
    header: {
      'content-type': 'application/x-www-form-urlencoded'
    },
    method: 'POST',
    success: function (result) {
      var data = result.data.data;
      if (result.data != null && result.data.status!=null&&result.data.status=='ok'){
        HandleOLAMIresponseData(data.nli[0], corpus, object);
        console.log('歐拉蜜有效數據', result.data);
      }else{
        console.log('歐拉蜜返回失敗', result.data.status);       
        object.setData({
          text: API_data_error
        })
      }
    },

    fail: function ({errMsg}) {
      console.log('request fail', errMsg)
      object.setData({
        text: API_data_error
      })
    }
  })


};
  1. 根據獲取到的Semantics內容提供服務

我的處理邏輯是根據不同的modifier進行相應的操作,不同的操作下又要檢查slot,代碼如下:

    function HandleOLAMIresponseData(data, corpus, object)
    {
         var textData='';  //text文本框要show的內容
         var semantics = data.semantic;
         if (semantics == null || semantics.length==0){
           if (data.desc_obj.result != null && data.desc_obj.result.length != 0 && data.desc_obj.status==0)  {
             if (data.type == 'joke' || data.type == 'cooking'){
               textData = data.data_obj[0].content;
             }else
               textData = data.desc_obj.result;
    
           }else
              textData='抱歉,我還理解不了你說的話。';
           object.setData({
             expresshead: '',
             text: textData
           })
           
         }else {
    
           for (var i = 0; i < semantics.length; i++) {
             var tempSem = data.semantic[0];
             if (tempSem.app == expressAPPname) { //僅處理快遞模塊的語義
               //處理modifier
               var mods = tempSem.modifier;
               if (mods.indexOf("query") > -1)
                 expAppinfo.OPT = OPT_QUERY;
               else if (mods.indexOf("query_num") > -1)
                 expAppinfo.OPT = OPT_QUERY_NUM;
               else if (mods.indexOf("query_name") > -1)
                 expAppinfo.OPT = OPT_QUERY_NAME;
               else if (mods.indexOf("query_name_num") > -1)
                 expAppinfo.OPT = OPT_QUERY_NUM_NAME;
    
               //獲取slots,即快遞公司名稱和運單號
               var slots = tempSem.slots;
               if (slots != null) {
                 for (var j = 0; j < slots.length; j++) {
                   var tempslot = slots[j];
                   if (tempslot.name == expNumSlotName) { //運單號
                     var numslot = new APPSlot();
                     numslot.name = expNumSlotName;
                     numslot.value = tempslot.value;
                     expAppinfo.numSlot = numslot;
                   } else if (tempslot.name == expNameSlotName) {//快遞名稱
                     var nameslot = new APPSlot();
                     nameslot.name = expNumSlotName;
                     nameslot.value = tempslot.value;
                     expAppinfo.nameSlot = nameslot;
                   }
    
                 }
    
               }
               //handle Operations
               switch (expAppinfo.OPT) {
          
                 case OPT_QUERY:
                   textData = '請提供您的運單編號。';
                   object.setData({
                     expresshead: '',
                     text: textData
                   })
                   break;
                 case OPT_QUERY_NUM:
                 //檢測是否存在快遞名稱
                   if (expAppinfo.nameSlot != null && expAppinfo.numSlot != null){ //採用快遞編號+快遞公司方式查詢
                     //獲取快遞公司名稱
                     var expname = getExpCode(expAppinfo.nameSlot.value);
                     var expcode = expCodes[expname];
                     queryExpress.queryExpress(expname,expcode, expAppinfo.numSlot.value, object);
                   } else if (expAppinfo.numSlot != null){
                      //用運單編號查詢
                     queryExpress.queryEXPbyNum(expAppinfo.numSlot.value, object);
                   }
                   resetExpInfo(object);
                   break;
                 case OPT_QUERY_NAME:
                   textData = '請提供您的運單編號。';
                   object.setData({
                     expresshead: '',
                     text: textData
                   })
                   break;
                 case OPT_QUERY_NUM_NAME:
                   if (expAppinfo.nameSlot != null && expAppinfo.numSlot != null) { //採用快遞編號+快遞公司方式查詢
                     //獲取快遞公司名稱
                     var expname = getExpCode(expAppinfo.nameSlot.value);
                     var expcode = expCodes[expname];
                     queryExpress.queryExpress(expname,expcode, expAppinfo.numSlot.value, object);
                   }
                   resetExpInfo(object);
                   break;
               }
    
               break;
    
             }
           }
         }
         
         
    
    }
    

   至此,OLAMI API 介面的基本調用工作已經完成,至於你要添加語言識別,語法完善,模塊添加等就看自己的需求了。

   最後說一下語法文件.osl下載之後如何導入。你創建好模塊之後,直接選擇上傳OSL文件即可



優秀自然語言理解博客文章推薦:

微信小程式+OLAMI自然語言API介面製作智能查詢工具--快遞、聊天、日曆等

根據OLAMI平臺開發的日曆Demo

用olami開放語義平臺做匯率換算應用

自然語言處理-實際開發:用語義開放平臺olami寫一個翻譯的應用

自定義java.awt.Canvas—趣味聊天

熱門自然語言理解和語音API開發平臺對比

使用OLAMI SDK和訊飛語音合成製作一個語音回覆的簡訊小助手


推薦自然語言理解愛好者博客:

http://blog.csdn.net/huangmeimao

http://blog.csdn.net/u011211290

http://blog.csdn.net/u011827504

http://blog.csdn.net/xinfinityx

http://blog.csdn.net/speeds3

http://blog.csdn.net/happycxz


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 原文鏈接:https://mp.weixin.qq.com/s?__biz=MzI0ODcxODk5OA==&mid=2247487055&idx=2&sn=ca0fe8740b78deb208c82eea73d56b37 誰會成為AI 和大數據時代的第一開發語言?這本已是一個不需要爭論的問題。如果 ...
  • 原文鏈接 http://www.envicloud.cn/pages/news/418.html 4 前段時間,ThoughtWorks在深圳舉辦一次社區活動上,有一個演講主題叫做“Fullstack JavaScript”,是關於用JavaScript進行前端、伺服器端,甚至資料庫(MongoDB ...
  • Python編程核心技術之正則表達式(regex) 一.正則表達式簡介 正則表達式(regex)為高級的文本模式匹配、抽取、與/或文本形式的搜索和替換功能提供了基礎。簡單的來說正則表達式是一些由字元和特殊符號組成的字元串,他們描述了模式的重覆或者表述多個字元,於是正則表達式能夠按照某種模式匹配一系列 ...
  • 1 概述 1 概述 本章敘述面向向對象設計的七大原則,七大原則分為:單一職責原則、開閉原則、里氏替換原則、依賴倒置原則、介面隔離原則、合成/聚合復用原則、迪米特法則。 2 七大OO面向對象設計 2 七大OO面向對象設計 2.1 單一職責原則SRP(Simple Responsibility Prin ...
  • 今天遇到一個坑,具體的不多說,直接上代碼 我預期的 arr 的結果應該是 最後arr的結果居然是這樣的 在一個基友群里問,最後終於自己得出結論了——這是因為值類型和引用類型不同的原因。 在JavaScript里的值大概分為兩種,一種是值類型,一種是引用類型。 值類型:數值、布爾值、null、unde ...
  • [1]引入 [2]概述 [3]索引設置 [4]索引種類 [5]全文索引 [6]地理位置索引 ...
  • 一.概述:jQuery是一個快速、簡潔的JavaScript框架,是繼Prototype之後又一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是“write Less,Do More”,即倡導寫更少的代碼,做更多的事情。它封裝JavaScript常用的功能代 ...
  • 今天接著說test8的頁面還原。 頭部header和尾部footer 我一開始是想直接使用bootstrap的柵格系統來實現的。但是內容的定位出了不少麻煩。 那麼就索性用原生html+css來還原頁面了。 放上效果圖 頭部html代碼 尾部html代碼 css代碼 友情鏈接的模塊就比較簡單的還原了( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...