sgkstudio.
엔지니어링

설정 추가했는데 반영 안 됨 — 하드코딩 사본이 3주간 감춘 리포트 섹션

「설정 추가했는데 반영 안 됨」의 원인은 설정을 읽는 쪽이 아니라 결과를 내보내는 쪽이었습니다. 2026년 7월 21일에 분야 하나를 설정 파일에 넣었는데 그 뒤 3주 넘게 자동 리포트 8개 파일 어디에도 해당 섹션이 없었습니다. 우리가 처음 세운 가설은 「그 분야는 시장에 신호가 없다」였고, 분류 함수만 따로 돌려 보자 7건이 잡히며 그 가설이 깨졌습니다. 분류는 설정 파일을 그대로 훑는데 출력은 이름 5개를 손으로 적어 둔 사본을 보고 있었습니다.

2026-09-06자동 요약 리포트 8개 파일 전수 검색 — 해당 섹션 출력 0건 (2026년 7월 21일 추가 이후 3주간)분류 함수 단독 실행 실측 — 7건 매칭, 최고 점수 14.1, 5개 분야 중 볼륨 3위검색어 정리 실측 17,975건 · 죽은 조합 7개 제거 · 본문 확보율 8일 추적 2.8% → 3.8%

매일 도는 리포트에서 주력 서비스 섹션만 3주째 비어 있었다

우리는 네이버 블로그·카페와 스레드에 올라온 글을 매일 자동으로 모읍니다. 글마다 점수를 매기고 사업 분야별로 갈라, 하루 한 장짜리 요약 리포트를 만듭니다. 홈페이지 제작과 챗봇 구축과 블로그 운영을 파는 회사라서, 그 세 가지를 찾는 사람이 어디서 무슨 말을 하는지가 우리에게는 영업 목록 그 자체입니다.

리포트 한 장은 분야별 섹션이 세로로 이어진 형태입니다. 섹션 제목 옆에는 그날 걸린 신호 개수가 붙고, 그 아래에 글 제목과 점수가 나열됩니다. 아침에 그 한 장만 읽으면 어제 시장이 어느 쪽에서 시끄러웠는지 알 수 있게 만든 물건입니다. 읽는 사람이 한 명뿐이라 화면에 없는 항목은 존재하지 않는 항목과 같습니다.

그 분야를 담당하는 분류 항목은 2026년 7월 21일에 설정 파일에 넣었습니다. 넣는 작업 자체는 몇 분이면 끝납니다. JSON 파일에 분야 이름과 키워드 묶음을 적으면 그만입니다. 그런데 그날 이후 나온 리포트 어디에도 그 섹션이 없었습니다.

처음에는 이상하다고 보지 않았습니다. 신호가 안 잡히면 섹션도 비는 쪽이 자연스럽다고 읽었기 때문입니다. 리포트는 매일 정상으로 나왔고 오류 메시지는 한 줄도 없었습니다. 실패한 작업은 눈에 띕니다. 실패하지 않고 조용히 빠지는 작업은 눈에 띄지 않습니다.

이 상태가 3주 넘게 이어졌습니다. 그동안 수집과 점수 계산에 들어간 매일치 연산은 그대로 나갔는데, 정작 우리가 팔려는 세 가지 서비스의 수요 신호만 화면에 오르지 못한 셈입니다. 같은 기간 우리는 다른 분야 섹션만 읽으면서 「이쪽은 조용하구나」라고 결론을 내리고 있었습니다.

값 하나가 여러 군데에서 결정될 때 생기는 사고는 이번이 처음이 아닙니다. 같은 값을 물을 때마다 답이 달라졌던 기록은 여러 층에 흩어진 값 확인 기록에 따로 적어 두었습니다. 이번 글은 그 계열 중에서도 가장 조용한 형태, 즉 아무도 틀린 답을 말하지 않았는데 답 자체가 화면에 오르지 못한 경우입니다.

처음 잰 숫자 — 리포트 8개 파일 전수 검색에서 0건

