Files
browser-use/examples/features/custom_vector_store.py
2025-05-29 20:45:06 -03:00

174 lines
6.8 KiB
Python

"""
Script that demonstrates how to use the new customizable MemoryConfig with Browser Use, showcasing two different vector store providers:
the default FAISS (local) and a more scalable option like Qdrant
You'll need a Qdrant server running locally to run the Qdrant example.
You can visualize your Qdrant memories at http://localhost:6333/dashboard#/collections
"""
import asyncio
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from browser_use import Agent
from browser_use.agent.memory import MemoryConfig
# Load environment variables (e.g., OPENAI_API_KEY)
load_dotenv()
# Ensure OpenAI API key is set
if not os.getenv('OPENAI_API_KEY'):
print('Error: OPENAI_API_KEY environment variable not set.')
exit()
async def run_agent_with_memory_config(
task: str,
llm: ChatOpenAI,
memory_config: MemoryConfig | None,
agent_name: str,
max_steps: int = 5, # Keep low for demo purposes
):
print(f'\n--- Running Agent: {agent_name} ---')
if memory_config:
print(f'Memory Provider: {memory_config.vector_store_provider}')
if memory_config.vector_store_provider != 'memory': # 'memory' provider doesn't use path or collection
print(f'Vector Store Collection: {memory_config.vector_store_config_dict["config"].get("collection_name", "N/A")}')
if memory_config.vector_store_provider in ['faiss', 'chroma']:
print(f'Vector Store Path: {memory_config.vector_store_config_dict["config"].get("path", "N/A")}')
agent = Agent(
task=task,
llm=llm,
enable_memory=True if memory_config else False, # Enable memory if config is provided
memory_config=memory_config, # Pass the specific memory config
# Set a lower planner_interval for more frequent planning in short demos
# and potentially see memory summarization happen sooner if memory_interval is also low.
planner_interval=2,
)
print(f'Starting task: {task}')
history = await agent.run(max_steps=max_steps)
print(f'\n--- {agent_name} Finished ---')
print(f'Task completed: {history.is_done()}')
print(f'Final result/summary: {history.final_result()}')
print(f'Number of steps taken: {len(history.history)}')
# Let's refine how to access summaries. The summary is added as a 'memory' type message.
summaries_created = []
for step_messages in agent.message_manager.state.history.get_messages():
if isinstance(step_messages, list):
for msg in step_messages:
if (
hasattr(msg, 'additional_kwargs')
and msg.additional_kwargs.get('metadata', {}).get('message_type') == 'memory'
):
summaries_created.append(msg.content)
elif (
hasattr(step_messages, 'additional_kwargs')
and step_messages.additional_kwargs.get('metadata', {}).get('message_type') == 'memory'
): # if it's a list of messages
summaries_created.append(step_messages.content)
if summaries_created:
print('\nProcedural Summaries Created during run:')
for i, summary in enumerate(summaries_created):
print(f' Summary {i + 1}: {summary[:150]}...') # Print first 150 chars
else:
# Check if messages were consolidated by looking at the agent's final message history
final_messages = agent.message_manager.get_messages()
summaries_in_final_context = [
m.content
for m in final_messages
if hasattr(m, 'additional_kwargs') and m.additional_kwargs.get('message_type') == 'memory'
]
if summaries_in_final_context:
print('\nProcedural Summaries in final context:')
for i, summary in enumerate(summaries_in_final_context):
print(f' Summary {i + 1}: {summary[:150]}...')
else:
print(
'No explicit procedural summaries found in final context (task might have been too short or memory interval not reached).'
)
print('---------------------------\n')
return history
async def main():
"""Main function to run the agent with different memory configurations."""
common_task = 'Find the current CEO of OpenAI and then search for news about their latest projects. Summarize your findings.'
shared_agent_id = 'persistent_browser_agent_001' # Use the same ID to test persistence with Qdrant
# Initialize the LLM (e.g., OpenAI's GPT-4o)
# Ensure your OPENAI_API_KEY is set in your environment or .env file
llm = ChatOpenAI(model='gpt-4o', temperature=0)
# --- Scenario 1: Default FAISS Memory ---
# MemoryConfig will use its defaults: FAISS, HuggingFace embedder if llm_instance not directly used by Mem0 for defaults
# Since we pass llm_instance, it will likely pick OpenAI embedder
faiss_memory_config = MemoryConfig(
llm_instance=llm, # Crucial for Mem0 to use this LLM for summarization
agent_id=shared_agent_id,
memory_interval=3, # Summarize more frequently for demo
# vector_store_provider is 'faiss' by default
# embedder_provider will default based on llm_instance
)
await run_agent_with_memory_config(common_task, llm, faiss_memory_config, 'Agent with FAISS Memory')
print('\n === PAUSE: Check FAISS data in /tmp/mem0... (if created) ===\n')
# You might need to adjust the path based on your embedder_dims, e.g., /tmp/mem0_1536_faiss
input('Press Enter to continue to Qdrant example...')
# --- Scenario 2: Qdrant Memory ---
# Ensure Qdrant server is running (e.g., `docker run -p 6333:6333 qdrant/qdrant`)
print('Attempting to use Qdrant. Make sure Qdrant server is running on localhost:6333.')
try:
qdrant_memory_config = MemoryConfig(
llm_instance=llm, # Pass the LLM for Mem0's internal use
agent_id=shared_agent_id, # Same agent_id for potential persistence
memory_interval=3, # Summarize more frequently
embedder_provider='openai', # Explicitly set for consistency
embedder_model='text-embedding-3-small',
embedder_dims=1536,
vector_store_provider='qdrant',
vector_store_collection_name='browser_use_qdrant_demo', # Custom collection name
vector_store_config_override={
'host': 'localhost',
'port': 6333,
# For Qdrant Cloud, you'd add "api_key": "YOUR_QDRANT_CLOUD_KEY", "url": "YOUR_QDRANT_CLOUD_URL"
# "path": ":memory:" # For in-memory Qdrant, useful for quick tests without persistence
},
)
await run_agent_with_memory_config(
common_task, # Could be a follow-up task to test memory persistence
llm,
qdrant_memory_config,
'Agent with Qdrant Memory',
)
except ImportError as e:
print(f'Could not run Qdrant example due to missing dependency: {e}')
print('Please install qdrant-client: pip install qdrant-client')
except Exception as e:
print(f'Error running Qdrant agent: {e}')
print('Ensure Qdrant server is running and accessible.')
# --- Scenario 3: No Memory (for comparison) ---
# await run_agent_with_memory_config(
# common_task,
# llm,
# None, # Pass None for memory_config to disable memory
# "Agent with NO Memory"
# )
if __name__ == '__main__':
import sys
if sys.platform.startswith('win'):
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
asyncio.run(main())