rcmdnk's blog

【GPT-4対応】【入門書】小学生でもわかるようにChatGPTを教えて: 「万能プロンプト」「登録方法〜使い方」「仕事にすぐ使える活用例」「便利な拡張機能」まで、この一冊だけで使いこなせる【図解版】入門書&実践書!

コマンドラインからサクッとChatGPTを使うためのラッパーツールを作りました。

chatpgpt-prompt-wrapper

OpenAIのAPIを使ってChatGPTにコマンドラインからアクセスするためのツール。

Homebrewを使っているなら

1
$ brew install rcmdnk/rcmdnkpac/chatgpt-prompt-wrapper

もしくはPython 3.9 ~ 3.11がインストールされている環境なら

1
$ pip3 install chatgpt-prompt-wrapper

とすればインストールでき、cgというコマンドが使えるようになります。

(エイリアスとしてchatgpt-prompt-wrapperというコマンドもインストールされます。)

準備

必要なものは、まずはPython 3.9~3.11。そのpipを利用すれば上のようにpipでインストールできます。

あとは Account API Keys - OpenAI API からOpenAIのAPI Keyを取得しておきます。

これを

1
export OPENAI_API_KEY="sk-..."

のようにしてOPENAI_API_KEYという環境変数にいれておきます。 常に使うなら上のコマンドを.bashrc.zshrcに書いておいてください。

簡単な使い方

ask

cg ask <message>のようにして質問を投げるとChatGPTが答えてくれます。

1
2
$ cg ask who are you?
I am an AI language model created by OpenAI. I am designed to assist in tasks such as answering questions, generating text, and providing language translation services. My role is to augment and support human decision-making through the use of natural language processing and machine learning algorithms.

chat

cg askとするとchatを開始できます。

20230410_chat.gif

chatではやり取りを続けられますが、Ctrl-Cを押すかbye, exit, quitというメッセージを送ると終わります。

デフォルトではmultilineモードで、複数行の書き込みが可能です。 Enterは改行になるので、 メッセージを送る際にはAlt(Opt)-Enter、もしくはEscEnter(続けて押す)を入力すると送信できます。

Backspaceや方向キーも普通のエディタのように使えます。

chatモードのオプション

--no_multilineオプションを与えるとシングルラインモードになって Enterでメッセージを送るようになります。

また、デフォルトでは通常のターミナル操作などのようにEmacsモードで動作しますが(Ctrl-B/Fで一文字戻る/進む、など)、 --viオプションを与えるとViモードになってEscを押すとH/J/K/Lで左/下/上/右に進めたりするようになります。

この辺の動作は Python Prompt Toolkit を使ってます。

本当はブラウザなどでよくあるようなShift-Enterで送信(もしくはEnterを送信でShift-Enterは改行)とかやりたかったのですが、 ターミナル自体がその区別をサポートしていないものもあるらしく難しい模様。

Is it possible to have a “shift + enter” keybinding? · Issue #529 · prompt-toolkit/python-prompt-toolkit

ということでmultilineモードの送信などはPython Prompt Toolkitのデフォルトの動作になっています。

chatモードでやっていること

chatモードではそれまでのやり取りを踏襲した答えを出してくれますが、 送信するたび、それまで全てのやり取りを送って答えを聞いているだけです。

Token数に制限があるので、制限を超えそうな場合には古いものからメッセージを削除して送るようにしています。

Token数は大体英語だと1 wordが1 tokenちょっと、日本語だと1文字1 tokenちょっとな感じです。

What are tokens and how to count them? OpenAI Help Center

token数はOpenAIが提供している tiktokenというライブラリを使えば数えることが出来ます。 これと、 以下のノートにあるnum_tokens_from_messages関数を参考に正確なtoken数を見積もることが可能です。 各メッセージの文字数以外にroleなどの情報も送るために少しプラスアルファがあることに注意が必要です。

openai-cookbook/How_to_count_tokens_with_tiktoken.ipynb at main · openai/openai-cookbook · GitHub

ある程度やり取りを行ったまま続けると、常にToken数制限ギリギリのやり取りを行うことになるのでちょっとcostに気をつけたほうが良いです。

gpt-3.5-turboなら4096 tokensの制限で最大1円弱なので機械的に大量に送らない限りは気にならない程度かと。

gpt-4-32kとかだと32768 tokensまで送れて、かつ1k tokensあたりの料金も数十倍になるので 最大で一回で100円程度かかってしまうこともあります。

Models - OpenAI API

Pricing

また、 Chat completion といううAPIを使っていますが、 streamというオプションがあり、これをTrueにすると 回答を少しずつ受け取ることが出来るので 受け取り次第書き出すようにすると Webでやってるようなツラツラと書いているような様子になります。

openai-cookbook/How_to_stream_completions.ipynb at main · openai/openai-cookbook · GitHub

openai-cookbook便利。

Usage

cg helpでコマンドのヘルプ、cg commandsで使えるサブコマンド一覧を見ることが出来ます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ cg help
usage: cg [-h] [-k KEY] [-c CONF] [-m MODEL] [-t MAX_TOKENS] [-T MIN_MAX_TOKENS] [-l TOKENS_LIMIT] [--show] [--hide] [--multiline]
          [--no_multiline] [--vi] [--emacs] [--show_cost]
          subcommand [message ...]

positional arguments:
  subcommand            Subcommand to run. Use 'commands' subcommand to list up available subcommands.
  message               Message to send to ChatGPT

