1. LlamaIndexとGeminiが拓く、自律型エージェントの未来
皆さん、AIの進化は本当に目覚ましいですよね。特に最近、私が注目しているのが「マルチエージェントシステム」です。これは、単一のAIではなく、複数のAIエージェントがそれぞれの役割を持ち、連携しながら一つの目標を達成する仕組み。まるでプロフェッショナルなチームが動いているようなものなんです。
今回ご紹介するのは、LlamaIndexという強力なフレームワークと、Googleの最先端LLMであるGeminiを組み合わせた方法です。LlamaIndexは、LLMを皆さんのデータと結びつけ、知識ベースのエージェントを構築するための「司令塔」のような存在だと私は捉えています。そして、Geminiは、そのエージェントの「頭脳」として推論やテキスト処理を担います。特に、高速性に優れた『gemini-3.6-flash』のようなモデルは、リアルタイムに近い応答が求められるエージェントシステムにおいて非常に有効だと感じていますね。
まずは、この強力なタッグを組むための準備から始めましょう。LlamaIndexの各種ライブラリをインストールし、Gemini APIキーを設定します。APIキーは環境変数として設定するのがスマートなやり方です。これで、エージェントが動き出すための舞台が整います。
pip install llama-index llama-index-utils-workflow llama-index-llms-google-genai llama-index-tools-google
APIキーの設定は、セキュリティ上も非常に重要なので、必ず環境変数として管理してくださいね。
import os
from llama_index.llms.google_genai import GoogleGenAI
# os.environ['GEMINI_API_KEY'] = 'YOUR_API_KEY_HERE' # 実際には環境変数に設定
assert 'GEMINI_API_KEY' in os.environ
llm = GoogleGenAI(model="gemini-3.6-flash")
2. エージェントの「手足」となるツールの構築と状態管理
エージェントがただ賢いだけでは、現実世界で役立つことはできません。彼らには「手足」が必要です。それが「ツール」です。ツールとは、エージェントが外部の世界と対話するための機能で、例えばインターネット検索をしたり、情報を記録したりする能力をエージェントに与えます。LlamaIndexでは、これらのツールを通常のPython関数として定義したり、既存のToolSpecsからインポートしたりできます。
Gemini自体もGoogle Searchという強力な組み込みツールを持っています。これを活用すれば、エージェントは瞬時に最新の情報をウェブから取得できるようになります。私の開発経験上、この「外部情報アクセス能力」はエージェントの賢さを飛躍的に向上させる鍵だと断言できますね。
from google.genai import types
google_search_tool = types.Tool(google_search=types.GoogleSearch())
llm_with_search = GoogleGenAI(
model="gemini-3.6-flash",
generation_config=types.GenerateContentConfig(tools=[google_search_tool])
)
# 検索が必要なクエリでLLMをテスト
# response = await llm_with_search.acomplete("What's the weather like today in Biarritz?")
# print(response)
さらに、マルチエージェントシステムでは、エージェント間で情報を共有し、状態を維持することが不可欠です。ここで登場するのがContextクラスです。これは、エージェントやツール間で「現在の状況」や「作業の進捗」といった状態をやり取りするためのハブとなります。例えば、search_webでウェブを検索し、record_notesでその結果を記録するといった一連の作業は、このContextを通じてスムーズに行われます。私はこれを「エージェント間の情報共有ノート」と呼んでいます。このノートがあるからこそ、エージェントたちはまるで人間のように協調作業ができるのです。
from llama_index.core.workflow import Context
async def search_web(ctx: Context, query: str) -> str:
# GeminiとGoogle Searchを使ってウェブ検索
...
async def record_notes(ctx: Context, notes: str, notes_title: str) -> str:
# 検索結果をContextに記録
current_state = await ctx.store.get("state")
if "research_notes" not in current_state:
current_state["research_notes"] = {}
current_state["research_notes"][notes_title] = notes
await ctx.store.set("state", current_state)
return "Notes recorded."
# write_report, review_reportなども同様に定義
3. 賢い「チーム」を動かすマルチエージェントワークフローの設計
ここからが本番です。複数のエージェントが連携して、一つの大きなタスクをこなす「マルチエージェントワークフロー」を構築します。今回の例では、以下の3つのエージェントを定義します。
- ResearchAgent: ウェブを検索し、情報を収集してメモを記録する「リサーチャー」。
- WriteAgent: ResearchAgentが集めた情報をもとにレポートを作成する「ライター」。
- ReviewAgent: WriteAgentが書いたレポートをレビューし、フィードバックを提供する「レビュアー」。
これらのエージェントは、AgentWorkflowクラスを使ってオーケストレーションされます。各エージェントにはsystem_promptを与え、彼らの役割と、他のエージェントとの連携方法を明確に指示します。これは、人間でいうところの「プロジェクトの役割分担と行動規範」のようなものです。さらに、can_handoff_toパラメータで、どのエージェントに次のタスクを引き渡せるかを明示的に指定することで、ワークフローの堅牢性を高めます。私の経験では、このsystem_promptの設計とcan_handoff_toによる連携パスの明確化が、ワークフローの成否を分けると言っても過言ではありません。
from llama_index.core.agent.workflow import FunctionAgent, AgentWorkflow
research_agent = FunctionAgent(
name="ResearchAgent",
description="Useful for searching the web for information on a given topic and recording notes on the topic.",
system_prompt=(
"You are the ResearchAgent that can search the web for information on a given topic and record notes on the topic. "
"Once notes are recorded and you are satisfied, you should hand off control to the WriteAgent to write a report on the topic."
),
llm=llm,
tools=[search_web, record_notes],
can_handoff_to=["WriteAgent"],
)
write_agent = FunctionAgent(
name="WriteAgent",
description="Useful for writing a report on a given topic.",
system_prompt=(
"You are the WriteAgent that can write a report on a given topic. "
"Your report should be in a markdown format. The content should be grounded in the research notes. "
"Once the report is written, you should get feedback at least once from the ReviewAgent."
),
llm=llm,
tools=[write_report],
can_handoff_to=["ReviewAgent", "ResearchAgent"],
)
review_agent = FunctionAgent(
name="ReviewAgent",
description="Useful for reviewing a report and providing feedback.",
system_prompt=(
"You are the ReviewAgent that can review a report and provide feedback. "
"Your feedback should either approve the current report or request changes for the WriteAgent to implement."
),
llm=llm,
tools=[review_report],
can_handoff_to=["ResearchAgent", "WriteAgent"],
)
agent_workflow = AgentWorkflow(
agents=[research_agent, write_agent, review_agent],
root_agent=research_agent.name,
initial_state={
"research_notes": {},
"report_content": "Not written yet.",
"review": "Review required.",
},
)
# ワークフローの実行
# handler = agent_workflow.run(user_msg="Write me a report on the history of the web...")
# for event in handler.stream_events():
# # イベントの監視ロジック
# ...
このように、エージェント間の役割と連携を明確に定義することで、複雑なタスクも自動で、しかも高品質に実行できるAIチームが誕生するわけです。これはまさに、未来の働き方を示唆していると私は確信しています。
4. 実務での活用と未来のビジネスインパクト
このマルチエージェントワークフローは、単なる技術デモで終わるものではありません。私たちの実務、特に営業、開発、そして一般的な業務において、計り知れない可能性を秘めていると私は見ています。
営業の現場ではどうでしょうか? 例えば、「競合他社の最新動向を調査し、その情報を盛り込んだ顧客向け提案書のドラフトを作成、さらに上司がレビューする」といった一連のプロセスを自動化できます。ResearchAgentが市場調査を行い、WriteAgentが提案書を生成、ReviewAgentがチェックを入れる。これにより、営業担当者はより戦略的な活動に時間を割けるようになります。私は、このシステムが営業の生産性を劇的に向上させると確信しています。
開発現場での応用も無限大です。 「特定の技術に関する最新情報を収集し、その技術を使ったサンプルコードの設計案を作成、そしてコードレビューの初期段階を行う」といったタスクも考えられます。ResearchAgentが技術トレンドを調査し、WriteAgentが設計ドキュメントを生成、ReviewAgentが潜在的な問題点を指摘する。これにより、開発者はより創造的なコーディングに集中でき、品質向上にも繋がります。
一般的な実務では、 「特定のテーマに関する市場調査レポートを自動生成し、その内容を要約して社内向けに共有する」といった用途も考えられます。情報収集からレポート作成、そしてレビューまでの一連の作業が自動化されれば、私たちの日常業務は大きく効率化されるでしょう。私自身、日々の情報収集やレポート作成にこの仕組みを応用できないかと、常に考えています。
この技術は、単なる自動化を超え、私たちの思考プロセスを拡張し、より高度な意思決定を支援するパートナーとなるでしょう。AIエージェントがチームとして機能することで、私たちはより複雑で創造的な課題に挑戦できるようになります。これからのビジネスにおいて、このマルチエージェントシステムをいかに自社の競争力に変えていくか、それが問われる時代がもうそこまで来ています。