◂ 일일 리포트2026-08-29 빌드
FEED RESEARCH · 일일 리포트

2026-08-08

토요일 · 읽는 데 약 6분

    X 착수. 저장소 셋업 + X 3세대 공개 소스 전수 해부.

    아래는 로그다. 근거 등급과 file:line 인용은 전부 services/x.mdtopics/*.md에 있고, 여기서는 반복하지 않는다.

    읽은 것

    • xai-org/x-algorithm (2026-01-20 aaa167b, 2026-05-15 e414c17·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. 1세대와 2세대 사이 26개월 공백, 2세대는 삭제가 0건. 2023 파일 집합이 2025의 진부분집합이다. → 레포에 파일이 있다는 게 현역이라는 뜻이 전혀 아니다. 폐기는 README 한 줄을 바꾸는 방식으로만 드러난다.
    2. "인네트워크 50:50"은 코드에 없다. 2026엔 배분기 자체가 없고, OON은 쿼터가 아니라 점수 배수(effective_oon)로 조절된다. 배분 문제가 랭킹 문제로 이사했다.
    3. xai-org/x-algorithm은 빌드되지 않는다. Cargo.toml 0개, crate::params/util/clients 통째 부재. 60개 파일이 params를 참조하는데 정의가 없다 — 로직의 형태만 공개하고 값과 배선은 뺐다. 우연이 아니라 일관된 설계다.
    4. README가 지목하는 스코어러 3개가 모듈 트리에서 끊겨 있다. 진짜 배선은 vec![phoenix_scorer, ranking_scorer, vm_ranker]. 죽은 파일 11개를 목록으로 확정했고, models/ vs candidate_pipeline/ 이중 레이아웃이 세대 차이 판별법이라는 걸 찾았다.
    5. 가중치 값은 어느 세대에도 1차 출처가 없다. 널리 인용되는 "reply 13.5 / report −369" 표는 블로그가 아니라 the-algorithm-ml의 README이고, 문서 스스로 "2023-04-05 기준, 언제든 바뀔 수 있다"고 못박는다. 2025 Scala는 ModelWeights 30개를 전부 default = 0.0으로 지웠다 (같은 파일 나머지 203개 default는 실제값을 가진다 — 스타일이 아니라 의도적 삭제).

    부수적으로: has_cached_posts 하나가 모든 소스·하이드레이터·Phoenix를 끄는 최대 스위치라는 것, PreviouslySeenPostsBackupFilter가 영구 no-op이라는 것, VMRanker 실패가 로그 없이 삼켜져 다양성이 조용히 사라진다는 것, grox/ 파이썬 두 파일이 리터럴 치환 때문에 import 자체가 안 된다는 것.

    검증에서 뒤집힌 것 (중요)

    초안을 verifier로 되짚었더니 결론 하나가 반대로 나왔고, 상수 인용 규칙 하나를 새로 배웠다.

    • 뒤집힘: "2025 tweet-mixer의 u2i 후보는 상한 절단 뒤에 붙어 특혜를 받는다"는 틀렸다. DropMaxResultsresult만 자르고 remainingCandidates를 남겨서 u2i는 꼬리에 놓이는데, 그 뒤 최종 절단선이 400(라이트랭커 상한 500보다 작다)이라 앞이 다 차면 u2i가 먼저 사라진다. 절단선을 하나만 보고 결론내면 방향이 반대로 나온다.
    • 새 규칙: grep으로 나온 숫자를 프로덕션 값으로 쓰면 안 된다. 세 가지 함정이 다 실재했다 — ① args.int(name, default)의 default(SimClusters maxNeighbors 코드 400 vs 같은 파일이 적어둔 프로덕션 명령 --maxNeighbors 100, maxEpochs 3 vs 4) ② 벤치마크·warmup 리터럴(HNSW efConstruction=200/maxM=16experimental/Runner.scala의 장난감, ef=800warmup() 안) ③ 모듈 트리에서 끊긴 파일의 상수(2026 죽은 스코어러의 p::AUTHOR_DIVERSITY_DECAY).
    • 수확: 2026 offset_score가 2025 RerankerUtil.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/dedup
    • topics/embedding-retrieval.md 신규 — SimClusters·TwHIN·two-tower·ANN 인덱스

    다음에 볼 것

    • EU DSA 투명성 보고서 — 가중치 실값이 규제 제출 문서에 있는지. 오늘 못 봤다.
    • e414c17(2026-05-15) 디프 — Phoenix 헤드가 19→22로 늘어난 시점이 여기인지
    • Meta 쪽 착수 (Instagram / Facebook / Threads) — 엔지니어링 블로그부터. X와 달리 코드가 없으니 근거 등급 관리가 더 중요해진다.