AIエージェント入門|ローカルLLMでマルチエージェントを構築する【第4週】

スポンサーリンク
この記事は約10分で読めます。

第3週では、ローカルLLMを使ってループ型エージェントを実装し、AIが「終わるまで考え続ける」仕組みを作りました。
これにより、AIは単発の処理ではなく、状況に応じて判断と実行を繰り返せるようになりました。

しかし実際のシステムでは、1つのAIだけですべてを判断・実行するのではなく、
役割ごとに複数のAIが分担して動く構成が一般的です。

本記事では、「司令塔」と「実行役」に分けたマルチエージェント構成を実装し、より実践的なAIエージェントの形を学びます。

AIエージェントとは

AIエージェントとは、単体で判断するだけでなく、複数の役割に分かれて連携しながら目的を達成する仕組みです。

第4週では「司令塔」と「実行役」に分けたマルチエージェント構成を実装します。

学習ロードマップ

内容
第1週チャット + JSON
第2週ツール呼び出し
第3週ループ
第4週マルチエージェント

作業環境について

本記事は、第1週の内容を前提として進めています。
そのため、以下の環境がすでに整っている状態を想定しています。

  • ローカルLLM実行環境:Ollama
  • 使用モデル:qwen3
  • Python仮想環境(venv)
  • ollama Pythonライブラリのインストール済み

作業環境の準備ができていない場合

第1週の記事で、環境構築からJSON出力までを解説しています。
未実施の場合は、先に第1週から進めることをおすすめします。

AIエージェント入門|ローカルLLMで学ぶチャットとJSON出力【第1週】

第4週のゴール

  • AIの役割を分けて設計できる
  • 複数のAIを連携させる
  • より実用的な構成を理解する

なぜマルチエージェントが必要なのか?

1つのAIでは何に限界があるのか

これまでの構成では、すべてを1つのAIが担当していました。

AI → 判断 → 実行 → 繰り返し

一見シンプルですが、実際の処理が増えてくると、ここに問題が出てきます。

限界①:判断が複雑になりすぎる

例えば、処理が増えると、1つのAIが、以下の「どの処理を選ぶか」の判断を毎回考える必要がでます。

  • タスクを追加する
  • タスクを削除する
  • 優先度を変更する
  • データを確認する

その結果、判断ロジックがどんどん複雑になります

限界②:役割が混ざる

1つのAIが、以下の様にすべて担当する必要があります。

  • 何をするか決める
  • 実行方法を考える
  • 結果を評価する

その結果、「何をしているAIなのか」が曖昧になります

限界③:拡張しにくい

例えば、以下の様に機能を追加した場合、すべて1つのAIに影響する。

  • 新しいツールを追加
  • 新しいルールを追加

その結果、コードの修正がどんどん難しくなります

限界④:コンテキスト長の制限

LLMの制約に、コンテキスト長(コンテキストウィンドウ)の上限があります。
コンテキスト長(単位:トークン)とは、LLMが一度に扱える情報量の限界のことです。

コンテキスト長は、LLMのモデル・バージョンやシリーズによって異なります。
例えば、Qwen3-4Bでは32Kトークン・Qwen3-8Bでは128Kトークンになります。
参考:Qwen3 公式ブログ

ループ型エージェントでは、次のように会話や処理履歴を蓄積していきます。

過去の指示
↓
過去の実行結果
↓
新しい入力
↓
AIが判断

しかし、履歴が増え情報量が増え、コンテキスト長の上限を超えるとLLMは処理ができなくなります。

これにより、以下の問題が生じてきます。

  • 古い情報が切り捨てられる
  • 文脈が欠ける
  • 判断の精度が下がる

マルチエージェントでどう解決されるか

これらの問題を解決するのが、AIを役割ごとに分ける方法です。

司令塔AI(Planner) → 何をするか決める
実行AI(Worker)   → 実際に処理する

① 判断がシンプルになる

司令塔AIは、「何をするか」だけ考えればいい

② 役割が明確になる

司令塔 → 判断専門
実行役 → 実行専門

これにより、責任がはっきり分けることができます。

③ 拡張しやすくなる

以下の場合でも、

  • 実行AIを増やす
  • 新しいツールを追加

司令塔はそのまま使うことができます。

1つのAI
→ 1人で全部やる

マルチエージェント
→ チームで分担する

