IBM Watson Conversationサービスの初心者向け講座 (3.5) 番外編: workspace JSONを見てみる

[IBM Watson Conversationサービスの初心者向け講座 (3) Dialog におけるcontextの扱い](https://qiita.com/yamachan360/items/e332e9a9ea5f850bc239) 投稿の番外編です。

IBM Watson Conversationサービスで作成したサンプルを、ダッシュボードからJSON形式でダウンロードしたものです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/7b3567d2-915b-d5c9-dc69-78b1b7e1881b.png)

IBM Watson Conversationサービスの内部データ構造に興味がある、ごく一部の方に向けた投稿です。より深く動作を理解するために。需要はないかも、ですが、まあ自分で後で参照すると思うので。

## 対象アプリ

[IBM Watson Conversationサービスの初心者向け講座 (3) Dialog におけるcontextの扱い](https://qiita.com/yamachan360/items/e332e9a9ea5f850bc239) 投稿で作成した以下のDialogで、intentとentityは定義していません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193519/afa34fa8-6800-327e-963f-f09bc05f9d7b.png)

## コードの修正

JSON はダウンロードした状態から、以下の3つの修正をして読みやすくしています。

* 操作を試したことによって生成されたであろう中身のない無駄な項目を削除
* dialog_node 値はノード名になる場合と、システムが自動生成した値になる場合があり、ノード名に準じたものに修正した
* 全体の並びを作成順から実行順(作成画面での表示順)に変更した

また全体を眺めてみて、個人的に面白かったのは以下の点です。

* 親が子のリストをもつ Tree 構造ではなく、子が親への参照を parent で持つ形式だった
* 子の前後関係は、後のものが前への参照を previous_sibling に保持しており、これが null のものが先頭

この構造は実行時にコストはかかりますが、変更が容易であると推察できます。

## 実際のコード

```json
{
"name":"dev test",
"created":"2017-10-08T09:16:13.013Z",
"intents":[],
"updated":"2017-10-11T15:27:47.764Z",
"entities":[],
"language":"ja",
"metadata":{
  "api_version":{
    "major_version":"v1",
    "minor_version":"2017-05-26"
  }
},
"description":"",
"dialog_nodes":[
  {
    "title":"ようこそ",
    "output":{},
    "parent":null,
    "context":null,
    "created":"2017-10-08T09:17:42.264Z",
    "updated":"2017-10-08T14:39:13.255Z",
    "metadata":{
      "fallback":"leave",
      "_customization":{"mcr":true}
    },
    "next_step":null,
    "conditions":"welcome",
    "description":null,
    "dialog_node":"ようこそ",
    "previous_sibling":null
  },
  {
    "type":"response_condition",
    "title":null,
    "output":{
      "text":{
        "values":["おはようございます。ご用件を入力してください。"],
        "selection_policy":"sequential"
      }
    },
    "parent":"ようこそ",
    "context":{"test_int":0},
    "created":"2017-10-08T10:09:30.070Z",
    "updated":"2017-10-11T15:07:41.770Z",
    "metadata":null,
    "next_step":null,
    "conditions":"now().before('12:00:00')",
    "description":null,
    "dialog_node":"ようこそ_condition1",
    "previous_sibling":null
  },
  {
    "type":"response_condition",
    "title":null,
    "output":{
      "text":{
        "values":["いらっしゃいませ。ご用件を入力してください。"],
        "selection_policy":"sequential"
      }
    },
    "parent":"ようこそ",
    "context":{"test_int":10},
    "created":"2017-10-08T16:10:13.200Z",
    "updated":"2017-10-11T15:09:00.574Z",
    "metadata":null,
    "next_step":null,
    "conditions":null,
    "description":null,
    "dialog_node":"ようこそ_condition2",
    "previous_sibling":"ようこそ_condition1"
  },
  {
    "title":"デバッグ",
    "output":{
      "text":{
        "values":["コンテキスト情報 <? context ?>"],
        "selection_policy":"sequential"
      }
    },
    "parent":null,
    "context":{"test_int":"<? $test_int + 1 ?>"},
    "created":"2017-10-11T14:31:43.667Z",
    "updated":"2017-10-11T15:27:47.764Z",
    "metadata":null,
    "next_step":{
      "behavior":"jump_to",
      "selector":"condition",
      "dialog_node":"その他"
    },
    "conditions":"true",
    "description":null,
    "dialog_node":"デバッグ",
    "previous_sibling":"ようこそ"
  },
  {
    "title":"その他",
    "output":{
      "text":{
        "values":[
          "解釈できませんでした。申し訳ありませんが違う表現を試していただけますか。",
          "恐れ入りますが表現を変えていただけますか。解釈できませんでした。"
        ],
        "selection_policy":"sequential"
      }
    },
    "parent":null,
    "context":null,
    "created":"2017-10-08T09:17:42.264Z",
    "updated":"2017-10-09T13:44:36.484Z",
    "metadata":null,
    "next_step":null,
    "conditions":"anything_else",
    "description":null,
    "dialog_node":"その他",
    "previous_sibling":"デバッグ"
  }
],
"workspace_id":"9919de2c-ab8d-409b-86ca-139f53c82dbd",
"counterexamples":[],
"learning_opt_out":false
}
```