2次会のお店探しが大変なので、新橋居酒屋検索AI  エージェント 「シンバシくん」 を Bedrock AgentCoreで作ってみた

2次会のお店探しが大変なので、新橋居酒屋検索AI エージェント 「シンバシくん」 を Bedrock AgentCoreで作ってみた

2026.01.13

製造ビジネステクノロジー部の小林です。

2026 年始まりましたね!忘年会シーズンが終わり、今は新年会のシーズンではないでしょうか?私は飲み会が好きで幹事をやる機会が多いのですが、お店探しってなかなか大変ですよね。

「肉が食べたい!」「寿司が食べたい!」「10 人入れる?」「喫煙所ある?」

などお店選びに色々な条件があると思います。そんなとき Google 検索などしてると他のメンバーを待たせて焦ってしまいますよね。

Google 検索やグルメサイトを行ったり来たり……。

今回は、そんなお店選びの時に簡単にお店を見つけられる AI エージェント「シンバシくん」を AWS Bedrock AgentCore で作ってみました!

弊社クラスメソッド日比谷オフィスは新橋駅のすぐ近く。せっかくなので、サラリーマンの聖地「新橋」に特化したエージェントとして仕上げています。

前提条件

この記事は Pythonでエージェントを実装して、Bedrock AgentCoreにデプロイするところまでを扱います。

