Serverless Operations, inc

>_cd /blog/id_4h5v1lav4rz2

title

Strands Agents - AWSにより開発されたオープンソースAI エージェントSDKを試してみた

今日は Strands Agents を試していきます。

Strands Agents とは

AWSにより開発されたオープンソースのPythonをベースとしたSDKです。

Strands Agents – オープンソース AI エージェント SDK の紹介

1) モデル2) ツール3) プロンプト 3つの要素から構成されており自律的に処理を行います。

Agentとは決まった定義はなく、 人(またはシステム)が与えた目標を実現するために、複数のステップや判断を通じて動くものを指します。
 (例えば、「資料を集めて要約する」「Web を検索して回答を得る」「データ集約を行う」など、単一の応答ではなく複数行動をひとまとめに遂行する)

MCPやRAGによりLLMの検索能力を拡張させることができますが、Agentによりさらに複雑な複数ステップの処理が可能となります。

モデル:Strands Agents はオープンソースでありAmazon Bedrock専用ではなく、様々なLLMモデルとの連携が可能となっています。

ツール:目的ごとに各ステップの処理を行います。

プロンプト:Agentに与えられる一連の仕事目標です。

Amazon Bedrock AgentCore と Strands Agents

先日一般サービス提供開始となり東京リージョンでも利用可能となったAmazon Bedrock AgentCore と Strands Agents の関係は少しややこしいですが、基本は補完関係にあります。AgentCoreはAI Agentの動作に必要なツール群がホスティングされている本番環境を想定した基盤サービスです。

Amazon Bedrock AgentCore (1) Bedrockとの違いの整理と AgentCore Runtime ~はじめてのAgentの起動~

Amazon Bedrock AgentCore (2) Memory 実践編:短期記憶と要約による長期記憶を試す

Amazon Bedrock AgentCore (3) Gateway :API や Lambda を OAuth やセキュリティ統制を統合してMCP Serverとして公開させる

Amazon Bedrock AgentCore (4) Code Interpreter :自然言語からのコードの記述・実行・デバッグ

Amazon Bedrock AgentCore (5) Browser Tool :AI上でPlaywrightを実行し、ヘッドレスブラウザからスクレイピングさせてみた

Amazon Bedrock AgentCore (6) Observability :OpenTelemetry を用いた AgentCore Runtime の実行状況や消費トークンの管理を行う

過去一連のブログで見てきたようにAgentsと連携する様々な機能がホスティングされています。

対してStrands AgentsはAgent開発用SDKです。AgentCoreの開発用にも使うことが可能です。つまり、「Strands で書いたエージェントを AgentCore に載せて運用する」という関係性です。

さっそくやってみる

Getting Started with Strands Agents: A Step-by-Step Guide

こちらに簡単な手順を中の人がまとめてくれていますのでやっていきます。

環境設定

必要なライブラリのインストールを行います。環境によっては pythonpython3 に読み替えてください。

bash
# Create a new directory for your project
mkdir strands-agent-project
cd strands-agent-project

# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install required packages
pip install strands-agents strands-agents-tools boto3

AWS CLI の設定

AWS CLIをインストールしIAMクレデンシャル設定します。このサンプルではStrands Agents のモデルはBedrockを指定するため、IAMユーザーにはBedRock のFullAccess を指定しておきます。

bash
# Configure a specific profile for Bedrock
aws configure --profile bedrock

# Verify your configuration
aws sts get-caller-identity --profile bedrock

# Check which models you have access to
aws bedrock list-foundation-models --profile bedrock

Agent の作成

まず requirements.txtで必要なライブラリを指定します。

strands-agents>=0.1.0
strands-agents-tools>=0.1.0
boto3>=1.28.0

次に _init_.pyを作成します。

python
from . import agent

最後にAgent本体のファイルを agent.py として作成します。

import os
import logging

# CRITICAL: Set AWS environment variables BEFORE importing strands
# This was key to solving my region configuration issues
os.environ['AWS_PROFILE'] = 'bedrock'
os.environ['AWS_REGION'] = 'us-east-1'  # Use a region where you have model access

# Configure logging for better debugging
# logging.basicConfig(level=logging.DEBUG, 
#                   format='%(levelname)s | %(name)s | %(message)s')

from strands import Agent, tool
from strands_tools import calculator, current_time, python_repl

