👻
テキストエディタを生成AIクライアントにすると便利だった
はじめに
- OpenAI API + Python を使います
- Windows を使います
- OpenAI API 自体の解説はしません
- 成果物のインストール等に関する親切丁寧な解説もしません
まとめ
- テキストエディタを生成AIクライアントにするとは?
- 1: テキストファイルに書いたプロンプトで問い合わせて、結果も追記させる
- 2: 1を行うシンプルなスクリプトをつくり、テキストエディタ(IDEでも可)からすぐに呼び出せるようにする
- 3: テキストエディタは、外から更新されたファイルを自動でリロードするので、2 によりあたかもテキストエディタ上でシームレスに生成AIを呼び出したような体験になる
- つくったもの:
- askai。指定ファイル(たとえば1.md)を使って問い合わせ&追記する
- pgpt。指定ファイル(たとえばp.md)を使って、複数のモデルで問い合わせて、それぞれファイルを分けて出力する(たとえばp-o1.md、p-o4.mdなど)
背景
- いちいち ChatGPT からコピペするのだるい
解法
- 使い慣れたテキストエディタ上でシームレスに使えるといいのでは?
成果物
- askai: https://github.com/stakiran/askai
- Ask AI の略
- pgpt: https://scrapbox.io/stao/pgpt.py
- Parallel GPT の略
デモ
askaiのデモ
詳しい話
まずは指定テキストファイルの内容で問い合わせ + 結果もそこに追記するようなスクリプトをつくった。
- 上述の askai と pgpt
次に、これをテキストエディタからシームレスに呼び出せるようにした。やり方はエディタ次第だろうが、今回は以下を試した。
- 秀丸エディタ。askai を呼び出すバッチファイルをつくる → そのバッチファイルを呼び出す秀丸エディタマクロをつくる → そのマクロを呼び出すショートカットキーを設定する。
- VSCode。tasks.json に askai や pgpt を呼び出すタスクをつくる。これによりコマンドパレット → Run Task → askaiやpgptを呼び出すタスク、で呼び出せる。
感想
想像どおり便利。
Google よりも、ChatGPT よりも、これらをメインに使うようになった。慣れたテキストエディタを開いて、プロンプト書いて、ショートカットキーを押せば、もう実行できる。実行結果もその場で編集して、また問い合わせたりといったこともできる。
特に意識したのが「マイクラのかまど」のような体験で、複数の問い合わせを並列に使い分けたかった。私は askai にて、1.md、2.md、3.md と三つのファイルを使い分けている。1.md でガリガリ対話して、ちょっと別の路線試したくなったら 2.md の方にコピペしてそっちで試して・・みたいなこともできる。
以下は技術的な話
Python による OpenAI API 呼び出し
こんな感じ。
- client.chat.completions.create を使っているだけ
- messages も role=user だけでいい
- タイムアウトは経験則的に 2 分ちょい
- 通常は足りるはずだが、o1-pro など高度な推論モデルの場合は足りないかもしれない
import openai
openai.api_key = os.environ["OPENAI_API_KEY"]
client = openai.OpenAI()
def ask(prompt):
response = client.chat.completions.create(
#model='o3-mini',
model='gpt-4o',
#model='gpt-4.1',
#model='gpt-4o-mini',
#model='gpt-4.1-mini',
messages=[
{'role': 'user', 'content': prompt},
],
timeout=130
)
return response
秀丸エディタから呼び出す
結構ややこしい&秀丸エディタユーザー以外には誰得だが、要するにテキストエディタからシームレスに呼び出すためにそれなりにごにょごにょしている。
面倒くさいだろうが、愛用のテキストエディタでシームレスに使いたいなら、頑張ってクリアしてください。これは秀丸エディタで頑張ってクリアしたら、たとえばこうなったよという例です。
例として 1.md で使いたい場合。
1: まず、1.bat をつくる
- start コマンドで小難しいことをしているが、これはノンブロッキングで実行するためである
- これを実行すると DOS 窓(黒い窓)が出てしまうが、それでいい
- 秀丸エディタは今開いてるファイルが外部から更新されても、(一度フォーカスを別窓に移さないと)自動でリロードしてくれないため
- つまり、DOS 窓が開くことで、自動でフォーカスがDOS窓に行く&DOS窓は実行を終えたら消える → 秀丸エディタにフォーカスが戻るので、自動リロードの挙動になる
@echo off
start /b "" cmd /c python openaiapi1.py --input 1.md
2: 次に 1.bat を呼び出す秀丸エディタマクロをつくる
// 余計なファイルで発動してしまわないようガード
if(filetype!=".md"){
endmacro;
}
// xxx.md を開いている想定で、xxx を取り出す
// xxx.bat という文字列をつくるため
#ext_len = strlen(filetype);
#filename_len = strlen(basename);
$basename = midstr(basename, 0, #filename_len-#ext_len);
// ★ディレクトリはハードコードなので各自設定して
// xxx.bat のフルパスをつくる
$basedir = "D:\\work\\github\\stakiran\\scripts\\gen\\";
$launcher_path = $basedir;
$commandline = $launcher_path+$basename+".bat";
// xxx.md の今の内容を(保存してないかもなので)改めて保存して、xxx.bat を実行
save;
run $commandline;
if(result==false){
message "run文の実行に失敗しています > " + $commandline;
}
endmacro;
3: 最後に 2 のマクロを呼び出すショートカットキーを設定する
今回は Alt + S を設定。
VSCode から呼び出す
今回は .vscode/tasks.json にタスクを定義することで実現。
まずは (askaiやpgpt用のフォルダ)/.vscode/tasks.json をつくって、以下を追記。
- 下記は Mac の場合。"command" の Python 実行パスは各自調整。
- ポイントは、xxx.md の xxx を取り出すのに
${fileBasenameNoExtension}を使うこと
{
"version": "2.0.0",
"tasks": [
{
"label": "Run askai",
"type": "shell",
"command": "/usr/local/bin/python3",
"args": [
"askai.py",
"--input",
"${fileBasenameNoExtension}.md"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Run pgpt",
"type": "shell",
"command": "/usr/local/bin/python3",
"args": [
"pgpt.py",
"--input",
"p.md"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
これができたら、コマンドパレット → Run Task → Run askai などで呼び出せるようになるはず。
Discussion