AI 뉴스를 따라가 본 사람은 안다. 하루만 안 봐도 타임라인은 “역대급”, “게임 체인저”, “이제 다 끝났다”로 도배된다. 모델이 나오고, 벤치마크가 깨지고, 누군가의 워크플로가 “인생을 바꿨다”고 한다. 정보가 부족한 게 아니다. 신호 대 잡음 비(SNR)가 무너진 것이다.
나는 12년차 데이터 분석가다. 게임·이커머스·회계 도메인을 거치며 늘 같은 일을 했다 — 원천 데이터를 직접 수집하고, 의심하고, 교차검증한 다음에야 숫자를 믿는다. 그런데 정작 내 일과 가장 가까운 “AI 동향”은 남이 요약해 준 트윗과 블로그로 받아먹고 있었다. 그 요약들이 얼마나 부풀려져 있는지 알면서도.
그래서 만든 게 ai-news-digest다. 핵심은 두 문장으로 요약된다. 수집은 결정론적 코드에 맡기고, 요약과 검증은 판단(LLM)에 맡기되 그 둘을 분리한다. 그리고 “요약하는 에이전트”와 “검증하는 에이전트”를 다시 분리한다(maker ≠ checker). 이 글은 그 설계와, 만들면서 배운 것들을 정리한 것이다.
① 문제 — 뉴스는 넘치고, 요약엔 과장이 기본값이다
정보 과부하 자체는 새롭지 않다. 문제는 두 겹이다.
- 양: RSS만 해도 국내 뉴스, 글로벌 뉴스레터, arXiv, 커뮤니티, 공식 블로그까지 수십 개 소스. 매일 수백 건이 쏟아진다. 다 읽는 건 불가능하고, 다 안 읽으면 불안하다.
- 질: 요약과 블로그에는 과장이 기본값으로 끼어 있다. 흔한 패턴을 일반화하면 이렇다.
- 벤치마크 출처 세탁: “v6가 v5 대비 +4.6%p” — 그런데 자세히 보면 자체(in-house) 벤치마크다. 제3자 평가가 아니다.
- N=1을 법칙처럼: “이 규칙 하나 넣었더니 게임 체인저” — 표본 1개의 개인 경험담인데 보편 법칙처럼 쓰인다.
- 출처 없는 숫자의 전파: “오류율이 41%→11%로 줄었다더라” — 본문엔 없고, 어딘가 제3자 블로그가 만들어낸 미검증 수치가 인용의 인용으로 떠돈다.
- 제목과 본문의 간극: 제목은 “정중한 해명 요구”, 본문은 사실상 중대한 규제 사건. 제목은 “전 세계를 안전하게”, 실제론 인증된 일부에게만 제한 공개.
데이터 분석가에게 이건 익숙한 풍경이다. 출처를 안 밝힌 숫자, 표본 1개의 일반화, 제목과 데이터의 불일치. 평소 대시보드에서 잡아내는 바로 그 오류들이, AI 뉴스에선 무방비로 통과되고 있었다.
요약 도구는 이 문제를 못 푼다. 오히려 악화시킨다. 요약은 본질적으로 “압축”인데, 과장은 압축할수록 더 또렷해진다. 단정적인 문장일수록 요약에 살아남기 때문이다.
② 설계 원칙 — 결정론은 코드로, 판단은 LLM으로, 그리고 maker ≠ checker
해법의 출발점은 역할 분리였다.
수집은 판단이 아니다. “어떤 RSS를 긁어와서 중복을 제거하고 키워드로 점수를 매긴다” — 이건 100% 결정론적 작업이다. 같은 입력이면 같은 출력이 나와야 하고, LLM의 창의성이 끼어들 자리가 없다. 여기에 LLM을 쓰면 느리고, 비싸고, 무엇보다 재현 불가능해진다. 그래서 수집기는 의존성 0의 평범한 스크립트로 짰다.
요약과 검증은 판단이다. “이 50건 중 내 관심사는 무엇인가”, “이 주장은 본문과 일치하는가”, “이 숫자는 믿을 만한가” — 이건 맥락과 판단이 필요하다. LLM의 영역이다.
여기서 한 발 더 나간다. 요약하는 행위와 검증하는 행위를 분리한다(maker ≠ checker). 자기가 쓴 요약을 자기가 검증하면, 사람이든 모델이든 자기 글에 관대해진다. 그래서 수집기(maker, 코드)가 만든 raw 더미를 별도의 판단 단계(checker, LLM)가 원천을 직접 다시 열어보며 검증하게 했다. 요약을 만든 근거와 검증의 근거가 같은 곳(1차 출처)에서 나오되, 행위는 분리된다.
정리하면 파이프라인은 이렇다.
[수집기: 결정론적 코드] [요약/검증: 판단 LLM]
RSS/Discourse 수집 ┌─ 관심사로 큐레이션(요약)
→ dedup → 키워드 점수 ──► raw ─┤
→ 우선/일반 분리 └─ 1차 출처 직접 fetch → 적대적 팩트체크
→ YYYY-MM-DD_raw.md → YYYY-MM-DD.md (⚠️로 과장 분리)
③ 수집기 — 공개 피드만, per-feed 격리, 짧은 타임아웃
수집기는 Node 18+ 내장 fetch만 쓴다. 외부 패키지 0개. 이유는 단순하다. 이건 “내가 보고 싶을 때 그때 실행하는” 도구라, npm install이 끼면 그 마찰만큼 안 쓰게 된다. 의존성이 없으면 노드만 있으면 어디서든 돈다.
구독 소스는 FEEDS 배열 하나로 관리한다. RSS/Atom과 Discourse JSON을 둘 다 받는다(둘은 파서가 다르다).
const FEEDS = [
// priority: 내가 직접 챙겨보는 곳 — 시간 제한 없이 소스별 최신 N개 전부 노출
{ name: 'GeekNews', cat: '국내', priority: true, url: 'https://example.com/rss/news' },
{ name: 'Forum News', cat: '국내', type: 'discourse', priority: true,
url: 'https://forum.example.com/c/news/14.json' },
// 일반 소스: 최근 N시간 + 관심 키워드 매칭만
{ name: 'Newsletter A', cat: '뉴스레터', url: 'https://example.com/feed' },
{ name: 'arXiv cs.CL', cat: '논문', url: 'https://example.com/rss/cs.CL' },
// ... (실제 URL은 레포 참조)
];
// 제목+요약에 몇 개나 걸리는지 = 관심도 점수
const KEYWORDS = ['agent', 'mcp', 'rag', 'llm', 'automation',
'에이전트', '자동화', '크롤', '문서', /* ... */];수집 루프에서 가장 중요한 설계는 per-feed 격리다. 피드 하나가 죽어도(타임아웃, 403, 깨진 XML) 전체가 멈추면 안 된다. 그래서 모든 피드를 병렬로 돌리되, 각 피드를 try/catch로 감싸고 AbortController로 20초 타임아웃을 건다. 실패한 피드는 조용히 버리는 게 아니라, 출력 맨 아래 “수집 실패” 섹션에 이유와 함께 기록한다.
const ok = [], fail = [], all = [];
await Promise.all(FEEDS.map(async f => {
try {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 20000); // 한 피드가 전체를 잡아먹지 못하게
const res = await fetch(f.url, {
headers: { 'User-Agent': 'ai-digest', 'Accept': /* RSS or JSON */ },
redirect: 'follow', signal: ctrl.signal,
});
clearTimeout(t);
if (!res.ok) throw new Error('HTTP ' + res.status);
const items = f.type === 'discourse'
? parseDiscourse(await res.text(), f)
: parseRss(await res.text(), f);
all.push(...items);
ok.push(`${f.name} (${items.length})`);
} catch (e) {
fail.push(`${f.name} — ${e.message}`); // 죽어도 기록만, 전체는 계속
}
}));이 격리 패턴은 데이터 수집 파이프라인의 기본기다. 게임 로그를 여러 소스에서 모을 때도, 마케팅 지표를 여러 채널 API에서 당겨올 때도, 원칙은 같다 — 한 소스의 장애가 전체 적재를 멈추게 두지 않는다. 커뮤니티 RSS는 종종 일시적으로 429(레이트리밋)를 뱉는데, 격리가 없으면 그날 다이제스트 전체가 날아간다. 격리가 있으면 “그 피드만 오늘 실패”로 끝난다.
수집 후엔 결정론적 가공만 남는다.
- dedup: 링크(없으면 제목) 기준으로 중복 제거. 같은 기사가 여러 피드에 뜨는 일이 흔하다.
- 우선/일반 분리: 내가 매일 챙겨보는 priority 소스는 시간 제한 없이 소스별 최신 N개를 전부 보여주고, 나머지 일반 소스는 “최근 N시간 + 관심 키워드 매칭”으로 좁힌다.
- 키워드 점수 정렬: 제목·요약에 관심 키워드가 몇 개 걸리는지로 점수를 매겨, 관심도 높은 항목을 위로 올린다.
그리고 한 가지 원칙을 못 박았다. 쿠키·세션·인증 일절 사용 안 함. 카테고리 JSON과 RSS는 전부 공개 엔드포인트라 로그인이 필요 없다. 로그인이 필요한 데이터는 애초에 대상이 아니다. (혹시 세션 쿠키를 건네받더라도 저장하지도, 쓰지도 않는다.) 이건 편의가 아니라 안전 경계선이다. 공개된 것만, 가볍게.
⚠️ robots · 약관 · 레이트리밋. 자동 수집은 남의 서버 위에서 돈다. 나는 (1) 공식적으로 제공되는 공개 RSS/JSON 피드만 쓰고, (2) 각 서비스 약관과 robots.txt를 확인하며, (3) 짧은 타임아웃·병렬 상한·on-demand 실행(상시 폴링 아님)으로 상대 서버를 두들기지 않는다. 본문 검증 단계에서 어떤 사이트가 봇 접근을 막아 두면(403), 우회하지 않고 “본문 미확보”로 정직하게 표기하고 검색·외부 1차보도로 보강한다. 막아둔 문은 두드리지 않는다.
④ 요약 단계 — LLM이 “내 관심사”로 큐레이션한다
수집기는 일부러 멍청하다. 키워드 매칭은 “agent”가 “user agent”에도 걸리는, 둔한 1차 필터다. 그래서 raw 더미에는 진짜 관심사와 노이즈가 섞여 있다. 여기서 LLM이 등장한다.
요약 단계의 역할은 두 가지다.
- 큐레이션: raw를 읽고 내 관심 축(코딩 에이전트·하네스·MCP·문서 AI·지식관리·자동화·비용/정책·SEO 등)으로 추린다. 키워드는 못 잡는 맥락 — 예컨대 “이건 내 평문 볼트 철학과 직결된다” 같은 연결 — 을 LLM이 붙인다.
- 구조화: 추린 항목을 주제별로 묶고, 읽기 순서를 제안하고, 이미 어제 정리한 반복 항목과 순수 노이즈(밈·잡담)를 따로 빼낸다.
여기서 데이터/마케팅 관점이 들어간다. 큐레이션은 결국 개인화된 콘텐츠 추천이다. 같은 raw라도 게임 분석가, 회계 자동화 담당자, 마케터는 추려야 할 게 다르다. 키워드 점수가 “모두를 위한 거친 랭킹”이라면, LLM 큐레이션은 “나를 위한 재랭킹”이다. 이 두 층을 분리해 둔 덕분에, 관심사가 바뀌면 코드가 아니라 프롬프트만 바꾸면 된다.
⑤ 핵심 — 다중 에이전트의 적대적 팩트체크
여기가 이 도구의 심장이다. 요약만 하면 다른 요약 도구와 다를 게 없다. 차별점은 검증이다.
방식은 이렇다. 큐레이션된 항목들에 대해, 별도의 검증 에이전트들이 각 항목의 본문을 1차 출처에서 직접 fetch한다. 트윗이나 제3자 요약이 아니라, 원 기사·원 블로그·원 모델카드·원 논문을 직접 연다. 그리고 주장(claim)과 실제(본문)를 대조한다. 일종의 적대적 독해다 — “이 제목/요약이 본문보다 세게 말하고 있지 않은가?”를 의심하며 읽는다.
검증에서 걸러낸 것들은 본문에 녹이지 않고 ⚠️ 표시로 분리한다. 요약과 경고를 섞으면 둘 다 흐려지기 때문이다. 실제로 잡혔던 과장의 유형을 (특정 회사·실명 없이) 일반화하면 이렇다.
- “+X%p 향상” → 자체 벤치마크였다. 성능 향상 수치가 제3자 평가가 아니라 모델 제작사 자체 측정인 경우. 검증 노트: “X%p 개선은 모두 in-house 벤치마크(제3자 평가 아님).”
- “게임 체인저” → N=1 경험담이었다. 규칙 하나 추가로 극적 효과를 봤다는 글이 사실은 개인 사례 1건. 검증 노트: “‘게임 체인저’는 표본 1개 일화. 함께 떠도는 ‘오류율 41%→11%‘는 본문이 아니라 제3자 블로그의 미검증 수치.”
- “제목 ≠ 본문”. 제목은 “정중한 요청”인데 본문은 사실상 중대한 규제/금지 사건인 경우. 검증 노트: “제목보다 실제는 훨씬 무거운 사안 — 제목에 속지 말 것.” 반대로 “전 세계를 안전하게” 같은 제목이 실제론 “인증된 일부에게만 제한 공개”인 경우도 같은 부류다.
- “본문 fetch 차단” → 발췌 기반임을 명시. 사이트가 봇을 막으면(403) 검증 강도가 떨어진다. 이때 묻어두지 않고 “원문 미검증, 발췌 기반”이라고 신뢰 수준을 라벨링한다. 가능하면 같은 사건의 외부 1차보도로 교차확인한다.
- “무료가 유료를 이긴다” → 자기 사이트 유입형 홍보 톤. 단정 뒤에 정확도·프라이버시·한계 언급이 빠진 경우, 그 점을 짚는다.
이게 왜 maker ≠ checker여야 하느냐. 요약을 만든 주체가 검증까지 하면, 자기가 추려 올린 항목을 “내가 골랐으니 괜찮겠지”라며 봐준다. 검증을 독립된 적대적 단계로 떼어내야, “이 항목, 본문 보니 부풀려졌네”라고 자기 큐레이션을 깎아내릴 수 있다. 한 모델 안에서도 역할(프롬프트)을 분리하면 이 효과의 상당 부분을 얻는다. 핵심은 검증의 기준점이 요약문이 아니라 1차 출처라는 점이다.
결과물의 한 줄은 대략 이렇게 생겼다(실제 사건과 무관한 예시).
- ⭐ **[새 OCR 모델, 50개 언어 경량](https://example.com/...)** (소스, 날짜)
— 핵심 요약... *→ 내 문서 AI 파이프라인 OCR 후보.*
⚠️ "v5 대비 +4.6%p"는 모두 **자체 벤치마크**(제3자 평가 아님). 라이선스는 모델카드 확인 필요.별 하나(⭐)는 큐레이션이 매긴 중요도, 화살표(→)는 “이게 내 작업과 어떻게 연결되는가”, ⚠️는 검증이 떼어낸 과장. 읽는 사람이 1초 안에 “믿어도 되는 만큼”을 알 수 있게 신뢰 수준을 시각적으로 분리해 둔다.
⑥ 배운 점
피드 격리는 생각보다 훨씬 값지다. 처음엔 “그냥 try/catch 하나”였는데, 운영해보니 이게 도구의 생존을 갈랐다. 커뮤니티 RSS는 수시로 429를 뱉고, 어떤 피드는 URL이 조용히 바뀐다. 격리가 없으면 “오늘은 그냥 안 됨”이 되고, 안 되는 도구는 안 쓰게 되고, 안 쓰는 도구는 죽는다. 부분 실패를 견디는 설계가 곧 지속가능성이다. 그리고 실패를 숨기지 않고 “실패 피드” 섹션에 기록하니, URL 교체 시점도 자연히 잡힌다.
1차 출처 교차확인은 타협 불가다. AI 뉴스의 과장 대부분은 “인용의 인용” 과정에서 생긴다. A의 본문엔 없던 숫자가 B의 요약에서 태어나고 C의 트윗에서 단정이 된다. 이 사슬을 끊는 유일한 방법은 맨 앞으로 돌아가는 것 — 원 기사·원 모델카드·원 논문을 직접 여는 것이다. 데이터 분석에서 “집계된 리포트 말고 raw 테이블을 봐라”와 정확히 같은 원리다. 그리고 출처에 닿지 못하면(차단·소실) 그 사실 자체를 신뢰 라벨로 남긴다. 모르는 걸 아는 척하지 않는 게 검증의 절반이다.
결정론 코드와 판단 LLM의 분리가 비용·재현성·디버깅을 동시에 잡는다. 수집을 LLM에 맡겼다면 매 실행이 비싸고 느리고 매번 결과가 달랐을 것이다. 반대로 검증을 코드로 짜려 했다면 “이 주장이 과장인가”라는 본질적 판단을 규칙으로 못 박지 못해 실패했을 것이다. 결정론적인 일은 코드에, 판단이 필요한 일은 LLM에 — 이 경계를 정확히 긋는 것이 자동화 설계의 핵심이고, maker와 checker를 다시 나누는 건 그 위에 얹는 안전장치다.
마지막으로, 데이터 분석가이자 콘텐츠를 다루는 사람으로서 가장 크게 남은 생각. AI 시대의 정보 우위는 “더 많이 읽는 것”이 아니라 “덜 속는 것”에서 온다. 모델이 아무리 좋아져도, 출처를 의심하고 1차 자료로 돌아가 교차검증하는 습관 — 그건 내가 12년간 데이터로 해온 일 그대로다. 도구는 그 습관을 자동화했을 뿐이다.
마무리
ai-news-digest는 거창하지 않다. “AI 뉴스가 너무 많고, 요약엔 과장이 흔하다”는 흔한 불만에서 출발했다. 다만 해법의 모양이 데이터 분석가다웠을 뿐이다 — 수집은 결정론적 코드로 재현 가능하게, 큐레이션과 검증은 판단 LLM으로, 그리고 만드는 자와 검증하는 자를 분리해서. 그 결과 매일 아침 받는 건 “오늘의 헤드라인”이 아니라 “오늘의, 검증된, 나에게 연결된 신호”다.
정보 과부하는 끌 수 없다. 하지만 잡음과 과장에 휘둘리는 건 끌 수 있다. 그게 이 도구가 한 일의 전부이자 핵심이다.
관련 글·리포 (placeholder)
- 🔧 ai-news-digest 레포:
github.com/DBhyeong/ai-news-digest(공개 준비 중 — 공개되면 이 자리에 링크) - ✍️ 관련 글: 「파이썬으로 멀티엔진 연관검색어 긁기 — related_kws」 (수집 자동화의 다른 사례)
- ✍️ 관련 글: 「.srt 자막을 SEO 블로그로 자동 변환하기」 (LLM 콘텐츠 파이프라인)
면책: 이 도구는 공개 RSS/JSON 피드를 대상으로 한 정보 수집·정리 자동화다. 특정 모델·회사·인물에 대한 평가나 투자 권유가 아니며, 본문의 과장 사례는 실명·실제 회사를 특정하지 않은 일반화된 유형이다. 수집은 각 서비스의 약관·robots를 준수하고 인증·쿠키 없이 공개 엔드포인트만 사용한다.