當(dāng)前位置:首頁 > IT技術(shù) > 微信平臺(tái) > 正文

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理
2021-07-25 20:30:25

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理

微信語義理解接口提供從用戶自然語言輸入到結(jié)構(gòu)化解析的技術(shù)實(shí)現(xiàn),使用先進(jìn)的自然語言處理技術(shù)給開發(fā)者提供一站式的語義解析方案。該平臺(tái)覆蓋多個(gè)垂直領(lǐng)域的語義場(chǎng)景,部分領(lǐng)域還可以支持取得最終的展示結(jié)果。開發(fā)者無需掌握語義理解及相關(guān)技術(shù),只需根據(jù)自己的產(chǎn)品特點(diǎn),選擇相應(yīng)的服務(wù)即可搭建一套智能語義服務(wù)。結(jié)合語音識(shí)別接口,通過微信語音識(shí)別得到用戶的語音信息之后,經(jīng)過語義分析理解,得到用戶需求,及時(shí)回復(fù)用戶。本文介紹如何實(shí)現(xiàn)對(duì)微信語義接口的封裝處理,以及一些常用場(chǎng)景的調(diào)用。

微信語義理解接口提供從用戶自然語言輸入到結(jié)構(gòu)化解析的技術(shù)實(shí)現(xiàn),使用先進(jìn)的自然語言處理技術(shù)給開發(fā)者提供一站式的語義解析方案。該平臺(tái)覆蓋多個(gè)垂直領(lǐng)域的語義場(chǎng)景,部分領(lǐng)域還可以支持取得最終的展示結(jié)果。開發(fā)者無需掌握語義理解及相關(guān)技術(shù),只需根據(jù)自己的產(chǎn)品特點(diǎn),選擇相應(yīng)的服務(wù)即可搭建一套智能語義服務(wù)。結(jié)合語音識(shí)別接口,通過微信語音識(shí)別得到用戶的語音信息之后,經(jīng)過語義分析理解,得到用戶需求,及時(shí)回復(fù)用戶。本文介紹如何實(shí)現(xiàn)對(duì)微信語義接口的封裝處理,以及一些常用場(chǎng)景的調(diào)用。

1)微信語義理解接口

這個(gè)東西也就是把我們?nèi)粘5脑捳Z(稱之為自然語言)解析為對(duì)應(yīng)的信息結(jié)構(gòu)體,方便我們提取里面的相關(guān)信息進(jìn)行搜索查詢,并精確回應(yīng)給對(duì)應(yīng)的請(qǐng)求者的一個(gè)橋梁,其主要的功能就是解析我們所說的內(nèi)容。

微信開放平臺(tái)語義理解接口調(diào)用(http請(qǐng)求)簡(jiǎn)單方便,用戶無需掌握語義理解及相關(guān)技術(shù),只需根據(jù)自己的產(chǎn)品特點(diǎn),選擇相應(yīng)的服務(wù)即可搭建一套智能語義服務(wù)。我們來看看微信語義理解接口的定義內(nèi)容。

http請(qǐng)求方式: POST(請(qǐng)使用https協(xié)議)

https://api.weixin.qq.com/semantic/semproxy/search?access_token=YOUR_ACCESS_TOKEN

POST數(shù)據(jù)格式:JSON,POST數(shù)據(jù)例子:

{

"query":"查一下明天從北京到上海的南航機(jī)票",

"city":"北京",

"category": "flight,hotel",

"appid":"wxaaaaaaaaaaaaaaaa",

"uid":"123456"

} 

參數(shù)說明

參數(shù) 是否必須 參數(shù)類型 說明
access_token String 根據(jù)appid和appsecret獲取到的token
query String 輸入文本串
category String 需要使用的服務(wù)類型,多個(gè)用“,”隔開,不能為空
latitude 見接口協(xié)議文檔 Float 緯度坐標(biāo),與經(jīng)度同時(shí)傳入;與城市二選一傳入
longitude 見接口協(xié)議文檔 Float 經(jīng)度坐標(biāo),與緯度同時(shí)傳入;與城市二選一傳入
city 見接口協(xié)議文檔 String 城市名稱,與經(jīng)緯度二選一傳入
region 見接口協(xié)議文檔 String 區(qū)域名稱,在城市存在的情況下可??;與經(jīng)緯度二選一傳入
appid String 公眾號(hào)唯一標(biāo)識(shí),用于區(qū)分公眾號(hào)開發(fā)者
uid String 用戶唯一id(非開發(fā)者id),用戶區(qū)分公眾號(hào)下的不同用戶(建議填入用戶openid),如果為空,則無法使用上下文理解功能。appid和uid同時(shí)存在的情況下,才可以使用上下文理解功能。

