はじめに
Amazon Bedrock Agent Core実践入門を読んだ背景
最近のAIの急成長ぶりについていけず、焦りを感じていたため、「AIを使う」というより「AIの仕組み」を理解することで根本から理解ができれば世の中の言っていることが理解できるんじゃないか?という思いから以下の本を買って勉強してみることにしました。
あの有名な「みのるん」さんの著書です。
なぜAIエージェントに興味をもったか
最近の世の中のAIについてよくわからないということもありますが、私は趣味で将棋を指します。
AIのことを学んで将棋のアプリケーションを何か作れないか?と思ったのがAIエージェントに興味を持ったキッカケです。
具体的には、将棋アプリで指した将棋には必ず"棋譜"が残ります。
棋譜はお互いの指し手のいわばログです。
この棋譜を使ってAIに解析させるアプリケーションは既に存在しますが、解析の結果この手は悪手、この手は最善手を見ることはできますが、「なぜ、この手が悪かったのか?、なぜこの手が最善手なのか?」については言語化してくれません。
将来的には解析の結果、明確に言語化してくれる解析アプリを作れないかな、という淡い期待を持ってAIエージェントを勉強してみようと思いました。
本記事の目的
まずは私のようにAIエージェントとは何か?といった基本的なことからわかっていない方に向けて解説し、AI初心者が読む記事を目的としています。
本書の感想
一通り読んでいきましたが、AI初心の私には最初は全く何を言っているのかわかりませんでした。
本当に絶望しながら本を読み進めていきました。
しかしながら諦めずに読み進めて、AIとも壁打ちしながら自分なりに理解できたことがあるのでその備忘として本記事にまとめていきたいと思います。
まずはじめに理解しておくと良いこと
Nintendo Switchとそのソフトを想像してください。
エンジニア的に言えば、ハードウェアとソフトウェアです。
つまり、基盤となるものと、基盤の上で動くものがあるということです。
ただし、基盤の上で動くものは「受け身」で動くものではなく、「自立的に」動くものです。
この「受け身」と「自立的に」の違いを具体的に表現しているのが以下の内容です。
AWSの解説ページ引用します。
AI エージェントは、絶え間ない人間の介入なしに自律的に行動します。従来のソフトウェアはハードコードされた指示に従いますが、AI エージェントは過去のデータに基づいて次の適切なアクションを特定し、人間の継続的な監視なしに実行します。
AIエージェントとは
そもそもAIエージェントってなんですか?
一言で言えば
「目的を達成するために必要な作業を自ら考えて実行する自立型のソフトウェア」です。
目的を与えることで、必要な情報を集めたり、ツールを利用して、自立的に行動します。
必要な情報を集めたり、ツールを利用してとはどういうこと?
具体的な例を用いて説明します。
例えば以下のように依頼した場合
「明日の東京の天気を調べて、雨ならTeamsに連絡して」
AIエージェントは次のように考えます。
1. 目的 -> 雨なら連絡する
2. 必要な情報は何か -> 明日の東京の天気
3. その情報はどこから取得できるか -> 天気API
4. 取得した結果はどうだったか? -> 雨予報
5. 次に何をするべきか -> Teamsへ通知する
6. どうやって通知するか? -> Teams APIを利用する
天気APIとTeams APIといったツールを利用して必要な情報を取得し、目的達成に向けて自律的に行動しています。
これがAIエージェントです。
自律できないAIチャットに同じように依頼したとしても
私は現在の天気を取得できません
と言われて終わります。
AgentCoreとは
Agent Coreってなんですか?
一言で言えば
「AIエージェントを動かすための土台 (プラットフォーム)」です。
冒頭でお話しましたが、イメージとしてはAIエージェントはゲームソフトだとすると、Agent CoreはNintendo Switch本体のような存在です。
AIエージェントが動作するために必要な仕組みを提供しています。
※実際にはハードウェアではなく、AIエージェントを動かすためのソフトウェア基盤です。
AIエージェントの裏側
ここまでの内容で理屈はわかった。
では実際にAIエージェントは裏側でなにやってんの?についてPythonのコードを見ながら理解していきます。
AIエージェントの動きはツールを利用して必要な情報を取得し、目的達成のために行動することでした。
この動きを実現するためには、あるエージェントが別のエージェントをツールとして利用する構成を作る必要があります。
著書の中ではAgents as Toolsというパターンが紹介されています。
Agents as Toolsとは、あるエージェントが別のエージェントをツールとして利用する設計パターンです。
これは親子関係になっていて、親 -> 子エージェントを呼び出して、調査の専門家に任せようという構成です。
1. 技術専門のリサーチエージェントを作成し、親エージェントからリサーチエージェントを呼び出せるようにする
2. ユーザ―から技術調査の依頼を受けた場合、親エージェントは自ら調査を行うのではなく、リサーチエージェントへ処理を移譲する
3. リサーチエージェントはWeb検索など情報収集を行い、その結果を親エージェントへ返却する
コードの例
親エージェント
Strands AgentsというOSSのAIエージェントフレームワークを使ってAIエージェントを作ってみます。
from strands import Agent
from agents.child_researcher import execute_research
parent_agent = Agent(
name="ParentOrchestrator",
system_prompt=(
"あなたは大工の棟梁のような親エージェント(オーケストレーター)です。"
"ユーザーからの質問を受け取ったら、自分でゼロから回答を作るのではなく、"
"適切なツール(execute_research)を呼び出して専門的な調査を行わせてください。"
"ツールから戻ってきたレポートを受け取ったら、ユーザーに向けてわかりやすく"
"全体をまとめた総括のコメントを添えて最終回答を作成してください。"
),
tools=[execute_research] # インポートした子ツールを登録
)
上記が親エージェントのコード例です。
親エージェントの実体は以下です。
ParentOrchestratorという識別名を定義しています。
parent_agent = Agent(
name="ParentOrchestrator"
)
以下は見ての通りシステムプロンプトの定義をしています。
自分が何者で、どう動くのかの役割を与えています。
system_prompt=(
"あなたは大工の棟梁のような親エージェント(オーケストレーター)です。"
"ユーザーからの質問を受け取ったら、自分でゼロから回答を作るのではなく、"
"適切なツール(execute_research)を呼び出して専門的な調査を行わせてください。"
"ツールから戻ってきたレポートを受け取ったら、ユーザーに向けてわかりやすく"
"全体をまとめた総括のコメントを添えて最終回答を作成してください。"
),
親エージェントの中に使えるツール (この場合子エージェント)を登録しています。
execute_researchは関数名で、親エージェントが必要に応じて子エージェントのexecute_research関数を使います。
tools=[execute_research]
必要に応じてとは、親エージェントが自律的に判断して子エージェントの関数を使うかを判断しています。
判断しているのはsystem_promptの以下の指示によって判断しています。
"ユーザーからの質問を受け取ったら、自分でゼロから回答を作るのではなく、"
"適切なツール(execute_research)を呼び出して専門的な調査を行わせてください。"
すごいですよね。
子エージェント
次に子エージェントです。
from strands import Agent, tool
# 1. 子エージェント本体
_researcher_agent = Agent(
name="ResearcherAgent",
system_prompt=(
"あなたは技術トピックの調査を担当する専門リサーチエージェントです。"
"入力されたテーマについて深く分析し、以下のフォーマットで出力してください。\n"
"1. 概要(2〜3文)\n"
"2. 主なメリット(箇条書き3点)\n"
"3. 導入時の考慮点(箇条書き1〜2点)"
)
)
# 2. 親から呼ばれるツールインターフェース
@tool
def execute_research(topic: str) -> str:
"""指定された技術トピックについて詳細な調査を行い、要約レポートを返します。
Args:
topic: 調査対象の技術やキーワード(例: 'AWS Bedrock AgentCore')
"""
print(f"\n[Tool Call] 親から依頼を受信: ResearcherAgent を起動中... (テーマ: '{topic}')")
response = _researcher_agent(f"『{topic}』について調査レポートを作成してください。")
return str(response)
以下が子エージェントの実体です。
_researcher_agent = Agent(
name="ResearcherAgent"
)
親エージェントと同様にシステムプロンプトの定義をしています。
system_prompt=(
"あなたは技術トピックの調査を担当する専門リサーチエージェントです。"
"入力されたテーマについて深く分析し、以下のフォーマットで出力してください。\n"
"1. 概要(2〜3文)\n"
"2. 主なメリット(箇条書き3点)\n"
"3. 導入時の考慮点(箇条書き1〜2点)"
)
ここでやっとexecute_research()関数が出てきました。
@toolデコレーター (目印)を付けることで親エージェントがエージェントツールとして利用することができます。
@tool
def execute_research(topic: str) -> str:
"""指定された技術トピックについて詳細な調査を行い、要約レポートを返します。
Args:
topic: 調査対象の技術やキーワード(例: 'AWS Bedrock AgentCore')
"""
print(f"\n[Tool Call] 親から依頼を受信: ResearcherAgent を起動中... (テーマ: '{topic}')")
response = _researcher_agent(f"『{topic}』について調査レポートを作成してください。")
return str(response)
main.pyの役割
main.py は、システム全体を動かす「起動スイッチ」であり、ユーザーとエージェントをつなぐ「受付窓口」となるファイルです。
ここでは親エージェントのみを呼び出しており、ユーザーから受け取った生の質問テキスト(user_query)を親へ渡す役割を担っています。
parent_agent(user_query)で親エージェントのparent_agent()関数を呼び出してユーザーからの自然言語の質問を渡しています。
from agents.parent_orchestrator import parent_agent
if __name__ == "__main__":
user_query = "AgentCore(AWS Bedrock AgentCore)の主なメリットと注意点について教えてください。"
print("==================================================")
print(f" ユーザーからのリクエスト:\n {user_query}")
print("==================================================")
final_output = parent_agent(user_query)
print("\n==================================================")
print(" 最終結果(親エージェントからの回答):")
print("==================================================")
print(final_output)
ここまでの流れを図で整理すると以下になります。
まとめ
本記事では主にAIエージェントにフォーカスを当てて内容をまとめてみました。
Agent Coreに関する詳細が書けていないため、この点を改めて自分の中でかみ砕いて理解し、実際にAIエージェントを動かす基盤の構築の仕方などをアウトプットできればと思っています。
