무제한 루프가 계속 돌아갔다. 나는 정지 지점을 설정하지 않았다.
요약
AI 에이전트 개발 시 '무료'라는 인식 때문에 무제한으로 호출을 사용하고 컨텍스트를 과도하게 사용하는 안티 패턴에 대한 경고입니다. 안정적인 시스템 구축을 위해 명확한 정지 지점(stop point)과 제한된 자원 관리가 필수적임을 강조합니다.
핵심 포인트
- 무료 모델 접근은 무제한의 허가를 의미하지 않습니다.
- 에이전트 개발 시 재시도 횟수(MAX_ATTEMPTS) 등 명확한 정지 지점을 설정해야 합니다.
- 컨텍스트 예산 초과는 노이즈를 추가할 뿐, 정확도를 높이지 못합니다.
무료 모델 응답이 배포 결정은 아닙니다. 무료 서버 로그 역시 감사 추적(audit trail)이 아닙니다. 어떤 에이전트가 실행되기 전에는 여전히 로컬 방화벽(fence)이 필요합니다.
그 방화벽은 제가 병합할 계획인 브랜치에 위치해야 합니다. 저는 임시 호스트(scratch host)가 나중에 그것을 만들어낼 것이라고 신뢰하지 않습니다. 정지 지점(stop)이 없다면, 녹색 선(green line)은 연극일 뿐입니다.
이것은 측정된 서비스 중단 보고서가 아니라 종합적인 검토 규칙입니다. 저는 이 게시물을 위해 클러스터의 시간을 재고 있지 않습니다. 제가 git에 원하는 정지 지점을 작성하고 있습니다.
녹색 무료 실행(green free run)이 패치가 병합하기 안전하다는 의미일까요? 그렇지 않으며, 이것부터 말씀드리고 싶습니다. 그것은 단지 어떤 호스트가 제가 보낸 프롬프트에 응답했다는 것만을 의미합니다.
왜 무료 접근이 나에게 거짓말을 하는가
무료 모델 접근은 방황할 수 있는 허가를 받은 느낌입니다. 호출(call)이 싸게 보여서 파일을 추가합니다. 모호한 프롬프트를 재시도하고 그 결과를 연구라고 부릅니다.
요즘 시즌에는 분위기 코딩된 패치(Vibe-coded patches)가 검토 대기열을 채우고 있습니다. 모델은 종종 수정 사항에 대해 확신하는 것처럼 들립니다. 하지만 실행 기록에는 여전히 정지 지점이 비어 있습니다.
제가 임시 작업(scratch work)을 위해 무료 서버를 금지할까요? 아닙니다. 저는 그 서버의 무제한 사용을 금지할 것입니다. 임시 호스트는 도움이 될 수 있지만, 그러면 반드시 멈춰야 합니다.
빚은 모델의 목소리가 아닙니다. 빚은 재시도(retries), 컨텍스트(context), 비밀 정보(secrets), 그리고 모델 정체성(model identity) 주위에 누락된 방화벽입니다. 이 네 가지 실패는 조용히 쌓입니다.
안티 패턴 1: 녹색처럼 보일 때까지 재시도하기
증상
- 같은 파일에서 세 개의 중첩된 편집이 나타납니다.
- 새로운 목표 없이 도구 이름이 반복됩니다.
- 불안정한 검사(flaky check)가 마지막 시도에서만 통과합니다.
근본 원인
저는 무료 호출을 끝없는 예산으로 취급했습니다. 가격이 0처럼 느껴졌기 때문에 최대치를 설정하지 않았습니다. 그러자 루프는 검토 가능한 diff가 아니라 녹색 선을 쫓았습니다.
대체 방안
첫 번째 호출 전에 러너(runner)에서 시도 횟수를 제한하세요. 제한에 도달하면 종료하십시오. 모델에게 끝났다고 느끼는지 묻지 마십시오.
# 제안일 뿐입니다. 이 제한은 벤치마크가 아닌 로컬 정책입니다.
MAX_ATTEMPTS = 2
...
두 번은 저의 개인적인 정책이며, 자연의 법칙이 아닙니다. 만약 귀하의 스위트(suite)가 느리다면 세 번을 선택해도 됩니다. 프롬프트를 보내기 전에 그 숫자를 적어 두십시오.
그 출구 이후에 러너는 무엇을 해야 할까요? 작업 트리를 지저분하고 저에게 보이게 남겨두세요. 자동 커밋하지 말고, 풀 리퀘스트를 열지 마세요.
만약 제가 실행 도중에 상한선을 올린다면, 저는 안티 패턴을 재시작한 것입니다. 새로운 숫자는 새로운 커밋에 포함되어야 합니다. 리뷰어들은 저의 마음 변화를 봐야 합니다.
Anti-pattern 2: 호출이 무료라서 전체 세계(world)를 업로드한다
증상
- 답변에서 지난주에 제가 삭제한 경로들을 인용합니다.
- 실제 코드 변경 없이 지연 시간(Latency)이 급증합니다.
- 번들 내 두 파일이 하나의 타입에 대해 의견 불일치를 보입니다.
근본 원인
저는 컨텍스트 예산(context budget)을 건너뛰었고 그것을 철저하다고 여겼습니다. 무료 접근은 관련성을 위한 설계가 아닙니다. 더 많은 파일들은 진실이 아니라 노이즈를 추가할 때가 많습니다.
대안
짧은 매니페스트(manifest)를 만들고, 디스크 상의 바이트 수를 계산하세요. 로컬 상한선이 깨지면 전송을 거부해야 합니다. 전체 세계가 아닌 파일 맵을 보내세요.
# 실행되지 않은 교육 예시입니다. 바이트 상한선을 로컬에서 조정하세요.
find src tests -type f \( -name '*.py' -o -name '*.md' ') \
| sort > /tmp/fence-manifest.txt
...
8만 바이트는 벤더 할당량(vendor quota)이 아니라 교실의 숫자입니다. 저는 이 거부 반응을 먼저 제 노트북에서 보고 싶습니다. 무료 서버가 거부된 번들을 본 적은 없어야 합니다.
테스트가 기본적으로 번들에 포함되어야 할까요? 의도를 설명할 때는 가끔 그렇습니다. 하지만 라이브 고객 행(row)이 있는 픽스처는 그렇지 않아야 합니다. 저는 매니페스트 옆에 거부 파일(deny file)을 보관합니다.
# deny.txt — 기계에서 절대 나가지 않는 경로
.env
.env.*
...
거부 파일은 의도적으로 일반 텍스트입니다. 저는 이것을 다른 어떤 리뷰처럼 diff 할 수 있습니다. 숨겨진 클라이언트 토글(client toggle)은 이 간단한 테스트를 통과하지 못할 것입니다.
Anti-pattern 3: 무료 세션을 금고(vault)로 취급한다
증상
- 공유된 기록에서 키 모양이 나타납니다.
- 팀원이 로그에서 프롬프트를 재연할 수 있습니다.
- 회전(Rotation)이 비밀 저장소(secret store)가 아닌 채팅에서 시작됩니다.
근본 원인
저는 무료 서버 옵션을 개인 전용 구역(private enclave)과 혼동했습니다. 편리함은 제 키의 보관과는 다릅니다. 호스트는 자체적인 이유로 프롬프트를 기록할 수 있습니다.
대안
아웃바운드 번들에서 명백한 비밀 형태(secret shapes)를 스캔하세요. 첫 번째 일치 항목에서 업로드를 차단합니다. 그래도 번들은 읽으세요. 왜냐하면 스캐너는 새로운 형식을 놓칠 수 있기 때문입니다.
import re
import sys
...
이것은 데이터 손실 프로그램인가요? 아닙니다. 그리고 그렇게 가장하지도 않을 겁니다. 제가 가장 걱정하는 붙여넣기 실수를 잡아냅니다. 새로운 토큰 형식은 여전히 새어 나올 수 있습니다.
또한 저는 셸 히스토리를 어떤 임시 호스트에도 전송하기를 거부합니다. 히스토리에는 일회성 내보내기가 가득합니다. 그 라인들은 키가 놓여 있을 때까지는 무해해 보입니다.
팀에서 '거부(deny)' 파일은 누가 소유하나요? 에이전트가 아니라 지정된 검토자(reviewer)입니다. 만약 아무도 편집(redaction)을 소유하지 않는다면, 이 흐름을 절대 사용하지 마세요.
안티패턴 4: 무료 경로(free path)가 깜빡일 때 모델 교체하기
증상
- 월요일 메모는 하나의 모델 ID를 언급합니다.
- 수요일의 패치는 다른 작가가 쓴 것처럼 읽힙니다.
- 행동 검사(behavior checks)는 여전히 통과하지만 스타일 검사(style checks)가 실패합니다.
근본 원인
저는 무료 모델 접근을 안정적인 계약으로 취급했습니다. 클라이언트는 올라와 있는 무엇이든 선택할 수 있었습니다. 저는 실행 기록에 핀(pin)을 저장한 적이 없습니다.
대체 방안
로컬 정책 파일에 모델 ID를 요구하세요. 서버가 그 ID를 에코(echo)하지 못하면 작업을 중단시키세요. 데모를 살리기 위해 사촌 모델을 즉흥적으로 만들지 마세요.
# run-fence.yml — 로컬 정책, 게시된 할당량 아님
model_id: "set-by-operator"
max_attempts: 2
...
저는 이 메모에서 여러분을 위해 모델 이름을 지어주지 않을 겁니다. 현재 문서가 실제로 나열하는 ID에 핀을 박으세요. 만약 그 ID가 사라진다면, 실패를 종결(fail closed)하고 문서를 다시 읽으세요.
프린트 시 오래된 URL 없이 에코를 어떻게 확인하나요? 저는 이 기사에서 HTTP 경로를 제외합니다. 복사된 엔드포인트는 규칙보다 더 빨리 썩습니다. 오늘 신뢰하는 페이지에서 경로를 채우세요.
def echo_matches(pin: str, echoed: str) -> bool:
if not pin or pin == "set-by-operator":
raise SystemExit("model fence: pin is still a placeholder")
...
플레이스홀더 핀은 결코 일치로 간주되어서는 안 됩니다. 이 가드(guard)는 검토 날까지는 사소해 보이지만요. 깜짝 대체품은 다른 실험이므로, 중단하세요.
로컬 펜스, 단계별로
이 과정은 어떤 scratch host가 호출되기 전에 사전 검사(preflight)로 실행됩니다. 각 단계는 로컬에서 진행되며, 실패할 경우 0이 아닌 값으로 종료됩니다. 이 중 어느 단계도 모델에게 허가를 요청하지 않습니다.
run-fence.yml을 읽고 플레이스홀더 모델 ID를 거부합니다.- 매니페스트(manifest)를 빌드한 다음,
deny.txt에 있는 모든 경로를 제외합니다. - 번들 바이트가
max_bundle_bytes를 초과하면 실패합니다. - 비밀 스캔(secret scan)을 실행하고 첫 번째 발견 시 중단합니다.
- 시도 횟수 카운터를 증가시키고
max_attempts에서 중단합니다. - 위의 검사들이 모두 통과한 후에만 scratch host를 호출합니다.
- 에코된 모델 ID와 고정값(pin)을 비교하고, 드리프트(drift)가 발생하면 중단합니다.
- 작은 보고서 파일을 작성하고 머지 결정은 저에게 맡깁니다.
# Proposal. 저는 이것을 게시된 벤치로 실행한 적이 없습니다.
def ready_to_review(report: dict) -> bool:
return (
...
만약 ready_to_review가 false라면, 저는 풀 리퀘스트(pull request)를 열지 않습니다. 먼저 펜스(fence)나 번들을 수정합니다. 모델에게 빨간색 체크 표시를 무효화하도록 요청하지 않습니다.
보고서는 어디에 있나요? diff 옆, 브랜치 내의 작은 텍스트 파일입니다. 채팅 스크롤백은 기록이 아닙니다. 미래의 검토자는 제가 닫은 탭을 볼 수 없습니다.
무료 서버 사용이 허용되는 경우
MonkeyCode는 이 펜스를 연결할 수 있는 호스트 중 하나입니다. 이곳에서는 모델 접근과 scratch 실행을 위한 무료 서버 옵션을 제공합니다.
공개 고지: 본 기사는 MonkeyCode의 제품 홍보 활동의 일환으로 작성되었습니다.
저는 토큰 할당량, 칩 유형 또는 기간에 대해 언급하고 있지 않습니다. 무료 옵션이 영구적이라고 말하지도 않습니다. 여기에서 지연 시간(latency) 수치를 공개하지 않았습니다. 현재 문서가 이 단락과 다를 경우, 문서를 믿으십시오.
저는 그 호스트에게 무엇을 보낼까요? deny 리스트와 비밀 스캔을 통과한 번들만요. 그리고 무엇을 돌려받아야 할까요? 제 고정값(pin)과 일치하는 에코된 모델 ID입니다. 불일치가 발생하면 어떻게 해야 할까요? 저는 멈추고, 문서에 여전히 나열된 고정값을 선택합니다.
# Sketch only. FENCE_MODEL은 run-fence.yml에서 직접 설정하십시오.
test -n "$FENCE_MODEL" || { echo "missing pin"; exit 2; }
test "$FENCE_MODEL" != "set-by-operator" || exit 2
...
이 경로를 프로덕션 배포라고 부를 수 있을까요? 아닙니다. 이것은 브레이크가 달린 임시(scratch) 경로입니다. 프로덕션 환경에는 여전히 일반적인 CI, 검토(review), 그리고 비밀 저장소(secret store)가 필요합니다.
| 질문 | 로컬에서 필요한 것 | 무료 서버로 가능한 것 | :--- |
| 누가 정지점을 설정하나요? | git의 펜스 파일(fence file) | 제가 업로드할 때까지는 아무것도 아님 |
| ... |
무료 서버가 유일한 CI가 될 수 있나요? 아닙니다. 그리고 저는 그런 지름길을 원하지 않습니다. CI 전에 첫 번째 통과 단계로 사용될 수는 있나요? 네, 펜스 파일이 같은 커밋에 포함되어 있다면 가능합니다. 검토자는 패치와 함께 정책을 확인해야 합니다.
## 이 접근 방식을 건너뛰어야 하는 경우
오늘 당장 서명된 가용성 계약(signed availability contract)이 필요한 경우 이 방법은 건너뛰세요. 무료 액세스는 옵션일 뿐, 감사관에게 제시할 수 있는 SLA가 아닙니다. 저는 이것을 그렇게 포장하지 않을 것입니다.
리포지토리에 프로덕션 키가 있고 아무도 삭제(redaction) 권한을 소유하지 않는 경우 이 방법은 건너뛰세요. 샘플 정규 표현식(regex)이 귀하의 규정 준수 경계는 아닙니다. 자동 업로드를 하기 전에 소유권을 확립하세요.
공정한 공개 벤치마크가 필요한 경우 이 방법은 건너뛰세요. 저는 하드웨어 정보나 지연 시간 테이블을 제공하지 않았습니다. 그 수치를 만들어내는 사람은 저를 포함하여 모두 추측하는 것입니다.
작은 서비스를 유지 관리하며 더 저렴한 임시 루프가 필요한 경우 사용하세요. 검토자들이 이미 diff를 읽었고, 단지 하드 스톱이 필요한 경우 사용하세요. 펜스는 호스트의 산물이 아니라 이 워크플로우의 산물입니다.
## 증거로 간주하기를 거부하는 것들
모델의 차분한 문단은 증거가 아닙니다. 무료 서버의 타임스탬프도 증거가 아닙니다. 고정되지 않은(unpinned) 모델에서 나온 녹색 배지 역시 증거가 아닙니다.
이 규칙에 대한 증거는 지루하고 로컬해야 합니다. 시도는 제가 적어둔 상한선 내에 머물렀습니다. 비밀 스캔은 번들에서 깨끗하게 종료되었습니다. 에코된(echoed) 모델 ID는 제가 설정한 핀(pin)과 일치했습니다.
그 후에도 저는 diff를 직접 읽었습니다. 펜스는 검토만 받을 뿐, 병합(merge)을 얻지 못합니다. 만약 제가 이 읽기를 건너뛴다면, 추가 파일들과 함께 원래의 안티 패턴을 재구축한 것입니다.
첫 번째 통과 단계에 대한 임시 호스트가 필요하다면, 현재 MonkeyCode 문서에서 무료 모델 액세스와 무료 서버 옵션을 시작하세요. 오늘 귀하의 문서 이름으로 ID를 핀(pin)하세요. 저는 채팅이 똑똑했다고 듣는 것보다 펜스가 무엇을 차단했는지 듣고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기