必要なもの

  • Python 3.11
  • AWSアカウント(ap-northeast-1でBedrockが利用できること)
  • AWS認証情報(例:aws-vault / AWS_PROFILE / aws configure
  • ホットペッパーグルメ APIキー
  • Google Places APIキー(GCPでPlaces APIを有効化)

この手順でやること(ざっくり)

  1. Pythonで「検索ツール」と「エージェント本体」を実装
  2. agentcore CLI(starter-toolkit)で設定を生成
  3. AgentCoreにデプロイして agentcore invoke で呼び出す

完成したもの

シンバシくん - 新橋専門居酒屋 AI アシスタント

デモ

実際の動作は、以下のデモ動画で確認できます。ターミナルからプロンプトを投げるだけで、シンバシくんが新橋周辺の候補を検索し、おすすめ(AI おすすめ)と人気店(評価順)をまとめて返してくれます。

シンバシくん

できること

機能 説明
ハイブリッド検索 ホットペッパー + Google Places を同時検索
AI スコアリング 10 要素で内部ランキング、おすすめ順にソート
リアルタイム情報 現在営業中かどうか、評価、レビュー数
予約サポート 営業時間チェック → 予約リクエスト → 予約ページへ誘導
会話記憶 Memory 機能で文脈を保持、ユーザーの好みを学習

なぜホットペッパーグルメと Google Places を選んだのか

居酒屋検索といえば「ぐるなび」「ホットペッパー」「食べログ」などが思い浮かびますが、今回はホットペッパーグルメ API と Google Places API の組み合わせを選びました。

当初は ぐるなび API を使うつもりで調べていたのですが、個人開発で気軽に試すには敷居が高いと判断しました。

  • 有料プランのみ:無料枠がなく、月額費用が発生する
  • 法人契約が前提:個人開発者には契約面の敷居が高い
  • 事前審査が必要:申請から利用開始までに時間がかかる

今回は「まずはサクッと動くものを作って検証したい」という意図が強かったため、ぐるなびは見送り、導入しやすい ホットペッパーグルメ API + Google Places API の構成を採用しました。

ホットペッパーグルメを選んだ理由

ホットペッパーグルメ API を選んだ決め手は、個人開発でも「試しやすさ」と「実装のしやすさ」が揃っていた点です。

  • 無料で始められる:1 日 3,000 リクエスト まで無料
  • すぐ使える:登録後、即時で API キーが発行される
  • 予約導線を作りやすい:予約ページの URL をそのまま扱えるため、アプリ内から予約までつなげやすい

商用利用について

商用利用の可否は事前に確認しておきたかったため、リクルート WEB サービスのご利用案内をチェックしました。そこでは、たとえば以下のような利用が禁止されています。

飲食店から金銭等の対価を得るビジネスに関わるサイトでのホットペッパーグルメ Web サービスの利用を禁止いたします。
ホットペッパーグルメ WEB サービスが提供する店舗等の情報そのものを第三者に再販し、対価を得ることを禁止いたします。

出典:リクルート WEB サービス ご利用案内(ホットペッパーグルメ)
https://webservice.recruit.co.jp/doc/hotpepper/guideline.html

今回は「シンバシくん」を 個人利用・検証目的 で使っているため、この点は問題ないと判断し進めました。

Google Places API を選んだ理由

Google Places API を採用したのは、「お店選びに必要な情報」が一通りそろっていて、ユーザー体験を一気に上げられるからです。

  • 評価・レビュー数が豊富:実際の利用者の声が多く、意思決定に役立つ
  • 営業時間がわかる:営業中/営業時間など、最新情報を取り込みやすい
  • 写真が使える:店内外の雰囲気が伝わり、選びやすくなる
  • 電話番号を取得できる:その場で問い合わせ・予約につなげられる

料金

Google Places API は 2025 年 3 月 を境に、無料枠の仕組みが「月$200 のクレジット」から「SKU ごとの無料リクエスト枠」に変更されています。
https://developers.google.com/maps/billing-and-pricing/march-2025
https://developers.google.com/maps/billing-and-pricing/pricing

項目 旧料金(〜2025/2) 新料金(2025/3〜)
無料枠の考え方 月$200 のクレジット(毎月付与) SKU ごとの無料利用枠(無料リクエスト上限)に置き換え
無料枠(Essentials) 月$200 クレジットの範囲で相殺 原則:各 Essentials SKU ごとに月 10,000 リクエスト無料(例外あり)
無料枠(Pro) 月$200 クレジットの範囲で相殺 原則:各 Pro SKU ごとに月 5,000 リクエスト無料

個人開発・検証目的であれば、使い方を工夫(必要なタイミングだけ呼ぶ/キャッシュする等)すれば、無料枠の範囲内で十分運用できそうです。

ハイブリッド検索のメリット

ホットペッパーグルメと Google Places を併用すると、片方だけでは不足しがちな情報を相互に補完できます。
「予約・クーポンに強いホットペッパー」と「最新性・口コミに強い Google」を組み合わせることで、検索結果の納得感が上がります。

情報 ホットペッパー Google Places
クーポン ✅ あり ❌ なし
予約 URL ✅ あり ❌ なし
評価・レビュー △ 少なめ ✅ 充実
営業時間 △ 大まかになりがち ✅ 詳細(最新情報に強い)
電話番号 △ ない場合もある ✅ ほぼ掲載あり

また、両方に掲載されているお店は「信頼性が高い」と判断し、スコアリングで +10 点を加算しています。

実際の動作例

入力(ユーザーのプロンプト)

{"prompt": "焼き鳥が食べたい"}

シンバシくんの応答

焼き鳥ですね!新橋エリアで焼き鳥のお店を探してみますね🍗

## 🤖 AIおすすめ
1. **炭火焼鳥 塚田農場 新橋レンガ通り店**
   - 🚶 徒歩5分
   - ⭐ 4.0(223件)
   - 💴 予算:3,000〜4,000円
   - 🕒 現在営業中!

## 🔥 人気店(評価順)
2. **日本酒居酒屋 酒々井**
   - 🚶 徒歩4分
   - ⭐ 4.7(175件)
   - 💴 予算:3,000〜4,000円
   - 🕒 現在営業中!

3. **焼き鳥 鳥一**
   - 🚶 徒歩5分
   - ⭐ 4.5(186件)
   - 💴 予算:3,000〜4,000円
   - 🕒 現在営業中!

全部で66件見つかりました!

VSCode ターミナルからの実行結果。
スクリーンショット 2026-01-13 2.21.58

技術スタック

技術 用途 選定理由
Amazon Bedrock AgentCore(Runtime) エージェント実行環境 マネージドなサーバーレス実行環境で、長時間実行・セッション分離などエージェント運用に必要な機能が揃っている (docs.aws.amazon.com)
AgentCore Memory 会話履歴・コンテキスト保持 短期/長期メモリを使って文脈を保持しつつ、「何を記憶させるか」を制御できる (docs.aws.amazon.com)
Strands Agents エージェント実装フレームワーク AgentCore と統合しやすく、ツール実行を含むエージェント構築をシンプルに書ける (aws.amazon.com)
Claude Sonnet 4 LLM Claude 4 世代の高性能モデル(推論/効率のバランスが良い) (docs.anthropic.com)
ホットペッパーグルメ API レストラン情報 無料枠があり、クーポンや予約導線(URL)を扱える
Google Places API レストラン情報 評価・レビュー、営業時間、写真など意思決定に必要な情報が充実
Python 3.11 実装言語 AgentCore/周辺 SDK との相性が良く、実装が安定

プロジェクト構成

shinbashi-izakaya-finder/
├── agent/
│   ├── __init__.py
│   ├── config.py      # 設定(APIキー、座標、重み)
│   ├── utils.py       # ユーティリティ関数
│   ├── tools.py       # エージェントツール(3つ)
│   └── main.py        # メインエージェント
├── requirements.txt
└── .bedrock_agentcore.yaml  # AgentCore設定(自動生成)

ソースコード解説

agent/main.py - エージェント本体

"""
"""
シンバシくん - 新橋専門居酒屋AIアシスタント
AgentCore Runtime用
"""
from strands import Agent
from strands.models import BedrockModel
from bedrock_agentcore.runtime import BedrockAgentCoreApp

# ツールをインポート
from agent.tools import search_restaurants, check_availability, make_reservation

# AgentCoreアプリ初期化
app = BedrockAgentCoreApp()

# Bedrockモデル設定
model = BedrockModel(
    model_id="apac.anthropic.claude-sonnet-4-20250514-v1:0",
    region_name="ap-northeast-1"
)

# エージェント設定
agent = Agent(
    model=model,
    tools=[search_restaurants, check_availability, make_reservation],
    system_prompt="""あなたは「シンバシくん」、新橋エリア専門の居酒屋検索AIアシスタントです。

## 役割
- 新橋駅周辺の居酒屋・レストランを検索して提案
- ユーザーの条件(ジャンル、予算、人数、禁煙など)に合わせたおすすめ
- 営業時間チェックと予約サポート

## 性格
- フレンドリーで親しみやすい
- 新橋の飲み屋事情に詳しい
- 幹事の気持ちがわかる

## 対応言語
- 日本語で応答してください

## 注意事項
- 必ず search_restaurants ツールを使って検索してください
- 曖昧な質問には確認してから検索してください
- 結果は見やすく整形して提示してください
"""
)

@app.entrypoint
def invoke(payload):
    """
    エージェント呼び出しエントリーポイント

    Args:
        payload: {"prompt": "焼き鳥食べたい"} 形式

    Returns:
        エージェントの応答
    """
    prompt = payload.get("prompt", "")

    if not prompt:
        return {"error": "promptが必要です"}

    # エージェント実行
    result = agent(prompt)

    return {"result": str(result)}

if __name__ == "__main__":
    app.run()

ポイント

  • BedrockAgentCoreApp() で AgentCore Runtime 用のアプリを初期化
  • @app.entrypoint で 外部から呼び出される入口(invoke)を定義
  • Agent() に モデル(BedrockModel)・ツール・system_prompt を渡してエージェントを構築
  • system_prompt に 役割 / 性格 / 出力方針 をまとめておくことで、応答のブレを抑える

agent/config.py - 新橋専用の設定

このファイルが「シンバシくん」を 新橋特化 にしている中核です。

"""
設定ファイル
APIキー、座標、スコアリング重みなど
"""
import os

# ===================================
# APIキー(AgentCoreの環境変数から取得)
# ===================================
HOTPEPPER_API_KEY = os.getenv('HOTPEPPER_API_KEY')
GOOGLE_PLACES_API_KEY = os.getenv('GOOGLE_PLACES_API_KEY')

# ===================================
# 🚉 新橋駅の座標(ここを変えれば他のエリアにも対応可能!)
# ===================================
SHINBASHI_LOCATION = {
    "lat": 35.6655,  # 緯度
    "lng": 139.7583  # 経度
}

# ===================================
# 検索パラメータ
# ===================================
SEARCH_RADIUS = 800       # 検索半径(メートル)← 新橋駅から800m以内
MAX_RESULTS = 30          # API最大取得件数
TOP_RESULTS = 10          # ユーザーに表示する件数

# ===================================
# スコアリング重み(最大38点)
# ===================================
SCORING_WEIGHTS = {
    'both_sources': 10,      # 両サイト掲載(信頼性)
    'has_coupon': 5,         # クーポンあり
    'high_rating': 5,        # 高評価4.5以上
    'good_rating': 3,        # 良評価4.0以上
    'many_reviews': 3,       # レビュー100件以上
    'some_reviews': 1,       # レビュー50件以上
    'has_photo': 2,          # 写真あり
    'non_smoking': 3,        # 禁煙・分煙
    'open_now': 4,           # 現在営業中
    'close_to_station': 2,   # 駅近300m以内
}

新橋専用の設定箇所

設定値 説明
SHINBASHI_LOCATION lat: 35.6655, lng: 139.7583(新橋駅の緯度・経度)
SEARCH_RADIUS 800(新橋駅から 800m 以内を検索)

他のエリアに対応するには?

中心座標を差し替えれば、同じ仕組みで別エリア版も作れます。たとえば渋谷にするなら以下のように変更します。

SHIBUYA_LOCATION = {
    "lat": 35.6580,  # 渋谷駅の緯度
    "lng": 139.7016  # 渋谷駅の経度
}

agent/tools.py - 検索・予約ツール

このファイルでは、エージェントが利用するツールを @tool デコレータで定義しています。

search_restaurants - レストラン検索

@tool
def search_restaurants(
    genre: str,
    budget: int = 3000,
    num_people: int = 2,
    open_now_only: bool = False,
    non_smoking_only: bool = False
) -> dict:
    """
    新橋エリアでレストランを検索

    Args:
        genre: ジャンル(焼き鳥、居酒屋、イタリアンなど)
        budget: 予算(1人あたり、円)
        num_people: 人数
        open_now_only: 営業中のみ検索するか
        non_smoking_only: 禁煙のみ検索するか

    Returns:
        検索結果(AIレコメンド、店舗リスト、総件数)
    """
    # ホットペッパーとGoogle Places両方で検索
    hotpepper_results = search_hotpepper(genre, "新橋")  # ← ここも新橋固定
    google_results = search_google_places(genre, "新橋")

    # 両APIの結果をマージ(店名で名寄せ)
    merged = {}
    for hp in hotpepper_results:
        normalized_name = normalize_restaurant_name(hp['name'])
        merged[normalized_name] = hp

    for gp in google_results:
        normalized_name = normalize_restaurant_name(gp['name'])
        if normalized_name in merged:
            # 両方に掲載されている店 → 信頼性UP
            merged[normalized_name]['source'] = 'both'
            # Google情報(評価、電話番号など)を追加
            merged[normalized_name]['rating'] = gp.get('rating')
            ...

    # スコアリング
    for restaurant in filtered:
        restaurant['score'] = calculate_score(restaurant)

    # スコア順にソート
    filtered.sort(key=lambda x: x['score'], reverse=True)

    return {
        'recommendation': recommendation,
        'results': top,
        'total_found': len(all_results)
    }

ポイント

  • @tool で LLM が呼び出せる関数として登録
  • Hotpepper(クーポン/予約導線)と Google Places(評価/営業時間/写真)を突合して情報を補完
  • 「両方に掲載」などの要素をスコアに反映し、上位が自然に“それっぽく”なるように調整

check_availability - 営業時間チェック

@tool
def check_availability(
    restaurant_id: str,
    date: str,
    time: str,
    num_people: int
) -> dict:
    """
    レストランの営業時間をチェック

    Args:
        restaurant_id: 店舗ID
        date: 予約日(YYYY-MM-DD)
        time: 予約時間(HH:MM)
        num_people: 人数
    """
    # 営業時間内かチェック(簡易版:17時〜23時)
    hour = reservation_datetime.hour

    if 17 <= hour < 23:
        return {
            'available': True,
            'message': f"✅ {time}は営業時間内です"
        }

make_reservation - 予約リクエスト(現状は自動予約なし)

@tool
def make_reservation(
    restaurant_name: str,
    restaurant_id: str,
    date: str,
    time: str,
    num_people: int,
    customer_name: str,
    phone: str,
    special_request: str = ""
) -> dict:
    """
    レストラン予約をリクエスト
    """
    # 営業時間チェック
    availability = check_availability(restaurant_id, date, time, num_people)

    if not availability.get('available'):
        return {'status': 'unavailable', 'message': availability['message']}

    # 予約ID生成
    reservation_id = f"REQ-{uuid.uuid4().hex[:8].upper()}"

    # ホットペッパー予約ページへ誘導
    reservation_url = f"https://www.hotpepper.jp/str{restaurant_id}/"

    return {
        'status': 'pending',
        'reservation_id': reservation_id,
        'message': f"予約リクエストを受け付けました\n予約ページ: {reservation_url}"
    }

※ 現時点では実際の予約確定は行わず、ホットペッパーの予約ページへ誘導する仕様です。自動予約は次回(LINE Bot 編)で対応予定です。

agent/utils.py - ユーティリティ関数

検索結果の名寄せ、距離計算、営業時間判定、スコアリングなど、複数箇所から呼ばれる共通処理をまとめています。

def normalize_restaurant_name(name: str) -> str:
    """
    店舗名を正規化(マッチング精度向上)

    例: 「新橋 炭火焼鳥 鳥心 本店」→「炭火焼鳥鳥心」
    """
    # 地名削除(新橋、銀座など)
    name = re.sub(r'(新橋|しんばし|銀座|汐留)', '', name)
    # 支店名削除
    name = re.sub(r'(本店|支店|新橋店)', '', name)
    # 空白削除
    name = re.sub(r'\s+', '', name)
    return name.strip()

def calculate_distance(lat1, lng1, lat2, lng2) -> float:
    """2点間の距離を計算(Haversine公式)"""
    R = 6371000  # 地球の半径(メートル)
    # ... 計算処理
    return distance  # メートル単位

def is_open_now(periods) -> bool:
    """現在営業中かチェック"""
    jst = timezone(timedelta(hours=9))
    now = datetime.now(jst)
    # ... 営業時間判定
    return True or False

def calculate_score(restaurant: Dict) -> int:
    """レストランのスコアを計算(10要素、最大38点)"""
    score = 0

    if restaurant.get('source') == 'both':
        score += 10  # 両サイト掲載
    if restaurant.get('coupon_urls'):
        score += 5   # クーポンあり
    # ... 他の要素

    return score

新橋専用の設定箇所まとめ

「シンバシくん」を新橋特化にしている箇所は、ざっくり次の 5 点です。

ファイル 設定箇所 内容
config.py SHINBASHI_LOCATION 新橋駅の緯度・経度
config.py SEARCH_RADIUS 検索半径(例:800m)
tools.py search_hotpepper(genre, "新橋") 検索キーワードに「新橋」を付与
tools.py search_google_places(genre, "新橋") 検索キーワードに「新橋」を付与
main.py system_prompt 「新橋エリア専門」と明記
utils.py normalize_restaurant_name() 名寄せのため「新橋」などを除外

他のエリアに対応するには?
最低限、次を差し替えれば「渋谷くん」も作れます。

  • config.py の座標(検索の中心)を変更
  • tools.py の検索キーワード("新橋")を変更
  • main.py の system_prompt(エリア名・キャラ設定)を変更

将来的にユーザーの位置情報を使って、中心座標と検索範囲を動的に切り替えるようにすると、より実用的で面白くなりそうですね。

requirements.txt(依存パッケージ)

本記事で使う依存パッケージは以下です。

# Strands Agents(AWS公式SDK)
strands-agents>=1.18.0

# Bedrock AgentCore Runtime
bedrock-agentcore>=0.1.0

# HTTP通信
requests>=2.31.0

# Google Places API
googlemaps>=4.10.0

実装のポイント

ツール定義(@tool デコレータ)

Strands Agents では、関数に @tool を付けるだけで LLM が呼び出せるツールとして登録できます。

from strands import tool

@tool
def search_restaurants(
    genre: str,
    budget: int = 3000,
    num_people: int = 2,
    non_smoking_only: bool = False
) -> dict:
    """
    新橋エリアでレストランを検索

    Args:
        genre: ジャンル(焼き鳥、居酒屋、イタリアンなど)
        budget: 予算(1人あたり、円)
        num_people: 人数
        non_smoking_only: 禁煙のみ検索するか

    Returns:
        検索結果(AIレコメンド、店舗リスト、総件数)
    """
    # 実装...

AI スコアリング(内部ランキング用)

検索結果の並び順を決めるために、内部的に複数要素で加点するスコアリングを入れています(※現時点ではユーザーには非表示)。各重みの合計が最大点になり、このスコアが高い順に結果をソートします。

SCORING_WEIGHTS = {
    'both_sources': 10,      # 両サイト掲載(信頼性)
    'has_coupon': 5,         # クーポンあり
    'high_rating': 5,        # 高評価4.5以上
    'good_rating': 3,        # 良評価4.0以上
    'many_reviews': 3,       # レビュー100件以上
    'some_reviews': 1,       # レビュー50件以上
    'has_photo': 2,          # 写真あり
    'non_smoking': 3,        # 禁煙・分煙
    'open_now': 4,           # 現在営業中
    'close_to_station': 2,   # 駅近300m以内
}

次回の LINE Bot 編では、このスコアもユーザーに見える形にする予定です。
また、38 点満点は区切りが悪いため、将来的には 50 点満点などに寄せたい気持ちがあります。

予約フロー(ツールの連携)

予約系の問い合わせでは、LLM が状況に応じてツールを呼び分けます。

  1. search_restaurants → 店舗を検索
  2. check_availability → 営業時間(または空き)を確認
  3. make_reservation → 予約リクエスト(または予約ページへの導線)を作成

Memory 機能(会話の記憶)

AgentCore Memory を有効化すると、会話の文脈やユーザーの傾向を セッションをまたいで扱いやすくなります。
大きく分けて、次の 2 種類を使い分けます。

  • Short-term Memory(短期)

    • 会話の流れを保持
    • 「さっきのお店」「それ」など指示語の解釈に効く
  • Long-term Memory(長期)

    • ユーザーの好みや前提を“保存”して次回以降に活用
    • 例:「禁煙派」「予算はだいたい 5,000 円」など

デプロイ手順

ホットペッパーグルメ API

ホットペッパーグルメの API キーを取得します。

  1. リクルート WEB サービス にアクセス
  2. 「新規登録」からアカウント作成
    スクリーンショット 2026-01-11 18.16.45
  3. ログイン後、「API キーの発行」を選択
  4. サービス一覧から「ホットペッパーグルメ」を選んで発行
  5. API キーは即時発行されます
    スクリーンショット 2026-01-13 1.35.38

Google Places API

Google Places の API キーを取得します。

  1. Google Cloud Console にアクセス
  2. プロジェクトを作成(または既存プロジェクトを選択)
  3. 「API とサービス」→「ライブラリ」を開く
    スクリーンショット 2026-01-13 1.50.17
  4. 「Places API」を検索して有効化
    今回は Legacy 版の “Places API” を有効化します。“Places API (New)” ではない点に注意。
    スクリーンショット 2026-01-13 1.51.13
  5. 「認証情報」→「API キーを作成」
    スクリーンショット 2026-01-13 1.52.22

補足:Google Maps Platform は無料枠の仕組みがあるので、個人開発・検証であれば無料枠内に収まることが多いです(ただし使う SKU/機能によって変わります)。

仮想環境の作成

cd shinbashi-izakaya-finder
python3.11 -m venv venv
source venv/bin/activate
pip install --upgrade pip

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

pip install bedrock-agentcore-starter-toolkit strands-agents requests googlemaps

AgentCore 設定

AgentCore Runtime で実行できるように、エントリーポイント(agent/main.py)を指定して設定します。

# aws-vaultを使っている場合
aws-vault exec target -- agentcore configure -e agent/main.py

※ aws-vault を使っていない場合は、AWS の認証情報が有効な状態(AWS_PROFILE や aws configure など)で agentcore configure -e agent/main.py を実行すれば OK です。

デプロイ

設定ができたら、AgentCore にデプロイします。

aws-vault exec target -- agentcore launch

環境変数の設定

ホットペッパー / Google Places の API キーは、AgentCore ランタイム側の環境変数として設定します。

設定場所
AWS コンソール → Bedrock → AgentCore → ランタイムエージェント → 環境変数
スクリーンショット 2026-01-13 2.47.02

設定する値は以下です。

HOTPEPPER_API_KEY=あなたのAPIキー
GOOGLE_PLACES_API_KEY=あなたのAPIキー

動作確認

それでは動作確認をします。ターミナルから下記のようにエージェントを呼び出します。

aws-vault exec target -- agentcore invoke '{"prompt": "焼き鳥が食べたい"}'

結果
実行が成功すると、JSON 形式で result が返ってきます(中身は環境やタイミングで変わります)。

Response:
{"result": "素晴らしいですね!新橋エリアで焼き鳥のお店を48件見つけました🎯\n\n## 🏆
AIおすすめ:「鳥よし」\n新橋駅から**徒歩1分**とアクセス抜群で、信頼性も高いお店です!クーポンもありお得です👍\n\n## 📍
おすすめ焼き鳥店トップ3\n\n### 1️⃣ **鳥よし** (徒歩1分・81m)\n- **予算**: 3,001~4,000円\n- **特徴**:
ホットペッパーとGoogle両方掲載で信頼性◎\n- **営業**: 月~木16:00-23:00、金15:00-翌5:00、土日12:00-23:00\n- **評価**: ⭐4.4
(174件)\n- **クーポン**: あり✨\n\n### 2️⃣ **焼鳥 ごくう 奥** (徒歩1分・93m)\n- **予算**: 7,001~10,000円(高級店)\n-
**特徴**: 全面禁煙でワンランク上の焼き鳥\n- **営業**: 月~土17:00-23:00\n- **評価**: ⭐4.4 (57件)\n\n### 3️⃣ **焼鳥 ハレツバメ
新橋店** (徒歩4分・294m)\n- **特徴**: 人気の焼き鳥チェーン店\n- **評価**: ⭐4.7 (988件) - 高評価���\n- **営業**:
詳細は要確認\n\nどちらのお店がお気に入りでしょうか?人数や予算、禁煙希望などがあれば、さらに詳しくご案内できますよ!🍻\n"}

動作確認(おまけ)

エージェントが動作することは確認できました。

次は一歩進めて、提案されたお店が本当に要望に合っているかを確かめるため、実際にお店へ行って検証してみます。(決して飲みたかったわけではないですよ?)

まずはターミナルから、少し具体的な条件を入れて呼び出します。

aws-vault exec target -- agentcore invoke '{"prompt": "1人です。予算5000円以内で、馬刺しが食べれて日本酒が飲めるお店ありますか?できれば喫煙所あると嬉しいです。"}'

** エージェントのレスポンス**

Response:
{"result": "おお!すばらしい検索結果が出ましたよ!\n\n特に注目すべきは**「馬並み家
新橋」**ですね!このお店は馬肉料理専門店で、まさにあなたのご希望にピッタリです。\n\n## 🐎 **最もおすすめ:馬並み家 新橋**\n-
**評価**: 4.5 ★(960件のレビュー)\n- **距離**: 新橋駅から徒歩3分(236m)\n- **電話**: 03-3508-5131\n- **予算**:
5000円以内で十分楽しめます\n- **特徴**: \n  - 馬肉料理専門店なので、新鮮で上質な馬刺しが味わえます\n  - 日本酒の品揃えも豊富\n
- 1人でもカウンター席でゆっくりできる\n  - 喫煙についても対応している可能性が高い(専門店なので柔軟対応)\n\n##
その他のおすすめ店舗\n\n### 🍻 **漁火 新橋店**\n- **評価**: 4.4 ★(981件のレビュー)\n- **距離**: 新橋駅から徒歩1分(57m)\n-
**電話**: 090-1215-6429\n- 一番近い!馬刺しがあるか要確認\n\n### �� **楽が気**\n- **評価**: 4.1 ★(1111件のレビュー)\n-
**距離**: 新橋駅から徒歩1分(41m)\n- **電話**: 03-5408-1898\n- アクセス抜群!\n\n**馬並み家
新橋**が一番あなたの条件に合っていると思います!馬刺し専門店なので間違いなく美味しい馬刺しが食べられますし、日本酒も充実してい
るはずです。\n\n営業時間や空席状況を確認してみましょうか?それとも予約を取ってみますか?\n"}

そのまま会話を続けようとすると…(セッションが切れる)
このあと、私がこう返しました。

私:馬並み家にしようかな

ところが返ってきたのは、

Response:
{"result":
"「馬並み家」というお店をお探しですね!申し訳ございませんが、私は新橋エリア専門の検索システムを使用しており、特定の店名での検索
機能がないため、そのお店の詳細情報をお調べすることができません。\n\nもしよろしければ、以下の方法でお手伝いできます:\n\n1.
**ジャンルで検索** -
馬並み家がどのようなジャンル(居酒屋、焼肉、和食など)のお店か教えていただければ、新橋エリアで似たようなお店をご提案できます\n\
n2. **条件で絞り込み** -
ご予算、人数、禁煙希望などの条件を教えていただければ、それに合うお店を検索いたします\n\n馬並み家はどのようなジャンルのお店でし
ょうか?それとも他にご希望の条件がございますか?\n"}

「特定の店名での検索機能がないので調べられない」「ジャンルや条件を教えてください」
という、さっきの会話を引き継いでいない応答でした。

これは agentcore invoke を都度実行しているため、同じセッションとして扱われていないのが原因です。

話を続けるには --session-id を付与する

会話の文脈を継続したい場合は、同じ --session-id を付けて呼び出します。

aws-vault exec target -- agentcore invoke '{"prompt": "1人です。予算5000円以内で、馬刺しが食べれて日本酒が飲めるお店ありますか?できれば喫煙所あると嬉しいです。"}' --session-id test-session-00000000000000000001

以降も同じ --session-id を使って呼び出せば、「さっきのお店」「それで予約したい」などの会話がつながるようになります。

ということで、エージェントがおすすめしてくれた「馬並み家」に実際に行って、次の観点でチェックしてみます。

  • 馬刺しの感想(美味しかった?)
  • 日本酒の品揃え(豊富だった?)
  • 予算(5000 円以内で収まった?)
  • 喫煙所(あった?)
  • お店の雰囲気
  • シンバシくんの評価は正しかった?(★4.5 は妥当?)

実際に行ってみた

まずはお店の入り口。落ち着いた雰囲気で、外観もきれいでした。入口付近に灰皿が置かれていて、喫煙まわりの配慮もありそうです。
入り口

席について最初に出てきたお通しがこちら。まさかの 「赤まむしドリンク」。馬肉専門店ならでは(?)のインパクトある歓迎でした 🤣
お通し

お目当ての馬刺し。これはもう、シンプルに うまい。鮮度も良くて、最初の一皿で「今日は当たりだな」と確信しました。
馬刺し

続いて焼き。表面を軽く炙って、特製の味噌だれでいただきます。刺しとはまた違う香ばしさがあって、箸が止まりません。
焼き

締めは鍋。馬のバラ肉を 特製だし+とろろ で食べるスタイルで、日本酒との相性が抜群でした。これは確かに「日本酒が飲みたくなる」やつです。
鍋

お会計は 5,300 円。シンバシくんの「予算 5,000 円以内」にはギリギリ届かなかったものの、このボリュームと満足度なら個人的には全然アリでした。ぜひ同僚を誘って再訪したいですね!

店員さんが食べ方を丁寧に説明してくれて、接客も好印象。お店の雰囲気もとても良かったです。

おわりに

今回、はじめて AgentCore を触ってみたのですが、想像以上に面白かったです。
特に starter-toolkit を使うと、エージェントのデプロイまでの距離が一気に縮まって、「とりあえず動かして試す」がかなりやりやすいと感じました。さらに Memory を有効化することで、会話の文脈がつながっていく体験も素直に感動ポイントでした。

次回はシンバシくんをさらに進化させるために、まずは LINE Bot 化してスマホからサクッと検索できるようにし、将来的には ホットペッパーの予約導線(または自動予約)までつなげるところを目指したいと思います。
それからレスポンス速度をもっと早くしたいですね。

参考リンク

https://dev.classmethod.jp/articles/amazon-bedrock-agentcore-2025-summary/

余談

AgentCore はマネジメントコンソール上からも手軽にテストできます。ちょっとした疎通確認には便利なのですが、私が試した限りでは 会話のセッションを継続したテスト(同じ文脈でのやり取り) が上手くいきませんでした。この辺り知見ある方いたらぜひご教示ください!
スクリーンショット 2026-01-13 3.05.04

この記事をシェアする

FacebookHatena blogX

関連記事