다음에 올 것을 만들어가는 기술에 대한 심층 기사.

추천 알고리즘 없는 피드: 알고리즘보다 큐레이션

사람의 큐레이션과 단순한 검색으로 추천 알고리즘 없는 피드를 만드는 방법. HackerTube에서 얻은 교훈을 정리했습니다.

시끄러운 썸네일이 뒤엉킨 벽과 차분하고 정돈된 큐레이션 영상 타일 선반을 대비한 일러스트
주의(attention)를 최적화한 피드와 사람이 큐레이션한 선반의 차이는 생각보다 확연합니다.

금요일 밤 11시입니다. 피곤한 상태로 YouTube를 열면 홈 화면은 비명 지르는 썸네일과 놀란 얼굴들, 그리고 2019년에 당신이 좋아한다고 멋대로 판단한 세 가지 주제로 가득합니다. 원하는 건 하나도 없지만 그래도 스크롤을 내립니다. 인터페이스가 그렇게 하도록 설계되어 있으니까요. 이런 종류의 피로를 느껴본 적이 있다면, 추천 알고리즘 없는 피드가 왜 갑자기 주목받는지 이해하실 겁니다. 최근에는 Hacker News 댓글 추천을 바탕으로 만든 YouTube 클론이 AI 에이전트와 함께 약 두 시간 만에 만들어져 큰 관심을 받기도 했습니다.

이 프로젝트는 HackerTube입니다. 2007년부터 지금까지 Hacker News 댓글에서 추천된 약 6,500개의 영상을 모아 YouTube 스타일의 인터페이스로 보여줍니다. 계정도, 추적도, 자동재생 조작도 없습니다. 상태 정보는 브라우저의 로컬 스토리지에만 저장됩니다. 토요일 아침 한 세션 동안 프롬프트로 데이터 추출부터 VPS 배포까지 모두 만들어냈습니다. 이 프로젝트가 왜 잘 작동하는지 이야기하고 싶은데, 단순한 사이드 프로젝트를 넘어 일반적인 교훈이 있기 때문입니다. 이 프로젝트가 잘 작동하는 이유는 일반적 의미의 추천 알고리즘이 없기 때문이고, 그것이 여러분의 제품에도 의도적으로 설계해 넣을 수 있는 기능이라는 점이 핵심입니다.

추천 알고리즘은 왜 엉뚱한 것을 최적화하는가

저는 몇 년간 랭킹 시스템을 다뤄왔기 때문에 솔직하게 말씀드리겠습니다. 목적 함수가 곧 제품입니다. 플랫폼 규모의 추천 시스템은 시청 시간, 클릭률, 세션 길이, 때로는 광고 노출로 가중된 체류 시간 같은 참여도 지표로 학습됩니다. 이 중 어느 것도 “사용자가 만족하고 떠났는가”를 재지 않습니다. “사용자가 머물렀는가”만 잴 뿐입니다. 이 지표들은 종종 상관이 있어서 좋은 것을 만들고 있다고 착각하게 만들지만, 정작 중요한 상황에서는 어긋납니다. 분노를 유발하는 콘텐츠, 자극적인 콘텐츠, 이미 질리도록 본 주제의 스무 번째 영상이 그런 경우입니다.

이건 트렌치코트를 걸친 굿하트의 법칙과 같습니다. 시청 시간이 목표가 되는 순간, 그 지표는 품질에 대해 아무것도 측정하지 못하게 됩니다. 더 나쁜 것은 피드백 루프가 닫혀 있다는 점입니다. 알고리즘이 무엇을 클릭할지 결정하고, 그 클릭이 다시 학습 데이터가 되며, 모델은 점점 더 좁아지는 당신의 모습을 점점 더 확신하게 됩니다. HackerTube를 본 몇몇 사람들이 지적했듯이, 개발자들이 추천한 개인화되지 않은 영상 피드의 적중률이 극도로 개인화된 YouTube보다 높았다고 합니다. 저도 같은 것을 느꼈습니다. 이건 놀랄 일이 아닙니다. 개인화는 가장 약한 순간(피곤한 밤 11시에 클릭한 것)으로 취향을 추론하지만, 큐레이션은 사람들이 가장 강하게 느낀 순간(동료에게 추천하려고 굳이 댓글을 달았던 순간)에서 취향을 담아냅니다.