④扱う情報を制限できる

それぞれのLLMが扱う情報量を限定することができます。

司令塔AI → 判断に必要な情報だけ持つ
実行AI   → 個別の処理だけ担当

これにより、以下のメリットが生じます。

  • コンテキストが短くなる
  • 情報の整理がしやすくなる
  • 精度が安定する

マルチエージェント動作の図解

シングルAIとマルチエージェント構成を比較した図。Planner AIが判断し、Worker AIが実行することで処理を分担する仕組みを示している。
AIを役割ごとに分けることで、処理がシンプルで効率的になる

実装してみる

完成コード

Multi-agent

マルチエージェントコード説明

マルチエージェントでは、「考える役割」と「動く役割」を分けて設計します。

司令塔AI(Planner)

何をするかを決める役割

ユーザーのメッセージ(messages)をもとに、

  • どの処理が必要か
  • どの関数を使うべきか

を判断します。

実行AI(Worker)

実際に処理を行う役割

司令塔AIが決めた内容を受け取り、

  • 関数(add_todo)を実行する
  • 結果を返す

といった「実際の動き」を担当します。

Plannerの指示を取り出す

messageの中に(tool_calls)が含まれている場合は、messageリストの中身(指示書)を tool_calls に入れる。
tool_calls)が含まれていない場合は、空のリスト []tool_calls に入れる。

tool_callsの中身

Workerが指示を実行し会話履歴(messages)を更新

tool_calls(Plannerの指示リスト)から順次指示を取り出し、Workerが実行する。
Plannerの指示内容(message)とWorkerの実行結果(result)を、会話履歴(messages)に追加する。

Workerの動作報告

Workerの動作結果を報告するために、会話履歴(messages)を、再度LLM(qwen3)にchat 関数で再度送り、返答を画面に表示する。

AIマルチエージェント処理フローまとめ

AIによるプランニング (planner)

  • ユーザーの依頼(「牛乳を買うタスクを追加して」)を受け取り、AIが「どの道具(関数)を使うべきか」を判断します。

AIの回答(指示書)を受け取る

  • AIの返答から「メッセージ本体(message)」と「道具の使用指示(tool_calls)」を取り出します。

道具を使う必要があるか判定 (if tool_calls)

  • AIが「道具を使いたい」と言った場合はステップ4へ進みます。
  • 「道具は不要(ただの雑談など)」と判断した場合はステップ8へ飛びます。

実際の関数を実行 (worker)

  • for 文を使って、AIからの指示(call)を一つずつ取り出し、プログラム内の関数(add_todo)を実際に動かして結果(result)を得ます。

AIの「考え」を履歴に記録 (messages.append(message))

  • 「AIがこの関数を使おうとした」という過程を、会話履歴に追加します。

関数の「実行結果」を履歴に記録 (messages.append(...))

  • 実際に道具を動かして得られた結果(「追加しました」という報告など)を、tool 役として履歴に追加します。

最終回答の作成と表示 (final = chat)

  • 「ユーザーの依頼」「AIの判断」「実際の実行結果」が揃った履歴をAIに送り直し、ユーザーへの丁寧な完了報告を作成して表示します。

(道具不要な場合)回答をそのまま表示 (else)

  • 道具を使わなかった場合は、AIが返したメッセージ(「こんにちは」など)をそのまま画面に表示します。

関数の実行

Git Bashで、保存したフォルダに移動してから実行します。

上記コマンドは、第1週で構築したPython仮想環境での実行例です。
Python仮想環境の構築に関しては、第1週ステップ5およびステップ6を参考にしてください。

正常に動けば、AIからの返答がターミナルに表示されます。

第4週のまとめ

この週では、AIエージェントを「役割ごとに分けて動かす」仕組みを学びました。

1. AIは分けて設計できる

AIは1つにまとめる必要はなく、役割ごとに分けて設計することができます。

2. 役割ごとに動かす

マルチエージェントでは、

  • 司令塔(Planner) → 何をするか決める
  • 実行役(Worker) → 実際に処理する

というように、判断と実行を分けて動かします。

3. これが実用的な構成

役割を分けることで、

  • 処理がシンプルになる
  • 拡張しやすくなる
  • 安定した動作になる

システムとして使える形になります。

シリーズまとめ

参考リンク

Function calling | OpenAI API