コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

献立エージェントの構築を通して学ぶ Strands Agents の使い方

こちらは「コドモン Advent Calendar 2025」の11日目の記事です。

こんにちは!コドモンでSREをしている江口です! 今回はずっと試してみたかったAWS製のAIエージェントフレームワーク「Strands Agents」を使って、ローカルに自分用の献立エージェントを作ってみました!

はじめに

この記事では、旬の食材を使った献立を考えるAIエージェントの作成を通じて、Strands Agentsの基本的な使い方を体験していきます。

私自身はPython初心者で、以前LangChainに挑戦して挫折した経験があります。 Strands Agentsはコードが簡潔で理解しやすいと聞いて、試してみることにしました。

この記事はStrands Agentsを試したことがない方を対象としています。 Strands Agentsの内部の仕組みや、本番環境へのデプロイ(Amazon Bedrock AgentCore Runtime)については扱いません。


Strands Agentsとは

AWSが開発したオープンソースのAIエージェントフレームワークです。 シンプルなコードでAIエージェントを構築できます。

構築を通して以下の特徴・機能を体験していきます。

  • シンプルなAPI:最小構成なら3行で動くエージェントが作れる
  • システムプロンプト:出力フォーマットを固定できる
  • ツール:LLMができないこと(日時取得など)を補える
  • MCP連携:外部サービスと連携できる

Strands Agentsの詳細は公式ドキュメントを参照してください。

strandsagents.com

github.com

エージェントを実装する

最小構成のエージェント

まずはじめに「今日の献立を1品考えてください」の入力に答えるシンプルなエージェントを作成します。

実装

事前準備として実装に必要なパッケージをインストールします。 本記事ではPython 3.12.11で動作を確認しています。 ※ Strands AgentsはPython 3.10以上が必要になります。

requirements.txt

strands-agents

パッケージをインストール

pip install -r requirements.txt

では本題のエージェントの実装です。

from strands import Agent
agent = Agent()
agent("今日の献立を1品考えてください")

とりあえず動かすなら、こんな感じで、たった3行で実装ができてしまいます。 実際に動かしてみましょう。

実行結果

実行結果を見る

❯ python -u simple_agent.py
**鮭とほうれん草のクリームパスタ**

【材料(2人分)】
- パスタ 200g
- 鮭の切り身 2切れ
- ほうれん草 1袋
- 玉ねぎ 1/2個
- 牛乳 200ml
- バター 大さじ2
- 小麦粉 大さじ1
- コンソメ 小さじ1
- 塩こしょう 適量

【作り方】
1. 鮭を一口大に切り、塩こしょうで下味をつける
2. ほうれん草は茹でて水気を切り、玉ねぎは薄切りにする
3. フライパンでバターを熱し、鮭と玉ねぎを炒める
4. 小麦粉を加えて炒め、牛乳を少しずつ加えてクリームソースを作る
5. 茹でたパスタとほうれん草を加えて絡める
6. コンソメ、塩こしょうで味を調えて完成

栄養バランスが良く、温かくて美味しい一品です!

きちんと献立が提案されましたね。たった3行でこれだけでしっかり回答が返ってくるのは嬉しいですね!

補足

たった3行で」と言ったものの、裏にはデフォルトの設定が隠れています。

  • モデル: Claude Sonnet 4 (リージョンは認証情報から自動検出)
  • 認証: 環境変数 → ~/.aws/credentials の順で自動検出

つまり、事前に export AWS_PROFILE=your-profile などで認証を設定しておいたから、3行で動かせたわけです。

先ほどの3行でやっていたことを省略せず、明示的に書くと以下のようになります。

import boto3  # 追加
from strands import Agent
from strands.models import BedrockModel  # 追加

# profileとリージョンを明示的に指定  # 追加
session = boto3.Session(
    profile_name='your-profile',
    region_name='ap-northeast-1'  # 指定しなければProfileの設定が使われる
)

# 使用するBedrockModelを明示的に指定  # 追加
bedrock_model = BedrockModel(
    model_id="apac.anthropic.claude-sonnet-4-20250514-v1:0",
    boto_session=session
)

agent = Agent(model=bedrock_model)  # 追加
agent("今日の献立を1品考えてください")

3行とはいかずとも、これでも十分シンプルですね。 以降はこれをベースにして肉付けしていきます。

システムプロンプトを使う

出力を決まったフォーマット(料理名、材料、調理工程、説明)で固定するため、「システムプロンプト」を設定します。

システムプロンプトとは

会話全体を通じて、モデルの振る舞いを指示するための指示文です。 ここに出力のフォーマットを指定する記述を追加することで、モデルの出力を安定させることができるようです。

