mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add Azure Managed Redis Support with Credential Provider (#2887)
* azure redis support * small fixes * azure managed redis sample * fixes
This commit is contained in:
committed by
GitHub
Unverified
parent
ff9343d7cc
commit
37b4cfd024
@@ -8,8 +8,11 @@ This folder contains an example demonstrating how to use the Redis context provi
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [`azure_redis_conversation.py`](azure_redis_conversation.py) | Demonstrates conversation persistence with RedisChatMessageStore and Azure Redis with Azure AD (Entra ID) authentication using credential provider. |
|
||||
| [`redis_basics.py`](redis_basics.py) | Shows standalone provider usage and agent integration. Demonstrates writing messages to Redis, retrieving context via full‑text or hybrid vector search, and persisting preferences across threads. Also includes a simple tool example whose outputs are remembered. |
|
||||
| [`redis_threads.py`](redis_threads.py) | Demonstrates thread scoping. Includes: (1) global thread scope with a fixed `thread_id` shared across operations; (2) per‑operation thread scope where `scope_to_per_operation_thread_id=True` binds memory to a single thread for the provider’s lifetime; and (3) multiple agents with isolated memory via different `agent_id` values. |
|
||||
| [`redis_conversation.py`](redis_conversation.py) | Simple example showing conversation persistence with RedisChatMessageStore using traditional connection string authentication. |
|
||||
| [`redis_threads.py`](redis_threads.py) | Demonstrates thread scoping. Includes: (1) global thread scope with a fixed `thread_id` shared across operations; (2) per‑operation thread scope where `scope_to_per_operation_thread_id=True` binds memory to a single thread for the provider's lifetime; and (3) multiple agents with isolated memory via different `agent_id` values. |
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
"""Azure Managed Redis Chat Message Store with Azure AD Authentication
|
||||
|
||||
This example demonstrates how to use Azure Managed Redis with Azure AD authentication
|
||||
to persist conversational details using RedisChatMessageStore.
|
||||
|
||||
Requirements:
|
||||
- Azure Managed Redis instance with Azure AD authentication enabled
|
||||
- Azure credentials configured (az login or managed identity)
|
||||
- agent-framework-redis: pip install agent-framework-redis
|
||||
- azure-identity: pip install azure-identity
|
||||
|
||||
Environment Variables:
|
||||
- AZURE_REDIS_HOST: Your Azure Managed Redis host (e.g., myredis.redis.cache.windows.net)
|
||||
- OPENAI_API_KEY: Your OpenAI API key
|
||||
- OPENAI_CHAT_MODEL_ID: OpenAI model (e.g., gpt-4o-mini)
|
||||
- AZURE_USER_OBJECT_ID: Your Azure AD User Object ID for authentication
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from agent_framework.redis import RedisChatMessageStore
|
||||
from azure.identity.aio import AzureCliCredential
|
||||
from redis.credentials import CredentialProvider
|
||||
|
||||
|
||||
class AzureCredentialProvider(CredentialProvider):
|
||||
"""Credential provider for Azure AD authentication with Redis Enterprise."""
|
||||
|
||||
def __init__(self, azure_credential: AzureCliCredential, user_object_id: str):
|
||||
self.azure_credential = azure_credential
|
||||
self.user_object_id = user_object_id
|
||||
|
||||
async def get_credentials_async(self) -> tuple[str] | tuple[str, str]:
|
||||
"""Get Azure AD token for Redis authentication.
|
||||
|
||||
Returns (username, token) where username is the Azure user's Object ID.
|
||||
"""
|
||||
token = await self.azure_credential.get_token("https://redis.azure.com/.default")
|
||||
return (self.user_object_id, token.token)
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
redis_host = os.environ.get("AZURE_REDIS_HOST")
|
||||
if not redis_host:
|
||||
print("ERROR: Set AZURE_REDIS_HOST environment variable")
|
||||
return
|
||||
|
||||
# For Azure Redis with Entra ID, username must be your Object ID
|
||||
user_object_id = os.environ.get("AZURE_USER_OBJECT_ID")
|
||||
if not user_object_id:
|
||||
print("ERROR: Set AZURE_USER_OBJECT_ID environment variable")
|
||||
print("Get your Object ID from the Azure Portal")
|
||||
return
|
||||
|
||||
# Create Azure CLI credential provider (uses 'az login' credentials)
|
||||
azure_credential = AzureCliCredential()
|
||||
credential_provider = AzureCredentialProvider(azure_credential, user_object_id)
|
||||
|
||||
thread_id = "azure_test_thread"
|
||||
|
||||
# Factory for creating Azure Redis chat message store
|
||||
chat_message_store_factory = lambda: RedisChatMessageStore(
|
||||
credential_provider=credential_provider,
|
||||
host=redis_host,
|
||||
port=10000,
|
||||
ssl=True,
|
||||
thread_id=thread_id,
|
||||
key_prefix="chat_messages",
|
||||
max_messages=100,
|
||||
)
|
||||
|
||||
# Create chat client
|
||||
client = OpenAIChatClient()
|
||||
|
||||
# Create agent with Azure Redis store
|
||||
agent = client.create_agent(
|
||||
name="AzureRedisAssistant",
|
||||
instructions="You are a helpful assistant.",
|
||||
chat_message_store_factory=chat_message_store_factory,
|
||||
)
|
||||
|
||||
# Conversation
|
||||
query = "Remember that I enjoy gumbo"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
# Ask the agent to recall the stored preference; it should retrieve from memory
|
||||
query = "What do I enjoy?"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
query = "What did I say to you just now?"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
query = "Remember that I have a meeting at 3pm tomorrow"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
query = "Tulips are red"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
query = "What was the first thing I said to you this conversation?"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
# Cleanup
|
||||
await azure_credential.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -91,7 +91,7 @@ async def main() -> None:
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
query = "Remember that anyone who does not clean shrimp will be eaten by a shark"
|
||||
query = "Remember that I have a meeting at 3pm tomorro"
|
||||
result = await agent.run(query)
|
||||
print("User: ", query)
|
||||
print("Agent: ", result)
|
||||
|
||||
Reference in New Issue
Block a user