株式会社CINC 開発本部(旧:開発部) エンジニアブログ

開発部→開発本部!!ビッグデータ取得/分析・自然言語処理・人工知能(AI)を用いた開発を軸に、マーケティングソリューションの開発や、DX推進を行っている、株式会社CINCの開発本部です。

Strands Agentsで爆速セットアップ!初めてのAIエージェント体験

Strands Agentsで爆速セットアップ!初めてのAIエージェント体験 こんにちは、CINC開発本部です!

本記事では、5/16に発表されたAWS製のPythonライブラリ「Strands Agents」を使って、AIエージェント開発をしてみます。 最小構成のエージェントを動かすところから、簡単なツールの使い方までを、実際のコードとともにご紹介します。

「AIエージェントに興味があるけど、何から始めればいいかわからない」 「とりあえず動かしてみたい」 そんな方に、Strands Agentsの雰囲気を掴んでいただければ幸いです。

最小構成のエージェントを作って見る

Strands Agentsを使ったAIエージェント開発の第一歩として、まずは最もシンプルな構成でエージェントを動かしてみましょう。 公式ドキュメント にも例がありますが、ここではその内容をご紹介します。

環境構築は、仮想環境を作成し、pip install strands-agents を実行するだけです。

# 環境構築
$ python -m venv .venv
$ pip install strands-agents

Pythonコードも非常に短く、strands から Agent をインポートし、インスタンスを作成して質問を投げる、という数行で完結します。

# agent_1.py
from strands import Agent

agent = Agent()
agent("AIエージェントについて教えてください。")

Strands AgentsはデフォルトでAmazon BedrockのClaude 3.7 Sonnet(us-west-2) を利用します。 そのため、事前にBedrockで該当モデルの利用申請と、AWS の認証情報設定が必要です。

準備が整ったら、Pythonスクリプトを実行します。

$ python -u agent.py

すると、AIエージェントが質問に対して回答を返してくれます。

# AIエージェントとは

AIエージェントは、特定の目標を達成するために環境を認識し、意思決定を行い、行動する自律型AIシステムです。

## 主な特徴

- 自律性: 人間の直接的な介入なしに行動できる
- 環境認識: センサーやデータ入力から周囲の状況を把握する
- 意思決定: 収集した情報に基づいて判断を行う
- 行動能力: 決定に基づいて具体的なアクションを実行する

## 代表的な種類

1. タスク指向型エージェント: 特定のタスク(予約管理、質問応答など)に特化
2. 会話型エージェント: チャットボットやバーチャルアシスタント
3. 自律学習型エージェント: 経験から学習して行動を改善するAI

## 応用分野

- ビジネス(カスタマーサポート、プロセス自動化)
- 医療(診断支援、患者モニタリング)
- 金融(取引分析、詐欺検知)
- 製造(品質管理、予測保守)
- 個人向け(バーチャルアシスタント)

## 今後の発展

AIエージェント技術は、マルチエージェントシステムや、より複雑な判断が求められる領域への応用が期待されています。

何か特定の側面についてさらに詳しく知りたいことはありますか?

このように、非常に少ない手順とコードで、Bedrock上のClaude 3.7 Sonnetを活用したAIエージェントをつくることができました。 複雑な設定なしに始められるのは、AIエージェント開発の入門として魅力的ですね。

ただし、これだけではエージェント感はないですね。

ステップアップ!Strands Agentsでツールを使いこなすAIエージェント開発

基本がわかったところで、次はもう少しステップアップしてみましょう。 Strands Agentsの公式クイックスタートガイド を参考に、複数の「ツール」を組み込んだエージェントを作成していきます。

エージェントに計算機能や時刻取得といった具体的な能力を与えるには、「ツール」の活用が鍵となります。 まずは、関連パッケージをインストールしましょう。

# 追加のライブラリをインストール
$ pip install strands-agents-tools strands-agents-builder

strands-agents-tools は、計算機や現在時刻取得など、すぐに使える便利なツール群を提供してくれます。 一方、strands-agents-builder は、オリジナルのエージェントやツールを開発する際に役立つサポートパッケージのようです。

それでは、ガイドを参考にこれらのツールと、簡単なカスタムツールを定義してエージェントに組み込んでみましょう。 ガイドでは指定された単語内に特定の文字がいくつ含まれるかを数える letter_counter というカスタムツールも作成しています。

# agent_2.py
from strands import Agent, tool
from strands_tools import calculator, current_time, python_repl

# @tool デコレータを使ってPython関数としてカスタムツールを定義
@tool
def letter_counter(word: str, letter: str) -> int:
    """
    単語内に特定の文字が何回現れるか数えます。

    引数:
        word (str): 検索対象の単語
        letter (str): 数えたい特定の文字

    戻り値:
        int: 単語内に含まれる文字の数
    """
    if not isinstance(word, str) or not isinstance(letter, str):
        return 0

    if len(letter) != 1:
        raise ValueError("'letter' パラメータは1文字でなければなりません")

    return word.lower().count(letter.lower())