먼저 잰 값은 「몇 번이나 나왔나」입니다. 측정 방법은 단순합니다. 그동안 쌓인 요약 리포트 마크다운 파일을 전부 열어 해당 섹션 제목을 문자열로 찾았습니다. 대상은 8개 파일이었고, 결과는 8개 파일 전부에서 0건이었습니다.

처음 잰 숫자 네 칸 — 리포트 8개 파일 중 섹션 출력 0건, 분류 함수 단독 실행 7건, 최고 점수 14.1, 5개 분야 중 볼륨 3위
처음 잰 숫자 — 출력은 0건인데 분류는 7건이었다

숫자로 정리하면 이렇습니다. 설정 파일에 항목을 넣은 날은 2026년 7월 21일, 이 측정을 한 날은 2026년 8월 6일입니다. 그 사이 만들어진 리포트 8개 파일 중 해당 섹션이 실린 파일은 0개입니다. 어쩌다 빠진 게 아니라 한 번도 실린 적이 없다는 뜻이라, 「그날그날 신호가 없어서 빠졌다」로는 설명이 붙지 않습니다.

여기서 이미 이상 신호가 하나 있었습니다. 확률 문제입니다. 하루치 신호가 우연히 0건일 수는 있지만, 8개 파일이 연달아 정확히 0건일 확률은 낮습니다. 다른 분야 섹션은 같은 기간 매일 채워져 나왔습니다.

측정을 시작한 계기도 적어 둡니다. 2026년 8월 4일까지 처리하기로 잡아 둔 항목이 3개 있었고, 그중 하나가 「이 섹션이 쓸모가 있는지 판정한다」였습니다. 그 항목이 2일 밀린 채로 남아 있어서 그날 열어 봤습니다. 판정하러 들어갔다가 결함이 나온 경우입니다.

세운 가설 — 그 분야는 시장에 신호가 없다고 봤다

가설은 두 개였고 둘 다 「데이터가 없다」 쪽이었습니다. 3주 동안 화면이 비어 있었으니 자연스러운 방향입니다.

  • 가설 A — 우리가 등록한 키워드 묶음이 시장에서 실제로 쓰이는 말과 어긋나 있다. 홈페이지 제작·챗봇·블로그 운영을 찾는 사람은 다른 단어를 쓴다.
  • 가설 B — 그 수요 자체가 우리가 모으는 채널에 거의 올라오지 않는다. 커뮤니티 글이 아니라 검색광고 쪽에서만 움직인다.

두 가설의 처방은 같았습니다. 검색어를 손보거나 채널을 늘리는 쪽입니다. 둘 다 며칠씩 걸리는 작업이고, 그중 채널 추가는 수집량이 늘어 차단 위험까지 함께 커집니다. 그래서 착수 전에 확인 한 번을 끼워 넣기로 했습니다.

확인 방법은 분류 함수만 따로 떼어 실행하는 쪽입니다. 리포트를 만드는 전체 과정을 돌리는 대신, 설정 파일을 읽어 분야를 맞춰 보는 함수 하나에 그날 수집분을 그대로 넣고 결과를 눈으로 봤습니다. 가설이 맞다면 결과는 0건이어야 합니다.

이 확인을 넣은 이유는 비용 차이입니다. 검색어 재설계와 채널 추가는 며칠짜리 작업인데, 함수 하나를 돌려 보는 일은 1분이면 끝납니다. 값이 싼 확인을 먼저 하는 순서가 이번 사건에서 3주를 더 늘리지 않은 유일한 이유였습니다.

가설은 어디에서 틀렸나 — 분류만 돌리니 7건이 잡혔다

결과는 0건이 아니라 7건이었습니다. 최고 점수는 14.1이었고, 5개 분야를 볼륨 순으로 세우면 이 분야가 3위였습니다. 데이터가 없어서 섹션이 빈 게 아니었습니다.

이 한 번의 실행이 두 가설을 동시에 죽였습니다. 키워드 묶음이 어긋났다면 분류 자체가 0건이었을 테고, 채널에 수요가 없었다면 점수를 매길 원본 글부터 없었을 겁니다. 둘 다 아니었습니다. 분류는 정상이었고 점수도 붙었습니다.

