記事一覧に戻る

コーディング Agent に画像圧縮を持たせる

PiPic チーム
Agents
pipic ./assets --replace --json
{"file":"assets/hero.png","status":"ok",…}
✓ exit 0

Claude Code や Codex に「このフォルダの画像を圧縮して」と頼んで、何が起きるか見てほしい。 sharp のインストールを提案し、使い捨ての Node スクリプトを書き、品質設定を当てずっぽう で決め、最後に渡してくるのは——いくつかは小さくなり、一つは大きくなり、どれがどれだか 誰にも言えないフォルダだ。

問題は Agent の側にはない。画像圧縮は「簡単そうに見えて実はそうではない」能力の典型だ。 フォーマットごとに異なるエンコーダ、品質のヒューリスティック、そして測ってみないと良し 悪しを判断できない結果。これはツールの仕事であって、Agent が毎回その場で即興するスクリプ トの仕事ではない。

これを成立させる分担

Agent には本当にできない工程が一つある。サインインだ。pipic login はブラウザを開いて あなたの承認を待つ。サンドボックスで動く Agent は HOME が違い、ブラウザもなく、その ボタンを押す手段もない。

だから頼まない。「実際に誰ができるか」で仕事を分ける:

あなたが、一度だけ。 自分のターミナルで:

npm i -g @pipic/cli
pipic login

認証情報は ~/.config/pipic/config.json に置かれる。そのマシンであなたとして動くツールは すべて、これ以降それを使える——あなたの Agent も含めて。

あなたの Agent が、その後は毎回。 これを会話に貼る:

Use the `pipic` CLI to compress the images in ./assets.
It's already installed and signed in — do not install it or run
`pipic login` yourself.

  pipic ./assets --replace --json

It prints one JSON object per file:
  {"file":"a.png","status":"ok","before":102400,"after":41000,"saved":61400}
status is "ok", "skipped" or "error". "skipped" is not a failure — it
carries an `error` string explaining why (e.g. already small enough).

Exit 0 = all good, 1 = some files failed, 3 = not signed in,
4 = monthly quota exhausted.
Don't retry on exit 2 (usage error), 3 or 4 — on 3, stop and tell the
user to sign in. On exit 1, re-run only the paths whose rows had status
"error": a full re-run re-uploads every file and spends quota again.

この中の一行一行が特定の失敗を防いでいる。うち二行が防ぐのは、高くつくほうの失敗だ。

"do not install it or run pipic login yourself" がないと、Agent はとにかく試そうとする ——そして pipic login は、Agent には与えられないブラウザ承認を最大 10 分待つ。Codex や Claude Code の中では、フレームワークがいずれ強制終了するツール呼び出しとして現れ、 「ツールがハングした」ように見える。

終了コード 1 についての一行がないと、100 ファイルの実行で 2 件の失敗を見た Agent は、 いかにもありそうな判断をする——ディレクトリ全体を再実行するのだ。ローカルには「圧縮済み」 のチェックは存在しない。全ファイルが再アップロードされ、月間の割り当てはサーバーが受け 付けたリクエストをすべて数える。無料枠は月 100 なので、盲目的な再試行 1 回で使い切りうる。

残りはもっと安い間違いだ。出力先フラグがなければ使い方エラーになるし、skipped は失敗 ではないと伝えておかないと、何も問題がないところで問題を報告してくる——スキップされた行も error 文字列を持っていて、なぜ何も変わらなかったかを説明しているからだ。

Agent が見ているもの

説明用のセッション——形は本物、数字は作りもので、あなたの環境では違う値になる:

> compress the images in ./assets

I'll use the pipic CLI.

  $ pipic ./assets --replace --json

  {"file":"assets/hero.png","status":"ok","before":2411233,"after":486201,"saved":1925032}
  {"file":"assets/team.jpg","status":"ok","before":880640,"after":712704,"saved":167936}
  {"file":"assets/icon.svg","status":"skipped","before":0,"after":0,"saved":0,"error":"unsupported file type"}
  {"file":"assets/logo.webp","status":"skipped","before":18944,"after":18944,"saved":0,"error":"not smaller — original kept"}

Done. Two files compressed, saving about 2.0 MB — hero.png did most of
the work, dropping from 2.4 MB to 486 KB. I left logo.webp alone because
compressing it came back larger, and skipped icon.svg since SVG isn't a
raster format.

注目すべきは最後の段落だ。Agent は推測していない——契約を読んでいる。saved は比率では なくバイト数。skippederror ではない。not smaller — original kept は、なぜ何も 変わらなかったのかを正確に述べている。

即興のスクリプトはこれを生まない。Agent がその場で書きたいと思った console.log を出す だけで、返ってくる要約は、Agent が自分の出力に対して抱いた印象にすぎない。

「小さくなったときだけ」がここで効く理由

最適化済みの画像は、圧縮するとかえって大きくなることがある。素朴なスクリプトはそれでも 上書きし、リポジトリは実行のたびに静かに太っていく。

pipic は結果が実際に小さいときだけ書き戻す。--replace では元ファイルは触られないまま、 -o ではコピーされるので出力ディレクトリは完全な一式のままになる。どちらの場合もその ファイルは error ではなく skipped として報告される——だから出力を読む Agent が、何も 失敗していないのに「失敗しました」と言い出すことはない。

省略できないフラグ

--replace-o <dir> は排他で、どちらか一方が必須だ。pipic ./assets をどちらもなし で実行すると、リクエストを一つも送る前に使い方エラーで終了する。

これは意図的で、Agent が運転しているときほど効いてくる。デフォルトで上書きするツールは、 いずれあなたが十分に読まなかった実行のなかで、残したかった何かを上書きする。出力先を明示 させるということは、Agent に意図を宣言させるということであり、その意図は Agent が見せて くるコマンドの中で確認できる。

Agent があなたの認証情報を見られないとき

サンドボックス化された Agent、コンテナ、CI——~/.config があなたのものではない場所すべて。 アカウントページでトークンを作り、その環境で PIPIC_TOKEN として渡す。認証情報ファイルより優先されるので、pipic login なしで同じコマンドが動く。

pipic token create があえてローカルで発行せずウェブページへ誘導するのは意図的だ。盗まれ た CLI 認証情報が、新しい認証情報を発行できてはならない。

終了コードがインターフェースだ

自動化されたものにとって、ここがいちばん重要だ:

コード意味
0すべて成功
1一部のファイルが失敗
2使い方エラー
3サインインが必要
4月間クォータ超過

3pipic login を実行せよという意味——あなた自身がやるしかない唯一のことだ。4 は CLI と API の月間割り当てを使い切ったという意味で、自動的な課金は一切なく、pipic.cc 上での 圧縮はいずれにせよ無料・無制限のままだ。

これらのコードで分岐する Agent は、あなたに長文を解釈させることなく正しく振る舞う。メッ セージ文字列にパターンマッチする Agent は、こちらが言い回しを変えた瞬間に壊れる——だから こそ、コードと status の値とフィールド名が安定した契約であり、人間向けの error テキスト はそうではない。

自分の画像で試してみる
無料、登録不要、保存も一切なし。
画像を圧縮する