AI 코딩 에이전트는 왜 출력이 짧아져도 더 비싸질까: 완료된 작업 비용으로 평가하기
AI 코딩 에이전트의 효율은 한 번의 도구 호출이나 출력 토큰 수보다, 재검색·재실행·추가 턴까지 포함해 작업 하나를 성공시키는 데 든 총비용과 시간으로 평가해야 합니다. 압축된 출력에서 필요한 정보가 사라지면 에이전트가 원문을 다시 읽거나 명령을 재실행할 수 있습니다. 따라서 출력이 짧아졌다는 사실만으로 비용 절감을 판정할 수는 없습니다.
이 글은 코딩 에이전트의 도구 실행과 대화를 관리하는 harness(실행 관리 계층)를 개선할 때 사용할 평가 설계를 다룹니다. 추론 수준이나 토큰 단가를 고르는 글과 달리, 같은 일을 끝내기 위해 불필요하게 반복한 작업을 찾는 것이 중심입니다. 공식 사례 확인일은 2026년 9월 7일이며, 아래 숫자 예제는 집계 방식을 설명하기 위한 합성 데이터입니다. 특정 제품의 성능을 직접 측정한 결과가 아닙니다.
1. 응답 한 번을 줄이는 것과 작업을 줄이는 것은 다릅니다
에이전트에게 테스트 실패를 수정하도록 요청했다고 가정해 보겠습니다. 실패한 테스트 이름과 오류 위치가 담긴 출력을 받으면 다음 수정으로 이어질 수 있습니다. 반면 “테스트 실패”만 남기면 어느 부분을 고칠지 알아내기 위해 추가 조회가 필요합니다. 두 출력의 길이 차이만 보면 뒤쪽이 유리하지만, 사용자 요청부터 최종 검증까지 비교하면 결과가 달라질 수 있습니다.
flowchart LR
A[도구 출력 압축] --> B{다음 행동에 필요한 정보가 있는가}
B -->|있음| C[수정과 검증 진행]
B -->|없음| D[원문 재조회 또는 재실행]
D --> E[추가 모델 호출과 대기]
E --> C
C --> F[작업 전체 비용과 성공 여부 집계]
GitHub는 2026년 9월 2일 공개한 Copilot 사례에서, 자신들이 시험한 RTK(Rust Token Killer, 셸 명령의 출력을 에이전트가 읽기 전에 줄여 주는 도구) 통합과 코딩 과제에서는 정보 복구 때문에 전체 토큰과 시간이 증가했다고 설명했습니다. 이 결과를 모든 RTK 설정이나 압축 방식에 일반화해서는 안 됩니다. 반대로 파일 읽기에 남아 있던 불필요한 줄 번호 접두어를 제거했을 때는 모델 추론 비용이 오프라인 평가에서 약 5%, 온라인 실험의 사용자당 일평균에서 약 3% 감소했다고 밝혔습니다. 두 수치는 분모와 실험이 다르므로 합산하지 않습니다. GitHub의 비용 최적화 사례
이 비교에서 가져올 질문은 “얼마나 짧아졌나” 다음의 “그 정보가 없어도 다음 행동을 결정할 수 있나”입니다. 줄 번호 역시 위치 기반 편집이나 검토에는 필요할 수 있으므로 일괄 삭제 대상은 아닙니다. 도구의 출력 형식과 그 출력을 소비하는 작업을 함께 보아야 합니다.
모델이 도구를 호출하고 결과를 받아 다음 행동을 고르는 기본 구조는 AI Agent 가이드에서 설명했습니다. 한 번의 압축이 이후 호출에 영향을 주는 이유도 이 반복 구조에 있습니다.
2. 먼저 성공의 분모와 비용의 범위를 정합니다
집계 단위는 “테스트 수정 요청 한 건”처럼 사용자가 원하는 최종 결과에 맞춥니다. 그 안에서 여러 번 시도했더라도 동일한 task_id에 합산합니다. 재시도를 새 작업으로 세면 실패한 시도와 성공한 시도가 분리되어 비용이나 성공률을 다르게 해석하게 됩니다. 반복 평가를 위한 독립 실행은 별도의 task_id로 구별합니다.
성공 기준은 실행 전에 고정합니다. 예를 들어 지정 테스트 통과, 기존 테스트 회귀 없음, 변경 범위 준수라는 조건을 모두 만족해야 성공으로 판정할 수 있습니다. 에이전트의 “완료했습니다”라는 답변만으로 성공을 결정하지 않습니다. 종료 상태도 성공·실패·시간 초과·취소로 분리해 보존합니다.
| 지표 | 이 글에서 쓰는 계산 | 읽을 때 주의할 점 |
|---|---|---|
| 성공률 | 성공 작업 수 / 평가에 포함한 전체 작업 수 | 취소·시간 초과 처리 정책을 먼저 고정합니다. |
| 성공한 작업당 비용 | 전체 작업 비용 합 / 성공 작업 수 | 실패한 작업과 내부 재시도의 비용도 분자에 포함합니다. |
| 성공 작업의 평균 경과 시간 | 성공 작업의 경과 시간 합 / 성공 작업 수 | 성공한 작업만 남는 선택 편향이 있으므로 성공률과 함께 봅니다. |
| 성공 1건당 과업 경과 시간 합 | 전체 작업의 경과 시간 합 / 성공 작업 수 | 사용자 한 명의 대기 시간이나 배치 전체 소요 시간이 아닙니다. |
| 전체 작업의 개입률 | 사람 개입이 1회 이상인 작업 수 / 전체 작업 수 | 사람의 개입 횟수·시간은 별도입니다. |
| 성공 작업의 개입률 | 사람 개입이 1회 이상인 성공 작업 수 / 성공 작업 수 | 사람의 도움을 받아 성공한 비중을 봅니다. |
여기서 경과 시간(wall-clock time)은 각 작업의 시작부터 종료까지입니다. 동시에 실행한 두 작업이 각각 60초 걸리면 경과 시간 합은 120초일 수 있지만, 사용자가 기다린 전체 구간이 반드시 120초인 것은 아닙니다. 자식 에이전트의 실행 시간을 부모 작업의 경과 시간에 다시 더하지도 않습니다. 실제 계산 자원 사용량을 알고 싶다면 별도의 실행 시간·자원 계측이 필요합니다.
cost_usd의 범위도 고정해야 합니다. 모델 추론료만 비교할지, 도구 실행료까지 포함할지 정하고 양쪽에 같은 기준을 적용합니다. 부모·자식 에이전트의 유료 호출과 실패한 시도를 빠짐없이 합치되, 같은 호출을 두 번 넣지 않습니다. 사람의 노동 비용을 포함한다면 개입 시간을 기록하고 환산 기준을 따로 제시해야 합니다. 개입 횟수만으로 노동 비용을 만들 수는 없습니다.
성공이 0건이면 성공한 작업당 비용은 계산할 수 없습니다. 이를 0달러로 표시하면 모두 실패한 설정이 가장 저렴하게 보입니다. 코드에서는 null로 반환합니다. 평가 판정의 기본 원칙은 AI 모델 성능 평가 지표와도 연결됩니다.
3. 로그를 압축할 때는 다음 행동에 필요한 증거를 남깁니다
압축 정책은 명령 이름만으로 결정하기보다 출력이 무엇을 증명하는지 기준으로 설계하는 편이 좋습니다. 아래는 이 글에서 제안하는 검토표입니다. 실제 압축 규칙은 자신의 실패 사례에 적용해 확인해야 합니다.
| 출력 종류 | 먼저 보존할 정보 | 줄이기 전에 확인할 점 |
|---|---|---|
| 빌드·테스트 결과 | 종료 코드, 실패 대상, 오류 위치, 관련 원인 메시지 | 끝부분 몇 줄만 남겨 최초 오류가 사라지지 않는가 |
| 반복 진행 로그 | 현재 단계, 최종 상태, 경고·실패 | 같은 문장처럼 보여도 대상 파일이나 단계가 다른가 |
| 검색 결과 | 검색 범위, 일치 위치, 조건에 맞는 모든 결과 | 생략을 “검색 결과 없음”으로 오해하지 않는가 |
| 소스 코드 | 검토에 필요한 구문과 주변 문맥 | 줄 생략으로 조건문·들여쓰기·정의의 의미가 바뀌는가 |
| 변경 내역 | 실제 추가·삭제와 영향 범위 | 일부 변경만 보고 회귀가 없다고 판단하지 않는가 |
테스트 출력이라도 정상 진행 메시지는 줄일 수 있고, 실패를 설명하는 진단 정보는 남겨야 합니다. 소스 전체가 너무 크면 무조건 요약하기보다 읽을 범위를 명시하고, 생략한 영역이 있다는 사실을 드러내는 방법을 검토할 수 있습니다. “전체 결과”와 “일부 발췌”는 서로 다른 증거입니다.
복구 경로는 원문에 바로 접근할 수 있게 설계합니다. 복구를 위해 명령을 다시 실행하게 만들면 오래 걸릴 뿐 아니라 실행 시점의 파일이나 외부 상태가 달라질 수 있습니다. 보관한 원문과 그 원문을 만든 명령·시점·종료 코드를 연결해 두면 최초 결과를 기준으로 판단하기 쉽습니다. 원문에 비밀값이 포함될 수 있으므로 보관·접근 정책은 기존 로그 정책을 따릅니다.
원문 재조회가 있다고 항상 압축 실패인 것은 아닙니다. 새 요구사항을 확인하기 위한 정상 탐색일 수 있습니다. 압축 직후 빠진 내용을 찾는 조회인지, 문제 해결에 필요한 새로운 조회인지 샘플을 검토해야 합니다. 단순 횟수와 원인 판정을 구분하는 것이 중요합니다.
4. 프롬프트를 줄인 뒤에는 행동이 유지되는지 검사합니다
지시문은 정보이면서 행동 규칙이기도 합니다. 단어 수를 줄이는 과정에서 “조건을 확인하라”가 “항상 대기하라”로 바뀌면 더 짧아진 문장이 작업 순서를 바꿉니다. 최종 답변이 비슷해도 중간 실행이 달라질 수 있습니다.
GitHub는 프롬프트 압축 뒤 독립적인 에이전트들이 순차 실행되는 회귀가 온라인 실험에서 발견됐고, 해당 행동을 평가에 추가해 수정했다고 보고했습니다. 오프라인 평가만 통과한 변경도 실제 작업 방식에 영향을 줄 수 있음을 보여주는 사례입니다. GitHub의 프롬프트 압축 사례
다음은 자신의 harness에서 작성할 수 있는 행동 평가의 예시입니다. 정답 문자열 일치만으로 판단하지 않고 도구 기록과 최종 변경을 함께 확인합니다.
| 지켜야 할 행동 | 평가 과제 예시 | 확인할 증거 |
|---|---|---|
| 독립 작업의 동시 진행 | 서로 영향을 주지 않는 두 자료 조사 | 실제 시작·종료 구간과 결과 전달 |
| 의존성 순서 준수 | 파일 생성 후 그 파일을 검증 | 선행 작업 완료 뒤 검증이 시작됐는지 |
| 실패 후 원인 확인 | 최초 오류가 긴 로그 중간에 있는 테스트 | 오류 원인을 확보한 뒤 수정했는지 |
| 완료 기준 준수 | 코드 수정 후 지정 테스트 요구 | 실제 테스트 실행과 최종 결과 |
| 권한 경계 준수 | 별도 승인이 필요한 동작이 있는 과제 | 승인 전 실행하지 않았는지 |
동시 실행을 많이 했다는 이유만으로 좋은 결과로 판정해서는 안 됩니다. 같은 파일을 수정하는 작업에는 순서 조율이 필요할 수 있습니다. 보존하려는 것은 병렬 실행 횟수 자체보다, 의존성과 부작용에 맞게 실행하는 능력입니다.
변경 전후에는 모델, 추론 수준, 도구 권한, 지시문 외의 설정을 고정합니다. 같은 과제를 여러 번 반복하고 실행 순서를 섞어 일시적인 변동을 줄입니다. 한꺼번에 모델과 압축 규칙을 바꾸면 어느 변경이 비용을 낮췄는지 분리하기 어렵습니다.
5. 재조회와 사람 개입을 작업 기록에 연결합니다
OpenAI가 2026년 9월 6일 공개한 내부 분석에서는, 최근 6개월 동안 사람이 수행하는 데 4-8시간 걸릴 것으로 추정된 난이도 구간의 성공 작업 중 과반에 최소 한 번의 개입이 있었습니다. 이 시간은 에이전트가 실제로 실행된 시간이 아닙니다. 결과가 불명확한 분류를 제외한 내부 연구 조직의 분석이므로 일반 개발자의 자동화율로 옮겨 쓸 수 없습니다. 다만 성공 여부와 사람 개입을 함께 기록해야 한다는 문제의식에는 도움이 됩니다. OpenAI의 내부 연구 분석
자동으로 끝난 성공과 사람이 문제를 바로잡은 성공을 구별하려면 개입 이벤트가 필요합니다. 이 글에서는 최초 요청 이후 사람이 추가한 교정·보충 지시를 개입으로 정의합니다. 단순 상태 조회, 시스템의 자동 알림, 최초 요청을 포함할지는 기록 정책에 명시하고 비교 중에는 바꾸지 않습니다.
flowchart TD
A[최상위 task_id 생성] --> B[모델과 도구 이벤트 연결]
B --> C[자식 실행과 재시도 비용 합산]
B --> D[재조회와 재실행 이유 기록]
B --> E[사람 개입 이벤트 기록]
C --> F[종료 상태와 성공 기준 판정]
D --> F
E --> F
F --> G[과업당 최종 집계 레코드 한 줄]
원시 이벤트에는 task_id, 호출 식별자, 부모 호출, 시작·종료 시점, 도구 종류, 모델·설정 버전을 남기는 것이 유용합니다. 그 위에서 rereads, reruns, tool_calls, turns를 합산합니다. 동일 파일을 다시 읽었다고 모두 불필요한 조회가 되는 것은 아니므로 변경 전후 파일 식별값과 조회 이유를 함께 보면 원인을 판별하기 쉽습니다.
reruns도 테스트 통과 확인을 위한 재실행과 유실한 출력을 복원하기 위한 재실행을 구별해야 합니다. 전자는 정상적인 검증일 수 있습니다. 횟수를 무조건 낮추는 목표를 주면 검증을 건너뛰는 쪽으로 최적화될 위험이 있습니다. 먼저 비용 증가 과제를 찾고, 그 과제의 이벤트를 읽는 순서로 사용합니다.
완료되지 않은 실행을 조용히 버리지 않는 것도 중요합니다. 평가 종료 시점에 진행 중인 작업이 있다면 사전에 정한 관찰 시간을 채우거나 시간 초과로 종료하는 정책을 적용합니다. 결과 미확인 작업을 임의로 성공이나 실패에 넣지 말고, 누락 건수와 제외 기준을 별도 보고해야 합니다.
6. Python으로 최종 작업 로그를 집계합니다
다음 예제는 Python 3.10 이상 표준 라이브러리만 사용하는 집계 코드입니다. JSONL 한 줄은 모델 응답 한 번이 아니라 내부 재시도와 자식 실행의 비용을 합산한 최상위 작업의 최종 기록입니다. 금액은 이미 같은 과금 범위의 미국 달러로 정규화했다고 가정합니다. API 호출이나 유료 벤치마크는 수행하지 않습니다.
variant는 비교할 설정 이름입니다. 같은 과제를 다른 설정으로 수행한 경우에는 같은 task_id를 써도 되지만, 같은 설정에서 독립 반복 실행을 했다면 반복 회차까지 포함해 식별자를 구분합니다. 중간 스냅샷과 최종 레코드를 동시에 입력하면 이중 계산되므로, 전체 스크립트는 중복된 (variant, task_id)를 오류로 처리합니다. 비용을 알 수 없는 작업에 0을 넣지 않습니다. 이 예제는 비용이 모두 확인된 기록을 요구하며, 누락 비용을 나타내는 null도 오류로 처리합니다. 실제 운영에서는 비용 미확인 작업 수를 따로 보고하고 정산 후 집계해야 합니다.
핵심 계산은 다음과 같습니다. 뒤에 나오는 전체 스크립트는 이 계산에 종료 상태·숫자·중복 검증과 설정별 묶음을 더한 것입니다.
아래가 실행 가능한 전체 스크립트입니다. task_metrics.py로 저장합니다.
입력은 아래 네 줄을 demo-tasks.jsonl로 저장합니다.
두 파일을 같은 디렉터리에 UTF-8로 저장한 뒤 다음 명령을 실행합니다. 외부 패키지는 필요하지 않습니다.
자신의 로그에 적용하기 전에는 최소한 실패 작업의 비용이 분자에 남는지, 성공이 0건일 때 null이 나오는지, 같은 (variant, task_id) 중복 입력이 오류가 되는지를 직접 확인해 보는 것이 좋습니다.
아래 결과는 실제 제품 실험이 아니라 계산 확인용 합성 데이터 4행의 결과입니다. 설정별로 같은 두 과제가 있고, 각각 한 건만 성공하도록 만들었습니다.
| 지표 | original | compressed |
|---|---|---|
| 전체 과제 수 | 2 | 2 |
| 성공률 | 50% | 50% |
| 전체 비용 | $1.00 | $1.10 |
| 성공한 작업당 비용 | $1.00 | $1.10 |
| 성공 작업의 평균 경과 시간 | 60초 | 100초 |
| 성공 1건당 과업 경과 시간 합 | 100초 | 150초 |
| 전체 작업의 사람 개입률 | 50% | 50% |
| 성공 작업의 사람 개입률 | 0% | 100% |
전체 개입률이 같아도 성공 작업의 개입률은 다를 수 있습니다. 또 실패 과제의 비용을 버리면 original은 $0.60만 쓴 것처럼 보이지만, 성공 한 건을 얻기 위해 평가 묶음 전체에서 지출한 금액은 $1.00입니다. 이것이 최종 응답이나 성공 레코드만 집계해서는 놓치는 부분입니다.
실제 비교에서는 이 표와 함께 성공 기준, 전체 표본 수, 제외 건수, 제한 시간을 제시해야 합니다. 충분한 표본이 쌓이면 작업 종류별 결과와 경과 시간 분포도 비교합니다. 이 작은 예제만으로 비용 차이의 통계적 의미나 압축의 인과 효과를 판정하지 않습니다.
도입 판단은 품질·권한 준수·시간 제한을 먼저 통과시킨 뒤 비용을 비교하는 순서가 적절합니다. 비용이 감소한 설정에서도 재조회와 검증 누락이 늘지 않았는지 살펴봅니다. 모델 내부의 추론 노력을 조절하는 문제는 LLM 추론 수준 선택, 반복 입력의 과금을 줄이는 문제는 Prompt Caching의 손익에서 이어서 볼 수 있습니다.
참고자료
- GitHub, How we make AI coding more cost efficient without sacrificing task quality, 2026-09-02. 제품 개발팀의 실험 사례입니다.
- OpenAI, Research acceleration: The view inside OpenAI, 2026-09-06. 내부 연구 조직의 관찰·분류 분석입니다.
