잘 돌던 수집기를 갈아엎었다 — 폴링에서 이벤트 기반으로
1시간마다 Jira·Confluence를 통째로 폴링하던 수집을 버리고, 변경이 일어난 순간만 잡아채는 이벤트 기반 구조로 다시 만든 이유. 도구부터 갈아타려다 멈추고, 두 번의 재시작을 거친 사내 LLM 위키 재구축기의 시작입니다.
지난 시리즈에서 사내 지식 위키를 한 번 완성했습니다. 1시간마다 Jira·Confluence를 긁어 synced/에 미러하고, LLM으로 요약해 위키를 만드는 구조였죠. 잘 돌았습니다. 그런데 얼마 지나지 않아, 그걸 통째로 갈아엎기로 했습니다.
이 글은 왜 멀쩡히 돌던 수집기를 버렸는지, 어떤 유혹에 잠깐 흔들렸는지, 그리고 두 번의 재시작 끝에 무엇으로 바꿨는지에 대한 이야기입니다.
우리가 만들려는 그림
먼저 팀 환경을 짚고 가겠습니다. 팀원들은 각자 노트북(맥북)으로 일하고, 팀에는 상시 켜져 있는 데스크탑 서버 한 대가 있습니다. 위키의 두뇌는 이 서버에 두고, 팀원들은 슬랙을 통해 그 지식을 꺼내 쓰는 그림을 그렸습니다. 개인 장비마다 뭔가를 설치하는 방식이 아니라, 서버 한 곳에 지식을 모으고 누구나 슬랙으로 접근하는 구조죠.
이 그림에서 가장 중요한 부품은 결국 **"Jira·Confluence의 변화를 얼마나 정확하게, 얼마나 빨리 따라가느냐"**였습니다. 그리고 바로 그 부품이 문제였습니다.
폴링의 한계가 보이기 시작했다
기존 방식은 **폴링(polling)**이었습니다. 1시간마다 "그동안 뭐 바뀐 거 있어?" 하고 Jira·Confluence 전체를 훑는 거죠. 처음엔 단순해서 좋았는데, 쓰다 보니 걸리는 게 하나둘 늘었습니다.
- 매번 전체를 훑는 낭비: 실제로 바뀐 건 문서 몇 개인데, 그걸 확인하겠다고 매시간 수천 건을 스캔합니다. 대부분은 지난번과 똑같은 문서를 다시 읽는 헛일입니다.
- 반영이 느리다: 방금 수정한 문서가 위키에 반영되려면 다음 폴링까지 최대 1시간을 기다려야 합니다. "위키가 최신"이라는 신뢰가 그만큼 흐려집니다.
- 삭제를 못 잡는다: 폴링은 "지금 있는 것"만 봅니다. 누가 페이지를 지우면, 그 사실 자체를 알아챌 방법이 마땅치 않았습니다.
특히 세 번째가 컸습니다. 지식 베이스는 더해지는 것만큼 지워지는 것도 정확히 따라가야 신뢰가 유지됩니다. 이미 없어진 문서를 근거로 답하는 위키만큼 위험한 것도 없으니까요. 그런데 폴링은 삭제를 구조적으로 놓치고 있었습니다.
첫 번째 유혹: 도구부터 갈아타기
한계가 보이자, 처음엔 판을 크게 뒤집고 싶었습니다. 아예 그래프 기반 위키 도구로 갈아타고, 팀 서버에 로컬 LLM 에이전트(오픈소스 Hermes 계열)를 얹어 근본부터 새로 짜는 구성이었죠. 새 도구들은 화려했고, "이참에 최신 스택으로"라는 마음이 들었습니다.
그런데 검토를 이어갈수록 뭔가 어긋났습니다. 새 도구를 붙여 봐도 그림이 이상했습니다. 한참을 붙들고 있다가 깨달았습니다 — 문제는 위키 도구가 아니라 **데이터가 흘러드는 방식(폴링)**에 있었는데, 저는 엉뚱하게 도구만 바꾸고 있었던 겁니다.
그래서 방침을 하나 세웠습니다. "도구부터 바꾸지 말자." 병목의 진짜 위치를 고치지 않은 채 스택만 갈아타면, 새 스택 위에서 같은 문제를 다시 만날 뿐이었습니다. 화려함보다 순서가 먼저였습니다. (로컬 에이전트는 버린 게 아니라, 나중에 '소비' 단계에서 제대로 쓰게 됩니다. 이 시리즈 마지막 글에서 다룹니다.)
발상의 전환: "묻지 말고, 알림을 받자"
방향을 다시 잡으니 답은 단순했습니다. 우리가 매시간 물어볼 게 아니라, 바뀔 때마다 저쪽에서 알려주게 하면 됩니다. 폴링(pull)이 아니라 이벤트(push)죠.
마침 Jira·Confluence에는 변경을 알려주는 앱 알림 기능이 있었습니다. 이슈가 생기거나 바뀌거나 지워지면 알림을 쏴 주는 것. 이걸 받아서 변경이 일어난 그 순간, 그 문서만 처리하면 세 가지 한계가 한꺼번에 풀립니다. 전체 스캔이 사라지고, 반영이 거의 실시간이 되고, 삭제 이벤트도 똑같이 하나의 알림으로 들어옵니다.
두 번째 재시작: 백업하고, 비우고, 다시
방향이 정해지자 과감하게 정리했습니다. 사실 한 번은 새 방식으로 손을 댔다가 "이것도 그림이 이상하다" 싶어 통째로 되돌린 적도 있습니다. 어설프게 얹기보다, 깨끗한 바닥에서 다시 세우는 게 낫다고 판단했습니다.
- 지금까지의 작업을 백업 브랜치에 통째로 보존합니다(되돌릴 여지는 남긴다).
main은 빈 리포로 비우고, 새 골격을 처음부터 세웁니다.- 생성물(
raw/·wiki/같은 산출물)은 버전 관리에서 제외(gitignore)합니다 — 코드와 데이터를 섞지 않는다.
멀쩡한 걸 지우는 건 늘 겁납니다. 백업 브랜치를 남겨 둔 것도 그래서였습니다. 하지만 "고쳐 쓰기"보다 "다시 세우기"가 나은 순간이 분명히 있습니다. 부품 하나가 아니라 구조 자체를 바꾸는 결정이라면 더욱 그렇습니다.
새 그림
새로 잡은 전체 흐름은 이렇습니다.
수집기가 변경을 잡아 5분 버킷에 쌓고, 봉인된 버킷을 에이전트가 소비해 위키를 만드는 흐름입니다. 각 단계마다 나름의 함정이 있었고, 그 함정을 하나씩 넘는 게 이번 시리즈입니다.
정리
- 문제의 위치를 착각하지 말자 — 병목은 위키 도구가 아니라 **수집 방식(폴링)**이었다.
- 도구부터 갈아타지 말고, 데이터가 흐르는 방식을 먼저 고친다.
- 폴링(pull)을 이벤트(push)로 — 바뀐 것만, 실시간으로, 삭제까지.
- 구조를 바꿀 땐 백업하고 비우고 다시 세우는 게 오히려 빠른 길일 수 있다.
다음 글에서는 첫 관문 — 슬랙을 데이터 파이프라인으로 삼아 변경을 잡아채는 수집기부터 만듭니다.