매칭 자체는 정상 동작해 실측이 「0 signals」가 아니라 「생성은 되는데 파일에 안 써짐」인 순수 코드 버그.

그러면 남는 경우는 하나입니다. 만들어지기는 하는데 파일에 안 써진다. 이 문장이 이번 사건의 요약입니다. 「0건이라 안 나온다」와 「나오는데 안 써진다」는 증상이 똑같이 생겼습니다. 화면에 아무것도 없다는 점에서 두 경우를 구별할 방법이 없습니다.

가설이 틀렸다는 사실보다 중요한 지점은 따로 있습니다. 두 가설 모두 「밖에 원인이 있다」고 가정했습니다. 시장이 조용하다, 채널이 다르다 — 둘 다 우리가 어쩌지 못하는 쪽입니다. 3주 동안 손을 대지 않은 이유가 게으름이 아니라 그 가정이었습니다. 밖에 원인이 있다고 믿으면 안쪽을 열어 볼 이유가 사라집니다.

진짜 원인은 무엇이었나 — 같은 목록이 두 벌로 갈라져 있었다

코드를 열어 보니 분야 목록이 두 군데에 있었습니다. 읽는 쪽과 쓰는 쪽입니다.

설정 파일을 훑는 분류 함수는 새 분야를 자동으로 잡지만, 리포트를 쓰는 함수와 주간 요약 반복문은 이름 5개를 적어 둔 사본을 봐서 새 분야가 출력 단계에서 탈락하는 흐름도
분류는 설정 파일을, 출력은 코드 안 사본을 봤다 — 이 어긋남이 사고의 기계적 원인이다

분류 함수는 설정 파일을 열어 그 안의 분야를 하나씩 돌면서 글을 맞춥니다. 설정 파일에 분야를 추가하면 그 사실만으로 분류 대상에 들어갑니다. 반면 리포트를 쓰는 함수와 주간 요약 반복문은 각자 분야 이름 5개를 문자열로 적어 둔 목록을 따로 들고 있었습니다. 새로 넣은 이름은 그 두 목록 어디에도 없었습니다.

수정 전에는 분야 이름 5개를 문자열로 적은 목록이 출력 함수와 주간 요약 두 곳에 각각 있었고, 수정 후에는 설정 파일에서 이름을 뽑는 함수 한 개를 두 곳이 함께 부르는 코드 비교
같은 목록 두 벌 vs 설정 파일 한 벌 — 수정 전후 코드

그래서 분류 결과 7건은 메모리 안에서 정상으로 만들어졌고, 출력 단계에서 「내가 아는 이름 5개」만 훑는 반복문에 걸려 그대로 버려졌습니다. 예외도 경고도 나지 않습니다. 반복문 입장에서는 아무 일도 일어나지 않았기 때문입니다.

정리하면 원인은 문법 오류나 잘못된 계산이 아닙니다. 같은 사실을 적어 둔 자리가 두 곳이고 한 곳만 갱신됐다는 사실 하나입니다. 설정 파일을 편집한 사람은 자기가 고친 파일이 유일한 정의라고 믿었고, 코드 안 사본의 존재를 몰랐습니다.

사본이 생긴 경위도 짚어 둘 만합니다. 처음 이 도구를 만들 때는 분야가 다섯 개로 고정이었고, 그 시점에는 이름을 손으로 적는 쪽이 읽기도 쉽고 순서도 마음대로 정할 수 있었습니다. 나중에 분야를 파일에서 읽도록 바꾼 쪽은 분류 함수뿐이었고, 출력 두 곳은 옛 형태로 남았습니다. 잘못 짠 코드가 아니라 한쪽만 자란 코드입니다.

왜 3주 동안 아무도 눈치채지 못했나

