MemoryBox - AI-Powered Semantic Search for Your Memories
This is my submission for the Hacktoberfest Weekend Challenge: Build for a Friend.
What I Built
I built this for a friend who has a lot of photos and memories that are meaningful to them, but finding a particular one later can be surprisingly difficult. They might remember the moment clearly:
"That evening when we went out."
"That photo with everyone."
"The day we were playing tennis."
But remembering a moment isn't the same as remembering a filename, folder, or date. That was the problem I wanted to solve for them. So I built MemoryBox - a personal memory archive where you can search for photos based on what you remember about the moment, rather than how the file is stored.
Instead of asking: "What was that file called?" you can ask: "Show me the photos from our tennis day."
MemoryBox uses open-weight AI to understand uploaded photos, turn that understanding into semantic representations, and make those memories searchable.
Demo
๐ฅ Demo video:
๐ Live app: https://memorybox-frontend.onrender.com/
The demo shows the complete flow: uploading a photo, having the AI understand it, and searching for the resulting memory using natural language.
Code
๐ป GitHub: https://github.com/asnamobin-hue/memorybox
The repository contains the Spring Boot backend, React frontend, Docker configuration, and Python embedding helper.
How I Built It
The core of MemoryBox is an open-weight AI pipeline.
Photo │
โผ
Qwen3-VL-2B-Instruct │
โผ
AI-generated image description │
โผ
Qwen3-Embedding-0.6B │
โผ
1024-dimensional embedding │
โผ
PostgreSQL + pgvector │
โผ
Semantic memory search
For image understanding, I used Qwen/Qwen3-VL-2B-Instruct. For embeddings, I used Qwen/Qwen3-Embedding-0.6B. Both model checkpoints are published under the Apache 2.0 license.
When a photo is uploaded, the vision model generates a description of what is happening in the image - including things like people, activities, objects, and surroundings. That description is then passed to the embedding model, which converts it into a 1024-dimensional vector. The vector is stored in PostgreSQL with pgvector.
When someone searches for a memory, the search text is embedded and compared against the stored vectors to find semantically related memories.
The application is built with:
-
Java 25 -
Spring Boot -
Spring Data JPA -
PostgreSQL -
pgvector -
React -
Vite -
Python -
Docker -
Render
The deployed version currently calls the models through Hugging Face inference. The application keeps the model layer separate from the rest of the backend, so the models can be changed without redesigning the entire application. That separation was important to me because I didn't want the AI part of the project to become permanently tied to one proprietary API.
Why Open Innovation Matters
I chose open-weight models because I wanted control over the most important part of the application. MemoryBox isn't just using AI to generate a nice description. The model output becomes part of the actual data pipeline: photo → understanding → embedding → vector search.
Using separate open-weight models for those stages means I can inspect the models, change them, and experiment with different approaches without rebuilding the entire application around a single closed provider. It also gives me a path toward a more private version of MemoryBox.
The current public deployment uses hosted inference because that made the project practical to deploy during the challenge. But the model checkpoints are available for local use, so a future version could move inference closer to the user's device or private server. For a project dealing with personal memories, that possibility matters. A closed API can be convenient, but I don't want convenience to be the only option.
Open models gave me a different starting point: build the application around models that can be replaced, inspected, and eventually run in an environment I control.
One Real Search
One of the searches I tested was
Comments
No comments yet. Start the discussion.