マークダウンでチャットボットをサクッと書けるサービスを作ってみた話

# はじめに
<img src="https://i.imgur.com/M0oJB8a.png" width="80%">

こんにちは、[maKunugi](https://twitter.com/maKunugi)です。
先日、マークダウンを書いて「**ドキュメントを書くような感覚**」でチャットボットを手軽に作成できる、「mabo」というサービスを開発し、ベータ版を公開しました。ぜひ経緯や内容を共有したいと思い記事を書いてみましたので、チャットボットに興味のある方はぜひ読んでみていただけると嬉しいです！

# どんなものを作ったか
[サービスページ](http://mabo.work/)
[利用ガイド](https://www.notion.so/mabo-33119299b066437ca91a5c702aecebb0)

<img src="https://i.imgur.com/FARV3Sk.png" width="500px">
maboはマークダウンをツラツラと記述するだけで、ブラウザ上で応答可能なチャットボットを簡単に構築できるサービスです。(スマホ・PC両対応)
まるでドキュメントを書いているかのような感覚でチャットボットを手軽に構築できるのが特徴です。
チャットボットは公開URLを配布することで、様々なユーザに利用をしてもらうことができます。
（Slack上でも動作します。)

# なぜ作ったか
数年前にチャットボットブームが到来し、チャットボットを業務効率化やカスタマーサポートのために導入する場面が増えてきています。

チャットボット導入のためのツールもそれに伴い増加し、様々なチャットボットツールが存在しています。
シナリオ構築のためのリッチなチャットボット開発用のGUIを提供しているサービスもあれば、Dialogflowのようにノーコードで多くのサービスと連携して動作するチャットボットを構築できるサービスもあったりと、チャットボット開発には多種多様なソリューションがあります。

そんな現状ですが、
いくつかのチャットボットツールを試したり、複数のプラットフォーム上で動くチャットボットの開発を行ってきた中で感じているのが、まだ**手軽にサクッと利用できるものが少ない**ということでした。チャットボットの導入は様々なメリットがありますが、導入には少々手間がかかります。例えば、ツールの使い方になれる必要があったり、そもそもの導入に資料請求や契約などの手順が必要だったりします。リッチなツールに慣れ、作り込んだチャットボットが必要な場面もあれば、手軽に素早くチャットボットを作って利用したいケースもあります。そういった手軽にチャットボットを活用したい場合に役立つサービスがあっても良いなと考えました。

そこで開発したのが、先ほど紹介した「mabo」というサービスです。

# 活用方法の例
手軽にチャットボットを導入して活用したい場合に適しています。
例えば下記のような活用方法があります。

- **個人開発しているサービス等のカスタマーサポートとして利用する**
<img src="https://i.imgur.com/E8oU7mY.png" width="300px">
ブラウザで動作するチャットボットを手軽に構築して、URLを配布してシェアできます。
チャットボットが解決できなかった内容は、個別のメール問い合わせに誘導することも可能です。

- **ドキュメントの検索効率を上げる**

<img src="https://i.imgur.com/RioeYd8.png" width="500px">

チャットボットは、必要な情報をチャット形式で素早く確認するための手段としても有用です。
よくアクセスしたい情報をマークダウンでまとめておき、Slack上で必要な情報にインタラクティブに問い合わせるといった活用が可能です。
よくある「ドキュメントどこだっけ？」といったコミュニケーションを削減にもつながります。


こういった用途に使えるチャットボットを、マークダウンを書くだけで手軽に作成することができます。

# 使い方
[利用ガイド](https://www.notion.so/mabo-33119299b066437ca91a5c702aecebb0)に詳細を載せてあるので、こちらでは使い方の要点をピックアップしながら紹介をします。

チャットボットを作成する手順は下記の4ステップです。

1. マークダウンでコンテンツを記述
2. プレビューで動作確認 & 必要に応じて編集
3. チャットボットを公開
4. チャットボットを改良する

## 1. マークダウンでコンテンツを記述
[チャットボット作成ページ](https://mabo-admin.work/admin/registerBot)を開き、マークダウンでコンテンツを記述していきます。

![](https://i.imgur.com/WZuBMEr.png)

基本的なマークダウンの記法は一通り利用できます。
利用可能な記法は[こちら](https://www.notion.so/30d5161963af465f84f5e6c92d21dddd)に記載してあります。

ここでは、最も重要な「見出し」の取り扱いについて見ていきます。

### マークダウンの書き方の例１ - 見出し

maboで生成されるチャットボットの応答の検索は、見出し(「#」から始まる表現)に記載された言葉が大きく検索結果に影響します。

```
# サービスについて
このサービスは、xxxのために作られました。

# 導入方法について
導入の手順は下記の通りです。
1. hoge
2. hoge
3. hoge


# 料金について
料金は無料です。
```

例えば、上記のようなマークダウンを記述したとします。
この場合、

- サービスについて
- 導入方法について
- 料金について

の３つの見出しがあります。

この状態で、チャットボットを作成して起動すると、このような状態になります。

![](https://i.imgur.com/MBJ2RDf.png)

見出しが「**発話候補**」として表示されていることがわかります。
※このサービスでは、次にユーザが聞きたいと思いそうな発話や関連度の高い発話を「**発話候補**」と読んでいます。多くのチャットボットでは「クイックリプライ」と呼ばれたりもします。

この状態で、発話候補を選択するか、自由にメッセージを入力することで、チャットボットの応答を確認することができます。

試しに「料金について知りたい」と話しかけてみます。

![](https://i.imgur.com/fTwLOzC.png)

先ほど、`# 料金について` の見出し配下に記述した文章が表示されていることがわかります。
このように、ユーザの発言と見出しに書かれた文言を比較し、類似性の高いコンテンツが選ばれ応答として返されます。

ある程度の表記揺れや類似表現については自動的に考慮されます。
例えば、「料金について」という見出しに対して、「値段は？」といった問いかけを行った場合も、同様の応答が返されます。


### マークダウンの書き方の例2 - 小見出し

小見出しをつけた場合の動きも確認してみましょう。
下記の例では、先ほどの「料金について」という見出しの下にいくつかの小見出しを追加した例です。

```
# サービスについて
このサービスは、xxxのために作られました。

# 導入方法について
導入の手順は下記の通りです。

1. hoge
2. hoge
3. hoge


# 料金について
フリープランは無料です。
フリープランの他に、有料のAプランとBプランがあります。

## Aプランについて
Aプランはxxx円です。
Aプランになると下記機能を利用可能です。

- hoge
- hoge
- hoge

## Bプランについて
Bプランはxxx円です。
Bプランになると下記機能を利用可能です。

- hoge
- hoge
- hoge

```

このマークダウン を記述したチャットボットに先ほどと同じように質問をしてみましょう。

![](https://i.imgur.com/iR7cTpM.png)

料金について尋ねると、応答とともに「Aプランについて」「Bプランについて」という発話候補が表示されていることがわかります。見出し配下の小見出しは、親見出しの応答が表示される際は発話候補に自動的に追加されるような仕組みになっているためです。

このように、maboでは関連度や見出しの親子関係に応じて、自動的に発話候補が挿入されます。
※ 手動で設定することもできます (後述する拡張機能をご参照ください)

以上がmaboの基本的なチャットボット記述方法です。
見出しとその配下のコンテンツの関係性に慣れれば、後は普通にマークダウンでドキュメントを書くような感覚でチャットボットを構築していけるはずです。

上記の記法以外に様々なTipsがあるので、詳しくは[利用ガイド](https://www.notion.so/30d5161963af465f84f5e6c92d21dddd)をご参照ください。

### 拡張機能を使う例
マークダウンを記述する他に、「拡張機能」を利用してチャットボットに機能を追加することもできます。

maboはマークダウンの記述に加え、「@」から始まる特定の表現を用いることで、下記のような機能をチャットボットに設定します。

■ 検索の拡張
- 見出しに対しての検索キーワードを追加する

■ 応答機能の拡張
- ランダムな応答を返す

■ 発話候補設定
- 応答時に表示される発話候補を手動で設定する
- 自動で追加される発話候補を除外する
- 発話候補に「戻る」機能を追加する
- 「ありがとう」「解決できない」という発話候補を非表示にする

■ チャットボット設定
- 自由入力を禁止する

■ その他
- メール送信ボタン(チャットボット運営者へのお問い合わせ窓口)を設置する
- ユーザの回答を記憶する
- ユーザの回答に応じて応答を出し分ける

１つ１つの拡張機能の使い方については、利用ガイドの[拡張機能を利用する](https://www.notion.so/38a8520d015446f6a0a772311346475d)をご参照ください。

本記事では、２つの拡張機能の使用例を紹介してみます。

### 見出しに対しての検索キーワードを追加する
```
# 導入方法について
@cov: ["インストール","始め方"]
導入の手順は下記の通りです。

1. hoge
2. hoge
3. hoge

```
先述したように、見出しに対する検索はある程度の類似表現は考慮されますが、その際に網羅されない検索キーワードは、手動で追加が可能です。

この例の場合、「導入方法について」という見出しが、「インストール」「始め方」といった言葉と紐付きます。
![](https://i.imgur.com/KIv0fh5.png)

このように、見出し配下に拡張機能を適用するとことで、特定の応答をカスタマイズすることができます。
※見出し外のトップ階層に記述する場合は、全体に適用されます。

#### 発話候補を手動で設定する
ユーザに対して表示される発話候補は、基本的に自動で挿入がされますが、チャットボット作成者が手動で設定することも可能です。

その場合は、`@add_options`と必要に応じて`@disable_auto_options`を挿入します。

```
# サービスについて
@disable_auto_options  
@add_options: ["hoge1","hoge2","hoge3"]  
このサービスは、xxxのために作られました。
```

`@add_options`に指定した言葉が発話候補として表示されるようになります。
`@add_options`だけ指定すると、自動の発話候補補填も行われるので、自動で補填されることを止めるには、`@disable_auto_options`を併用します。

![](https://i.imgur.com/FvZ7M47.png)

この他にも、拡張機能としてユーザが直接メールでお問い合わせをする機能やランダムな応答を返す機能などが用意されています。 詳細は「[そのほかの拡張機能](https://www.notion.so/38a8520d015446f6a0a772311346475d)」をご覧ください。


## 2. プレビューで動作確認
マークダウンの記述が終わったら、公開前にプレビューでチャットボットの動作を確認できます。

![](https://i.imgur.com/PYCXOpb.png)

想定通りの動作がしているかを確認しつつ、必要に応じてコンテンツを修正しましょう。

## 3. チャットボットを公開

![](https://i.imgur.com/qpbsELO.png)

チャットボットの動作が確認できたら、公開をします。
公開は「一般公開」「限定公開」が選択できます。

限定公開の場合、チャットボットを作成した本人以外はチャットボットを利用することができません。
Slackでのみ利用したいなど、チャットボット用のURLを他人とシェアしたくない人はこちらを利用します。
一般・限定を問わず、公開をすると外部サービス連携(現在はSlackのみ)ができるようになります。
Slackとの連携方法は[こちら](https://www.notion.so/mabo-33119299b066437ca91a5c702aecebb0?p=217285a134aa484095285b71ff463af7)に詳細を記載しました。


### チャットボットを一般公開する

![](https://i.imgur.com/LHDQKbR.png)

一般公開をすると、チャットボットの共有URLが取得できます。
そのURLをシェアすることで、誰でもブラウザ上でチャットボットと会話をすることができます。

#### 共有URLのカスタマイズ
共有URLにはクエリパラメータをつけて配布ができます。
例えば、チャットボットの会話画面を立ち上げた時にデフォルトで表示したい質問がある場合は、
`<チャットボットのURL>&utterance=開始したい文言`
上記のように、`utterance`パラメータを付与します。特定の会話に飛ばすためのリンクとしてシェアする際に便利です。

![](https://i.imgur.com/Fg74Dbh.png)

その他にも、会話で利用する情報としてクエリパラメータを活用するといった方法もあるので、詳しくは[こちら](https://www.notion.so/ca57c52bf0ed4a73a83ce37dc1100940#d2ce369d805f4540a3d682b52c501bb3)をご確認ください。

## 4. チャットボットを改良する
管理画面の「[ログ画面](https://mabo-admin.work/admin/logging#)」から、チャットボットに話しかけられた言葉の履歴が確認できます。
![](https://i.imgur.com/zN3lBZU.png)

チャットボットがうまく返すことのできない応答があれば、随時マークダウンコンテンツを編集をし、チャットボットのアップデートを行うことができます。


以上のような４ステップでチャットボットの作成から共有、改良をすることができます。

# 主な利用技術
maboは以下のような技術を利用して開発しました。

- フロントエンド
    - Next.js (TypeScript)
- バックエンド
    - Go + Echo
- DB
    - Firebase Cloud Firestore
- ストレージ
    - Firebase Cloud Storage
- 文書検索
    - ElasticSearch (Elastic Cloud)   
- 認証
    - Firebase Authentication

開発には約２ヶ月を要しました。
チャット画面、ボット管理画面の両フロントエンドをNext.js(TypeScript)で開発しています。
フロントエンドの開発は初心者だったため、勉強も兼ねて前々から気になっていたNext.jsを採用しました。
認証やストレージ、DBにはFirebaseを利用して、チャットボットやユーザの管理の大半の機能をサーバレスに開発しています。
チャットボットの質問・応答となるコンテンツはElasticSearchで扱っており、ElasticSearchの文書検索と自前のGo製発話処理APIを組み合わせてチャットボットの応答を行っています。(応答精度にはまだまだ改善の余地があるので、今後は文書検索結果をBERT等を用いてさらに最適化することを考えています。)

# まとめ
マークダウンを書いてチャットボットを構築するサービスについて紹介させていただきました。
まだまだ品質向上が必要な余地が多くありますが、このサービスの需要を見定めつつ、改善をしていこうと思います。
マークダウンでチャットボットを書いてみたいと思ってくれた方がいらっしゃいましたら、ぜひサービスを触ってみてもらえると嬉しいです！
もしサービスのフィードバックやバグ報告などあれば、[Twitterアカウント](https://twitter.com/maKunugi)までお寄せください。


それでは、最後までお読みいただきありがとうございました。