System prompts provide high-level instructions to the model about its role, capabilities, and constraints. They set the foundation for how the model should behave throughout the conversation.

訳:システムプロンプトは、モデルの役割、機能、制約に関する高レベルな指示を提供します。会話全体を通じてモデルがどのように振る舞うべきかの基盤を設定します。

strandsagents.com

実装

system_prompt 変数にシステムプロンプトを定義し、Agentsystem_promptパラメータで渡すだけです。

import boto3
from strands import Agent
from strands.models import BedrockModel

# profileとリージョンを明示的に指定
session = boto3.Session(
    profile_name='your-profile',
    region_name='ap-northeast-1'
)

# 使用するBedrockModelを明示的に指定
bedrock_model = BedrockModel(
    model_id="apac.anthropic.claude-sonnet-4-20250514-v1:0",
    boto_session=session
)

# システムプロンプトで出力フォーマットを固定  # 追加
system_prompt = """あなたは料理の献立を考えるアシスタントです。
献立を提案する際は、必ず以下のフォーマットで回答してください。

## 料理名
[料理名をここに記載]

## 必要な材料
- [材料1]
- [材料2]
- ...

## 調理工程
1. [手順1]
2. [手順2]
3. ...

## 料理の説明
[この料理についての簡単な説明(2-3文程度)]
"""

agent = Agent(model=bedrock_model, system_prompt=system_prompt)  # 追加
agent("今日の献立を1品考えてください")

実行結果

1回目の実行結果を見る

❯ python -u using_system_prompt_agent.py
## 料理名
鶏肉と野菜の照り焼き炒め

## 必要な材料
- 鶏もも肉 250g
- ピーマン 2個
- 人参 1/2本
- 玉ねぎ 1/2個
- しょうゆ 大さじ2
- みりん 大さじ2
- 砂糖 大さじ1
- 酒 大さじ1
- サラダ油 大さじ1
- 塩・こしょう 少々

## 調理工程
1. 鶏もも肉を一口大に切り、塩・こしょうで下味をつける
2. ピーマンは細切り、人参は短冊切り、玉ねぎはくし切りにする
3. フライパンにサラダ油を熱し、鶏肉を焼き色がつくまで炒める
4. 野菜を加えて2-3分炒める
5. しょうゆ、みりん、砂糖、酒を混ぜ合わせたタレを加え、汁気が少なくなるまで炒める

## 料理の説明
甘辛い照り焼き味が食欲をそそる、鶏肉と野菜がバランス良く摂れる一品です。ご飯との相性も抜群で、忙しい日でも手軽に作れる栄養満点のおかずです。

2回目の実行結果を見る

❯ python -u using_system_prompt_agent.py
## 料理名
鶏肉とブロッコリーの中華炒め

## 必要な材料
- 鶏もも肉 200g
- ブロッコリー 1株
- にんじん 1/2本
- 長ネギ 1/2本
- にんにく 1片
- しょうが 1片
- サラダ油 大さじ2
- 醤油 大さじ2
- 酒 大さじ1
- オイスターソース 大さじ1
- 鶏がらスープの素 小さじ1
- 片栗粉 小さじ1(水大さじ1で溶く)

## 調理工程
1. 鶏肉を一口大に切り、ブロッコリーは小房に分けて下茹でする
2. にんじんは薄切り、長ネギは斜め切り、にんにく・しょうがはみじん切りにする
3. フライパンに油を熱し、にんにく・しょうがを炒めて香りを出す
4. 鶏肉を加えて色が変わるまで炒め、にんじん・長ネギを加える
5. ブロッコリーを加え、調味料を全て混ぜて加える
6. 水溶き片栗粉でとろみをつけて完成

## 料理の説明
彩り豊かで栄養バランスの良い中華風の炒め物です。鶏肉の旨味とオイスターソースのコクが野菜に絡んで、ご飯がすすむ一品になります。短時間で作れるので忙しい日の夕食にもおすすめです。

出力が指定したフォーマット通りになりましたね。エージェントの振る舞いが安定し、より使いやすくなりました。

ツールを使う

旬の食材を使った献立」を提案するため、現在の日時を取得する「ツール」を追加します。

ツールとは

ツールはLLMができないことをエージェントの力を借りて実現するための仕組みです。 例えば、現在の日時の取得、外部APIの呼び出し、ファイル操作などはLLM単体ではできません。

このLLMができないことをエージェント側で負担するためにツールが使用されます。

ツール使用の簡単な流れ

以下のような流れで、ツールは実行されます。

  1. エージェントがツールを準備し、インプットと共にLLMに教える
  2. LLMがインプットの内容と一緒に渡されたツール見て、「どれを使うか」を判断し、実行の方法をエージェントに返す
  3. エージェントがLLMからの返答を元にツールを実行、実行結果をLLMに渡す
  4. LLMがツールの実行結果を元に回答を生成

