🧑‍💻

GPT から Linux マシンを操作して作業をしてもらう

2023/03/23に公開

ChatGPT の API が面白そうだったので気軽に触り始めたらすっかりのめり込んでしまいました。久々に新しいテクノロジーにワクワクしながら過ごしています。

どんなことができるのかと色々と試していたところ、GPT に Linux マシンを渡したらどんなことが起こるのだろうと思ったので gptask というコマンドラインツールを開発して色々と実験をしてみることにしました。

https://github.com/summerwind/gptask

セットアップ

まだ実験段階なので gptask は実行可能なバイナリやコンテナイメージは配布していません。そのため、使うにはまず Docker を使ったコンテナイメージのビルドが必要になります。Docker をすでにインストール済みの環境であれば、リポジトリをチェックアウトして次のようにしてコンテナイメージをビルドしてセットアップしてください。

$ docker build -t gptask:latest .

使い方

セットアップが完了したら、次のようにして gptask のコンテナを実行します。

$ docker run \
    -it --rm \
    -e "OPENAI_API_KEY=$OPENAI_API_KEY" \
    -v "$PWD/workdir:/opt/gptask" \
    gptask:latest \
    gptask "あなたのタスクは..."

$OPENAI_API_KEY には OpenAI の API キーを設定してください。また /opt/gptask にディレクトリをマウントするのは任意です。GPT はこのパスを作業用ディレクトリとして使用するので、GPT がタスクの中で作成したファイルを取り出す場合に使用します。

しくみ

gptask の内部では次のような流れで処理を実行しています。引数にタスクの定義を記述します。

  1. 引数に指定したタスクの定義を gptask が OpenAI API を使って GPT に渡す
  2. GPT がそのタスクの実行に必要なコマンドを出力する
  3. gptask が出力されたコマンドを実行し、その結果を GPT に渡す
  4. GPT が結果をもとに次に必要なコマンドを出力する
  5. タスクが完了するまで 3 から 5 を繰り返す

コンテナで実行するのは GPT がどうタスクを処理するかが分からないので、コンテナ内に閉じ込めて外部への影響を最小化するためです。

実行例

ここからは gptask タスクの実行例をいくつか紹介します。

画像ファイルの変換

この例では PNG 形式の画像ファイルを JPEG 形式のファイルに変換するタスクを実行してもらいます。gptask に入力したタスクの定義は次のとおりです。

'sakura.png' ファイルを JPEG 形式に変換し、'sakura.jpg' として保存してください

出力結果は次のようになりました。ステップ1で convert コマンドを実行してファイルを変換したようです。この convert というのは ImageMagick に付属するコマンドですが、実は事前にインストールしたものなので、ちょっとだけチートしています。

Step 1: ImageMagick を使用して、'sakura.png' ファイルを JPEG 形式に変換し、'sakura.jpg' として保存します。
Action: shell
convert sakura.png sakura.jpg

実際に GPT が作成した画像は次のとおりです。

sakura.jpg

RSS フィードのダウンロードと整形

この例では RSS フィードをダウンロードして記事のタイトルと URL を抽出し、Markdown 形式でファイルに出力するタスクを実行してもらいます。gptask に入力したタスクの定義は次のとおりです。

あなたのタスクは次のステップに従って実行してください。エラーが発生した場合は修正してください。

1. URL 'https://blog.summerwind.jp/index.xml' の内容をダウンロードして 'feed.xml' という名前で保存してください。
2. 'feed.xml' ファイルに含まれるRSSフィード形式のデータから記事のURLとタイトルを5件抽出し、Markdown形式に変換して 'articles.md' というファイルに保存してください。

実行ログは次のようになりました。ステップ1で curl コマンドを使って RSS フィードをダウンロードしています。ステップ2では Python のコードを実行してダウンロードした RSS フィードの内容を整形し、ファイル articles.md に書き出しました。

Step 1: 次のステップでは、XMLファイルから情報を取得して、Markdown形式でファイルに書き出す必要があります。このタスクにはPythonのxmlライブラリを使用することができます。
Action: shell
curl -o feed.xml https://blog.summerwind.jp/index.xml
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 32767    0 32767    0     0   197k      0 --:--:-- --:--:-- --:--:--  198k


Step 2: XMLファイルの内容をダウンロードして、ファイルが存在することを確認したので、xmlライブラリを使用してタイトルとリンクを抽出する必要があります。
Action: python
import xml.etree.ElementTree as ET

tree = ET.parse('feed.xml')
root = tree.getroot()

with open('articles.md', 'w', encoding='utf-8') as f:
    f.write('# 投稿一覧\n\n')
    for i, item in enumerate(root.findall('./channel/item')):
        if i == 5:
            break
        title = item.find('title').text
        link = item.find('link').text
        f.write(f'## [{title}]({link})\n\n')

書き出されたファイルの内容を確認すると次のようになっていました。リストにならなかったのはやや期待外れですが、タスクの定義に明記しなかったのでやむなしでしょう。タスクとしてはたしかに Markdown ファイルが作成されたので完了しています。

# 投稿一覧

## [Actions Runner Controller と OSS](https://blog.summerwind.jp/posts/20221217/)

## [JR東日本パスで東北へ](https://blog.summerwind.jp/posts/20221029/)

## [2022年の夏休み](https://blog.summerwind.jp/posts/20220911/)

## [RFC 9113 (HTTP/2) 日本語訳](https://blog.summerwind.jp/posts/20220809/)

## [小矢部市でワーケーション](https://blog.summerwind.jp/posts/20220130/)

その他のユースケース

他にも以下のようなタスクが実行できることを確認しています。なお、ここまでの例を含めて全て GPT-3.5 のモデルを使用しています。

  • AWS の Security Group のうち全開放になっているルールを見つけてきて削除する
  • 固定のレスポンスを返す AWS の Lambda Function を実装し、デプロイ可能な zip ファイルを作成後、AWS にデプロイする

必要なコマンドがない場合はエラーを見て apt get したり、AWS の操作時に必要な IAM ロールがない場合は自分で作成するなど、エラーリカバリをちゃんとしてくれたりするので驚きました。

最後に

ここまでにいくつか実行例を紹介しましたが、実用的かというとまだそうとも言えません。

実際に gptask を実行してみると分かるのですが、タスクの全てのステップをすんなり実行できることは少なく、何度か試してみてようやくうまくいく、という感じです。とりわけ以下のようなエラーを回避したりデバッグしたりするのは苦手なようです。

  • ワンライナーに含まれてしまった意図しない文字の訂正
  • Python スクリプトで意図しない出力が出てきた場合の修正

GPT-4 を使えば部分的には改善しますが、今は API に実行回数制限があるので自分もあまり試行錯誤できていません。安定してタスクが実行できるような方法をもう少し実験して考えてみようと思います。

免責事項

gptask は誤った使い方をするとマシンや外部のサーバーに意図しない悪影響を及ぼす可能性があります。このソフトウェアを用いて行う一切の行為に関連するあらゆる損害に関して、理由の如何に関わらず筆者は一切の責任を負いません。

謝辞

  • ChatGPT を色々試している時に、@qluto さんから LangChain で色々できることを教えてもらい、これが今回の実験のきっかけになりました。どうもありがとうございました。
  • 実験の当初は LangChain の Agent を使用して色々試していました。便利なフレームワークを開発してくれたプロジェクトの貢献者のみなさんに感謝しています。

Discussion