無料：ターミナルからローカルAIと自然な会話をもとめて：LM Studio + Zsh 関数で簡単チャット環境を構築

# ✅ できること
- ターミナルを開いてローカル AI と直ぐにチャットできる
- 文脈を維持しながらチャットができる
- クラウドのサービスを使わずにローカルだけで完結する
- （あれです。chat-gpt とか cursor のチャットをターミナルで且つローカルで実現したかった）

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594280/ddb0c85d-0855-4649-ade7-2117c8616c84.gif)

# ✅ 前提
- [LMStudio](https://lmstudio.ai) がセットアップ済みであること・起動済み・API が使える状態
- モデルは `gemma-3-4b-it-qat` を使用（レスの速さ重視で軽量を選択）
- M1 Mac環境で動作確認済み

# 💻 how to use: 単発の質問（短文）
コマンドに続けてそのまま質問を入力することで、即座にAIからの回答を得られる
```bash
chat "curl コマンドで POST する方法は？"
```

# 💻 how to use: 複数行での入力（ヒアドキュメント形式）
シェルのヒアドキュメント (<< EOF) を使って、複数行のプロンプトを渡すことも可能。特にスクリプトや長文の質問を扱う場合に便利。
```bash
chat << EOF
jq コマンドで以下の JSON から email アドレスの一覧を取り出したい。

{
  "users": [
    { "name": "Alice", "email": "alice@example.com" },
    { "name": "Bob", "email": "bob@example.com" }
  ]
}
EOF
```

# 💻 導入方法
この関数を `.zshrc` に追加するだけ
```bash
vim ~/.zshrc
```
```zsh
chat() {
  local model="gemma-3-4b-it-qat"
  if [ -z "$CHAT_HISTORY" ]; then
    CHAT_HISTORY='[{"role": "system", "content": "あなたは親切なアシスタントです。日本語で回答してくれます。"}]'
  fi
  if [ -t 0 ]; then
    input="$*"
  else
    input="$(cat)"
  fi
  CHAT_HISTORY=$(jq -c --arg msg "$input" '. + [{"role": "user", "content": $msg}]' <<< "$CHAT_HISTORY")
  curl -sN http://localhost:1234/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "'"$model"'",
      "stream": true,
      "messages": '"$CHAT_HISTORY"'
    }' | while IFS= read -r line; do
      if [[ $line == data:\ * ]]; then
        json="${line#data: }"
        if [ $(echo "$line" | wc -l) -gt 1 ]; then
          json=$(echo "$json" | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g')
          content=$(echo "$json" | jq -r '.choices[0].delta.content // empty' 2>/dev/null)
          content=$(echo "$content" | sed 's/\\n/\n/g')
          echo $content
        else
          content=$(echo "$json" | jq -r '.choices[0].delta.content // empty' 2>/dev/null)
          [ -n "$content" ] && printf "%s" "$content"
          buffer+="$content"
        fi
      fi
    done
  echo
  CHAT_HISTORY=$(jq -c --arg msg "$buffer" '. + [{"role": "assistant", "content": $msg}]' <<< "$CHAT_HISTORY")
}
```
ターミナルを開き直さない場合は忘れずに以下のコマンドを叩いて反映させる
```bash
source ~/.zshrc
```

# 💪 LM Studio の API を叩いてチャットする仕組み
LM Studio が提供するローカルエンドポイント http://localhost:1234/v1/chat/completions に対して、JSONを送信して返答を取得している。
## 💪 シンプルなAPI呼び出し（stream = false）
```bash
curl -sN http://localhost:1234/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
      "model": "gemma-3-4b-it-qat",
      "stream": false,
      "messages": [
        {"role": "system", "content": "あなたは親切なアシスタントです。日本語で回答してくれます。"},
        {"role": "user", "content": "あなたは誰ですか"}
      ]
    }'
```
```json
{
  "id": "chatcmpl-4yv0trm70guibqj98zhi5m",
  "object": "chat.completion",
  "created": 1746188391,
  "model": "gemma-3-4b-it-qat",
  "choices": [
    {
      "index": 0,
      "logprobs": null,
      "finish_reason": "stop",
      "message": {
        "role": "assistant",
        "content": "私は、Googleによってトレーニングされた、大規模言語モデルです。人間のように会話したり、テキストを生成したりすることができます。 \n\n簡単に言うと、「AIアシスタント」としてあなたのお役に立てるように設計されています。何かお手伝いできることはありますか？ 😊\n"
      }
    }
  ],
  "usage": {
    "prompt_tokens": 28,
    "completion_tokens": 55,
    "total_tokens": 83
  },
  "stats": {},
  "system_fingerprint": "gemma-3-4b-it-qat"
}
```

## 💪 AIが喋ってる感を出す（stream = true）
```bash
curl -sN http://localhost:1234/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemma-3-4b-it-qat",
    "stream": true,
    "messages": [
      {"role": "system", "content": "あなたは親切なアシスタントです。日本語で回答してくれます。"},
      {"role": "user", "content": "あなたは誰ですか"}
    ]
  }' | while IFS= read -r line; do
    if [[ $line == data:\ * ]]; then
      echo $line
    fi
  done
```
```json
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"私は"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"、"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"Google"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"によって"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"トレーニング"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"された"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"、"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"大規模"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"言語"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"モデル"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"です"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"。"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"人間"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"のように"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"会話"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"したり"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"、"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"テキスト"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"を"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"生成"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"したり"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"することができます"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"。"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":" "},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"

"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"簡単に"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"言う"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"と"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"、「"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"AI"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"アシ"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"スタ"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"ント"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"」"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"として"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"あなた"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"のお"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"役に"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"立て"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"る"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"ように"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"設計"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"されています"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"。"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"何か"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"お手"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"伝"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"い"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"できる"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"ことは"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"あります"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"か"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"？"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":" 😊"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{"role":"assistant","content":"
"},"logprobs":null,"finish_reason":null}]}
data: {"id":"chatcmpl-94huqxugqh30xt7h4o6wl","object":"chat.completion.chunk","created":1746188646,"model":"gemma-3-4b-it-qat","system_fingerprint":"gemma-3-4b-it-qat","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}]}
data: [DONE]
```

# 💪 チャットの文脈
LMStudio（OpenAI API）との対話履歴を messages に蓄積していくことで、会話のコンテキストを維持している。具体的には、プロンプト入力のたびに次のような処理を行っている。
```bash
messages.append({"role": "user", "content": prompt})
response = openai.ChatCompletion.create(
    model="gpt-4",
    messages=messages,
    ...
)
messages.append({"role": "assistant", "content": response.choices[0].message["content"]})
```

この履歴（messages）は、ターミナルが起動している間のみ保持される。つまり、1つのターミナルを「1セッション」として捉えており、そのセッション内では文脈を保持した対話が可能。一方、別のターミナルから新たに実行した場合は、履歴が初期化されるため、新たな文脈での対話となる。

# 🙇 おわりに
クラウドベースのサービスに比べて通信の可視性が高く、オンプレミス環境にも適している。例えばインターネット接続が制限された社内ネットワーク内でも、安全かつ柔軟に導入しやすい。加えて、ターミナルで完結する UI は、ちょっとしたコマンドの確認や man 代わりのリファレンスとしても期待できる。複雑なコマンドの構文やツールの使い方などを、わざわざブラウザを開くことなく、自然な対話形式で調べられるのは大きなメリットである。

「AIは万能ではない」ことを体験し、正解を期待しすぎないマインドセットを持つことが重要だと個人的には思う。命令の仕方ひとつでAIの出力が大きく変わることを理解すると良いと思う。AIとの信頼関係（笑）として対話力のメンタルも大事で、すぐ怒らず、冷静にAIの限界を理解しつつ“会話”できる力も必要だ💪

ここまで読んでくれてありがとうございました。