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?

llm 0.32のサーバー側ツール、CodeInterpreterはあなたのPCで動かない

0
Posted at

llm --tool CodeInterpreter 'いまのPythonとSQLiteのバージョンを教えて' と打つと、Pythonが動いてバージョンが返ってくる。ただし、そのPythonはあなたのマシンでは動いていない。OpenAIのサーバー上でコードが実行され、結果だけが手元に届く。

8月4日に出た LLM 0.32 は、この「ツールがどこで動くのか」という設計を正面から扱ったリリースだ。作者のSimon Willison自身が「プロジェクト開始以来もっとも大きな更新」と書いている。地味なCLIのバージョンアップに見えて、エージェントの実行モデルに関わる変化が入っている。

そもそもLLM(このCLI)とは何か

混乱しやすいのだが、ここで言う llm は「大規模言語モデル」の略称ではなく、Simon Willisonが作っている同名のコマンドラインツール兼Pythonライブラリのことだ。OpenAI、Anthropic、ローカルモデルなど数百のモデルを、同じ llm 'プロンプト' という文法で叩ける薄いラッパーで、応答をSQLiteに全部記録してくれるのが特徴になっている。データ処理系のエンジニアの間で定番になっているツール、という位置づけで捉えるとわかりやすい。

これまでの llm でも「ツール」は使えた。ただしそれは、モデルが「この関数を呼びたい」と要求したら、llmあなたのマシン上でそのPython関数を実行し、結果をモデルに返す、という仕組みだった。モデルは考える、道具を振るうのは手元、という分担である。

クライアント側ツールとサーバー側ツールの違い 🔧

0.32で加わったのが「サーバー側ツール(server-side tools)」だ。名前のとおり、道具を振るう場所がモデルプロバイダ側に移る。

冒頭の CodeInterpreter がまさにそれで、コードを実行する砂場(サンドボックス)はOpenAIのインフラ側にある。手元のPython環境も、ネットワークの口も一切使わない。同様に WebSearch を渡せば、モデルは検索を自前のサーバーで済ませて要約だけ返してくる。

呼び出しは既存のツールと同じ -T(--tool の短縮形)フラグで、名前を渡すだけだ。

# OpenAIのサーバー側でコードを実行
llm -T CodeInterpreter '1から100までの素数を数えて'

# サンドボックスにメモリ上限を渡す
llm -T 'CodeInterpreter(memory_limit="4g")' '大きめのCSVを集計して'

プロバイダごとに使える道具が違うのが実務上の注意点で、そこは表で押さえておきたい。

プロバイダ サーバー側ツール
OpenAI WebSearch, CodeInterpreter
Anthropic(llm-anthropicプラグイン) WebSearch, WebFetch, CodeExecution, AnthropicMCP

面白いのはAnthropic側の AnthropicMCP で、外部のMCPサーバーをモデルの実行環境から直接叩かせられる。作者は自分のブログのデータベースを例に出している。

llm -m claude-sonnet-5 \
  -T 'AnthropicMCP("https://datasette.simonwillison.net/-/mcp")' \
  'how many rows in the blog_blogmark table?'

どのモデルがどのサーバー側ツールに対応しているかは llm tools -m モデル名 で確認できる。

この分担の移動には利点と注意が両面ある。利点は、砂場や検索基盤の運用をプロバイダに丸投げできること。ローカルにDockerを立てたりネットワークの権限を管理したりせずに、コード実行やWeb検索がエージェントに生える。一方で、コードの実行がプロバイダ側のブラックボックスに入るので、何がどう動いたかを手元で完全に監査するのは難しくなる。どこまで信頼して任せるか、というトレードオフを自分で切る必要がある。私見だが、外部データに触るWeb検索はサーバー側で握らせ、社内固有のロジックは従来どおりクライアント側のツールで持つ、という使い分けが現実的だと思う。

エージェントのループがログを膨張させる問題 🗄️

もう一つ、地味だが効いてくるのがログの作り直しだ。

サーバー側ツールを使うと、モデルは「考える→検索する→また考える」とツール呼び出しをまたいで推論を続ける。これはOpenAIの Responses API を既定で使うようになったことと対になっていて、推論(reasoning)とツール呼び出しが1つのチェーンの中で交互に走る。

その代償がログである。エージェント的なやり取りは、毎ターンごとにそれまでの全メッセージ列をAPIに送り直す。素直に記録すると、同じ会話履歴のJSONが何度も重複して保存されてしまう。作者はこう書いている。

If we're going to support the pattern where the message sequence is appended to on every request, ideally we can avoid logging all of that duplicate JSON for every turn.

0.32はこれをGitに着想を得た方式で解いた。メッセージをハッシュで内容アドレス化(content-addressable)し、同一内容のメッセージは一度しか保存しない。SQLiteのスキーマもスレッド・ターン・メッセージという単位に組み直されている。Gitが同じ中身のファイルを1つのオブジェクトとして共有するのと同じ発想で、長時間動くエージェントのログが会話の伸びに比例して膨れ上がるのを止める、という狙いだ。利用には sqlite-utils の4.0以上が必要になる。

すぐ効く小さな改善:推論トレースの分離

派手さはないが日常で効くのが、推論トレースの出力先だ。推論モデルの「考えている途中」は標準エラー出力(stderr)に流れ、最終的な答えだけが標準出力(stdout)に出る。つまり llm ... | jq のようにパイプで後段に渡す中身は答えだけに保たれ、思考の途中経過が混ざらない。パイプラインを組む人間には地味にありがたい設計で、思考を見たくないときは -R(--hide-reasoning)で止められる。

Pythonライブラリ側も構造化メッセージに作り替えられ、model.prompt(messages=[llm.user("Hello")]) のように型付きのメッセージを渡せる。response.stream_events() で推論・テキスト・ツール呼び出しが混ざったストリームを扱え、ツール実装が llm.PauseChain を投げれば、承認を挟むために実行チェーンを一時停止して後から再開することもできる。人間の承認をワークフローに差し込みたいときの土台になる。

なお既定モデルは新しい gpt-5.6-luna に変わり、gpt-5.6-solgpt-5.6-terra も追加された。

何が持ち帰れるか

llm を普段使っていなくても、このリリースが示す方向は押さえておく価値がある。エージェントの道具は「手元で動かすもの」から「プロバイダが持つもの」へと二層化しつつあり、そのぶんログや監査の設計が新しい課題になる。0.32はその両方に手を入れた実装例として読める。まず試すなら、pip install -U llm で上げて、llm -T WebSearch '最近のニュースを3つ' を叩き、そのやり取りが llm logs にどう積まれるかを覗いてみるのが早い。道具がどこで動いているかを意識する、いい入り口になる。

出典は以下のとおり。

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?