生成AIをもっと知りたい 〜Vertex AI〜

# 生成AIをもっと知りたい 〜Vertex AI〜

この記事は[株式会社ビットキー Advent Calendar 2023](https://qiita.com/advent-calendar/2023/bitkey)の18日目の記事です。

# はじめに

この記事では、Google CloudのVertex AIについて、ハッカソンイベントを通して学んだ内容を中心に、Vertex AIにおけるプロンプトの概要とパラメータ設定について、ふんわりと理解した情報を元に整理してみました！

# 0. 背景

ChatGPTの普及をはじめ、

エンジニアの界隈ではCopilot、

先日もGoogleからはGeminiが発表されたり

まさに2023年は生成AIの年でしたね

弊社でも、AI技術を活用したプロジェクトが始まっています

※ 以下、ニュースリリース

[https://bitkey.co.jp/newsroom/20211109/](https://bitkey.co.jp/newsroom/20211109/)

また、同11月にはGoogle Cloudの生成AIをテーマとしたハッカソンイベントに参加させていただきました！

[https://cloud-ace.jp/column/detail457/](https://cloud-ace.jp/column/detail457/)

そんな生成AIですが、

当初、私自身はすごいなぁという反面、

雑に質問をぶん投げても、なんかいい感じに答えてくれたり、他のソースコードと似た体裁のいい感じのコードをサジェストしてくれたり、不気味だなぁ、怖いなぁという気持ちの方が強かったと感じておりました

ただ、次第に利用していく中で、アホっぽい回答を返してくれたり、的外れな回答を返してくれたりとChatGPTくん、Copilotくんからユーモア？機械臭さ？を感じたことももちろんですが

Vertex AIのチュートリアルを通して、プロンプトのコンテンツタイプやパラメータの概念を知ったことで、あーなるほどなと、納得した部分もありポジティブな感情でお付き合いできるようになってきました

この記事ではVertex AIを通して知ったプロンプトのコンテンツタイプやパラメータについて題材を例に使って、ふわっと理解する為の情報を整理してみようと思います

※ 基礎的な内容となります

※ Vertex AIにおける内容となります

cf. [https://cloud.google.com/vertex-ai?hl=ja](https://cloud.google.com/vertex-ai?hl=ja)

# 1. 題材

題材が欲しかったので私がはじめて生成AIを使った頃のプロンプトは多分こんな感じだっただろうな、というプロンプトを用意しました！

※ 先に断っておきますが、もちろん私は対局中に、生成AIを用いたことはございません

※ また、筆者の麻雀知識はにわかなので暖かい目で見守ってください

## 1-1. 例

```
麻雀、オーラス16000点差、まくり方、子供
```

これは南四局（子）において、1位のプレイヤーと16000点差離れている状況を覆したいので逆転する戦略を考えて欲しいという場面をイメージしたプロンプトとなります

cf. この時のレスポンスは以下の通り

> 1. **手牌をチェックする。** まだ高得点の可能性のある手牌があるかどうかを確認します。
> 2. **聴牌する。** まだ聴牌していない場合は、できるだけ早く聴牌します。
> 3. **ドラを手にする。** ドラを手にすることで、得点の可能性を高めることができます。
> 4. **対面のアガリの可能性を抑える。** 対面のアガリが近づいている場合は、アガリを防ぐために彼がアガリ牌になりやすい牌を切るのを防ぐようにしましょう。
> 5. **自分のアガリを積極的に狙う。** アガリの可能性のある牌が出たら、積極的にアガリを狙いましょう。
> 6. **あがれる牌を切る。** あがれる牌か、他の可能性のある手に役立つ牌を切ります。可能性の低い牌を切ると、高得点の可能性を損ないます。
> 7. **責任を持ってプレイする。** 自分の点数を大きくリードしている場合は、できるだけ自分の点数を維持するように注意しましょう。
> 

想定していた通り、具体的な回答を得ることはできませんでした

↓ 撮影時12月中旬: Gemini Proモデルが新たに追加されてました

![スクリーンショット 2023-12-15 17.31.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631617/6855c90d-0d68-e411-1704-90d57e9289fd.png)

## 1-2. 完成形をイメージしてみる（具体的な回答 is 何？）

まずはどんな出力結果が欲しいかを考えてみます

必要なことはオーラス16000点差を逆転することですが、初期配牌は最低限渡すようにして、結果、和了時の形を出力してもらいます！

ex. 初期配牌が「一筒、一筒、二筒、七筒、九筒、三萬、八萬、九萬、一索、三索、西、北、中」だったとした時に、こんな回答がもらえるイメージ ※ 白をドラとします

▼ 出力イメージ

```
和了：一筒、一筒、一筒、七筒、八筒、九筒、七萬、八萬、九萬、一索、二索、三索、白、白
役（6翻）：立直、自摸、混全帯么九、ドラ、ドラ
```

## 1-3. 判断するのに必要な情報を考えてみる

完成形をイメージをしたので次は、生成AIに判断してもらう為に必要な情報がどんなものであるかを考えてみます

- 自分を取り巻く状況はどうなっているか（オーラス、16000点差、自風は？ドラは？）
- どんなルールで行なっているか、どんな役が利用可能か（一発は？アカドラは？裏ドラは？食いタンはあり？etc …）

以降ではこれらを前提として、プロンプトのコンテンツタイプやパラメータを取り扱っていきます

# 2. プロンプトのコンテンツタイプ

そもそもプロンプトって何？

> プロンプトとは、レスポンスを受け取るために言語モデルに送信される自然言語リクエストです。プロンプトには、モデルを完了または続行するための質問、手順、コンテキスト情報、例、部分入力を含めることができます。モデルは、使用しているモデルのタイプに応じてプロンプトを受信した後、テキスト、エンベディング、コード、画像、動画、音楽などを生成できます。
> 

cf. [https://cloud.google.com/vertex-ai/docs/generative-ai/learn/introduction-prompt-design?hl=ja](https://cloud.google.com/vertex-ai/docs/generative-ai/learn/introduction-prompt-design?hl=ja)

コンテンツタイプは以下3タイプ

- 入力（必須）
- コンテキスト（省略可）
- 例（省略可）

### 入力（必須）

> 入力は、モデルにレスポンスを提供させるプロンプトのテキストであり、必須のコンテンツ タイプです。（以下略）
> 

入力＝初期配牌をここで渡してあげます

ex.

```
一筒、一筒、二筒、七筒、九筒、三萬、八萬、九萬、一索、三索、西、北、中
を初期配牌とした場合に、条件を満たす手配を考えてください
```

### 例（省略可）

> 例は、モデルに理想的なレスポンスの例を与えるためにプロンプトに含める入力と出力のペアです。プロンプトに例を含めると、レスポンスの形式を効果的にカスタマイズできます。
> 

例を含めることで1-2でイメージした完成形（＝出力例）に沿った、結果を返すようにコントロールします

ex.

```
和了：一筒、一筒、一筒、七筒、八筒、九筒、七萬、八萬、九萬、一索、二索、三索、白、白
役（6翻）：立直、自摸、混全帯么九、ドラ、ドラ
```

### コンテキスト（省略可）

> コンテキストは次のいずれかです。
モデルがどのように動作すべきかを指定する指示。モデルが回答を生成するために使用または参照する情報。モデルに情報を与える必要がある場合、または回答の範囲をプロンプト内の要素だけに制限する必要がある場合は、コンテキスト情報をプロンプトに追加します。
> 

1-3で考えた、生成AIに判断してもらう為に必要な情報をここにまとめて含めます

ex.

```
あなたは麻雀をしています
今、南4局のオーラスで
1位は北家で、あなたとは16000点差があります

あなたは1位になるために、自摸で12000点をアガる為の戦略を考えています。
入力として与えられる初期配牌を鑑みて、12000点のアガリをする手配を考えてください。

あなたの自風は「南」であり、ドラは「白」です
```

※ 現時点ではPaLM2モデルの場合には、構造化タブがあります

コンテンツタイプを意識しやすいインターフェースになってるので理解しやすいと感じました

![スクリーンショット 2023-12-16 12.46.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631617/8ebd3f71-d6fc-c96e-aa3e-27a28b92eb55.png)

ただ結果（出力）は散々…

なかなか、正しくアガれる出力を返させることができずでした。

難しいですね…

<details><summary>＜とりあえず調整した最終的なプロンプトはこちら＞</summary>

    あなたは麻雀をしています
    今、南4局のオーラスで
    1位は北家で、あなたとは16000点差があります
 
    あなたは1位になるために、自摸で12000点をアガる為の戦略を考えています。
    入力として与えられる初期配牌を鑑みて、12000点のアガリをする手配を考えてください。
    
    ルールはMリーグの公式戦ルールに則り、
    一発・裏ドラ・赤ドラありを採用します
    
    あなたの自風は「南」であり、ドラは「白」です
    
    門前でアガるパターンと鳴きありでアガるパターンをそれぞれ示してください。
    なお、門前のパターンの場合は、「立直、自摸」を前提とする為、残りの4翻または5翻を、鳴きありのパターンの場合は、6翻または7翻を作ってください
    
    利用できる役は以下の通りです
    
    ・門前のパターンで利用できる役
    1翻役 門前清自摸和
    1翻役 立直
    1翻役 役牌(翻牌)
    1翻役 平和
    1翻役 断么九
    1翻役 一盃口
    1翻役 海底摸月
    1翻役 河底撈魚
    1翻役 搶槓
    1翻役 嶺上開花
    2翻役 ダブル立直
    2翻役 連風牌
    2翻役 対々和
    2翻役 三暗刻
    2翻役 三色同刻
    2翻役 三槓子
    2翻役 小三元
    2翻役 混老頭
    2翻役 三色同順
    2翻役 一気通貫
    2翻役 全帯么九
    2翻役 七対子
    3翻役 二盃口
    3翻役 混一色
    3翻役 純全帯么九
    6翻役 清一色
    
    ・鳴きありのパターンで利用できる役
    1翻役 役牌(翻牌)
    1翻役 断么九
    1翻役 海底摸月
    1翻役 河底撈魚
    1翻役 搶槓
    1翻役 嶺上開花
    1翻役 三色同順
    1翻役 一気通貫
    1翻役 全帯么九
    2翻役 連風牌
    2翻役 対々和
    2翻役 三暗刻
    2翻役 三色同刻
    2翻役 三槓子
    2翻役 小三元
    2翻役 混老頭
    2翻役 混一色
    2翻役 純全帯么九
    5翻役 清一色
    
    出力例
    「
    和了：一筒、一筒、一筒、七筒、八筒、九筒、七萬、八萬、九萬、一索、二索、三索、白、白
    役（6翻）：立直、自摸、混全帯么九、ドラ、ドラ
    」
    
    入力
    「一筒、一筒、二筒、七筒、九筒、三萬、八萬、九萬、一索、三索、西、北、中」

</details>
※ 長いので折りたたみます


また、そのレスポンスは以下

```
**門前のパターン**

和了：一筒、一筒、一筒、七筒、八筒、九筒、七萬、八萬、九萬、一索、二索、三索、白、白
役（6翻）：立直、自摸、混全帯么九、ドラ、ドラ

**鳴きありのパターン**

和了：一筒、一筒、九筒、七筒、八筒、九筒、七萬、八萬、九萬、一索、三索、東、東、白
役（7翻）：清一色、ドラ、ドラ
```

鳴きありパターンはツッコミどころが多いですが、

門前パターンは正しくアガれてます

しかも初期配牌を鑑みた上で、条件を満たしてます

# 3. パラメータ

### MAX_OUTPUT_TOKENS

> レスポンス内に生成できるトークンの最大数。1 トークンは約 4 文字です。100 トークンは約 60～80 語に相当します。レスポンスを短くしたい場合は小さい値を、長くしたい場合は大きい値を指定します。
> 

そのままですが、最大文字数を規定します

料金は以下の通りなので、短くしてあげた方がコストを抑えられるようなので、

例えば、利用できる役パターンは門前と鳴きありで分けない方が良さそうです

> Vertex AI の生成生成サポートは、入力 1,000 文字（プロンプト）と出力 1,000 文字（レスポンス）ごとに課金されます。（以下略）
> 

cf. [https://cloud.google.com/vertex-ai/pricing?hl=ja](https://cloud.google.com/vertex-ai/pricing?hl=ja)

### TOP_K

> トップ K は、モデルが出力用にトークンを選択する方法を変更します。トップ K が 1 の場合、次に選択されるトークンは、モデルの語彙内のすべてのトークンで最も確率の高いものであることになります（グリーディ デコードとも呼ばれます）。トップ K が 3 の場合は、最も確率が高い上位 3 つのトークンから次のトークン選択されることになります（温度を使用します）。トークン選択のそれぞれのステップで、最も高い確率を持つトップ K のトークンがサンプリングされます。その後、トークンはトップ P に基づいてさらにフィルタリングされ、最終的なトークンは温度サンプリングを用いて選択されます。ランダムなレスポンスを減らしたい場合は小さい値を、ランダムなレスポンスを増やしたい場合は大きい値を指定します。トップ K のデフォルト値は 40 です。
> 

要するに、ランク付けされた結果に対して、 `上位何個` に含まれる結果を使うかということ

デフォルトは40なので、40個のトークンから選択された結果を返します

### TOP_P

> トップ P は、モデルが出力用にトークンを選択する方法を変更します。トークンは、確率の合計がトップ P 値に等しくなるまで、確率の高いもの（トップ K を参照）から低いものへと選択されます。たとえば、トークン A、B、C の確率が 0.3、0.2、0.1 で、トップ P 値が 0.5 だとします。このとき、モデルは温度を使って A か B を次のトークンとして選択し、C は候補から外します。ランダムなレスポンスを減らしたい場合は小さい値を、ランダムなレスポンスを増やしたい場合は大きい値を指定します。トップ P のデフォルト値は 0.95 です。
> 

要するに、ランク付けされた結果に対して、 `上位何%` に含まれる結果を使うかということ

デフォルトは0.95なので上位95%に含まれるトークンから選択された結果を返します

### TEMPERTURE

> 温度は、レスポンス生成時のサンプリングに使用されます。レスポンス生成は、topP と topK が適用された場合に発生します。温度は、トークン選択のランダム性の度合いを制御します。温度が低いほど、確定的で自由度や創造性を抑えたレスポンスが求められるプロンプトに適しています。一方、温度が高いと、より多様で創造的な結果を導くことができます。温度が 0 の場合、確率が最も高いトークンが常に選択されます。この場合、特定のプロンプトに対するレスポンスはほとんど確定的ですが、わずかに変動する可能性は残ります。ほとんどのユースケースでは、温度 0.2 から始めてみることをおすすめします。モデルが返すレスポンスが一般的すぎたり、短すぎたり、フォールバック レスポンスが返ってきたりする場合は、温度を高くしてみてください。
> 

topP, topKが適用された場合、この値が高いほど、ランダム性が高くなるため、自由な発想をし

逆に、正しさを重視するなら低く設定すると良いということになります

[https://cloud.google.com/vertex-ai/docs/generative-ai/text/test-text-prompts?hl=ja](https://cloud.google.com/vertex-ai/docs/generative-ai/text/test-text-prompts?hl=ja)

つまり、topP: 1, topK: 40, 温度: 1にして何度か実施すると自由な発想をしてくれるはずなので実行してみましたが、例が少ないからかあまり自由な発想をしてくれずでした…

なので、「おまけ」として、出力部分に言及せず自由にやらせてみることにしました


<details><summary>おまけ</summary>

試行1の結果が以下です

```
**門前パターン**

・清一色・役牌
ドラの白を含む9つの筒子で清一色の形を作る
残りの3つは萬子で三暗刻にして5翻にする
また、萬子の中で三牌、中を3張揃えた役牌で1翻を加算

・七対子
2つの筒子を全て刻子にし、七対子で6翻にする
また中と北を加えた4つの風牌をすべて鳴いて暗刻にする

**鳴きありパターン**

・清一色・混一色
同様に9つの筒子で清一色の形を作る
河に中が捨てられているので、中を鳴いて平和にする
残りの3つは九萬や八萬、三萬などの萬子の刻子なり順子にして混一色で2翻を加える

・清一色・純全帯么九
同様に9つの筒子で清一色の形を作り、ドラの白を鳴いて7翻にする
```

テキストはめちゃくちゃですが、清一色＋役牌＝7翻、七対子はドラ重ねれば6翻でちょっとそれっぽいぞw

- 試行2
    
    ```
    **門前パターン**
    
    ・清一色・役牌
    ドラの白を含む9つの筒子で清一色の形を作る
    残りの3つは萬子で三暗刻にして5翻にする
    また、萬子の中で三牌、中を3張揃えた役牌で1翻を加算
    
    ・七対子
    2つの筒子を全て刻子にし、七対子の形にする
    また、三元牌のうち北を3張揃えた役牌で1翻を加算
    
    **鳴きありパターン**
    
    ・清一色・混一色
    萬子と筒子のみで清一色を目指す
    河に發が捨てられているので、立直をせずに平和で和了
    また、場に發や中が捨てられているので、萬子の刻子、対子を念頭に入れて鳴いていく
    
    ・三色同刻・一気通貫・対々和・嶺上開花
    ドラの白を含む筒子で三色同刻の役を作る
    場に切り出されている發・中・西を含めるとポン・チーの待ちになり、嶺上開花も狙える
    残りの2つは索子を切って三索のターツで待つ
    開いた三索が嶺上和となれば、嶺上開花も狙える
    ```
    
    鳴きありの2パターン目が変わりました「一気通貫」と「三色同刻」「対々和」が両立しないですが、嶺上開花狙うあたり咲を見てきたのかもしれませんね。鳴きで「三色同刻」「対々和」＝4翻＋「嶺上開花」で5翻なので、真ドラが乗れば12000点になるかもしれません
    
- 試行3
    
    ```
    
    **鳴きありパターン**
    
    ・三暗刻・三色同刻
    河には萬子の6・7・9が捨てられているので、同刻にする
    残りの捨て牌から、翻牌や一盃口になるかどうかを念頭に入れてポン・チーをしていく試行1と結果、変わらず
    ```
    
    門前パターンと鳴きあり1パターン目がは変わらないので省略
    
    三暗刻＋三色同刻で4翻
    
- 試行4
    
    ```
    **門前パターン**
    
    ・清一色・役牌
    ドラの白を含む9つの筒子で清一色の形を作る
    残りの3つは萬子で三暗刻を狙っていく
    
    上がり牌は九萬または北
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 三萬, 三萬, 三萬, 七筒, 七筒, 八萬, 九萬, 九萬, 中中, 白白
    
    ・三槓子・小三元・断ヤオ九
    三槓子完成後に小三元体制に入れる
    8索で嶺上開花
    上がり牌は五索
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 七筒, 七筒, 八索, 八索, 八索, 三萬, 六萬, 九萬, 白白, 中中
    
    **鳴きありパターン**
    
    ・純全帯么九・一気通貫
    ドラの白を含む9つの索子で全帯么九の一気通貫の形を作る
    万子と筒子は鳴いてポン・チーをしていく
    
    上がり牌は九萬
    牌姿は以下の通り
    
    一索, 一索, 一索, 一筒, 三筒, 西西, 中中, 白白, 三萬, 三萬, 三萬, 五萬, 五筒
    ```
    
    わりと変わったのですが、ルールは忘れてしまった模様…
    
- 試行5
    
    ```
    **門前パターン**
    
    ・清一色・役牌
    ドラの白を含む9つの筒子で清一色の形を作る
    残りの3つは萬子で三暗刻を狙っていく
    
    上がり牌は九萬または北
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 三萬, 三萬, 三萬, 七筒, 七筒, 八萬, 九萬, 九萬, 中中, 白白
    
    ・三槓子・小三元・断ヤオ九
    三槓子完成後に小三元体制に入れる
    8索で嶺上開花
    上がり牌は五索
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 七筒, 七筒, 八索, 八索, 八索, 三萬, 六萬, 九萬, 白白, 中中
    
    **鳴きありパターン**
    
    ・純全帯么九・一気通貫
    ドラの白を含む純全帯么九の形を als既に7翻に届いているので国士無双を失敗してもあがれる
    上がり牌は六萬
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 七筒, 七筒, 六萬, 九萬, 一索, 一索, 三索, 四索, 北北, 白白
    
    ・嶺上開花・国士無双
    国士無双を狙っていく
    上がり牌は六筒
    牌姿は以下の通り
    
    一筒, 一筒, 二筒, 七筒, 七筒, 八筒, 九萬, 一索, 一索, 三索, 四索, 北北, 白白
    ```
    
    試行4同様、ルールを…
    

※ 結果、自由度の高さからかルールを無視するようになりました
</details>

# おわりに

（何事もそうですが）当初、不気味だなぁと感じていた生成AIも体系的に理解しようとすることで可愛らしいと感じることができました

折角やるなら好きなものを題材に選びたかったのですが、中々アガれる結果を返してくれずいまだに苦心してます

もっといい結果を出せるようなチューニングをしていきたいと思います

特に、今回はサボってしまったのですが例をもっと増やすことでより精度を上げられるようです

プロンプトに書いていくのは大変なので、近いうち言語モデルチューニングにチャレンジしてみようと思います

> チューニング済みテキストモデルは、プロンプトに収まりきらない多くの例でトレーニングされています。このため、事前トレーニング済みモデルをチューニングした後は、元の事前トレーニング済みモデルの場合よりも、プロンプトに表示する例を少なくできます。必要な例の数を削減できることには、次のようなメリットがあります。
> 

cf. [https://cloud.google.com/vertex-ai/docs/generative-ai/models/tune-text-models?hl=ja&authuser=0](https://cloud.google.com/vertex-ai/docs/generative-ai/models/tune-text-models?hl=ja&authuser=0)

※ 最後に、卓上で、スマホをいじるのは多分マナー違反なので実戦では使わないことをオススメします

19日目の [株式会社ビットキー Advent Calendar 2023](https://qiita.com/advent-calendar/2023/bitkey) は @hosht が担当します！