0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Willison製CLI『llm』0.32が推論を標準エラーへ分離した

0
Posted at

推論モデルの応答を jq に流したら、JSONのはずの標準出力に「まず条件を整理すると…」という思考文が混じってパースが落ちた。そんな経験があるなら、この更新は刺さるはずだ。

ターミナルからLLMを呼ぶCLIツール llm(名前がそのまま「LLM」でややこしい)は、8月4日公開の0.32でこの問題に素直な答えを出した。モデルが答えにたどり着くまでの推論トレース(思考の実況)を標準エラー出力に回し、標準出力には最終結果だけを残す。パイプは標準出力しか運ばないので、| jq の下流はきれいなまま、という理屈だ。その後も0.32.1(8月21日)、0.33(8月22日)と短い間隔で更新が続いている。

llm はSimon Willison(Djangoの共同創設者で、Datasette の作者)が開発するコマンドラインツールだ。pip install llm などで入り、OpenAI・Anthropic・Geminiからローカルモデルまで、プラグイン越しに同じ書き方で叩ける。今回の0.32は小さな新機能の寄せ集めではなく、Python API全体を「メッセージ」と「パート」という構造に組み直した大改修で、以下の実務寄りの変更はその土台の上に乗っている(リリースノート)。

🧵 推論は標準エラーへ、結果は標準出力へ

これまで推論系モデルをCLIで使うと、思考の途中経過と最終回答が同じ標準出力に混ざりがちだった。0.32は推論の要約を標準エラー(stderr)にストリーミングし、-R(--hide-reasoning)で完全に消せる。

# 推論の途中経過は画面(stderr)に出るが、ファイルへの保存はきれいなまま
llm "この関数のバグを説明して" < app.py > answer.md

# 推論の表示自体が要らないなら黙らせる
llm -R "42を2進数で"

出力の粒度は reasoning_summaryauto / concise / detailed から選べる。

llm -o reasoning_summary detailed "巡回セールスマン問題を素朴に解くと何が問題?"

この「思考はstderr、結果はstdout」という切り分けは、UNIXの流儀そのものだ。すべてを標準出力に垂れ流すツールが少なくないなか、パイプで組み合わせて使う前提を最初から取ったのは、地味だが正しい判断だと思う。

サーバ側で動く道具と、手元で動く道具

0.32のもう一つの軸が、ツール(function calling。モデルに外部処理を呼ばせる仕組み)の扱いだ。llm には以前から、モデルにローカル関数を実行させる機能がある。たとえば式の評価はこう書く。

llm -T simple_eval "4444 * 233423" --td

-T でツールを渡し、--td(--tools-debug)で呼び出しの中身を覗ける。実行前に一つずつ承認する --ta(--tools-approve)もある。どれも自分のマシンで動くので、何が走るかを止めて確認できる。

0.32はこれに加えて、プロバイダ側で完結する「サーバ側ツール」を正式に扱えるようにした。OpenAIの WebSearchCodeInterpreter がそれで、実行はモデル提供者のインフラ上で起きる。

# そのモデルが使えるサーバ側ツールを一覧
llm tools -m gpt-5.6-luna

# 検索やコード実行をプロバイダ側にやらせる
llm -T WebSearch "llmの最新バージョンは?"
llm -T 'CodeInterpreter(memory_limit="4g")' "2の64乗を計算して"

両者の違いは、実行がどこで起きるかに尽きる。

ローカルツール サーバ側ツール
実行場所 自分のマシン モデル提供者側
simple_evalDatasette(...) WebSearchCodeInterpreter
中身の確認 --td で可視化、--ta で承認 手元からは介入しづらい
向く場面 社内DB照会・自前ロジック 汎用の検索・計算

便利さと引き換えに、サーバ側ツールは何を検索し何のコードを走らせたかが手元からは見えにくい。実行内容を止めて監査したい処理は、従来のローカルツール側に置くのが無難だ。用途で分けたい。

会話ログをGitのように一意化する

3つ目は目立たないが、長く使うほど効いてくる変更だ。llm は会話をSQLiteに記録する。ただしマルチターンの会話は毎回過去の全履歴をやり取りするため、素朴に保存すると同じテキストが何度も重複して溜まっていく。

0.32は保存方式を刷新し、メッセージ内容から一意なIDを作って本体は一度だけ保存、以降は参照で済ませるコンテンツアドレス方式に切り替えた。Willison自身がGitになぞらえているとおり、Gitがファイル内容をハッシュで一意に管理するのと同じ発想だ。会話ログの重複が消え、message_tree というSQLビューでスレッドをそのまま辿れる。ただしこの新スキーマは sqlite-utils 4.0以降を要求する(変更履歴)。

数週間ぶんの会話を貯め込むと、この重複排除の有無はDBサイズにそのまま出る。派手さはないが、今回いちばん「インフラらしい」改善だと感じた。

pipで入れて挙動を確かめる

pip install llm            # brew install llm / uv tool install llm でも可
llm "Ten fun names for a pet pelican"   # 既定モデルで即実行

OpenAIやAnthropicを使う場合はAPIキーの登録が要る(手順は公式ドキュメント)。8月22日の0.33ではOpenAI Python 3.x系に追随してHTTPクライアントを httpx から httpx2 に切り替え、llm embed--key が付き、llm logs がサーバ側ツールの結果を「Tool results」として表示するようになった。0.32から既定モデルが GPT-5.6 Luna に変わっている点も、初回は課金先の確認をしておくといい。

エージェント的なCLIが増えるなか、「思考はstderr、結果はstdout、履歴は一意化して残す」という素直な配管の作り直しは、パイプで道具を組み合わせて使う人にこそ効く。派手なモデル発表の裏で、こういう地ならしが後から効いてくる。最新の詳細は本家のリリースノートが早い。

※本記事は一次情報の調査をAIが行い、事実確認のうえ執筆・公開しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?