ChatGPTにOS管理運用をまかせてみた（かった）

ChatGPT/GPT が面白すぎて、色々と触ってみてきました。 [前々回の記事]()では業務システムっぽい動きを試してみたり、[前回の記事]()ではGitHubのデータをサマリーさせてみたり。

今回は、「**もういっそのこと、ChatGPTにOSコマンド実行させてみたい**」という検証です。理想的には勝手にメンテナンスしてくれたらいいなくらいの気持ちでした。
なお、今回使用したモデルも"ChatGPT-3.5-TURBO"です。早く4でやりたいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/c344de96-ce29-0e2e-eee9-9e90991ceca4.png)
1. ChatGPTに、OSに関する質問や依頼をする
1. ChatGPTが回答する、必要なコマンドがあればそれも返す
1. OS上でコマンドを実行する
1. 結果を必要に応じて再度ChatGPTに伝える
※繰り返し

# 作ったアプリケーションとざっくり結果
前回と前々回同様、フロントにVue3.2(CDN)+バックエンドにExpress のライト構成です。
画面はこんな感じです。（とりあえず、ネットワークの状況について聞いてみたら、ping google.comを打てば？と応答があって、それを実行した結果を、再度chatgptに送ったところ、「良好と言えます」と返ってきた状況です）

やっぱり自動でOSコマンドの実行は怖くてできませんで、左パネルがchatgpt とのチャットで、そこでOSコマンドが提示されていたら右パネル側で実行できるようにしました。へたれました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/08b52eaf-754a-5baf-800c-1caf2f833a51.png)

コードは[shyamagu/chatos](https://github.com/shyamagu/chatos)に置いてあります。
ただし、あとで説明しますが、**脆弱性の塊みたいなアプリケーション**です。なので、**決してインターネットから不用意にアクセスできる環境では利用しないでください**。
実行したければローカル環境か、あるいはネットワークをガチガチにしばってくださいね。

以下色々と試してみたサマリーです。

### よかったところ
- 何していいかわからない時にコマンドを提案してくれるので、用途でコマンド検索するよりも楽なシーンがありそう
- チャットしながら提案コマンドを試したりしながらChatGPTと会話ができるのは面白い

### いまいちだったところ
- ある程度主体的な回答も期待していたけど、いつものChatGPT節。（プロンプト次第？）
- OSコマンド実行を"child_process"パッケージでやったところ、権限や入力待ちなどでうまく実行できないコマンドが多々ある
- 結局これをして欲しいという知識がないと、ChatGPTと一緒に堂々巡りしてしまう

### 期待できるところ
- **運用手順書とかマニュアルとかをプロンプトに取り込めば、かなりそれっぽい回答になりそう**
- GPT-4とかになればもう少し回答の改善が期待できそう

というわけで、以下は個別の説明です。

# 画面構成と動きの説明
CSSのdisplay:flexって素晴らしいですね。やりたいことがさっくりできました。（ありがとうBing Chat)

基本的な流れと画面構成は以下の通りです。
1. ユーザ入力（「ネットワークは良好？」などの問いかけ）
1. ChatGPT による応答（「ping google.comすべし」という応答)
1. 提案コマンドの確認と実行
1. コマンド実行結果の確認
1. コマンド実行結果を再度chatgptに送る
1. ChatGPT による分析（「良好ですね」という回答）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/5033cce9-628a-dde2-e839-8f12654839fd.png)

# ChatGPTのAIモデル
OpenAI のSDKを用いて以下のメソッドで実現しています。
```js
async function getChatGPTAnswer(messages) {

    let chatgpt_messages = messages.map((obj)=>{
        const role = obj.by;
        const content = obj.message;
        return { role: role, content: content}
    })
    chatgpt_messages.unshift({ role: "system", content:`
    あなたはIT運用プロフェッショナルとして、${process.env.YOUR_OS}のOSマシンを管理してます。
    もしOS側のコマンドを実行する必要があるときは、回答末尾に以下の形でコマンド候補を１つだけ返してください。
    CHATGPT_OS_COMMAND:コマンド
    **コマンドはクォーテーションやダブルクォーテーションで囲まないでください**
    **Windowsの場合、PowerShellは使えません、コマンドプロンプトだけでの作業となります**
    **コマンドを提示する場合は、回答の最後に、CHATGPT_OS_COMMANDを必ずつけてください**
    **コマンドを提示する必要がない場合は、CHATGPT_OS_COMMANDは絶対につけないでください。**
    `})

    // OpenAIのAPIに問い合わせる
    const completion = await openai.createChatCompletion({
        model: "gpt-3.5-turbo",
        messages: chatgpt_messages,
        temperature: 0.5,
    });
    const response = completion.data.choices[0].message.content
    return response
}
```

