[watsonx.ai]出力を制御したい

# 前置き
モデルの出力を制御するためにFew shotなどの方法がいくつか存在します。
この方法はモデルの出力を制御するために強力な方法であることは確かですが、sampleを用意するのが少し面倒です。
そこで今回は主にwatsonx.aiで利用可能なモデル、llama3を対象になるべく柔軟に簡単に制御が出来ないかを試しました。（他のモデルでも使用できますがllama3を対象に検証した為、llama3に最も効果があります。）
この記事はその備忘録です。
検証環境はPrompt Labです。

# 前提：制御が出来ていないパターン
まず前提として制御が出来ていないパターンについて説明します。
例えばLLMに対して文章を渡し、何についての説明なのかを質問します。
その際に返してほしい結果は`何`にあたる部分のみでありそれ以外の出力はなるべく避けたいと考えますが、時折LLMは`Here is answer!`のように余計な発言を付け足してしまいます。
下記の例ではWikipediaのJAPAN SPORT OLYMPIC SQUAREの内容を引用し、何についての説明なのかを[馬,スポーツ,オリンピック]の中から2つ選んでもらい、pythonのリスト形式で出力するように指示をしています。
### 入力例1
![スクリーンショット 2024-06-18 123102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/dee63fd1-6761-7fbf-4eca-9e797e05f5de.png)

### 出力例1
![スクリーンショット 2024-06-18 123422.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/d278f348-0915-f2d5-ac05-31482412da6b.png)

出力結果を見てみるとpythonのリスト形式でしっかりと選ぶことは出来ていますが、余計なコメントが入ってきてしまいます。
もちろんuser promptを改善することでこの余計なコメントを出力しないようにすることは出来ますが、あくまでもこの例はかなり簡単なタスクであり実際はもっと複雑なタスクを行うはずです。
その際に適切なuser promptを都度考えていくのは正直面倒です。

# 制御方法
では、どのようにしてLLMの出力を制御するのでしょうか？
今回はsystem promptを下記の様に変更しました。
```
Respond to the human as helpfully and accurately as possible. Provide your response in the following JSON format:
{
"Thinking action": $"Your thinking action",
"Answer": $"Your answer to human. ",
"description of Answer": $"Your explanation"
}

If it's a user error or something you don't understand, respond as follows:
{
"Thinking action": $"Your thinking action",
"Answer": "Do not answer",
"description of Answer": $"Your explanation"
}

Reminder to ALWAYS respond with a valid json.
json format.:
{
"Thinking action": $"Your thinking action",
"Answer": $"Your answer to human. ",
"description of Answer": $"Your explanation"
}
```
このsystem promptではjson形式でAnswerそのものと、そのAnswerに至るまでのLLMの考え方を出力させるようにしています。このようにすることでpythonコード上で実行した際は出力結果をjson形式に変換しキーに"Answer"を選択することで最終的な結果のみを抽出できるほか、なぜそのような結果になったのかを確認（デバッグ）できます。
今回はPrompt Lab上で実行しているためその操作は割愛しています。
このsystem promptでの実行結果を見てみます。

### 入力例2（1と同様）
![スクリーンショット 2024-06-18 123102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/9b4ecd6b-1d1d-7e49-8834-dde5fa40a326.png)

### 出力例2
![スクリーンショット 2024-06-18 125206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/f1939e30-baf0-557c-188f-366b8edaa1d9.png)

Answerの部分を見ると正確なpythonのリスト形式のみがあることが分かります。
これで今回の記事に書きたいことは9割程度終了ですが、このsystem promptに更に変更を加えたパターンを捕捉として付け足します。

# 補足
### binary判定（Yes or No）

#### system prompt
```
Respond to the human as helpfully and accurately as possible. Provide your response in the following JSON format:
{
"Thinking action": $"Your thinking action",
"Answer": $"Your answer to human. Answer is must selected from [Yes, No]",
"description of Answer": $"Your explanation here"
}

If it's a user error or something you don't understand, respond as follows:
{
"Thinking action": $"Your thinking action",
"Answer": "Do not answer",
"description of Answer": $"Your explanation here"
}

Reminder to ALWAYS respond with a valid json.
json format.:
{
"Thinking action": $"Your thinking action",
"Answer": $"Your answer to human. Answer is must selected from [Yes, No]",
"description of Answer": $"Your explanation here"
}
```

#### 実行例
![スクリーンショット 2024-06-18 130221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/4919a44f-3cbb-59c8-6d28-a1d2a5007544.png)

### Answerのみの出力（最終出力の形式をuser promptで指示）
#### system prompt
```
Respond to the human as helpfully and accurately as possible. Provide your response in the following JSON format:
{
"Answer": $"Your answer to human.  only final answer that user suggest."
}
If it's a user error or something you don't understand, respond as follows:
{
"Answer": "Do not answer"
}
Reminder to ALWAYS respond with a valid json.
json format.:
{
"Answer": $"Your answer to human. only final answer that user suggest. "
}
```

#### 実行例
![スクリーンショット 2024-06-18 145101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491855/d659649e-fdf4-ee2d-bf26-2eafbe48ae48.png)


# 終わりに
今回のsystem promptではある程度の制御は出来ることが確認できました。
しかしまだまだ改善の余地はあるため検証を続けたいと思います。
（llama3以外のモデルとか）