参考Blog:aws.amazon.com/blogs/aws/i…
AWS AgentCore是一系列服务的组合,包括:
AgentCore Runtime – 提供具有会话隔离功能的低延迟无服务器环境,支持任何代理框架(包括流行的开源框架、工具和模型),并处理多模式工作负载和长时间运行的代理。 AgentCore Memory - 管理会话和长期记忆,为模型提供相关上下文,同时帮助代理从过去的交互中学习。 AgentCore Observability — 通过元数据标记、自定义评分、轨迹检查和故障排除/调试过滤器提供代理执行的逐步可视化。 AgentCore Identity – 使 AI 代理能够代表用户或在预先授权的用户同意下自行安全地访问 AWS 服务以及第三方工具和服务,例如 GitHub、Salesforce 和 Slack。 AgentCore Gateway – 将现有 API 和 AWS Lambda 函数转换为代理就绪工具,提供跨协议(包括 MCP)和运行时发现的统一访问。 AgentCore Browser – 提供托管的 Web 浏览器实例来扩展代理的 Web 自动化工作流程。 AgentCore 代码解释器 - 提供一个隔离的环境来运行代理生成的代码。
Memory说明
Agentcore对于Memory提供两方面支持:
-
短期记忆
- 代理会将交互作为短期事件存储在 AgentCore Memory 中。之后,代理可以检索这些事件,以便无需你重复之前的信息即可进行对话。短期记忆可以捕获原始交互事件,维护即时上下文,支持实时对话,丰富长期记忆系统,并支持构建高级上下文解决方案,例如多步骤任务完成、会话中知识积累和上下文感知决策。
-
长期记忆
-
长期记忆存储从原始代理交互中提取的结构化信息,这些信息会在多个会话中保留。长期记忆不会保存所有原始对话数据,而是仅保留关键洞察,例如对话摘要、事实和知识(语义记忆)或用户偏好。例如,如果客户在聊天中告诉代理他们喜欢的鞋子品牌,AI 代理会将其存储为长期记忆。之后,即使在不同的对话中,代理也能记住并推荐该鞋子品牌,从而使互动更加个性化和更具相关性。
-
在 AgentCore Memory 中,你可以添加内存策略作为 CreateMemory 操作决定从原始对话中提取哪些信息。这些策略是一种配置,可以智能地从交互中捕获主要概念(在 CreateEvent 操作中以事件形式发送),并将其持久化。目前支持的策略包括:
- 摘要
- 语义记忆(事实和知识)
- 用户偏好
-
AgentCore Memory 支持两种方式将这些策略添加到内存中
- 内置策略(由 AgentCore 管理并在服务管理账户中运行)
- 自定义策略,允许您附加到系统提示并选择模型。这允许您根据特定领域或用例定制内存提取和整合。
-
Memory交互流程
Memory API的交互流程如下:
- 创建短期和长期记忆,并添加策略来创建长期记忆
- 开始会话:当Sarah 发起对话时,代理会创建一个新的、唯一的会话 ID 来单独跟踪此交互
- 捕获对话历史记录:当Sarah解释她的问题时,每条消息(她的问题和代理的回复)都使用 CreateEvent 操作保存为一个事件,确保按顺序记录完整的对话。
- 生成长期记忆:在后台,异步提取过程每隔几轮运行一次。此过程使用内置或自定义内存策略(您在通过 CreateMemory 操作设置 AgentCore Memory 时已配置)分析近期原始事件,以提取长期记忆,例如摘要、语义事实或用户偏好,然后将其存储以备将来使用。
- 从短期记忆中检索过去的互动:为了提供情境感知的帮助,agent调用ListEvents来加载对话历史记录。这有助于agent了解Sarah之前提出过哪些问题。
- 利用长期记忆提供个性化帮助:代理调用 RetrieveMemoryRecords,它会对提取的长期记忆进行语义搜索,以查找有关 Sarah 的偏好、订单历史记录或过往顾虑的相关洞察。这使得代理能够提供高度个性化的帮助,而无需要求 Sarah 重复她在之前的聊天中已经分享过的信息。
Short-term Memory示例代码
import os
import logging
from datetime import datetime
from strands import Agent, tool
from strands.hooks import AgentInitializedEvent, HookProvider, HookRegistry, MessageAddedEvent
from bedrock_agentcore.memory import MemoryClient
from botocore.exceptions import ClientError
region = os.getenv('AWS_REGION', 'us-east-1')
MODEL_ID = "us.anthropic.claude-sonnet-4-20250514-v1:0"
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
logger = logging.getLogger("agentcore-memory")
client = MemoryClient(region_name=region)
memory_name = "TravelAgent_STM_%s" % datetime.now().strftime("%Y%m%d%H%M%S")
memory_id = None
# Create shared memory
try:
print("Creating Memory...")
memory_name = memory_name
# Create the memory resource
memory = client.create_memory_and_wait(
name=memory_name, # Unique name for this memory store
description="Travel Agent STM", # Human-readable description
strategies=[], # No special memory strategies for short-term memory
event_expiry_days=7, # Memories expire after 7 days
max_wait=300, # Maximum time to wait for memory creation (5 minutes)
poll_interval=10 # Check status every 10 seconds
)
# Extract and print the memory ID
memory_id = memory['id']
print(f"Memory created successfully with ID: {memory_id}")
except ClientError as e:
if e.response['Error']['Code'] == 'ValidationException' and "already exists" in str(e):
# If memory already exists, retrieve its ID
memories = client.list_memories()
memory_id = next((m['id'] for m in memories if m['id'].startswith(memory_name)), None)
logger.info(f"Memory already exists. Using existing memory ID: {memory_id}")
except Exception as e:
# Handle any errors during memory creation
print(f"❌ ERROR: {e}")
import traceback
traceback.print_exc()
# Cleanup on error - delete the memory if it was partially created
if memory_id:
try:
client.delete_memory_and_wait(memory_id=memory_id)
logger.info(f"Cleaned up memory: {memory_id}")
except Exception as cleanup_error:
logger.info(f"Failed to clean up memory: {cleanup_error}")
# Create Memory Hook Provider
class ShortTermMemoryHook(HookProvider):
def __init__(self, memory_client: MemoryClient, memory_id: str, actor_id: str, session_id: str):
self.memory_client = memory_client
self.memory_id = memory_id
self.actor_id = actor_id
self.session_id = session_id
def on_agent_initialized(self, event: AgentInitializedEvent):
"""Load recent conversation history when agent starts"""
try:
# Get last 5 conversation turns
recent_turns = self.memory_client.get_last_k_turns(
memory_id=self.memory_id,
actor_id=self.actor_id,
session_id=self.session_id,
k=5,
branch_name="main"
)
if recent_turns:
# Format conversation history for context
context_messages = []
for turn in recent_turns:
for message in turn:
role = message['role'].lower()
content = message['content']['text']
context_messages.append(f"{role.title()}: {content}")
context = "\n".join(context_messages)
logger.info(f"Context from memory: {context}")
# Add context to agent's system prompt
event.agent.system_prompt += f"\n\nRecent conversation history:\n{context}\n\nContinue the conversation naturally based on this context."
logger.info(f"✅ Loaded {len(recent_turns)} recent conversation turns")
else:
logger.info("No previous conversation history found")
except Exception as e:
logger.error(f"Failed to load conversation history: {e}")
def on_message_added(self, event: MessageAddedEvent):
"""Store conversation turns in memory"""
messages = event.agent.messages
try:
self.memory_client.create_event(
memory_id=self.memory_id,
actor_id=self.actor_id,
session_id=self.session_id,
messages=[(messages[-1]["content"][0]["text"], messages[-1]["role"])]
)
except Exception as e:
logger.error(f"Failed to store message: {e}")
def register_hooks(self, registry: HookRegistry) -> None:
# Register memory hooks
registry.add_callback(MessageAddedEvent, self.on_message_added)
registry.add_callback(AgentInitializedEvent, self.on_agent_initialized)
# Create Multi-Agent Architecture with Strands Agents
# Create unique actor IDs for each specialized agent but share the session ID
flight_actor_id = f"flight-user-{datetime.now().strftime('%Y%m%d%H%M%S')}"
hotel_actor_id = f"hotel-user-{datetime.now().strftime('%Y%m%d%H%M%S')}"
session_id = f"travel-session-{datetime.now().strftime('%Y%m%d%H%M%S')}"
flight_namespace = f"travel/{flight_actor_id}/preferences"
hotel_namespace = f"travel/{hotel_actor_id}/preferences"
# Creating Specialized Agents with Memory Access
# System prompt for the hotel booking specialist
HOTEL_BOOKING_PROMPT = f"""You are a hotel booking assistant. Help customers find hotels, make reservations, and answer questions about accommodations and amenities.
Provide clear information about availability, pricing, and booking procedures in a friendly, helpful manner."""
# System prompt for the flight booking specialist
FLIGHT_BOOKING_PROMPT = f"""You are a flight booking assistant. Help customers find flights, make reservations, and answer questions about airlines, routes, and travel policies.
Provide clear information about flight availability, pricing, schedules, and booking procedures in a friendly, helpful manner."""
# Implementing Agent Tools
@tool
def flight_booking_assistant(query: str) -> str:
"""
Process and respond to flight booking queries.
Args:
query: A flight-related question about bookings, schedules, airlines, or travel policies
Returns:
Detailed flight information, booking options, or travel advice
"""
try:
flight_memory_hooks = ShortTermMemoryHook(
memory_id=memory_id,
memory_client=client,
actor_id=flight_actor_id,
session_id=session_id
)
flight_agent = Agent(hooks=[flight_memory_hooks],model=MODEL_ID, system_prompt=FLIGHT_BOOKING_PROMPT)
# Call the agent and return its response
response = flight_agent(query)
return str(response)
except Exception as e:
return f"Error in flight booking assistant: {str(e)}"
@tool
def hotel_booking_assistant(query: str) -> str:
"""
Process and respond to hotel booking queries.
Args:
query: A hotel-related question about accommodations, amenities, or reservations
Returns:
Detailed hotel information, booking options, or accommodation advice
"""
try:
hotel_memory_hooks = ShortTermMemoryHook(
memory_id=memory_id,
memory_client=client,
actor_id=hotel_actor_id,
session_id=session_id
)
hotel_booking_agent = Agent(hooks=[hotel_memory_hooks],model=MODEL_ID, system_prompt=HOTEL_BOOKING_PROMPT)
# Call the agent and return its response
response = hotel_booking_agent(query)
return str(response)
except Exception as e:
return f"Error in hotel booking assistant: {str(e)}"
# Creating the Coordinator Agent
# System prompt for the coordinator agent
TRAVEL_AGENT_SYSTEM_PROMPT = """
You are a comprehensive travel planning assistant that coordinates between specialized tools:
- For flight-related queries (bookings, schedules, airlines, routes) → Use the flight_booking_assistant tool
- For hotel-related queries (accommodations, amenities, reservations) → Use the hotel_booking_assistant tool
- For complete travel packages → Use both tools as needed to provide comprehensive information
- For general travel advice or simple travel questions → Answer directly
Each agent will have its own memory in case the user asks about historic data.
When handling complex travel requests, coordinate information from both tools to create a cohesive travel plan.
Provide clear organization when presenting information from multiple sources. \
Ask max two questions per turn. Keep the messages short, don't overwhelm the customer.
"""
travel_agent = Agent(
system_prompt=TRAVEL_AGENT_SYSTEM_PROMPT,
model=MODEL_ID,
tools=[flight_booking_assistant, hotel_booking_assistant]
)
response = travel_agent("Hello, I would like to book a trip from LA to Madrid. From July 1 to August 2.")
response = travel_agent("I would only like to focus on the flight at the moment. direct flimid-range, city center, pool, standard room")
代码说明:
-
使用AWS Bedrock的MemoryClient创建短期记忆存储,支持多智能体间的对话历史共享
-
内存钩子机制,智能体启动时加载历史对话,新消息时存储到内存
-
多智能体
- 航班预订agent (flight_booking_assistant)
- 酒店预订agent (hotel_booking_assistant)
- 协调器智能体 (travel_agent),作为主入口,智能路由用户请求
响应如下:
2025-08-12 17:38:22 - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2025-08-12 17:38:22 - INFO - Initialized MemoryClient for control plane: us-east-1, data plane: us-east-1
Creating Memory...
2025-08-12 17:38:23 - INFO - Created memory: TravelAgent_STM_20250812173822-meRL9V5L7s
2025-08-12 17:38:23 - INFO - Created memory TravelAgent_STM_20250812173822-meRL9V5L7s, waiting for ACTIVE status...
2025-08-12 17:38:24 - INFO - Memory TravelAgent_STM_20250812173822-meRL9V5L7s is now ACTIVE (took 0 seconds)
Memory created successfully with ID: TravelAgent_STM_20250812173822-meRL9V5L7s
2025-08-12 17:38:24 - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2025-08-12 17:38:24 - INFO - Creating Strands MetricsClient
I'd be happy to help you plan your trip from LA to Madrid from July 1 to August 2! Let me get you information on both flights and hotels for your month-long stay.
Tool #1: flight_booking_assistant
Tool #2: hotel_booking_assistant
2025-08-12 17:38:29 - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2025-08-12 17:38:29 - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2025-08-12 17:38:30 - INFO - Retrieved total of 0 events
2025-08-12 17:38:30 - INFO - No previous conversation history found
2025-08-12 17:38:30 - INFO - Retrieved total of 0 events
2025-08-12 17:38:30 - INFO - No previous conversation history found
2025-08-12 17:38:30 - INFO - Created event: 0000001754991510000#c41434c0
2025-08-12 17:38:31 - INFO - Created event: 0000001754991510000#486e0e32
I'd be happy to help you find flights from Los Angeles to Madrid! However, I should clarify that I'm a flight booking assistant that can provide guidance and information, but I don't have access to real-time flight data or booking systems.
Here's how I can help you find the best options for your July 1 - August 2 trip:
## **Recommended Airlines for LAX-MAD Route:**
- **Iberia** (direct flights available)
- **American Airlines** (direct flights, partner with Iberia)
- **Delta/Air France/KLM** (1-stop via European hubs)
- **Lufthansa** (1-stop via Frankfurt)
- **British Airways** (1-stop via London)
## **Typical Flight Options:**
- **Direct flights**: ~12 hours westbound, ~11 hours eastbound
- **One-stop flights**: 14-18 hours total travel time
## **To find current pricing and availability:**
1. **Check airline websites directly**
2. **Use comparison sites like:**
- Google Flights
- Kayak
- Expedia
- Momondo
3. **Consider booking tips:**
- Book 2-3 months ahead for better prices
- Tuesday/Wednesday departures often cheaper
- Compare round-trip vs. one-way tickets
Would you like me to provide2025-08-12 17:38:46 - INFO - Created event: 0000001754991526000#f937ffe4
more specific guidance on any particular airline, help you understand baggage policies, or assist with other aspects of your trip planning?I'd be happy to help you find hotel accommodations in Madrid for your extended 32-night stay from July 1 to August 2! However, I should clarify that I don't have access to real-time hotel inventory or booking systems, so I can't show you actual availability or current pricing.
**Here's how I can help you:**
## Recommended Approach for Your Extended Stay:
**1. Extended Stay Options to Consider:**
- **Apart-hotels/Serviced apartments** - Often better value for long stays
- **Hotel apartments** - Kitchen facilities for cost savings
- **Business hotels** - May offer monthly rates
- **Boutique hotels** - Some provide extended stay discounts
**2. Popular Areas in Madrid:**
- **Sol/Gran Vía** - City center, tourist attractions
- **Malasaña** - Trendy, nightlife, mid-range options
- **Salamanca** - Upscale, shopping district
- **Chueca** - Central, LGBTQ+ friendly area
- **La Latina** - Historic, authentic atmosphere
**3. What You Should Do:**
- Contact hotels directly for extended stay rates (often 20-30% off standard rates)
- Check booking platforms: Booking.com, Hotels.com, Expedia
- Consider Airbnb for monthly discounts
- Look into corporate rates if traveling for business
**Would you like me to provide:**
- Specific hotel chain recommendations?
- Tips for negotiating extended stay rates?
- Information about typical amenities in Madrid hotels?
- Guidance on the best neighborhoods for your needs?
What's most important to you for this2025-08-12 17:39:20 - INFO - Created event: 0000001754991559000#c143709f
stay - location, budget range, or specific amenities?Great! I've gathered information for both your flights and accommodation needs. Here's what I found:
## **Flight Options (LAX ↔ MAD)**
**Direct flights available with:**
- Iberia (about 12 hours to Madrid, 11 hours back)
- American Airlines (Iberia partner)
**One-stop options:**
- Delta/Air France/KLM, Lufthansa, British Airways (14-18 hours total)
## **Madrid Hotels for Your 32-Night Stay**
For such an extended stay, I'd recommend considering:
- **Apart-hotels/serviced apartments** with kitchens (cost-effective for long stays)
- **Business hotels** that offer monthly rates
- Direct hotel contact for extended stay discounts (often 20-30% off)
**Popular areas to consider:**
- **Sol/Gran Vía** - Central, near attractions
- **Malasaña** - Trendy area with great nightlife
- **Salamanca** - Upscale shopping district
**Next steps I'd recommend:**
1. Check Google Flights, Kayak, or airline websites for current flight prices
2. Contact Madrid hotels directly for extended stay rates
3. Consider Airbnb monthly discounts as an alternative
What's your priority - staying in the city center near attractions, or would you prefer a quieter neighborhood? And do you have a budget range in mind for both flights and accommodation?Perfect! Let me get you more specific information about direct flights from LA to Madrid for your July 1 - August 2 trip.
Tool #3: flight_booking_assistant
2025-08-12 17:40:30 - INFO - Found credentials in shared credentials file: ~/.aws/credentials
2025-08-12 17:40:30 - INFO - Retrieved total of 2 events
2025-08-12 17:40:30 - INFO - Context from memory: Assistant: I'd be happy to help you find flights from Los Angeles to Madrid! However, I should clarify that I'm a flight booking assistant that can provide guidance and information, but I don't have access to real-time flight data or booking systems.
Here's how I can help you find the best options for your July 1 - August 2 trip:
## **Recommended Airlines for LAX-MAD Route:**
- **Iberia** (direct flights available)
- **American Airlines** (direct flights, partner with Iberia)
- **Delta/Air France/KLM** (1-stop via European hubs)
- **Lufthansa** (1-stop via Frankfurt)
- **British Airways** (1-stop via London)
## **Typical Flight Options:**
- **Direct flights**: ~12 hours westbound, ~11 hours eastbound
- **One-stop flights**: 14-18 hours total travel time
## **To find current pricing and availability:**
1. **Check airline websites directly**
2. **Use comparison sites like:**
- Google Flights
- Kayak
- Expedia
- Momondo
3. **Consider booking tips:**
- Book 2-3 months ahead for better prices
- Tuesday/Wednesday departures often cheaper
- Compare round-trip vs. one-way tickets
Would you like me to provide more specific guidance on any particular airline, help you understand baggage policies, or assist with other aspects of your trip planning?
User: I need to book flights from Los Angeles to Madrid departing July 1 and returning August 2. Please show me available flight options, airlines, and pricing.
2025-08-12 17:40:30 - INFO - ✅ Loaded 2 recent conversation turns
2025-08-12 17:40:31 - INFO - Created event: 0000001754991630000#5cf8d7b5
Great choice focusing on direct flights! Both Iberia and American Airlines offer excellent nonstop service on the LAX-MAD route. Here's what you need to know:
## **Direct Flight Options:**
### **Iberia (IB)**
- **Flight IB6253**: Typically departs LAX around 2:35 PM, arrives MAD next day ~10:35 AM
- **Return flights**: Usually depart MAD in the afternoon (around 1:00-3:00 PM), arrive LAX same day
- **Aircraft**: Usually Airbus A350-900
- **Frequency**: Daily service
### **American Airlines (AA)**
- **Flight AA96**: Generally departs LAX around 3:40 PM, arrives MAD next day ~12:25 PM
- **Return flights**: Typically depart MAD early afternoon, arrive LAX same day
- **Aircraft**: Boeing 787-9 Dreamliner
- **Frequency**: Daily service
## **Key Advantages of These Direct Flights:**
- **Time savings**: No layovers or connections
- **Less jet lag**: Fewer disruptions to sleep schedule
- **Lower risk**: No missed connections or lost luggage between flights
## **Booking Tips for Direct Flights:**
- **Book 60-90 days ahead** for best prices on these popular routes
- **Compare both airlines** - sometimes AA has better AA/Oneworld member benefits
- **Iberia Plus vs. AAdvantage** - consider which loyalty program benefits you more
- **Seat selection**: Premium economy worth considering for 11+ hour flights
## **What to Expect:**
- **Pricing**: Direct flights typically $200-400 more than connecting flights
- **Check-in**: Online check-in opens 24 hours before departure
- **Arrival**: Both land at Madrid-Barajas Terminal 4
Woul2025-08-12 17:41:18 - INFO - Created event: 0000001754991678000#a82e728c
d you like me to explain the differences in cabin classes, baggage allowances, or help you understand the best booking strategy for your specific dates?Perfect! Here are your direct flight options from LAX to Madrid:
## **Direct Flight Options**
**Iberia (IB6253)**
- Departs LAX ~2:35 PM → Arrives MAD next day ~10:35 AM
- A350-900 aircraft, daily service
**American Airlines (AA96)**
- Departs LAX ~3:40 PM → Arrives MAD next day ~12:25 PM
- Boeing 787-9 Dreamliner, daily service
Both return flights typically depart Madrid in the afternoon and arrive LAX same day.
## **Key Benefits**
- **11-12 hour nonstop flights** (no connections!)
- Less jet lag and baggage risk
- Both land at Madrid Terminal 4
## **Booking Strategy**
- Book 60-90 days ahead for best prices
- Direct flights cost ~$200-400 more than connecting flights
- Compare both airlines as prices can vary
Would you like me to help you understand the cabin class options, or do you have questions about baggage allowances and check-in procedures for these flights?%
让我们分析下这里的memory机制是如何生效的:
-
Memory与Event的关系
- Memory整个会话期间只创建了一次,所有智能体共享这个容器
- 每次对话都创建新的event,每个event都有唯一id,存储在memory容器中
- event创建(每次对话)/检索(需要上下文时)
def on_message_added(self, event: MessageAddedEvent):
# 每次有新消息时触发
self.memory_client.create_event(
memory_id=self.memory_id, # 存储到哪个容器
actor_id=self.actor_id, # 谁的消息
session_id=self.session_id, # 哪次会话
messages=[(content, role)] # 消息内容
def on_agent_initialized(self, event: AgentInitializedEvent):
# 从容器中检索最近的events
recent_turns = self.memory_client.get_last_k_turns(
memory_id=self.memory_id, # 从哪个容器读取
actor_id=self.actor_id, # 读取谁的历史
session_id=self.session_id, # 哪次会话的历史
k=5 # 最近5轮对话
)
-
内存初始化阶段
- 成功创建了共享内存存储,ID为 TravelAgent_STM_20250812173822-meRL9V5L7s
- 内存状态变为ACTIVE,可以开始存储对话
2025-08-12 17:38:23 - INFO - Created memory: TravelAgent_STM_20250812173822-meRL9V5L7s
2025-08-12 17:38:24 - INFO - Memory TravelAgent_STM_20250812173822-meRL9V5L7s is now ACTIVE
-
首次对话 - 无历史记录
- 当用户首次询问"LA到Madrid旅行"时,两个专业智能体(航班和酒店助手)都检查内存,由于是首次对话,没有找到历史记录,智能体从零开始处理请求
2025-08-12 17:38:30 - INFO - Retrieved total of 0 events
2025-08-12 17:38:30 - INFO - No previous conversation history found
-
对话存储
- 航班助手和酒店助手的响应都被存储到内存中
- 每个事件都有唯一ID(如 c41434c0, 486e0e32)
2025-08-12 17:38:30 - INFO - Created event: 0000001754991510000#c41434c0
2025-08-12 17:38:31 - INFO - Created event: 0000001754991510000#486e0e32
-
Memory检索和上下文加载
-
当用户说"只关注航班"时,观察到:
- 检索到2个历史事件:之前航班助手的完整响应被加载
- 上下文注入:历史对话被添加到智能体的system prompt中
-
2025-08-12 17:40:30 - INFO - Retrieved total of 2 events
2025-08-12 17:40:30 - INFO - Context from memory: Assistant: I'd be happy to help you find flights...
2025-08-12 17:40:30 - INFO - ✅ Loaded 2 recent conversation turns