注:?jiǎn)晤悇e意圖比較明確,識(shí)別的覆蓋率比較大,所以如果只要使用特定某個(gè)類別,建議將category只設(shè)置為該類別。

返回說明 正常情況下,微信會(huì)返回下述JSON數(shù)據(jù)包:

{ 

“errcode”:0, 

“query”:”查一下明天從北京到上海的南航機(jī)票”, 

“type”:”flight”, 

“semantic”:{ 

    “details”:{

        “start_loc”:{ 

            “type”:”LOC_CITY”, 

            “city”:”北京市”, 

            “city_simple”:”北京”, 

            “l(fā)oc_ori”:”北京” 

            }, 

        “end_loc”: { 

            “type”:”LOC_CITY”, 

            “city”:”上海市”, 

            “city_simple”:”上?!? 

            “l(fā)oc_ori”:”上?!?

          }, 

        “start_date”: { 

            “type”:”DT_ORI”, 

            “date”:”2014-03-05”, 

            “date_ori”:”明天” 

          }, 

       “airline”:”中國(guó)南方航空公司” 

    }, 

“intent”:”SEARCH” 

}

?

返回參數(shù)說明

參數(shù) 是否必須 參數(shù)類型 說明
errcode Int 表示請(qǐng)求后的狀態(tài)
query String 用戶的輸入字符串
type String 服務(wù)的全局類型id,詳見協(xié)議文檔中垂直服務(wù)協(xié)議定義
semantic Object 語義理解后的結(jié)構(gòu)化標(biāo)識(shí),各服務(wù)不同
result Array 部分類別的結(jié)果
answer String 部分類別的結(jié)果html5展示,目前不支持
text String 特殊回復(fù)說明

上面就是微信官方給出的代碼案例,以及一個(gè)《語義理解接口協(xié)議文檔》,里面介紹了各個(gè)場(chǎng)景的語義結(jié)構(gòu)信息,雖然這個(gè)文檔好像好久都沒怎么更新,不過總體內(nèi)容還是穩(wěn)定的,我們可以通過這個(gè)文檔進(jìn)行相關(guān)的類庫設(shè)計(jì)工作。

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理_微信公眾平臺(tái)及門戶應(yīng)用

?

2、語義理解接口的C#實(shí)現(xiàn)

根據(jù)《語義理解接口協(xié)議文檔》文檔,我們可以定義各種所需的語義結(jié)構(gòu)類庫,這些是我們開展語義接口的基礎(chǔ)類。

例如我們定義基礎(chǔ)的時(shí)間協(xié)議類,如下所示。

    /// <summary>
    /// 時(shí)間相關(guān)協(xié)議datetime
    /// </summary>
    public class Semantic_DateTime
    {
        /// <summary>
        /// 單時(shí)間的描述協(xié)議類型:“DT_SINGLE”。DT_SINGLE又細(xì)分為兩個(gè)類別:DT_ORI和DT_INFER。DT_ORI是字面時(shí)間,比如:“上午九點(diǎn)”;
        /// DT_INFER是推理時(shí)間,比如:“提前5分鐘”。 時(shí)間段的描述協(xié)議類型:“DT_INTERVAL”
        /// 重復(fù)時(shí)間的描述協(xié)議類型:“DT_REPEAT”  DT_ REPEAT又細(xì)分為兩個(gè)類別:DT_RORI和DT_RINFER。DT_RORI是字面時(shí)間,比如:“每天上午九點(diǎn)”;DT_RINFER是推理時(shí)間,比如:“工作日除外”
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 24小時(shí)制,格式:HH:MM:SS,默認(rèn)為00:00:00
        /// </summary>
        public string time { get; set; }
        /// <summary>
        /// Time的原始字符串
        /// </summary>
        public string time_ori { get; set; }
    }

    /// <summary>
    /// 單時(shí)間的描述協(xié)議datetime
    /// </summary>
    public class Semantic_SingleDateTime : Semantic_DateTime
    {
        /// <summary>
        /// 格式:YYYY-MM-DD,默認(rèn)是當(dāng)天時(shí)間
        /// </summary>
        public string date { get; set; }

        /// <summary>
        /// 格式:YYYY-MM-DD 農(nóng)歷
        /// </summary>
        public string date_lunar { get; set; }

        /// <summary>
        /// date的原始字符串
        /// </summary>
        public string date_ori { get; set; }
    }

當(dāng)然時(shí)間還有很多類型的定義,都基本上按照文檔所列的字段進(jìn)行處理,上面的代碼只是定義了常用的單時(shí)間的描述協(xié)議類型:“DT_SINGLE”。

除了時(shí)間協(xié)議,還有數(shù)字,地點(diǎn)位置等相關(guān)協(xié)議,如數(shù)字協(xié)議如下所示。

    public class Semantic_Number
    {
        /// <summary>
        /// 大類型:“NUMBER”  NUMBER又細(xì)分為如下類別:NUM_PRICE、NUM_PADIUS、NUM_DISCOUNT、NUM_SEASON、NUM_EPI、NUM_CHAPTER。
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 開始
        /// </summary>
        public string begin { get; set; }
        /// <summary>
        /// 結(jié)束
        /// </summary>
        public string end { get; set; }
    }

地點(diǎn)位置協(xié)議如下所示

    /// <summary>
    /// 地點(diǎn)相關(guān)協(xié)議
    /// </summary>
    public class Semantic_Location
    {      
        /// <summary>
        /// 大類型:“LOC”  LOC又細(xì)分為如下類別:LOC_COUNTRY、LOC_PROVINCE、LOC_CITY、LOC_TOWN、LOC_POI、NORMAL_POI。
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 國(guó)家
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string country { get; set; }
        /// <summary>
        /// 省全稱,例如:廣東省
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string province { get; set; }
        /// <summary>
        /// 省簡(jiǎn)稱,例如:廣東|粵
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string province_simple { get; set; }
        /// <summary>
        /// 市全稱,例如:北京市
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string city { get; set; }
        /// <summary>
        /// 市簡(jiǎn)稱,例如:北京
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string city_simple { get; set; }

         ..............

前面我們看到了,語音立即的POST數(shù)據(jù)格式是一個(gè)較為固定的格式內(nèi)容,我們可以把它定義為一個(gè)類,方便數(shù)據(jù)處理。

POST數(shù)據(jù)格式:JSON,POST數(shù)據(jù)例子如下所示:

{

"query":"查一下明天從北京到上海的南航機(jī)票",

"city":"北京",

"category": "flight,hotel",

"appid":"wxaaaaaaaaaaaaaaaa",

"uid":"123456"

} 

那么我們可以定義它的類庫如下所示。

    /// <summary>
    /// 語義查詢條件
    /// </summary>
    public class SemanticQueryJson
    {
        /// <summary>
        /// 輸入文本串
        /// 必填
        /// </summary>
        public string query { get; set; }

        /// <summary>
        /// 需要使用的服務(wù)類別,多個(gè)用,隔開,不能為空
        /// 必填
        /// </summary>
        public string category { get; set; }

        /// <summary>
        /// 城市名稱,與經(jīng)緯度二選一傳入
        /// 見說明,選填
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string city { get; set; }

        /// <summary>
        /// App id,開發(fā)者的唯一標(biāo)識(shí),用于區(qū)分開放者,如果為空,則沒法使用上下文理解功能。
        /// 非必填
        /// </summary>
        public string appid { get; set; }

        /// <summary>
        /// 用戶唯一id(并非開發(fā)者id),用于區(qū)分該開發(fā)者下不同用戶,如果為空,則沒法使用上下文理解功能。appid和uid同時(shí)存在的情況下,才可以使用上下文理解功能。
        /// 非必填
        /// </summary>
        public string uid { get; set; }

        ................
    }

接著我們分析語義理解的接口返回值,它們基本上都是很有規(guī)律的內(nèi)容,如下所示。

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理_微信公眾平臺(tái)及門戶應(yīng)用_02

這樣我們也就可以定義一個(gè)通用的類庫對(duì)象,用來存儲(chǔ)不同的返回內(nèi)容了,如下代碼所示。

    /// <summary>
    /// 微信語義結(jié)果
    /// </summary>
    public class SemanticResultJson<T> : ErrorJsonResult
    {
        /// <summary>
        /// 用戶的輸入字符串
        /// </summary>
        public string query { get; set; }
        /// <summary>
        /// 服務(wù)的全局類別id
        /// </summary>
        public string type { get; set; }

        /// <summary>
        /// 語義理解后的結(jié)構(gòu)化標(biāo)識(shí),各服務(wù)不同
        /// </summary>
        public T semantic { get; set; }
    }

而其中的T semantic就是另外一個(gè)結(jié)構(gòu)體里面的內(nèi)容,這個(gè)結(jié)構(gòu)體總體也是固定的內(nèi)容,我們繼續(xù)定義一個(gè)如下的類。

    /// <summary>
    /// 詳細(xì)信息里面的對(duì)象
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SemanticDetail<T>
    {
        /// <summary>
        /// 詳細(xì)信息
        /// </summary>
        public T details { get; set; }

        /// <summary>
        /// 查詢類型
        /// </summary>
        public string intent { get; set; }
    }

有了這些類庫的支持,我們可以封裝語義理解接口的返回值了,這樣它的接口定義和封裝處理代碼如下所示。

    /// <summary>
    /// 語意理解接口
    /// 微信開放平臺(tái)語義理解接口調(diào)用(http請(qǐng)求)簡(jiǎn)單方便,用戶無需掌握語義理解及相關(guān)技術(shù),只需根據(jù)自己的產(chǎn)品特點(diǎn),選擇相應(yīng)的服務(wù)即可搭建一套智能語義服務(wù)。
    /// </summary>
    public class SemanticApi : ISemanticApi
    {
        /// <summary>
        /// 發(fā)送語義理解請(qǐng)求
        /// </summary>
        /// <param name="accessToken">調(diào)用接口憑證</param>
        /// <param name="data">查詢條件</param>
        public SemanticResultJson<SemanticDetail<T>> SearchSemantic<T>(string accessToken, SemanticQueryJson data)
        {
            var url = string.Format("https://api.weixin.qq.com/semantic/semproxy/search?access_token={0}", accessToken);
            string postData = data.ToJson();

            return JsonHelper<SemanticResultJson<SemanticDetail<T>>>.ConvertJson(url, postData);
        }

由于微信語義結(jié)果是針對(duì)不同的服務(wù)協(xié)議,我們需要根據(jù)這些不同的服務(wù)協(xié)議,來定義屬于這些信息結(jié)構(gòu),如在文檔里,我們可以看到有很多不同類型的服務(wù)協(xié)議。

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理_微信公眾平臺(tái)及門戶應(yīng)用_03

根據(jù)文檔的詳細(xì)字段說明,我們可以定義不同服務(wù)的對(duì)應(yīng)類庫。

例如對(duì)于旅游服務(wù)的語義理解,它們的協(xié)議類如下所示。

    /// <summary>
    /// 旅游服務(wù)(travel)
    /// </summary>
    public class Semantic_Details_Travel
    {
        /// <summary>
        /// 旅游目的地
        /// </summary>
        public Semantic_Location location { get; set; }
        /// <summary>
        /// 景點(diǎn)名稱
        /// </summary>
        public string spot { get; set; }
        /// <summary>
        /// 旅游日期
        /// </summary>
        public Semantic_SingleDateTime datetime { get; set; }
        /// <summary>
        /// 旅游類型詞
        /// </summary>
        public string tag { get; set; }
        /// <summary>
        /// 0默認(rèn),1自由行,2跟團(tuán)游
        /// </summary>
        public int category { get; set; }
    }

那么調(diào)用的旅游語義的案例代碼如下所示

            var api = new SemanticApi();
            var json = new SemanticQueryJson
            {
                appid = appId,
                uid = openId,
                category = SemanticCategory.travel.ToString(),
                query = "故宮門票多少錢",
                city = "北京市"
            };

            var travel = api.SearchSemantic<Semantic_Details_Travel>(token, json);
            Console.WriteLine(travel.ToJson());

如果我們測(cè)試,上面的代碼跑起來會(huì)返回一個(gè)旅游的協(xié)議對(duì)象,包括了相關(guān)的數(shù)據(jù)信息。

{
   "errcode" : 0,
   "query" : "故宮門票多少錢",
   "semantic" : {
      "details" : {
         "answer" : "",
         "context_info" : {},
         "hit_str" : "故宮 門票 多少 錢 ",
         "spot" : "故宮"
      },
      "intent" : "PRICE"
   },
   "type" : "travel"
}

我們?cè)賮砜匆粋€(gè)例子,例如對(duì)于航班服務(wù),我們定義它的語義理解協(xié)議如下所示。

    /// <summary>
    /// 航班服務(wù)(flight)
    /// </summary>
    public class Semantic_Details_Flight
    {
        /// <summary>
        /// 航班號(hào)
        /// </summary>
        public string flight_no { get; set; }
        /// <summary>
        /// 出發(fā)地
        /// </summary>
        public Semantic_Location start_loc { get; set; }
        /// <summary>
        /// 目的地
        /// </summary>
        public Semantic_Location end_loc { get; set; }
        /// <summary>
        /// 出發(fā)日期
        /// </summary>
        public Semantic_SingleDateTime start_date { get; set; }
        /// <summary>
        /// 返回日期
        /// </summary>
        public Semantic_SingleDateTime end_date { get; set; }
        /// <summary>
        /// 航空公司
        /// </summary>
        public string airline { get; set; }
        /// <summary>
        /// 座位級(jí)別(默認(rèn)無限制):ECONOMY(經(jīng)濟(jì)艙)BIZ(商務(wù)艙)FIRST(頭等艙)
        /// </summary>
        public string seat { get; set; }
        /// <summary>
        /// 排序類型:0排序無要求(默認(rèn)),1價(jià)格升序,2價(jià)格降序,3時(shí)間升序,4時(shí)間降序
        /// </summary>
        public int sort { get; set; }
    }

那么調(diào)用獲取語義理解內(nèi)容的代碼如下所示。

            json = new SemanticQueryJson
            {
                appid = appId,
                uid = openId,
                category = SemanticCategory.flight.ToString(),
                query = "查一下明天從廣州到上海的南航機(jī)票",
                city = "廣州"
            };
            var flight = api.SearchSemantic<Semantic_Details_Flight>(token, json);
            Console.WriteLine(flight.ToJson());

我們可以獲取到的JSON數(shù)據(jù)如下所示

{
   "errcode" : 0,
   "query" : "查一下明天從廣州到上海的南航機(jī)票",
   "semantic" : {
      "details" : {
         "airline" : "中國(guó)南方航空公司",
         "answer" : "已幫您預(yù)定2016-04-13,從廣州市出發(fā),前往上海市的航班。",
         "context_info" : {
            "isFinished" : "1",
            "null_times" : "0"
         },
         "end_loc" : {
            "city" : "上海市",
            "city_simple" : "上海|滬|申",
            "loc_ori" : "上海",
            "modify_times" : "0",
            "slot_content_type" : "2",
            "type" : "LOC_CITY"
         },
         "hit_str" : "查 一下 明天 從 廣州 到 上海 南航 機(jī)票 ",
         "sort" : "1",
         "start_date" : {
            "date" : "2016-04-13",
            "date_lunar" : "2016-03-07",
            "date_ori" : "明天",
            "modify_times" : "0",
            "slot_content_type" : "2",
            "type" : "DT_ORI",
            "week" : "3"
         },
         "start_loc" : {
            "city" : "廣州市",
            "city_simple" : "廣州",
            "loc_ori" : "廣州",
            "modify_times" : "0",
            "province" : "廣東省",
            "province_simple" : "廣東|粵",
            "slot_content_type" : "2",
            "type" : "LOC_CITY"
         }
      },
      "intent" : "SEARCH"
   },
   "type" : "flight"
}

這樣就是我們把我們常規(guī)的語義,分析成了機(jī)器可以識(shí)別的準(zhǔn)確的數(shù)據(jù)結(jié)構(gòu)了,我們可以根據(jù)不同的語義場(chǎng)合對(duì)它進(jìn)行分析,然后給用戶進(jìn)行不同的響應(yīng)就可以了,結(jié)合微信語音識(shí)別為文本內(nèi)容,我們可以把它做得很強(qiáng)大,有的類似機(jī)器智能的味道了。

微信語義理解是一個(gè)好東西,不過在微信官網(wǎng)上沒有看到進(jìn)一步的案例,如果能夠有一些與實(shí)際結(jié)合的例子,估計(jì)更能幫助我們理解和應(yīng)用了。

?

C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理_微信公眾平臺(tái)及門戶應(yīng)用_04主要研究技術(shù):代碼生成工具、會(huì)員管理系統(tǒng)、客戶關(guān)系管理軟件、病人資料管理軟件、Visio二次開發(fā)、酒店管理系統(tǒng)、倉庫管理系統(tǒng)等共享軟件開發(fā)
專注于Winform開發(fā)框架/混合式開發(fā)框架、Web開發(fā)框架、Bootstrap開發(fā)框架、微信門戶開發(fā)框架的研究及應(yīng)用。
??轉(zhuǎn)載請(qǐng)注明出處:
C#開發(fā)微信門戶及應(yīng)用(31)--微信語義理解接口的實(shí)現(xiàn)和處理_微信公眾平臺(tái)及門戶應(yīng)用_04撰寫人:伍華聰?

本文摘自 :https://blog.51cto.com/w

開通會(huì)員,享受整站包年服務(wù)立即開通 >