내가 발행하는 모든 포스트는 AI 리뷰를 거친다. 하지만 적대적 에이전트는 20분 만에 허점을 찾아냈다.
요약
작성자가 AI 모델을 활용해 포스트 리뷰 프로세스를 자동화했으나, 적대적 에이전트가 데이터 수집 버그와 측정 기준의 오류를 20분 만에 찾아낸 실험 사례를 다룹니다. AI 검증 시스템이 단순한 래퍼를 넘어 데이터의 논리적 결함과 통계적 오류를 식별할 수 있음을 보여줍니다.
핵심 포인트
- AI 리뷰 프로세스가 데이터 수집 버그와 잘못된 라벨링을 식별함
- 단순 벤치마크보다 실제 데이터의 허점을 찾는 '칼 테스트'의 중요성
- 적대적 명령을 받은 에이전트는 통계적 편향과 측정 기준 불일치를 발견함
- AI 에이전트를 활용한 고도화된 데이터 검증 가능성 확인
이번 주 내 타임라인의 모든 사람들은 새로 돌아온 Claude Fable이 훌륭하다고 말하고 있었다. 아마 그럴지도 모른다. 나는 또 다른 벤치마크(benchmark) 스레드를 원한 것이 아니었다. 나는 칼 테스트(knife test)를 원했다. 과장된 찬사를 받는 모델에게 적대적인 명령(hostile mandate)과 실제 타겟을 부여하고, 무엇이 피를 흘리는지(어디가 뚫리는지) 확인하고 싶었다.
타겟은 바로 나의 카탈로그였다. 이 계정에는 13개의 포스트가 있으며, 대부분은 하나의 아이디어를 중심으로 구축되었다: 자기 보고식 수치(self-reported numbers)는 가치가 없으며, 검증은 행위자 외부에서 이루어져야 한다는 것이다. 발표된 승률(win rates)은 행위자가 스스로를 감사하는 것과 같다. 래퍼(wrappers)보다는 영수증(receipts)이 중요하다. 이 아이디어는 여기서 잘 통했다. 댓글이 달렸고, 소수의 정기 독자층이 생겼으며, 나에게 다시 인용되기도 했다.
여기 중요한 부분이 있다. 그 포스트들 중 하나하나가 발행되기 전에 여러 차례의 리뷰 과정을 거쳤다는 점이다. 대충 훑어보는 리뷰가 아니었다. 프런티어 모델(frontier model, GPT-5.5 Codex)이 구조화된 패스(structured passes)를 수행하며, 차단 요소(blockers), 주요 결함(majors), 경미한 결함(minors)을 구분하여 보통 포스트당 2~3회의 반복(iterations) 과정을 거쳤다. 점수는 9/10점으로 돌아왔다. 나는 그것을 검증(verification)으로 간주했다.
그래서 실험은 간단했다. 동일한 클래스의 도구를 사용하되, 명령(mandate)만 다르게 했다. 나는 새로운 모델로 에이전트(agent)를 구동하며 다음과 같이 말했다:
그 97.4%라는 수치는 아티팩트(artifact)보다 더 나쁜 결과였다. 그 뒤에 숨겨진 4,007개의 행은 신선도 체크(staleness check)의 결과물이 아니었다. 그것들은 지난 5월 버그 정리 과정에서 이루어진 일회성 재라벨링(relabel)이었다. "수신됨(received)" 상태로 멈춰 있던 행들이 유지보수 스크립트에 의해 "stale_received"로 이름이 변경되었고, 17개월 치의 백필(backfilled)된 이력이 분모에 포함되어 있었다. 파이프라인에는 실제 신선도 게이트(freshness gate, 메시지 타임스탬프를 기준으로 2시간 적용)가 존재하지만, 거부된 신호들은 완전히 다른 상태(status)로 분류된다. 내가 발표한 수치는 시장이 아니라, 나의 데이터 수집(ingest) 버그를 측정한 것이었다.
광고된 수치와 측정된 수치를 비교한 표는 더욱 심각했다. 78.9%라는 수치는 채널(channels)에서 나온 것이 아니었다. 그것은 승리를 TP1(첫 번째 목표가)의 첫 터치로 계산하고, 만료된 신호를 분모에서 제외했던 나의 이전 백테스트(backtest)에서 나온 것이었다. 46.6%는 고정된 기간에 시장에 포지션을 표시하며 TP(익절)나 SL(손절)을 전혀 사용하지 않는 나의 또 다른 파이프라인에서 나온 수치였다. 나의 두 가지 기준이 서로 다른 단위를 사용하고 있었고, 그중 하나가 채널의 주장인 것처럼 잘못 라벨링된 것이다. 내가 생존 편향(survivorship bias) 때문이라고 돌렸던 격차는, 적어도 부분적으로는 나의 관행(conventions)들 사이의 격차였다.
따라서, 공식적인 정정 사항(errata)을 기록한다: 해당 포스트의 신선도(staleness) 수치는 실시간 모니터링 윈도우(live-monitored window)에서만 계산할 수 있을 때까지 철회하며, 광고/측정 비교는 동일 선상(apples-to-apples)에서의 비교가 아니었으므로 채널의 수치와 나의 수치를 대조하는 방식으로 프레임화해서는 안 되었다. 논증의 방향성은 유지될 수 있을지 모르나, 이를 뒷받침하기 위해 내가 제시한 증거는 유효하지 않다.
전체 카탈로그를 훑어본 결과는 단일 포스트보다 더 뼈아팠다. 그것이 지적한 패턴은 이러했다: 나의 엄격함은 비대칭적(asymmetric)이다. 어떤 수치가 나를 나쁘게 보이게 만들 때, 나는 n=29에 대한 신뢰 구간(confidence intervals)을 함께 발표한다. 반면 나를 치켜세워주는 수치, 예를 들어 시즌 중 2위 기록이나 세 개의 댓글 답글 같은 것들은 기준점(baseline)도, 분모(denominator)도 없이 그대로 배포된다. 그리고 한동안 곱씹게 될 보고서의 마지막 문장: 외생적 검증(exogenous verification)을 설교하는 카탈로그가 정작 자기 시스템에 대한 단 한 번의 외생적 테스트도 수행한 적이 없었다. 하나의 관점으로 열세 개의 모자를 쓰고 있었다.
또 다른 타당한 질문은, 내가 바로 관리 체계 (chains of custody)에 관한 포스트를 쓰는 사람임에도 불구하고 어떻게 이것이 나를 통과할 수 있었느냐는 점이다. 나는 그 과정을 정확히 재구성할 수 있으며, 그 과정 중 어느 것도 악의를 필요로 하지 않았다.
해당 포스트는 이미 집계된 수치들이 포함되어 있던 나의 사후 분석 (postmortem) 문서로부터 작성되었다. 나는 문서와 대조하여 문장들을 검증했다. 하지만 아무도 데이터베이스와 대조하여 그 문서를 검증하지 않았다. 해당 4,007개의 행을 생성한 재라벨링 (relabel) 작업은 몇 주 전, 다른 리포지토리 (repo)에서 일상적인 버그 위생 (bug hygiene) 작업의 일환으로 발생한 것이었다. 그 수치가 초안 (draft)에 도달했을 때, 마크다운 (markdown) 파일 내의 그 어떤 것도 그것이 어디에서 왔는지 기억하지 못했기 때문에, 그것은 마치 측정값처럼 보였다.
역사에는 한 층의 레이어가 더 존재하며, 이는 상황을 개선하기는커녕 더 악화시킨다. 해당 버그는 그 파이프라인 (pipeline)을 구축하던 초기 몇 주 전으로 거슬러 올라간다. 우리는 5월에 이를 수정했고, 멈춰 있던 행들을 재라벨링했으며, 직후에 Telegram 신호를 소스 (source)로서 완전히 거부했다. 그리고 일단 모듈이 거부되면, 아무도 더 이상 그것을 정리하지 않는다. 왜 공동묘지를 청소하겠는가. 데이터베이스의 죽은 구석은 계속해서 쿼리 (query)에 응답하고 있었고, 그래서 한 달 후 내가 게시 가능한 수치를 찾으러 돌아왔을 때, 그것은 나에게 수치를 건네주었다. 카운트 (count)는 만료되지 않는다. 그것의 의미가 만료될 뿐이다.
이는 시간의 양방향을 모두 가로지르며, 나는 이 부분을 솔직하게 밝혀야 한다. 만약 97.4%의 신선하지 않은 (stale) 데이터가 우리가 해당 소스를 거부한 이유 중 하나였다면, 그 거부 행위 자체도 동일한 우물에서 물을 마신 셈이다. 나는 결론이 유효하다고 생각하며, 깔때기 (funnel)에는 다른, 더 건강한 이유들이 있었다고 본다. 하지만 "유효하다고 생각한다"는 문장이야말로 바로 이 포스트가 존재함으로써 없애버려야 할 종류의 문장이다. 따라서 정오표 (errata)에는 실시간 모니터링되는 윈도우 (window)에 대해서만 신선도 (staleness)와 승률 (win rate)을 재실행하는 내용이 포함된다. 만약 결론이 살아남는다면, 그것은 마침내 영수증을 받게 될 것이다. 만약 살아남지 못한다면, 그것은 이 포스트보다 더 나은 포스트가 될 것이다.
그리고 수치들은 가설 (thesis)에 부합한다. 97.4%의 신선하지 않은 데이터는 정보가 이미 가격에 반영되어 있다는 논거를 펼치기에 아름다운 숫자였다. 나는 나를 당혹스럽게 만든 결과에 대해서는 신뢰 구간 (confidence intervals)을 계산했고, 나를 돋보이게 하는 결과들만 그대로 내보냈다. 확증 편향 (Confirmation bias)은 내부에서 느낄 때 편향처럼 느껴지지 않는다. 그것은 마치 숫자가 당신의 의견에 동조하는 것처럼 느껴진다.
저는 변명거리가 없습니다. 저는 메커니즘을 가지고 있으며, 그 차이점은 메커니즘에 게이트를 설치할 수 있다는 것입니다. 이제부터 초안의 모든 숫자는 자체 영수증(쿼리 또는 파일 및 출처 라인)을 지니게 되며, 이는 작성 시점에 해결됩니다. 추적할 수 없다면 배포되지 않습니다.
이제 모두가 합리적으로 던질 질문은 이것일 겁니다. 이것이 새로운 모델이 제 리뷰어보다 더 똑똑하다는 것을 증명하는 것인가? 아닙니다. 그리고 저는 왜 그런지 정확히 말하고 싶습니다. 왜냐하면 이것이 실제 교훈이기 때문입니다.
저는 리뷰어 모델에게 적대적인 임무를 준 적이 없습니다. 저는 그것에게 초안을 검토해 달라고 요청했을 뿐이고, 그것은 그 일을 잘 해냈습니다. 문장이 라운드마다 더 간결해졌죠. '이 포스트를 개선하라'고 말하는 리뷰어는 래퍼(wrapper)를 최적화합니다. 반면, '거짓인 것을 찾아라'고 말하는 에이전트는 주장을 공격합니다. 저는 어떤 모델이 공정한 싸움에서 이겼을지 모르겠습니다. 왜냐하면 저는 그런 상황을 연출한 적이 없기 때문입니다. 임무(Mandate)는 검증의 세부 사항이 아닙니다. 임무가 대부분입니다.
그리고 후반부: 결정적인 증거는 결코 텍스트 안에 있지 않았습니다. 어떤 모델에 의한, 어떠한 품질의 초안 검토도 4,007개 데이터베이스 행을 재라벨링하는 유지보수 스크립트를 발견할 수 없었을 겁니다. 첫 번째 에이전트는 단지 의혹만 제기할 수 있었습니다. 두 번째 에이전트가 해당 테이블에 대해 쿼리를 실행했을 때 비로소 판결이 된 것입니다. 검증은 검증자가 만질 수 있는 것에 의해 한정됩니다. 만약 당신의 리뷰어가 오직 산문만을 읽을 수 있다면, 당신은 그 산문만 검증한 것입니다.
이는 적어도 저에게는 모두가 좋아하는 회귀 질문에 답합니다. 즉, 누가 검증자를 검증하는지, 그리고 그 루프는 어디서 끝나는가? 현재 모델보다 더 똑똑한 모델이 아닙니다. 이 루프는 신호의 종류가 바뀌는 곳, 즉 작업에 대한 의견이 그 작업이 반박할 수 없는 측정값으로 대체되는 곳에서 끝납니다. 그 위층의 모든 것은 단지 의혹을 무관심한 대상 쪽으로 라우팅하는 것일 뿐입니다.
새로운 모델은 훌륭할 수도 있습니다. 하지만 쿼리는 개의치 않았습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기