repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | --- |
| #2 | title: Search with Personal Context |
| #3 | description: "Blend Tavily's realtime results with personal context stored in Mem0." |
| #4 | --- |
| #5 | |
| #6 | |
| #7 | <Snippet file="security-compliance.mdx" /> |
| #8 | |
| #9 | Imagine asking a search assistant for "coffee shops nearby" and instead of generic results, it shows remote-work-friendly cafes with great WiFi in your city because it remembers you mentioned working remotely before. Or when you search for "lunchbox ideas for kids" it knows you have a 7-year-old daughter and recommends peanut-free options that align with her allergy. |
| #10 | |
| #11 | That's what we are going to build today, a Personalized Search Assistant powered by Mem0 for memory and [Tavily](https://tavily.com) for real-time search. |
| #12 | |
| #13 | |
| #14 | ## Why Personalized Search |
| #15 | |
| #16 | Most assistants treat every query like they've never seen you before. That means repeating yourself about your location, diet, or preferences, and getting results that feel generic. |
| #17 | |
| #18 | - With Mem0, your assistant builds a memory of the user's world. |
| #19 | - With Tavily, it fetches fresh and accurate results in real time. |
| #20 | |
| #21 | Together, they make every interaction smarter, faster, and more personal. |
| #22 | |
| #23 | ## Prerequisites |
| #24 | |
| #25 | Before you begin, make sure you have: |
| #26 | |
| #27 | 1. Installed the dependencies: |
| #28 | ```bash |
| #29 | pip install langchain mem0ai langchain-tavily langchain-openai |
| #30 | ``` |
| #31 | |
| #32 | 2. Set up your API keys in a .env file: |
| #33 | ```bash |
| #34 | OPENAI_API_KEY=your-openai-key |
| #35 | TAVILY_API_KEY=your-tavily-key |
| #36 | MEM0_API_KEY=your-mem0-key |
| #37 | ``` |
| #38 | |
| #39 | ## Code Walkthrough |
| #40 | Let’s break down the main components. |
| #41 | |
| #42 | ### 1: Initialize Mem0 with Custom Instructions |
| #43 | |
| #44 | We configure Mem0 with custom instructions that guide it to infer user memories tailored specifically for our usecase. |
| #45 | |
| #46 | ```python |
| #47 | from mem0 import MemoryClient |
| #48 | |
| #49 | mem0_client = MemoryClient() |
| #50 | |
| #51 | mem0_client.project.update( |
| #52 | custom_instructions=''' |
| #53 | INFER THE MEMORIES FROM USER QUERIES EVEN IF IT'S A QUESTION. |
| #54 | |
| #55 | We are building personalized search for which we need to understand about user's preferences and life |
| #56 | and extract facts and memories accordingly. |
| #57 | ''' |
| #58 | ) |
| #59 | ``` |
| #60 | Now, if a user casually mentions "I need to pick up my daughter" or "What's the weather at Los Angeles", Mem0 remembers they have a daughter or the user is interested in or connected with Los Angeles in terms of location. These details will be referenced for future searches. |
| #61 | |
| #62 | ### 2. Simulating User History |
| #63 | To test personalization, we preload some sample conversation history for a user: |
| #64 | |
| #65 | ```python |
| #66 | def setup_user_history(user_id): |
| #67 | conversations = [ |
| #68 | [{"role": "user", "content": "What will be the weather today at Los Angeles? I need to pick up my daughter from office."}, |
| #69 | {"role": "assistant", "content": "I'll check the weather in LA for you."}], |
| #70 | [{"role": "user", "content": "I'm looking for vegan restaurants in Santa Monica"}, |
| #71 | {"role": "assistant", "content": "I'll find great vegan options in Santa Monica."}], |
| #72 | [{"role": "user", "content": "My 7-year-old daughter is allergic to peanuts"}, |
| #73 | {"role": "assistant", "content": "I'll remember to check for peanut-free options."}], |
| #74 | [{"role": "user", "content": "I work remotely and need coffee shops with good wifi"}, |
| #75 | {"role": "assistant", "content": "I'll find remote-work-friendly coffee shops."}], |
| #76 | [{"role": "user", "content": "We love hiking and outdoor activities on weekends"}, |
| #77 | {"role": "assistant", "content": "Great! I'll keep your outdoor activity preferences in mind."}], |
| #78 | ] |
| #79 | |
| #80 | for conversation in conversations: |
| #81 | mem0_client.add(conversation, user_id=user_id) |
| #82 | ``` |
| #83 | This gives the agent a baseline understanding of the user’s lifestyle and needs. |
| #84 | |
| #85 | ### 3. Retrieving User Context from Memory |
| #86 | When a user makes a new search query, we retrieve relevant memories to enhance the search query: |
| #87 | |
| #88 | ```python |
| #89 | def get_user_context(user_id, query): |
| #90 | # For Platform API, user_id goes in filters |
| #91 | filters = {"user_id": user_id} |
| #92 | user_memories = mem0_client.search(query=query, filters=filters) |
| #93 | |
| #94 | if user_memories: |
| #95 | context = "\n".join([f"- {memory['memory']}" for memory in user_memories]) |
| #96 | return context |
| #97 | else: |
| #98 | return "No previous user context available." |
| #99 | ``` |
| #100 | This context is injected into the search agent so results are personalized. |
| #101 | |
| #102 | ### 4. Creating the Personalized Search Agent |
| #103 | The agent uses Tavily search, but always augments search queries with user context: |
| #104 | |
| #105 | ```python |
| #106 | def create_personalized_search_agent(user_context): |
| #107 | tavily_search = TavilySearch( |
| #108 | max_results=10, |
| #109 | search_depth="advanced", |
| #110 | include_answer=True, |
| #111 | topic="general" |
| #112 | ) |
| #113 | |
| #114 | tools = [tavily_search] |
| #115 | |
| #116 | prompt = ChatPromptTemplate.from_messages([ |
| #117 | ("system", f"""You are a personalized search assistant. |
| #118 | |
| #119 | USER CONTEXT AND PREFERENCES: |
| #120 | {user_context} |
| #121 | |
| #122 | YOUR ROLE: |
| #123 | 1. Analyze the user's query and context. |
| #124 | 2. Enhance the query with relevant personal memories. |
| #125 | 3. Always use tavily_search for results. |
| #126 | 4. Explain which memories influenced personalization. |
| #127 | """), |
| #128 | MessagesPlaceholder(variable_name="messages"), |
| #129 | MessagesPlaceholder(variable_name="agent_scratchpad"), |
| #130 | ]) |
| #131 | |
| #132 | agent = create_openai_tools_agent(llm=llm, tools=tools, prompt=prompt) |
| #133 | return AgentExecutor(agent=agent, tools=tools, verbose=True, return_intermediate_steps=True) |
| #134 | ``` |
| #135 | |
| #136 | ### 5. Run a Personalized Search |
| #137 | The workflow ties everything together: |
| #138 | |
| #139 | ```python |
| #140 | def conduct_personalized_search(user_id, query): |
| #141 | user_context = get_user_context(user_id, query) |
| #142 | agent_executor = create_personalized_search_agent(user_context) |
| #143 | |
| #144 | response = agent_executor.invoke({"messages": [HumanMessage(content=query)]}) |
| #145 | return {"agent_response": response['output']} |
| #146 | ``` |
| #147 | |
| #148 | ### 6. Store New Interactions |
| #149 | Every new query/response pair is stored for future personalization: |
| #150 | |
| #151 | ```python |
| #152 | def store_search_interaction(user_id, original_query, agent_response): |
| #153 | interaction = [ |
| #154 | {"role": "user", "content": f"Searched for: {original_query}"}, |
| #155 | {"role": "assistant", "content": f"Results based on preferences: {agent_response}"} |
| #156 | ] |
| #157 | mem0_client.add(messages=interaction, user_id=user_id) |
| #158 | ``` |
| #159 | |
| #160 | ### Full Example Run |
| #161 | |
| #162 | ```python |
| #163 | if __name__ == "__main__": |
| #164 | user_id = "john" |
| #165 | setup_user_history(user_id) |
| #166 | |
| #167 | queries = [ |
| #168 | "good coffee shops nearby for working", |
| #169 | "what can I make for my kid in lunch?" |
| #170 | ] |
| #171 | |
| #172 | for q in queries: |
| #173 | results = conduct_personalized_search(user_id, q) |
| #174 | print(f"\nQuery: {q}") |
| #175 | print(f"Personalized Response: {results['agent_response']}") |
| #176 | ``` |
| #177 | |
| #178 | ## How It Works in Practice |
| #179 | |
| #180 | Here's how personalization plays out: |
| #181 | |
| #182 | - **Context Gathering**: User previously mentioned living in Los Angeles, being vegan, and having a 7-year-old daughter allergic to peanuts. |
| #183 | - **Enhanced Search Query**: |
| #184 | - Query: "good coffee shops nearby for working" |
| #185 | - Enhanced Query: "good coffee shops in Los Angeles with strong WiFi, remote-work-friendly" |
| #186 | - **Personalized Results**: The assistant only returns WiFi-friendly, work-friendly cafes near Los Angeles. |
| #187 | - **Memory Update**: Interaction is saved for better future recommendations. |
| #188 | |
| #189 | ## Conclusion |
| #190 | |
| #191 | With Mem0 and Tavily, you can build a search assistant that doesn't just fetch results but understands the person behind the query. |
| #192 | |
| #193 | Whether for shopping, travel, or daily life, this approach turns a generic search into a truly personalized experience. |
| #194 | |
| #195 | Full Code: [Personalized Search GitHub](https://github.com/mem0ai/mem0/blob/main/examples/misc/personalized_search.py) |
| #196 | |
| #197 | --- |
| #198 | |
| #199 | <CardGroup cols={2}> |
| #200 | <Card title="Deep Research with Mem0" icon="magnifying-glass" href="/cookbooks/operations/deep-research"> |
| #201 | Build comprehensive research agents that remember findings across sessions. |
| #202 | </Card> |
| #203 | <Card title="Tag and Organize Memories" icon="tag" href="/cookbooks/essentials/tagging-and-organizing-memories"> |
| #204 | Categorize search results and user preferences for better personalization. |
| #205 | </Card> |
| #206 | </CardGroup> |
| #207 |