# Define a custom tool
@tool
def letter_counter(word: str, letter: str) -> int:
    """
    Count occurrences of a specific letter in a word.
    
    Args:
        word (str): The input word to search in
        letter (str): The specific letter to count
        
    Returns:
        int: The number of occurrences of the letter in the word
    """
    if not isinstance(word, str) or not isinstance(letter, str):
        return 0
    
    if len(letter) != 1:
        raise ValueError("The 'letter' parameter must be a single character")
        
    return word.lower().count(letter.lower())

# Create the agent with tools and specify the model
# Use a model ID you confirmed access to in your region
agent = Agent(
    tools=[calculator, current_time, python_repl, letter_counter],
    model="anthropic.claude-3-5-sonnet-20240620-v1:0"  # Specify your model
)

# Define a message to test the agent
message = """
I have 4 requests:
1. What is the time right now?
2. Calculate 3111696 / 74088
3. Tell me how many letter R's are in the word "strawberry"
4. Output a script that does what we just spoke about!
   Use your python tools to confirm that the script works before outputting it
"""

# Run the agent and handle any errors
if __name__ == "__main__":
    try:
        print("Running the agent...")
        response = agent(message)
        print("\nAgent Response:")
        print(response)
    except Exception as e:
        print(f"Error: {e}")
        import traceback
        traceback.print_exc()

元のブログの内容は微小ながらバグがあったため修正していますのでこちらを使うようにしてください。

実行

ではいよいよ実行です。

python -u agent.py
Running the agent...
Certainly! I'll address each of your requests one by one using the available tools.

1. To get the current time:
Tool #1: current_time
The current time is 2025-10-18T04:22:23.943672+00:00 in UTC.

2. To calculate 3111696 / 74088:
Tool #2: calculator
The result of 3111696 / 74088 is 42.

3. To count the number of letter R's in the word "strawberry":
Tool #3: letter_counter
There are 3 occurrences of the letter 'r' in the word "strawberry".