AWS 公式ブログ:Strands Agents – オープンソース AI エージェント SDK の紹介

つまり、「ツールの準備、実行」はエージェントが担い、「ツールの使い方、呼び出し方など推論が必要な作業」はLLMに任せるといった具合です。 この一連のやり取りは「Agent Loop」と呼ばれ、Strands Agentsの中心的なコンセプトになっているようです。

Agent Loopについてこれ以上深掘りしませんが、詳しく知りたい方は以下の公式ドキュメントを参照してください。 strandsagents.com

実装

今回はstrands-agents-toolsパッケージに含まれるcurrent_timeツールを使って、現在の日時を取得できるようにします。

まずはrequirements.txtにパッケージを追加します。

requirements.txt

strands-agents
strands-agents-tools
pip install -r requirements.txt

Strands Agentではtoolsパラメータでツールを渡すことができます。

import boto3
from strands import Agent
from strands.models import BedrockModel
from strands_tools import current_time  # 追加

# profileとリージョンを明示的に指定
session = boto3.Session(
    profile_name='your-profile',
    region_name='ap-northeast-1'
)

# 使用するBedrockModelを明示的に指定
bedrock_model = BedrockModel(
    model_id="apac.anthropic.claude-sonnet-4-20250514-v1:0",
    boto_session=session
)

# システムプロンプトで出力フォーマットを固定
system_prompt = """あなたは料理の献立を考えるアシスタントです。
...(省略)
"""

agent = Agent(model=bedrock_model, system_prompt=system_prompt, tools=[current_time])  # 追加
agent("季節の旬の食材を使った献立を1品考えてください")  # 追加

実行結果

実行結果を見る

❯ python -u using_tool_agent.py

現在の季節を確認して、旬の食材を使った献立を提案いたします。
Tool #1: current_time
今日は12月ということで、冬の旬の食材を使った献立を提案いたします。

## 料理名
大根と豚バラ肉の煮物

## 必要な材料
- 大根 1/2本(約600g)
- 豚バラ肉薄切り 300g
- 生姜 1片
- 醤油 大さじ3
- みりん 大さじ2
- 酒 大さじ2
- 砂糖 大さじ1
- だし汁 400ml
- サラダ油 小さじ1
- 青ねぎ(飾り用) 適量

## 調理工程
1. 大根は2cm厚の半月切りにし、面取りをして米のとぎ汁で下茹でする
2. 豚バラ肉は4cm幅に切り、生姜は千切りにする
3. 鍋にサラダ油を熱し、豚バラ肉を炒めて色が変わったら生姜を加える
4. 下茹でした大根を加え、だし汁、醤油、みりん、酒、砂糖を入れる
5. 落とし蓋をして中火で20-25分煮込む
6. 大根に竹串がすっと通るまで柔らかくなったら完成
7. 器に盛り、小口切りした青ねぎを散らす

執筆は11月下旬に行っています。この時期に旬の大根を使った献立が提案されましたね。

JAの公式サイトによると、大根の旬は11月から2月にかけてとのことなので、エージェントは正しく旬の食材を選んでくれたようです。

JAが出すダイコンの旬カレンダー

補足

プロンプトの調整

当初は冒頭の「季節の」という単語を入れずに「旬の食材を使った献立」とだけ指示していました。 これだと現在日時から「11月下旬が旬の食材」に限定してしまい、「レタスを使った料理」ばかりが提案されてしまいました。(なぜか「白菜と豚バラ肉の重ね蒸し」が頻出しました…笑)

旬の期間に幅を持たせるため「季節の旬の食材を使った」と指示を変えています。 こうした細かい調整でエージェントの出力をコントロールできるのも面白いところですね。

ツールの自作

今回はstrands-agents-toolsが提供するツールを使用しましたが、自作することも可能です。 @toolデコレータを使うことで、任意のPython関数をツールとして登録できます。

詳しくは公式ドキュメントを参照してください

https://strandsagents.com/latest/documentation/docs/user-guide/concepts/tools/python-tools/#python-tool-decoratorsstrandsagents.com

MCPサーバーからツールを使う

やや強引ですが、料理名を「AWSの公式ドキュメントの内容にインスピレーションを受けた命名」にしてもらうようエージェントに無茶振りしてみます。

Strands Agentsに連携したいMCPサーバーを教えることで、MCPから取得したツールを利用できるようになります。 今回はAWS Documentation MCPを使って、AWSの公式ドキュメントを検索・取得します。

strandsagents.com

実装

