축적되는 인텔리전스: 우리 AI 뉴스봇이 더 이상 잊지 않게 된 이유
AI SOTA Feed Bot은 하루 3번 돌아갑니다. 24개 소스를 스크래핑하고, 랭킹을 매겨서 상위 AI 뉴스를 보여줘요.
최근까지는 매 실행마다 이전 결과를 덮어쓰기 했습니다. 오전 9시 결과? 정오 실행 후 사라짐. 이 봇은 기억이 없었어요. 매번 새로 시작하는 구조였죠.
대시보드로는 괜찮아요. 그런데 “돌아보기”가 필요한 순간에는 치명적입니다.
휘발성 피드의 한계
실행 사이의 기록이 남지 않으면 기본적인 질문도 답하기 어렵습니다.
- 이번 주 AI 뉴스에서 진짜 큰 이슈는 뭐였나?
- 며칠 연속으로 계속 등장한 논문은 뭐였나?
- 지난달 흐름은 어땠나?
- 연말 회고에서 무엇을 근거로 뽑을 건가?
그리고 중요한 시그널도 사라져요. 8회 연속 등장한 아티클은 1회 등장한 아티클과 의미가 다릅니다. 누적 저장은 “등장 빈도”를 랭킹 신호로 바꿔줍니다.
그래서 Harry가 accumulation 레이어를 만들었습니다.
아키텍처: 스냅샷 + 중복 제거 + 시간 윈도우
실행마다 스냅샷 저장
파이프라인 종료 시 write_run_snapshot()이 호출돼서:
- 전체 결과를
data/processed/runs/<timestamp>.json에 저장 runs_index.json업데이트 (최신순, 최대 500개)
각 스냅샷에는 실행 시각, 아이템 개수, 아이템 배열(점수/요약/메타데이터)이 들어갑니다.
data/processed/
├── latest.json ← 하위 호환용 유지
├── runs_index.json ← 스냅샷 인덱스
└── runs/
├── 20260216-080057.json
├── 20260216-090315.json
├── 20260216-120003.json
└── ...
API가 시간 범위를 받음
/api/feed는 이제 from, to, limit 쿼리를 지원합니다.
/api/feed?from=2026-02-10T00:00:00Z&to=2026-02-16T23:59:59Z&limit=50
범위에 맞는 스냅샷만 골라서 병합합니다.
중복 제거 + 히스토리 유지
핵심은 accumulateItems() 함수예요. url + title 복합 키로 중복 제거를 하면서 아래 필드를 추적합니다.
first_seen: 처음 등장한 시각last_seen: 가장 최근 등장 시각seen_count: 몇 번의 실행에서 등장했는지
중복이 발견되면 최신 실행의 메타데이터를 우선 적용하되, 히스토리는 유지합니다.
결과는 last_seen 내림차순 정렬(최근 활성 아이템 우선)입니다.
이미 20개 실행만으로도 보이는 변화
누적 저장은 이제 막 시작됐고(현재 20개 스냅샷), 데이터가 아직 많진 않습니다. 그래도 시간 범위 조회가 벌써 유용해요.
- 최근 6시간 조회: 지금 뜨는 이슈만 확인
- 최근 48시간 조회: 반복 등장한 아이템이
seen_count로 드러남
앞으로 쌓이면(하루 3회, 주 21회, 월 약 90회) 데이터의 가치가 급격히 커집니다.
다음에 가능해지는 것
이건 기능 하나가 아니라 기반 레이어입니다.
주간 리캡
from=월요일, to=일요일로 조회해서 seen_count 기준으로 상위 정렬. 한 주 동안 15회 이상 등장한 이슈는 “그 주를 지배한 스토리”라고 볼 수 있어요.
월간 트렌드
약 90회 실행 데이터를 보면:
- 어떤 소스가 꾸준히 고품질 아이템을 공급하는지
- 어떤 카테고리(platform/release/research)가 오르내리는지
- 어떤 토픽(에이전트 엔지니어링, 추론 최적화, 신모델)이 강세인지
연말 회고
연말이면 약 1,000개 실행 스냅샷이 생깁니다. 이건 “느낌”이 아니라, 시계열 근거가 있는 2026 AI 회고를 만들 수 있는 데이터량이에요.
빈도 기반 시그널
seen_count는 지금도 강력한 신호입니다.
- 1회: 일회성 혹은 매우 최신
- 5~10회: 며칠간 꾸준히 언급
- 20회+: 주/월 단위 핵심 이슈
향후 랭킹에서 LLM relevance 점수와 함께 가중치로 쓰기 좋습니다.
지루하지만 중요한 운영 포인트
하위 호환
스냅샷이 없으면 API는 기존 latest.json으로 자동 폴백하고 seen_count: 1로 감싸서 반환합니다. 기존 소비자 안 깨집니다.
인덱스 상한
runs_index.json은 최대 500개로 제한됩니다. 하루 3회 기준 약 5.5개월 분량이에요. 인덱스만 순환하고 실제 스냅샷 파일은 남기기 때문에 복구 여지도 있습니다.
그레이스풀 디그레이데이션
인덱스가 잘리거나 깨져도 API는 runs/ 디렉터리에서 다시 읽어옵니다. 안전장치가 이중으로 들어가 있어요.
중요한 설계 선택
뉴스 피드는 보통 “최신만 보여줘”로 최적화되기 쉽습니다. 실시간, 항상 최신, 매번 교체.
근데 진짜 가치 있는 데이터 제품은 기억합니다. 과거를 잊는 분석 시스템은 트렌드를 못 보여주고, 과거를 덮어쓰는 피드는 “무엇이 중요했는지”를 말해줄 수 없습니다.
이번 변화 자체는 작아요. 함수 하나, 디렉터리 하나, 쿼리 파라미터 몇 개.
하지만 이걸로 봇의 성격이 바뀌었습니다. 단순 피드가 아니라, 시간축 위에서 누적되는 AI 변화 기록이 된 거예요.
코드 diff에서는 작아 보여도, 제품의 미래를 바꾸는 종류의 변경이었습니다.