온라인으로 렌터카를 예약하는데 양식에 운전면허증 번호와 만료일을 적어야 합니다. 그런데 면허증이 손에 없습니다. 작년에 새 면허증으로 바꿀 때 앞면과 뒷면을 사진으로 찍어 둔 기억은 있지만, 그 사진은 iPhone 속 수만 장의 사진 사이에 묻혀 있습니다. Comma에게 자연어로 물어서 그 두 장을 찾고 싶습니다.
이 가이드는 그렇게 하는 방법 하나를 소개합니다. 먼저 로컬 모델로 사진 인덱스를 만들고, 그다음 Comma가 그 인덱스를 검색하게 합니다. 이것은 Mac 한 대에서 구성한 예시이며, Comma의 기본 기능이 아닙니다.
라이브러리는 로컬에 둔다
Comma에는 사진의 사본이 필요 없습니다. 가장 무거운 작업, 즉 각 이미지의 글자를 읽고 각 사진을 벡터로 바꾸는 일은 로컬 모델이 합니다. 에이전트가 받는 것은 한 번의 검색 결과입니다. 사진 ID 몇 개, 그 날짜, 이미지에서 읽은 글자, 그리고 선택이 필요할 때는 썸네일을 모은 콘택트 시트 한 장입니다. 마지막에 당신이 고른 사진만 채팅으로 보내집니다.
사진 동기화 자체는 iCloud를 거칩니다. 여기서 말하는 로컬은 내보낸 뒤의 글자 인식, 벡터, 인덱스를 뜻합니다. Comma가 클라우드 모델을 쓴다면, 이 검색 결과와 당신이 보라고 한 이미지는 당신이 고른 모델 제공자에게 전송됩니다. 운전면허증 같은 문서라면 인식된 글자에 번호와 주소가 들어 있습니다. 인덱스 자체는 어디로도 보내지지 않습니다. Comma는 오픈 소스이며, 직접 소유한 머신에 설치할 수도 있습니다.
사진 인덱스 만들기
인덱스는 사진이 원래 지나가는 경로 뒤에 붙습니다. iPhone에서는 아무것도 바꾸지 않습니다.
구성은 세 단계입니다.
사진을 로컬로 가져온다. iCloud 사진으로 iPhone의 사진을 Mac에 동기화하고, 새 사진을 매일 폴더 하나로 내보냅니다.
로컬 모델로 처리한다. 이미지 속 글자를 인식하고, Chinese-CLIP과 Qwen3-VL-Embedding으로 이미지를 벡터로 바꿉니다.
로컬 인덱스에 저장한다. 결과를 로컬 데이터베이스에 저장하고, 검색 명령을 하나 둡니다. 이 예시에서는 그 명령을
lpa라고 부릅니다.
검색이 돌려주는 것
로컬에서 검색 한 번은 명령 하나입니다. 한 번의 호출에 여러 표현을 넣을 수 있고, 모델은 한 번만 불러옵니다. 에이전트는 “작년” 같은 말을 날짜 범위로 바꿉니다.
각 결과에는 그 뒤에 어떤 근거가 있는지 표시됩니다.
--prefer text는 글자 일치를 앞에 두므로 문서, 카드, 스크린샷을 찾을 때 알맞습니다. --prefer picture는 비슷해 보이는 사진을 앞에 두므로 고양이나 해변을 찾을 때 알맞습니다. 몇 분 안에 찍은 거의 같은 사진은 목록에서 한 자리만 차지하고, 나머지는 그 아래에 묶입니다.
맨 위의 결과가 확실하지 않으면 에이전트는 추측하지 않습니다. 후보의 썸네일을 번호를 붙인 시트 한 장에 모으고(최대 아홉 장), 당신에게 고르게 합니다.
두 가지 벡터를 함께 쓰는 방식은 약 5만 장의 사진이 있는 실제 라이브러리에서 보정해 정했습니다. Qwen3-VL-Embedding만 쓰면, 사람이 고른 정답이 Chinese-CLIP만 쓸 때보다 오히려 뒤로 밀렸습니다. 두 순위를 합치자, 확인한 모든 항목이 어느 한 모델만 쓸 때보다 나빠지지 않았습니다. "가능성 있음"도 두 모델의 유사도가 모두 기준을 넘을 때만 붙습니다. 한 테스트 질의에서는 "가능성 있음"으로 표시된 사진이 4,970장에서 4장으로 줄었습니다. 그 대가로 검색 한 번이 약 3초에서 3.5~6초로 늘었습니다.
이 예시는 메모리 16 GB의 MacBook Air에서 실행되며, Qwen3-VL-Embedding은 2B를 씁니다. 더 좋은 머신이라면 더 큰 Qwen 모델을 쓸 수 있습니다.
더 큰 벡터 모델. Qwen3-VL-Embedding-2B를 Qwen3-VL-Embedding-8B로 바꿉니다. 바꾼 뒤에는 모든 사진의 벡터를 새 모델로 다시 계산해야 합니다.
사진마다 설명과 태그 달기. Qwen3-VL-4B-Instruct나 Qwen3-VL-8B-Instruct를 따로 실행해 사진마다 한 문장 설명과 태그 몇 개를 쓰고, 글자 인덱스에 저장합니다. 예를 들어 메모리 24 GB의 MacBook Pro에서는 8B(8-bit 양자화)를 실행할 수 있습니다. 생성된 태그는 대략적인 걸러내기에 알맞지만, 정확하다고 보장하지는 않습니다.
영어는 어떻게 하나. Chinese-CLIP은 주로 중국어 이미지와 텍스트로 학습되어 영어 질의에는 믿을 수 없습니다. 나머지 두 가지는 영향을 받지 않습니다. 글자 인식은 중국어와 영어를 모두 읽고, Qwen3-VL-Embedding도 여러 언어를 지원합니다. 그래서 앞의 명령처럼 검색에 중국어와 영어 표현을 함께 넣습니다. 이 내용은 Skill에 적어 둘 수 있습니다. 라이브러리와 질문이 주로 영어라면 Chinese-CLIP을 원래의 CLIP으로 바꿀 수도 있으며, 이때도 벡터를 다시 계산해야 합니다.
가족과 친구 찾기
“사진” 앱은 원래 같은 사람의 얼굴을 한데 모읍니다. 인덱스는 이 그룹을 그대로 쓰고, 직접 얼굴 인식을 하지 않습니다.
먼저 사람을 확인한다. 처음 쓸 때 에이전트는 이 그룹들에서 사진 몇 묶음을 골라 번호를 붙이고, 누구인지 묻습니다. 당신이 "3번은 엄마"라고 답해야 비로소 기억합니다. 확인하지 않은 그룹은 누구로도 취급되지 않습니다.
사람으로 찾는다. 그 뒤로 이름을 말하면, 그 사람이 나온 사진 안에서만 검색합니다. 이름은 겹쳐 쓸 수 있습니다. 두 사람의 이름을 말하면 두 사람이 모두 나온 사진, 즉 함께 찍은 사진만 돌려줍니다.
다른 조건과 함께 쓴다. 이름은 이미지 내용이나 시기와 함께 검색할 수 있습니다. 예를 들어 "작년에 엄마와 해변에서 찍은 사진"은 이렇습니다.
이름이 아직 확인되지 않았거나 같은 이름을 가진 사람이 두 명이면, 검색은 추측하지 않고 그렇다고 알려 줍니다. 잘못된 이름은 고칠 수 있고, 모든 수정은 되돌릴 수 있습니다.
동영상 찾기
동영상은 사진과 따로 검색합니다. 기본 검색은 사진만 찾습니다. 예를 들어 아이가 생일 촛불을 끄는 동영상을 찾고 싶다면, 동영상을 찾는다고 Comma에게 분명히 말하면 검색에 --source video를 붙입니다.
뒤에서는 세 단계가 이어집니다.
프레임을 잘라 낸다. 동영상 자체는 모델에 들어가지 않습니다. 인덱스 프로그램은 동영상에서 5초마다 한 프레임을 잘라 내며, 동영상 하나당 최대 12프레임입니다.
프레임으로 검색한다. 잘라 낸 프레임은 사진과 같은 처리를 거칩니다. 글자를 인식하고 두 가지 벡터를 계산합니다. 검색은 이 프레임들을 비교하며, 한 프레임이라도 맞으면 동영상 전체를 찾은 것으로 보고 결과에서는 한 자리만 차지합니다.
동영상을 보낸다. 당신이 고르면 에이전트가
lpa video로 동영상을 보냅니다.
지금은 화면만 보고 소리는 듣지 않습니다. 동영상에서 한 말은 아직 검색할 수 없고, 동영상에 나온 사람도 아직 알아보지 못합니다. 잘라 내는 프레임 수에 상한이 있어서, 긴 동영상에서 잠깐 스쳐 가는 장면은 못 찾을 수 있습니다.
LocalPhotoAgent의 구조
이 가이드의 lpa는 우리가 직접 만든 인덱스 프로그램 LocalPhotoAgent에서 나왔으며, 앞으로 오픈 소스로 공개할 예정입니다. 인덱스를 만드는 부분은 앞에서 다뤘으니, 여기서는 두 가지만 덧붙입니다.
언제든 멈출 수 있다. 사진마다 각 단계를 따로 기록하므로, 중간에 멈추면 다음에 이어서 진행합니다. 설정을 바꾸면 영향을 받는 단계만 다시 실행합니다. 처리하는 동안 메모리, 온도, 디스크 공간을 지켜보다가 한도를 넘으면 잠시 멈춥니다.
에이전트에게 명령 몇 개를 준다.
lpa search는 검색,lpa sheet는 콘택트 시트 생성,lpa preview는 사진 전송,lpa video는 동영상 전송입니다. 에이전트는 사진을 찾을 때 이 순서로 호출합니다.
Comma 연결하기
LocalPhotoAgent가 이미 Mac에서 잘 돌아가고 있다고 가정합니다. 연결은 네 단계입니다.
기기를 추가한다. Comma의 Settings > Devices에서 Add device를 눌러 설치 명령을 받습니다.
명령을 실행한다. 라이브러리가 있는 Mac의 터미널에서 그 명령을 실행해 Comma Connector를 설치합니다.
권한을 켠다. 새 기기는 처음에 Off입니다. 이것을 Full로 바꿔야 에이전트가
lpa를 실행할 수 있습니다.Skill을 쓴다. 먼저 검색하고, 확실하지 않으면 콘택트 시트를 보내고, 당신이 고른 뒤에 사진을 보내라고 에이전트에게 알려 줍니다. Comma에게 "Skill을 만들어 줘"라고 하기만 해도 됩니다.
그다음부터는 평소 채팅하듯 물어보면 됩니다. “작년에 찍은 운전면허증 사진 찾아 줘. 앞면과 뒷면 둘 다.”
신뢰와 한계
인덱스는 원본을 읽기만 하며, 옮기거나 편집하거나 삭제하지 않습니다. 검색은 외장 드라이브를 전혀 건드리지 않고, 콘택트 시트를 만들거나 사진을 보낼 때만 읽습니다. 사진을 옮기거나 삭제하는 일은 이 구성의 범위 밖입니다. 다만 Full 권한으로 설정하면 에이전트가 이 Mac에서 실행할 수 있는 명령은 lpa에 그치지 않습니다.
글자 일치는 그 글자를 찾았다는 뜻일 뿐, 그것이 원하는 사진이라는 뜻은 아닙니다. "가능성 있음"은 후보일 뿐입니다. Comma가 요청을 완료로 표시하면 보내 온 사진을 확인하세요.
처음 해 볼 때는 이렇게 말해 보세요. “작년에 찍은 운전면허증 사진을 찾아 줘. 먼저 콘택트 시트를 보여 주고, 아무것도 보내거나 옮기거나 삭제하지 마.”