더 미묘한 실패 방식도 있습니다. 최적화된 피드는 이미 아는 것을 더 많이 보여주는 데 탁월합니다. 하지만 사람들이 탐색하는 이유 중 상당수는 지평 확장입니다. 세상에 대한 내 모델을 다시 보정해 주는 뜻밖의 발견 말입니다. 참여도 최적화에는 나중에 빛을 발하는 놀라움에 대한 그래디언트 신호가 없습니다. 오직 머물렀는지만 압니다. 제가 AI 벤치마크가 실제 업무의 대부분을 놓치는 이유를 주장한 것도 같은 맥락입니다. 측정 가능한 대리 지표는 실제로 원하던 것에서 점점 멀어지고, 그 간극은 복리로 커집니다.

큐레이션을 코퍼스로: Hacker News 댓글 마이닝

그렇다면 추천 없는 피드의 콘텐츠는 어디서 올까요? HackerTube의 답은 영리합니다. 이미 존재하는 고품질 신호, 즉 20년치 Hacker News 댓글을 재활용하기 때문입니다. 파이프라인은 설명하기 간단합니다. 공개된 모든 HN 댓글을 내려받습니다(공식 API와 커뮤니티 데이터셋으로 얻을 수 있습니다). YouTube 링크가 포함된 댓글만 거르면 약 40,000개가 남습니다. 그다음 저렴한 LLM으로 각 댓글에 대해 한 가지 질문에 답하게 합니다. 이 사람이 실제로 이 영상을 추천하는가, 아니면 스팸이거나, 지나가며 던진 링크이거나, 영상을 조롱하기 위해 인용한 것인가? 이 필터링 단계를 거치면 150개 주제 클러스터에 걸친 약 6,500개의 영상으로 좁혀집니다.

여기서 따라 할 만한 설계 선택이 두 가지 있습니다. 첫째, 분류 단계는 LLM이 특히 잘하는 범위가 정해진 판단 작업입니다. 짧은 근거와 함께 예/아니오를 답하게 하고, 그것을 대규모로 푼돈 수준의 비용으로 적용합니다. 이는 제약된 디코딩으로 LLM을 빠른 의사결정 모델로 만드는 방법과 같은 패턴입니다. 모델에게 생성을 시키지 말고 필터링을 시키세요. 둘째, 이 코퍼스에는 내장된 품질 하한선이 있습니다. 모든 영상은 사람이 공개 석상에서 글로 남긴 보증이며, 그 앞에는 헛소리에 반대표를 던지는 독자들이 있습니다. 이것은 클릭이 아니라 평판에 기반하기 때문에 어떤 참여도 모델도 흉내 낼 수 없는 필터링 메커니즘입니다.

댓글에 쓴 추천은 평판을 걸고 하는 행위입니다. 클릭은 반사 신경입니다. 전자로 만든 피드가 다르게 느껴지는 이유는 실제로 다르기 때문입니다.

시간 차원도 중요합니다. 이 추천들은 2007년부터 지금까지 걸쳐 있기 때문에, 코퍼스는 알고리즘이 이번 주에 밀어 올리는 것보다 오래 살아남는 콘텐츠, 즉 강의, 깊이 있는 기술 발표, 긴 인터뷰 위주로 채워져 있습니다. 사람들이 특히 좋아한 것 중 하나는 긴 영상을 모은 “Longs” 카테고리입니다. YouTube에서 90분짜리 강연은 추천 알고리즘이 사용자의 세션을 걸고 하는 도박입니다. HackerTube에서는 그 옆에 “이 영상 덕분에 컴파일러를 보는 관점이 바뀌었다”라는 댓글이 달려 있으니 오히려 장점입니다.

