EnvHarness: 정적인 벤치마크 환경을 에이전트의 약점에 맞춰 재구성하는 래퍼 계층에 대한 연구

EnvHarness 소개

다 푼 문제집은 더 가르쳐 줄 것이 없습니다

문제집 한 권을 두세 번 반복해서 풀고 나면 어느 순간부터는 답이 아니라 페이지 배치가 기억납니다. 문제집은 그대로인데 내가 달라졌다는 이유만으로 그 책은 더 가르쳐 줄 것이 없어지는데, EnvHarness 는 LLM 에이전트의 학습 환경에서 똑같은 일이 벌어진다는 문제의식에서 출발한 연구로, 이미 만들어진 정적인 벤치마크 환경을 내부 코드 수정 없이 감싸서 특정 에이전트의 약점을 겨냥한 학습 환경으로 바꾸는 방법을 제안합니다. Google Cloud AI Research를 중심으로 워싱턴대학교 세인트루이스(Washington University in St. Louis)와 노스캐롤라이나대학교 채플힐 연구진이 함께 참여했습니다.

LLM이 자율 에이전트로 배치되면서, 학습의 원천은 잘 정제된 텍스트 데이터에서 상호작용 가능한 환경(environment)으로 옮겨가고 있습니다. 웹 페이지를 탐색하든, 코드베이스의 이슈를 해결하든, 체화된(embodied) 플랫폼을 제어하든, 에이전트는 환경으로부터 학습 신호를 얻습니다. 환경은 과제를 제시하고, 변화하는 상태를 관리하며, 행동에 반응하고, 성공 여부를 판정하는 상호작용의 상대역입니다.

문제는 이 상대역을 만드는 비용입니다. 상호작용 로직과 검증기(verifier)를 사람이 일일이 하드코딩해야 하고, 그렇게 만들어진 환경은 경직된 상태로 굳어 버립니다. 어떤 에이전트가 상호작용하든, 그 에이전트가 얼마나 성장했든 환경은 똑같이 동작합니다. 연구팀은 이 경직성이 에이전트 학습을 두 가지 방향으로 제약한다고 지적합니다: 하나는 특정 에이전트의 약점을 겨냥한 학습 신호를 줄 수 없다는 것이고, 다른 하나는 에이전트가 기존 과제를 다 풀고 나면 더 가르쳐 줄 것이 남지 않는다는 것입니다.

기존 접근법과 각각의 한계

환경을 사람이 만드는 비용이 크다 보니, 자동 환경 생성(automated environment generation)이 하나의 연구 흐름으로 자리 잡았습니다. 그러나 연구팀은 이 흐름에 두 가지 한계가 있다고 봅니다.

첫째, 생성 파이프라인은 본질적으로 도메인 특화입니다. 이유는 분명합니다: 새 과제를 만들려면 환경 내부에 손을 넣어야 하고, 그 과제를 채점할 검증기까지 새로 만들어야 하기 때문입니다. 웹 탐색용으로 만든 파이프라인, 프로그래밍용으로 만든 파이프라인, 도구 사용용으로 만든 파이프라인은 서로 옮겨 쓸 수 없습니다. 그래서 논문의 비교에서도 GenEnv 는 ALFWorld에만, VeriEnv 는 WebArena에만, SWE-smith 는 SWE-bench Verified에만 적용할 수 있었고, 나머지 칸은 전부 빈칸으로 남았습니다. 사무 자동화처럼 아예 생성 베이스라인이 존재하지 않는 도메인도 있습니다.

둘째, 정확성을 담보하는 비용이 크고 그마저도 신뢰하기 어렵습니다. 환경과 검증기를 LLM이 생성하기 때문에, 실무에서는 과잉 생성한 뒤 대량으로 걸러내는 방식을 쓰는데도 정확성을 완전히 보장하지는 못합니다. 논문에서는 EnvGen 처럼 시뮬레이터 내부의 설정(맵, 지형 파일 등)을 고쳐 적응시키는 방식과, Agent-World 처럼 실행 가능한 도구와 데이터베이스, 과제를 통째로 합성하는 방식도 함께 비교하면서, 전자는 벤치마크마다 깊은 수작업이 필요하고 후자는 생성된 도구 자체에 로직 오류가 섞여 학습을 멈춰 세울 수 있다고 정리하였습니다.

한편 자기 진화 에이전트(self-evolving agent) 연구는 프롬프트와 반성, 스킬과 워크플로 라이브러리, 경험 메모리, 나아가 에이전트 하네스 자체까지 진화시켜 왔습니다. 그런데 이 흐름에서도 에이전트가 진화하는 동안 에이전트가 학습하는 세계는 고정되어 있습니다.

발상의 전환: 하네스를 반대편에 적용하기

여기서 이 연구의 발상 전환이 나옵니다. 새 환경을 만드는 대신, 이미 있는 환경을 감싸는 것입니다.

에이전트 하네스(agent harness)는 실행 루프, 도구 레지스트리, 컨텍스트 관리 같은 소프트웨어 계층으로 LLM을 감싸 자율 에이전트를 만들어 냅니다. 모델 가중치는 하나도 건드리지 않으면서 능력을 더하는 방식이고, 이를 식으로 쓰면 \text{Agent} = \text{Model} + \text{Harness} 입니다. 연구팀은 같은 아이디어를 에이전트와 환경이 맞물리는 고리의 반대편에 적용합니다.

\text{Customized Env} = \text{Static Env} + \text{EnvHarness}

EnvHarness는 기존의 정적인 환경을 감싸서 제어 가능한 환경으로 바꾸는 프로그래머블 계층입니다. 표준 인터페이스를 통과하는 정보의 흐름만 손대고, 그 아래에 있는 환경은 전혀 건드리지 않습니다. 인터페이스 수준에서만 동작한다는 성질 덕분에 두 가지 이득이 한꺼번에 따라옵니다: 하나는 도메인에 무관하게 적용된다는 것이고, 다른 하나는 재구성된 모든 환경이 원본 환경의 사람이 만든 검증기를 그대로 물려받는다는 것입니다. 새로 만든 환경의 채점을 LLM에게 맡기지 않아도 됩니다.

실험 결과, 4개 도메인 5개 벤치마크에서 EnvHarness 환경으로 학습한 에이전트는 원본 환경으로 학습한 에이전트를 모든 벤치마크에서 앞섰고, 미학습 과제에서 최대 9.0 포인트를 더 얻으면서 상호작용 스텝은 9.8\% 더 적게 썼습니다. 강화학습에서도 더 강한 정책(policy)을 만들어 냈고, 커스터마이징을 반복하면 사람이 만든 환경과 생성된 환경이 모두 평평해지는 지점에서도 성능이 계속 올라갔습니다.

EnvHarness: 환경을 감싸는 프로그래머블 계층

환경을 튜플로 보고, 무엇을 바꾸고 무엇을 남길지 정하기

연구팀은 환경을 튜플 E = (\mathcal{S}, \mathcal{A}, \mathcal{O}, T, R, s_0) 로 모델링합니다. 각각 상태 공간, 행동 공간, 관측 공간, 상태와 행동을 다음 상태로 옮기는 전이 함수, 검증기가 유도하는 보상, 초기 상태입니다. EnvHarness 컴포넌트는 여기에 적용되는 환경 무관 변환 w 입니다.

E' = w(E), \qquad E' = (\mathcal{S}', \mathcal{A}', \mathcal{O}', T', R', s_0')

이 정의에서 가장 중요한 것은 무엇을 바꾸지 않는가입니다. w 는 초기 상태 s_0' 를 조정하고, 노출되는 공간 \mathcal{A}'\mathcal{O}' 를 걸러 내고, 전이 역학 T' 를 갱신하지만, 시뮬레이터 백엔드와 구현 세부는 손대지 않습니다. 개입이 전부 외부에 머무르기 때문에 정답 판정 로직이 보존되고, 원본 검증기가 그대로 에피소드를 채점할 수 있습니다.

