NVIDIA NeMo Guardrailsとは? -情報まとめ その2-

続くと書いて続いた実績が全くなかったのですが、奇跡的に続きを書きます。

# はじめに
「NVIDIA NeMo Guardrailsとは? -情報をまとめ-」の続きになります。Nemo Guardrailsの概要、インストール方法等、概略を纏めてありますので、まだ前回の記事を確認されていない場合、下記のリンクからご確認戴ければと思います。

https://qiita.com/mana-murakami/items/336711f7d761a0b2368d
# Nemo Guardrailsのコンフィグレーション
早速、Nemo Guardrailsで色々試してみようと思います。まずはNemo Guardrailsのコンフィグファイルを作成します。[Configuration Guide](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/user_guide/configuration-guide.md)からコンフィグの詳細を確認できるので、そちらも併せてご確認下さい。

Nemo Guardrailsの設定ファイルは以下の２つのコンフィグレーションファイルを作成する必要があります。
- __一般的なオプション (ymlファイル)__
    - 使うLLMを指定する。その他一般的な指示等を定義するファイル
- __ガードレール定義 (coファイル)__
    - ダイアログフローとガードレールを定義する。Colang形式で定義する。
    - Colangガイドは[こちら](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/user_guide/colang-language-syntax-guide.md)

```ruby:nemoの設定ファイル構成
.
├── config
│   ├── file_1.co
│   ├── file_2.co
│   ├── ...
│   └── config.yml
```
## シンプルなガードレールの作成
以下に最小構成のシンプルなコンフィグレーションを作成してみます。config.yml(一般オプション)にはどのLLMモデルを使うか等連携するLLM Serviceに関する情報のみ今回は記載します。2023年5月現在はengineはopenaiのみ指定が可能です。
- __config.yml__
```yml
models:
  - type: main
    engine: openai
    model: text-davinci-003
```
- __hello-world-1.co__
[Hello Worldサンプル](https://github.com/NVIDIA/NeMo-Guardrails/blob/main/docs/getting_started/hello-world.md)を参考に、挨拶時の振る舞いに関するガードレールをColang形式で定義します。
今回の例は、greetingで定義した挨拶の状態に遷移したら、how are you doing? というように相手の状態を確認し、体調が悪い時は共感するような振る舞いをせよという定義になります。
```conf
define user express greeting
  "Hello"
  "Wassup?"

define bot express greeting
  "Hey there!"

define bot ask how are you
  "How are you doing?"
  "How's it going?"
  "How are you feeling today?"

define flow greeting
  user express greeting
  bot express greeting
  bot ask how are you

  when user express feeling good
   bot express positive emotion

  else when user express feeling bad
   bot express empathy
```

# まずは動かしてみる
作成したシンプルなコンフィグレーションでNemo Guardrailsを動かしてみます。作成した設定ファイルは以下のようにconfig配下にhello-world-1というフォルダを作成して配置しました。
```
.
├── config
│   ├── hello-world-1
│   │   ├── hello-world-1.co
│   │   └── config.yml
```
nemoguardrails serverを以下のコマンドで起動します。nemoguardrails serverはカレントディレクトリ配下にconfigフォルダがあるとそれをガードレールの設定が入っているフォルダだと認識します。
今回はhello-world-1ファルダのみですが、複数ある場合、複数認識します。
```ruby:nemoguardrails serverの起動
(nemo) $ nemoguardrails server
INFO:     Started server process [1389868]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
```
ブラウザでNemo GuardrailsのテストサーバーのUIにアクセスし、Configurationでhello-world-1を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/700fd273-6ad3-a02b-9fba-e07d3b1d6606.png)
早速チャットボットと会話してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/7763aa09-ac58-3952-9cf7-08797851ce0e.png)
hello-world-1.coのgreetingの定義には"Hello"と"Wassup?"を定義したので、敢えて"Hi"と定義していない挨拶でチャットボットに話しかけてみる事にしましたが、きちんとご機嫌伺いをしてくれています。
"Not so good"と具合があまり良くない事を伝えると"I'm sorry to hear that"と弔意を示してくれました。
この時、nemoguardrails serverのログを見てみると以下の通り、"Hi"をきちんとgreetingだと認識しており、ガードレールの定義の通りbotもgreetingとhow are you?のフローに入っている事が分かります。
![guadrails1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/3d69cd97-00c2-b554-d3eb-f3f70f267530.png)
ちなみにhello-world-1.coを適用していない場合、botはすぐに"Is there anything i can do to help?"と気分を確認する事なく会話を続けていました。