쏟아지는 댓글 말풍선들이 걸러져 작은 큐레이션 타일 더미로 모이는 깔때기 일러스트
댓글 4만 개가 들어가고 보증받은 영상 6,500여 개가 나옵니다. 이 깔때기 자체가 제품입니다.

단순한 검색이 똑똑한 랭킹을 이긴다

추천 시스템 업계에 있었다면 이 부분이 이단처럼 들릴 겁니다. 코퍼스가 작고 좋다면 랭킹은 거의 중요하지 않습니다. 영상 6,000개는 아무것도 아닙니다. 두 타워 임베딩 모델이나 재순위 캐스케이드가 필요하지 않고, 주제 태그, 최신성, 그리고 클라이언트에서 돌아가는 가벼운 개인화 한 번이면 충분합니다. HackerTube의 “For You”는 로컬 스토리지의 세션 상태를 기반으로 동작합니다. 즉 이 브라우저에서 본 것과 건너뛴 것을 기록하지만 계정도, 서버 측 프로필도 없습니다. 이것은 한계가 아닙니다. 나쁜 인센티브 한 부류를 아예 없애는 아키텍처 결정입니다. 사용자 행동을 저장하지 않으면, 그것에 맞춰 최적화하고 싶은 유혹도 생기지 않습니다.

여러분만의 버전을 만들고 싶다면, 논문, 컨퍼런스 발표, 블로그 글, 커뮤니티가 추천하는 무엇이든 피드로 만들 수 있습니다. 랭킹 로직은 몇십 줄이면 충분합니다. 대략적인 형태는 다음과 같습니다.

import math
import time
def score(video, session, now=None):
now = now or time.time()
s = 0.0
# Corpus quality signal: how many distinct humans vouched for it
s += math.log1p(video["recommenders"])
# Gentle recency so the feed isn't frozen in 2014
age_days = max((now - video["recommended_at"]) / 86400, 1)
s += 0.5 / math.log1p(age_days)
# Session-level taste: topics the user finished vs. skipped,
# stored in localStorage — never leaves the browser
for topic in video["topics"]:
s += 1.5 * session["finished"].get(topic, 0)
s -= 1.0 * session["skipped"].get(topic, 0)
# Already watched? Push it down hard, don't hide it
if video["id"] in session["seen"]:
s -= 5.0
return s
def for_you_feed(videos, session, limit=24):
return sorted(videos, key=lambda v: score(v, session), reverse=True)[:limit]

눈에 띄지 않는 것이 있습니다. 체류 시간 특성도, 참여 속도도, 사용자의 한계점을 찾으려는 탐색-활용 밴딧도 없습니다. 개인화 신호는 명시적이고(사용자가 이 세션에서 끝까지 본 것과 건너뛴 것이라는 본인 행동으로 결정), 제한적입니다(각각 몇 점 수준이며 코퍼스 품질 항에 쉽게 밀립니다). 알고리즘은 살짝 밀어줄 수는 있어도 가두지는 못합니다. 이 비대칭이 점수 함수 하나에 담긴 철학 전부입니다.

썸네일 결정도 짚고 넘어갈 만합니다. 인터페이스를 최적화 해제하는 깔끔한 사례이기 때문입니다. YouTube 크리에이터들은 썸네일을 끝없이 A/B 테스트하기 때문에, 썸네일 자체가 적대적 산물이 되었습니다. HackerTube는 업로드된 썸네일을 무시하고 영상의 50% 지점 프레임을 대신 사용합니다. 한 줄짜리 변경으로 낚시성 썸네일 군비 경쟁을 완전히 없앱니다. 미리보기는 제작자가 클릭을 유도할 거라 생각하는 모습이 아니라 영상이 실제로 무엇인지 보여줍니다.

계정과 추적 없이 피드 설계하기

상태를 클라이언트로 옮기면 개인정보 보호 태세만 바뀌는 것이 아니라 비용 구조와 법적 노출 범위도 바뀝니다. 사용자 계정이 없으니 인증 시스템도, 비밀번호 재설정도, GDPR 열람 요청 처리 장치도, 행동 프로필에 대한 유출 책임도 없습니다. 백엔드는 정적 파일 서버이거나 작은 API 하나면 충분합니다. 사이트 전체가 빌드 산출물이 될 수 있습니다. 아키텍처가 사용자 데이터를 쌓을 수 없다면, 대부분의 다크 패턴은 정책 위반이 아니라 물리적으로 불가능해집니다. 저는 어떤 개인정보 처리방침보다 이런 종류의 보장을 훨씬 더 신뢰합니다.