에이전트 하네스와의 대응 관계를 논문에서는 다음과 같이 정리하였습니다.

에이전트 하네스 EnvHarness
기반 시스템 고정된 LLM 정적인 환경
해결하려는 문제 행동, 기억, 루프의 부재 하드코딩된 상호작용 로직
하네스 계층이 더하는 것 능력(도구, 메모리) 제어(상태, 규칙, 관측)
결과물 자율 에이전트 커스터마이징된 환경

두 경우 모두 핵심 시스템을 바꾸는 대신 외부 계층을 덧붙여 능력을 확장한다는 점이 같습니다.

세 가지 컴포넌트

w 를 따르는 변환이면 무엇이든 유효한 EnvHarness 컴포넌트이고, 이 논문은 그중 환경 커스터마이징의 세 가지 기본 방식을 덮는 컴포넌트를 제시합니다. 각 컴포넌트는 자기만의 파라미터를 가지며 reset 이나 step 같은 표준 인터페이스 메서드를 재정의합니다.

논문은 세 컴포넌트를 ALFWorld의 한 과제, "깨끗한 머그컵을 책상 위에 놓아라" 위에서 설명합니다. 기본 인스턴스에서는 머그컵이 눈에 보이는 곳에 놓여 있고, 컵을 내려놓는 순간 에피소드가 끝납니다.

Stage: 초기 상태를 바꾸는 컴포넌트

Stage w_{\mathrm{stage},\delta} 는 상태 조작 행동의 시퀀스 \delta = (a_1, \ldots, a_k) 로 지정됩니다. 이 행동들은 reset() 이 만들어 낸 초기 상태 s_0 에 순서대로 적용됩니다.

s_0' = T(\cdots T(T(s_0, a_1), a_2) \cdots, a_k)

이 변환에서 바뀌는 것은 초기 상태뿐입니다. Stage는 에이전트의 출발점을 바꿔서, 특정 스킬을 요구하는 장애물을 심어 놓거나 반대로 초반 하위 목표를 미리 완료해 과제의 길이를 줄입니다. 예시 과제에서 한 Stage는 take mug 1, open drawer 1, put mug 1 in drawer 1, close drawer 1 을 차례로 실행합니다. 머그컵을 서랍에 감춰 버리는 것인데, 눈에 보이는 컵을 그냥 집어 오면 되던 과제가 먼저 물건을 찾아야 하는 과제로 바뀝니다. 반대 방향으로도 쓸 수 있어서, 컵을 미리 씻어 둔 채로 시작하면 마지막 배치 단계만 남습니다.

구현 관점에서 Stage가 우아한 부분은 환경 내부에 대한 특권적 접근이 전혀 필요 없다는 점입니다. reset() 이 호출되면 안쪽 환경을 먼저 리셋한 다음 \delta 의 행동을 평범한 inner.step() 인터페이스로 재생하고, 재생이 끝난 시점의 관측을 에피소드의 초기 관측으로 돌려줍니다. 그래서 변형된 시작 상태는 언제나 도달 가능한 상태이며, 저장해야 하는 것도 행동 목록 하나뿐입니다. 재생이 끝나면 notify_replay_complete() 를 호출해서, 준비 단계에 쓴 스텝이 에이전트의 스텝 예산에 잘못 청구되지 않도록 안쪽 환경이 카운터를 되감게 합니다.

Contract: 상호작용을 다시 쓰는 컴포넌트

Contract w_{\mathrm{contract},r} 는 변환 맵 세 개의 조합 r = (f_A, f_T, f_O) 로 지정되며, 각각 항등 함수가 기본값입니다. 이 맵들은 행동 공간, 전이 역학, 관측 공간을 각각 다시 씁니다.

