🍏

ターミナル上で生成AIを動作させる

2024/07/27に公開

完成図

  • ai xxxの形式で記載すると生成AIを実行できる
  • 実行結果は緑色になり見やすい
  • 5回分の会話を記憶している
  • ターミナル操作で生成AIに聞きたくなったときにターミナルですべて簡潔できる

コード

以下のshellを.zshrcalias設定しました。

  • モデルやキーはハードコーディングです。動けば良し
  • jqが存在していることが前提になっています
  • Rustなどで作り変えれば、早く動くようになるのかなと思います。このままでも十分使えたので良しとしました。
ai.sh
#!/bin/bash

# 会話履歴を保存するファイル
HISTORY_FILE="/tmp/chat_history.json"

# 履歴ファイルが存在しない場合は作成
if [ ! -f "$HISTORY_FILE" ]; then
    echo '[]' > "$HISTORY_FILE"
fi

# 引数チェック
if [ "$#" -eq 0 ]; then
    echo -e "\033[31mUsage: $0 <CONTENT>\033[0m"
    exit 1
fi

# 引数からコンテンツを取得
CONTENT="$*"

export OPENAI_KEY="sk-xxxxx"

# 履歴を読み込む
HISTORY=$(cat "$HISTORY_FILE")

# 新しいメッセージを追加(特殊文字と改行を除去)
SANITIZED_CONTENT=$(echo "$CONTENT" | tr -d '[:cntrl:]' | sed 's/"/\\"/g')
NEW_HISTORY=$(echo "$HISTORY" | jq --arg content "$SANITIZED_CONTENT" '. + [{"role": "user", "content": $content}]')

# 履歴を最新の10件に制限
TRIMMED_HISTORY=$(echo "$NEW_HISTORY" | jq 'if length > 10 then .[length-10:] else . end')

# APIリクエストを作成
REQUEST=$(jq -n \
    --argjson messages "$TRIMMED_HISTORY" \
    '{
        "model": "gpt-4o-mini",
        "messages": ([$messages] | add | [{"role": "system", "content": "日本語で最大400文字で回答してください。改行は最大5回までで結果を表現してください"}] + .)
    }')

# APIリクエストを送信
RESPONSE=$(curl https://api.openai.com/v1/chat/completions \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer ${OPENAI_KEY}" \
    -d "$REQUEST" \
    2>/dev/null | jq -r '.choices[].message.content')

# レスポンスを表示
echo "\033[32m${RESPONSE}\033[0m"

# レスポンスを整形(特殊文字と改行を除去)
SANITIZED_RESPONSE=$(echo "$RESPONSE" | tr -d '[:cntrl:]' | sed 's/"/\\"/g')

# 履歴を更新
UPDATED_HISTORY=$(echo "$TRIMMED_HISTORY" | jq --arg response "$SANITIZED_RESPONSE" '. + [{"role": "assistant", "content": $response}]')

# 最新の10件に制限して保存
FINAL_HISTORY=$(echo "$UPDATED_HISTORY" | jq 'if length > 10 then .[length-10:] else . end')
echo "$FINAL_HISTORY" > "$HISTORY_FILE"

Discussion