AWSが開発するAIエージェントフレームワーク Strands Agents と、HuggingFaceが提供するお手軽なWeb UIライブラリ Gradio を組み合わせて、独自ツールを実行できるシンプルなAIチャットを作ってみます。
Strands Agentsとは
Strands Agents は、AIエージェントを構築するためのPython製フレームワークです。AWSによってオープンソースとして開発・公開されています。
Strandsの特徴
- コードファーストで軽量、シンプル
- 特定のAIプロバイダーに依存しない
- 可観測性 (Observability) 対応など、本番運用も考慮している
数行のコードで基本的なAIエージェントを作成でき、拡張もサクサクできます。シンプルながら必要な機能が一通り備わっており、他のフレームワークと比べても「ちょうどいい」感じがします。
また、AWSがバックにいるため安心感もあります🤗
エージェントの例
以下はエージェントのサンプルです。Ollama のローカルAIモデルに接続し、いくつかのツール(Python関数)を利用できるように設定しています。
from strands import Agent
from strands.models.ollama import OllamaModel
from strands_tools import current_time # Strandsに付属するツール
import tools as my_tools # 自作のツール
# AIモデルを定義
# Ollama (ローカルのAIサーバ) と接続し、gpt-ossモデルを使用する
model = OllamaModel(model_id="gpt-oss:20b", host="http://localhost:11434")
# モデルをエージェント化する。ツールとプロンプトを設定
agent = Agent(
model=model, tools=[current_time, my_tools],
system_prompt="あなたは有能なアシスタントです。"
)
このエージェントに指示を与えてみます。
# エージェントに指示
agent("いま何時?")
agent("tools/__init__.py内の関数を教えて")
すると、以下のような応答が返ってきます。使用したツール名とユーザーへのメッセージが出力されます。
「いま何時?」 の応答例:
Tool #1: current_time
現在は 2025‑09‑15 01:51:44 (UTC)です。
もし日本時間(JST)など別のタイムゾーンでの時刻が知りたい場合は、タイムゾーンを教えてくださいね。
ここでは current_time ツールを呼び出して、現在時刻を取得してから回答しています。
また、次の応答例では、複数のツールを組み合わせて必要な情報を集めています。
「tools/__init__.py内の関数を教えて」 の応答例:
Tool #2: list_files
Tool #3: read_file
`tools/__init__.py` に定義されている関数は以下の3つです。
- `get_timezone`
- `read_file`
- `list_files`
対象のファイルを探してから内容を読み込み、関数名を抽出して回答しているようです。
かしこい!
Gradioとは
Gradio(グレーディオ)は、簡易的なWeb UIを構築できるPythonフレームワークです。HuggingFace がオープンソースで開発しており、生成AIのデモなどで広く利用されています。
Pythonコードから直接UI部品を呼び出すだけで、そのままWeb UIを組み立てられる手軽さが特徴です。 Streamlit に似ていますが、Gradioの方がAIツールのプロトタイピングに向いている印象があります。特に2024年にリリースされたバージョン5ではパフォーマンスが大幅に改善され、UIも洗練されてかなり垢抜けました。
Gradioは豊富なUIコンポーネントが標準で用意されています。また、任意の処理をキュー化できるため、GPU依存の重いタスクも扱いやすいです。さらに、3Dモデルの表示にも対応しているため、AWSの 3D Gaussian Splat パイプライン でもUIとして使われています。
Pythonで簡易Web UIが欲しくなったら、とりあえずGradioを試すと間違いない🤗と思います。
StrandsとGradioの連携
概要
今回はStrands AgentsとGradioを組み合わせて、シンプルなAIチャットを実装します。
Gradioでチャット用のWeb UIを立ち上げ、AIエージェントの管理はStrands Agentsに任せます。手順は以下の通りです。
- エージェント用のツールを作成
- エージェントを作成 (Strands Agents)
- チャットUIを作成 (Gradio)
- チャットUIとエージェントを連携させる
- Gradioアプリとして起動する🚀
これだけで実現できます。
準備
まず、Pythonのパッケージ管理ツールからStrands AgentsとGradioをインストールします。
以下の例では pip を利用していますが、実用上は uv での管理をおすすめします。
pip install strands-agents gradio
実装
1. エージェント用のツールを作成
任意のPythonの関数にStrandsの @tool デコレータを付けると、エージェントが関数を利用できるようになります。エージェントは関数のコメント(docstring)を読み取り、処理内容を理解して必要に応じてツールを呼び出します。
以下はサイコロを転がすだけの、シンプルなツールの例です。
import random
from strands import tool
@tool
def roll_dice(num_dice: int) -> list[int]:
"""
サイコロを転がして出た目の数を返します。
Args:
num_dice (int): サイコロの数
Returns:
list[int]: それぞれのサイコロの出た目の値
"""
return [random.randint(1, 6) for _ in range(num_dice)]
ただの関数に @tool が付いているだけです。
2. エージェントを作成
次にエージェントを作成します。
以下の例ではClaudeを利用していますが、OpenAIやOllamaなど他のモデルも利用できます。関数定義にしているのは、あとでUIから設定を変更した際に、エージェントを再作成できるようにするためです。
from typing import Any
from strands import Agent
from strands.models.anthropic import AnthropicModel
from strands.session.file_session_manager import FileSessionManager
from strands_tools import calculator, current_time
def create_agent(system_prompt: str, session_id: str) -> tuple[Agent, list[dict]]:
"""エージェントを作成し、セッションIDに基づいてチャットの履歴を復元"""
# モデルの定義
# 今回はAnthoropicのAPIを利用 (APIキーが必要)
model = AnthropicModel(
model_id="claude-sonnet-4-0",
max_tokens=8192,
client_args={"api_key": os.environ["ANTHROPIC_API_KEY"]},
)
# ローカルファイルベースのセッション管理
# "./sessions" の下にセッションIDのフォルダが作られて、チャット履歴が記録される
session = FileSessionManager(session_id=session_id, storage_dir="./sessions")
# エージェントを作成
agent = Agent(
model=model,
session_manager=session,
tools=[calculator, current_time, roll_dice], # ツールを登録
system_prompt=system_prompt,
)
# チャットの履歴から本文だけを取り出し
# 元の履歴にはツール呼出しなどの情報も記録されており、GradioのチャットUIとは互換性がない
# ここでつじつま合わせをする
chat_history = []
for message in agent.messages:
# チャットの本文("text" コンテンツの中身)だけ取り出す
contents = message.get("content", [])
text_items = (x["text"] for x in contents if x.get("text"))
text = next(text_items, None)
if text:
chat_history.append({"role": message.get("role"), "content": text})
return agent, chat_history
戻り値として、エージェント本体とチャット履歴(Gradio用に整形したもの)を返しています。チャット履歴は FileSessionManager というセッション管理クラスを利用してローカルに自動保存させています。
3. チャットUIを作成
Gradioには gradio.ChatInterface というシンプルなチャットUIが用意されています。以下のようにメッセージ処理関数を指定するだけで、すぐにチャットができるようになります。
import gradio as gr
def handle_chat(message, history):
"""引数のユーザーメッセージに対して返答する"""
return "さすが鋭いですね!確かに '" + message + "' と思います!!"
chat = gr.ChatInterface(handle_chat, type="messages")
chat.launch()
今回はこのチャットUIをベースに、いくつか設定をカスタマイズできるように拡張します。開閉パネル gr.Accordion を設定パネルとしてチャットの上部に設置し、システムプロンプトやセッションIDを切り替え可能にします。
import gradio as gr
with gr.Blocks(fill_height=True) as demo:
# 設定パネル
with gr.Accordion("🛠️ 設定", open=False):
system_prompt = gr.Textbox(
value="あなたは有能なアシスタントです。",
label="システムプロンプト",
)
session_id = gr.Dropdown(
choices=get_available_session_names(), # セッション一覧を取得 (実装は省略)
value="default",
label="セッションID",
allow_custom_value=True,
)
# エージェント格納用の入れ物
agent_state = gr.State(None)
# メインのチャットUI
chat = gr.ChatInterface(
handle_chat, # ※後述
type="messages", additional_inputs=[agent_state]
)
# エージェントを作成
gr.on(
# 起動時、設定パネルの内容変更時に呼び出し
[chat.load, system_prompt.blur, session_id.blur],
create_agent,
inputs=[system_prompt, session_id],
outputs=[agent_state, chat.chatbot_value],
)
真ん中あたりにある agent_state 変数は、 gr.State を利用してエージェントの参照を保持します。また、最後の gr.on はイベントハンドラとしてUI操作とエージェント作成処理を紐づけています。
4. チャットUIとエージェントを連携させる
チャットUIのメッセージ処理関数 handle_chat() を実装します。
以下のように、引数のメッセージをStrandsのエージェントに渡し、応答をyield文でチャットUIに返します。
async def handle_chat(message, _history, agent: Agent):
"""引数のユーザーメッセージに対して返答する"""
chunks = []
async for event in agent.stream_async(message):
if "data" in event:
chunks.append(event["data"])
yield "".join(chunks)
引数の agent には、 ChatInterface の additional_inputs で指定したエージェントが渡されます。
5. Gradioアプリとして起動する🚀
最後にGradioアプリを起動します。
demo.launch()
これらのコードを my_chat_app.py として保存し、実行します。
$ python my_chat_app.py
* Running on local URL: http://127.0.0.1:7860
* To create a public link, set `share=True` in `launch()`.
ブラウザで http://localhost:7860/ にアクセスすると、チャットUIが表示され、AIと会話が可能になります。
まとめ
Strands AgentsとGradioを組み合わせることで、簡単にツール実行機能付きのAIチャットアプリを構築できました。
この実装をベースに、ツールを増やしたり、複数のAIモデルを切り替えたりと、さまざまなカスタマイズが可能です。Strandsのユーザガイドの目次には、MCPの利用やOpenTelemetry連携、マルチエージェント構成など、さらに発展的な機能も載っています。
今後のさらなる進化に期待です!!
おまけ: 他のエージェントフレームワークの印象
他のエージェントフレームワークもいくつか調べたので、軽く印象をまとめます:
- LangChain, Semantic Kernel: 複雑でとっつきづらい。過度な抽象化のにおいが😣
- LlamaIndex, Agno: 多機能すぎて迷う😵💫
- smolagents: シンプルすぎるよ!!
これらと比べると、Strandsは中庸でいいバランスなのかなと思います。 ただ、基本的にはどのフレームワークでも同じことが実現可能だと思います。つまりバイブス🤞で選んでオッケーってことですね。
おまけ: 全コード

