Recall – 로컬 멀티모달 시맨틱 검색 for your files

발행: (2026년 4월 6일 AM 09:09 GMT+9)
5 분 소요

Source: Hacker News

Local multimodal memory with semantic search.
이미지, 오디오, 비디오, PDF 및 텍스트를 로컬 벡터 데이터베이스에 임베드하고 — 자연어 쿼리로 모든 것을 찾을 수 있습니다. *“team dinner”*에 대한 텍스트 검색으로 사진을 찾아낼 수 있습니다. 사진에 텍스트 메타데이터가 없더라도 말이죠.

Comes with an animated setup wizard and a Raycast extension for instant visual search.
애니메이션 설정 마법사와 즉시 시각 검색을 위한 Raycast 확장이 포함되어 있습니다.

Powered by Gemini Embedding 2 (768‑dim, free tier) and ChromaDB stored entirely on your machine.
Gemini Embedding 2 (768‑차원, 무료 티어)와 ChromaDB를 기반으로 하며, 모든 데이터는 완전히 사용자의 머신에 저장됩니다.

작동 방식

You                     Gemini Embedding 2          ChromaDB (local)
 |                            |                        |
 |-- team-dinner.jpg -------->|-- 768-dim vector ------>|-- stored on disk
 |-- meeting-notes.pdf ------>|-- 768-dim vector ------>|-- stored on disk
 |-- "team dinner" (query) -->|-- query vector -------->|-- cosine search
 |, validates your key, saves to `.env` |
| **Folder picker**| Checkbox list of your home folders with live file counts |
| **Indexing**   | Progress bar with current filename, auto‑retries on rate limits |
| **Raycast card**| Prints pre‑filled Python Package Path and Python Binary — just copy‑paste |

수동 키 설정 (필요한 경우)

cp .env.example .env
# then edit .env and add:
# GEMINI_API_KEY=your_key

Python API

from vector_embedded_finder import search, ingest_file, ingest_directory, count

# Embed a single file — image, PDF, audio, video, or text
ingest_file("~/Photos/team-dinner.jpg")

# Embed an entire directory (recursive by default)
ingest_directory("~/Documents/", source="docs")

# Search with natural language
matches = search("team dinner at the rooftop", n_results=5)
for m in matches:
    print(f"{m['file_name']}  {m['similarity']:.0%} match  {m['file_path']}")

# Housekeeping
print(f"{count()} items indexed")

ingest_file"status"("embedded" | "skipped" | "error")를 포함하는 dict를 반환합니다. 파일은 SHA‑256으로 중복 제거되며, 동일한 파일을 다시 삽입해도 아무 작업도 수행되지 않습니다.

Raycast 확장

런처에서 바로 이미지 썸네일이 포함된 시각적 그리드 검색.

Setup

cd raycast
npm install
npx ray develop

Raycast를 열고 Memory Search를 검색하세요. 첫 실행 시, 환경설정으로 이동하여 다음을 설정합니다:

PreferenceValue (example)
Python Package Path/Users/you/vector-embedded-finder
Python Binary/usr/bin/python3
Gemini API Keyyour key (or leave blank if set in .env)

팁: 먼저 python setup_wizard.py를 실행하세요 — 해당 값들이 미리 채워진 형태로 출력됩니다.

Commands

CommandWhat it does
Memory Search이미지/비디오 썸네일이 포함된 그리드 UI, 400 ms 디바운스 실시간 검색
Memory Open헤드리스 — 쿼리를 입력하면 가장 일치하는 파일을 즉시 엽니다

지원되는 파일 유형

카테고리형식
이미지.png .jpg .jpeg .webp .gif .bmp .tiff
오디오.mp3 .wav .m4a .ogg .flac .aac
비디오.mp4 .mov .avi .mkv .webm
문서.pdf
텍스트.txt .md .csv .json .yaml .yml .toml .py .js .ts .go .rs .sh

구성

VariableDefaultDescription
GEMINI_API_KEY(required)Google Gemini에서 제공하는 무료 키
VEF_DATA_DIR./dataChromaDB가 벡터를 저장하는 디렉터리

아키텍처

vector_embedded_finder/
  config.py      — env, API key, supported types, paths
  embedder.py    — Gemini Embedding 2 (text, image, audio, video, PDF)
  store.py       — ChromaDB layer: cosine distance, SHA‑256 dedup, upsert
  search.py      — natural language search with similarity scoring
  ingest.py      — file detection → embedding → storage pipeline
  utils.py       — hashing, MIME detection, timestamp helpers

raycast/
  src/lib/runner.ts       — Python bridge: spawnSync + JSON envelope protocol
  src/search-memory.tsx   — grid search UI with thumbnails
  src/open-memory.tsx     — headless instant file opener

setup_wizard.py           — animated CLI setup: key → folders → index → Raycast card

모든 벡터는 data/chromadb/에 로컬로 저장됩니다. 외부로 나가는 트래픽은 Google에 대한 임베딩 API 호출뿐이며, 파일은 절대 머신을 떠나지 않습니다.

라이선스

MIT

0 조회
Back to Blog

관련 글

더 보기 »