4. Now, let's create a Python script that does all of the above and confirm that it works:
Tool #4: python_repl
Do you want to proceed with Python code execution? [y/*] y
I apologize for the error. It seems the `pytz` module is not available in the Python environment. Let's modify the script to use the built-in `datetime` module instead:
Tool #5: python_repl
Do you want to proceed with Python code execution? [y/*] y
1. Current time:
2025-10-18T04:27:10.396333+00:00

2. Result of 3111696 / 74088:
42.0

3. Number of 'r's in 'strawberry':
3

All tasks completed!
Great! The script works as expected. Here's the final Python script that performs all the tasks we discussed:

```python
import datetime

def current_time():
    return datetime.datetime.now(datetime.timezone.utc).isoformat()

def calculator(a, b):
    return a / b

def letter_counter(word, letter):
    return word.lower().count(letter.lower())

# 1. Get current time
print("1. Current time:")
print(current_time())

# 2. Calculate 3111696 / 74088
print("\n2. Result of 3111696 / 74088:")
print(calculator(3111696, 74088))

# 3. Count 'r' in "strawberry"
print("\n3. Number of 'r's in 'strawberry':")
print(letter_counter("strawberry", "r"))

print("\nAll tasks completed!")
```

This script accomplishes all four tasks:
1. It gets the current time in UTC and prints it in ISO format.
2. It calculates 3111696 / 74088 and prints the result (42.0).
3. It counts the number of 'r's in "strawberry" and prints the result (3).
4. The script itself is the output that does what we discussed, and we've confirmed that it works correctly.

You can run this script, and it will perform all the tasks we've discussed in our conversation.
Agent Response:
Great! The script works as expected. Here's the final Python script that performs all the tasks we discussed:

```python
import datetime

def current_time():
    return datetime.datetime.now(datetime.timezone.utc).isoformat()

def calculator(a, b):
    return a / b

def letter_counter(word, letter):
    return word.lower().count(letter.lower())

# 1. Get current time
print("1. Current time:")
print(current_time())

# 2. Calculate 3111696 / 74088
print("\n2. Result of 3111696 / 74088:")
print(calculator(3111696, 74088))

# 3. Count 'r' in "strawberry"
print("\n3. Number of 'r's in 'strawberry':")
print(letter_counter("strawberry", "r"))

print("\nAll tasks completed!")
```

This script accomplishes all four tasks:
1. It gets the current time in UTC and prints it in ISO format.
2. It calculates 3111696 / 74088 and prints the result (42.0).
3. It counts the number of 'r's in "strawberry" and prints the result (3).
4. The script itself is the output that does what we discussed, and we've confirmed that it works correctly.

You can run this script, and it will perform all the tasks we've discussed in our conversation.

実行解説

全部で4つのツールが5回実行されています。MCP等であれば1プロンプトが1実行となるため、Agentの方がより複雑な処理が可能になることがわかります。

agent = Agent(
    tools=[calculator, current_time, python_repl, letter_counter],
    model="anthropic.claude-3-5-sonnet-20240620-v1:0"  # Specify your model
)

この部分によりまず4つのツールがAgentに読み込まれています。letter_counter のみ以下のスクリプトにより外部で定義されたカスタムツールで他はビルトインツールです。

# Define a custom tool
@tool
def letter_counter(word: str, letter: str) -> int:
    """
    Count occurrences of a specific letter in a word.
    
    Args:
        word (str): The input word to search in
        letter (str): The specific letter to count
        
    Returns:
        int: The number of occurrences of the letter in the word
    """
    if not isinstance(word, str) or not isinstance(letter, str):
        return 0
    
    if len(letter) != 1:
        raise ValueError("The 'letter' parameter must be a single character")
        
    return word.lower().count(letter.lower())

Agentに与えられるスクリプトは以下です。

# Define a message to test the agent
message = """
I have 4 requests:
1. What is the time right now?
2. Calculate 3111696 / 74088
3. Tell me how many letter R's are in the word "strawberry"
4. Output a script that does what we just spoke about!
   Use your python tools to confirm that the script works before outputting it

呼び出すツール名を指定しなくても、適宜必要なツールが呼び出されます。これは指定しているanthropic.claude-3-5-sonnet-20240620-v1:0 により判断されています。

ツール名と docstring

各ツールの動作概要はdocstring変数に格納されます。例えば上記カスタムツールであれば以下にがセットされます。

"""
Count occurrences of a specific letter in a word.

Args:
    word (str): The input word to search in
    letter (str): The specific letter to count

Returns:
    int: The number of occurrences of the letter in the word
"""

ビルトインのcalculatorであれば以下のコマンドで確認できます。

python
Python 3.12.3 (main, Aug 14 2025, 17:47:21) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from strands_tools import calculator
>>> calculator.__doc__

Calculator tool powered by SymPy for comprehensive mathematical operations.

This module provides a powerful mathematical calculation engine built on SymPy
that can handle everything from basic arithmetic to advanced calculus,
equation solving, and matrix operations. It's designed to provide formatted,
precise results with proper error handling and robust type conversion.

Key Features:
1. Expression Evaluation:
   • Basic arithmetic operations (addition, multiplication, etc.)
   • Trigonometric functions (sin, cos, tan, etc.)
   • Logarithmic operations and special constants (e, pi)
   • Complex number handling with proper formatting

2. Specialized Mathematical Operations:
   • Equation solving (single equations and systems)
   • Differentiation (single and higher-order derivatives)
   • Integration (indefinite integrals)
   • Limit calculation (at specified points or infinity)
   • Series expansions (Taylor and Laurent series)
   • Matrix operations (determinants, multiplication, etc.)

3. Display and Formatting:
   • Configurable precision for numeric results
   • Scientific notation support for large/small numbers
   • Symbolic results when appropriate
   • Rich formatted output with tables and panels

Usage with Strands Agent:
```python
from strands import Agent
from strands_tools import calculator

agent = Agent(tools=[calculator])

# Basic arithmetic evaluation
agent.tool.calculator(expression="2 * sin(pi/4) + log(e**2)")

# Equation solving
agent.tool.calculator(expression="x**2 + 2*x + 1", mode="solve")

# Calculate derivative
agent.tool.calculator(
    expression="sin(x)",
    mode="derive",
    wrt="x",
    order=2
)

# Calculate integral
agent.tool.calculator(
    expression="x**2 + 2*x",
    mode="integrate",
    wrt="x"
)

この文字列とツールが処理する内容がずれている場合、LLMモデルは間違ったツールを呼び出す可能性があるため、丁寧に内容を記載しておく必要があります。

Written by
編集部

亀田 治伸

Kameda Harunobu

  • Facebook->
  • X->
  • GitHub->

Share

Facebook->X->
Back
to list
<-