import boto3
from mcp import stdio_client, StdioServerParameters  # 追加
from strands import Agent
from strands.models import BedrockModel
from strands.tools.mcp import MCPClient  # 追加
from strands_tools import current_time

# profileとリージョンを明示的に指定
session = boto3.Session(
    profile_name='your-profile',
    region_name='ap-northeast-1'
)

# 使用するBedrockModelを明示的に指定
bedrock_model = BedrockModel(
    model_id="apac.anthropic.claude-sonnet-4-20250514-v1:0",
    boto_session=session
)

# システムプロンプトで出力フォーマットを固定
system_prompt = """あなたは料理の献立を考えるアシスタントです。
...(省略)
"""

# AWS Documentation MCPサーバーに接続  # 追加
aws_docs_mcp = MCPClient(lambda: stdio_client(
    StdioServerParameters(
        command="uvx",
        args=["awslabs.aws-documentation-mcp-server@latest"]
    )
))

# withブロックでMCP接続を管理(ブロック終了時に自動クローズ)  # 追加
with aws_docs_mcp:
    tools = aws_docs_mcp.list_tools_sync() + [current_time]
    agent = Agent(model=bedrock_model, system_prompt=system_prompt, tools=tools)
    agent("季節の旬の食材を使った献立を1品考えてください。料理名はAWSの公式ドキュメントの内容にインスピレーションを受けた命名にしてください。")

実行結果

実行結果を見る

❯ python -u using_mcp_agent.py

AWS Lambdaのレイヤー機能から「レイヤー」という概念をインスピレーションに受けて、冬の旬の食材を使ったレイヤー状の料理を考案します!

## 料理名
**Lambda Layered Winter Root Vegetable Stack**(ラムダ・レイヤード・ウィンター・ルート・ベジタブル・スタック)

## 必要な材料
- 大根: 1/3本(約300g)
- かぶ: 2個
- 白菜: 1/4玉
- 長ねぎ: 1本
- 生姜: 1片
- 豚バラ薄切り肉: 200g
- 昆布だし: 400ml
- 白味噌: 大さじ3
- 酒: 大さじ2
- みりん: 大さじ2
- 醤油: 大さじ1
- 柚子の皮: 少々

## 調理工程
1. 大根とかぶは皮をむき、1cm厚の輪切りにして下茹でしておく
2. 白菜は5cm幅に切り、長ねぎは斜め切り、生姜は千切りにする
3. 鍋の底から順に豚バラ肉→大根→かぶ→白菜の順にレイヤー状に重ねる
4. 昆布だしに白味噌、酒、みりん、醤油を混ぜた調味液を注ぐ
5. 蓋をして中火で20分間、各レイヤーが柔らかくなるまで煮込む
6. 最後に長ねぎと生姜を加えて5分煮て、柚子の皮を散らして完成

## 料理の説明
AWS Lambdaのレイヤー機能のように、異なる食材を層状に重ねて一つの機能的な料理に仕上げた冬の温かい煮物です。各層(レイヤー)の食材が互いの旨味を共有しながら、それぞれの特性を活かした、まさにサーバーレス料理のような効率的で美味しい一品です。

出力を見てみましょう

## 料理名
**Lambda Layered Winter Root Vegetable Stack**(ラムダ・レイヤード・ウィンター・ルート・ベジタブル・スタック)

Lambda レイヤーからインスピレーションを受け、 Lambda Layered Winter Root Vegetable Stack(ラムダ・レイヤード・ウィンター・ルート・ベジタブル・スタック) なる料理が提案されました。

...
3. 鍋の底から順に豚バラ肉→大根→かぶ→白菜の順にレイヤー状に重ねる
...

カタカナ多いですが、要はただのミルフィーユ鍋ですね…笑

...
AWS Lambdaのレイヤー機能のように、異なる食材を層状に重ねて一つの機能的な料理に仕上げた冬の温かい煮物です。各層(レイヤー)の食材が互いの旨味を共有しながら、それぞれの特性を活かした、まさにサーバーレス料理のような効率的で美味しい一品です。

「サーバーレス料理」の意味はよくわかりませんが、結構な無茶振りにもかかわらず、しっかりドキュメントを参照した上で料理名まで考えてくれました。

最後はちょっとネタに走りましたが、シンプルなAIエージェントから、システムプロンプト、ツール、MCP連携と段階的に機能を追加する方法を体験し、より便利なエージェントを作成することができました🎉

まとめ

AIエージェントの作成を通じて、Strands Agentsの基礎的な機能の使い方を体験することができました! コードが簡潔なので、LangChainに挫折したPython初心者の私でも理解しながら実装できたのは嬉しいポイントですね。 今後はこのエージェントをAmazon Bedrock AgentCore Runtimeにデプロイするところにも挑戦してみたいです!