コマンドプロンプト、PowerShell、Linuxで生成AIを呼び出すコマンドを作る

# はじめに
Linuxのコマンドに慣れていると、たまにコマンドプロンプトを扱う際にコマンドや仕様が分からなくてもどかしくなることがあるんじゃないかと思います。(逆もまた然り)
今回はそのような場合にいちいち検索せずともコマンドや仕様を調べられるように、ChatGPTをコマンドで呼び出す方法を紹介します。一応コマンドプロンプト、PowerShell、Linuxのそれぞれで使えるものを(~~主にAIが~~)作成しました。(.bat、.ps1、.sh について作成しました)

# 作成したコード
:::note info
OpenAIのAPIキーはご自身のものを利用してください
:::
### コマンドプロンプト
コードは以下の通りです。
```bat
@echo off
REM コードページをUTF-8に変更
chcp 65001 >nul
setlocal enabledelayedexpansion

REM -pオプションの引数を取得
set "PROMPT="
for %%i in (%*) do (
    if "%%i"=="-p" (
        set PROMPT=1
    ) else if defined PROMPT (
        set "PROMPT=%%i"
        set PROMPT_FOUND=1
    )
)

REM -pオプションが指定されていなければエラーメッセージを表示
if not defined PROMPT_FOUND (
    echo エラー: -p オプションが必要です。
    exit /b 1
)

CALL :escapeJSON "%PROMPT%" ESCAPED_PROMPT

REM 日本語メッセージをエスケープ後のプロンプトに結合
SET "ESCAPED_PROMPT=日本語で回答してください。あなたはコマンドプロンプトを使う私をサポートしてください。%ESCAPED_PROMPT%"

curl -s -X POST "https://api.openai.com/v1/chat/completions" ^
     -H "Content-Type: application/json" ^
     -H "Authorization: Bearer <OpenAIのAPIキー>
     -d "{\"model\": \"gpt-4o-mini\", \"messages\": [{\"role\": \"user\", \"content\": \"%ESCAPED_PROMPT%\"}], \"max_tokens\":500 }" | powershell -Command "[Console]::OutputEncoding = [Text.Encoding]::UTF8; ($input | ConvertFrom-Json).choices[0].message.content"

GOTO :EOF

REM エスケープ関数の定義

:escapeJSON
SET "str=%~1"
SET "str=%str:\=\\%"
SET "str=%str:"=\"%"
SET "%~2=%str%"
GOTO :EOF
```

コード上でコマンドプロンプトを使う旨を宣言しています。
```
gpt -p {プロンプト}
```
のように実行してください。

**実行例と結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841947/d4f36c13-7e47-a7b5-dba8-d108d2608677.png)


### PowerShell
コードは以下の通りです。
```powershell
param (
    [string]$p  # プロンプトとして入力する文字列
)

function gpt {
    # APIエンドポイントとキーの設定
    $apiUrl = "https://api.openai.com/v1/chat/completions"
    $apiKey = <OpenAIのAPIキー>
    
    # プロンプトの文字列結合を事前に実行
    $prompt = "日本語で回答してください。あなたはPowerShellを使う私をサポートしてください。\n "
    $fullPrompt = $prompt + $p

    # JSONデータの生成
    $jsonBody = @{
        model = "gpt-4o-mini"
        messages = @(
            @{
                role = "user"
                content = $fullPrompt
            }
        )
        max_tokens = 500
    } | ConvertTo-Json -Depth 3 


    # APIリクエストの送信
    $response = Invoke-RestMethod -Uri $apiUrl -Method Post -Headers @{
        "Content-Type" = "application/json"
        "Authorization" = "Bearer $apiKey"
    } -Body $jsonBody -ContentType "application/json; charset=utf-8"

    $result = [System.Text.Encoding]::UTF8.GetString( [System.Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($response.choices[0].message.content) )
    echo $result

}

# 関数の呼び出し
gpt
```

コード上でPowerShellを使う旨を宣言しています。
```
./gpt -p {プロンプト}
```
のように実行してください。

**実行例と結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841947/22458b02-18b0-e710-8aa3-40e9406badc5.png)

### Linux
コードは以下の通りです。
```bash
#!/bin/bash

# ChatGPT API key
API_KEY=<OpenAIのAPIキー>

# 引数が正しく指定されているか確認
if [ "$1" != "-p" ] || [ -z "$2" ]; then
    echo "使い方: gpt -p \"質問内容\""
    exit 1
fi

# APIに送信するプロンプト内容
PROMPT=PROMPT="日本語で回答してください。あなたはLinuxを使う私をサポートしてください。"$2

# ChatGPT API呼び出し
response=$(curl -s -X POST "https://api.openai.com/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $API_KEY" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "'"$PROMPT"'"}],
    "max_tokens": 500
  }')

# 結果の抽出と表示
echo "$response" | jq -r '.choices[0].message.content'
```

コード上でPowerShellを使う旨を宣言しています。
```
./gpt.sh -p {プロンプト}
```
のように実行してください。

**実行例と結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3841947/743bd533-09fe-4e0a-1b69-90d6d996048c.png)


## 注意点
- 今回は同一ディレクトリ内で実行していますが、本来はパスを通してコマンドをどこからでも実行できるようにするのが良いと思います
- トークン数が少なすぎると途中で途切れてしまいます
- デフォルトの状態だと出力結果が大変見にくいです
- コマンドプロンプトだとダブルクォーテーションを付けるなどして柔軟に引数を入力することができませんでした(実力不足)
- コマンドプロンプトだと文字コードの関係で、初回実行時に画面が一度clearされてしまいます(実力不足)


# 終わりに
改善点が非常に多いですが、コマンドから呼び出すことができてよかったです。
今後はバッチファイルやシェルスクリプトを勉強して、より使い勝手の良いものを作っていければと思います。