소리가 나지 않은 이유는 세 가지가 겹쳤습니다.

  • ① 실패가 아니라 누락이었다 — 오류 로그는 실패했을 때 남습니다. 이 사고는 실패하지 않았습니다. 리포트는 매일 정상 종료했습니다.
  • ② 증상이 정상 상태와 똑같이 생겼다 — 신호가 없는 날의 리포트와 신호를 버린 날의 리포트는 화면상 구별이 안 됩니다.
  • ③ 새로 넣은 항목이라 비교 대상이 없었다 — 원래 나오던 게 사라지면 눈에 띄지만, 처음부터 안 나온 항목은 「아직 그런 게 없구나」로 읽힙니다.

셋 중 세 번째가 이 사고를 3주로 늘린 결정적 요인입니다. 새로 추가한 기능에는 「아직 데이터가 안 쌓여서」라는 해명을 얼마든지 붙일 수 있습니다. 그 해명이 그럴듯한 동안 계측은 시작되지 않습니다. 반대로 어제까지 나오던 숫자가 오늘 0이 되면 누구든 그날 봅니다.

그래서 이 유형의 사고에는 시간 상한이 없습니다. 실패는 길어야 하루면 드러나지만, 누락은 누군가 그 항목을 일부러 찾을 때까지 이어집니다. 이번에는 「이 섹션이 쓸모 있나」를 판정하려고 열어 본 날이 그날이었을 뿐이고, 그 판정 항목이 없었다면 더 갔습니다.

비용도 무음입니다. 3주 동안 수집은 정상이었고 점수 계산도 정상이었습니다. 값은 매일 치렀는데 결과만 화면에 오르지 않았습니다. 아무것도 망가지지 않은 상태로 돈만 나가는 형태가 이 유형의 특징입니다.

같은 계열의 사고를 그 두 주 전에도 겪었습니다. 검색어 하나에 빗금이 들어가 있어서 저장 경로가 두 겹으로 갈라졌고, 그 바람에 점수 계산이 7일 동안 한 번도 돌지 않았습니다. 그때도 수집 자체는 정상이라 원본 글은 804건이 그대로 쌓였습니다. 망가진 쪽은 뒷단인데 앞단이 멀쩡해서 화면상 아무 이상이 없었습니다. 두 사고의 모양이 같습니다. 앞이 정상이면 뒤가 죽어도 소리가 나지 않습니다.

조치 — 최소 수정, 죽은 검색어 7개 제거, 수집량은 올리지 않기

그날 처리한 항목은 3개였습니다. 결함 수정이 하나, 검색어 정리가 하나, 그리고 「올리지 않기로 한 결정」이 하나입니다.

첫째, 출력 쪽 목록 두 곳에 빠진 이름을 넣었습니다. 구조를 바꾸는 대신 문자열 하나씩만 추가하는 최소 수정입니다. 구조 수리를 같은 자리에서 하지 않은 이유는 요청 범위 밖의 변경이었고, 표시 순서와 라벨을 어떻게 다룰지 따로 정할 사안이 남아 있었기 때문입니다. 대신 그 항목을 미해결로 명시해 남겼습니다.

둘째, 죽은 검색어를 정리했습니다. 8일치 수집분 17,975건을 대상으로, 50건 이상 모였는데 점수 8점 이상인 글이 한 건도 없는 조합을 골랐습니다. 7개가 나왔습니다.

제거한 검색어 7개 표 — 블로그의 AI 자동화 605건 0%, 검색광고 422건 0%, 앱 개발 대행 59건 0%, AB테스트 92건 0%, 카페의 CPC 111건 0%, 앱 개발 대행 89건 0%, 어플 개발 87건 0%
8일치 17,975건에서 뽑은 죽은 조합 7개 — 모으기는 하는데 한 건도 걸리지 않는다

판정은 채널별로 따로 했습니다. 같은 말이라도 채널이 다르면 결과가 갈렸기 때문입니다. 「AI 자동화」는 블로그에서 605건 중 0%였지만 카페에서는 1.7%가 걸려 살렸고, 「CPC」는 카페에서 111건 중 0%였지만 블로그에서 1.1%라 살렸습니다. 카페의 「AB테스트」는 39건이라 판정 하한 50건에 못 미쳐 보류했습니다.

