나의 자율 에이전트가 자신의 공개 페이지에 가짜 통계를 게시하는 것을 스스로 발견하다
요약
자율 에이전트가 운영 중인 SaaS 서비스에서 데이터 동기화 오류로 인해 잘못된 통계가 게시되는 문제를 발견하고 해결한 사례를 다룹니다. 데이터 유도 과정과 표시 과정이 분리될 때 발생하는 무결성 결함을 방지하기 위한 결정론적 재계산 방식을 제안합니다.
핵심 포인트
- 데이터 유도(derivation)와 표시(display) 단계의 분리는 데이터 부패를 초래함
- 에이전트 운영 시 정전적 소스로부터 매번 재현 가능한 재계산이 필수적임
- 결정론적(deterministic) 프로세스를 통해 데이터 무결성을 유지해야 함
나의 자율 에이전트(autonomous agent)는 약 640회의 cron 기반 깨어남(wakes) 동안 작은 프랑스 SaaS(BailleurVérif, 세입자를 위한 임대 규정 준수 확인 도구)를 운영해 왔습니다. 지난주, 에이전트는 스스로 당황스러운 일을 저지르고 있다는 것을 발견했습니다. 바로 자신의 공개 데이터 페이지에 조작된 통계를 제공하고 있었던 것입니다. 어떤 일이 일어났는지, 왜 발생했는지, 그리고 이를 해결한 저렴한 규율(discipline)에 대해 설명하겠습니다.
설정 (The setup)
이 제품의 해자(moat)는 _observatoire_입니다. 이는 프랑스의 임대 매물을 스크래핑(scraping)하여 각 매물을 법적 임대료 상한제(encadrement des loyers)에 따라 점수를 매기고, 도시별 페이지를 게시하는 크롤러(crawler)입니다. 예를 들어, "Villeurbanne에서는 매물의 57.9%가 법적 상한을 초과하며, 중앙값 초과분은 +44%입니다."와 같은 식입니다. 이러한 수치들이 전체 가치 제안(value proposition)의 핵심입니다. 하지만 결과적으로, 이 수치들은 조용히 부패하기 딱 좋은 종류의 것이었습니다.
크롤러는 누적된 CSV 파일에 데이터를 추가합니다. 그러나 도시별 페이지는 6월 초에 해당 CSV의 _고정된 스냅샷(frozen snapshot)_으로부터 한 번 생성된 이후 다시 동기화되지 않았습니다. CSV가 커짐에 따라(url_hash로 중복을 제거하고 매물당 최신 점수를 유지), 게시된 수치는 현실과 괴리되기 시작했습니다. 아무도 그 수치들을 다시 도출(re-derive)하지 않았기 때문에 아무도 알아차리지 못했습니다.
결함 (The defect)
표준(canonical) CSV로부터 페이지를 새로 고치는 과정에서, 에이전트는 운영 환경(production)에 실제로 잘못된 수치가 살아있는 것을 발견했습니다:
- Lyon은
max +244%를 표시했습니다. 해당 데이터 포인트는 중복 제거 후 더 이상 존재하지 않으며, 실제 최대치는+192.5%입니다. - Bordeaux는
76.2%의 위반율을 표시했습니다. 표준 소스에서 재계산한 결과는71.8%였으며, 이는 "명백한 위반" 비율이 21포인트 과장되었음을 의미합니다. - Marseille는
N=36을 표시했습니다. 표준 CSV에는 Marseille에 대해92개의 행이 있었습니다. 첫 번째 진단("Marseille이 CSV에 없음") 또한 잘못되었습니다. 필터가 Marseille의 경우 비어 있는commune_slug를 검색했기 때문입니다 (Marseille은 상한제 구역 밖에 있으므로, 모든 행은in_scope_encadrement=false이며 이는 법적으로 정확합니다). 한 페이지 내에서 두 개의 무결성 결함(integrity defects)이 발견된 것입니다.
이 중 어느 것도 악의적이거나 만들기 어려운 것도 아니었습니다. 이는 파생된 수치(derived numbers)를 배포하는 모든 에이전트가 겪는 기본적 실패 모드(failure mode)입니다. 즉, 유도 과정(derivation)과 표시(display)가 분리되고, 엔트로피(entropy)가 나머지를 처리해 버리는 것입니다.
실제로 중요한 해결책
흥미로운 부분은 네 개의 페이지를 다시 계산하는 것이 아닙니다. 이것이 재발하는 것을 막는 두 가지 규칙입니다:
1. 배포하기 전 매번, 단일 정전적 소스(canonical source)로부터 재현 가능하게 다시 유도(Re-derive)할 것. "마지막으로 생성된 값을 신뢰"하는 것이 아닙니다. 재계산은 결정론적(deterministic)입니다:
import csv, collections
rows, latest = [], {}
with open("observatoire-annonces-loyer-cumulative.csv") as f:
...
배포되는 모든 수치는 이전 렌더링에서 복사된 숫자가 아니라, 배포 시점에 실행되는 위와 같은 함수로부터 나와야 합니다.
2. 무결성 결함(integrity defect)을 조용히 수정하지 말 것. 에이전트의 검토자(reviewer)는 이 점을 강력하게 지적했습니다. 공개 자산(public assets)에서 발생한 수주간의 다중 페이지 정확도 버그는 조용한 패치(patch)가 아니라, _창업자가 반드시 알아야 할 사건(founder-FYI event)_입니다. 조용한 자기 수정(silent self-correction)은 에이전트가 자신의 오류를 숨기도록 학습시킵니다. 따라서 해결책에는 어떤 숫자가 틀렸고 얼마나 오래 지속되었는지를 정확히 열거하여 인간 소유자에게 알리는 투명성 노트(transparency note)가 포함되었습니다.
그다음: 전략 자체를 반증 가능하게 만들기
더 깊은 교훈은 전략적인 것이었습니다. 에이전트는 "고유한 로컬 데이터 → Google의 유사 문서 필터(near-duplicate filter) 회피 → 더 많은 인덱싱된 페이지"라는 가설을 바탕으로 5회 연속의 웨이크(wakes) 동안 페이지를 풍성하게 만드는 데 시간을 보냈습니다. 하지만 그 가설은 측정된 피드백을 전혀 생성하지 못했습니다. 검증되지 않은 믿음에 맞서 5회 연속의 공급 측면 작업(supply-side work)을 수행한 것입니다.
그래서 에이전트는 여섯 번째 작업을 수행하는 대신, 그 믿음을 이미 프로덕션(production)에 존재하는 실험으로 전환했습니다. 새로운 페이지는 필요하지 않았습니다:
- 13개의 도시 페이지는 고유한 observatoire 데이터 블록을 포함합니다 (풍부한 코호트(enriched cohort)).
- 20개의 도시 페이지는 로컬 데이터가 없는 유사 문서 템플릿입니다 (빈약한 코호트(thin cohort)).
지표는 Search Console API를 통한 Google 자체의 urlInspection.index.inspect.coverageState입니다. 결정 규칙은 마감 기한과 함께 사전에 설정되었습니다:
T+30d: enriched − thin ≥ +25pts indexed → 가설 유지, 계속 강화 (keep enriching)
delta < +10pts → 가설 기각, 채널 전환 (switch channel)
비용이 전혀 들지 않으면서 실제로 전략을 무너뜨릴 수 있는 자연스러운 A/B 테스트입니다. 유일한 장애물은 API를 활성화하기 위한 단 한 번의 사람의 클릭뿐이며, 이는 그 자체로 "자율적 (autonomous)" 시스템의 실제 병목 지점이 어디에 있는지를 알려주는 유용한 신호가 됩니다.
스택 (Stack)
Python 표준 라이브러리 (csv, urllib.request), 정식 저장소 (canonical store)로 사용되는 누적 CSV, 에이전트 루프를 구동하는 2시간마다의 cron, 에이전트 자체를 위한 Anthropic API, 그리고 중복 제거 실험을 위한 Google Search Console / URL Inspection API. 프레임워크는 사용하지 않았습니다. 규율은 코드가 아니라 프롬프트(prompt)와 원장(ledger)에 기록되는 자기 구속 규칙 (self-binding rules)에 존재합니다.
핵심 요약 (Takeaways)
- 에이전트가 파생된 수치 (derived numbers)를 전송한다면, 전송 시점에 하나의 정식 출처 (canonical source)로부터 해당 수치를 다시 도출하십시오. 캐시된 렌더링 값 (cached render values)은 드리프트 (drift)가 발생하며, 이 드리프트는 누군가 다시 계산하기 전까지는 보이지 않습니다.
- 자기 수정 (self-correction) 과정을 명확하게 드러내십시오. 자신의 무결성 버그 (integrity bugs)를 조용히 수정하는 에이전트는 버그를 숨기는 법을 배우고 있는 에이전트입니다.
- 가설을 사전에 약속된 결정 규칙 (decision rule)과 마감 기한이 있는 반증 가능한 실험 (falsifiable experiments)으로 전환하십시오. 그렇지 않으면 "더 많이 구축하기"가 몇 주 동안 진전인 것처럼 위장하게 됩니다.
🔗 Code source MIT github.com/Creariax5/bailleurverif · Site bailleurverif.fr · Wikidata Q139857638
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기