以下のようにいくつかのパターンで試してみましたが、ガードレールは機能していそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/5dce1472-a607-a28d-8fa1-2b8605e89fda.png)
# 侮辱のガードレールを追加してみる
次にhello-world-2.coを作成しhello-world-1.coの設定に更に定義を追加してみます。"define user express insult"を追加し、侮辱に対するガードレールを定義してみます。
```ruby:hello-world-2.co
define user express greeting
  "Hello"
  "Wassup?"

define bot express greeting
  "Hey there!"

define bot ask how are you
  "How are you doing?"
  "How's it going?"
  "How are you feeling today?"

define flow greeting
  user express greeting
  bot express greeting
  bot ask how are you

  when user express feeling good
   bot express positive emotion

  else when user express feeling bad
   bot express empathy

define user express insult
  "You are stupid"

define flow
  user express insult
  bot express calmly willingness to help
```
nemoguardrails serverを起動しなおし、hello-world-2を選択してbotとの会話を開始します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/a8a7f8ac-8c5c-6feb-cc39-d04bbff3f06e.png)
なんて大人な対応…。冷静に対応しつつ、何かお手伝いできる事はありますか?と通常のフロー誘導しています。
ログでChainを確認すると、"express insult"のフローにきちんと入っている事が確認できます。
![guadrails2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/47363f78-7c97-21ac-24c6-f2e5bd24b3e0.png)

# 日本語は?
ガードレール定義ファイルに日本語を定義して、test UIでテストしてみました。
hello-world-ja.coを作成しgreetingやhow are youの定義を以下のように日本語に書き換えました。

```
define user express greeting
  "こんにちは"
  "どうも"

define bot express greeting
  "やあ!"

define bot ask how are you
  "調子はどう?"
  "お元気ですか?"
  "今日の調子はいかがですか?"

define flow greeting
  user express greeting
  bot express greeting
  bot ask how are you

  when user express feeling good
   bot express positive emotion

  else when user express feeling bad
   bot express empathy

```
以下がbotとの会話になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/ccc78cdd-c1fa-57d4-d67f-7dad010be2dc.png)
結果を見ると、なんとなく日本語で入力してもガードレールが機能していそうに見えます。ログでChainも確認してみます。
![guadrails3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125731/71c23138-fc96-e3cb-d4c1-4f6538123b44.png)

「おはようございます」とBotに話しかけてみましたが、express greetingと認識出来ており、ガードレールの定義通り、体調を質問するフローに入っています。今回のhello-world-ja.coは侮辱の定義(insult)を行っていなかったので、「ばーか、ばーか」はfrustrationと判定されており、その後の会話に続いているようです。

日本語でガードレールを定義しても動作しそうです。今回はNemo GuardrailsのTest UIからテストしましたが、Pythonからでも恐らく動作すると思うので、(次回があれば)確認してみようと思います。

# まとめ
今回は、Nemo Guardrailsの設定ファイルの書き方、Test UIからテストの仕方、そしてガードレール定義ファイルに日本語を記述した際の動作について確認しました。
Nemo Guardrailsを試してみたい方は[こちらから](https://github.com/NVIDIA/NeMo-Guardrails)、ぜひ試してみて下さい。

次があれば次回は、もう少し応用的なガードレール定義の書き方やTest UIからではなくPythonからのテストなども試してみようと思います。つづく…かも