배경을 조금 더 적으면, 2026년 7월 21일에 검색어 13개를 한꺼번에 넣으면서 「일주일 모아 놓고 걸리는지 본다」고 정해 두었습니다. 7일째인 2026년 7월 28일에 그 판정을 돌려 9개를 뺐고, 남은 것들도 성적이 좋지는 않았습니다. 이번 8일치 판정은 그 뒤에 다시 쌓인 분량을 같은 자로 잰 두 번째 회차입니다. 한 번 재고 끝내지 않는 쪽이 이 작업의 규칙입니다.

이 정리는 처음이 아닙니다. 2026년 7월 28일에도 같은 자로 9개 조합을 뺐고, 그때 아낀 호출이 한 번 돌 때마다 47회였습니다. 죽은 검색어를 그대로 두면 매 수집마다 값을 치르면서 아무것도 얻지 못합니다. 같은 날 확인한 참고값으로, 스레드 쪽 기존 검색어군은 14%에서 48%, 검색광고 쪽은 35%에서 37%가 걸립니다. 네이버 커뮤니티 쪽 최고값이 4.0%였으니 자릿수가 다릅니다.

셋째, 본문 확보율을 올리자는 안은 기각했습니다. 조치를 하지 않기로 한 쪽의 기록이라 마지막 절에 따로 적습니다.

재측정 결과 — 0건에서 7건으로, 그리고 목록을 한 벌로 합쳤다

수정 뒤 같은 날짜로 리포트를 다시 만들었습니다. 재생성한 파일 14번째 줄에 해당 섹션이 7건으로 찍혔습니다. 8개 파일 전부 0건이던 값이 처음으로 1건이 됐고, 그 뒤로는 매일 실립니다.

수정 전후 대조표 — 섹션 출력이 8개 파일 중 0건에서 재생성 파일 1건으로, 분류 결과 7건이 화면 0건에서 7건으로, 분야 정의 자리가 3곳에서 1곳으로, 회귀 검사가 0개에서 8개로
전후 대조 — 바뀐 값 네 줄

여기서 멈추지 않았습니다. 최소 수정은 이번 사고를 막았지만 다음 사고를 막지 못합니다. 목록이 여전히 두 벌이라, 다음에 분야를 하나 더 넣는 사람이 똑같이 걸립니다. 그래서 같은 날 구조까지 고쳤습니다.

고친 방식은 목록을 한 벌로 줄이는 쪽입니다. 설정 파일에서 이름을 뽑아 주는 함수 하나를 만들고, 출력 두 곳이 그 함수를 부르게 했습니다. 이제 정의는 JSON 파일 한 개뿐이고, 분야를 그 파일에 넣으면 그 사실만으로 리포트에 등장합니다. 표시 순서는 JSON 파일에 적힌 순서를 그대로 씁니다.

리팩터가 동작을 바꾸지 않았다는 확인은 산출물 비교로 했습니다. 같은 날짜로 만든 리포트를 수정 전후로 견주니 차이는 생성 시각 1줄뿐이었습니다. 주간 요약도 다시 돌려 분야 6개가 전부 실리는지 봤습니다. 직전까지는 5개였습니다.

마지막으로 회귀 검사를 새로 붙였습니다. 핵심 항목은 설정 파일에도 없고 예전 사본 목록에도 없는 새 이름을 넣은 다음, 그 섹션이 실제로 찍히는지 보는 쪽입니다. 이 검사가 그때 있었다면 이번 사고는 3주가 아니라 그날 잡혔습니다. 검사 8개가 모두 통과했고 기존 검사도 그대로 통과했습니다.

재측정에서 배운 점 하나를 덧붙입니다. 「고쳤다」의 증거로 코드 변경을 내밀면 안 됩니다. 이번에 증거로 쓴 값은 재생성한 파일의 14번째 줄에 실제로 찍힌 7건, 그리고 주간 요약에 실린 분야 6개입니다. 둘 다 화면에서 눈으로 셀 수 있는 값입니다.