# strands-toolsのサンプルツールパッケージとカスタムletter_counterツールを使ってエージェントを作成
agent = Agent(tools=[calculator, current_time, python_repl, letter_counter])

# 利用可能なツールを使ってエージェントに質問を投げる
message = """
4つお願いがあります:

1. 今の時刻を教えてください。
2. 3111696 ÷ 74088 を計算してください。
3. "strawberry" という単語に含まれる "R" の数を教えてください 🍓
4. 今話した内容を実行するスクリプトを出力してください!
   スクリプトを出力する前に、Pythonツールを使って正しく動作することを確認してください
"""
agent(message)

このエージェントに複数のお願いをすると、以下のように各タスクに対応するツールを判断し、順番に実行してくれました。

お願いを4つ承りました。順番に対応いたします。

### 1. 現在の時刻
Tool #1: current_time
現在の時刻は 2025年5月29日 03時39分58秒 (UTC) です。

### 2. 計算: 3111696 ÷ 74088
Tool #2: calculator
3111696 ÷ 74088 = 42 です。

### 3. "strawberry"に含まれる"R"の数
Tool #3: letter_counter
"strawberry"という単語には "r" が3回含まれています。

### 4. これらの処理を行うPythonスクリプト
Tool #4: python_repl
Do you want to proceed with Python code execution? [y/*] y
1. 現在の時刻: 2025-05-29T03:40:17.372240+00:00
2. 3111696 ÷ 74088 = 42.0
3. "strawberry"という単語に含まれる"r"の数: 3
すべての処理が完了しました。
以上で4つのお願いにお応えしました。

1. 現在の時刻は UTC で 2025年5月29日 03時39分58秒 です。
2. 3111696 ÷ 74088 の計算結果は 42 です。
3. "strawberry" という単語には "r" が3回含まれています。
4. これらの処理を行うPythonスクリプトを作成し、実行して正しく動作することを確認しました。

スクリプトは以下の通りです:

``python
import datetime
import pytz

def main():
    # 1. 現在時刻を取得して表示
    current_time = datetime.datetime.now(pytz.UTC).isoformat()
    print(f"1. 現在の時刻: {current_time}")
    
    # 2. 3111696 ÷ 74088 を計算
    result = 3111696 / 74088
    print(f"2. 3111696 ÷ 74088 = {result}")
    
    # 3. "strawberry"という単語に含まれる"r"の数を数える
    word = "strawberry"
    letter = "r"
    count = word.lower().count(letter.lower())
    print(f"3. \"{word}\"という単語に含まれる\"{letter}\"の数: {count}")
    
    print("すべての処理が完了しました。")

if __name__ == "__main__":
    main()
``

すべてのタスクを正常に実行し、Pythonスクリプトでも動作確認が取れました。 このように、エージェントが自ら判断してツールを使いこなし、最終的にはPythonスクリプトまで生成してくれるのは、非常に強力ですね。

pythonコードの実行は以下の部分で実行してよいかの確認が入ります。

Do you want to proceed with Python code execution? [y/*] y

コード実行やファイル操作などは実行前に確認が入るので安心して使えますね。

自由自在!Strands AgentsでAIエージェントの心臓部「モデル」を操る

Strands Agents でエージェントが使用する基盤モデルを確認する方法と、特定のモデルを指定する方法について見ていきましょう。これらの詳細については、公式ドキュメントのモデルプロバイダーに関するセクションも参考になります。

まず、エージェントが現在どのモデルを利用しているか確認するには、Agentインスタンスmodel.configを参照します。

# agent_3.py
from strands import Agent

agent = Agent()

print(agent.model.config)
# {'model_id': 'us.anthropic.claude-3-7-sonnet-20250219-v1:0'}

上記のように、デフォルトではAmazon Bedrockのus.anthropic.claude-3-7-sonnet-20250219-v1:0が使用されていることが分かります。

モデルを変更する主な方法としては、以下の2つがあります。

  • モデルIDを文字列で指定する
  • 各モデルプロバイダーに対応したクラス(例:BedrockModel)を使用する

モデルIDを文字列で指定

最も手軽な方法は、モデルIDを文字列としてAgentの初期化時にmodel引数に渡すことです。

# agent_4.py
from strands import Agent

# Create an agent with a specific model by passing the model ID string
agent = Agent(model="us.anthropic.claude-3-7-sonnet-20250219-v1:0")

この方法では、モデルIDを直接文字列で指定するため、手軽にモデルを切り替えることができます。

BedrockModelを使用する

Strands Agentsのデフォルトの挙動でもありますが、strands.modelsモジュールにはBedrockModelクラスが用意されています。これを利用すると、Bedrock上のモデルをより詳細に設定することが可能です。

# agent_5.py
from strands import Agent
from strands.models import BedrockModel

# Create a BedrockModel
bedrock_model = BedrockModel(
    model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
    region_name='us-west-2',
    temperature=0.3,
)

agent = Agent(model=bedrock_model)

BedrockModelを使用すると、モデルIDだけでなく、リージョンやtemperatureといったパラメータも指定できます。

Bedrock 以外にも、Strands Agentsは様々なモデルプロバイダーに対応しています。例えば、以下のようなものが利用可能です。

これらのプロバイダーの中にはOllamaのようにローカルLLMをサポートするものもあり、ローカル環境で動作するセキュアなエージェントの構築も視野に入ります。

可能性は無限大!Strands Agentsの「ツール」でエージェントを最強装備に

Strands Agentsを用いてAIエージェントを開発する上で、「ツール」という機能の活用が不可欠です。 ツールを利用することで、エージェントは単にテキストを生成するだけでなく、外部システムと連携したり、データを取得したり、さらには様々なアクションを実行したりできるようになります。

Strands Agentsには、すぐに試せる便利なサンプルツール群が strands-agents-tools パッケージとして提供されており、これらを利用することで開発や実験をスムーズに進めることができます。

ツールの概要については公式ドキュメントのTools Overviewで、利用可能な具体的なツールの一覧はExample Built-in Toolsで確認できます。

以下は、strands-agents-tools で提供されている主なツールとその簡単な説明です。

  • RAG & Memory
    • retrieve: Amazon Bedrock Knowledge Bases からデータを検索・取得できるRAG(検索拡張生成)やメモリ用ツール。
    • memory: Bedrock Knowledge Bases を使ったエージェントのメモリ永続化。
    • mem0_memory: Mem0 を使ったパーソナライズ&メモリ機能。
  • File Operations
    • editor: ファイルの編集や検索、元に戻すなどの操作。
    • file_read: ファイルの読み込み・解析。
    • file_write: ファイルの作成・編集。
  • Shell & System
    • environment: 環境変数の管理。
    • shell: シェルコマンドの実行。
    • cron: cronジョブによるタスクスケジューリング。
  • Code Interpretation
  • Web & Network
    • http_request: APIコールやWebデータ取得、ローカルHTTPサーバー呼び出し。
    • slack: Slack連携(リアルタイムイベント、API、メッセージ送信)。
  • Multi-modal
    • image_reader: 画像の処理・解析。
    • generate_image: Amazon BedrockでAI画像生成。
    • nova_reels: BedrockでAI動画生成。
    • speak: テキストから音声生成(macOS sayコマンドやAmazon Polly)。
  • AWS Services
    • use_aws: AWSサービスとの連携。
  • Utilities
    • calculator: 数学演算。
    • current_time: 現在日時の取得。
    • load_tool: 実行時にツールを動的に追加。
  • Agents & Workflows
    • agent_graph: エージェントのグラフ構築・管理。
    • journal: タスクやログの構造化管理。
    • swarm: 複数エージェントの協調・ネットワーク化。
    • stop: エージェントのイベントループを強制停止。
    • think: 複数の思考プロセスを並列で実行。
    • use_llm: カスタムプロンプトで新しいAIイベントループを実行。
    • workflow: シーケンス化されたワークフローのオーケストレーション

これらのツールを組み合わせることで、エージェントに多種多様な機能を持たせることが可能になります。 ツールが非常に豊富で、これらを組み合わせることで、一通りの作業はこなせるようになりそうです。 全てのツールを試したわけではありませんが、AWS製ということもあり、use_aws ツールなどを通じてAWSサービスとの連携が容易である点は大きなメリットと言えるでしょう。

エージェントがエージェントを呼ぶ!?Strands Agentsで実現する高度な連携術

これまでの説明で、Strands Agentsを使った基本的なAIエージェントの構築やツールの利用方法を見てきました。ここではさらに一歩進んで、公式ドキュメントを参考にAIエージェント自体を「ツール」として扱い、より複雑なタスクを実行する例を紹介します。これは、エージェントがサンプルツールを使うだけでなく、特定の機能を持つエージェントを別のエージェントがツールとして呼び出す、という入れ子構造の考え方です。

例として、指定されたURLのブログ記事の内容を要約し、ファイルに保存するタスクを考えてみましょう。今回は、弊社のブログ記事「複数のMCPサーバ間でツール名が重複したら何が起きる?CopilotとClaudeで徹底検証」を対象とします。

まず、記事の要約と保存を行う機能を持つAIエージェントを「ツール」として作成します。

# agent_6.py
from strands import Agent, tool
from strands_tools import current_time, file_write, http_request


@tool
def summarize_assistant(query: str) -> str:
    SUMMARIZE_ASSISTANT_PROMPT = """
あなたは、与えられた記事の要約を作成するアシスタントです。
ユーザーが提供する記事の内容に基づいて、要約を作成し、yyyymmdd_${summary_title}.mdの形式で保存します。
"""
    summarize_agent = Agent(
        system_prompt=SUMMARIZE_ASSISTANT_PROMPT,
        tools=[file_write, http_request, current_time]
    )
    response = summarize_agent(query)
    return str(response)

次に、この summarize_assistant ツールを呼び出すオーケストレーターエージェントを定義します。

# agent_7.py
MAIN_SYSTEM_PROMPT = """
あなたは、クエリを専門エージェントにルーティングするアシスタントです:
- 研究に関する質問と事実情報 → research_assistant ツールを使用します
- 記事の要約と保存 → summarize_assistant ツールを使用します
- 専門知識を必要としない単純な質問 → 直接回答します

ユーザーのクエリに基づいて、常に最も適切なツールを選択してください。
"""

# Strands Agents SDK を使用すると、エージェントツールを簡単に統合できます
orchestrator = Agent(
    system_prompt=MAIN_SYSTEM_PROMPT,
    callback_handler=None,
    tools=[summarize_assistant] # 作成した要約アシスタントをツールとして登録
)

USER_PROMPT = "https://cincdevteam.hatenablog.com/entry/2025/05/16/140356について内容をまとめて保存して。"
response = orchestrator(USER_PROMPT)

これを実行すると、以下のような流れで処理が行われます。

ウェブ記事の内容を要約するために、まずはそのURLから記事の内容を取得します。
Tool #1: http_request
現在は記事の内容を取得できました。この記事を要約してファイルに保存します。
Tool #2: current_time
記事の内容を要約し、ファイルに保存します:
Tool #3: file_write
Do you want to proceed with the file write? [y/*] y
記事の要約が完了し、ファイルとして保存しました。この要約では、以下の内容を含めました:

1. 記事のタイトルと概要
2. MCPサーバの基本的な説明
3. GitHub CopilotとClaude Desktopでの検証結果の概要
4. 各AIツールの具体的な挙動の違い
5. 問題を回避するための提案された対策

ファイル名は「20250530_複数のMCPサーバ間でツール名が重複した場合の検証.md」として、今日の日付とタイトルの要約を含む形式で保存しました。要約は、原文の重要なポイントをすべて含みながら、簡潔にまとめられています。

ファイルは「20250530_複数のMCPサーバ間でツール名が重複した場合の検証.md」として保存されていました。 内容はきちんと読み取れており、しっかりと内容をまとめたファイル名で保存されていました。 ※実際の検証結果も非常に興味深いものになっていますのでこちらの記事も読んでみてくださいね。

このように、比較的少ないコード量で、エージェントが他のエージェントをツールとして呼び出し、協調してタスクを実行するような高度な処理も実現できます。

Strands Agentsは、公式ドキュメントの「Agents as Tools」のセクションでも示されているように、複数のエージェントを連携させるマルチエージェントシステムの構築もサポートしています。例えば、公式ドキュメントの例では、調査や事実確認に関する質問に答える research_assistant のようなエージェントや、製品の推薦を行う product_recommendation_assistant、旅行計画を支援する trip_planning_assistant といった、特定の役割を持つエージェントをツールとして利用するアイデアが紹介されています。

このようなアプローチにより、各エージェントが特定の専門知識や機能に特化し、それらを組み合わせることで、より複雑で高度なタスクに対応できるシステムの開発が期待できます。

まとめ

本記事では、AWS製のPythonライブラリ「Strands Agents」の基本的な使い方から応用までを解説しました。

  • 最小構成での実行: pip install strands-agents だけで、数行のコードでBedrock 上の Claude 3.7 Sonnetを利用したエージェントを簡単に動かせます。
  • モデルの選択: デフォルトモデルの確認や、モデルID指定、BedrockModel クラスによる詳細設定など、柔軟なモデル変更が可能です。Bedrock 以外にも多様なプロバイダーやローカルLLMも利用できます。
  • 豊富なツール群: RAG、ファイル操作、コード実行、Web連携など、多岐にわたる機能が提供されており、エージェントの能力を大きく拡張できます。
  • エージェントのツール化: エージェント自体をツールとして扱い、他のエージェントから呼び出すことで、より複雑なタスクを協調して処理するマルチエージェントシステムを構築できます。

Strands Agentsは、シンプルながらも高い拡張性を持ち、AIエージェント開発の多様なニーズに応えるライブラリと言えるでしょう。

参考情報源