솔직한 트레이드오프도 있습니다. 로컬 상태는 휘발성이고 기기에 묶여 있습니다. 브라우저 데이터를 지우면 피드가 초기화됩니다. 기기 간 연속성도 없습니다. 누워서 보는 영상 사이트라면 괜찮습니다. 오히려 가끔은 초기화가 건강에 좋다고 생각합니다. 사용자가 장기적으로 컬렉션을 쌓는 기능이라면 내보내기/가져오기 탈출구가 필요합니다. 그리고 이것은 공교롭게도 이 프로젝트에서 가장 앞을 내다본 결정으로 이어집니다.

데이터가 곧 인터페이스: 포크 가능한 코퍼스 배포하기

HackerTube에서 진짜 새롭다고 생각하는 부분은 UI가 아닙니다. 사이트 뒤의 전체 데이터셋을 zip으로 내려받을 수 있고, 그 안에 AI 에이전트를 위해 특별히 작성된 DATA.md가 들어 있다는 점입니다. 파일들이 어떻게 맞물리는지, 주의할 점, 예시 레코드, 최신 메타데이터를 가져오는 방법이 문서화되어 있습니다. 의도된 워크플로는 이렇습니다. zip을 코딩 에이전트에게 주고 “내 주제에 맞는 강연을 매주 이메일로 보내 줘” 또는 “이걸 위한 터미널 클라이언트를 만들어 줘”라고 말하는 것입니다. 제품은 웹사이트가 아닙니다. 제품은 큐레이션된 코퍼스이고, 웹사이트는 그것을 보여주는 참조 렌더러일 뿐입니다.

앞으로 더 많이 보게 될 패턴이라고 생각합니다. 20년 동안 표준 조언은 “API를 노출하라”였습니다. 하지만 API는 여전히 질의의 문지기로 여러분을 세워 두고, 유지보수를 멈추는 순간 썩어 버립니다. 이식 가능하고 에이전트가 읽을 수 있는 데이터셋은 관계를 뒤집습니다. 잘 문서화된 것을 한 번 공개하면, 수많은 개인화된 프론트엔드가 피어나게 됩니다. 이것은 스몰 웹의 정신과 통합니다. 플랫폼이 무엇을 보여줄지 결정하는 대신, 사람들이 좋아하는 것을 서로 링크하는 방식으로 발견이 이루어집니다. 다만 데이터의 첫 소비자가 언어 모델일 수도 있는 세상에 맞게 업데이트된 형태입니다.

에이전트를 위한 문서 작성은 새롭게 떠오르는 하나의 기술입니다. 사람은 훑어 읽지만, 에이전트는 글자 그대로 빠짐없이 읽고, 사람이 자연스럽게 유추하는 암묵적 가정에서 헤맵니다. 좋은 DATA.md는 단위, null 허용 여부, 인코딩의 특이점, 실패 모드를 처음부터 명시합니다. 데이터셋을 공개한다면 이제 이것은 기본 요건입니다. 에이전트가 한 번의 시도로 작동하는 포크를 만드느냐, 스키마를 환각으로 만들어내느냐의 차이입니다.

하나의 아카이브 상자에서 여러 기기와 형식으로 뻗어 나가는 가지를 그린 일러스트
코퍼스는 한 번만 공개하면 됩니다. 수백 개의 프론트엔드가 피어날 것입니다.

큐레이션 피드의 솔직한 한계

