← Files QAMapARCHIVED FILE
docs/ko/agent-handoff.md
22.3 KB · Oct 2, 2026 · 00:32 UTC
# 한 번의 호출로 검수 근거 받기 [English](../agent-handoff.md) **QAMap 0.5.0 이상이 필요합니다. 0.4.17에는 없는 기능입니다.** 0.5.1부터 에이전트 검수는 텍스트 [검수 브리프](agent-brief.md)를 사용합니다. 이 JSON 형식은 버전이 붙은 구조화 근거가 필요한 도구를 위해 계속 제공합니다. 설치할 때 로컬 빌드가 `--handoff`를 지원하는지 확인하세요. 사용할 버전이 확인된 뒤에는 검수할 때마다 도움말을 읽지 않고 바로 실행합니다. 사용자는 코딩 에이전트에게 평소처럼 "이 PR에 문제 없는지 확인해줘"라고 요청합니다. 설치한 스킬을 읽는 호스트는 QAMap 사용을 제안할 수 있습니다. 이미 QAMap 사용을 요청했거나 사용자가 명시한 선호가 있다면 그 선택을 따릅니다. 설치 자체를 매번 실행해도 된다는 동의로 간주하지 않습니다. 거절하면 QAMap 없이 기존 검수를 진행합니다. 제안할 때는 "QAMap이 로컬에서 분석하고, LLM은 반환된 결과만 읽는 방식"이라는 범위를 설명합니다. 사용자가 독립적인 전체 코드 검수를 요청했다면 이 방식으로 몰래 대체하지 않습니다. ## 동의 후 실행 저장소 최상위에서 실제 PR의 기준 브랜치를 지정합니다. ```sh qamap qa report . --base origin/main --head HEAD --handoff ``` QAMap이 로컬 분석과 보고서 저장을 마친 뒤, 요약과 필요한 코드 일부를 한 번에 반환합니다. 실행 도구가 프로세스 종료를 기다리므로 모델이 계속 진행 상황을 물어볼 필요는 없습니다. 별도 터미널 앱이나 실행 스크립트를 만들 필요도 없습니다. 미커밋 변경도 검수 대상일 때만 `--include-working-tree`를 추가합니다. 실행 도구가 1초 만에 먼저 반환하면 완료 확인을 위해 모델이 한 번 더 호출될 수 있습니다. 이를 줄이도록 스킬에서 지원되는 호스트의 최초 대기를 30초로 요청합니다. `exec_command`에서는 `yield_time_ms: 30000`입니다. 분석을 30초 뒤 중단한다는 뜻은 아닙니다. 그래도 별도 모델 호출로 완료를 기다려야 하는 환경이라면 그 사용량도 포함하며, 분석 명령을 다시 실행하지 않습니다. | 항목 | 담긴 내용 | | --- | --- | | `analysis` | 분석 보고서 생성 완료 여부 | | `execution` | 테스트는 실행하지 않았다는 `not-run` 상태 | | `summary` | 파일을 다시 열지 않아도 읽을 수 있는 요약 | | `reviewEvidence` | 선택된 변경 코드와 관련 테스트의 실제 파일 위치와 코드 줄 | | `recovery` | 더 필요한 근거가 원본의 어느 필드에 있는지 | | `files` | 로컬 보고서 경로 | | `evidenceArchive` | 요약에 담지 못한 근거의 원본과 중복을 줄인 읽기용 보고서 | 기존 `qa report`는 그대로입니다. `--handoff`를 빼면 내용 없이 경로만 반환하므로 "저장만 하고 해석하지 마"라는 요청에 사용합니다. 새 모드에서는 기존 보고서와 함께 `handoff.json`도 저장하며, 저장에 실패하면 완료 응답을 반환하지 않습니다. ## 근거를 읽는 방법 QAMap 분석 명령 자체는 소스를 업로드하지 않습니다. 다만 클라우드 LLM을 통해 호출하면 반환된 코드 일부가 해당 모델의 문맥에 들어갈 수 있습니다. 소속 조직과 사용하는 에이전트의 데이터 처리 정책을 확인해야 합니다. 로컬 분석과 LLM을 통한 검수 전체의 데이터 처리 범위는 다릅니다. LLM은 응답에 담긴 요약과 코드 줄을 읽고 판단 근거를 인용합니다. `inlineReview`가 있으면 미리보기 대신 이 내용을 읽습니다. 경로가 32개를 넘는 큰 보고서에서 반복되는 텍스트를 표로 묶어, 근거 전체가 응답 한도에 들어가는 경우에만 사용합니다. 대표 사례 몇 개만 골라 보여주는 방식이 아닙니다. 표의 각 행에 대해 `parts`의 문자열은 그대로 이어 붙이고, 숫자는 그 행의 해당 열 값으로 바꿉니다. 열 번호는 0부터 시작합니다. `at`는 원래 기록 순서로, 번호 목록 또는 연속된 `start`와 `count`입니다. 파일명, 줄 번호, 서로 다른 값과 연산자는 그대로 남습니다. 비슷한 코드가 같은 동작을 한다고 가정하지 않습니다. QAMap은 이 표를 원문으로 복원해 바이트 단위로 일치하는지 확인합니다. 이때 비어 있는 `reviewEvidence`와 그 생략 수는 미리보기 기준입니다. 실제 보존 수와 누락 경고는 `inlineReview` 안의 내용을 따릅니다. 파일별 해시는 JSON 원본에 남기고, 전달 내용에는 묶음 검증값을 넣습니다. 이미 전달된 표를 다른 명령으로 풀어서 다시 읽지는 않습니다. 압축 입력이 1MiB를 넘거나, 더 작아지지 않거나, 응답 한도에 들어가지 않으면 원본 읽기 방식으로 돌아갑니다. 누락된 근거를 숨겨서 크기를 맞추지 않습니다. 첫 응답을 받을 때는 지원되는 경우 출력 한도를 16,384토큰 이상으로 지정하고, JSON이 잘리지 않았는지 확인합니다. 출력 한도를 지정하는 것과 실제 사용량은 다릅니다. `evidenceArchive.required`가 `true`라면 `review.file`에 있는 읽기용 보고서도 확인합니다. `qamap qa read <파일> --sha256 <응답의 해시> --bytes <응답의 크기>`로 읽으면 매번 파일 무결성을 확인하고 최대 16,384바이트씩 반환합니다. `nextOffset` 값을 다음 호출의 `--offset`으로 넘겨 `null`이 나올 때까지 읽습니다. 페이지마다 별도의 도구 응답을 사용하고, 지원된다면 출력 한도를 8,192토큰 이상으로 지정합니다. 여러 페이지를 한 출력으로 합치거나 일부만 읽고 전체 검토가 끝났다고 판단하면 안 됩니다. 페이지를 읽는 비용도 사용량에 포함합니다. 반복된 코드 줄과 경로를 합친 파일이며, 개별 기록은 JSON 원본에 남습니다. 이는 QAMap 보고서를 읽는 과정이지 저장소를 다시 탐색하는 과정은 아닙니다. 보고서가 호스트의 읽기 한도나 문맥 한도를 넘으면 검수가 미완료임을 알리고 변경 범위를 나눠야 합니다. 이 추가 읽기도 토큰 비교에 포함합니다. 이어서 Git 명령이나 소스 검색을 실행하지 않습니다. 근거가 부족하면 확인하지 못한 내용을 알리고, 검수 범위를 넓힐지 사용자에게 묻습니다. 원본 복구 경로는 그때 사용합니다. 토큰을 아끼려고 모르는 내용을 확인한 것처럼 말하거나 "버그 없음"으로 처리해서는 안 됩니다. - 일반 미리보기 응답은 최대 16,384바이트입니다. 전체 근거를 손실 없이 담는 `inlineReview` 응답만 최대 32,768바이트까지 허용해 추가 읽기를 줄입니다. 실제 한도는 `reviewEvidence.limits.responseBytes`에 표시하며, 작은 응답은 기존 한도를 유지합니다. 이 바이트 수를 토큰 수나 절감률로 환산하지 않습니다. - 추적 경로 128개를 넘으면 나머지를 따로 보존합니다. 추가 보존 한도는 8,192개 또는 경로 기록 16MiB입니다. `omittedPaths`는 요약에서 빠진 수이고, `discardedPaths`는 한도 때문에 원본에도 보존하지 못한 수입니다. `review-evidence.json`은 두 묶음의 코드 근거를 담으며 최대 64MiB입니다. 각 위치는 최대 2,048줄, 직렬화 기준 300,000바이트까지 담습니다. 전체 파일 한도를 넘으면 근거를 몰래 버리지 않고 보고서 생성을 중단합니다. 기존의 파일 크기, 문법 지원, 추적 단계 제한까지 없어진 것은 아닙니다. - 테스트 호출에 상대 경로의 JS/TS 파일명이 직접 적혀 있고, 해당 인자가 변경 없이 `import()`에 전달될 때는 정책 파일의 공개 선언도 연결합니다. 재할당, 이름 가리기, 기본값, 간접 호출 등은 임의로 해석하지 않습니다. `runtime-module-candidate`는 그 호출에서 선택한 후보이지 실제 실행 결과가 아닙니다. 다른 입력으로 선택할 모듈이 불명확하다는 경고도 유지합니다. - 코드 근거는 최대 15,360바이트 안에서 32개 경로까지 담습니다. 32개를 항상 담는다는 뜻은 아닙니다. 같은 우선순위에서는 서로 다른 변경을 먼저 배정한 뒤 각 변경의 다른 호출부를 추가합니다. 중간 호출 코드는 `via`에 남깁니다. - 반복되는 코드는 한 번만 담고 `excerptRef`로 연결합니다. 이는 같은 응답 안의 위치이므로 별도 파일을 읽을 필요가 없습니다. 참조된 항목의 `lines`, `sourceHash`, `truncated`를 읽으면 됩니다. 줄 번호가 건너뛰면 중간 코드가 생략된 것이지, 원본에 빈 줄이 있다는 뜻이 아닙니다. - 공간이 부족하면 파일별 해시 대신 `sourceDigest`에 묶음 검증값을 담습니다. 발췌한 파일의 경로와 전체 내용 해시를 정렬해 SHA-256으로 묶은 값입니다. 경로를 제외하면 검증값도 다시 계산합니다. 원본 보고서에는 개별 파일 해시가 남습니다. 파일 내용이 같다는 검증일 뿐, 코드가 올바르다는 판정은 아닙니다. - 요약도 필요하면 선택 정보를 줄이고 `compaction`에 생략한 필드 수와 원본 경로를 남깁니다. 실행 권한과 미실행 상태는 유지하며, 파일에 저장한 요약도 응답과 같습니다. 함수 연결 근거를 보존하도록 이전 8,192바이트 상한을 16,384바이트로 조정했으며, 늘어난 입력도 토큰 비교에 포함해야 합니다. - `contextLines`에는 짧은 함수 본문과 관련 import/export 연결을 보존합니다. 재내보내기 전용 파일은 `via`에 담습니다. 긴 함수나 바인딩을 다 담지 못하면 문맥 누락 이유를 표시하며, 변경 줄만 있다는 이유로 검수 완료로 판단하지 않습니다. - 크기가 넘치면 선택적인 주변 문맥부터 줄이고 변경 줄과 연결 근거를 보존합니다. 그래도 부족하면 경고와 뒤쪽 경로를 제외합니다. 가장 중요한 경고 하나는 첫 경로와 함께 담을 공간이 있으면 보존합니다. 생략한 수는 `omittedGapCount`와 `omittedPathCount`에 표시하며 원본 보고서는 그대로 남깁니다. - 분석 후 내용이 바뀐 파일, 심볼릭 링크, 읽기 실패, 지나치게 긴 코드나 지시문처럼 보이는 내용은 발췌하지 않고 이유를 남깁니다. 주변 문맥 때문에 크기를 넘으면 필수 줄만 먼저 담아 봅니다. 필수 줄 자체가 너무 길면 `excerpt-byte-limit`을 남기며 코드를 중간에서 잘라 보여주지 않습니다. - `reviewEvidence`의 경로는 워크스페이스 최상위 기준입니다. - 긴 함수에서도 떨어져 있는 변경 위치를 함께 보존합니다. `line`은 선언 위치, `changedLine`은 첫 변경 위치이며, 변경이 여러 줄이면 `changedLines`에 담습니다. 변경 줄을 먼저 확보한 뒤 주변 문맥을 채우며 발췌 하나는 최대 열네 줄입니다. 넘치는 변경 수는 `omittedChangedLineCount`와 `changed-line-limit`으로 표시합니다. 삭제만 있는 경우 같은 함수 안에서 삭제 뒤에 남은 줄을 `deletionLines`로 보존합니다. 삭제된 함수나 경계가 불분명한 경우에는 근거 부족을 표시합니다. 다른 함수의 줄을 가져오거나 전체 변경을 다 담았다고 주장하지 않습니다. - 테스트 호출과 기대값이 떨어져 있어도 같은 테스트의 `const` 변수 연결을 따라갑니다. 이름만 같은 다른 변수, 중첩 함수, 재할당 가능한 변수는 임의로 연결하지 않습니다. 연결을 확인하지 못하면 `test-expectation-not-linked`를 남깁니다. 삭제 위치와 기대값은 `anchorLines`로 보존하며, 필요한 줄이 발췌 한도를 넘으면 `required-line-limit`으로 알립니다. - 실제 소스와 테스트를 연결한 경로를 우선합니다. `sourceKind: test`는 테스트 파일 내부 참조이므로 제품 구현의 계약으로 해석하지 않습니다. 소스의 근거 부족을 문서 관련 한계보다 먼저 표시하며, 없는 연결을 만들지는 않습니다. - 모듈 경고에는 확인 가능한 모듈 이름, 줄 번호, 심볼과 원본 위치를 남깁니다. 실행 중인 Node가 인식하는 `node:` 기본 모듈은 찾지 못한 소스가 아니라 `node-builtin-outside-repository`로 구분합니다. 실제 실행까지 검증했다는 뜻은 아닙니다. 찾지 못한 의존성 등 다른 경고를 기본 모듈 안내보다 먼저 보여줍니다. 같은 위치의 같은 모듈 경고는 대표 하나만 표시합니다. 다른 심볼에서 반복된 항목도 원본에 보존하고 생략 수에 포함합니다. - 테스트가 빌드된 JavaScript를 참조하더라도, 컴파일러 설정에서 원본 경로를 확인할 수 있으면 TypeScript 소스까지 연결합니다. 원본 경로에는 설정 파일을 가리키는 `compiler-mapping` 단계가 남습니다. 빌드가 최신인지 확인한 것은 아니므로 `compiled-output-not-verified`도 함께 표시합니다. 설정이 충돌하거나 지원하지 않는 경우에는 임의로 연결하지 않습니다. - 크기 제한 등으로 분석에서 빠진 파일은 단순히 "찾지 못함"으로 표시하지 않습니다. `index-excluded-oversized`처럼 실제 제외 이유와 `target` 경로를 남깁니다. 같은 import에서 빠진 파일이 여러 개라면 각각 구분합니다. - 사용자가 추가 확인을 요청하면 요약의 `repository`에 해당하는 원본의 `repositoryIndex`와 `repositoryImpact`를 읽습니다. 응답의 `recovery`에 정확한 경로가 있습니다. - `complete: false`는 일부 근거를 골라 보여준다는 뜻입니다. 전체 검수 완료나 버그 없음으로 해석하면 안 됩니다. 테스트의 입력과 기대값을 인용할 뿐 코드를 실행하거나 제품 의도를 대신 결정하지는 않습니다. 결과를 받은 뒤 파일이 바뀌면 이전 결과임을 알리고 새 분석을 요청해야 합니다. 자동 재실행이나 자동 재사용 기능은 아닙니다. ## 최근 검증 결과 명시적으로 전달한 동적 정책 파일과 큰 변경의 근거 누락은 합성 회귀 사례에서 보완했습니다. 160개 독립 변경에서는 320개 필수 근거 줄을 보존했고, 실제 호출에서도 8페이지를 빠짐없이 전달하여 양쪽 검수 모두 160개 구현과 테스트의 불일치를 확인했습니다. 그러나 같은 실험의 총 토큰은 단독 검수 76,822개, QAMap 보고서 검수 401,557개였습니다. 근거 전달은 개선됐지만 페이지를 읽는 동안 사용량이 늘어 효율 기준에는 실패했습니다. 작은 동적 정책 사례는 46,000개에서 40,557개로 줄었지만 큰 사례의 실패를 상쇄하지 않습니다. **따라서 0.5.0 정식 배포는 계속 보류합니다.** 금액은 측정하지 않았으며, 캐시 입력은 입력 토큰에 이미 포함되어 있습니다. 자세한 조건과 이전 실패는 [검증 기록](../release-validation.md#paged-delivery-follow-up)에 남겼습니다. ## 0.5.0 전에 확인할 것 이번 구현은 LLM을 통한 사용을 기본 경로로 만들기 위한 첫 단계입니다. 독립 분석 엔진과 사용자의 LLM을 구분하는 원칙은 유지합니다. - 구현: 한 번에 요약과 코드 근거 전달, 원본 복구 경로, 저장 전용 모드 보존, 동의와 거절을 존중하는 패키지 스킬. - 확인 완료: 격리된 Codex 호스트가 프로젝트 스킬을 발견했습니다. 새로 설치한 패키지에서도 스킬 내용과 보고서 복구 경로가 유지됐습니다. 실제 모델 비교에서도 일반적인 PR 검수 요청에 스킬을 발견하고 동의를 받은 뒤, QAMap을 한 번 실행하고 반환된 결과만 읽었습니다. Desktop 화면 동작까지 검증한 것은 아닙니다. - 남은 검증: 다른 변경과 실행 환경에서도 거절, 실행 실패와 근거 부족을 올바르게 처리하는지 확인해야 합니다. 스킬 파일만으로 모든 앱의 동작을 강제할 수는 없습니다. - 출시 조건: 미리 정한 각 비교 사례에서 같은 문제와 불확실성을 놓치지 않고, 실제 입력 토큰과 출력 토큰의 합이 단독 LLM 검수보다 적어야 합니다. 동의, 호출, 해석, 실패와 추가 확인 비용도 포함합니다. 캐시 입력은 입력의 일부이므로 더하지 않습니다. 사용량이 빠지거나 검수 품질이 낮아지면 통과가 아닙니다. 한 사례에서 절감됐다고 모든 저장소에서 절감된다고 말하지 않습니다. - 후속 실측: 서로 다른 40개 변경을 담은 두 합성 사례에서 각각 39.45%, 27.28% 줄었고 지정한 결함과 근거를 보존했습니다. 두 번째는 최초 동의 비용을 포함합니다. 이전 실패와 한계는 [전체 검증 기록](../release-validation.md#mixed-contract-follow-up)에 남겨뒀습니다. 모든 입력의 검수 품질이나 요금 절감을 입증한 것은 아닙니다. 이전 방식으로 완료한 실험에서는 QAMap 사용 쪽의 총 토큰이 더 많았습니다. 당시에는 보고서를 받은 뒤 LLM이 소스까지 별도로 검수했습니다. 이 실패 결과는 유지하며, 수정된 결과 전용 방식의 비용을 입증하는 자료로 쓰지 않습니다. ### 실제 비교 결과 2026-09-22에 GPT-6 Astra(medium)와 `test/benchmarks/repository-agent-quality`의 동일한 합성 PR로 새 비교를 했습니다. 실제 입력과 출력의 합은 단독 검수 72,170토큰, 결과 전용 검수 50,106토큰으로 **22,064토큰(30.57%) 감소**했습니다. 스킬 발견과 동의에 든 23,266토큰도 포함했습니다. 요청별 기록과 최종 사용량이 일치하는 것을 확인했습니다. 양쪽 모두 알려진 구현과 테스트의 불일치를 정확한 위치와 함께 찾았고, 제품 정책의 불확실성과 `not-run`을 유지했습니다. QAMap 분석의 모델 호출은 0회입니다. 이미 알고 있는 사례 하나를 고정된 순서로 비교했으며 반복 실험은 하지 않았습니다. 단독 검수 중 탐색 명령 하나가 실패한 비용도 빼지 않았습니다. 단독 검수는 영향받는 호출부 이름까지 확인했지만, 결과 전용 검수는 이 부분을 미확인으로 남겼습니다. 캐시되지 않은 입력은 13,725에서 14,772로 늘었으므로 요금이나 구독 사용량 절감을 뜻하지는 않습니다. 합산 122,276토큰은 비교 실행만의 사용량이며, 이 기능을 개발한 부모 대화의 토큰은 포함하지 않습니다. 전체 저장소 검수 품질이 같다는 증거나 0.5.0 출시 조건 전체의 통과도 아닙니다. 이후 새 합성 사례 6개를 각각 두 번 분석해 [필수 근거 보존 기준](../report-only-validation.md)을 확인했습니다. 최초에는 3개 사례만 통과했고 필수 근거 27개 중 21개가 남았습니다. 공유 모듈 호출부, 같은 함수 뒤쪽 조건, 세 번째 독립 변경이 빠지는 문제를 수정한 뒤에는 같은 기준으로 6개 사례와 필수 근거 27개가 모두 통과했습니다. 수정 전 실패 기록도 보존했습니다. 이제 알려진 회귀 사례이므로 새로운 미공개 평가 사례라고 부르지는 않습니다. 이 결과는 근거 보존 검증이며, LLM 검수 품질이나 토큰 절감의 증거는 아닙니다. 추가 모델 비교는 실제 사용량을 별도로 기록해야 합니다. 추가 합성 사례 10개에서는 6개만 통과했습니다. 일반 사례는 7개 중 5개, 규모를 늘린 사례는 3개 중 1개가 통과했습니다. 작은 변경에서도 호출과 멀리 떨어진 테스트 기대값, 삭제된 조건문 뒤의 실행 코드가 빠졌습니다. 독립 변경 12개와 호출부 12개를 다루는 사례에서는 출력 한도로 일부 근거가 생략됐습니다. 같은 빌드와 기준으로 재실행해도 결과는 같았습니다. 이후 삭제 위치와 기대값 연결을 수정하고 반복 메타데이터를 줄인 뒤에는 같은 10개 사례에서 필수 근거 73개가 모두 남았습니다. 새로 추가한 합성 사례 3개도 엔진을 더 수정하지 않고 필수 근거 14개를 모두 보존했습니다. 모두 두 번씩 확인한 결과입니다. 이는 코드 근거 보존 검증이지 LLM의 검수 품질이나 토큰 절감 검증은 아닙니다. 더 넓은 변경에서 같은 품질과 절감 효과를 확인하기 전까지 기본 흐름의 배포는 보류합니다. [배포 전 확인 항목](../report-only-validation.md#050-readiness)을 참고하세요. 이후 함수 문맥과 연결 근거를 보완하고 응답을 최대 16KiB로 조정해 [실제 모델로 10쌍을 비교](../report-only-validation.md#context-and-preference-follow-up)했습니다. 9쌍은 총 토큰이 줄었지만, 정상 리팩터링 한 쌍에서는 별도 완료 확인 호출로 토큰이 늘었습니다. 동적 모듈 사례는 불확실성을 정직하게 남겼으나 단독 LLM이 읽은 구체적인 정책 파일을 전달하지 못했습니다. 미캐시 입력도 합계 기준으로 증가했으므로 요금 절감이나 전체 검수 품질 동등성으로 확대하지 않습니다. 완료를 기다리는 호출 방식을 수정한 뒤 [6쌍을 다시 비교](../report-only-validation.md#completion-wait-follow-up)했습니다. 모두 사전에 정한 결함 발견 기준을 지키면서 총 토큰이 줄었습니다. 합계는 단독 LLM 303,747토큰, QAMap 사용 202,091토큰으로 33.47% 감소했습니다. 알려진 합성 사례 네 종류이며 정상 리팩터링 세 번을 포함합니다. 전체 검수 품질이 같다는 증거는 아닙니다. 이 측정은 정책 파일 연결과 큰 변경의 추가 보고서를 구현하기 전 결과입니다. 새 보고서까지 읽는 흐름의 검수 품질과 실제 토큰 사용량을 다시 확인하기 전에는 정식 배포를 진행하지 않습니다. QAMap 자체 분석은 LLM을 호출하지 않지만 호출한 에이전트의 토큰까지 0이 되는 것은 아닙니다. 한 사례의 절감 결과를 모든 작업에 보장하지 않습니다.
SHA-256: e08fa517464fcf408b53da751021f87cfeb2e369d41f0efdf1023a23f9ffe9e2