A sample Travel Chat Agent built with Microsoft Agent Framework, Azure OpenAI, and Azure Managed Redis demonstrating intelligent conversation management with persistent memory and semantic preference retrieval.
This sample was fully "vibe coded" using GitHub Copilot Agent. All specifications and prompts available in the specs_and_prompts folder.
The agent implements a dual-memory system using Agent Framework:
agent = responses_client.create_agent(
name=agent_name,
description=f"{TRAVEL_AGENT_DESCRIPTION} for {user_name}",
instructions=TRAVEL_AGENT_INSTRUCTIONS,
tools=travel_tools,
chat_message_store_factory=chat_message_store_factory, # Short-term memory: conversation history
context_providers=redis_provider # Long-term memory: user preferences with semantic search
)chat_message_store_factory: Short-term memory storing conversation history in Redis for context continuity across sessionscontext_providers: Long-term memory using RedisProvider for semantic retrieval of user preferences with vector embeddings
- Intelligent Travel Agent: Single unified agent handling destination research, weather, flights, accommodations, and sports event booking
- Persistent Conversation History: All conversations stored in Azure Managed Redis and persist across sessions using Agent Framework's RedisChatMessageStore
- Automatic Context Injection: RedisProvider automatically injects relevant user preferences into each conversation using semantic search
- Semantic Preference Retrieval: Vector-based preference storage with semantic search capabilities powered by RediSearch
- Per-User Context: Each user has their own RedisProvider instance with preference storage
- DevUI Integration: Interactive testing interface with multi-user support
Choose your deployment method:
Deploy the entire application with all required Azure resources automatically provisioned:
Prerequisites:
- Azure Developer CLI (azd)
- Azure subscription with appropriate permissions
- Python 3.10 or higher
Steps:
- Clone the repository
git clone https://github.com/AzureManagedRedis/cool-vibes-travel-agent.git
cd cool-vibes-travel-agent- Login to Azure
azd auth login- Deploy everything with one command
azd upThis will automatically provision:
- Azure Managed Redis instance (with RediSearch module)
- Azure OpenAI service with required deployments (GPT-4o, text-embedding-3-small)
- Azure Container Apps for hosting the agent
- Application Insights for observability
- All necessary networking and security configurations
- Access your deployed application
After deployment completes, azd will output the application URL. Open it in your browser to interact with the travel agent.
Changing deployment settings:
# Change Azure region
azd env set AZURE_LOCATION eastus
# Set environment name
azd up -e production
# View all environment variables
azd env get-valuesRun the application locally with your own Azure resources:
Prerequisites:
- Python 3.10 or higher
- Azure Managed Redis instance (with RediSearch module enabled)
- Azure OpenAI deployment with:
- GPT-4o or GPT-4 model deployment
- text-embedding-3-small or text-embedding-ada-002 deployment
- Valid Azure credentials
Steps:
- Install Dependencies
pip install -r requirements.txt- Configure Environment
Copy .env.example to .env and fill in your credentials:
REDIS_URL=redis://:your_password@your-redis-instance.redis.cache.windows.net:6380?ssl=True
AZURE_OPENAI_ENDPOINT=https://your-openai-instance.openai.azure.com/
AZURE_OPENAI_API_KEY=your_api_key_here
AZURE_OPENAI_API_VERSION=preview
AZURE_OPENAI_DEPLOYMENT_NAME=gpt-4o
AZURE_OPENAI_EMBEDDING_DEPLOYMENT=text-embedding-3-small
AZURE_OPENAI_EMBEDDING_API_VERSION=2023-05-15
- Run the Application
python main.py- Access DevUI
Open your browser to http://localhost:8000 to interact with the agent.
cool-vibes-travel-agent.vNext
├── agents/
│ └── travel_agent.py # Travel agent definition and instructions
├── tools/
│ ├── user_tools.py # User preference tools (remember, search, reseed)
│ ├── user_tools_enhanced.py # Reference implementation with improvements
│ ├── travel_tools.py # Travel research tools
│ └── sports_tools.py # Sports event tools
├── data/
│ ├── sample_sport_events.py # Sports event sample data
│ └── sample_sport_venues.py # Venue seating sample data
├── specs_and_prompts/ # Specifications and prompts used to vibe code
│ ├── prompts to vibe code/
│ │ └── Prompts.md # Prompts for GitHub Copilot Agent
│ ├── specs/ # Feature specifications
│ │ ├── Agents_And_Tools.md
│ │ ├── Feature1-AgentsAndTools.md
│ │ ├── Feature2-SeedingPreferences.md
│ │ ├── Feature3-CachingConversations.md
│ │ ├── Feature4-DynamicPreferences.md
│ │ ├── RedisProvider.md # RedisProvider implementation spec
│ │ └── RedisProvider2.md # RedisProvider deep dive
│ └── Implementation_Plan_Context_Updates.md # Context update strategies
├── seed.json # User preferences seed data
├── seeding.py # RedisProvider context seeding
├── redis_provider.py # RedisProvider and vectorizer configuration
├── context_manager.py # Programmatic context management utility
├── conversation_storage.py # Redis conversation persistence
├── main.py # Application entry point
├── azure.yaml # Azure Developer CLI configuration
└── requirements.txt # Python dependencies
User: Hi, I'm Mark. Can you help me plan a trip?
Agent: [RedisProvider automatically injects Mark's preferences via semantic search]
Hello Mark! I'd be happy to help. I see you enjoy boutique hotels
and professional sports events...
Note: Preferences are automatically injected by RedisProvider - no explicit tool call needed!
User: I'm traveling to New York in November and want to catch a basketball game
Agent: I found several NBA games in November! The Knicks vs Lakers on
November 15th at Madison Square Garden. Based on your preferences
for boutique experiences, I recommend premium seating...
User: I also prefer aisle seats on flights. Please remember that.
Agent: [Calls remember_preference tool to write directly to RedisProvider's context store]
✅ I'll remember that Mark prefers aisle seats on flights
The preference is immediately stored with vector embedding in the Context namespace and will be automatically retrieved in future conversations.
User: What do you know about my hotel preferences?
Agent: [Uses get_semantic_preferences with query "hotels"]
Based on what I know, you enjoy boutique hotels with unique character
and prefer staying in walkable neighborhoods...
Travel-Agent (Unified)
- Destination research
- Weather information
- Flight and accommodation search (uses sample data)
- Sports event booking (uses sample data)
- General travel assistance
- Preference learning and retrieval
User Preference Tools:
remember_preference- Learn and store new preferences directly to RedisProvider's context store with embeddingsget_semantic_preferences- Perform targeted semantic search for specific preference topics
Note: General preferences are automatically injected by RedisProvider - no explicit tool call needed for basic retrieval!
Travel Tools:
research_weather- Get weather informationresearch_destination- Destination attractions and culturefind_flights- Flight options (uses sample data)find_accommodation- Hotel recommendations (uses sample data)booking_assistance- General booking support (uses sample data)
Sports Tools:
find_events- Search professional sports events (uses sample data)make_purchase- Book tickets (simulated)
All conversations are automatically persisted to Redis using Agent Framework's RedisChatMessageStore under the namespace cool-vibes-agent-vnext:Conversations:. Each conversation thread stores:
- All messages (user and assistant)
- Message timestamps
- Agent information
- Complete conversation context
Benefits:
- Conversations persist across application restarts
- Users can resume previous conversations
- Full conversation history available for analysis
- Thread isolation per user (
thread_id="{user_name}") - Automatic cleanup via
max_messagesconfiguration
User preferences are stored with vector embeddings in Redis under the namespace cool-vibes-agent-vnext:Context:{user_name}:{doc_id} using agent-framework-redis RedisProvider.
Storage structure (Redis Hash):
content: Text content of the preferenceembedding: 1536-dimensional vector (text-embedding-3-small, stored as bytes)role: "user" (indicates user-provided context)user_id: User identifier (e.g., "Mark", "Shruti")agent_id: Agent identifier (e.g., "agent_mark")application_id: "cool-vibes-travel-agent-vnext"timestamp: ISO format timestampsource: "seed" (initial data) or "learned" (from conversation)mime_type: "text/plain"
RedisProvider Capabilities:
- Automatic Context Injection: Relevant preferences are automatically retrieved and injected into each conversation
- Semantic Search: Uses RediSearch HNSW vector similarity with cosine distance metric
- Per-User Isolation: Each user has their own context namespace and RedisProvider instance
- Thread Awareness: Can scope context to specific conversation threads if needed
- Index Management: Automatically creates and manages RediSearch index
user_preferences_ctx_vnext
Three Ways to Update Context:
-
Automatic Extraction (Passive)
- Happens naturally during conversation
- Provider may extract preferences automatically
- No explicit code needed
-
Tool-Based Direct Write (Active - Primary Method)
- Use
remember_preferencetool to explicitly store preferences - Writes directly to Context namespace in RedisProvider format
- Immediate storage with vector embedding
- Example: "Please remember that I prefer luxury hotels"
- Use
-
Programmatic Update (System)
- Use
ContextManagerclass for bulk/system operations - Useful for migrations, batch imports, system-initiated updates
- See
context_manager.pyfor implementation
- Use
Example Flow:
User: "What hotels does Mark like?"
→ RedisProvider performs semantic search on Context:{Mark}:* keys
→ Finds: "Likes boutique hotels" (via vector similarity, even without exact match)
→ Automatically injects relevant preferences into conversation context
→ Agent responds with personalized recommendations
RediSearch Index:
- Index name:
user_preferences_ctx_vnext - Prefix:
cool-vibes-agent-vnext:Context: - Vector field:
embedding(HNSW algorithm, cosine distance, 1536 dimensions) - Filterable by:
user_id,agent_id,application_id
Verification:
# Check stored context
redis-cli KEYS "cool-vibes-agent-vnext:Context:*"
# View index info
redis-cli FT.INFO user_preferences_ctx_vnext
# Check conversations
redis-cli KEYS "cool-vibes-agent-vnext:Conversations:*"-
Connect to your Azure Managed Redis instance
-
Look for these key patterns:
cool-vibes-agent-vnext:Context:*- User context/preferences (RedisProvider)cool-vibes-agent-vnext:Conversations:*- Conversation history (RedisChatMessageStore)
-
Inspect user context:
HGETALL cool-vibes-agent-vnext:Context:Mark:abc123Each key is a hash with:
content: Preference textembedding: 1536-dimensional vector (binary bytes)user_id: User nameagent_id: Agent identifierapplication_id: App identifiertimestamp: When storedsource: "seed" or "learned"role: "user"mime_type: "text/plain"
-
Inspect conversation threads:
LRANGE cool-vibes-agent-vnext:Conversations:Mark 0 -1Each entry contains:
- Complete message history
- User and assistant messages
- Timestamps and metadata
- Thread isolation per user
-
Run RediSearch queries:
# View all indexed context FT.SEARCH user_preferences_ctx_vnext "*" # View index details FT.INFO user_preferences_ctx_vnext # Search by user FT.SEARCH user_preferences_ctx_vnext "@user_id:{Mark}" # Vector similarity search (manual) FT.SEARCH user_preferences_ctx_vnext "*=>[KNN 5 @embedding $vec]" \ PARAMS 2 vec <embedding_blob> DIALECT 2 -
Verify Context Seeding:
- After startup, check that Context keys exist for each user from seed.json
- Each user should have multiple context entries
- All entries should have valid embeddings
-
Test Dynamic Learning:
- Use DevUI to say "Please remember that I prefer window seats"
- Check that new Context key is created with
source=learned - Verify embedding exists and is correct dimension
- Sports event data and ticket purchases are simulated with sample data
- This is a demonstration application showcasing Agent Framework capabilities
- RediSearch module required for vector similarity search
- In production, tools would connect to real travel and event APIs
Redis Connection Error:
- Verify your REDIS_URL is correct
- Check firewall rules allow your IP
- Ensure SSL is enabled in connection string
- For Azure deployment: Resources are auto-configured by
azd up
Azure OpenAI Error:
- Verify endpoint and API key are correct
- Check your deployment name matches
- Ensure you have quota available
- For rate limits: Consider implementing retry logic or increasing quota
- In case Agent Framework shows API invalid, please make sure your env file states AZURE_OPENAI_API_VERSION=preview
Vector Search Not Working:
- Ensure RediSearch module is enabled in your Redis instance
- Check embedding deployment is configured correctly
- Verify
AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAMEenvironment variable - Azure Managed Redis Enterprise tier required for RediSearch
- Verify index exists:
redis-cli FT.INFO user_preferences_ctx_vnext - Check that Context keys have embeddings:
redis-cli HKEYS cool-vibes-agent-vnext:Context:Mark:*
Context Not Being Injected:
- Verify RedisProvider was created successfully (check logs)
- Ensure seed data was loaded properly on startup
- Check that Context keys exist in Redis
- Verify vectorizer is properly initialized
- Test with
get_semantic_preferencestool to verify search works
Import Errors:
- Run
pip install --upgrade -r requirements.txt - Ensure Python 3.10+ is being used
- Check virtual environment is activated
AZD Deployment Issues:
- Run
azd auth loginto ensure you're authenticated - Check you have permissions in the target subscription
- Verify the selected Azure region supports all required services
- Use
azd env get-valuesto inspect environment configuration
- Jan Kalis, specfications, prompts and vibe coding
- Jason Wang, AZD configuration
MIT License - Sample/Demo Application