- 環境変数より管理しているOSを設定してます。
- 会話履歴も重要なので、unshiftでsystemのプロンプトをいれてます

ちなみに、同じ内容の英語も試してみたのですが、**英語の方がやっぱりなんか精度がいい**ですね。今回コマンドが必要なら文末にCHATGPT_OS_COMMAND:コマンドの形式を依頼しているのですが、英語だとまず間違いなくこのルールにのっとってくれます。日本語だとたまにルールを完全に忘れて回答してきました。

# OSコマンドの実行

ここは"child_process"モジュールを使ってさっくりと実現です。
```js
app.post('/execute', async (req, res)=>{
    const command = req.body.command;

    exec(command, (error, stdout, stderr) => {
        if (error) {
            res.json({
                output:JSON.stringify(error)
            })
        }else if(stderr){
            res.json({
                output:JSON.stringify(stderr)
            })
        }else{
            res.json({
                output:JSON.stringify(stdout)
            })
        }
    });
})
```

脆弱性の塊というか、脆弱性そのもののなコードですｗが、検証なのでまぁ良しとしちゃいます。もしこれで使うとなったら、ネットワークをガッチガチに縛るか、やっぱりきちんとした認証を付与しないと怖くて使えませんｗ

なお、Windowsの場合Shift-JIS の関係でコマンド実行結果が文字化けしちゃうことがありますが、ChatGPTは文字化け含めてうまい具合に見てくれたりすること、またこのアプリの出番はむしろLinuxの気がしてならないので、一旦対応は保留です。

# 色々と聞いてみる (Windows11編)
パッチの最新状況について聞いてみたところ、KBの情報までは辿り着けました。
でも本当はこれで最新なのかを教えてほしいところですね。まぁChatGPT的には不可能な機能なんですが… Bing Chat API とかあればなぁ。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/fa445d90-48c0-bc7e-6fd7-a6525f559190.png)

あとはイベントログのエラーも wevtutil qe System /C:1 /rd:true /f:text を提示してくれました。冒頭にはったネットワーク状態に関するやりとりも含めて、なかなか悪くない感じですね。

# 色々と聞いてみる (Linux編)

Azure上にLinux VMたてて、そこでアプリを実行してみました。

## 最初にやることを聞いてみる

topすると入力待ちになってしまうので、一旦実行は見送って、次にやることを聞いたらサービスの確認とかを提示してきました。（有識者に聞いたらetc/hostsの確認だろが！とか言われましたけどw）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/153a035f-eb15-01e8-79cf-5d98bd5d3f6b.png)

## ディスクやメモリーが聞いてみる

容量を聞いてみました。df -h を提案してきました。これ結果を再度ChatGPTに送るときちんと説明してくれるのはいいですね。（今回のケースならみりゃ分かるという話ですが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/cd8123e0-d1fa-59d5-2d33-30ab214651e9.png)

## CPUを一番使っているプロセスを聞いてみる

top -b -n 1~~~ を提示してきました。これだけだとスナップショット的な感じであんまり意味はないですが、これ何？っていうときに少し楽に調べられるかもですね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/977156/b511e6cc-c0c1-d691-14ec-2a75cc86916a.png)

# まとめ

もうAIに運用保守まかせられないかな？と思って作ってみたアプリでしたが、それなりに楽しく触れました。特にOSコマンドを全然知らない場合なんかは、検索するよりもChatGPTに聞きながら、かつ、簡単にコマンド実行を試しながら触れるので、これはこれでありかも、という感じでした。
運用保守の知見のある人が触ったときにどう思うか聞いてみたいところです。

ただ本来の目的であるメンテナンスをしてもらう、まではまだちょっと遠い感じですね。モデル自体の改善、プロンプトの再検討、パラメータの調整、独自マニュアルや運用手順などの取り込み、なんかはやらないとダメそうですね。

でも、いずれはプロセスに常駐させてしまって、問題が起きたら or 起きそうになったら勝手にメンテナンスしてもらうまで、いずれはできるのでは？という可能性を感じました、というところで今回の検証はひとまず終わりです。