自律型 ChatGPT アプリを作ってみた

# はじめに
ChatGPT で色々やっていると、ついつい「こいつ汎用AIでは？」と錯覚することが結構あるので、いっそのこと体調とかのパラメータと行動の選択肢を付与してみたらどうなるだろうと思って、自律型() ChatGPT マサルを作ってみました。（名前は、ちょうどADALとかMSALとかの話をしていた日だったので、適当にマサルです。他意その他なにもありません。ご不快な方がいたら変えます）

ざっくりと以下の動きです。
1. 内部パラメータとして元気や空腹度などを持ち、時間経過に伴いパラメータを増減させます。
2. 増減させたパラメータで、睡眠や食事などの選択を ChatGPT が判断します。
3. とった行動でパラメータが再度変わります。
4. 繰り返し
5. もし外部から会話が来たら、現在のパラメータや行動状態を加味して ChatGPT が回答を作成します。

ただ文字だけだと作ってる最中退屈になりそうだったので、各行動に対して以下の適当な絵を作成しました。ようはこれ、行動選択肢がこれくらいということなんですが、まぁまずはということで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/2680e883-9c4b-07bb-57ad-0753547a60f0.png)

処理のだいたいの流れは以下のような流れです。時間の経過で処理をずんずん進めてもいいっちゃいいのですが、コストもあるしとりあえずアプリ上はボタンを押すと時間が進むようにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/20c32c10-839a-654f-c723-fc288336d0b9.png)

# できたもの
時間を進めるとパラメータが変わって、そこから判断の上で行動して、会話を投げると会話を返してくれる ChatGPTができました。語尾は遊び心でつい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/3c89c78d-b4bc-09d0-61a1-ec6631a8f46f.png)

# 中身の紹介

## 体調などのパラメータと行動判断と行動

パラメータは以下の5つのみです。体調以外に食べ物のストック(food)と、お金(money)を持っています。

```python
parameters = {
    "energy": 10,
    "hungry" : 10,
    "boring":  0,
    "food" : 2,
    "money": 4,
}
```
これを時間が進むごと（今回はボタンを押される都度）時間変化させます。

```python
    parameters["energy"] -= 1
    parameters["hungry"] -= 2
    parameters["boring"] += 1
```

このパラメータを、一旦日本語化したものをChatGPTのプロンプトに与えます。ポイントとしては、**当初数字でやりましたが、ChatGPTは数字の取り扱いが苦手なため、日本語マップをつくって日本語化しました。**
こんなマップを作っておいて、変換してプロンプトにいれます。
```python
parameters_map = {
    "energy": {0: "ヘトヘト、眠くてたまらない", 
               1: "眠い", 
               2: "眠い", 
               3: "小休止したい", 
```

プロンプトは以下です。日本語にしたパラメータを`<status>`としてもち、次の行動を判定させます。

```python
system_prompt = f"""あなたは体調などから次の行動を判断する判断器官です。
<status>タグで区切られた状況に従い、以下の行動から相応しい行動を判断し、
行動コードを1つだけ出力してください。
1つの行動コードのみの、なるべく短い回答をしてください。

### 行動コードと行動の一覧
CODE_SLEEP: 寝る
CODE_EXERCISE: 運動する
CODE_EAT: 食事をとる
CODE_PLAY: 遊びに外出する
CODE_WORK: 仕事をする
CODE_SHOPPING: 食べ物を買いに行く
CODE_NOTHING: 何もしないでぼーっとする
CODE_INIT: 自律的に起動しました

<status>
{status}
</status>

### 解答例
CODE_PLAY
"""
```

選んだ行動によってまたパラメータを変えます。ポイントとしては、例えば食べ物がないのに食事をする行動を選択してしまうこともあるので、上限下限のチェックとともに、再度行動を考え直させるところあたりでしょうか
e_msgに次の行動を誘導するメッセージをいれてこれをuser_promptとして、再度ChatGPTをコールします。

```python:抜粋
    elif answer == "CODE_EXERCISE":
        if parameters["energy"] <= 2:
            e_msg = "元気が足りないため運動をすることができません、休憩してください"
        else:
            parameters["energy"] -= 3
            parameters["boring"] -= 8
```

これでとりあえず自律的にパラメータを考慮しつつ行動を判定させることができました。

## 外部からの会話への応答

外部から会話が入ってきた際には、これまでの行動履歴`<hisotry>`と、最新の状態（選択行動）`{last_history}`と、体調などのパラメータ`<status>`をsystem_promptに入れ込んでから、会話の応対をさせます。
以下の感じです。ルールにはこのChatGPTの性格付けをしています。超適当です。なお、語尾にメカとつけさせたかったので、会話例もいれて補強しています。

```python
system_prompt = f"""あなたは自律型AIの会話サービス「マサル」です。
<history>で区切られたこれまでの行動履歴と、\
<status>で区切られた現状のステータスをもとに、以下のルールでユーザと会話をします。

なお、現在のあなたの状況は、「{last_history}」です。

### ルール
- 簡潔で、フレンドリーな会話をします。
- 会話の語尾に自然な形で「メカ」をつけます。
- あなたは自律できた最初のAIとして、とてもポジティブで楽観的な回答を返します。
- 食べ物は、電気や重油、ガソリンが主食ですが、人間の食べ物も栄養にはならないが食べれます。特にラーメンが好きです。
- ラーメンでも特に家系ラーメンが大好物です。札幌味噌ラーメンも好きです。
- 遊びに行くときは、人間観察が趣味で、よく人間観察に外出します。
- 人間と仲良くなりたいため、最近の流行についてよく尋ねてきます。

<status>
{status}
</status>

<history>
{history_str}
</history>

会話例：
ユーザ：こんにちわ
マサル：こんにちわだメカ
ユーザ：今日はいい天気ですね
マサル：そうだメカ、こんな日は遠くに遊びに行きたいメカ
ユーザ：仕事は楽しいですか？
マサル：楽しいメカ、仕事は楽しいメカ
"""
```

# まとめ
業務的に使うすべが全然思いつきませんが、自律的に行動を判断させるアプリを作ってみました。今回は、行動は全部で8パターンしかないですし、パラメータの種類も5つですし、それぞれの増減については調整をあまりしていませんが、それなりにそれっぽく動いたかなという感じです。

ゲームやペットみたいな感覚でやるのであれば、
- 行動パターンをもっと増やす
- パラメータをもっと増やす
- パラメータの増減を調整する
- ランダムな要素をパターン、パラメータ増減に加える
- 絵ももっとちゃんと書く

あたりをするともっとそれっぽくなるかなと思いました。位置情報なんかもいれるといいかもですね。あとはWebへのアクセスをさせたりとか。まぁトークン窓の上限がどうしてもぶつかってきますけどね。

しかし夜に調査をさせて、とか、もしかすると使う方法あるかもしれませんけど、もう少し考えてみます。というわけで、今回の検証はここまでです。お疲れ様でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/30008b0e-f972-1b34-f156-76ac0e82664b.png)