弊社Slack内に蔓延る人ならざるもの「カイル」作ってみた。

## あなたは知っているだろうか…
弊社slackには「カイルという」人ならざる者(Bot)が存在します。

こんな見た目のアイコンです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/0ef0ae3c-db0c-1041-a581-4c2270a66336.png)

[Windowsで見たことある見た目ですね](https://dic.pixiv.net/a/%E3%82%AB%E3%82%A4%E3%83%AB%E5%90%9B)

そんなカイル君はChatGPT-APIを使用して運用されています。

時に暴れたり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/5b1fe5e0-a650-7a55-adfc-0859189cf423.png)

時に詰められたり
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/cba575bc-a012-3b06-98ab-bbbd98e46163.png)

そんなカイルですが、。結構ちゃんと作りました
言語はnode.jsを使用
EC2上でforeverを使って永続タスク化して動かしています。

## 機能紹介
カイルの機能には大きく二つの機能があります。

### 1. 高度な会話機能
カイルの根幹をなす「gpt-4-0613」モデルによる会話機能です。8000トークンの会話記憶能力を持ち、障害が発生しても、直前までの会話はファイルに保存されるため、直前の会話まで記憶しておくことが可能です。

### 2. 機能拡張：Function Calling
「gpt-4-0613」の機能Function Callingを使用し、拡張性を確保しています。
Function CallingはGPT-4にあらかじめ様々な機能(主にAPIをラップしたメソッドたち)の使い方を教えることで
必要に応じてGPT-4から「この機能(メソッド)をこの引数で使用して、その結果教えてー」とくるのでその通りに実行して実行結果を返すことで会話機能の拡充をするものです。

#### 拡充機能1. サイト要約機能
指定されたURLのコンテンツを500文字以内で要約し、情報のキャッチアップを効率的に行います。要約された内容は会話として保存されるため、カイルとの議論の材料にもなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/7d86b986-4c96-53ca-6bb0-0dada4c71c66.png)


#### 拡充機能2. 今日の予定確認
Googleカレンダーと連携し、今日の予定を瞬時に把握します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/3307ba58-2217-dd39-9bd8-aae27599d637.png)


#### 拡充機能3. お天気取得機能
弊社オフィス周辺(新宿)の今日と明日の天気予報を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/45667946-96da-6468-608b-c8fc2e2fe45f.png)


#### 拡充機能4. wikipedia検索機能
wikipediaのAPIを使用し、「gpt-4-0613」の知らない情報はwikipediaから補完し、より正確な情報を提供します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/cf1bcb5d-4084-511d-dc2e-d37079626b0c.png)
GPT-4の学習データは2021年で止まっているので2025年の大阪万博を知らないはずなのですが、このようにwikipediaのAPIをたたいて情報を取得することで回答の正確さを向上させます。

#### 拡充機能5. 画像読み込み機能
「gpt-4-vision-preview」モデルを使用し、画像の内容を読み取り、その解析結果を提供します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/705249/5701c4b7-f5c9-2cda-01f1-393a5d0e9e40.png)

#### Function Callingにはこのような情報を渡しています
```javascript
let functions = [
  {
      "name": "getWebData",
      "description": "Webサイトの文章を取得する",
      "parameters": {
          "type": "object",
          "properties": {
              "url": {
                  "type": "string",
                  "description": "取得したいWebサイトのURL",
              },
          },
          "required": ["url"],
      },
  },
  {
    "name": "getCalender",
    "description": "カレンダーの予定を取得する",
    "parameters": {
        "type": "object",
        "properties": {
            "day": {
              "type": "integer",
              "description": "今日を0日後として、何日後の予定を取得するか",
          },
        },
        "required": ["day"],
    },
  },
  {
    "name": "getWikiData",
    "description": "wikipediaから文章を取得する",
    "parameters": {
        "type": "object",
        "properties": {
            "keyword": {
              "type": "string",
              "description": "wikipeidaから調べたいキーワード",
          },
        },
        "required": ["keyword"],
    },
  },
  {
    "name": "getImageData",
    "description": "imageのURLから画像を読み取り文章を取得する",
    "parameters": {
        "type": "object",
        "properties": {
            "image_url": {
              "type": "string",
              "description": "imageのURL",
          },
            "image_prompt": {
              "type": "string",
              "description": "文章を取得するためのprompt",
          }
        },
        "required": ["url","prompt"],
    },
  }
]

```

## あとがき
node.jsで書いているのですが(なぜそうしたか忘れたけど)プロセスの永続化にforeverつかったりと少し古めなことしてますが
node.jsって動的型付けなので、今まで静的型付けばっかり使っていた自分は困惑しました…
こういうのなれないといけないなぁ。。。

## 宣伝
PsychicVRLabではUnityエンジニア・サーバーサイドエンジニアを募集しています！！ご応募お待ちしています！！
入社するとカイル君触れるよ！

https://www.wantedly.com/projects/1360135

https://www.wantedly.com/projects/1360123