A comprehensive travel planning agent demonstrating LLM-controlled memory tools with Redis Agent Memory Server.
This example showcases memory tools that the LLM can explicitly call:
- Memory Tools - SearchMemoryTool, CreateMemoryTool, UpdateMemoryTool, DeleteMemoryTool
- ADK Built-in - preload_memory, load_memory
- Web search with caching - Tavily search with Redis-backed result caching
- Calendar integration - Export itineraries to ICS format
- Multi-day trip planning - Structured itinerary generation
- Multi-user support - Memory isolation per user
Key Difference from travel_agent_memory_hybrid:
- This example uses
adk web .with only memory tools (no Redis services) travel_agent_memory_hybridusespython main.pywith BOTH services AND tools
cd examples/travel_agent_memory_tools
docker compose up -dWhat's running:
- Redis 8.4 on port 6379 (automatically started by Docker Compose)
- Agent Memory Server on port 8088 (using Gemini with
EXTRACTION_DEBOUNCE_SECONDS=5)
Note: Docker Compose automatically downloads and starts Redis 8.4. You don't need to start Redis manually for this example. Redis 8.4 includes the Redis Query Engine with native support for vector search, full-text search, and JSON operations.
Configuration: The docker-compose.yml is pre-configured with Gemini. To use a different provider, edit the environment variables in
docker-compose.yml:environment: - GEMINI_API_KEY=${GEMINI_API_KEY} # Change to your provider's API key - GENERATION_MODEL=gemini/gemini-2.0-flash # Change to your model - EMBEDDING_MODEL=gemini/text-embedding-004 # Change to your embedding model - FAST_MODEL=gemini/gemini-2.0-flash # Model for quick tasks - SLOW_MODEL=gemini/gemini-2.0-flash # Model for complex tasks - EXTRACTION_DEBOUNCE_SECONDS=5
If you prefer to run containers manually:
# 1. Start Redis 8.4
docker run -d --name redis -p 6379:6379 redis:8.4-alpine
# 2. Start Agent Memory Server
docker run -d --name agent-memory-server -p 8088:8088 \
-e REDIS_URL=redis://host.docker.internal:6379 \
-e GEMINI_API_KEY=your-gemini-api-key \
-e GENERATION_MODEL=gemini/gemini-2.0-flash \
-e EMBEDDING_MODEL=gemini/text-embedding-004 \
-e FAST_MODEL=gemini/gemini-2.0-flash \
-e SLOW_MODEL=gemini/gemini-2.0-flash \
-e EXTRACTION_DEBOUNCE_SECONDS=5 \
redislabs/agent-memory-server:0.13.2 \
agent-memory api --host 0.0.0.0 --port 8088 --task-backend=asyncioConfiguration Options:
- LLM Provider: Agent Memory Server uses LiteLLM and supports 100+ providers (OpenAI, Gemini, Anthropic, AWS Bedrock, Ollama, etc.). Set the appropriate environment variables for your provider (e.g.,
GEMINI_API_KEY,GENERATION_MODEL=gemini/gemini-2.0-flash). See the Agent Memory Server LLM Providers docs for details.- Memory Extraction Debounce:
EXTRACTION_DEBOUNCE_SECONDScontrols how long to wait before extracting memories from a conversation (default: 300 seconds). Lower values (e.g., 5) provide faster memory extraction, while higher values reduce API calls.- Embedding Models: Agent Memory Server also uses LiteLLM for embeddings. For local/offline embeddings, use Ollama (e.g.,
EMBEDDING_MODEL=ollama/nomic-embed-text,REDISVL_VECTOR_DIMENSIONS=768). Note: Theredis/langcache-embed-v1model used in the semantic_cache example is not supported by Agent Memory Server (it's RedisVL-specific). See Embedding Providers docs for all options.
cd examples/travel_agent_memory_tools
cp .env.example .env
# Edit .env and add your GOOGLE_API_KEY and TAVILY_API_KEYuv run python seed_data/seed_script.pyThis creates 3 demo users:
- tyler - Luxury traveler (business class, 5-star hotels, $5k-10k budget)
- nitin - Comfort traveler (premium economy, 3-4 star hotels, vegetarian, $2.5k-4k budget)
- vishal - Budget traveler (economy class, hostels, $800-1.5k budget)
Option 1: ADK Web Runner (Recommended)
# From the repository root
cd examples/travel_agent_memory_tools
uv run adk web .Or specify the directory directly:
# From anywhere
uv run adk web examples/travel_agent_memory_toolsThen open http://localhost:8000 in your browser.
Web UI Features:
- Chat interface with message history
- Events panel to inspect function calls
- Trace button for latency visualization
- Hot reload on code changes
Option 2: Programmatic Usage
from travel_agent import root_agent
from google.adk.runners import Runner
runner = Runner(agent=root_agent)
# Run a conversation
response = runner.run("Hi, I need help planning a trip to Tokyo")
print(response.text)This agent uses both explicit and automatic memory approaches:
Explicit Memory Tools (User-Controlled):
search_memory- Search for stored preferencescreate_memory- Store new preferencesupdate_memory- Modify existing preferencesdelete_memory- Remove preferences
Automatic Memory Callbacks (Framework-Controlled):
load_memory- Automatically loads relevant context before processingpreload_memory- Enriches responses with user historyafter_agentcallback - Extracts and stores memories after each turn
Why both?
- Explicit tools give users control ("remember this", "forget that")
- Automatic callbacks ensure nothing is missed
- Best of both worlds: transparency + seamlessness
- Tavily search integration for real-time travel information
- Results cached in Redis (1 hour TTL)
- Reduces API calls and improves response time
- Automatically disabled if
TAVILY_API_KEYnot set
plan_itinerary- Create structured multi-day trip plansexport_to_calendar- Generate ICS files for calendar import- Organized by day and time with emoji categories
- Compatible with Google Calendar, Outlook, Apple Calendar
- Memory isolated per user via
user_id - Demo users: tyler (luxury), nitin (comfort), vishal (budget)
- Persistent preferences across sessions
The agent will ask for your name/user_id on first interaction:
USER: "Hi, I need help planning a trip"
AGENT: "Hello! I'd be happy to help you plan your trip. To provide
personalized recommendations and remember your preferences for
future conversations, may I ask your name or a preferred identifier?"
USER: "I'm Sarah"
AGENT: "Great to meet you, Sarah! Let me search my memory to see if
we've talked before... I don't have any previous conversations
with you. How can I help you plan your trip today?"
If you seeded the demo users, you can use their profiles:
USER: "Hi, I'm Nitin"
AGENT: "Welcome back, Nitin! I remember you prefer premium economy flights,
3-4 star hotels, and vegetarian meals. How can I help you today?"
All preferences are stored in Agent Memory Server and persist across sessions:
# Session 1
USER: "I'm vegetarian"
AGENT: "I'll remember that you're vegetarian for future recommendations."
# Session 2 (days later)
USER: "Recommend restaurants in Bangkok"
AGENT: "Based on your vegetarian diet, I recommend..."
USER: "I'm vegetarian and prefer window seats"
AGENT: "I'll remember that! ✓ Stored your dietary preference (vegetarian)
✓ Stored your seating preference (window seats)"
USER: "What do you remember about me?"
AGENT: "Let me check... You're vegetarian and prefer window seats on flights."
USER: "Actually, forget the seating preference"
AGENT: "✓ Deleted your seating preference. I'll no longer remember that."
USER: "What are the best vegetarian restaurants in Bangkok?"
AGENT: [Uses web_search tool - first time]
"Searching the web for current recommendations...
Based on recent reviews, here are top vegetarian restaurants in Bangkok:
1. Broccoli Revolution - Modern plant-based cuisine
2. May Veggie Home - Traditional Thai vegetarian
3. Veganerie Concept - Vegan comfort food
[Result cached for 1 hour]"
USER: "What about vegetarian restaurants in Bangkok?" [Asked 10 minutes later]
AGENT: [Uses cached result - instant response]
"From my recent search: Broccoli Revolution, May Veggie Home,
and Veganerie Concept are highly rated..."
USER: "Plan a 3-day trip to Paris"
AGENT: [Uses plan_itinerary tool]
"Here's your 3-day Paris itinerary:
Day 1: Arrival & Eiffel Tower
• 10:00 AM - Eiffel Tower visit
• 1:00 PM - Lunch at Le Jules Verne (vegetarian options available)
• 3:00 PM - Seine River cruise
Day 2: Museums & Culture
• 9:00 AM - Louvre Museum
• 12:30 PM - Lunch at Wild & The Moon (plant-based)
• 3:00 PM - Musée d'Orsay
Day 3: Montmartre & Departure
• 10:00 AM - Sacré-Cœur Basilica
• 12:00 PM - Lunch at Hank Vegan Burger
• 2:00 PM - Shopping at Le Marais
Would you like me to export this to your calendar?"
USER: "Yes, export it to my calendar"
AGENT: [Uses export_to_calendar tool]
"✓ Calendar export created with 9 events!
Here's the ICS content (copy and save as .ics file):
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//ADK-Redis Travel Agent//EN
BEGIN:VEVENT
SUMMARY:Eiffel Tower visit
DTSTART:20260215T100000
DTEND:20260215T120000
LOCATION:Eiffel Tower, Paris
...
END:VEVENT
...
END:VCALENDAR
To import:
• Google Calendar: Settings → Import & Export → Import
• Outlook: File → Open & Export → Import/Export
• Apple Calendar: File → Import"
# User: nitin (vegetarian, premium economy, $2.5k-4k budget)
USER: "Hi, I'm Nitin"
AGENT: "Welcome back, Nitin! I remember you prefer premium economy flights,
3-4 star hotels, and vegetarian meals. How can I help you today?"
# User: tyler (luxury, business class, $5k-10k budget)
USER: "Hi, I'm tyler"
AGENT: "Welcome back, Tyler! I remember you prefer business class flights,
5-star hotels with spa facilities. Planning another luxury trip?"
# User: arsene (budget, economy, $800-1.5k budget)
USER: "Hi, I'm Vishal"
AGENT: "Hey Vishal! I know you're into budget travel, hostels, and backpacking.
What adventure are you planning next?"
# Automatic memory (via callbacks)
USER: "I'm planning a trip to Tokyo in March"
AGENT: "Tokyo in March is beautiful with cherry blossoms! What would you like to know?"
[after_agent callback automatically stores: trip to Tokyo, March timing]
# Later session - automatic recall
USER: "What was I planning?"
AGENT: [preload_memory callback loads context]
"You were planning a trip to Tokyo in March. Have you made any decisions?"
# Explicit memory management
USER: "Remember I need wheelchair accessible hotels"
AGENT: [Uses create_memory tool explicitly]
"✓ Stored: Requires wheelchair accessible accommodations.
I'll keep this in mind for all future hotel recommendations."
User Message
↓
[preload_memory] ← Loads relevant memories from Agent Memory Server
↓
[Agent Processing] ← Uses explicit memory tools if needed
↓
Agent Response
↓
[after_agent callback] ← Extracts and stores new memories
Memory Tools (8 total):
search_memory- Search stored preferencescreate_memory- Store new informationupdate_memory- Modify existing memoriesdelete_memory- Remove memoriespreload_memory- Auto-load context (framework)load_memory- Load specific memories (framework)export_to_calendar- Generate ICS filesplan_itinerary- Create structured trip plans
Optional:
9. web_search - Tavily search (if TAVILY_API_KEY set)
examples/travel_agent_memory_tools/
├── README.md # This file (comprehensive guide)
│
├── travel_agent/ # Main agent package
│ ├── __init__.py # Exports root_agent
│ └── agent.py # Agent definition with all tools
│
├── tools/ # Custom tools
│ ├── __init__.py
│ ├── tavily_search.py # Web search with Redis caching
│ ├── calendar_export.py # ICS calendar generation
│ └── itinerary_planner.py # Multi-day trip planning
│
├── seed_data/ # Demo user profiles
│ ├── users.json # Tyler, Nitin, Vishal profiles
│ └── seed_script.py # Script to populate Agent Memory Server
│
├── docker-compose.yml # Redis + Agent Memory Server
├── .env.example # Environment template
└── .env # Your local environment (gitignored)
Via Web UI:
- Start
uv run adk web . - Navigate to "Evaluate" tab
- Select test file and run
Via CLI:
uv run adk eval evaluation/travel_agent_eval.test.jsonVia pytest:
uv run pytest evaluation/travel_agent_eval.test.json -vThe evaluation framework includes test cases for:
- Memory management (create, search, update, delete)
- Trip planning with itinerary generation
- Calendar export functionality
If you run the seed script, you get 3 pre-configured users:
| User | Style | Preferences | Budget |
|---|---|---|---|
| tyler | Luxury | Business class, 5-star hotels, spa | $5k-10k |
| nitin | Comfort | Premium economy, 3-4 star, vegetarian | $2.5k-4k |
| vishal | Budget | Economy, hostels, backpacking | $800-1.5k |
Try: "Hi, I'm Nitin" to see personalized responses based on stored preferences.
Error: Connection refused to http://localhost:8088
Solution: Start the services using Docker Compose:
cd examples/travel_agent_memory_tools
docker compose up -dOr manually:
# Start Redis
docker run -d --name redis -p 6379:6379 redis:8.4-alpine
# Start Agent Memory Server
docker run -d --name agent-memory-server -p 8088:8088 \
-e REDIS_URL=redis://host.docker.internal:6379 \
-e OPENAI_API_KEY=your-openai-key \
redislabs/agent-memory-server:0.13.2 \
agent-memory api --host 0.0.0.0 --port 8088 --task-backend=asyncioNote: Agent Memory Server supports multiple LLM providers via LiteLLM. See the note in the Quick Start section above for configuration details.
ℹ️ Web search disabled (TAVILY_API_KEY not set)
Solution: Add TAVILY_API_KEY to your .env file. The agent will still work with memory only.
ModuleNotFoundError: No module named 'adk_redis'
Solution: Use uv run to run commands:
uv run python your_script.py
# or
uv run adk web .Solution: Make sure Agent Memory Server is running on port 8088. The seed script was recently updated to use the correct API endpoint (/v1/long-term-memory/).
- Tool-based memory - LLM-controlled memory operations via Agent Memory Server API
- Explicit + automatic - Memory tools +
after_agent_callbackfor extraction - Redis caching - Web search results cached for performance
- Multi-user isolation - Each user has separate memory namespace
- Tool composition - Memory + search + calendar + planning
- Standard ADK CLI - Uses
adk web .without custom services
- ADK-Redis Documentation - Main project documentation
- Redis Agent Memory Server - Memory server documentation
- Google ADK - ADK framework documentation
Copyright 2025 Google LLC and Redis, Inc.
Licensed under the Apache License, Version 2.0. See LICENSE for details.