TechBlogHub 개편기 — 방치하던 서비스를 다시 운영하기 위해
TechBlogHub는 국내 IT 기업의 기술 블로그를 한곳에서 모아보고 싶어서 만든 서비스입니다. RSS로 글을 수집하고 AI로 요약과 태그를 생성한 뒤 검색과 필터를 붙였습니다. 개발하면서 시도한 내용은 이 블로그에도 몇 차례 기록했습니다.
그런데 어느 순간부터 서비스에 손이 잘 가지 않았습니다. 서버비를 줄이기는 했지만 여전히 방치하고 있었습니다. 기존 서비스와의 차별점도 애매했고 무엇을 더 만들어야 할지도 명확하지 않았습니다.
그래서 이번에는 techbloghub-v2라는 새 저장소에서 전면 개편을 시작했습니다.
현재 배포된 버전은 TechBlogHub v2 바로가기에서 확인할 수 있습니다. 아직 개편 중이고 검색과 수집 품질을 계속 다듬고 있습니다.
무엇을 잘하는 서비스로 만들 것인가
우선 이 서비스를 누가, 어떤 상황에서 쓰면 좋을지부터 다시 정했습니다.
다른 기업에서는 Kafka를 어떻게 도입했을까?
MSA로 전환하면서 어떤 문제를 겪었을까?
이런 질문이 생겼을 때 국내 기업의 실제 경험이 담긴 글을 찾을 수 있으면 좋겠다고 생각했습니다. 이번 개편에서는 검색 결과가 읽을 만한 원문을 잘 찾아주는 것을 우선으로 두기로 했습니다.
운영 구조를 바꾸기
기존 서비스에서는 Next.js 프론트엔드가 FastAPI를 통해 데이터를 조회하고 PostgreSQL에 글과 본문, 처리 상태를 저장했습니다. 수집 작업도 FastAPI 런타임 안의 APScheduler가 실행했습니다.
개편 전 — 목록·검색 조회가 API 서버와 데이터베이스의 가용성에 연결돼 있었습니다. 그림을 누르면 확대 가능한 도면이 열립니다.
v2에서는 Astro와 Pagefind를 이용하는 정적 검색 구조로 옮겼습니다. 크롤러는 GitHub Actions에서 주기적으로 실행하고 수집한 데이터는 Cloudflare D1에 저장합니다. 이 데이터로 사이트와 검색 인덱스를 만들고 검증을 통과한 결과물을 Cloudflare Pages에 배포합니다.
개편 후 — 수집·빌드·배포와 사용자 검색을 분리했습니다. 검색 관측 이벤트는 별도 경로로 Pages Worker를 거쳐 관측용 D1에 집계합니다.
| 구분 | 기존 | v2 |
|---|---|---|
| 웹 화면 | Next.js | Astro 정적 사이트 |
| 검색 실행 | FastAPI를 통한 서버 조회 | Pagefind 인덱스로 브라우저에서 실행 |
| 원문 수집 | FastAPI 런타임의 APScheduler | GitHub Actions에서 주기적으로 실행 |
| 데이터 저장 | PostgreSQL | Cloudflare D1 |
| 검색 데이터 갱신 | 서버가 저장된 데이터를 조회 | 수집 후 인덱스를 다시 빌드·검증·배포 |
| AI 요약 | 상세 화면에서 제공 | 초기 개편 범위에서 제외 |
사용자가 검색할 때마다 API 서버와 데이터베이스에 요청하는 대신 미리 만들어둔 인덱스로 검색합니다. 초기에는 비용을 거의 들이지 않고 운영하는 것을 목표로 잡았습니다. 그 대신 새로 수집한 글은 다음 빌드와 배포를 통과해야 검색에 반영됩니다.
위 그림은 개편 전후의 핵심 구조를 비교한 도면입니다. 아래에서 설명할 MCP는 아직 도입 예정이라 현재 도면에는 포함하지 않았습니다. 도면은 Archify로 작성했습니다.
RSS를 모으는 것과 검색할 원문을 만드는 것은 달랐다
v2 초기 구현을 확인해보니 RSS에 들어 있는 짧은 요약을 본문처럼 저장하고 있었습니다. 검색에 넣을 데이터부터 고쳐야 했습니다. 기업이 특정 기술을 도입한 이유나 운영 중 겪은 문제는 대개 원문 안에 있는데 RSS만으로는 그 내용을 충분히 검색하기 어려웠습니다.
그래서 RSS는 글 주소를 발견하는 용도로 사용하고 본문은 원문 페이지에서 다시 추출하도록 바꿨습니다. 일반 HTTP 요청으로 처리할 수 있는 글은 가볍게 수집하고 브라우저 렌더링이 필요한 글에만 Playwright를 제한적으로 사용했습니다.
검색이 된다고 좋은 검색은 아니었다
검색도 붙였다고 끝나지는 않았습니다. 실제 검색어로 상위 결과를 평가했을 때 처음에는 관련성이 부족한 글이 꽤 섞여 있었습니다. 초기 평가에서 평균 P@5는 0.56이었습니다.
P@5(Precision@5)란?
검색 결과 상위 5개 중 검색 의도에 맞는 글의 비율입니다. 5개 중 4개가 관련 있는 글이라면 P@5는 0.8(80%)입니다. 이 글의 수치는 여러 검색어에서 측정한 P@5의 평균입니다.
검색 결과가 좋아졌다는 인상만으로는 변경 전후를 비교하기 어려웠습니다. 검색 로직을 바꿀 때마다 무엇이 좋아지고 나빠졌는지 확인할 기준이 필요했습니다. 그래서 이 서비스에서 찾고 싶은 기업의 도입 사례, 운영 경험, 장애 대응을 중심으로 검색어를 정했습니다. 같은 질문으로 반복 평가하는 방식부터 만든 셈입니다.
현재 평가셋은 Kafka 도입 사례, MSA 전환 문제, API 성능 개선 같은 고정 검색어 27개입니다. 검색어마다 찾으려는 의도와 관련·비관련 문서 목록을 기록하고 실제 브라우저 검색의 상위 5개 결과를 이 목록과 비교합니다.
2026년 9월 7일 수정본 기준으로 검색어–문서 조합 246건에 관련 172건, 비관련 74건의 판정이 저장돼 있습니다. 문서 중복을 제외하면 215개입니다. 같은 글도 질문에 따라 판정이 달라질 수 있습니다.
관련성은 원문이 해당 검색 의도에 실질적으로 답하는지를 기준으로 검토합니다. 검색어별로는 아래 기준을 적용했습니다.
| 검색어 | 관련으로 보는 내용 | 제외하는 내용 |
|---|---|---|
| Kafka 도입 사례 | 기업이 Kafka를 선택한 이유와 운영에서 얻은 교훈 | 사용 기술 목록에 Kafka만 언급 |
| CI/CD 배포 자동화 | 배포 파이프라인을 실제로 자동화한 구현 | 문서 생성만 자동화한 사례 |
| 데이터베이스 마이그레이션 경험 | 운영 환경에서 실행한 DB 이전 사례 | 방법론 발표나 실습 튜토리얼 |
평가 프로그램은 저장된 판정으로 P@5를 계산합니다. 태그가 같거나 검색 점수가 높다는 이유만으로 정답을 붙이지는 않습니다. 새 글이 상위 결과에 들어왔는데 판정 기록이 없으면 미판정으로 남깁니다.
현재 검색 품질 검사를 통과하려면 27개 검색어의 결과를 모두 평가할 수 있어야 합니다. 결과가 없는 검색어가 없어야 하고 평균 P@5도 0.75 이상이어야 합니다.
한국어와 영문 동의어를 보강하고 제목뿐 아니라 본문에 검색 의도에 맞는 내용이 있는지도 반영하면서 같은 평가셋에서 0.70까지 개선했습니다. 이후 평가 검색어를 늘린 별도 실험에서는 0.7100에서 0.8074로 개선됐습니다. 평가 대상이 달라진 만큼 두 실험의 수치를 하나의 연속된 성과로 묶지는 않으려고 합니다.
27개 검색어만으로 실제 사용자의 다양한 질문을 대표하기는 어렵습니다. 같은 검색어의 결과를 보며 검색 로직을 조정했기 때문에 그 질문들에만 잘 맞아졌을 가능성도 있습니다.
판정 기준도 검색어별 짧은 메모에 의존합니다. 예를 들어 레디스 캐시 전략은 로컬·분산 캐시 전략까지 관련 범위에 포함하고 있어 다른 검색어보다 기준이 넓습니다.
개발 과정에는 AI 에이전트가 원문을 검토해 판정을 추가한 작업도 있었습니다. 운영 문서는 사람의 검토와 애매한 사례의 재검토를 요구합니다. 하지만 평가셋에는 개별 판정마다 검토자와 본문 근거를 일정한 형식으로 기록해두지 않았고 여러 평가자의 판정 일치율도 기록돼 있지 않습니다.
이 점수가 말해주는 범위
평균 P@5가 약 0.8이라는 것은 이 평가셋과 판정 기준에서 상위 결과의 관련 비율이 약 80%였다는 뜻입니다. 모든 검색어에 대한 정확도가 80%라는 의미로 해석할 수는 없습니다.
검색어별 포함·제외 기준을 더 구체적으로 적고 판정 근거와 검토 이력을 남기려 합니다. 검색 개선에 사용하지 않은 별도의 평가 질문과 실제 사용 중 발견한 질문으로도 확인해야 합니다. 지금의 평가셋은 검색을 바꿨을 때 결과가 나빠지는지 반복 확인하는 첫 기준으로 사용하고 있습니다.
자동화에서 성공의 기준을 다시 정하기
수집 대상을 늘리면서는 운영 문제도 드러났습니다. 새 글이 올라오지 않았을 뿐인데 장애 알림이 뜨기도 했고 브라우저 실행 한도를 앞쪽 출처에서 소진해 뒤쪽 출처의 수집이 어려워지기도 했습니다. 같은 글이 Medium 주소와 기업의 자체 도메인 주소로 각각 저장되는 중복도 있었습니다.
이런 문제를 하나씩 정리하면서 자동화에서 무엇을 성공으로 볼지 다시 정했습니다. 새 글이 없는 날도 정상일 수 있습니다. 수집에 성공했더라도 배포 전에 확인할 일이 남아 있었습니다.
새 글이 검색 상위에 들어왔는데 아직 관련성을 평가하지 못했다면 기존 배포를 유지하고 검토를 기다리도록 했습니다. 자주 들여다보지 못하더라도 수집은 이어가고 사람의 판단이 필요한 지점은 확인할 수 있도록 다듬고 있습니다.
다음 단계: AI가 찾아 읽을 수 있도록 MCP 도입하기
이제 AI가 TechBlogHub에 모인 글을 찾아 읽을 수 있도록 MCP 도입을 준비하고 있습니다.
사람이 웹사이트에서 검색하는 흐름에 더해 AI에게 “국내 기업의 Kafka 운영 사례를 찾아 비교해줘”라고 요청했을 때도 TechBlogHub에서 자료를 찾도록 만들려 합니다.
현재 설계에는 세 가지 도구를 두었습니다.
list_companies: 검색할 기업과 블로그 확인find_articles: 질문과 관련된 글 검색get_article: 선택한 글의 수집된 본문 조회
AI가 필요한 글을 고르고 본문을 읽은 뒤 원문 링크를 근거로 답변하는 흐름을 생각하고 있습니다. 웹사이트와 같은 검색 데이터와 정렬 기준을 사용하도록 설계했습니다. 그동안 개선한 검색 품질도 함께 활용하려고 합니다.
원문 수집은 기존 크롤러가 계속 담당합니다. MCP는 그 위에서 AI가 수집된 자료를 검색하고 읽을 수 있는 읽기 전용 인터페이스로 시작할 예정입니다. 검색 당시의 글과 본문 조회 시점의 데이터가 달라지는 경우도 구분할 수 있도록 설계하고 있습니다.
MCP는 아직 도입을 준비하는 단계입니다. 우선 수집과 검색을 안정적으로 운영하고 그 위에 AI가 접근할 수 있는 경로를 붙여보려 합니다. 사람이 직접 찾아 읽을 때도 AI와 함께 자료를 조사할 때도 쓸 수 있는 서비스로 만들어보려고 합니다.