1. はじめに
はじめまして、Sreake事業部インターン生の井上です。私はSreake事業部にてSRE技術の調査と研究を行う目的で2023年3月6日から長期インターン生として参加しています。
本記事では、ChatOpsという概念に基づいて開発したSlack Bot、h1-slack-botとskaffoldを使ったCloudRunへのデプロイについて説明します。h1-slack-botはSlack上でChatGPTの利用を可能にして、ChatOps実現への第一歩を提供します。
2. ChatOpsとは?
ChatOpsは、チャットツールを活用して業務を行う、一連の手法を指します。
運用や開発フローにおけるChatOpsの簡単な例:
- Slackを介してビルド、テスト、デプロイの命令を行うことで、チーム全体がその進捗状況や結果を確認することが可能となります。
- 障害や監視通知をSlackに投稿する仕組みを用意する事で、チーム全体が問題の発生や進行状況を把握することができます。
これらの手法は、ChatOpsの一部として挙げられます。ChatOpsの主な目的は、オペレーション(運用や開発作業)とチャットツールを連携させ、全チームメンバーが作業の進捗や結果をリアルタイムで把握できる環境を作ることです。この結果、問題解決の迅速化、作業の一貫性確保、透明性の向上などを通じて全体の生産性と効率が向上します。
また、Slackは多くの企業で導入されている今、様々な外部サービスと連携できるSlack Botのようなツールは、ChatOpsの実現において重要な役割を果たします。これらのツールを活用することで、作業の自動化が可能になり、チームのコミュニケーションの助けとなり、問題解決を迅速に行うことができます。
特に、OpenAIのChatGPTをSlack Botと組み合わせることで、自然言語処理能力を活用した幅広い作業の自動化が可能になります。ChatGPTは自然言語処理における最先端のモデルで、人間と同様のコミュニケーションを実現します。
このような組み合わせを用いることで、以下のような事例が実現できます:
- チームメンバーからの問い合わせに自動的に回答する
- チームメンバーからの要求に基づいてタスクを自動化する
- チームの会話から重要な情報を抽出し、それをトラッキングする
- 進行中の議論の要約・補助を行う
以上の例は一部に過ぎません。ChatGPTの高度な自然言語理解能力を活用すれば、さらに多様な自動化や効率化の可能性が広がります。
また、3-shakeではSRE支援ソリューションを行っています。SRE支援の一つの手法としても、ChatOpsは有効な手段になる可能性があります。クライアント企業内でのChatOpsの導入により、運用業務の透明化や効率化、さらには問題解決の迅速化を実現することが可能です。
例えば、ChatGPTと組み合わせたSlack Botは、運用状況のレポート生成やトラブルシューティングのガイダンス提供、さらにはインシデント管理の自動化など、SRE業務のさまざまな面で活用することができます。これにより、クライアント企業の運用安定性向上と効率化を実現し、我々のサービス価値を高めることができます。
3. Slack × ChatGPT = ChatOpsの第一歩
概要
ChatOpsの第一歩として、Slack上でChatGPTとの対話を実現する「h1-slack-bot」を作成しました。h1-slack-botの主な動作原理は以下の図の通りです。
h1-slack-botがメンションされた際にトリガーされるイベントハンドラを利用して、メンションされた内容とその会話履歴を基に、ChatGPTが応答を生成し、その応答を返します。
メンションがスレッド内で行われていた場合は、そのスレッドの会話履歴を取得し、それをChatGPTに渡して適切な応答を生成します。
ChatGPT APIの利用時において、ユーザの発言とChatGPTの発言は、内部的に差別化する処理を行っています。
Slack上から設定値の変更を行う機能
また、h1-slack-botの設定値をSlack上から編集出来る機能や、現在読み込まれている設定の表示機能が搭載されています。また、現在利用可能なChatGPTのモデル一覧を表示して、Slack上から切り替える事も出来ます。
再帰的要約機能(RSF: Recursive summarise function)
再帰的要約とはChatGPT APIの入出力制限(Token上限)を緩和するために編み出されたテクニックです。このテクニックは、以下の様に行われます。
- 長い文章を文字数を基に分割(分割された文章をチャンクと呼ぶ)
- チャンク毎に要約
- 全体の文章量を大きく削減
従って、ChatGPT APIの入出力制限をToken制限を疑似的に回避する事ができます。また、h1-slack-botでは、モデルのToken上限と閾値を別途設定して、これを元に、再帰的要約が行われます。この手法のメリットデメリットは以下です。
- メリット
- チャンク上限まで情報を詰め込めるので、後述と手法と比較して、繰り返し要約の依頼回数が減ります。
- デメリット
- 文章が中途半端に区切られて、要約精度低下や要約の重複の可能性があります。
デメリットを克服するため、以下のような仕組みを考案して、h1-slack-botに実装を行いました。
この仕組みは、設定したToken値以下になるまで、ユーザのメッセージをチャンクに詰め込み、要約を行います。ただし、1メッセージでToken値を超過する場合は、超過メッセージに対して前手法を適用します。この手法のメリット・デメリットは以下です。
- メリット
- 文章が途中で途切れずに要約を実現するので、前手法と比べ要約精度の向上が期待できる。
- デメリット
- チャンクの中身にムラが出来るので、繰り返し要約の依頼回数が増加します。
補足 ChatGPTのToken制限について
ChatGPT APIのこのToken制限は、ChatGPT APIへの入力と出力される文章のToken上限を制限しています。つまり、入力時にTokenを使いすぎると、出力時点でToken上限に達して、文章が途切れる事があります。例えば、gpt-3.5-turboの合計Tokenは4096です。Token数を計算するPythonのライブラリとしてはtiktokenがあります。
使用した技術について
- ChatGPT API
- Docker
- Python3.9
- slack-bolt==1.18.0
- slack-sdk==3.21.2
- openai==0.27.5
- PyYAML==6.0
- tiktoken==0.4.0
4. Skaffoldを利用したCloud Runへのデプロイ
本記事では、上記図の様にmCI/CDツールのSkaffoldを利用して、Google Cloudが提供するCloud Run上に、h1-slack-botをデプロイします。開発者がSkaffold runを実行すると、マニフェストファイルに従い、skaffoldがh1-slack-botのDocker imageをビルドします。ビルドしたイメージは、Artifact RegistryにPushされます。最後に、SkaffoldがCloud Runにデプロイを行います。
ディレクトリ構成は以下です。
.
├── docker-compose.skaffold.yaml # Skaffoldを実行するためのDocke Compose
├── h1-slack-bot # CI/CD対象のアプリケーションフォルダ
│ ├── Dockerfile
│ ├── LICENSE
│ ├── README.md
│ ├── config.yaml
│ ├── contexts
│ │ ├── chat_gpt.py
│ │ ├── command_handler.py
│ │ ├── debug.py
│ │ ├── get.py
│ │ ├── help.py
│ │ ├── help.txt
│ │ ├── main.py
│ │ ├── model_handler.py
│ │ ├── personal_expansion.py
│ │ ├── requirements.txt
│ │ ├── rsf.py
│ │ └── tokens.py
│ ├── docker-compose.yaml
│ └── sample.env
├── resources
│ └── cloud-run-service.yaml # Cloud Runのマニフェストファイル
└── skaffold.yaml # Skaffoldのマニフェストファイル
Google Cloud Run
Google Cloud Runは、Google Cloud Platform (GCP) が提供するフルマネージドなサーバレスプラットフォームです。任意のステートレスコンテナをホスティングし、HTTPリクエストに対応できるようにすることができます。
Cloud Runの主な特徴は以下の通りです。
- コンテナ化されたアプリケーションの実行
あらゆる言語やライブラリを使用して作成されたアプリケーションを実行できます。唯一の要件は、アプリケーションがHTTPリクエストを受け取り、HTTPレスポンスを返すことができるようにコンテナ化することです。 - フルマネージド
サーバーのプロビジョニング、パッチ適用、サーバー管理等を手動で行う必要がありません。 - 自動スケーリング
トラフィックが増えた時には自動的にスケールアウトし、トラフィックが無い時には0までスケールダウンします。これにより、リソースの使用効率を最大化しつつ、コストを最小化することができます。
なぜCloud Runか?
Slack Bot構築にあたり、事前の調査で、Cloud Runを利用している記事が数件あったため、先駆者に倣い、Cloud Runへデプロイを行います。また、元々Dockerコンテナで構築していたという理由もあります。 参考記事1、参考記事2
ただし、Google Cloud Runでは、今回の様なバックグラウンドプロセスを動作させるケースにおいて、3つの問題点があります。
- Webサービスを動作させる事が前提のサービスなので、コンテナのポートが空いていないとエラーでデプロイできません。デフォルトで8080ポートが空いている必要があります。
- ポートへのHTTPアクセスが無いと、Google Cloud Runは0にスケールインします。最小スケール数を設定する必要があります。
- Google Cloud Japan Teamや公式ドキュメントによれば、Google Cloud Runではリクエストやイベント処理以外では、CPU割り当てが発生しません。常時稼働CPUを割り当てる必要があります。
解決策
問題点1に関しては、Dockerコンテナにslack-botとhttp.serverを同時に動作させることで解決しました。
# ベースイメージを指定
FROM ubuntu:22.04
# タイムゾーンの選択肢をスキップ
ENV DEBIAN_FRONTEND=noninteractive
# パッケージリストを更新
RUN apt-get update && \
apt-get install -y software-properties-common && \
add-apt-repository ppa:deadsnakes/ppa -y && \
apt-get update && \
apt-get upgrade -y
# Python 3.9をインストール
RUN apt-get install -y python3.9 \
python3-pip
# コンテキストをイメージにコピー
COPY ./contexts/ /root/contexts/
WORKDIR /root/contexts/
# Configをイメージにコピー
COPY ./config.yaml /root/contexts/config.yaml
# 必要なPythonライブラリをインストール
RUN pip3 install -r requirements.txt
# ENTRYPOINT ["python3", "main.py"]
# CMD nginx && python3 main.py
CMD mkdir -p /tmp/none && \
cd /tmp/none && \
python3 -m http.server 8080 & \
cd /root/contexts/ && \
python3 main.py
問題点2, 3に関しては、後述のskaffoldによるデプロイで作成するcloud-run-service.yamlに、Google Cloud Runへのデプロイ時の引数に--no-cpu-throttling
と--min-instances=1
を記述する事で解決します。
Skaffold
SkaffoldはGoogleが提供するコマンドラインで動作するCI/CDツール、ビルド、デプロイ、テスト関連の機能が実装されています。CI/CD対象のアプリケーションはコンテナ化される事が前提で、KubernetesやCloud Runに対応しています。本記事では、v2.3.4で行っています。
1.skaffold.yamlを用意して適宜必要なものを記述します。
# skaffold.yaml
apiVersion: skaffold/v4beta4
kind: Config
metadata:
name: h1-slack-bot
build:
artifacts:
- image: app
context: ./h1-slack-bot/
docker:
dockerfile: "Dockerfile"
manifests:
rawYaml:
- resources/*
deploy:
cloudrun:
projectid: <YOUR PROJECT ID>
region: <YOUR REGION>
2.cloud-run-service.yamlを用意します。主にCloud Run周りの設定をここで行います。
# cloud-run-service.yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: h1-slack-bot
spec:
template:
metadata:
annotations:
run.googleapis.com/cpu-throttling: "false" # 常時稼働CPU割り当て
autoscaling.knative.dev/minScale: "1" # 最小スケール数を設定
autoscaling.knative.dev/maxScale: "1"
spec:
containers:
- image: app
resources:
limits:
memory: 1Gi
env:
- name: SLACK_APP_TOKEN
value: <YOUR SLACK_APP_TOKEN>
- name: SLACK_BOT_TOKEN
value: <YOUR SLACK_BOT_TOKEN>
- name: OPENAI_API_KEY
value: <YOUR OPENAI_API_KEY>
- name: ORGANIZATION_ID
value: <YOUR ORGANIZATION_ID>
3..envファイルにARTIFACT REGISTRYの情報を記述します。予めリポジトリを作成する必要があります。
SKAFFOLD_DEFAULT_REPO=<YOUR ARTIFACT REGISTRY>
4.docker-compose -f docker-compose.skaffold.yaml up -d
でskaffoldによるCI/CDが始まります。本記事では、以下のDocker-Composeを用いて、skaffoldを利用します。ここで、Host OSのgcloud認証を利用してCloud Runへのデプロイを実現しています。CI/CD終了後、コンテナは自動的に停止します。
version: '3.1'
services:
Skaffold:
image: gcr.io/k8s-skaffold/skaffold:v2.3.4
volumes:
- .:/root/project
- /var/run/docker.sock:/var/run/docker.sock
- $HOME/.docker:/root/.docker
- $HOME/.config/gcloud:/root/.config/gcloud # HostOSのgcloud認証を利用
working_dir: /root/project
entrypoint: ["sh", "-c", "skaffold run --default-repo ${SKAFFOLD_DEFAULT_REPO}"]
env_file:
- .env
Google Cloud側の設定
- Cloud RunやArtifact Registryに関する権限を自身のアカウントに与えてください。
5. 実際に使用してみてどうなのか?
デプロイ後、3-Shakeの皆様がどのような感じで使っているか見ていきましょう。雑談から相談事、仕事等h1-slack-bot(testbot-hide1)に問い合わせています。
実際に、ChatOpsできているか?という点についてですが、このようなスレッドがありました。スレッド内でレシピを書いていき、markdown化するという「タスクの自動化」を行っています。
ChatGPTと違い、他のメンバーにも自然と議論内容が見えるため、チームメンバーの相談内容、悩み、作業内容が可視化され、透明性向上やタスクが効率化が期待できます。今後の展望として、ChatGPTと外部連携を実現するLangChainやFunction Callを利用して、よりインタラクティブにChatOpsが行える様に取り組みたいと考えます。
6. まとめ
本記事では、ChatOpsについて説明しました。次に、Slack × ChatGPT = ChatOpsの第一歩として、Slack上でChatGPTが利用できるh1-slack-botを作成して、その機能説明や、Skaffoldを用いてGoogle Cloudへデプロイする方法についても言及しました。
参考文献
- https://www.systems-inc.co.jp/solutions/484/#:~:text=ChatOpsとは?,化を行えるものです。
- https://tintri.co.jp/blog/chatops/
- https://chatops.jp/
- https://qiita.com/m_mizutani/items/f7fa7b1d1c077b139f98
- https://techblog.gmo-ap.jp/2023/04/17/connecting-slack-app-with-chatgpt/
- https://future-architect.github.io/articles/20230626a/