과장보다 실용성을 약속드렸으니 날카로운 부분도 짚겠습니다. 첫째, 큐레이션된 코퍼스는 큐레이터의 편향을 물려받습니다. Hacker News는 특정한 인구통계와 특정한 취향을 가진 집단입니다. 그 결과는 “100% 순수한 너드 콘텐츠”이며, 대상 독자라면 즐겁고 아니라면 아예 보이지 않습니다. 이 접근법은 “모두”를 위한 방식으로 확장되지 않으며, 그렇게 하려고 하지도 않습니다. 이것은 유틸리티가 아니라 선술집입니다.

  • 신선도 저하: 고정된 스냅샷은 시간이 지나면 썩습니다. 추출 파이프라인을 다시 돌리는 예약 작업이 없다면, 피드는 조용히 박물관이 되어 버립니다.
  • 플랫폼 의존성: 영상은 여전히 YouTube에 있습니다. 삭제, 지역 제한, 이용약관 변경이 밑에서부터 코퍼스를 썩게 만듭니다. 죽은 링크를 추적하지 않으면 신뢰를 잃습니다.
  • 인구통계적 고착: 추천하는 사람이 취향을 정의합니다. 커뮤니티 사이트라면 괜찮지만, 중립적인 발견 도구라고 내세우는 순간 심각한 편향 문제가 됩니다.
  • 신선도의 천장: 막 나온 훌륭한 콘텐츠에는 아직 추천이 없습니다. 큐레이션 피드는 새로운 것을 체계적으로 덜 보여주며, 바로 그 틈을 참여도 알고리즘이 메우고 있습니다. 좋은 쪽으로도 나쁜 쪽으로도요.

이 마지막 지점이 이 접근법에 대해 저를 솔직하게 만드는 부분입니다. 참여도 피드와 큐레이션 피드는 적이 아니라 서로 다른 시간 지평을 위해 최적화된 것입니다. 큐레이션은 무엇이 가치가 입증되었는지 알려 줍니다. 참여도 랭킹은 최선일 때 무엇이 가치 있어질 수도 있는지를 드러냅니다. 건강한 버전의 YouTube 추천 시스템은 HackerTube의 코퍼스에 작고 명확하게 표시된 “새롭고 아직 검증되지 않은” 레인이 더해진 모습일 겁니다. 비극은 추천 알고리즘이 존재한다는 데 있지 않습니다. 비즈니스 모델이 그것을 인터페이스 전부로 만들도록 요구한다는 데 있습니다.

직접 만들어야 할 때

두 시간짜리 빌드 시간이 이야기 속의 이야기입니다. 5년 전에는 이 속도로 이 프로젝트를 만드는 것이 불가능했습니다. 어느 한 단계가 특별히 어려워서가 아니라, 추출, 필터링, 메타데이터 보강, UI, 배포, 보안 강화까지 까다로운 단계가 40개쯤 있기 때문입니다. 계획 전체를 컨텍스트에 담을 수 있는 에이전트가 있으면 이 모든 것이 프롬프트 한 세션으로 압축됩니다. 즉 플랫폼 피드에 대한 틈새 큐레이션 대안을 만드는 장벽은 “토요일 아침의 의지 있는 한 사람” 수준으로 낮아졌습니다.

그래서 제 결론을 말씀드리겠습니다. 피드가 있는 제품을 운영한다면, 사내 지식 베이스든, 커뮤니티 포럼이든, 콘텐츠 제품이든, 알고리즘 버전을 만들기 전에 큐레이션 버전을 먼저 프로토타입으로 만들어야 합니다. 명시적인 사람의 추천으로 시작해서, 저렴한 LLM 필터링을 거치고, 스탠드업에서 설명할 수 있을 만큼 단순한 점수 함수로 랭킹하며, 가능한 한 오래 상태를 클라이언트에 두세요. 그러면 실제로 인벤토리 문제가 있는지, 랭킹 문제가 있는지 알게 됩니다. 제 경험상 거의 항상 인벤토리 문제입니다. 참여도 최적화 피드는 지표를 극대화하기 위한 도구입니다. 큐레이션 피드는 사람을 존중하기 위한 도구입니다. 두 번째 것을 먼저 만드세요. 첫 번째 것은 그것이 왜, 그리고 누구를 위해 존재해야 하는지 정확히 설명할 수 있을 때만 손대세요.