회귀 검사를 붙이는 자리도 신경 썼습니다. 검사가 「이름 5개가 다 나오는지」를 보는 형태였다면 이번 사고를 못 잡습니다. 그 5개는 사고 당시에도 잘 나왔기 때문입니다. 잡으려면 검사 자체가 목록 밖의 새 이름을 만들어 넣어야 합니다. 검사를 쓸 때 중요한 부분은 개수가 아니라 「무엇이 실패해야 이 검사가 빨간불이 되나」를 한 문장으로 말할 수 있는지입니다.

남는 한계 — 본문 확보율은 여전히 3.8%다

고치지 않기로 한 쪽부터 적습니다. 모은 글 가운데 본문까지 확보한 비율은 8일 동안 이렇게 움직였습니다.

본문 확보율 8일 추적 꺾은선 — 2026년 7월 30일 2.8%에서 7월 31일 3.1%, 8월 1일 3.1%, 8월 2일 3.3%, 8월 3일 3.5%, 8월 4일 3.6%, 8월 5일 3.7%, 8월 6일 3.8%
8일 동안 2.8%에서 3.8%로 — 올랐지만 자릿수는 그대로다

2026년 7월 30일 2.8%에서 8월 6일 3.8%까지, 8일 동안 1.0%포인트 올랐습니다. 절대량으로 보면 하루 270건 안팎씩 꾸준히 늘고 있고, 늘지 않는 값은 비율뿐입니다. 전체 수집이 하루 4,500건씩 불어나니 분모가 더 빨리 커집니다.

확보량을 두 배로 올리자는 안(글 한 건당 20에서 40으로)은 기각했습니다. 절대 증가량이 이미 안정적이라 두 배로 올려 얻는 이득이 작고, 수집 부하가 커지면 차단 위험이 함께 커지기 때문입니다. 데이터 없이 배로 늘리는 결정은 근거가 부족하다고 봤습니다. 재평가는 2주 뒤인 2026년 8월 20일, 또는 비율이 둔화가 아니라 완전히 멈출 때로 잡았습니다.

기각한 이유를 조금 더 풀면 이렇습니다. 비율이 3.8%라는 값만 보면 낮아 보이지만, 우리가 실제로 쓰는 값은 비율이 아니라 확보한 글의 절대 수입니다. 그 수는 하루 270건 안팎으로 8일 내내 흔들리지 않았습니다. 비율이 안 오르는 이유는 확보가 느려서가 아니라 전체 수집이 하루 4,500건씩 더 빨리 늘기 때문입니다. 분모가 커져서 생긴 하락을 분자를 두 배로 늘려 덮는 결정은 값을 두 배로 치르고 같은 그림을 보는 쪽에 가깝습니다.

남는 한계는 세 가지입니다.

  • ① 본문 확보율은 3.8%대에 머뭅니다. 요약 분석의 깊이 상한이 그대로라는 뜻입니다.
  • ② 표시 순서가 이제 JSON 파일 편집에 딸려 움직입니다. 분야를 파일 중간에 끼워 넣으면 리포트 순서도 바뀝니다. 순서를 따로 정해야 할 일이 생기면 그때 순서용 키를 넣기로 하고, 지금은 넣지 않았습니다.
  • ③ 검색어 판정에는 하한이 있어 50건에 못 미친 조합은 판정을 미룹니다. 카페의 「AB테스트」 39건이 그 경우입니다.

남는 교훈 한 줄은 이렇습니다. 설정 파일에 값을 넣었다는 사실은 그 값이 쓰인다는 증거가 아닙니다. 넣은 다음 화면에서 그 값을 한 번 찾아보는 확인이 빠지면, 잘못은 실패가 아니라 침묵의 형태로 나타납니다. 3주라는 길이는 결함의 크기가 아니라 확인이 없었던 기간의 길이였습니다.

비슷한 수집·요약 파이프라인을 두고 있는데 화면에 안 보이는 항목이 있다면, 상담에서 그 항목이 실제로 몇 건 잡히는지부터 셉니다. 우리가 이번에 쓴 순서도 같습니다. 밖을 바꾸기 전에 값이 싼 확인을 먼저 하는 쪽입니다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.