모델이 OSS 패치에 접근하기 전에 실패하는 오라클을 고정하는 방법
요약
AI 모델이 생성한 코드가 기존 버그를 수정했는지 검증하는 과정에서 발생하는 '오라클 고정(frozen oracle)' 문제를 다룹니다. 이 글은 패치 전후의 테스트 결과를 비교하여, AI가 단순히 실패하지 않는 코드를 만드는 것을 넘어 실제로 버그를 수정했음을 증명하는 체계적인 워크플로우와 매니페스트 작성 방법을 제시합니다.
핵심 포인트
- AI 모델이 생성한 코드만으로는 실제 버그 수정을 증명하기 어렵습니다.
- 패치 전후의 테스트 결과를 비교하여 '오라클 고정'을 구현해야 합니다.
- 매니페스트를 통해 예상 상태와 실패 마커를 명시적으로 기록하는 것이 중요합니다.
주말 동안 기여자가 작은 라이브러리를 복제하고 파서 버그를 재현한 다음, 저녁 식사 전에 코딩 모델에게 이를 수정해 달라고 요청합니다. 모델은 깔끔한 diff와 자신감 있는 요약, 그리고 패치된 트리에서 이미 통과하는 테스트를 반환합니다. 하지만 유지 관리자는 나중에 동일한 테스트가 패치되지 않은 태그에서도 통과했다는 것을 발견했고, 따라서 풀 리퀘스트는 수정이 이루어졌다는 것을 결코 증명하지 못했습니다. 이러한 패턴은 검토 시간을 낭비하며, '오라클 고정(frozen oracle)'은 브랜치가 포크를 떠나기 전에 이를 막아줍니다.
통과하는 테스트가 증거가 아닌 이유
오픈 소스 리뷰는 패치 이전에 존재하고 패치 후에 사라지는 실패를 동일한 명령어로 요구합니다. 수정 후 작성된 생성된 테스트는 결코 실패하지 않았더라도 새로운 동작을 인코딩할 수 있습니다. 그러면 검토자들은 두 번의 캡처 실행을 비교하는 대신 의도된 동작에 대해 논쟁하게 됩니다. 아래 워크플로우는 이 두 번의 실행을 모든 이후 댓글이 존중해야 하는 계약으로 간주합니다.
순서대로 루프 실행하기
- 생산 코드 수정 전에 예상 상태와 두 개의 마커를 포함하여 인자 목록과 함께 매니페스트(manifest)를 작성합니다.
- 손대지 않은 체크아웃에서 '이전' 측을 캡처하고, 상태가 이미 성공 코드로 되어 있으면 중단합니다.
- 사람이든 모델이든 diff를 작성했는지 여부와 관계없이 실패 마커를 제거할 수 있는 가장 작은 패치를 적용합니다.
- '이후' 측을 캡처하고, 검사기를 실행하며, 검사기가 오류를 반환하면 풀 리퀘스트 텍스트를 거부합니다.
- 모델에게 diff를 해당 파일들과 비교하도록 요청하고, 병합 결정은 인간 검토자에게 맡깁니다.
수정하기 전에 증거 제시하기
기여자는 생산 코드에 손대기 전에 '증거(evidence)' 디렉터리를 생성한 다음, 실패하는 명령을 작은 매니페스트에 기록합니다. 이 매니페스트는 명령어, 예상되는 0이 아닌 상태, 그리고 실패 출력에 나타나야 하는 짧은 마커를 명시합니다. 이후의 검사기는 두 캡처 중 하나가 누락되었거나 명령어 문자열이 변경된 경우 패치를 승인하지 않습니다. 핵심은 간단합니다: 모델이 이야기를 다시 쓰기 전에 이 명령어로 이 버그를 증명하는 것입니다.
디렉터리 계약 (Directory contract)
evidence/
manifest.json
before/stdout.txt
...
제안된 매니페스트 (Proposed manifest)
아래 샘플은 하나의 pytest 노드를 위한 제안이며, 명명된 상위(upstream) 저장소의 결과가 아닙니다. 오라클의 양쪽 측면을 캡처하기 전에 인자 목록을 프로젝트의 실제 테스트 명령어로 교체하십시오. 나중에 검토자가 추측하지 않고도 저장된 출력에서 볼 수 있도록 마커를 짧고 구체적으로 유지하십시오. 샘플 상태를 모든 언어 또는 프로젝트의 모든 테스트 러너에 대한 기본값으로 간주해서는 안 됩니다.
{
"command": ["python", "-m", "pytest", "-q", "tests/test_parser.py::test_trailing_comma"],
"before_status": 1,
...
하나의 스크립트로 양쪽 측면을 캡처하기 (Capture both sides with one script)
이 캡처 스크립트는 매니페스트를 읽고, 나열된 명령어를 실행하며, 상태와 두 스트림 모두를 요청된 측면 디렉터리에 작성합니다. 이 스크립트는 버그를 해석하지 않으며, 인자 목록을 사용함으로써 우발적인 따옴표 문제를 피할 수 있어 자유 형식의 셸 문자열을 허용하지 않습니다. 기여자(contributor)는 손대지 않은 체크아웃에서 한 번 실행하고, 사람 또는 모델 패치를 적용한 다음, 'after' 측면으로 다시 실행합니다. 만약 before 상태가 이미 after 상태와 일치한다면, 오라클은 유효하지 않으며 패치는 열어서는 안 됩니다.
#!/usr/bin/env python3
"""제안된 로컬 헬퍼. 상위 저장소에 대한 기록된 실행이 아닙니다."""
import json
...
python capture_oracle.py before
python capture_oracle.py after
python check_oracle.py
검토 코멘트가 존재하기 전에 오라클 확인하기 (Check the oracle before review comments exist)
체커는 매니페스트와 두 상태 파일을 로드한 다음, 실패 마커와 성공 마커가 올바른 측면에 도달했는지 확인합니다. 또한 before 출력에 이미 나타난 성공 마커도 거부하여, 한 번도 실패하지 않은 테스트를 포착합니다. 0이 아닌 체커 결과는 풀 리퀘스트 설명에서 캡처된 버그가 수정되었다고 주장해서는 안 된다는 의미입니다. 아래 스크립트는 포크 로컬 게이트(fork-local gate)에 대한 제안이며, 프로젝트의 실제 테스트 진입점(test entry point)에 맞게 조정되어야 합니다.
#!/usr/bin/env python3
"""제안된 검사기. 샘플 마커는 보편적인 통과 기준이 아닙니다."""
import json
...
모델에게 계약을 검토하게 하고, 직접 만들게 하지 않기
공개: 이 기사는 MonkeyCode의 제품 홍보 활동의 일환으로 작성되었습니다.
MonkeyCode의 무료 모델 접근은 오라클이 이미 디스크에 존재하는 후에 검토 단계에 위치할 수 있습니다. 유용한 작업은 버그에 대한 새로운 판결을 내리는 것이 아니라, 증거 파일과 비교하여 diff를 경계 지어 읽는 것입니다. 신중한 프롬프트는 모델에게 불일치 사항, 테스트되지 않은 브랜치, 그리고 캡처된 파일이 지원하지 않는 주장들을 나열하도록 요청합니다. 무료 서버 옵션은 깨끗한 원격 실행이 필요할 때 도움이 되지만, 결과로 나온 증거 파일들이 여전히 로컬 검사기를 통과하는 경우에 한해서입니다.
검토 대상: evidence/manifest.json, before 및 after 캡처, 그리고 diff.
버그가 수정되었다고 주장하지 마십시오. 검사기가 해당 파일들로 통과할 수 없는 한.
캡처된 출력이 지원하지 않는 풀 리퀘스트 주장을 나열하십시오.
...
모델의 코멘트와 유지 관리자의 결정을 분리하기
| 질문 | 모델이 초안 작성 가능 | 인간이 결정해야 함 |
|---|---|---|
| before 상태가 manifest와 일치했는가? | 상태 파일을 인용 | 그렇지 않다면 요청 거부 |
| ... | ||
| 모델은 이 워크플로우의 검토 경계이며, 다음 달에 모델 이름이 바뀌더라도 유용하게 유지됩니다. 현재 할당량, 모델 목록 및 서버 제한은 만료되는 제품 사실들이므로, 이 기사에서는 이를 인용하지 않습니다. 기여자들은 시간 제한이 있는 기여를 위해 무료 실행에 의존하기 전에 최신 MonkeyCode 문서를 읽어야 합니다. 변경된 제한 사항은 오라클을 건너뛸 이유가 아니라, 동일한 스크립트를 로컬에서 실행해야 할 이유입니다. |
패치를 오라클 내부에 유지하기
고정된 오라클이 모든 수정된 라인이 필수적이었음을 증명하지 않으므로, 기여자(contributor)는 요청을 열기 전에 여전히 diff를 읽어야 합니다. 추가적인 리팩토링(refactors), 이름 변경된 헬퍼 함수(renamed helpers), 그리고 임의로 적용된 포맷팅 변경 사항은 별도의 커밋으로 이동하거나 브랜치에 남겨두어야 합니다. 모델이 그러한 추가 경로들을 나열할 수는 있지만, 증거가 녹색(green) 상태가 된 후에 모듈을 정리하도록 요청해서는 안 됩니다. 작은 패치와 실패했다가 성공하는 명령어 조합이, 그럴듯한 요약과 함께 광범위하게 재작성된 코드보다 되돌리기(revert)가 더 쉽습니다.
검토자가 다시 실행할 수 있는 명령어들
풀 리퀘스트 본문에는 터미널에서 복사한 매니페스트 명령어와 체커 결과가 포함되어야 하며, 단순히 바꿔 쓰는 것이 아닙니다. 다른 기계의 검토자는 동일한 인자 목록을 실행하고, 상태 파일들을 비교하며, 마커(marker)가 너무 모호하면 중단할 수 있습니다. 문서화된 설정 대상(setup target)은 매니페스트 노트에 포함되어야 하며, 이 글이 보편적인 컨테이너 이름(universal container name)을 발명한 것은 아닙니다. 증거 파일들은 유지보수자(maintainer)가 요청하기 전까지 포크(fork)에 남아 있어야 하는데, 일부 프로젝트는 크고 무거운 로그를 커밋하는 것을 선호하지 않기 때문입니다.
마커가 거짓말을 할 때
일반적인 성공 출력에서 나타나는 마커는 체커가 실제 수정 사항을 거부하게 만들 것이며, 그 실패가 유용합니다. 기여자는 특정 예외 텍스트(exception text)나 피처 이름(fixture name)처럼 깨진 실행(broken run)에만 나타나는 문자열을 선택해야 합니다. 그러한 문자열이 존재하지 않는다면, 테스트 자체가 누락된 아티팩트이며, 생산 코드(production code)를 먼저 수정하는 것은 그 간극을 숨길 것입니다. 불안정한 명령어(Flaky commands)는 범위를 벗어납니다. 왜냐하면 두 번의 이전 캡처(before captures) 사이에서 상태가 변경된다는 것은 오라클이 모델 검토에 준비되지 않았음을 의미하기 때문입니다.
이 게이트를 건너뛰어야 하는 사람들
이 접근 방식은 안정적인 마커와 하나의 명령으로 줄일 수 없는 패치에는 적합하지 않습니다. 문서만 수정하는 경우(Documentation-only edits), 시각적 변경 사항, 그리고 드문 경쟁 조건(race conditions)은 다른 증명이 필요합니다. 왜냐하면 단일 캡처된 상태가 녹색처럼 보여도 버그는 남아있을 수 있기 때문입니다. 이미 기록된 리플레이 파일이 필요한 프로젝트는 두 번째 증거 형식을 추가하기보다는 해당 프로젝트의 규칙을 따르는 것이 좋습니다. 또한, 이 검사기는 비밀 스캐닝(secret scanning), 라이선스 검토(license review), 또는 공유 헬퍼에 대한 폭발 반경(blast-radius) 분석을 대체하지 않습니다.
파일들이 동의할 때만 브랜치를 닫으세요
두 번째 검토를 원하는 기여자(contributor)는 검사기 출력과 diff를 무료 모델 세션에 붙여넣을 수 있습니다. 요청되는 유일한 출력은 증거 디렉터리에 이미 저장된 파일들과 비교하여 확인된 미지원 주장들입니다. 해당 스크립트들은 여전히 실행되지 않은 제안(unexecuted proposals)이므로, 각 포크는 녹색 라인을 신뢰하기 전에 자체 테스트 러너에 마커를 조정해야 합니다. 두 가지 캡처와 검사기가 동의하면, 그 브랜치는 또 다른 생성된 요약본보다는 인간 검토자에게 준비됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기