This scenario demonstrates powermem's UserMemory feature - automatic user profile extraction, management, and integration with memory search.
- Python 3.11+
- powermem installed (
pip install powermem) - LLM provider configured (for profile extraction)
- OceanBase configured as vector store (UserMemory requires OceanBase)
Important Note:
UserMemoryrequires OceanBase as the storage backend. If you attempt to useUserMemorywith a different storage provider, it will raise aValueError. Please configure OceanBase as your vector store provider.
UserMemory extends Memory with user profile capabilities:
- Automatic profile extraction: Extracts user-related information from conversations (name, profession, interests, preferences, etc.)
- Continuous profile updates: Updates and refines the profile based on new conversations
- Profile storage: Stores profiles separately from memories for efficient retrieval
- Joint search: Optionally includes profile information when searching memories
First, let's initialize UserMemory with proper configuration:
# user_profile_example.py
from powermem import UserMemory, auto_config
# Load configuration (auto-loads from .env or uses defaults)
config = auto_config()
# Create UserMemory instance
user_memory = UserMemory(config=config)
print("✓ UserMemory initialized successfully!")Run this code:
python user_profile_example.pyExpected output:
✓ UserMemory initialized successfully!
Add a conversation and automatically extract user profile information:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
# Add a conversation
conversation = [
{"role": "user", "content": "Hi, I'm Alice. I'm a 28-year-old software engineer from San Francisco. I work at a tech startup and love Python programming."},
{"role": "assistant", "content": "Nice to meet you, Alice! Python is a great language for software engineering."}
]
result = user_memory.add(
messages=conversation,
user_id="user_001",
agent_id="assistant_agent",
run_id="session_001"
)
print(f"✓ Conversation added successfully")
print(f" - Profile extracted: {result.get('profile_extracted', False)}")
if result.get('profile_content'):
print(f" - Profile content: {result['profile_content']}")
print(f" - Memory results count: {len(result.get('results', []))}")Run this code:
python user_profile_example.pyExpected output:
✓ Conversation added successfully
- Profile extracted: True
- Profile content: Name: Alice. Age: 28. Location: San Francisco. Profession: Software engineer at a tech startup. Interests: Python programming.
- Memory results count: 1
Add more conversations to update and refine the user profile:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
# First conversation
conversation1 = [
{"role": "user", "content": "Hi, I'm Alice. I'm a software engineer from San Francisco."},
{"role": "assistant", "content": "Nice to meet you, Alice!"}
]
result1 = user_memory.add(
messages=conversation1,
user_id="user_001",
agent_id="assistant_agent"
)
print("=== First conversation ===")
print(f"Profile extracted: {result1.get('profile_extracted', False)}")
if result1.get('profile_content'):
print(f"Profile: {result1['profile_content']}")
# Second conversation - adds more information
conversation2 = [
{"role": "user", "content": "I also enjoy reading science fiction novels and playing tennis on weekends."},
{"role": "assistant", "content": "That sounds like great hobbies!"}
]
result2 = user_memory.add(
messages=conversation2,
user_id="user_001",
agent_id="assistant_agent"
)
print("\n=== Second conversation ===")
print(f"Profile updated: {result2.get('profile_extracted', False)}")
if result2.get('profile_content'):
print(f"Updated profile: {result2['profile_content']}")Run this code:
python user_profile_example.pyExpected output:
=== First conversation ===
Profile extracted: True
Profile: Name: Alice. Profession: Software engineer. Location: San Francisco.
=== Second conversation ===
Profile updated: True
Updated profile: Name: Alice. Profession: Software engineer. Location: San Francisco. Hobbies: Reading science fiction novels, playing tennis.
Retrieve the user profile directly:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
# Add some conversations first
conversation = [
{"role": "user", "content": "I'm Bob, a data scientist. I love machine learning and hiking."},
{"role": "assistant", "content": "Great to meet you, Bob!"}
]
user_memory.add(
messages=conversation,
user_id="user_002",
agent_id="assistant_agent"
)
# Get the user profile
profile = user_memory.profile(
user_id="user_002"
)
if profile:
print("✓ Profile retrieved successfully")
print(f" - Profile ID: {profile.get('id')}")
print(f" - User ID: {profile.get('user_id')}")
if profile.get('profile_content'):
print(f" - Profile content: {profile.get('profile_content', '')}")
if profile.get('topics'):
print(f" - Topics: {profile.get('topics')}")
print(f" - Created at: {profile.get('created_at')}")
print(f" - Updated at: {profile.get('updated_at')}")
else:
print("✗ No profile found")Run this code:
python user_profile_example.pyExpected output:
✓ Profile retrieved successfully
- Profile ID: 1234567890123456789
- User ID: user_002
- Agent ID: assistant_agent
- Run ID:
- Profile content: Name: Bob. Profession: Data scientist. Interests: Machine learning, hiking.
- Created at: 2024-01-15T10:30:00
- Updated at: 2024-01-15T10:30:00
Search memories without including the profile:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
user_id = "user_003"
# Add some conversations
user_memory.add(
messages=[
{"role": "user", "content": "I'm Charlie, a product manager. I work on mobile apps."},
{"role": "assistant", "content": "Interesting!"}
],
user_id=user_id,
agent_id="assistant_agent"
)
user_memory.add(
messages=[
{"role": "user", "content": "I prefer agile development methodology."},
{"role": "assistant", "content": "That's a popular approach."}
],
user_id=user_id,
agent_id="assistant_agent"
)
# Search without profile
results = user_memory.search(
query="work and preferences",
user_id=user_id,
agent_id="assistant_agent",
limit=5,
add_profile=False # Don't include profile
)
print(f"✓ Search completed")
print(f" - Results count: {len(results.get('results', []))}")
print(f" - Profile included: {'profile_content' in results}")
for i, result in enumerate(results.get('results', []), 1):
print(f" {i}. {result.get('memory', '')} (score: {result.get('score', 0):.2f})")Run this code:
python user_profile_example.pyExpected output:
✓ Search completed
- Results count: 2
- Profile included: False
1. Works on mobile apps as a product manager (score: 0.85)
2. Prefers agile development methodology (score: 0.78)
UserMemory.search() can optionally rewrite the query using the user's profile to improve recall. This feature is optional and disabled by default. It only runs when query_rewrite.enabled=True and a user_id with profile_content is available. If the profile is missing, the query is too short, or the rewrite fails, it falls back to the original query.
Practical example (profile + ambiguous query):
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
user_id = "user_rewrite_demo"
# Build profile with relocation info
user_memory.add(
messages="Last month I moved from Chengdu to Hangzhou, and started a new job.",
user_id=user_id,
profile_type="content"
)
# Ambiguous query that relies on profile context
results = user_memory.search(
query="Recommend some delicious food near my place.",
user_id=user_id,
limit=5
)Contrast: rewrite enabled vs disabled
import os
# Enable query rewrite via env
os.environ["QUERY_REWRITE_ENABLED"] = "true"
user_memory_rewrite = UserMemory(config=auto_config())
# Disable query rewrite via env
os.environ["QUERY_REWRITE_ENABLED"] = "false"
user_memory_no_rewrite = UserMemory(config=auto_config())
# Same query, same user profile
query = "Recommend some delicious food near my place."
result_with_rewrite = user_memory_rewrite.search(
query=query,
user_id=user_id,
limit=5
)
result_without_rewrite = user_memory_no_rewrite.search(
query=query,
user_id=user_id,
limit=5
)Example config:
config = {
# ... other config
"query_rewrite": {
"enabled": True,
# "prompt": "Rewrite queries to be specific and grounded in the user profile."
}
}Environment variables are also supported (see .env.example):
QUERY_REWRITE_ENABLED=false
# QUERY_REWRITE_PROMPT=
# QUERY_REWRITE_MODEL_OVERRIDE=QUERY_REWRITE_PROMPTis optional custom instructions for rewrite.QUERY_REWRITE_MODEL_OVERRIDEis optional and must be another model from the same LLM provider family.
Search memories and include the user profile in results:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
user_id = "user_004"
# Add conversations
user_memory.add(
messages=[
{"role": "user", "content": "I'm Diana, a UX designer. I love creating beautiful interfaces."},
{"role": "assistant", "content": "That's wonderful!"}
],
user_id=user_id,
agent_id="assistant_agent"
)
# Search with profile
results = user_memory.search(
query="user background and interests",
user_id=user_id,
agent_id="assistant_agent",
limit=5,
add_profile=True # Include profile
)
print(f"✓ Search with profile completed")
print(f" - Results count: {len(results.get('results', []))}")
print(f" - Profile included: {'profile_content' in results}")
if 'profile_content' in results:
print(f"\n User Profile:")
print(f" {results['profile_content']}")
print(f"\n Search Results:")
for i, result in enumerate(results.get('results', []), 1):
print(f" {i}. {result.get('memory', '')} (score: {result.get('score', 0):.2f})")Run this code:
python user_profile_example.pyExpected output:
✓ Search with profile completed
- Results count: 1
- Profile included: True
User Profile:
Name: Diana. Profession: UX designer. Interests: Creating beautiful interfaces.
Search Results:
1. Works as a UX designer, loves creating beautiful interfaces (score: 0.92)
You can specify a native language for profile extraction, ensuring the profile is written in the user's preferred language regardless of the conversation language:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
# Example 1: English conversation, Chinese profile
conversation_en = [
{"role": "user", "content": "I am a software engineer working in Beijing. I love drinking tea and reading books."},
{"role": "assistant", "content": "That sounds great!"}
]
result_zh = user_memory.add(
messages=conversation_en,
user_id="user_bilingual_001",
native_language="zh" # Extract profile in Chinese
)
print("✓ English conversation processed")
if result_zh.get('profile_content'):
print(f" - Profile (Chinese): {result_zh['profile_content']}")
# Example 2: Chinese conversation, English profile
conversation_zh = [
{"role": "user", "content": "I'm 25 years old, working at Microsoft in Seattle."},
{"role": "assistant", "content": "Nice to meet you"}
]
result_en = user_memory.add(
messages=conversation_zh,
user_id="user_bilingual_002",
native_language="en" # Extract profile in English
)
print("\n✓ Chinese conversation processed")
if result_en.get('profile_content'):
print(f" - Profile (English): {result_en['profile_content']}")
# Example 3: Structured topics with native language
result_topics = user_memory.add(
messages="I'm 25 years old, working at Microsoft in Seattle.",
user_id="user_bilingual_003",
profile_type="topics",
native_language="zh" # Topic values in Chinese, keys remain English
)
print("\n✓ Structured topics extracted")
if result_topics.get('topics'):
print(f" - Topics: {result_topics['topics']}")Run this code:
python user_profile_example.pySupported Language Codes:
| Code | Language | Code | Language |
|---|---|---|---|
| zh | Chinese | en | English |
| ja | Japanese | ko | Korean |
| fr | French | de | German |
| es | Spanish | it | Italian |
| pt | Portuguese | ru | Russian |
| ar | Arabic | hi | Hindi |
| th | Thai | vi | Vietnamese |
Delete a user profile:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config, agent_id="assistant_agent")
user_id = "user_007"
# Add conversation and create profile
user_memory.add(
messages=[
{"role": "user", "content": "I'm Grace, a teacher."},
{"role": "assistant", "content": "Nice to meet you!"}
],
user_id=user_id
)
# Get profile to confirm it exists
profile = user_memory.profile(user_id=user_id)
if profile:
profile_id = profile.get('id')
print(f"✓ Profile exists with ID: {profile_id}")
# Delete the profile
deleted = user_memory.delete_profile(
user_id=user_id
)
if deleted:
print(f"✓ Profile deleted successfully")
else:
print(f"✗ Failed to delete profile")
# Verify deletion
profile_after = user_memory.profile(user_id=user_id)
if not profile_after:
print("✓ Profile confirmed deleted")
else:
print("✗ Profile still exists")Run this code:
python user_profile_example.pyExpected output:
✓ Profile exists with ID: 1234567890123456789
✓ Profile deleted successfully
✓ Profile confirmed deleted
Here's a complete example combining all the features:
# complete_user_profile_example.py
from powermem import UserMemory, auto_config
def main():
# Load configuration
config = auto_config()
# Initialize UserMemory
user_memory = UserMemory(config=config, agent_id="demo_agent")
user_id = "demo_user"
print("=" * 60)
print("UserMemory Profile Management Example")
print("=" * 60)
# Step 1: Add initial conversation
print("\n1. Adding initial conversation...")
conversation1 = [
{"role": "user", "content": "Hi, I'm Alex, a 32-year-old data scientist from New York. I specialize in machine learning and love reading tech blogs."},
{"role": "assistant", "content": "Nice to meet you, Alex! That's fascinating."}
]
result1 = user_memory.add(
messages=conversation1,
user_id=user_id,
run_id="session_001"
)
print(f" ✓ Profile extracted: {result1.get('profile_extracted', False)}")
if result1.get('profile_content'):
print(f" Profile: {result1['profile_content']}")
# Step 2: Update profile with more information
print("\n2. Updating profile with more conversations...")
conversation2 = [
{"role": "user", "content": "I also enjoy hiking and photography on weekends."},
{"role": "assistant", "content": "Those are great hobbies!"}
]
result2 = user_memory.add(
messages=conversation2,
user_id=user_id,
run_id="session_002"
)
print(f" ✓ Profile updated: {result2.get('profile_extracted', False)}")
# Step 3: Get full profile
print("\n3. Retrieving full profile...")
profile = user_memory.profile(
user_id=user_id
)
if profile:
print(f" ✓ Profile ID: {profile.get('id')}")
print(f" Profile content: {profile.get('profile_content', '')}")
print(f" Last updated: {profile.get('updated_at')}")
# Step 4: Search with profile
print("\n4. Searching memories with profile...")
search_results = user_memory.search(
query="user interests and hobbies",
user_id=user_id,
limit=5,
add_profile=True
)
if 'profile_content' in search_results:
print(f" User Profile: {search_results['profile_content']}")
print(f"\n Found {len(search_results.get('results', []))} memories:")
for i, result in enumerate(search_results.get('results', []), 1):
print(f" {i}. {result.get('memory', '')} (score: {result.get('score', 0):.2f})")
# Step 5: Cleanup (optional)
print("\n5. Cleaning up...")
# Note: In production, you might want to keep the profiles
# deleted = user_memory.delete_profile(user_id=user_id)
# if deleted:
# print(" ✓ Profile deleted")
print("\n" + "=" * 60)
print("Example completed successfully!")
print("=" * 60)
if __name__ == "__main__":
main()Run this code:
python complete_user_profile_example.py-
Always provide
user_id: Theadd()method requiresuser_id; ensure each user has a unique identifier -
Use
agent_idto distinguish agents: In multi-agent scenarios, useagent_idto separate profiles and memories across agents -
Use
run_idappropriately: Userun_idto distinguish sessions or runs for more precise profile management -
Check profiles regularly: Use
profile()to periodically check and ensure profile information remains accurate -
Include profile when needed: When additional context is useful, set
add_profile=Trueto include the user profile in search results -
Handle empty profiles: If
profile()returns{}, no profile has been extracted yet; calladd()with conversation data first -
Profile updates: Profiles are automatically updated when you add new conversations with the same
user_id,agent_id, andrun_idcombination -
Message filtering: By default, only
userrole messages are used for profile extraction (assistant messages are excluded). You can customize this withinclude_rolesandexclude_rolesparameters -
Query rewrite (optional): Enable
query_rewrite.enabled=Trueto letsearch()rewrite queries using profile content; it falls back to the original query when unavailable
By default, UserMemory.add() only extracts profile information from user messages. You can customize which message roles are used for profile extraction:
# user_profile_example.py
from powermem import UserMemory, auto_config
config = auto_config()
user_memory = UserMemory(config=config)
# Conversation with multiple roles
conversation = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hi, I'm Frank, a doctor from Boston."},
{"role": "assistant", "content": "Nice to meet you, Frank!"},
{"role": "tool", "content": "Weather data: Boston, 72°F"}
]
# Default behavior: only include 'user' messages, exclude 'assistant' messages
result = user_memory.add(
messages=conversation,
user_id="user_008"
)
print("Default filtering (user only):")
print(f" Profile: {result.get('profile_content', 'N/A')}")
# Include all messages (disable filtering)
result = user_memory.add(
messages=conversation,
user_id="user_009",
include_roles=None, # or []
exclude_roles=None # or []
)
print("\nNo filtering (all roles):")
print(f" Profile: {result.get('profile_content', 'N/A')}")
# Custom filtering: include user and system, exclude tool
result = user_memory.add(
messages=conversation,
user_id="user_010",
include_roles=["user", "system"],
exclude_roles=["tool"]
)
print("\nCustom filtering (user + system, exclude tool):")
print(f" Profile: {result.get('profile_content', 'N/A')}")Run this code:
python user_profile_example.pyExpected output:
Default filtering (user only):
Profile: Name: Frank. Profession: Doctor. Location: Boston.
No filtering (all roles):
Profile: Name: Frank. Profession: Doctor. Location: Boston.
Custom filtering (user + system, exclude tool):
Profile: Name: Frank. Profession: Doctor. Location: Boston.
- UserMemory Guide - Detailed guide on UserMemory features
- Getting Started - Learn the basics of PowerMem
- Multi-Agent Guide - Using multiple agents with Memory