북마크 관리자 회고록
배경
나는 “오 이 블로그 유용하다” 거나 “오 이 툴 좋다 쓸 일 있을 때 써봐야지” 하면서 저장해놓는 북마크들이 많다. 폴더 안에 폴더가 있을정도로… 그러다보니 느꼈던 몇 가지 불편함이 있었다.
- 북마크만으로는 이걸 왜 저장했는지, 뭔 내용인지 알기 어려움
- 북마크했던 것 같은데 어디에 했는지 못 찾겠음
- 내가 북마크했다는 사실을 잊어버리고 검색하고 있음
- 과거엔 의미 있었으나 이젠 의미 없어진 링크들이 많음
- 나중에 봐야지 하고 저장했다가 까먹고 잊혀진 링크들 있음
나만 느낀 불편함이었을까? 주변인들에게 물어봤을 때 다들 비슷한 불편을 느낀 적이 있었다. 딱히 문제라고 느끼지를 못했을 뿐. 레딧에도 검색해보니 북마크 관리자에 대한 수요가 정말 많았다. 당연히 기존 서비스들도 많았다..
가장 대표적인건 raindrop. 이건 크롬 북마크랑 연계되진 않고 개별적인 북마크 관리자다. 근데 실제로 쓸 때는 메모라든가 태깅이라든가 약간 기능이 과하다? 조금 번거롭다?라는 생각이 들었다. 근데 미리보기도 가능하고 검색도 가능하고 카드 레이아웃이라 뭔 내용인지 1번과 2번 문제는 해결하기 좋겠다는 생각이 들었다.
그 외에 markmind, savespace, 이제는 멈춘 pocket 등 많은 서비스를 찾아봤다. 찾아보면서 공감됐던 댓글은 레인드롭이 인기있는 이유이자 많은 사람들이 북마크에 대한 불편함을 느끼면서도 관리자를 쓰지 않는 이유, “아무도 북마크를 관리하는데 그런 비용을 내고 싶지는 않을거야”
비용을 최소화하면서 내가 느낀 불편을 해결할 완벽한 서비스는 없어서 내가 한 번 만들어보기로 했다.
핵심은
- 내가 느낀 불편들을 해결할 수 있을 것
- 기존 북마크와 연동이 가능할 것
- 최대한 사용자가 번거롭지 않게 할 것
- 생성형 ai는 자제할 것(비용 때문)
으로 잡았다. 그럼 각각 어떻게 해결할 수 있을까
1. 북마크만으로는 이걸 왜 저장했는지, 뭔 내용인지 알기 어려움
현재 상단 뷰에 뜨는 북마크는 파비콘과 제목만 뜬다. 이걸 카드 형식으로 바꾸기로 했다. 이미지만 보아도 이게 어떤 내용인지 떠올리기 쉬워진다. 난 여기에 내용 요약을 추가하기로 했다.
- 카드형식 레이아웃
- 요약과 썸네일
- 클릭하면 해당 url로 이동
요약은 Gemini api를 활용했다. 단순히 크롤링해서 요약하기엔 페이지마다 html이 너무 달라 본문 콘텐츠를 찾기 어려웠기 때문이다.
썸네일은 Google Cloud Function을 활용했다.
- 대표 사진(og:image)
- 본문에서 가장 큰 이미지
- 파비콘
우선순위대로 썸네일을 저장했다.
이후 북마크 저장 팝업을 구현했다. 팝업을 열면 메타데이터가 자동으로 작성되고 사용자는 저장 버튼만 누르면 된다. 그럼 알아서 요약하고 썸네일을 만들어 원래의 북마크바에 연동되어 저장된다. 카드뷰에는 url, 썸네일, 요약, 폴더가 뜬다.
여기에 키워드 태깅도 추가할 생각이다. 레딧을 뒤져보니 생각외로 많은 사람들이 태그로 내용을 기억하더라고 ㄴㅇㄱ
추가로 이런 태깅에는 단순히 tf-idf로 희소성이 높은 키워드를 쓰는 게 아니라 논리적이고 구조적인 흐름이 보이게끔 해야 한다는 피드백이 있길래 제로샷 분류(ZSC)를 활용해서 “북마크가 쓰이는 활용 상황”이라는 컨텍스트를 담아내는 태깅을 할 생각이다.
그리고 원래는 이 카드 형식을 브라우저 상단 뷰에서 바로 보이게 하고 싶었다. 왜냐면 그렇게 한 서비스가 아무도 없어서 ㅎㅅㅎ
-> 찾아보니 그건 확장자의 권한 밖의 일이었다. 그래서 다들 안 한 거였어… 어쩔 수 업이 나도 manage.html을 만들었다. 후순위지만 사이드 패널로 개선할 예정이다. 단축키 기능도 생각중
2. 북마크했던 것 같은데 어디에 했는지 못 찾겠음
검색 기능을 구현하면 된다. 임베딩 벡터를 이용해 의미기반검색이 가능하도록 하면 될 거라 생각했다.
- transformer와 Univertial Sentence Encoding으로 의미 기반 검색
- WebGL 기반의 임베딩 모델을 사용
- 입력 쿼리와의 코사인 유사도를 측정해 상위 n개만
이랬더니 테스트했을 때 성능이 너무 안 좋게 나왔다. 이유는?
- USE는 영어로 사전학습된 모델, 한국어 문맥 이해 능력이 부족
- USE는 각 단어의 임베딩 벡터를 평균 내어 문장 벡터를 생성하는데, 다음처럼 [“햄버거”, “뭐야”] 와 [“감자”, “튀김”, “뭐야”]처럼 단어 구조만 비슷하면 높은 유사도로 판단 -> 문장의 의미보다는 단어 구성의 유사성이 유사도 계산에 더 큰 영향을 줌
그렇다면 어떻게 하는가 한국어 임베딩 모델을 올려야 하나?
한국어 임베딩 모델을 쓰려면 파이썬 기반 모델을 확장자 위에 올려야 하므로 js로 변환 하고 경량화도 해야한다.(Chrome 확장 프로그램의 크기 제한 때문)
근데 이렇게 하자니…꼭 그렇게 한국어 모델이 필요한가? 그냥 번역하면 될 것을… 노력이나 비용 대비 효용이 크지 않아 보였다.
임베딩하는 메타데이터를 모두 영어로 설정하고 사용자에게 보이는 단계에서만 번역 과정을 거치기로 했다!
이제 의미 기반 검색은 잘 되는데 단어 하나 정도의 키워드만으로는 검색 성능이 안 나왔다. 실제 사용자는 키워드 위주로 간단하게 검색할텐데…?
결국 키워드 만으로도 검색 가능하게 하이브리드 검색 구현
TF-IDF를 사용하여 검색어와 북마크 텍스트 간의 키워드 중요도를 측정하고 의미 점수와 키워드 점수에 가중치($\alpha, \beta$)를 주어 스코어 내렸다.
3. 내가 북마크했다는 사실을 잊어버리고 검색하고 있음
내가 가장 필요를 느낀 부분이다. 실제로 나는 저장하고도 검색하는 경우가 허다하기 때문.. 어떻게 이 문제를 해결할까 고민을 많이 했는데 검색했을 때 검색 결과보다 먼저 “어? 이거 이미 있어!”를 알려주면 해결할 수 있지 않을까 싶었다.
검색엔진에 특정 키워드를 검색할 경우 “잠깐! 이 검색어에 필요한 관련 북마크가 있습니다.”라고 팝업 아이콘 배지로 알림을 주는 기능
- 기존에 있는 임베딩 모델로 활용 상황 정의 -> 토픽 벡터 생성
- 크롬 api 활용해서 검색어 가로채기
- 추출한 쿼리로 임베딩 벡터 계산
- 유사도 계산
생각하고 이런 기능 시중에 있나? 하면서 찾아봤는데 있긴 하더라…
깃허브가 없어서 구현 방식은 모르지만 구현 가능하다는 걸 확인했으니 나도 할 수 있을거다!
실제로 이 서비스는 사용자가 꽤 많았다. 레딧에서도 은근히 많이 언급되고 있었다.
4,5 합쳐서 링크 무덤
이건 좀 더 고민을 해봐야 한다. 단순하게 그냥 자주 안 들어간 것들 리마인드하거나 삭제하자! 라고 하기엔
정말 쓸모 있고 필요할 때 잘 참고하고 있지만 참고할 때 자체가 적어 자주 안 들어가는 링크도 무덤으로 판별할 수 있다. 즉 안 들어간다고 의미없는 링크가 아닌데 오히려 맘대로 삭제했다간 사용자 입장에서 화날 것 같았다.
리마인드도 걸리는 것이 생각해보면 그 북마크 내용을 주기적으로 떠올려야 할 필요가 없다. 필요할 때만 보면 되는데 왜? 그리고 그 안 내용을 충분히 숙지할 필요도 없다. 보면 되는데 왜? 완벽 숙지했어도 또 들어가서 볼 수도 있는거고. 또 리마인드를 하기엔 이게 필요한 상황이 아닌데 자꾸 뜨면 나라도 짜증날 것 같다는 생각이 들었다.
조금 더 고민해볼것!
개선 혹은 문어발
개선 요소들을 생각해보다가 이게 처음 계획했던 목적에 부합한가? 에 막혀 사라진 아이디어들.. 모르지 나중에 어떻게 결합시킬 수 있을지
1. 가장 유사한 폴더 추천/디폴트 설정
기존 폴더들 중에 제일 유사한 폴더를 디폴트로
기존 폴더에 속한 북마크 임베딩의 평균 벡터(Centroid)를 계산하고, 클러스터링으로 새 북마크 벡터와 가장 가까운 폴더를 추천하는 방식
하지만 현재 폴더가 front, git, design, tip 뭐 이렇게 되어있을때 그냥 이거 이름 가지고 유추하는건 tip, front처럼 광범위하거나 애매모호한 이름도 많다 보니 결과 오류 가능성이 매우 높음
그리고 원래 목적과 상관 없이 그냥 편의성 키우는 기능이랑 탈락
2. 시간 정보 처리
“지난주에 봤던 리액트 성능 최적화 방법"이 가능하도록
시간 구문 파악: “지난주에 봤던” 부분을 추출
시간 구문을 검색 쿼리에서 제거해 순수 의미만 남기고 시간구문은 타임스탬프 범위로 변환해서 검색 성능 높이기
검색 성능 향상 면에서 쓸만하지만 중요하지 않음, 후순위
3. 북마크 정렬
최근에 들어간 순대로, 가장 많이 클릭한 순대로, 가장 오래 체류한 순대로 각각 가중치를 주고 스코어를 내려서 점수 높은 순대로 정렬하기
이건 manage.html에선 구현이 되어있는데 브라우저 상단 뷰에서 적용할 수 있을까?를 고민했다.
확장자 권한 문제로 될 수도 있고 안 될 수도 있다. 찾아보니 정설은 안된다지만 편법이 있는 것 같았다. 해보고 더 자세히 조사해봐야 알텐데 이것도 폴더와 마찬가지로 편의성 키우는 기능에 그쳐서 탈락