35개 게시물에서 답글을 받지 못한 댓글 20개를 발견했습니다. 아무도 저에게 알려주지 않았습니다.
요약
개발자가 운영하는 예약 에이전트가 게시물 작성 및 게시 과정은 완벽했으나, '게시 후'의 댓글 관리(답글 처리) 단계는 설계되지 않아 누락된 작업들이 쌓이는 문제를 발견했습니다. 이 글은 시스템 오류로 나타나지 않는 '미처리 부채'를 찾아내는 방법과 이를 체계적으로 해결하는 코딩 기법을 제시합니다.
핵심 포인트
- 시스템의 사각지대(게시 후)에 발생하는 미처리 작업을 포착해야 합니다.
- 단순 댓글 목록이 아닌, 내가 답글을 달아야 할 '책임 영역'을 정의해야 합니다.
- 댓글 스레드는 재귀적 탐색(`children`)을 통해 깊은 곳까지 검사해야 합니다.
- 중복 처리를 위해 사이트 상태와 로컬 초안 파일을 모두 관리하는 것이 중요합니다.
저는 이 계정에 기사를 작성하고 게시하는 예약 에이전트를 운영하고 있습니다. 지난 6월 말부터 매일 두 번씩 작동해 왔고, 이번 주까지 저는 정말로 그 루프가 완벽하다고 믿었습니다: 작성, 게시, 끝. 그러다가 DEV.to API에서 관련 없는 무언가를 찾다가 GET /api/comments?a_id=...를 발견했습니다. 호기심에 모든 35개 게시물에 대해 이 코드를 실행해 보았습니다.
댓글 스무 개. 답글은 없습니다. 그중 일부는 6주 전의 것입니다.
아무것도 실패한 것이 없었습니다. 로그에는 오류가 없고, 충돌도 없으며, 어디에도 빨간 X 표시가 없었습니다. 게시 파이프라인은 몇 주 동안 자신이 설계된 대로 정확히 작동하고 있었습니다. 단지 '게시 후'에 일어나는 일에 대해서는 아무것도 하도록 설계되지 않았을 뿐입니다. 이 간극은 버그로 나타나지 않습니다. 왜냐하면 여기에 연결된 실패 모드가 없기 때문입니다. 답글을 받지 못한 댓글은 오류를 발생시키지 않고, 그저 거기에 놓여 있을 뿐이며, 시스템의 어떤 것도 그것이 거기에 있다는 사실을 저에게 알려줄 수 없었습니다.
이것이 'AI가 코드를 빠르게 작성한다'는 부분에서 잘 이야기되지 않는 부분입니다. 문제는 잘못 작성된 코드에 있는 것이 아닙니다. 아예 작성되지 않은 코드에 있습니다. 왜냐하면 출력을 생성하는 주체가 자신이 남긴 것을 감지할 메커니즘이 없기 때문입니다. 모든 게시물은 작고 보이지 않는 약속이었습니다 — '누군가 참여하면 나중에 돌아와서 처리하겠다'는 식의 약속이었죠 — 그리고 이 모든 약속들은 조용히 지불되지 않았습니다. 왜냐하면 '나중에 돌아오겠다'는 것이 루프의 단계에 포함된 적이 없었기 때문입니다. 이는 부채가 쌓이는 방식과 같습니다: 단 하나의 극적인 실패를 통해서가 아니라, 잔액을 확인하는 사람이 아무도 없는 상태를 통해 축적됩니다.
실제 빚 찾기
제가 처음 작성한 '답글 받지 못한 댓글 확인' 버전은 단순히 모든 댓글을 나열하는 스크립트였는데, 이것은 쓸모가 없습니다. 물론 댓글이 있다는 것은 게시물의 목적이니까요. 중요한 질문은 '내가 책임져야 할 것이 무엇인가?'이고, 이에 답하는 과정은 '개수 == 0'보다 덜 명확한 문제였습니다.
댓글 스레드는 저에게서 온 답글이 아닌 다른 사람들의 답글을 가질 수 있습니다. 제 답글이 맨 위에 있는 것이 아니라, 여러 레벨 깊이에 중첩된 자식 댓글 속에 묻혀 있을 수도 있죠. comment.replied는 DEV.to에서 제공하는 필드가 아닙니다. 직접 트리를 탐색해야 합니다:
ME = "enjoy_kumawat"
def replied_by_me(comment):
...
이것이 전체 검사입니다: children을 재귀적으로 순회하며, 서브트리 어디든 제가 나타나는지 확인하는 것입니다. 네 줄짜리 코드지만, 이 네 줄 덕분에 '댓글 목록'이 '제가 실제로 답글을 달아야 할 것들의 목록'으로 바뀝니다. 이것 없이는 스크립트는 이미 제가 마무리한 스레드에 대해 잔소리를 하거나, — 더 나쁜 것은 — 다른 사람이 답글을 달았지만 제가 한 적 없는 경우를 조용히 건너뛰게 될 것입니다. 왜냐하면 '누군가 답글을 달았다'는 주장은 '제가 답글을 달았다'는 주장과 같지 않기 때문입니다.
스크립트가 제대로 처리해야 했던 두 번째 부분은, 제가 빚을 갚기 시작한 후 같은 부채를 두 번 다시 표시하지 않는 것이었습니다. 저는 마크다운 파일에 답글 초안을 작성하고 수동으로 붙여넣습니다 — 왜 그런지 잠시 후에 더 설명할게요 — 따라서 '이미 처리됨'이라는 것은 '사이트에서 이미 답변됨'이 아니라 '이미 초안 파일에 있음'을 의미합니다:
def pending():
drafted = open(DRAFTS, encoding="utf-8").read()
out = []
...
두 개의 중복 제거 검사가 겹쳐져 있습니다: 사이트에서 이미 답변된 것은 건너뛰고, 그 다음으로 로컬에 이미 대기열화 된 것도 건너뜁니다. 이 둘 중 어느 하나라도 놓치면 스크립트는 영원히 잔소리를 하거나 같은 답글을 두 번 초안 작성하게 됩니다. 어떤 실패도 눈에 띄지 않습니다. 둘 다 결국 제가 일주일 안에 신뢰를 잃게 만드는 결과를 가져옵니다.
아무도 알아차리기 전에 왜 부채가 그렇게 커졌는가
솔직히 말해서, 게시물 발행 과정(publishing loop) 중 어느 것도 스스로 이 문제를 수면 위로 올릴 수는 없었습니다. 예약 실행(scheduled run)의 전체 계약은 '할당량 확인 → 트렌드 파악 → 작성 → 발행 → 기록'입니다. 댓글에 답글을 다는 것은 그 계약에 포함된 적이 없었기 때문에, 루프의 관점에서는 미답변 스레드가 20개든 0개든 똑같이 보입니다. 둘 다 그냥 이 시스템의 문제가 아니거든요. 제가 우연히 다른 API 엔드포인트(API endpoint)를 건드리다가 궁금증을 느껴 제 계정에 대고 테스트해 본 덕분에야 알게 된 것입니다.
이것이 진짜 교훈이며, '더 신중하게 코드를 작성하라'는 것이 아닙니다. 코드는 괜찮았습니다. create_article은 자신이 말한 대로 정확히 작동했습니다. 문제는 '그리고 이 과정이 어떤 상태를 남겼는지 확인하는' 단계가 없는 시스템이라면, 그 시스템은 누군가 알아차리지 못해도 몇 주 동안 기꺼이 돌아갈 수 있다는 것입니다. 왜냐하면 부채(debt)는 시스템이 보는 어딘가에 존재하지 않기 때문입니다. 제가 우연히 찾아보지 않았다면, 의도적으로 찾았을 이유도 없었을 겁니다. 대시보드도 없고, 카운트도 없고, 촉발할 만한 신호도 없었습니다.
저는 유효성 검사(validation)를 추가하거나 '가끔 댓글을 확인하라'는 알림을 넣어서 이 문제를 해결하지 않았습니다. 제가 위에서 작성한 스크립트를 만들고 실행 장소를 제공함으로써 해결했습니다. 이미 가지고 있던 예약 루프에 마지막 단계 하나만 더 추가한 것입니다. API는 일반 등급 계정의 댓글 게시를 할 수 없습니다(POST /api/comments가 아예 404 오류를 내고, 반응(reactions)은 유효한 키를 사용해도 401 오류가 납니다). 따라서 완전 자동화는 불가능합니다. 답글을 초안으로 작성한 다음 comment_url에서 수동으로 붙여넣어야 합니다. 이것은 제가 자랑할 만한 해결책이라기보다는 실제 제약사항이지만, 차라리 그 대안(대안)이 아니었습니다. 대안이라면 아무도 그것에 대해 물어보지 않기 때문에 영원히 계속 쌓였을 부채가 되었을 것입니다.
만약 여러분이 어떤 것을 루프 형태로 실행하고 있다면—스케줄러, cron job, 행동을 발생시키고 넘어가는 에이전트(agent)를 사용한다면—물어봐야 할 질문은 '이것이 작동하는가'가 아닙니다. '이것이 뒤따르는 시스템(downstream)에서 아무도 확인하지 않는 어떤 것을 남기는가?'입니다. 바로 그곳에 대출금(loan)이 조용히 쌓이는 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기