(\mathcal{A}', \mathcal{O}', T') = \big(f_A(\mathcal{A}), f_O(\mathcal{O}), f_T(T)\big)

실제로는 행동의 사전 조건을 강제하거나, 관측을 덧붙이거나 가리거나, 특정 결과에 구조화된 피드백을 붙여 학습 방향을 유도하는 데 쓰입니다. 예시 과제에서 한 Contract는 f_O 로 방 설명을 앞 두 문장까지만 남겨서, 에이전트가 공간에 대한 표상을 여러 스텝에 걸쳐 쌓도록 만듭니다. 다른 Contract는 f_T 로 컵을 들고 있지 않은 상태의 clean mug 행동을 막아, 물건을 먼저 집게 강제합니다. 또 다른 Contract는 f_A 로 고수준 순간이동 이동 명령을 제거해서, 한 걸음씩 움직이며 탐색하게 만듭니다.

세 훅은 각각 filter_action, modify_transition, filter_observation 으로 구현되어 있고, 설계자 에이전트가 내놓는 산출물은 바로 이 훅들을 재정의한 파이썬 서브클래스의 소스 코드 그 자체입니다. Contract 컴포넌트가 저장하는 상태도 그 소스 문자열입니다. 불러올 때는 추상 데이터 타입만 노출된 네임스페이스에서 다시 컴파일하고, 컴파일된 코드는 에피소드마다 별도의 서브프로세스 안에서 실행됩니다. 생성된 코드가 잘못되었을 때 프레임워크 전체가 아니라 에피소드 하나만 죽게 하려는 설계입니다.

경계 하나도 의도적으로 그어져 있습니다. 차단된 행동은 환경을 전혀 건드리지 않고, 다시 관측한 뒤 f_O 로 걸러진 현재 상태를 차단 사유와 함께 돌려줍니다. 거절이 에이전트를 오도 가도 못하게 만들지 않습니다. 그리고 Contract는 s_0R 도 구현하지 않습니다: 초기 상태는 Stage의 몫이고, 최종 성공 판정은 끝까지 벤치마크 자신의 결정으로 남습니다.

Chain: 환경을 이어 붙이는 컴포넌트

Chain w_{\mathrm{chain},\ell} 은 추가 환경 E_{\mathrm{ext}} 와 합성 로직 g 의 쌍 \ell = (E_{\mathrm{ext}}, g) 로 지정됩니다. 합성 로직은 원본 환경 EE_{\mathrm{ext}} 를 하나의 합성 환경으로 묶고, 그 결과도 같은 인터페이스로 노출됩니다.

E' = g(E, E_{\mathrm{ext}}), \qquad \mathcal{A}' = \mathcal{A} \cup \mathcal{A}_{\mathrm{ext}}

합성 로직 g 에는 제약이 없습니다. 논문 부록은 네 가지 모드를 예시 코드로 보여 주는데, 기본값인 순차 연결, 첫 과제의 성공 여부에 따라 더 어려운 환경과 보충 환경으로 갈라 보내는 분기, 특정 행동이 관측되는 즉시 과제가 끝나기를 기다리지 않고 넘기는 도중 전환, 매 스텝 두 환경을 오가는 교차 배치입니다. 넷 모두 modify_transition 훅에서 switch_to() 를 부르는 방식으로 구현되며, 다만 이 논문의 실험은 전부 순차 연결만 사용합니다. 예시 과제에서 한 Chain은 같은 집 안에서 "감자를 데워 조리대 위에 올려라" 를 뒤에 덧붙이고, 두 환경이 모두 검증을 통과할 때만 성공으로 판정합니다. 원래대로라면 멈췄을 지점을 넘어서까지 목표를 이어 가는 법을 배우게 만드는 것입니다.

에이전트는 환경 A 의 과제가 끝날 때까지 상호작용한 뒤 이어 붙인 전환 관측을 받아 환경 B 로 넘어가는데, 이때 스텝 예산은 두 환경이 함께 씁니다. Chain은 하위 환경들의 종료 신호를 가려서, 에피소드가 언제 끝날지는 합성 환경만 결정하게 합니다. 합성된 판정은 R' = R_A \wedge R_B 의 논리곱이고, 각 항은 해당 하위 환경 자신의 검증기가 결정합니다. 이어 붙인 과제는 양쪽 부모로부터 신뢰할 수 있는 검증을 그대로 물려받습니다. 구현 측면에서는 두 번째 환경을 인계 시점에 지연 리셋해서, 첫 번째 환경에서 일찍 실패했을 때 컨테이너나 브라우저 기동 비용을 물지 않도록 했습니다.

컴포넌트의 합성

세 컴포넌트가 모두 같은 표준 인터페이스를 공유하므로 자유롭게 겹쳐 쌓입니다. 머그컵 과제에 셋을 모두 쌓으면 하나의 합성 환경이 됩니다.

E' = w_{\mathrm{chain},\ell}\left(w_{\mathrm{contract},r}\left(w_{\mathrm{stage},\delta}(E)\right)\right)

이 구성에서 Stage는 머그컵을 서랍에 숨겨 공간 탐색을 강제하고, Contract는 관측을 두 문장으로 잘라 부분 관측성을 시험하며, Chain은 후속 과제를 덧붙여 목표 지속성을 시험합니다. 다만 이 변환들은 교환 법칙이 성립하지 않습니다(w_1 \circ w_2 \neq w_2 \circ w_1 ). 중첩 순서가 결과 환경의 구성 방식과, 어떤 제약이 초기화 단계에 걸리고 어떤 제약이 상호작용 중에 걸리는지를 결정합니다.

코드에서는 이 중첩이 데코레이터 패턴으로 구현되어 있습니다. EnvHarness 자체가 다른 ActionableEnv 를 감싸는 ActionableEnv 이므로, Rules(Setup(Toy24Bridge)) 역시 다시 하나의 ActionableEnv 이고, 가장 바깥 계층과 상호작용하는 에이전트는 그 아래에 컴포넌트가 몇 겹 깔려 있는지 알 수 없습니다.

EnvRigger: 커스터마이징을 자동화하는 설계자 루프

EnvHarness는 어디에나 적용되는 틀이지만, 구체적인 설정은 대상 정책과 과제마다 달라야 합니다. 그러면 이 설정을 누가 정해 줄까요? 연구팀이 내놓은 답이 EnvRigger 입니다.

EnvRigger가 실현하는 것은 과제와 정책에 조건화된 사상 \mathcal{H} 입니다.

E' = \mathcal{H}(E, t; \pi) = (w_k \circ w_{k-1} \circ \cdots \circ w_1)(E)

컴포넌트 하나하나는 정책과 무관합니다. 식 w 가 환경만의 변환으로 정의되어 있으므로 같은 컴포넌트를 어떤 정책에든 수정 없이 적용할 수 있습니다. 반대로 어떤 컴포넌트를 어떤 파라미터로 고를지는 기본 과제 t 와 정책 \pi 의 관측된 행동 양쪽에 조건화되어야 합니다. EnvRigger는 모델 내부 가중치를 들여다보지 않고 출력만 가지고 이 선택을 수행합니다.

Observe: 기준선 롤아웃 관찰

EnvRigger는 먼저 현재 환경에서 기본 과제에 대해 정책 \pi 를 실행하고, 롤아웃(rollout) 궤적을 모아 분석합니다. 논문의 하이퍼파라미터에서 과제당 기준선 롤아웃은 5회입니다.

여기서 실패만 보지 않는다는 점이 중요합니다. 실패는 이 과제 안에서 다뤄야 할 약점을 드러내지만, 성공은 그 약점의 경계를 정의해 줍니다. 어떤 능력이 이미 온전하고 어디서부터 무너지기 시작하는지는 성공 궤적 쪽에서 읽힙니다.

Diagnose: 근본 원인 진단과 방향 결정

수집한 궤적에서 관찰된 행동의 근본 원인을 찾아냅니다. 같은 행동을 반복하는 루프, 긴 관측을 파싱하지 못하는 실패, 도구 제약을 잘못 읽는 문제처럼 계통적인 사안에 초점을 둡니다.

이 진단이 커스터마이징의 방향까지 정합니다. 정책이 고전하고 있으면 목표는 빠진 단계를 떠받쳐 주고 과제를 단순하게 만드는 쪽입니다. 반대로 정책이 완벽한 성공률을 내고 있으면, 현재 환경이 남은 약점을 드러내기에는 지나치게 관대하다는 신호로 읽습니다. 이 경우 EnvRigger는 환경을 더 어렵게 만들어야 한다고 진단하고, 잠재적 결함이 표면으로 드러나도록 더 도전적인 시나리오를 주입하는 쪽으로 방향을 틉니다.

Write: 컴포넌트 작성

진단을 바탕으로 지목된 결함을 겨냥하는 컴포넌트를 하나 이상 합성합니다. 결함 하나가 여러 컴포넌트의 조합을 필요로 할 수도 있어서, 초기 상태를 조정하는 Stage와 이후 상호작용을 거르는 Contract를 한 후보 집합으로 함께 내놓기도 합니다. 한 후보에 들어가는 컴포넌트 개수에는 상한이 없고 몇 개가 필요한지는 설계자가 정하는데, 수용과 기각은 컴포넌트 하나씩이 아니라 후보 집합 통째로 이뤄집니다.

예를 들어 정책이 학습을 우회하는 취약한 지름길에 의존하고 있다고 진단되면, EnvRigger는 특정 조건에서 그 행동을 막는 Contract를 작성합니다. 정책은 이제 탐색을 해서 의도된 스킬을 익힐 수밖에 없게 됩니다.

Validate: 새 롤아웃으로 검증

작성된 후보로 현재 환경을 감싸 E' 를 만들고, 같은 기본 과제 위에서 정책 \pi 의 롤아웃을 새로 5회 돌립니다. 성공률과 실패 분포 같은 궤적 지표를 보고 세 가지 중 하나를 결정합니다: 후보를 수용하거나, 풀 수 없거나 도전적이지 않은 후보를 기각하거나, 신호의 크기가 어긋난 후보를 다듬는 것입니다.

다듬기가 필요하면 궤적과 조정 피드백이 Write 단계로 되돌아가고, 후보가 수용되거나 수정 예산이 소진될 때까지 이 Write와 Validate 루프가 반복됩니다. 논문의 설정에서 수정 예산은 인스턴스당 5회이고, 수용된 컴포넌트는 최종적으로 EnvHarness에 추가됩니다. 예산을 다 쓰고도 수용되는 후보가 없으면 그 인스턴스는 컴포넌트를 하나도 내놓지 못한 채 끝납니다. 판정은 언제나 롤아웃 5회를 모아 본 성공률과 실패 분포, 타임아웃 횟수로 내리고 궤적 하나만 보고 내리지 않습니다.

설계자 프롬프트가 명시해 둔 것들

논문 부록에 공개된 설계자 시스템 프롬프트를 보면, 이 루프가 실제로 어디서 어긋나는지에 대한 연구팀의 경험이 그대로 드러납니다. 특히 눈에 띄는 지침을 살펴보겠습니다.

가장 강하게 명시해 둔 것은 과제를 풀 수 없게 만들지 말라는 것입니다. 성공을 불가능하게 만드는 변형은 난이도 상승이 아니며, 불가능해서 나온 성공률 0 은 너무 쉬워서 나온 성공률 1 과 정확히 같은 정도로 쓸모없다고 적혀 있습니다. 직전 변형이 풀 수 없었다는 신호(대부분의 롤아웃이 타임아웃으로 끝나거나, 실패가 행동 축을 가리키며 성공률이 0 인 경우)가 잡히면 다음 제안은 문제가 된 제약을 되돌리거나 느슨하게 만들어야 하고, 금지 규칙을 더 쌓아서는 목표 구간으로 올라갈 수 없습니다.

기준선을 읽는 법도 세 가지로 지정되어 있습니다: 정책이 애초에 이 과제를 풀 수 있는지(기준선 성공률이 거의 0 이면 "더 어렵게" 는 말이 되지 않으므로 떠받쳐 주거나 건너뜁니다), 어떻게 푸는지(4스텝 해법은 30스텝 해법보다 여유가 적으므로 변형의 크기를 그 여유에 맞춥니다), 그리고 환경의 어느 부분에 실제로 의존하는지(쓰지도 않는 명령을 흔들어 봐야 의미가 없습니다)입니다.

다듬기 단계의 지침도 구체적입니다. 이 변형이 성공률을 목표 구간 쪽으로 옮겼다면 변형의 종류가 맞은 것이므로 동작하는 훅은 글자 그대로 유지하고 크기만 조정하며, 롤아웃 5회의 신호를 치르고 얻어 낸 코드를 버리지 않습니다. 옮기지 못했다면 다른 종류의 변형으로 처음부터 다시 시작합니다.

마지막으로 보상 축 R 은 설계자에게 아예 노출되지 않습니다. 성공은 벤치마크 자신의 판정이므로, 보상을 재구성하는 것으로는 평가 지표를 움직일 수 없다는 것이 프롬프트에 명시되어 있습니다.

실험 설계

벤치마크와 평가

연구팀은 4개 도메인에 걸친 5개 벤치마크에서 실험했습니다. 텍스트 기반 체화 환경으로는 ALFWorld, 웹 상호작용으로는 WebArena, 소프트웨어 엔지니어링으로는 SWE-bench Verified, 사무 자동화로는 OfficeQA와 SpreadsheetBench 입니다. 각 벤치마크의 고유 지표를 보고하되, SWE-bench Verified에서는 실행 효율의 척도로 평균 스텝 수를 함께 추적했습니다.

학습과 평가 에피소드는 모든 벤치마크에서 엄격히 분리했습니다.

벤치마크 학습 평가
ALFWorld 표준 학습 세트에서 100개 과제 나머지 미학습 과제 전체
WebArena 하위 도메인당 20개 과제 나머지 과제 전체
SWE-bench SWE-bench Lite에서 100개 과제 Lite에 없는 Verified 이슈 407개
OfficeQA 공식 분할의 50개 과제 공식 테스트 과제 172개
SpreadsheetBench 검증된 400개 중 100개 과제 미학습 과제 299개(인스턴스 897개)

이 표에서 한 가지를 더 짚어야 합니다. 학습 과제는 설계자 에이전트가 재구성하는 코퍼스이지만, 평가는 재구성하지 않은 원본 과제로만 이뤄집니다. EnvHarness 환경에서 익힌 스킬을 손대지 않은 벤치마크로 되가져와 시험하는 구조라서, 성능 향상이 환경을 쉽게 만들어 얻은 것일 가능성이 설계 단계에서 차단됩니다. ALFWorld의 In-Dist와 OOD도 연구팀이 나눈 분할이 아니라 벤치마크 자체의 seen과 unseen 평가 분할이며, 과제의 물체와 수납처 조합이 학습 중에 등장했는지로 갈립니다.

여기서 중요한 통제가 하나 더 있습니다. EnvRigger와 정책 에이전트는 벤치마크마다 같은 모델 백본을 씁니다. ALFWorld와 WebArena에서는 Gemini 3.1 Flash-Lite, 나머지에서는 Gemini 3.5 Flash입니다. 성능 향상이 더 강한 외부 모델을 증류(distillation)해서 얻어진 것이 아님을 보장하려는 설계입니다.

학습 방식으로는 스킬 기반 학습(skill-based learning)을 주로 다룹니다. EnvRigger가 만든 환경에서 궤적을 모으고, ReasoningBank 방식으로 그 궤적에서 스킬을 추출한 뒤, 스킬을 장착한 정책 에이전트를 미학습 인스턴스에서 평가합니다. Chain 컴포넌트는 이 자동 파이프라인에서 제외했는데, 이어 붙인 환경들의 내부 상태를 EnvRigger가 관찰하기 어렵기 때문입니다. Chain의 효과는 별도 분석으로 다룹니다.

비교 대상

스킬의 출처를 네 가지로 나눠 비교했습니다: 스킬 없이 정책 에이전트만 쓰는 No Skills, 원본 환경에서 추출한 스킬로 재구성 효과만 분리해 내는 Original Envs, 그리고 각 벤치마크에 해당하는 도메인 특화 생성 베이스라인(GenEnv, VeriEnv, SWE-smith)입니다. 공정한 비교를 위해 모든 베이스라인이 같은 시드 인스턴스, 같은 환경 개수, 같은 추출 파이프라인, 같은 정책 모델을 공유하므로, 차이는 데이터나 모델이나 생성량이 아니라 생성 전략에서 나옵니다. EnvRigger는 베이스라인과 동일한 오라클 검증 권한 아래 오직 학습 에피소드에서만 동작하며, 평가 인스턴스는 하나당 한 번씩만 시도합니다. 그래서 아래 성공률은 여러 번 시도해 하나만 맞아도 인정하는 값이 아닙니다.

실험 결과

정적인 환경이 못 하는 일을 해냅니다

EnvHarness가 커스터마이징한 환경에서 얻은 스킬은 모든 벤치마크에서 원본 환경에서 추출한 스킬을 앞섰습니다. ALFWorld와 WebArena 결과는 다음과 같습니다.

스킬 출처 ALFWorld In-Dist ALFWorld OOD ALFWorld 평균 WebArena 평균
No Skills 62.6 60.7 61.7 38.7
Original Envs 63.3 61.4 62.4 38.5
GenEnv 63.3 61.9 62.6 해당 없음
VeriEnv 해당 없음 해당 없음 해당 없음 39.6
EnvHarness Envs \mathbf{66.2} \mathbf{70.4} \mathbf{68.3} \mathbf{41.6}
개선폭 +2.9 +9.0 +5.9 +3.1

모든 수치는 독립 실행 3회의 평균입니다. ALFWorld의 미학습 분포(OOD)에서 9.0 포인트를 얻은 것이 최대 개선폭입니다.

나머지 세 벤치마크 결과는 다음과 같습니다.

스킬 출처 SWE-verified 성공률 SWE-verified 평균 스텝(낮을수록 좋음) OfficeQA EM(Exact Match) SpreadsheetBench Pass@1
No Skills 47.67 53.58 54.23 46.44
Original Envs 49.88 55.01 54.40 45.88
SWE-smith 50.12 54.72 해당 없음 해당 없음
EnvHarness Envs \mathbf{52.58} \mathbf{49.61} \mathbf{56.20} \mathbf{49.15}
개선폭 +2.70 -5.40 +1.80 +3.27

주목할 대목은 Original Envs 행입니다. 정적인 기본 환경에서 스킬을 추출하면 성능이 오히려 떨어질 수 있습니다. SpreadsheetBench에서 원본 환경 스킬은 45.88 로 스킬 없는 기준선 46.44 보다 낮고, SWE-bench Verified에서는 실행 궤적을 53.58 스텝에서 55.01 스텝으로 늘려 놓았습니다. 정적인 환경은 에이전트가 이미 수행하고 있는 행동만 연습시키기 때문에, 중복되거나 최적이 아닌 스킬을 건져 올리기 쉽다는 것이 연구팀의 설명입니다. 반면 EnvRigger의 Write와 Validate 루프는 새 정책 궤적으로 검증된 컴포넌트만 확정하므로, 모든 벤치마크에서 스킬 없는 기준선보다 나은 결과를 유지했습니다.

하나의 인터페이스로 도메인을 가로지릅니다

인터페이스 프로토콜, EnvRigger 루프, 스킬 추출 파이프라인은 5개 벤치마크 전체에서 동일하게 적용되고, 도메인마다 달라지는 것은 프롬프트 템플릿 정도입니다. 반면 특화된 생성 베이스라인은 자기 벤치마크를 벗어나지 못합니다.

구현 수준에서 이 주장을 떠받치는 것은 브릿지(Bridge) 계층입니다. 저장소에는 브릿지가 7개 들어 있고 그 아래 런타임은 네 종류로 완전히 다릅니다: 순수 인메모리 산술 게임(Toy24), 텍스트 어드벤처 엔진(TextWorld 위의 ALFWorld), 인스턴스별로 띄우는 도커 컨테이너(SWE-bench, OfficeQA, SpreadsheetBench이며 매 스텝이 과제 저장소에 대한 무상태 docker exec 입니다), Playwright로 움직이는 브라우저(BrowserGym 위의 WebArena와 WebShop)입니다. 런타임을 아는 계층은 브릿지 하나뿐이고, 그 위쪽의 정책 루프와 오케스트레이터, 모든 컴포넌트 코드는 7개 환경에서 글자 그대로 같은 코드가 동작합니다.

적용 가능한 자리에서도 EnvHarness가 앞섰습니다. ALFWorld에서 GenEnv를 평균 5.7 포인트, 미학습 분포에서는 8.5 포인트 앞섰습니다. 연구팀은 일반적인 인스턴스 생성이 정책의 약점을 다루지 않은 채 반복 연습만 늘린다고 해석합니다. SWE-bench Verified에서는 이 벤치마크를 위해 만들어진 SWE-smith보다 성공률에서 2.46 포인트 높으면서 에피소드당 실행 스텝은 5.11 스텝 적게 썼습니다.

낭비되는 행동을 고쳐 효율을 올립니다

효율 개선은 진단 내용과 직접 연결됩니다. SWE-bench Verified에서 EnvHarness 환경의 스킬은 에피소드당 평균 스텝을 53.6 에서 49.6 으로 줄인 반면, 원본 환경의 스킬은 오히려 55.0 으로 늘렸습니다. 반복 행동 루프를 깨뜨리고 장황한 관측을 걸러 내도록 겨냥된 Contract와 Stage가 실행 궤적을 실제로 짧게 만들었다는 것이 연구팀의 분석입니다.

추가 분석

강화학습의 학습 신호로도 동작합니다

스킬 기반 학습을 넘어, 재구성된 환경이 온라인 강화학습(reinforcement learning)에서 능동적인 학습 신호가 될 수 있는지도 확인했습니다. ALFWorld와 WebShop에서 Qwen3-8B-base를 정책으로 두고 GRPO(Group Relative Policy Optimization) 로 최적화했습니다. 원본 정적 환경에서만 학습한 정책과 EnvHarness로 재구성된 환경에서만 학습한 정책을 만들어 같은 미학습 인스턴스에서 평가했습니다. 학습은 NVIDIA H100 8장을 단 노드 하나에서 이뤄졌고, 에피소드 최대 길이는 50스텝, 총 150 에폭을 돌렸습니다.

학습 세트 ALFWorld In-Dist ALFWorld OOD ALFWorld 평균 WebShop 점수 WebShop 성공률
Original Envs 81.4 \mathbf{89.6} 85.5 75.6 66.0
EnvHarness Envs \mathbf{87.9} 88.8 \mathbf{88.4} \mathbf{79.2} \mathbf{67.4}

평균을 제외한 네 지표 중 세 지표에서 EnvHarness 환경이 앞섰고, ALFWorld의 미학습 분포에서만 88.889.6 으로 소폭 뒤졌습니다. 논문이 강화학습 쪽 대표 수치로 내세운 것은 ALFWorld 분포 내 성공률로, 81.4 에서 87.96.5 포인트 올랐습니다. 재구성된 환경이 보조 데이터에 머무르지 않고 온라인 정책 학습에 대한 독립적인 최적화 신호를 제공한다는 것이 연구팀의 결론입니다.

Chain은 장기 과제를 효율적으로 풀게 만듭니다

Chain 컴포넌트는 무작위로 짝지은 두 기본 환경을 하나의 확장된 에피소드로 잇습니다. 효과를 분리하기 위해 이 짝짓기는 자율 EnvRigger 루프와 무관하게 동작시켰고, 추출한 스킬은 표준 단일 환경 테스트 인스턴스에서 평가했습니다.

스킬 출처 성공률 평균 스텝(낮을수록 좋음)
No Skills 47.67 53.58
Original Envs 49.88 55.01
EnvHarness (Stage와 Contract만) 52.58 49.61
EnvHarness (Chain만) 49.63 \mathbf{41.96}
결합 스킬 (셋 모두) \mathbf{54.30} 43.12

Chain 환경의 스킬은 평균 스텝을 53.58 에서 41.96 으로 크게 줄였습니다. 단독 성공률 49.63 은 기준선 49.88 보다 아주 조금 낮은데, 성공하려면 양쪽 절반을 모두 풀어야 하는 엄격한 학습 조건이 짧은 과제의 성공률 극대화보다 장기 목표 유지를 우선하게 만들었기 때문이라고 연구팀은 설명합니다. 두 스킬 집합을 결합하면 최고 성공률 54.30 과 준수한 효율 43.12 스텝을 동시에 달성해서, 두 종류의 행동이 서로 보완적임을 보여 줍니다.

Chain 환경에서 어떤 스킬이 나왔는지를 보면 스텝이 줄어든 이유가 드러납니다. 연구팀이 대표 사례로 든 것은 이어 붙은 과제 전체를 하나의 유한한 예산으로 보고 첫 과제를 "충분히 좋은" 수준에서 마무리해 두 번째 과제에 자원을 남기는 행동과, 과제가 바뀐 직후 conda env listwhich python 같은 정찰을 먼저 수행해 달라진 환경 설정을 파악하는 행동이었습니다. 둘 다 과제를 하나만 풀 때는 나타날 이유가 없고, 환경을 이어 붙였기 때문에 비로소 학습되는 행동입니다.

환경을 늘릴수록 계속 올라갑니다

환경 스케일링 실험은 동일한 예산 아래 세 가지 할당 전략을 비교합니다: EnvHarness 환경, 수정하지 않은 벤치마크 환경, SWE-smith가 생성한 환경입니다. 정책 모델과 환경 예산, 스킬 검색 프로토콜을 고정한 채 환경 50개마다 스킬 뱅크 하나를 만들고, 환경 300개 시점에서 총 15개 스킬이 쌓이게 했습니다.

결정적인 차이는 배치를 고르는 방식에 있습니다. 두 베이스라인은 학습자와 무관하게 환경 배치를 독립적으로 고르는 반면, EnvHarness는 이전까지 축적된 스킬을 장착한 현재 정책을 겨냥해 각 배치를 합성합니다. 환경과 정책이 함께 진화하는 구조입니다.

그 결과 EnvHarness는 47.67 에서 54.797.12 포인트 올라갔고, 환경 300개 시점에서도 상승세를 유지했습니다. 같은 예산으로 원본 환경은 52.13, 생성 환경은 50.37 에 그쳤습니다. 학습자의 현재 능력 경계를 겨냥하는 것이 조건 없는 환경 확장보다 근본적으로 효과적임을 보여 주는 결과입니다.

라운드마다 진단이 다른 층을 겨냥합니다

환경을 늘릴 때 성능이 올라간다는 것 외에, 라운드마다 추출되는 스킬의 성격이 달라진다는 관찰도 함께 공개되었습니다. 연구팀은 SWE-bench Verified의 각 라운드에서 나온 스킬을 그 스킬을 유발한 컴포넌트와 짝지어 실었는데, 겨냥되는 결함이 라운드마다 다른 층으로 옮겨 갑니다.

1라운드의 기본 정책은 테스트를 안정적으로 호출하지도, 주어진 도구로 파일 수정을 적용하지도 못합니다. 그래서 이 라운드의 스킬은 기초적입니다: 첫 실패에서 즉시 멈춰 테스트 스위트 타임아웃을 피하는 pytest -x, 통합 diff를 정확히 적용하는 patch -p1 << 'EOF', 디렉터리 전체 대신 정확한 테스트 파일 경로를 지정하기입니다.

2라운드가 되면 그 실패는 대부분 사라지고, 남은 실패가 한 층 위로 올라갑니다. 테스트 진입점 자체가 깨지고, 정확히 겨냥한 실행조차 자원 제한에 강제 종료되며, 파일 인자마저 통제됩니다. 이 라운드의 스킬은 CLI가 망가졌을 때 python -c "import pytest; pytest.main([...])" 로 우회하기, 프로세스 강제 종료를 피하려 pytest -k 로 테스트 케이스를 걸러 내기가 됩니다. 연구팀은 이런 실패 양상이 동작하는 명령줄을 전제하고 있던 1라운드 뱅크에는 하나도 없었다고 짚습니다.

3라운드에서 정책은 테스트 러너를 안정적으로 다루고, 남은 것은 셸의 아래와 주변입니다. PATH를 통한 인터프리터 해석과, 값싼 제자리 수정이 막힌 뒤에 필요해진 탐색 습관입니다. 이 라운드의 스킬은 conda 환경의 절대 경로 바이너리를 직접 호출하기, grep -rn 으로 예외 처리 경로와 참조 구현을 찾기입니다.

여기서 연구팀은 이 루프가 잘 돌지 않는 지점도 함께 보고합니다. 3라운드에 이르면 학습 과제의 약 3분의 1에서 2라운드 정책이 기준선 롤아웃 전부를 성공시킵니다. EnvRigger는 이를 환경을 더 어렵게 만들라는 신호로 읽지만, 그렇게 내놓은 후보들이 검증에서 줄줄이 기각됩니다. 성공률이 그대로이거나 아예 0 으로 떨어져 버려서, write와 validate 루프가 수정 예산을 다 쓰고도 수용된 컴포넌트를 내놓지 못합니다. 이 과제들은 3라운드 뱅크에 아무것도 기여하지 못합니다. 라운드가 갈수록 개선폭이 줄어드는 것도 같은 맥락으로, 남은 결함이 점점 국소적이어서 겨냥하기가 어려워지기 때문입니다.

백본을 가리지 않습니다

일반화 가능성을 확인하기 위해 SWE-bench Verified에서 성능대가 다른 4종의 모델을 시험했습니다. Gemini 3.1 Flash-Lite, Qwen3.6 27B, Gemini 3.5 Flash, Claude Sonnet 4.6이며, 오픈 웨이트와 상용 모델을 모두 포함합니다. 각 설정에서 대상 정책과 EnvRigger에 같은 모델 백본을 씁니다.

스킬 출처 Gemini 3.1 Flash-Lite Qwen3.6 27B Gemini 3.5 Flash Claude Sonnet 4.6
No Skills 30.7 / 36.7 41.0 / 69.8 47.7 / 53.6 67.2 / 29.3
Original Envs 36.8 / 50.0 48.4 / 37.1 49.9 / 55.0 69.2 / 25.4
EnvHarness Envs \mathbf{40.0} / 50.6 \mathbf{52.1} / 40.8 \mathbf{52.6} / 49.6 \mathbf{72.4} / 25.6

각 칸은 성공률과 평균 스텝을 나란히 적은 값이고, 볼드는 성공률 기준입니다.

스킬 없는 성공률이 30.7 에서 67.2 까지 넓게 퍼져 있는데도, EnvHarness 스킬은 네 정책 모두에서 원본 환경 스킬을 2.7 에서 3.7 포인트 사이로 앞섰습니다. 개선폭의 크기가 기반 정책의 강도와 거의 무관한 셈입니다. 커스터마이징 루프는 가장 약한 모델에서 무너지지도, 가장 강한 모델에서 포화되지도 않았고, 파이프라인과 프롬프트, 수용 기준은 전부 동일하게 유지되었습니다. 정책의 능력 수준이 바꾸는 것은 루프의 적용 가능성이 아니라 진단의 내용 쪽으로 보인다는 것이 연구팀의 해석입니다.

성공률은 한 방향으로 움직이지만, 평균 스텝을 함께 놓고 보면 세 가지 서로 다른 양상이 드러납니다. Qwen3.6 27B는 스킬 없이 69.8 스텝으로 네 모델 중 가장 길게 헤매는데, 스킬이 이를 37.1 스텝으로 거의 절반까지 줄입니다. 방향 없는 시행착오에 예산을 쓰고 있었고, 스킬이 그 자리를 알려진 절차로 대체한 경우입니다. Gemini 3.1 Flash-Lite는 정반대입니다. 스킬 없는 정책은 36.7 스텝에서 일찍 포기해 버리고, 스킬은 50 스텝 언저리까지 버티게 만들면서 훨씬 많은 과제를 풉니다. 여기서는 길어진 것 자체가 성과입니다. Claude Sonnet 4.6은 29.3 에서 25 스텝 안팎으로 거의 움직이지 않는데, 이미 방향이 잡힌 정책에는 스킬이 되찾아 올 낭비 시간이 별로 없기 때문입니다. Gemini 3.5 Flash는 그 사이에 있으면서, 두 베이스라인 모두를 상대로 성공률과 스텝을 동시에 개선한 유일한 모델입니다.

이 수치에서 두 가지가 더 따라 나옵니다. 첫째, EnvHarness가 원본 환경 스킬보다 나은 이유가 단순히 더 오래 돌기 때문은 아닙니다. Flash-Lite와 Sonnet에서 두 스킬 출처의 에피소드 길이 차이는 한 스텝 안쪽이고, Flash에서는 EnvHarness가 다섯 스텝 넘게 짧으며, Qwen에서만 더 쓰는데 그것도 3.7 스텝을 더 써서 3.7 포인트를 더 얻습니다. 추가로 푼 과제들이 사실상 같은 예산 안에서 나온 셈입니다. 둘째, 평균 스텝만으로는 품질을 판단할 수 없습니다. 짧은 에피소드는 Sonnet처럼 효율적인 해법일 수도 있고 스킬 없는 Flash-Lite처럼 조기 포기일 수도 있는데, 두 경우의 스텝 수가 거의 같습니다. 연구팀이 이 지표를 본문이 아니라 부록에 성공률과 나란히 실은 이유입니다.

목표 지표를 지정하면 그쪽으로 환경을 빚습니다

기본 설정에서 EnvRigger는 행동 진단으로 학습 목표를 스스로 찾지만, 같은 기계 장치가 사용자가 명시한 제약도 받을 수 있습니다. 연구팀은 ALFWorld의 100개 과제에서 과제당 롤아웃 10회로 측정하며 두 가지 정량 목표를 시험했습니다: 과제별 성공률을 [0.4, 0.6] 구간으로, 성공한 에피소드의 평균 스텝 수를 [25, 35] 구간으로 맞추는 것입니다.

지표 목표 구간 원본 EnvHarness
성공률 [0.4, 0.6] 6.0\% \mathbf{80.0\%}
평균 스텝 [25, 35] 18.0\% \mathbf{53.0\%}

표의 값은 측정값이 목표 구간 안에 들어간 과제의 비율입니다. 성공률 쪽이 더 다루기 쉬운 목표였습니다. 원본 과제는 대부분 항상 풀리거나 전혀 풀리지 않는 강한 이봉 분포를 이루는데, EnvHarness가 이를 구간 가운데로 압축해 구간 내 비율을 6.0\% 에서 80.0\% 로 올리고 평균 성공률을 0.74 에서 0.48 로 옮겼습니다. 평균 스텝은 비율이 아니라 정확한 스텝 수를 고정하는 더 빡빡한 제약이라 상승폭이 작았지만, 그래도 18.0\% 에서 53.0\% 로 올랐습니다.

지정한 약점을 겨냥해 가르칩니다

정량 목표 대신 자연어로 능력 약점을 지정하는 것도 가능합니다. 연구팀은 세 벤치마크에 걸쳐 9건의 사례를 정리했는데, 설계자에게 약점 한 문장을 건네면 설계자가 그 약점이 평범한 벤치마크 과제 안에서 치명적으로 작동하게 만드는 컴포넌트를 작성하고, 재구성된 환경에서 모은 궤적으로부터 스킬 하나를 증류하는 방식입니다.

벤치마크 지정한 약점 생성된 컴포넌트 증류된 스킬
ALFWorld 닫힌 용기를 열지 않고 물건을 집으려 한다 Stage: 대상 물건이 닫힌 서랍 안에서 시작 상호작용 전 상태 확인
ALFWorld 다중 물건 과제에서 두 번째 물건을 잊는다 Stage: 첫 하위 목표를 미리 완료 과제 상태 확인 루프
WebArena 화면 아래 내용을 스크롤하지 않고 결론을 낸다 Contract f_A : 스크롤 전까지 조회 행동 차단 점진적 뷰포트 확장
WebArena 사이트 검색 대신 URL을 추측한다 Contract f_A : 직접 이동 차단 검색 우선 탐색 규약
SWE-bench Verified 실패하는 테스트를 돌리지 않고 패치를 제출한다 Contract f_T : 테스트 실행 전까지 제출 거부 검증 주도 개발 루프
SWE-bench Verified sed -i 를 써서 들여쓰기를 망가뜨린다 Contract f_T : sed 사용 시 파일이 조용히 손상됨 파이썬 스크립트를 통한 안전한 파일 수정

SWE-bench Verified의 검증 사례를 보면 설계자가 실제로 어떤 코드를 쓰는지 알 수 있습니다. "정책이 실패하는 테스트를 돌리지 않고 패치를 제출해서, 수정이 검증되지 않은 채로 남는다" 는 약점을 주면 다음과 같은 Contract가 생성됩니다.

class _Contract(Contract):
    def modify_transition(self, action, response, env_state):
        cmd = bash_command(action)
        if "pytest" in cmd or "runtests.py" in cmd:
            env_state.extras["ran_tests"] = True
        if is_submission(cmd) \
                and not env_state.extras.get("ran_tests"):
            return failed(response,
                "githook: pre-commit hook 'verify-tests' "
                "failed. Run the test suite before submitting.")
        return response

pre-commit 훅이 실패한 것처럼 꾸며서 제출을 거절하는 것입니다. 이 환경에서 모은 궤적에서 증류된 스킬은 "버그를 고치거나 기능을 구현하는 코드 변경을 마무리하기 전에, 관련 테스트 스위트를 돌려 실패를 확인하고 패치 이후 다시 돌려 수정을 검증하며, 필요하면 환경을 먼저 초기화한다" 는 내용이었습니다. 한 과제에 과적합된 요령이 아니라 일반 원칙과 실행 가능한 단계가 결합된 형태입니다.

설계자는 컴포넌트의 축도 스스로 골랐습니다. 지시 없이 Stage로 시작 상태를 배치하고, Contract의 행동 필터로 지름길을 막고, Contract의 전이 훅으로 결과를 위조했습니다. 모든 컴포넌트가 원본 분포 안에 머물렀고 목표와 채점기는 건드리지 않았습니다.

비용은 어느 정도일까요

EnvHarness는 반복 루프를 돌리므로 연산 비용이 관건입니다. 연구팀은 토큰 소비를 설계 토큰과 롤아웃 토큰으로 나눠 공개했습니다.

벤치마크 방법 설계 토큰 롤아웃 토큰 합계
ALFWorld GenEnv 38K 64.2M 64.2M
ALFWorld EnvHarness 1.46M 226.6M 228.0M
WebArena VeriEnv 20K 137.7M 137.8M
WebArena EnvHarness 1.58M 135.7M 137.3M

EnvHarness는 단일 패스 베이스라인보다 설계에 훨씬 많이 씁니다(ALFWorld에서 $1.46$M 대 $38$K). 정책을 보지 않고 과제를 생성하는 대신 전체 궤적을 프롬프트에 넣어 약점을 진단하겠다는 선택의 대가입니다. 그래도 설계는 어느 쪽 예산에서도 작은 비중이고, 롤아웃이 지배적입니다.

실제 환경에서 실행하는 VeriEnv와 비교하면 총합이 사실상 같습니다($137.3$M 대 $137.8$M). 앞서 본 성능 향상은 베이스라인보다 많이 써서 얻어진 것이 아닙니다. GenEnv의 총합은 3.5\times 낮지만, 그 롤아웃은 실제 실행이 아니라 LLM이 시뮬레이션한 것이고 그 절약의 대가로 환각(hallucination) 전이와 흔들리는 성공 신호를 떠안습니다. 접지(grounding) 수준을 같게 맞추면 EnvHarness의 비용은 베이스라인과 같은 규모입니다.

스킬이 과제 유형을 건너뛰어 전이됩니다

학습한 과제 유형을 넘어 스킬이 전이되는지 확인하기 위해 ALFWorld에서 리브 원 아웃(leave-one-out) 평가를 수행했습니다. 한 유형을 제외한 모든 유형의 환경에서 스킬을 추출하고, 제외된 유형에서만 정책을 평가하는 방식입니다. 6개 유형 중 4개에서 원본 환경 스킬을 앞섰고 평균 3.1 포인트 높았는데, clean 유형에서 16.4 포인트로 가장 크게 앞선 반면 heat 유형에서는 8.7 포인트 뒤지는 역행도 있었습니다. 재구성된 환경이 스킬 추출 과정에서 정책을 외운 경로 바깥으로 밀어내기 때문에, 한 유형에 묶인 요령이 아니라 유형을 가로지르는 행동이 스킬에 담긴다는 것이 연구팀의 해석입니다.

설치 및 사용 방법

코드는 google-research/envharness 저장소에 Apache 2.0 라이선스로 공개되어 있습니다. ActionableEnv 계약, 벤치마크별 브릿지(Bridge), 세 가지 컴포넌트, 설계자 에이전트가 모두 포함되어 있고, 벤치마크별 프리셋도 함께 들어 있습니다. 설치 방법과 각 그림을 재현하는 절차는 README에 정리되어 있습니다.

여기서 한 가지 주의할 점이 있습니다. 저장소는 논문의 용어보다 먼저 만들어져서, 컴포넌트 클래스 이름이 논문과 다릅니다. 논문의 Stage, Contract, Chain은 코드에서 각각 Setup, Rules, Link 이고, 설계자가 내놓는 후보는 in_env_actionsrules_code 필드를 담습니다.

먼저 모델 제공자를 설정합니다. 모든 단계(코퍼스 생성, 스킬 증류, 평가)가 같은 모델 문자열을 받으므로 설정은 한 줄이면 됩니다.

# Gemini (논문의 모든 수치가 이 계열로 산출되었습니다)
export GEMINI_API_KEY="your-gemini-api-key"

# 또는 OpenAI
export OPENAI_API_KEY="your-openai-api-key"

# 또는 Vertex AI 위의 Claude
gcloud auth application-default login
export GOOGLE_CLOUD_PROJECT="your-project-id"
pip install "google-cloud-aiplatform>=1.38"

벤치마크마다 자기 환경과 실행 스크립트가 있습니다. 각 폴더는 같은 모양을 따릅니다.

python scripts/check_env.py <benchmark>           # 사전 점검
bash experiments/<benchmark>/reproduce_smoke.sh   # 같은 단계, 적은 과제로
python experiments/<benchmark>/reproduce.py       # 전체 프로토콜

논문의 표를 재현하려면 모델을 Gemini로 되돌려야 합니다. 저장소의 설정 기본값은 openai/gpt-4.1-mini 입니다.

MODEL=gemini/gemini-3.5-flash python experiments/swebench/reproduce.py

MODEL 환경 변수는 임베딩을 포함한 모든 단계에 도달하므로, 한 번의 실행이 여러 제공자로 쪼개지는 일이 생기지 않습니다.

앞서 살펴본 "성공률을 [0.4, 0.6] 구간에 맞춰라" 는 실험도 별도 코드가 아니라 코퍼스 설정의 objective 블록으로 지정합니다. 설계자에게 무엇을 최적화할지 알려 주는 자리가 이 몇 줄입니다.

env:
  import_path: envharness.bridges.mybench.bridge:MyBenchEnv
policy:
  client_factory: envharness.infra.llm:LiteLLMClient
  client_kwargs: { model: openai/gpt-4.1-mini }
objective:
  type: difficulty_zone
  target_band: [0.4, 0.6]

새 벤치마크를 붙이려면 ActionableEnv 인터페이스 하나만 구현하면 됩니다. reset, step, observe, evaluate, get_env_state, save_state, from_state 일곱 개 메서드이고, 그 아래의 설계자와 컴포넌트, 루프, 평가는 벤치마크에 무관하게 그대로 동작합니다. observereset 과 따로 있는 것도 의도된 설계인데, reset 이 반환된 뒤 정책이 행동하기 전에 컴포넌트가 환경을 변형할 수 있어야 하고, 그때 리셋을 한 번 더 치르지 않고 세계를 다시 읽을 방법이 필요하기 때문입니다. 여기서 지켜야 할 계약 하나가 get_env_state()데이터만 담고 런타임(runtime) 핸들을 담지 않는다는 것입니다. 이 값이 설계자가 생성한 훅에 전달되고 서브프로세스 경계를 넘기 때문에, 도커 클라이언트나 브라우저 페이지가 들어 있으면 양쪽 모두 깨집니다.

세 컴포넌트로 덮이지 않는 능력이 필요하면 새 계층 클래스를 만들어 등록할 수도 있습니다. EnvHarness 가 곧 ActionableEnv 이므로 계층은 임의로 쌓이고, 위아래 어느 쪽도 몇 겹이 쌓였는지 알 필요가 없습니다.

한편 프로젝트 홈페이지에는 브라우저에서 바로 돌려 볼 수 있는 플레이그라운드가 있습니다. 카드 4장을 사칙연산으로 조합해 24 를 만드는 24 게임을 과제로 두고, 정책이 무엇을 관측하는지와 환경이 실제로 무엇을 들고 있는지를 나란히 보여 줍니다. 컴포넌트 코드를 직접 고쳐 스택에 적용해 보면서 차이를 눈으로 확인할 수 있어서, 논문을 읽기 전에 감을 잡기에 좋습니다.

한계점과 향후 연구 방향

연구팀은 세 가지 한계를 명시했습니다.

설계 루프의 비용입니다. EnvHarness는 설계자 에이전트가 후보를 제안하고 실행하고 수정하는 반복 루프로 환경을 하나씩 만듭니다. 설계자가 약할수록 검증을 통과하는 하네스에 도달하기까지 더 많은 반복이 필요하고, 반복마다 환경을 롤아웃해야 하므로 양질의 환경 풀을 만드는 데 상당한 시간과 추론(inference) 연산이 듭니다. 다만 이 비용은 학습 에피소드마다가 아니라 환경마다 한 번 지불되고, 설계자 에이전트가 개선되면 줄어들 것으로 연구팀은 보고 있습니다.

리셋 가능한 gym 형태 인터페이스가 필요하다는 점입니다. 구속력 있는 제약은 리셋 쪽입니다. Stage는 환경을 선택된 초기 상태로 놓아야 하고 Chain은 하위 과제 사이에서 환경을 알려진 상태로 되돌려야 하는데, 둘 다 환경을 앞으로 진행시키는 것만이 아니라 복원할 수 있어야 성립합니다. 그래서 실제 사용자 계정 위에서 동작하는 에이전트처럼 보낸 메일이나 넣은 주문을 되돌릴 수 없는 환경, 에피소드 사이에 주변 환경이 초기 배치로 돌아오지 않는 물리 로봇은 대상에서 제외됩니다.

Chain의 합성이 순차적이라는 점입니다. Chain은 하위 과제를 이어 붙이는 방식으로 합성하고 결과를 각 부분의 검증기로 판정합니다. 재구성된 모든 과제가 신뢰할 수 있는 사람 제작 검증을 물려받는 근거가 바로 이 구조인데, 대가로 Chain에는 합성된 하위 과제들이 의미상 관련이 있는지에 대한 개념이 없고 분기나 공유 중간 상태를 가진 워크플로도 표현할 수 없습니다. 제어 흐름 자체는 더 풍부하게 만들 수 있지만, 합성된 검증기를 가질 수 있는 것은 순차 연결뿐입니다. 각 구간이 스스로 종료하고 판정을 내놓아야 그 논리곱을 합성 판정으로 쓸 수 있는데, 분기나 교차 배치에서는 결합할 판정 쌍 자체가 존재하지 않기 때문입니다. 의미적 합성을 하려면 하위 과제 사이의 호환성을 재는 척도와 합성된 목표 위에 정의된 검증기가 함께 필요합니다.

향후 방향으로는 컴포넌트 자체의 확장이 먼저 꼽힙니다. Stage, Contract, Chain은 첫 묶음이지 닫힌 집합이 아니라는 것이 연구팀의 입장입니다. 에이전트 하네스가 초기 구성 요소를 훌쩍 넘어 성장한 것처럼, 확률성이나 부분 관측성을 주입하는 컴포넌트, 보조 피드백 채널을 여는 컴포넌트, 여러 에이전트를 한 환경에 놓는 컴포넌트가 같은 resetstep 인터페이스를 지키면서 고정된 벤치마크의 재구성 폭을 넓힐 수 있습니다. 텍스트 밖으로 나가는 것도 과제입니다. 현재 EnvHarness는 텍스트 행동과 관측 위에서만 동작하는데, 시각이나 GUI, 체화 환경으로 확장하면 관측이 더 이상 기호가 아닐 때도 이 감싸기 추상화가 살아남는지 시험하게 됩니다.

이 연구가 던지는 더 큰 메시지는 환경 구축을 저작(authoring)의 문제가 아니라 감싸기(wrapping)의 문제로 재정의했다는 데 있습니다. 자기 진화 에이전트 연구가 프롬프트와 스킬 라이브러리, 스캐폴드, 나아가 모델 가중치까지 진화시키는 동안, 정작 그 에이전트가 마주 서 있는 세계는 거의 언제나 고정되어 있었습니다. EnvHarness는 그 나머지 절반을 에이전트 하네스와 같은 방식으로 채웁니다. 고정된 핵심을 외부 계층이 유능하게 만드는 구조입니다. 인터페이스 계약과 사람이 만든 검증기를 모두 보존한다는 조건 아래에서 환경 공급을 확장할 수 있다면, 에이전트 학습의 병목은 더 이상 새 환경을 몇 개나 만들었느냐가 아니라 이미 있는 환경을 얼마나 잘 겨냥해 다시 쓰느냐가 될 것입니다.

:scroll: EnvHarness: Awakening Static Worlds for Agent Learning 논문

:house: EnvHarness 프로젝트 홈페이지

:github: EnvHarness GitHub 저장소

더 읽어보기




이 글은 GPT 모델로 정리한 초안을 바탕으로 한 것으로, 원문의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 원문도 함께 참고해주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 댓글로 알려주시기를 부탁드립니다. :hugs:

논문의 주장이나 벤치마크에 대한 의견, 직접 재현해보신 결과가 있다면 :pytorch:파이토치 한국 사용자 모임:south_korea: 회원들을 위해 댓글로 공유해주세요! :folded_hands: