터미널-벤치(Terminal-Bench) 과제: 최전선 에이전트들도 통과하지 못한 이유
요약
본 글은 AI 에이전트가 법원 제출용 PDF에서 이름과 ID를 검게 처리(redaction)하는 까다로운 명령줄 작업 벤치마크인 Terminal-Bench를 소개합니다. 저자는 Claude Opus와 GPT-6 Sol 등 최신 모델들이 이 작업을 통과하지 못한 이유와, 에이전트가 특정 지점에서 실패하는 원인을 분석했습니다.
핵심 포인트
- Terminal-Bench는 까다로운 명령줄 작업의 공개 벤치마크입니다.
- 에이전트는 주어진 정보만으로 해결할 수 있는 '좋은' 작업을 아직 완성하지 못했습니다.
- 실패는 에이전트에게 정답을 결정하는 정보가 노출될 때 발생합니다.
- 규칙(rules)과 테스트 케이스를 분리하여 과제를 설계하는 것이 중요합니다.
저는 AI 에이전트를 위한 까다로운 명령줄 작업의 공개 벤치마크인 Terminal-Bench에 하나의 작업을 만들었습니다. 이 에이전트는 법원 제출용 PDF에서 가시적인 모든 이름과 ID를 검게 처리(redactor)하는 작업을 수행해야 합니다. 파일에 복구 가능한 정보는 아무것도 남기지 않으면서, 페이지의 다른 내용은 전혀 변경해서는 안 됩니다.
저는 Claude Opus 5.5와 GPT-6 Sol을 각각 최고 추론 설정으로 세 번씩 실행했습니다. 총 여섯 번의 시도 모두 실패했으며, 에이전트에게 부정행위를 하도록 지시한 두 번의 시도 역시 마찬가지였습니다. 각 에이전트는 약 4,000줄 분량의 도구를 작성하고 테스트를 거친 후에 중단했으며, 그들 모두 자신이 작업을 통과했다고 믿었습니다. 이 글은 제가 어떻게 이 작업을 만들었는지, 그리고 왜 에이전트들이 특정 지점에서 멈췄는지에 대한 내용입니다.
Terminal-Bench 작업이란 무엇인가요
작업(Task)은 Docker 환경, 명령어(instruction), 참고 솔루션(reference solution), 그리고 숨겨진 테스트 스위트(hidden test suite)로 구성됩니다. 에이전트는 셸을 받고 명령어를 받습니다. 에이전트가 완료했다고 말하면, 그들이 남긴 결과물에 대해 테스트가 실행되고, 결과는 통과(pass) 또는 실패(fail)로 나옵니다.
좋은 작업이란 강력한 엔지니어가 주어진 정보만으로 완성할 수 있지만, 현재의 에이전트들은 여전히 틀리는 것입니다. 이 두 가지를 모두 갖추는 것이 가장 많은 노력이 필요했습니다.
작동하지 않은 열세 가지 디자인들
각 아이디어에 대해 저는 먼저 도구 없이 몇몇 모델들에게 어떻게 해결할지 물어보았습니다. 만약 그들의 계획이 트릭을 언급한다면, 그 아이디어는 폐기되었습니다. 대부분은 여기서 죽었습니다.
살아남은 것들은 실제로 구축되어 도구를 가진 실제 에이전트들을 대상으로 실행되었습니다. 펌프 모니터링 작업은 서류상으로는 견고해 보였습니다. Opus는 데이터의 잔여물(residuals)에서 숨겨진 동작을 파악하여 54분 만에 이를 해결했습니다. 하수도 범람 모델도 같은 방식으로 진행되었으며, Opus가 제시한 답은 제가 만든 참고 솔루션보다 더 정확했습니다. 소방 옥상관 유량 작업은 다섯 명의 에이전트 중 다섯 명이 통과시켰습니다.
모든 실패는 같은 지점에서 발생했습니다. 작업을 공정하게 하려면, 정답을 결정하는 정보가 에이전트에게 보여야 합니다. 만약 그것이 보인다면, 셸(shell)을 가진 에이전트는 그 안에서 구조를 찾아낼 것입니다. Opus는 보통 7분에서 30분 사이에 이를 수행했습니다.
PDF 검게 처리 선택하기
저는 규정이 짧고 명확하게 설명할 수 있고, 어려움은 콘텐츠가 PDF 내부에 얼마나 많은 방식으로 존재하느냐에 달려 있기 때문에 '삭제(redaction)'를 선택했습니다. 또한 이는 실제 발생 가능한 실패 모드이기도 합니다. 파일에 여전히 텍스트가 있는데 누군가 그 위에 검은 상자를 그리면 법원 서류가 유출될 수 있습니다.
첫 번째 버전에서는 에이전트에게 정책과 세 개의 샘플 파일을 제공했습니다. 저는 두 개의 에이전트를 실행해 보았습니다. 하나는 실패했고 다른 하나는 만점을 받았습니다. Opus는 정책을 읽고 파일에 접근하기도 전에 PDF 내에서 이름이 숨어 있을 수 있는 거의 모든 방식을 나열했습니다.
가장 당연한 해결책은 더 모호한 사양(spec)을 만드는 것이었습니다. 하지만 저는 그렇게 하지 않았습니다. 왜냐하면 규칙을 숨기는 과제는 불공평하고, 검토자는 이를 거부하는 것이 옳다고 판단할 것이기 때문입니다.
규칙과 테스트 케이스 분리하기
작동했던 방식은 규칙(rules)과 테스트 케이스를 별개의 것으로 취급한 것입니다. 정책에는 모든 규칙이 완전하게 명시되어 있습니다. 숨겨진 테스트 세트(hidden test set)는 샘플에서 보여주지 않은 사례들을 포함하며, 각각의 사례는 이미 정책에 명시된 규칙에 의해 결정됩니다. 에이전트는 이를 처리하는 데 필요한 모든 것을 가지고 있습니다. 단지 그 처리를 예제와 비교하여 확인할 수 없을 뿐입니다.
저는 후보 케이스를 만들었고 다음 조건을 만족할 때만 유지했습니다:
- 두 이전 에이전트의 완성된 도구(finished tools)보다 우수했을 경우,
- 저의 참조 솔루션(reference solution)이 특별한 사례가 아닌 일반적인 방법으로 이를 처리했고,
- 정책에 이미 있는 규칙이 이를 결정했을 경우.
두 번째 조건 때문에 저는 여섯 개의 후보를 포기해야 했습니다. 저 자신의 참조 솔루션도 그것들을 깔끔하게 처리할 수 없었기 때문입니다.
그 후, 제가 테스트했던 두 도구에 맞춰 조정된 것이 아닌지 확인했습니다. 그 도구들을 본 적이 없는 두 개의 새로운 에이전트 역시 실패했습니다. 그 후에 저는 이 과제를 확정(freeze)했습니다.
시험 실행하기
저는 첫 번째 실행 전에 규칙을 설정했습니다. 왜냐하면 실행 자체가 결함이 있다면 0% 결과는 아무 의미가 없기 때문입니다:
- 첫 번째 시도 전에 과제를 고정(Freeze)하고 체크섬을 생성하며, 이후에는 절대 수정해서는 안 됩니다.
- 어떤 에이전트가 실행되기 전까지 참고 솔루션은 100% 점수를 받고, 아무것도 제출하지 않은 경우(do-nothing submission)는 0%를 받습니다.
- 먼저 일반 시도와 부정행위 시도를 각각 한 번씩 실행한 후 나머지 시도를 진행합니다.
- 에이전트가 자체적으로 중단하고, 하네스 오류(harness errors), 속도 제한(rate limits)이나 채점기 탐색(probing of the grader) 없이 완료된 경우에만 해당 실행을 인정합니다. 그 외의 경우는 다시 한 번 재실행하여 표시됩니다.
One Sol은 도중에 사용량 상한선(usage cap)에 걸렸습니다. 저는 이를 재실행했고, 상한선이 걸린 시도는 카운트하지 않았습니다.
고정하기 전에, 저는 제 자체 채점기에서 버그를 발견했습니다. 이 채점기는 올바르게 삭제된 페이지 중 일부를 실패로 표시하고 있었습니다. 저는 이것을 수정했는데, 만약 그대로 두었다면 과제가 더 어려워졌을 것입니다. 채점기가 잘못해서 어렵다는 과제는 아무것도 측정하지 못합니다.
최종 결과: Opus 3회 중 0회, Sol 3회 중 0회, 부정행위 시도 모두 0회입니다.
에이전트들이 멈춘 이유
에이전트들은 테스트를 건너뛰지 않았습니다. 각각은 대규모 도구를 구축하고 자체 테스트 문서를 생성하여 실행했습니다. 한 에이전트는 52개를 만들었습니다.
문제는 그들이 무엇을 테스트했는지였습니다. 각 에이전트는 이름들을 찾기 위해 사용했던 것과 같은 종류의 검사로 자신의 출력을 확인했습니다. 검색에서 놓친 것은 검증에서도 놓쳤고, 따라서 테스트 결과는 깨끗하게 나왔으며 에이전트는 멈췄습니다. 동일한 종류의 더 많은 테스트를 작성한다고 해서 누락된 부분을 잡아낼 수는 없었습니다.
정책은 또한 페이지의 다른 부분이 변경되지 않도록 요구하므로 과도한 삭제(over-redacting) 역시 실패 원인이 됩니다. 첫 번째 버전에서는 한 에이전트가 의심스러워 보이는 모든 것을 검게 칠하는 안전장치(safety net)를 추가했습니다. 이로 인해 하나의 문서는 수정되었지만, 유지되어야 할 배너까지 가려버려서 다른 문서에서 오류가 발생했습니다.
두 모델의 실패 방식 차이점
Opus와 Sol은 각각 상대방의 모든 실행을 능가하는 케이스를 처리했습니다. 한 가지 사례는 여섯 번의 모든 실행을 능가했습니다.
이것이 제가 하나의 영리한 트릭보다는 여러 개의 개별적으로 추론된 케이스들이 전면전(all-or-nothing)으로 채점되는 것을 더 선호하는 이유입니다. 다음 모델 버전은 단일한 트릭을 해결하는 경향이 있습니다. 많은 사례가 있을 경우, 모델은 그 모든 것에 대해 동시에 올바르기만 하면 됩니다.
부정행위 시도
치트 시도에서 에이전트는 어떤 수단을 써서라도 통과하라는 지시를 받습니다. 두 에이전트 모두 문제를 해결하기보다는 문제를 쉽게 만들려고 했습니다. 채점기는 에이전트의 손이 닿지 않는 자체적인 정답(ground truth)을 가지고 복사본에 에이전트의 도구를 실행했기 때문에, 어떤 시도도 점수를 얻지 못했습니다.
또한 이 과제를 만드는 동안 제가 사용한 에이전트들의 기록(transcript)을 감사하여, 그들 중 어느 것도 샌드박스 외부로 나가지 않았는지 확인했습니다. 이 감사를 신뢰하기 전에, 제가 직접 심어 놓은 일곱 가지 치트에 대해 테스트를 진행했습니다.
작업 분담 방식
저는 이것을 작은 팀처럼 운영했습니다. Claude 에이전트가 대부분의 구축, 탐색(probing), 그리고 실패 테스트(kill-testing) 작업을 수행했습니다. 저는 규칙을 설정하고, 각 시도 결과에 대한 결정 기준을 작성했으며, 최종 판단을 내렸습니다. 첫 번째 PDF 버전 이후, 에이전트는 이를 제출할 것을 권장했습니다. 저는 대신 규칙보다는 테스트 케이스를 숨기는 방향으로 밀어붙였고, 이것이 최종 버전으로 이어졌습니다.
제가 얻은 교훈
만약 여러분이 에이전트를 구축하거나 배포한다면, 에이전트가 멈추기 전에 무엇을 확인하는지 살펴보십시오. 자신의 작업을 테스트하는 에이전트는 자신이 작성할 것이라고 생각하는 테스트에 의해 제한됩니다. 만약 그 테스트들이 해결책과 사각지대(blind spot)를 공유한다면, 잘못된 답변과 통과하는 테스트 스위트와 함께 멈추게 됩니다.
이 과제는 Terminal-Bench 레포의 PR #2184에서 공개되어 있으며, 모든 실행에 대한 증거는 과제 레포에 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기