X 착수. 저장소 셋업 + X 3세대 공개 소스 전수 해부.
아래는 로그다. 근거 등급과 file:line 인용은 전부 services/x.md와 topics/*.md에 있고, 여기서는 반복하지 않는다.
읽은 것
xai-org/x-algorithm(2026-01-20aaa167b, 2026-05-15e414c17·0bfc279) —home-mixer/,thunder/,phoenix/,grox/,candidate-pipeline/전체twitter/the-algorithm@c54bec0(2025-09-03 리프레시) —home-mixer/,tweet-mixer/twitter/the-algorithm@72eda9a(2023) —simclusters_v2/,simclusters-ann/,ann/,cr-mixer/twitter/the-algorithm-ml(2023) —projects/home/recap/,projects/twhin/
새로 알게 된 것 (오늘의 큰 것 5개)
- 1세대와 2세대 사이 26개월 공백, 2세대는 삭제가 0건. 2023 파일 집합이 2025의 진부분집합이다. → 레포에 파일이 있다는 게 현역이라는 뜻이 전혀 아니다. 폐기는 README 한 줄을 바꾸는 방식으로만 드러난다.
- "인네트워크 50:50"은 코드에 없다. 2026엔 배분기 자체가 없고, OON은 쿼터가 아니라 점수 배수(
effective_oon)로 조절된다. 배분 문제가 랭킹 문제로 이사했다. xai-org/x-algorithm은 빌드되지 않는다.Cargo.toml0개,crate::params/util/clients통째 부재. 60개 파일이params를 참조하는데 정의가 없다 — 로직의 형태만 공개하고 값과 배선은 뺐다. 우연이 아니라 일관된 설계다.- README가 지목하는 스코어러 3개가 모듈 트리에서 끊겨 있다. 진짜 배선은
vec![phoenix_scorer, ranking_scorer, vm_ranker]. 죽은 파일 11개를 목록으로 확정했고,models/vscandidate_pipeline/이중 레이아웃이 세대 차이 판별법이라는 걸 찾았다. - 가중치 값은 어느 세대에도 1차 출처가 없다. 널리 인용되는 "reply 13.5 / report −369" 표는 블로그가 아니라
the-algorithm-ml의 README이고, 문서 스스로 "2023-04-05 기준, 언제든 바뀔 수 있다"고 못박는다. 2025 Scala는ModelWeights30개를 전부default = 0.0으로 지웠다 (같은 파일 나머지 203개 default는 실제값을 가진다 — 스타일이 아니라 의도적 삭제).
부수적으로: has_cached_posts 하나가 모든 소스·하이드레이터·Phoenix를 끄는 최대 스위치라는 것, PreviouslySeenPostsBackupFilter가 영구 no-op이라는 것, VMRanker 실패가 로그 없이 삼켜져 다양성이 조용히 사라진다는 것, grox/ 파이썬 두 파일이 리터럴 치환 때문에 import 자체가 안 된다는 것.
검증에서 뒤집힌 것 (중요)
초안을 verifier로 되짚었더니 결론 하나가 반대로 나왔고, 상수 인용 규칙 하나를 새로 배웠다.
- 뒤집힘: "2025 tweet-mixer의 u2i 후보는 상한 절단 뒤에 붙어 특혜를 받는다"는 틀렸다.
DropMaxResults가result만 자르고remainingCandidates를 남겨서 u2i는 꼬리에 놓이는데, 그 뒤 최종 절단선이 400(라이트랭커 상한 500보다 작다)이라 앞이 다 차면 u2i가 먼저 사라진다. 절단선을 하나만 보고 결론내면 방향이 반대로 나온다. - 새 규칙: grep으로 나온 숫자를 프로덕션 값으로 쓰면 안 된다. 세 가지 함정이 다 실재했다 — ①
args.int(name, default)의 default(SimClustersmaxNeighbors코드 400 vs 같은 파일이 적어둔 프로덕션 명령--maxNeighbors 100,maxEpochs3 vs 4) ② 벤치마크·warmup 리터럴(HNSWefConstruction=200/maxM=16은experimental/Runner.scala의 장난감,ef=800은warmup()안) ③ 모듈 트리에서 끊긴 파일의 상수(2026 죽은 스코어러의p::AUTHOR_DIVERSITY_DECAY). - 수확: 2026
offset_score가 2025RerankerUtil.weightedScoresSum의 직역이라 비공개 상수NEGATIVE_SCORES_OFFSET을 2025의Epsilon = 0.001로 복원했다. "두 레포는 코드 중복 0"이라는 통설의 예외. 다른 비공개 상수도 같은 방법이 통할 수 있다. - 그 외 수정:
FailOpenPolicy.Always가 9개 중 8개뿐이라 ContentExploration만 fail-closed, 2025 MMR은 리스트 앞(1-diversityRatio)×n개엔 다양성을 아예 안 건다,QuoteDeduplicationFilter는 인용문이 아니라 인용당한 원본을 지운다, tweet-mixer 파이프라인은 35개가 아니라 34개.
반영
services/x.md신규 — 3세대 비교표, 지면, retrieval 11소스, Phoenix 22헤드, 필터 17개, 광고 블렌딩, 콜드스타트, 함정 목록 11개topics/sequence-transformer-ranking.md신규 — Phoenix 구조·마스크topics/llm-in-recsys.md신규 — Grok/Grox 주석 파이프라인topics/multi-task-ranking.md신규 — 세대별 헤드 목록, 가중치 불투명성topics/candidate-allocation.md신규 — 비율/상한/인터리브, "50:50" 반박topics/feed-diversity.md신규 — 감쇠/MMR/DPP/deduptopics/embedding-retrieval.md신규 — SimClusters·TwHIN·two-tower·ANN 인덱스
다음에 볼 것
- EU DSA 투명성 보고서 — 가중치 실값이 규제 제출 문서에 있는지. 오늘 못 봤다.
e414c17(2026-05-15) 디프 — Phoenix 헤드가 19→22로 늘어난 시점이 여기인지- Meta 쪽 착수 (Instagram / Facebook / Threads) — 엔지니어링 블로그부터. X와 달리 코드가 없으니 근거 등급 관리가 더 중요해진다.