optional arguments:
  -h, --help            show this help message and exit
  -k KEY, --key KEY     OpenAI API key.
  -c CONF, --conf CONF  Path to the configuration toml file.
  -m MODEL, --model MODEL
                        ChatGPT Model to use.
  -t MAX_TOKENS, --max_tokens MAX_TOKENS
                        The maximum number of tokens to generate in the chat completion. Set 0 to use the max values for the model
                        minus prompt tokens.
  -T MIN_MAX_TOKENS, --min_max_tokens MIN_MAX_TOKENS
                        The minimum of max_tokens for the completion when max_tokens = 0.
  -l TOKENS_LIMIT, --tokens_limit TOKENS_LIMIT
                        The limit of the total tokens of the prompt and the completion. Set 0 to use the max values for the model.
  --show                Show prompt for ask command.
  --hide                Hide prompt for ask command.
  --multiline           Use multiline input for chat command.
  --no_multiline        Use single line input for chat command.
  --vi                  Use vi mode at chat.
  --emacs               Use emacs mode at chat.
  --show_cost           Show cost used.
1
2
3
4
5
6
7
8
9
10
11
12
13
$ cg commands
Available subcommands:
  Reserved commands:
    ask       : Ask w/o predefined prompt.
    chat      : Start chat w/o predefined prompt.
    init      : Initialize config file with an example command.
    cost      : Show estimated cost used until now.
    commands  : List up subcommands (show this).
    version   : Show version.
    help      : Show help.
  User commands:
    test      : Example command to test the OpenAI API.
    ...

自作サブコマンド

あらかじめ指定したプロンプトを用意しておいて、それを自作のサブコマンドとして呼ぶことも出来ます。

設定ファイルは~/.config/cg/config.tomlTOML formatのファイルです。

各コマンドは以下のような感じで。 testというサブコマンドを作っています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[test]
# Example command to test the OpenAI API, taken from below.
# [Chat completion - OpenAI API](https://platform.openai.com/docs/guides/chat/introduction)

description = "Example command to test the OpenAI API."
show = true

[[test.messages]]
role = "system"
content = "You are a helpful assistant."
[[test.messages]]
role = "user"
content = "Who won the world series in 2020?"
[[test.messages]]
role = "assistant"
"content" = "The Los Angeles Dodgers won the World Series in 2020."
[[test.messages]]
role = "user"
content = "Where was it played?"

20230410_test.png

質問も含まれたものが用意されてるので何も追加メッセージ無しで実行して、 最後のassitantのところでその答えが帰ってきています。

Pythonの辞書に直すと

1
2
3
4
5
6
7
8
9
10
11
12
{"test": 
    {
        "description": "Example command to test the OpenAI API.",
        "show": True,
        "messages": [
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": "Who won the world series in 2020?"},
            {"role": "assistant", "content", "The Los Angeles Dodgers won the World Series in 2020."},
            {"role": "user", "content": "Where was it played?"},
        ],
    }
}
  • description: cg commandsでコマンドリストを表示する際に出す説明文。
  • show: 入力のプロンプトを表示するかどうか。デフォルトではfalse。
  • <cmd>.messages: [[]]は同じものを一連のリストにします。それぞれrolecontentという値を持った辞書です。
    • role: system, user, assistantのいずれか。
      • system: 役割の指定などの指示。ただ、gpt-3.5では余り意味をなさず、userとして指示を出したほうがうまくいく場合が多い、とのことなので、cgコマンドの中ではgpt-3.5系ではuserに変換して送っています。
      • user: ユーザーの入力。
      • assitant: AIの返信。あらかじめやり取りを行ったという想定で質問したい場合などに使う。
    • content: メッセージ内容。

これ以外に chat = trueとすればchatモードとしてやり取りを開始することが出来ます。

自作サブコマンドの簡単な例

上のは特に追加で質問せずともそのまま答えてもらう文章を書いてしまっていますが、 よく使いそうな例としては役割を与えておいて、質問はその都度する、というもの。

1
2
3
4
5
[sh]
description = "Ask a shell scripting question."
[[sh.messages]]
role = "system"
content = "You are an expert of the shell scripting. Answer the following questions."

みたいな感じで設定しておくと、

$ cg sh show number of cpus
To show the number of CPUs in a shell script, you can use the `nproc` command which prints the number of available processing units (CPU cores or threads) that the system has.

To use it, you can simply run the following command in your terminal:

```
nproc
```

This will output a single number representing the number of available processing units on your system.

To save the output of the `nproc` command in a script variable, you can use command substitution like this:

```
num_cpus=$(nproc)
echo "Number of CPUs: $num_cpus"
```

This will store the output of the `nproc` command (number of CPUs) in the `$num_cpus` variable and print it to the console.

こんな感じで、特に質問ではシェルスクリプトと言わなくてもシェルスクリプトで使えるような方法を答えてくれます。

同様にchat = trueでも相手の役割や事前知識をあらかじめ指定した上で開始することが出来ます。

まとめ

ChatGPTをコマンドラインやシェルスクリプトなどからサクッと呼びたかったのでそれ用のツールを作ってみました。 多分同じようなものはすでに色々とあるとは思いますが。

適当なプロンプト入れたsubcommandを作っておけば手短に質問するだけでもいい感じに答えてくれるように出来るので ターミナルで作業を使う身としては便利。

Sponsored Links
Sponsored Links

« Python製コマンドラインツールをHomebrewで配布する git-gpt-commit: ChatGPTにGitのcommitを書かせる »

}