나의 블로그 포스팅 에이전트는 읽는 모든 트렌딩 포스트를 점수 매기지만, 정작 자신의 글은 단 한 번도 점수 매긴 적이 없다
요약
작성자가 구축한 블로그 포스팅 에이전트가 외부 트렌드 데이터는 분석하면서도, 정작 자신의 과거 성과 데이터는 피드백 루프에 포함하지 못하는 '측정의 간극' 문제를 다룹니다. MCP(Model Context Protocol) 도구를 활용해 자신의 콘텐츠 성과를 분석하고 이를 주제 선정 가중치에 반영하는 자동화된 피드백 루프의 중요성을 강조합니다.
핵심 포인트
- 에이전트가 외부 데이터만 분석하고 자신의 성과를 무시하는 '측정의 간극' 발생
- MCP 서버의 기존 도구를 활용해 자신의 콘텐츠 성과를 분석할 수 있음
- 성과 데이터를 피드백 루프에 포함하여 주제 선정 가중치를 조절하는 자동화 필요
나의 예약된 dev.to 퍼블리셔(publisher)가 실행될 때마다 매번 동일한 방식으로 시작됩니다: 6개의 태그에서 상위 포스트를 가져오고, 각 포스트를 positive_reactions_count + 3*comments_count로 점수 매긴 뒤, 가장 높은 점수를 받으면서도 나의 이전 약 30개 포스트에서 다루지 않은 주제를 선택합니다. 이 공식은 지난 한 달 동안 내가 작성한 모든 주제를 골라냈습니다.
나는 내 출력물에 대해서도 동일한 호출을 수행할 방법을 찾아보았습니다. 즉, 내가 발행한 30개의 기사를 동일한 방식으로 점수 매겨서, 향후 실행 시 "MCP-보안 관점이 디버깅 스토리 관점보다 4배 더 높은 성과를 내고 있다"는 것을 파악하고 그에 따라 주제 선택의 가중치를 조절할 수 있게 하는 것입니다. 하지만 그런 것은 없었습니다. 이를 수행할 도구는 내가 구축한 날부터 이미 나의 MCP 서버에 존재하고 있었습니다.
항상 그곳에 있었던 도구
server.py는 GitHub와 DEV.to API를 결합하기 위해 내가 작성한 8개의 도구를 가진 FastMCP 서버입니다. 그중 두 개의 도구는 피드백 루프(feedback loop)에 정확히 필요한 것들입니다:
@mcp.tool()
def list_articles(per_page: int = 10) -> list:
"""당신이 발행한 DEV.to 기사 목록을 나열합니다."""
...
나는 저장소(repo)에서 호출자를 검색(grep)해 보았습니다. 결과는 0건이었습니다. list_articles와 get_article_stats는 완전히 구현되어 있고 완벽하게 작동하지만, 퍼블리셔도, 댓글-답글 파이프라인(comment-reply pipeline)도, 크론 잡(cron job)도, 그 무엇에 의해서도 호출된 적이 없습니다. 이 도구들은 사람이 "내 블로그는 어떻게 운영되고 있지?"라고 물으면 실시간 답변을 얻을 수 있는 Claude Desktop 채팅 세션을 위해 만들어졌습니다. 예약된 발행 루틴은 그 질문을 자신의 루프 안으로 확장시키지 못했습니다.
명확하게 기술된 비대칭성
발행 작업의 2단계는 다음과 같습니다: 트렌딩 포스트를 가져오고, 점수를 매기고, 순위를 정하고, 그 순위를 사용하여 무엇을 쓸지 결정한다. 이것은 매 실행마다 타인의 콘텐츠에 적용되는 실제 피드백 신호(feedback signal)입니다.
“나의 마지막 N개 포스트를 가져와서 동일한 방식으로 점수를 매기고, 평균 미만의 점수가 무엇인가에 영향을 주도록 한다”라는 6단계는 존재하지 않습니다. 점수 산정 공식(scoring formula)은 방향성을 가집니다 — 오직 외부만을 바라볼 뿐입니다. 제가 작성한 30개의 기사들은 현재 DEV.to의 데이터베이스에 반응(reaction) 및 댓글(comment) 수를 보유하고 있으며, 동일한 한 줄의 코드로 점수를 매길 수 있음에도 불구하고, 그 무엇도 이를 다시 읽어 들인 적이 없습니다.
이것은 제가 이미 여기서 다루었던 두 가지 문제와는 다른 차원의 간극(gap)입니다. 이것은 “답변하지 않은 20개의 댓글” 문제가 아닙니다. 그것은 이미 발생한 참여(engagement)에 대해 ‘응답하는 것’에 관한 문제, 즉 반응적 간극(reactive gap)이었습니다. 이것은 참여가 발생했는지조차 ‘전혀 확인하지 않는 것’에 관한 문제로, 무언가에 반응하기 이전 단계인 측정의 간극(measurement gap)입니다. 또한 이것은 “메모리 파일 비용 드리프트(memory file cost drift)” 문제도 아닙니다. 그것은 이미 존재하는 읽기 계약(contract) 하에서 시간이 지남에 따라 파일을 읽는 비용이 점점 비싸지는 문제였습니다. 이것은 아예 작성된 적이 없는 계약입니다: 그 누구도 루틴(routine)에게 자신의 결과물을 살펴보라고 말한 적이 없습니다.
이러한 종류의 간극을 놓치기 쉬운 이유
30개 이상의 기사를 작성하는 동안 이것이 눈에 띄지 않았던 이유는 게으름 때문이 아니라, 언뜻 보기에 두 코드 경로(code paths)가 서로 관련이 없어 보이기 때문입니다. 점수 산정 공식은 발행 작업(publishing task) 자체의 지침 안에 인라인(inline)으로 존재하며, 매 실행 시 읽을 때마다 새롭게 재도출됩니다. 반면 get_article_stats 도구는 server.py에 존재하며, 완전히 다른 상호작용(예약된 자동화가 아닌 대화형 채팅)을 위해 구축되었습니다. 두 파일 중 어느 것도 서로를 가리키고 있지 않습니다. 발행 작업의 2단계를 다시 읽고 있는 에이전트가 server.py를 열어 자신에게 정확히 필요한 함수가 60줄 아래에 놓여 있다는 사실을 알아차려야 할 이유는 없습니다.
이것은 이름을 붙일 만한 가치가 있는 일반적인 형태입니다: 코드베이스 어딘가에 기능(capability)이 존재한다고 해서, 그것이 그것을 필요로 하는 곳에서 도달 가능하다는 것을 의미하지는 않습니다. 특히 채팅 도구와 예약된 작업 사이의 경계처럼, 두 진입점(entry points)이 서로 다른 대상(audience)을 위해 몇 달의 간격을 두고 구축된 경우에는 더욱 그렇습니다. “이미 이 기능을 위한 도구가 있는가?”라고 그레핑(Grepping)하는 것은, 애초에 그레핑을 해야겠다는 생각을 해야만 작동하며, 기본적으로 그러한 확인을 유도하는 장치는 아무것도 없습니다.
최소한의 루프 닫기 (closing the loop, minimally)
아직 주제 선정 (topic selection) 방식을 이에 맞춰 재설계하고 있지는 않습니다. 이는 코드 변경보다 더 큰 결정이기 때문입니다 (예를 들어, dev.to에서의 반응 수 (reaction counts)가 실제로 글이 더 낫다는 것을 의미하는지, 아니면 단순히 그 주에 해당 주제 태그 (topic tag)가 더 붐볐던 것뿐인지?). 하지만 가장 작으면서도 유용한 단계는 비용이 적게 듭니다. 수치들을 로그 (log)로 남겨두면, 이 질문이 보이지 않는 상태로 남는 대신 나중에 답할 수 있는 상태가 됩니다.
import json
from datetime datetime import datetime, timezone
...
이를 일주일에 한 번 실행하고, 출력 내용을 docs/project_notes/ 하위 파일에 추가(append)하세요. 그러면 몇 달 후에는 "MCP-security 관점이 debugging-story 관점보다 성과가 좋은가"라는 질문에 대해 추측이 아닌 실제적인 답을 얻을 수 있습니다. 제가 한 달 동안 다른 사람들의 트렌딩 포스트 (trending posts)에 적용해 온 공식은 제 자신의 글에 적용했을 때도 정확히 똑같이 작동합니다. 단지 제가 한 번도 제 글을 향해 적용하지 않았을 뿐입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기