登場人物と責任範囲¶
最初に、LLM エージェントを構成する登場人物と、それぞれが何を担当しているのかを整理する。以降の章はこの見取り図を頭に入れた上で、各要素を順番に掘り下げる形になる。
LLM は次のことを知っているか¶
以下を LLM (モデル) 単体に聞いた場合、どこまで正確に答えられるか考えてみる。
| # | 質問 | LLM 単体でわかる? |
|---|---|---|
| Q1 | 今の日時は? | ✗ わからない |
| Q2 | 今日の東京の天気は? | ✗ わからない |
| Q3 | 3847 × 2915 は? | △ 推論モデルなら大抵解けるが、速度 / コスト / 信頼性の面でツールが有利 |
| Q4 | 日本の現在の政策金利は? | △ 学習カットオフ次第 |
| Q5 | このリポジトリにある examples/agent-demo/src/tools.ts の中身は? |
✗ わからない |
| Q6 | 富士山の高さは? | ◯ わかる |
なぜこうなるのか:
- Q1 (日時): LLM は推論時にクロックを持っていない。入力テキストから日付を推測することはあるが、実行時の「今」を正しく把握する手段がない。
- Q2 (天気): リアルタイム情報。学習データに含まれるはずがない。
- Q3 (計算): 少し前の LLM は「次のトークンを確率的に予測する」仕組みから離れられず、桁が増えるとすぐにボロが出ていた。しかし最近の推論モデル (GPT-5.4 reasoning / Claude Sonnet 4.6+ / Gemini 2.5 Pro 等) は、内部で chain-of-thought を展開して筆算相当の手続きを踏むので、3847 × 2915 のような問題はほぼ正答する。ただしそれでも
calcツールを使うべき理由がいくつもある: - 速い: 電卓 (あるいは Python) なら μs オーダーで終わることを、LLM は数千〜数万トークン消費してやっている
- 安い: 推論トークンは大抵のモデルで通常トークンの数倍〜のコスト。桁数が増えるほど料金が跳ねる
- 確実: 推論モデルでも稀に計算ミスする (特に浮動小数点、大きな桁数、複数ステップの四則混合)
- 監査可能: ツール実行ログには明示的に入力 / 出力が残るので、「正しく計算されたか」を後から検証できる
- 要するに「LLM が計算できるかどうか」と「LLM に計算させるべきか」は別の問題
- Q4 (金利): 学習データに含まれるのは特定時点までで、それ以降の値は知らない。さらに直近の話題は学習時点より数か月古いことが多い。
- Q5 (リポジトリのファイル): ローカルファイルシステムは学習データに含まれない (当たり前)。
- Q6 (富士山の高さ): 学習データに含まれる安定した事実は答えられる。
つまり LLM 単体でできるのは「学習時に焼き込まれた一般的な事実と言語運用」+「推論モデルなら論理的展開や筆算」まで。一方で、「今この瞬間の情報」「ローカル環境の中身」、そして 「速度 / コスト / 確実性が求められる計算」は、引き続き別の仕組み (ツール) で補うのが合理的。
登場人物¶
その「別の仕組み」を組み上げたのがエージェントという構造。本リポジトリの examples/agent-demo/ を例にすると、登場人物はこの 5 つ:
┌─────┐
│ 人 │ 質問を投げる / 応答を受け取る
└──┬──┘
│ 入力 / 出力
▼
┌──────────────┐
│ [入力ガード] │ ユーザ入力の検査 / 正規化 / マスキング
└──────┬───────┘
▼
┌─────────────────────┐ prompt ┌─────┐
│ エージェント │ ──────────► │ │
│ │ │ LLM │ 学習済みの言語モデル
│ (agent-demo の │ ◄────────── │ │
│ TS プログラム) │ tool_call └─────┘
└─────────┬───────────┘
│ 呼び出し
▼
┌──────────────┐
│ [ツールガード]│ 引数バリデーション / 認可 / レート制限
└──────┬───────┘
▼
┌──────────────┐
│ ツール │ search, calc, wikipedia, now, ...
│ (外の世界に │ LLM の「手足」。実世界から情報を取る /
│ 繋がる道具) │ 実世界に働きかける
└──────┬───────┘
│ 結果
▼
(エージェントへ戻る)
│
▼
┌──────────────┐
│ [出力ガード] │ LLM の最終応答の検閲 / PII 除去 / 整形
└──────┬───────┘
▼
┌─────┐
│ 人 │ 最終応答を受け取る
└─────┘
それぞれの役割¶
| 登場人物 | 何をする | 実体 (agent-demo の場合) |
|---|---|---|
| 人 | 要求を入力し、最終応答を受け取る | ターミナルで mise run agent-single -- "..." を叩く人、対話モードの you> プロンプトに入力する人 |
| エージェント | 人の要求 → LLM への問いかけ → 必要ならツール呼び出しのループ → 最終応答、のオーケストレーション | examples/agent-demo/src/agent-single.ts / agent-chat.ts (LangChain JS の createAgent を使った TypeScript プログラム) |
| LLM | 与えられた会話履歴に対し「次に何を言うか / どのツールを呼ぶか」を判断する | LiteLLM 経由で叩かれる Claude / GPT / Gemini / Ollama のモデル |
| ツール | LLM が自分では持っていない情報や能力を提供する (時刻、検索、計算、RAG、API 呼出、ファイル操作など) | examples/agent-demo/src/tools.ts に定義された search / fetch_url / wikipedia / now / calc / random_int / end_chat |
| ガード | 安全性 / 整合性 / 認可の担保。入力・出力・ツール実行の各段で働く | agent-demo は最小構成のため未実装だが、本番では必須 (後の章で扱う) |
誰がやっているのか¶
最初の Q1-Q5 をエージェント越しに聞くと、それぞれ次のように解決される:
| 質問 | 誰が答えるか | 流れ |
|---|---|---|
| Q1: 今の日時 | now ツール |
LLM が「時刻を知らないので now を呼ぼう」と判断 → ツール実行 → 結果を LLM に戻す → LLM が人間向けに整形 |
| Q2: 今日の天気 | search ツール (→ SearXNG → Web) |
LLM が「Web 検索が必要」と判断 → search ツール → 検索結果から要約 |
| Q3: 3847 × 2915 | calc ツール (決定論的な計算) |
推論モデルは「頑張れば自力で解ける」が、速度 / コスト / 信頼性のために LLM が「ここは calc に任せるべき」と判断 → 即座に正答 |
| Q4: 政策金利 | search or wikipedia ツール |
LLM が「自分の知識は古いかも」と判断 → 最新情報を取得 |
| Q5: リポジトリのファイル | (agent-demo には無いが) file_read ツール |
ローカルに繋ぐツールを追加すれば解決可能 |
| Q6: 富士山の高さ | LLM 単独 | 学習済みの事実で十分 → ツール呼出なしで直接答える |
ここで重要なのは、LLM は「自分には何ができて、何が無理か」を判断するという部分が core であること。道具箱 (tools) をどれだけ揃えても、LLM 側で「これは道具を使うべき場面だ」と認識しなければ使ってくれない。この判断を LLM に促すのがエージェントのシステムプロンプトで、道具を渡すだけなのがツール定義 (JSON schema)。