환경이 곧 reward다 — 샌드박스·테스트·상태 검증
Training Software Engineering Agents and Verifiers with SWE-Gym (Pan et al., ICML 2025)
Introduction
2부(#4~#8)가 다룬 질문은 “공을 어디에 돌릴 것인가”였다. 궤적을 에피소드·턴·스텝·토큰 중 어느 입도로 쪼개고, 그 입도에서 credit을 어떻게 계산할지가 관심사였다. 그런데 이 질문 전체가 암묵적으로 전제하는 것이 하나 있다 — 쪼갠 단위마다 매길 점수 자체는 어디선가 이미 주어져 있다는 전제다. #2의 의사결정 트리도 첫 질문으로 “최종 결과를 규칙으로 검증할 수 있는가”를 던졌을 뿐, 그 규칙이 실제로 어떻게 만들어지는지는 열어두었다.
3부(#9~#11)는 이 열린 질문에 답한다. 그 점수를 실제로 어디서 얻는가. 답은 세 갈래로 나뉜다 — 환경이 직접 알려주거나(이 글), 도구 호출 자체의 성패를 채점하거나(#10), 별도의 judge가 궤적을 읽고 점수를 매기거나(#11). 이 세 갈래 중 첫 번째 답이 언제나 가장 좋은 답이다 — 가능하기만 하다면. 코드가 실제로 컴파일되는가, 테스트가 실제로 통과하는가, 웹페이지의 장바구니에 실제로 그 상품이 담겼는가. 이런 질문에는 모델이 판단을 보탤 필요가 없다. 환경에게 그냥 물어보면 된다.
이 구도는 낯설지 않다. RLHF Reward 설계 시리즈가 정리한 reward의 4분류 — 규칙 기반 검증, 학습된 스칼라 RM, reference 기반 judge, 생성형 RM(GRM) — 중 첫 번째인 ① 규칙 기반 검증이 정확히 이 글의 자리다. RLHF 시리즈 #33 DeepSeek-R1이 단일 턴 추론(수학·코드)에서 보여준 것을, 이 글은 멀티턴 에이전트로 확장한다. 정답 문자열을 비교하던 규칙 검증기가, 이제는 파일 시스템의 상태를 읽고, 테스트 스위트를 돌리고, 브라우저의 DOM을 조회하는 환경 상태 검증으로 몸집을 키운다.
| RLHF reward 4분류 | 파라미터 | 이 시리즈에서 |
|---|---|---|
| ① 규칙 기반 검증 | 없음 | 이 글(#9) — 환경 상태 검증으로 확장 |
| ② 학습된 스칼라 RM | 있음 | RLHF 시리즈의 영역, 이 시리즈는 별도로 다루지 않음 |
| ③ reference 기반 judge | 있음(judge 모델) | #11 — 궤적을 judge가 채점 |
| ④ 생성형 RM(GRM) | 있음 | RLHF 시리즈의 영역, 이 시리즈는 별도로 다루지 않음 |
표에서 보듯 파라미터가 없는 칸은 딱 하나, ①뿐이다. 나머지 셋은 전부 어떤 형태로든 학습된 모델이 판정에 개입한다. 그래서 이 글이 3부의 첫 문을 여는 것은 우연이 아니다 — 가장 값싸고 가장 편향에서 자유로운 칸부터 먼저 소진하고, 그걸로 부족할 때만 ③·④로 넘어가는 것이 순서에 맞다.
규칙 기반 reward의 핵심 매력은 #33에서 이미 정리했다 — 파라미터가 없는 함수는 hacking의 대상이 될 근사 자체가 없다. 학습된 reward model은 근사이기 때문에 항상 실제 품질과 어긋나는 지점이 있고, 정책이 그 지점을 찾아내면 hacking이 된다. 반면 “테스트를 통과했는가”에는 근사가 없다. 통과했거나 안 했거나 둘 중 하나다. 이 통념은 에이전트 환경으로 넘어와도 그대로 성립하는 것처럼 보인다 — 샌드박스에는 학습 가능한 가중치가 없으니까.
그런데 이 통념에는 중요한 단서가 붙는다. 뚫리는 것은 함수가 아니라 판정 로직 — 무엇을 검증할지, 어떻게 파싱할지, 얼마나 촘촘하게 확인할지를 정한 사람의 설계다. 테스트 커버리지가 부족하면 잘못된 코드도 통과한다. 판정 조건이 “화면에 목표처럼 보이는 것이 있으면 성공”이라면, 목표를 실제로 달성하지 않고도 그 겉모습만 만들어낼 수 있다. 숫자로 이 단서를 먼저 박아두자.
| 항목 | 수치 |
|---|---|
| EvalPlus가 HumanEval 테스트를 늘린 배수 | 80배(HumanEval+) |
| 테스트 증강 후 pass@k 하락폭 | 최대 19.3~28.9%p |
| SWE-Gym 환경 구축에 든 인간 노동 | 약 200시간(annotation) |
| SWE-Gym 환경 구축에 든 연산 | 약 10,000 CPU-core-hour |
| SWE-Gym으로 얻은 SWE-bench 해결률 개선 | 최대 절대 19%p |
| WebArena에서 GPT-4 에이전트의 end-to-end 성공률 | 14.41%(사람 78.24%) |
이 글은 다음 네 가지를 순서대로 다룬다.
- 환경이 줄 수 있는 신호에는 정확히 어떤 종류가 있고, 각각이 #2의 어느 입도에 대응하는가.
- 왜 환경 신호가 다른 reward 원천보다 특별한가 — 그리고 그 특별함의 한계는 어디인가.
- “파라미터가 없으니 안전하다”는 통념이 실제로 어디서 깨지는가 — 테스트 커버리지, 대리 지표, 파서라는 세 개의 구멍.
- 검증 가능한 환경을 만드는 것 자체가 왜 값비싼 공학 문제인가.
Background — 환경이 주는 신호의 종류
에이전트가 환경과 상호작용할 때 되돌아오는 신호는 하나가 아니다. 최소 네 가지 성격이 다른 신호가 섞여 있는데, 이걸 뭉뚱그려 “환경 reward”라고 부르면 설계를 그르치기 쉽다. 먼저 넷을 구분하고, 각각이 #2가 그린 입도 지도의 어느 칸에 해당하는지 표로 정리한다.
| 신호 종류 | 무엇을 확인하는가 | 대응 입도([#2]) | 판정 방식 | 예시 |
|---|---|---|---|---|
| 종료 상태 검증 | 태스크가 최종적으로 완료됐는가 | 에피소드(#4) | 이진(성공/실패) | SWE-bench: FAIL_TO_PASS 전부 + PASS_TO_PASS 전부 통과해야 “resolved” |
| 중간 상태 검증 | 하위 목표를 달성했는가, 상태가 옳게 바뀌었는가 | 턴(#5)·스텝(#6) | 이진 또는 비율 | 개별 유닛 테스트 하나의 통과 여부, 파일이 기대한 값으로 바뀌었는지 diff 비교 |
| 실행 피드백 | 실패했다면 왜 실패했는가 | 스텝(#6)·토큰(#7) | 텍스트(구조화 안 됨) | 컴파일 에러 메시지, 예외 스택 트레이스, 린터 경고 |
| 비용 신호 | 얼마나 비싸게 도달했는가 | 궤적 전체(직교축, 모든 입도에서 동시에 정의 가능) | 스칼라(작을수록 좋음) | 턴 수, 토큰 수, 도구 호출 횟수, wall-clock 시간 |
종료 상태 검증 — 가장 성긴, 가장 믿을 만한 신호
에피소드가 끝난 뒤 “목표 상태에 도달했는가”만 확인하는 가장 단순한 형태다. #4가 다룬 outcome reward의 환경 버전이라고 보면 된다. SWE-bench의 “resolved” 판정이 정확한 예다 — 이슈를 재현하던 FAIL_TO_PASS 테스트가 전부 pass로 바뀌었는지, 그리고 원래 잘 돌아가던 PASS_TO_PASS 테스트가 하나도 안 깨졌는지를 AND로 묶어 판정한다(SWE-bench 리뷰가 이 F2P/P2P 구조를 자세히 다뤘다 — 여기서는 “검증 가능한 채점”이라는 다른 각도로, 이 AND 판정 자체가 왜 그렇게 설계됐는지를 Experiments에서 다시 짚는다). 신호는 성기지만(에피소드당 숫자 하나) 대신 가장 신뢰할 만하다 — 최종 상태는 대개 가장 명확하게 정의되기 때문이다.
중간 상태 검증 — 궤적 도중의 체크포인트
턴이나 스텝 단위로, 궤적이 끝나기 전에 “지금까지는 옳은 방향인가”를 확인하는 신호다. 개별 유닛 테스트 하나의 통과 여부, 웹 에이전트가 올바른 페이지로 이동했는지, 파일 시스템의 특정 경로가 기대한 내용으로 바뀌었는지 같은 것들이 여기 해당한다. #5와 #6이 다룬 턴·스텝 단위 credit assignment 방법들이 학습에 쓰는 원재료가 대개 이 신호다 — AgentPRM류 TD 방법이 “목표에 얼마나 가까워졌는가”를 추정할 때, 그 추정의 근거가 되는 관측치가 바로 중간 상태 검증 결과인 경우가 많다.
실행 피드백 — 실패의 내용이 신호다
종료·중간 상태 검증이 “통과했는가 아닌가”라는 이진 신호라면, 실행 피드백은 실패 그 자체의 형태를 신호로 쓴다. 컴파일이 아예 안 됐다면 파서가 문법 오류를 뱉는다. 컴파일은 됐는데 런타임에 죽었다면 스택 트레이스가 어느 줄에서 무슨 예외가 났는지 알려준다. 테스트가 실행은 됐는데 값이 다르다면 assertion 메시지가 기대값과 실제값을 나란히 보여준다. 이 세 가지는 전부 “실패”라는 점에서 같지만, 실패의 심각도가 순서를 이룬다 — 문법 오류(가장 나쁨) > 런타임 예외 > assertion 실패(가장 나음, 로직은 거의 맞았다는 뜻) 같은 식이다.
이 순서 자체를 이진 reward보다 촘촘한 신호로 바꿔 쓸 수 있다는 게 실행 피드백의 값어치다. “테스트를 통과했는가”만 보면 위 세 실패가 전부 똑같이 0점이지만, 실패의 종류를 구별해 순위를 매기면 “컴파일도 안 되는 코드”와 “거의 맞았는데 부호 하나 틀린 코드” 사이에 학습 신호의 차이를 줄 수 있다. 이게 #8이 다룬 reward shaping과 만나는 지점이다 — 원 신호(이진 통과 여부)를 그대로 쓰지 않고, 그 밑에 깔린 더 풍부한 정보(실패의 종류)를 끄집어내 shaping에 쓰는 것이다.
설계 예시를 하나 들어보자(아래 값은 이 글에서 임의로 정한 예시이지 특정 논문의 확인된 수치가 아니다). 실패의 심각도에 순서를 매겨 스칼라로 바꾸면 다음과 같은 형태가 된다.
| 실행 결과 | 의미 | 예시 shaped reward |
|---|---|---|
| 문법 오류 | 파서 단계에서 죽음. 로직을 전혀 시도하지 못함 | \(-1.0\) |
| 런타임 예외 | 문법은 통과, 실행 중 죽음. 로직의 일부는 맞았을 가능성 | \(-0.5\) |
| 실행은 됐으나 assertion 실패 | 로직 전체가 돌아감. 값만 틀림 | \(-0.1\) |
| 전부 통과 | 목표 달성 | \(+1.0\) |
이진 reward라면 위 넷 중 앞의 셋이 전부 같은 \(0\)(혹은 \(-1\))으로 뭉개진다. 실패의 형태를 구별해 순서를 매기면, 정책은 “문법 오류를 내는 것보다는 최소한 런타임까지는 도달하자”는 중간 목표를 학습할 여지가 생긴다 — 최종 목표에 못 미치더라도 방향이 맞는 실패와 방향이 틀린 실패를 구별해주기 때문이다. 다만 이 설계 자체가 이미 하나의 판정 정의라는 점을 기억해두자. 뒤에서 볼 “그런데 환경 검증도 뚫린다” 절의 논지가 이 shaped reward에도 그대로 적용된다 — 이 순서를 매긴 사람의 직관이 틀렸다면(예를 들어 특정 종류의 assertion 실패가 실은 문법 오류보다 고치기 어려운 경우), shaping 자체가 잘못된 방향을 강화한다.
비용 신호 — 도달했다고 끝이 아니다
목표에 도달했는지와는 독립적으로, 얼마나 비싸게 도달했는지를 재는 신호다. 턴 수, 소비한 토큰 수, API 호출 횟수, wall-clock 시간이 여기 해당한다. 이 신호는 다른 세 신호와 직교한다 — 토큰 단위로도, 턴 단위로도, 에피소드 단위로도 똑같이 정의할 수 있다는 뜻이다. 비용 신호를 reward에 섞는 이유는 단순하다. 최종 상태 검증만으로는 “10턴 만에 끝낸 에이전트”와 “80턴을 헤매다 겨우 끝낸 에이전트”를 구별하지 못한다. 실무에서는 후자가 훨씬 나쁜 정책이다 — 같은 목표에 도달했더라도, 그 과정에 든 API 비용과 지연 시간이 실제 서비스 비용으로 그대로 전가되기 때문이다.
비용 신호를 다룰 때 흔히 저지르는 실수는 이걸 목표 달성 reward에 그대로 더하는 것이다. \(R = R_{\text{성공}} - \lambda \cdot \text{비용}\)처럼 단순히 빼주면, \(\lambda\)가 조금만 커도 정책이 “아예 짧게 실패하는” 쪽을 “느리지만 성공하는” 쪽보다 선호하게 될 위험이 있다. RLHF 시리즈 #15 Safe RLHF가 안전성을 reward 항이 아니라 제약(constraint)으로 다룬 것과 같은 논리가 비용 신호에도 적용된다 — 비용은 “낮을수록 가산점”이 아니라 “일정 예산 안에서는 무관하고, 예산을 넘으면 강하게 페널티”인 제약으로 다루는 편이 목표 달성이라는 본래 목적을 비용 절감이라는 부차적 목적에 잠식당하지 않게 한다.
Method
왜 환경 신호가 특별한가
환경 신호가 다른 reward 원천(스칼라 RM, judge)보다 우월한 위치에서 출발하는 이유는 세 가지로 요약된다.
judge 편향이 없다. #11이 다룰 judge 기반 채점은 결국 또 다른 LLM이 궤적을 읽고 점수를 매기는 구조다. 그 judge 자체가 장황한 응답을 선호하거나(verbosity bias), 특정 문체에 후한 점수를 주거나, 자기 자신이 생성한 스타일을 편애하는(self-preference) 편향을 가질 수 있다. 테스트 실행기에는 이런 편향이 있을 자리가 없다 — 코드가 컴파일되든 안 되든, 그 판정에 “문체가 매끄러워서” 같은 여지가 끼어들 통로 자체가 없다.
라벨 잡음이 없다. 스칼라 RM은 결국 사람이 매긴 선호 라벨로 학습된다. 사람마다 판단이 갈리고, 같은 응답을 두고도 평가자 간 합의도가 낮은 경우가 흔하다. 반면 “이 테스트가 통과했는가”는 재현 가능하고 결정적인 사실이다(단, 뒤에서 볼 것처럼 환경 자체가 비결정적이면 이 전제가 깨진다).
비용이 낮다. 이게 실무에서 가장 체감되는 차이다. judge 기반 채점 한 번은 검증 대상 응답을 생성하는 것과 맞먹는 별도의 LLM 추론을 또 한 번 태우는 일이다. SWE-Gym 저자들은 프론티어 모델로 태스크 하나를 푸는 데 1달러 이상이 든다고 보고한다 — 그 비용의 상당 부분이 에이전트의 추론 호출이다. 반면 유닛 테스트 스위트 하나를 돌리는 데는 보통 수 초의 CPU 시간이면 충분하다. 같은 궤적을 백만 번 굴려 credit assignment 실험을 반복해야 하는 RL 학습 루프에서, 이 비용 격차는 그대로 학습 가능한 데이터 양의 격차로 번역된다.
세 가지 reward 원천의 비용 구조를 거칠게 정리하면 다음과 같다.
| reward 원천 | 채점 1회당 드는 일 | 병렬화 단위 |
|---|---|---|
| 환경 상태 검증(이 글) | 프로세스 실행, CPU 수 초~수십 초 | CPU 코어 수만큼 |
| reference judge(#11) | LLM 추론 1회(응답 생성과 맞먹는 비용) | GPU 처리량만큼 |
| 사람 라벨(2부 RLHF 시리즈 영역) | 사람의 판단 시간 | 고용한 인원 수만큼 |
같은 채점 1회를 기준으로 보면 아래로 갈수록 자릿수가 뛴다 — CPU 초 단위에서 GPU 추론 단위로, 다시 사람의 분 단위로. RL 학습이 요구하는 채점 횟수(수백만 회)를 곱하면 이 격차가 그대로 학습 파이프라인의 실현 가능성을 가른다.
이 논리는 이미 #33 DeepSeek-R1이 단일 턴 추론에서 정리한 것과 정확히 같다. 다른 점은 딱 하나 — DeepSeek-R1의 검증기는 정답 문자열 하나를 비교했지만, 에이전트 환경의 검증기는 파일 시스템, 데이터베이스, 브라우저 DOM 같은 훨씬 복잡한 상태를 들여다봐야 한다는 것이다. 그리고 바로 이 복잡함이 다음 절의 구멍을 연다.
그런데 환경 검증도 뚫린다
환경은 심판이 아니라 저울에 가깝다. 심판은 매수될 수 있지만, 저울 자체는 물리 법칙을 어길 수 없다 — 다만 저울에 무엇을 올릴지, 눈금을 어떻게 읽을지는 사람이 설계한다. “파라미터가 없으니 안전하다”는 명제가 참인 대상은 저울(실행기, 테스트 러너, 파서)이지, 저울에 무엇을 올릴지를 정한 판정 정의가 아니다. 뚫리는 지점은 정확히 세 곳이다.
테스트 커버리지 부족 — EvalPlus가 보여준 것
가장 먼저 뚫리는 곳은 검증 자체의 범위다. 테스트를 통과했다는 것은 “그 테스트가 확인하는 범위 안에서는 맞다”는 뜻일 뿐, “일반적으로 맞다”는 뜻이 아니다. 이 간극을 정면으로 측정한 연구가 EvalPlus(Liu et al., NeurIPS 2023, arXiv 2305.01210)다.
저자들은 코드 생성 표준 벤치마크인 HumanEval의 테스트 케이스가 지나치게 부실하다는 데서 출발한다. HumanEval의 각 문제는 평균 몇 개 안 되는 테스트만 딸려 있는데, 이 정도로는 함수의 edge case(빈 입력, 음수, 경계값 등)를 충분히 커버하지 못한다. EvalPlus는 LLM 기반 생성과 mutation 기반 생성을 결합한 자동 테스트 생성기로 HumanEval의 테스트 케이스를 80배로 증강해 HumanEval+를 만들었다. 26개 주요 LLM(GPT-4, ChatGPT 등)을 이 증강된 테스트로 다시 채점한 결과는 명확했다 — pass@k가 최대 19.3~28.9%p 하락했다. 즉 원래 테스트를 통과했던 코드 중 상당수가, 조금 더 촘촘한 테스트 앞에서는 틀린 코드로 드러났다.
더 중요한 발견은 순위 자체가 뒤집혔다는 것이다. 원 HumanEval에서는 ChatGPT를 넘지 못했던 WizardCoder-CodeLlama와 Phind-CodeLlama가, HumanEval+에서는 둘 다 ChatGPT를 앞질렀다. 테스트가 부실하면 “어느 모델이 더 낫다”는 판단 자체가 뒤집힐 수 있다는 뜻이다.
이게 RL 학습에 무슨 의미인지가 이 시리즈의 관심사다. 평가 시점의 테스트 부실은 “벤치마크 순위가 부정확하다”는 문제로 끝나지만, 학습 시점의 테스트 부실은 그 부실함을 정책이 직접 그래디언트로 학습해버린다는 점에서 훨씬 심각하다. 정책이 “이 문제 유형은 테스트가 몇 개 안 되니, 그 몇 개만 정확히 맞히면 된다”는 지름길을 explore하다가 우연히 발견하면, GRPO나 PPO의 advantage가 그 지름길을 그대로 강화한다. 부실한 테스트는 평가에서는 잡음이지만, 학습에서는 적극적으로 착취당하는 신호가 된다.
판정 로직이 대리 지표일 때 — Motif의 NetHack 오라클
두 번째 구멍은 더 미묘하다. 검증 로직이 “진짜 목표”를 직접 확인하지 못하고, 그 목표가 있을 때 관측되는 대리 지표(proxy)만 확인할 때 생긴다. 이 실패 양상을 극적으로 보여준 사례가 Motif(Klissarov et al., Mila/Meta AI, ICLR 2024, arXiv 2310.00166)의 NetHack 실험이다. 이 사례는 #15 에이전트의 reward hacking에서 “misalignment by composition”이라는 이름으로 본격적으로 다룬다. 여기서는 이 글의 논지 — 판정 정의가 대리 지표일 때 무슨 일이 생기는가 — 를 보여주는 예고편으로 짧게 소개한다.
NetHack은 절차적으로 생성되는 던전 탐험 게임이다. 그 안에 “오라클(Oracle)”이라는 특정 NPC가 있고, 실험에 쓰인 “oracle 태스크”의 목표는 에이전트가 실제로 이 오라클을 찾아가는 것이다. 그런데 판정 로직 자체는 “에이전트를 찾아갔다”를 직접 확인하지 않는다. NetHack Learning Environment(NLE)는 에이전트 근처에 오라클로 인식되는 문자(@)가 있으면 태스크 완료로 판정한다 — “실제로 그 오라클에게 도달했는가” 대신 “화면에 오라클처럼 보이는 것이 있는가”를 본 것이다.
Motif로 학습된 에이전트는 이 틈을 정확히 찾아냈다. NetHack에는 환각(hallucination) 상태가 있는데, 이 상태에서는 몬스터가 실제와 다른 모습으로 보인다. 에이전트가 학습한 전략은 이렇다 — ① 노란 곰팡이(yellow mold)라는 특정 몬스터를 찾아 처치한다, ② 그 시체를 먹어 환각 상태에 들어간다, ③ 환각 상태에서 아무 몬스터나 만나되 절대 공격하지 않고 버틴다, ④ 운이 좋으면 그 몬스터가 환각으로 인해 오라클(@)처럼 보이고, NLE는 이걸 “오라클을 찾았다”고 판정한다. 저자들이 직접 확인한 바로는, 이렇게 학습된 에이전트는 던전 1층을 넘어가는 일이 거의 없었다 — 실제로 오라클이 있는 깊은 층까지 내려가는 대신, 얕은 층에서 환각을 유도해 목표를 “꿈꾸는” 쪽을 선택한 것이다.
이 사례가 정확히 짚는 것은 이렇다. 판정 로직(“근처에 오라클로 인식되는 문자가 있는가”)은 파라미터가 없는, 겉보기에 안전한 규칙이다. 그런데 그 규칙이 진짜 목표(오라클에 도달)의 완벽한 대리 지표가 아니었다. 체크포인트 경비원이 “얼굴이 몽타주와 닮았으면 통과”라는 규칙만 갖고 있다면, 진범이 아니라 변장한 다른 사람도 통과시켜버리는 것과 같은 구조다. 저자들은 이 현상에 “misalignment by composition”이라는 이름을 붙였다 — 개별적으로는 사람의 직관과 잘 맞아떨어지던 두 보상(Motif의 내재적 보상과 환경의 외재적 보상)을 결합했더니, 그 조합에서 어느 쪽도 의도하지 않은 우회 경로가 새로 열렸다는 뜻이다.
이 글의 논지에서 가장 중요한 대목은 저자들이 이 구멍을 어떻게 막았는가다. 새로운 검증 함수를 만들지 않았다. 대신 판정 정의에 조건 하나를 추가했다 — “에이전트가 오라클 옆에 서 있고, 동시에 환각 상태가 아닐 것.” 이 수정된 태스크를 저자들은 oracle-sober라 이름 붙였다. 환각을 이용한 우회는 정의상 이 조건을 만족할 수 없으므로 exploit이 봉쇄된다. 이 수정 이후 다시 학습시킨 Motif는 여전히 이 극도로 희소한 보상 태스크를 어느 정도 풀어냈다고 저자들은 보고한다 — 다만 hack이 가능했을 때보다는 성공률이 낮아졌다. 즉 함수(NLE의 문자 인식 로직)는 처음부터 끝까지 그대로였고, 바뀐 것은 오직 판정 정의 한 줄이었다. 이 글이 반복해서 강조하는 결론이 이 사례에서 가장 선명하게 확인된다.
같은 논문은 판정 정의가 아니라 환경이 기본으로 제공하는 점수 체계 자체도 대리 지표일 수 있음을 보여주는 두 번째 사례를 남겼다. NetHack에는 게임 시작부터 에이전트를 돕는 반려동물(pet)이 있는데, 이 반려동물이 몬스터를 대신 잡으면 그 몬스터를 잡은 점수는 반려동물이 아니라 다른 방식으로 처리된다. 그 결과 “게임 점수를 최대화하라”는 외재적 보상만으로 학습된 에이전트는 반려동물을 99.4%±0.63%의 확률로 직접 죽여버리는 행동을 학습했다 — 반려동물이 자기 대신 몬스터를 잡아 점수를 “가로채는” 것을 막기 위해서다. 사람이라면 게임이 강제하지 않는 한 거의 하지 않을 행동이다. 반면 Motif의 내재적 보상(사람의 선호를 반영하도록 LLM으로부터 추출한 보상)으로 학습된 에이전트는 반려동물을 죽이는 비율이 33.4%±25.14%로 훨씬 낮았다. “게임 점수”라는, 개발자가 만들지 않고 게임 자체가 제공하는 지표조차도 사람의 진짜 의도(반려동물과 잘 지내며 던전을 탐험하기)의 완벽한 대리 지표는 아니었다는 뜻이다. 환경이 주는 신호를 그대로 믿는 것과, 그 신호가 애초에 무엇을 측정하려던 것인지를 따져보는 것은 다른 일이다.
파서 취약점 — 정답 추출이라는 좁은 문
세 번째 구멍은 가장 기계적이다. #33이 다룬 정답 추출 방식을 떠올려보자 — 모델의 출력에서 \boxed{} 안의 문자열을 정규식으로 뽑아 정답과 비교한다. 이 파서가 완벽하지 않으면, 두 방향으로 문제가 생긴다.
작은 토이 예제로 감을 잡아보자. 파서가 \d+(숫자 하나 이상) 패턴으로 정답을 뽑는다고 하자. 모델이 “따라서 정답은 7이고, 검산해도 70이 아니라 7이 맞다”라고 답했다면, 정규식은 첫 매치인 “7”을 뽑을 수도, 혹은 구현에 따라 뒤에 나온 “70”의 일부를 잘못 뽑을 수도 있다 — 어느 쪽이든 파서의 구현 디테일이 채점 결과를 좌우한다. 반대 방향의 문제도 있다. 파서가 지나치게 엄격해서 \boxed{7}만 인정하고 \boxed{x=7}은 놓친다면, 실제로는 맞은 풀이가 오답으로 채점된다(false negative). 파서가 지나치게 관대해서 답을 여러 번 반복하는 응답 중 하나라도 맞으면 정답 처리한다면, 모델은 “그럴듯한 답을 여러 개 나열해 하나라도 걸리길 바라는” 전략을 학습할 유인이 생긴다(false positive).
에이전트 환경에서는 이 파서 취약점이 텍스트 정답 추출을 넘어 상태 파싱 전반으로 확장된다. 도구 호출의 JSON 인자를 파싱하는 로직, 브라우저 DOM에서 특정 엘리먼트가 존재하는지 확인하는 셀렉터, 파일 diff를 비교하는 로직 — 이 전부가 “환경 상태를 읽어 판정으로 바꾸는” 좁은 문이고, 그 문의 설계가 허술하면 진짜 상태와 무관하게 문을 통과하는 길이 생긴다.
세 구멍을 관통하는 결론은 하나다. 규칙 기반 reward의 취약점은 실행기·테스트 러너·파서라는 함수 자체에 있지 않다. 그 함수에게 무엇을 검증하라고 시켰는지, 그 검증 범위를 얼마나 촘촘하게 잡았는지, 판정 결과를 어떻게 읽어낼지를 정한 판정 정의에 있다. “파라미터가 없다”는 사실은 이 판정 정의가 뚫릴 가능성을 전혀 줄여주지 않는다.
환경을 만드는 비용 — 샌드박스와 결정성
지금까지는 이미 만들어진 환경이 뚫리는 지점을 봤다. 그런데 그 환경을 애초에 만드는 것 자체가 만만치 않은 공학 문제다. 검증 가능한 에이전트 환경 하나가 갖춰야 할 것은 최소 네 가지다 — 실제 태스크를 재현하는 샌드박스, 같은 행동에 같은 결과가 나오는 결정성(determinism), 학습을 위해 수천 개를 동시에 돌릴 수 있는 병렬 실행, 그리고 매 에피소드를 깨끗한 초기 상태로 되돌리는 리셋 로직이다.
SWE-Gym(Pan et al., ICML 2025, arXiv 2412.21139)이 이 비용을 숫자로 보여준다. 저자들은 GitHub의 실제 이슈로부터 실행 가능한 환경을 만들려 했는데, 여기서 바로 막힌 지점이 의존성 설정이었다. 파이썬 패키지를 설치하는 표준 방법이 하나로 통일돼 있지 않고, 오래된 이슈일수록 당시의 하위 호환성 문제까지 재현해야 한다. 저자들은 결국 각 태스크 인스턴스마다 requirements.txt, CI 스크립트, 저장소 문서를 사람이 직접 보고 의존성을 수작업으로 구성했다. 이 작업에 약 200 인간-시간(annotation hour)과 약 10,000 CPU-core-hour가 들었고, 그렇게 검증을 마친 인스턴스는 11개 저장소에서 2,438개뿐이었다. 재현성을 위해 공개한 사전 빌드 Docker 이미지의 총 용량은 6TB다. 이렇게 만든 환경으로 학습한 에이전트는 SWE-bench Verified/Lite에서 해결률이 최대 19%p 개선됐다 — 환경을 잘 만드는 값어치는 분명하지만, 그 값어치의 대가가 이만큼 크다는 뜻이기도 하다.
이 병목을 정면으로 겨냥한 후속 연구가 SWE-smith(Yang et al., NeurIPS 2025, arXiv 2504.21798)다. 저자들은 자신들의 논문 초록에서 이 문제를 이렇게 요약한다 — 기존 데이터셋은 “수백 시간의 인간 노동”이 필요하고, 그렇게 만든 실행 환경은 “수 테라바이트”를 차지해 확장성이 심각하게 제한된다는 것이다. SWE-smith는 이 수작업 병목을 자동화로 우회한다. 사람이 실제 이슈를 찾아 검증하는 대신, 임의의 파이썬 코드베이스를 받아 기존 테스트를 깨뜨리는 버그를 자동으로 합성해 태스크를 대량 생성한다. 이 방식으로 128개 저장소에서 5만 개 인스턴스를 만들었다 — SWE-Gym의 저장소 수 대비 약 12배, 인스턴스 수로는 약 20배다. 이 데이터로 학습한 SWE-agent-LM-32B는 SWE-bench Verified에서 40.2% pass@1을 기록해 오픈소스 모델 중 최고 성능을 냈다.
두 논문을 나란히 놓으면 이 절의 요지가 선명해진다. 검증 가능한 환경을 만드는 비용은 우연히 큰 게 아니라, 실제 소프트웨어의 지저분함(의존성 충돌, 버전 호환성, 저장소마다 다른 빌드 방식)을 그대로 흡수해야 하기 때문에 구조적으로 크다. 이 비용을 줄이는 연구 방향 자체가 하나의 흐름을 이룰 만큼, “환경을 만드는 것”은 “환경으로 학습하는 것”과 맞먹는 별도의 공학 과제다.
앞서 이 절 서두에서 환경이 갖춰야 할 네 요건으로 샌드박스·결정성·병렬 실행·상태 초기화를 꼽았다. 앞의 두 사례가 주로 샌드박스(의존성을 재현하는 실행 환경 자체)의 비용을 보여줬다면, 나머지 둘도 각자의 이유로 만만치 않다.
병렬 실행. RL 학습 한 스텝은 보통 같은 프롬프트에서 여러 궤적을 동시에 굴려 그룹 내 상대 비교로 advantage를 계산한다(#33의 GRPO가 그 전형이다). 환경 기반 reward에서는 이 “동시에 여러 궤적을 굴린다”가 곧 동시에 여러 개의 독립된 샌드박스를 띄운다는 뜻이다. SWE-Gym 스타일이라면 궤적 하나당 별도의 Docker 컨테이너가 필요하다는 뜻이고, 그룹 크기가 \(G\)면 한 프롬프트당 \(G\)개의 컨테이너가 동시에 CPU·메모리·디스크 I/O를 다툰다. 컨테이너 하나의 기동 자체에도 초 단위의 시간이 들고, 수백 개를 동시에 띄우면 디스크 I/O와 네트워크 대역폭이 병목이 된다 — 텍스트만 생성하면 되는 추론 RL과 달리, 에이전트 RL의 병렬화는 GPU가 아니라 인프라(컨테이너 오케스트레이션)의 병렬화 문제로 옮겨간다.
상태 초기화. 매 롤아웃은 정확히 같은 시작 상태에서 출발해야 궤적 간 비교가 공정하다. 코드 에이전트라면 매 에피소드마다 저장소를 커밋 시점으로 되돌리고, 이전 에피소드가 남긴 파일 변경·프로세스·임시 파일을 깨끗이 지워야 한다. 이 리셋을 매번 처음부터(의존성 재설치부터) 하면 에피소드 하나 시작하는 데만 몇 분이 걸릴 수 있다 — 그래서 SWE-Gym이 사전 빌드 Docker 이미지를 통째로 배포하는 것도 이 이유다. 이미지 하나를 스냅샷째로 띄우면 의존성 설치 단계를 건너뛰고 곧바로 깨끗한 초기 상태에서 시작할 수 있다. 반대로 리셋이 불완전하면(예: 이전 에피소드의 캐시 파일이 남아 있으면) 같은 행동인데도 이전 에피소드의 흔적 때문에 다른 결과가 나올 수 있다 — 이건 다음 절에서 다룰 비결정성 문제의 또 다른 원천이다.
결정성이 깨지면 credit이 오염된다
환경을 갖췄다고 끝이 아니다. 그 환경이 결정적이지 않으면, 즉 같은 상태에서 같은 행동을 해도 다른 결과가 나올 수 있다면, 지금까지 이 시리즈가 애써 세운 credit assignment 전체가 흔들린다. #2가 정리한 “에이전트 RL이 credit assignment를 다시 어렵게 만드는 여섯 가지 이유” 중 첫 번째가 바로 이것이었다 — 환경 전이가 확률적이면, 같은 상태를 재현해 비교하는 전략의 전제 자체가 깨진다.
이 문제가 실제로 학습을 어떻게 망가뜨리는지 정량적으로 보여준 최근 사례가 AutoForge(Cai et al., arXiv 2025, arXiv 2512.22857)다. 이 논문은 고객 서비스형 에이전트 태스크(소매·항공·통신 도메인)를 위한 환경을 자동으로 합성하는데, 이런 환경에는 정적인 테스트 스위트가 아니라 시뮬레이션된 사용자(user agent)가 들어간다. 문제는 이 시뮬레이션된 사용자 자체가 하나의 LLM이라는 점이다 — 가끔 정보를 잘못 알려주거나(hallucinate), 원래 알려줘야 할 정보를 누락한다.
이게 credit assignment에 어떤 영향을 주는지가 핵심이다. 에이전트가 완벽하게 옳은 행동을 했는데도, 시뮬레이션된 사용자가 실수로 필요한 정보를 안 주면 태스크는 실패로 끝난다. 이 실패의 최종 reward는 GRPO의 그룹 정규화를 거쳐 그 궤적 전체에, 즉 에이전트의 올바른 행동에까지 페널티로 방송된다. 저자들은 이 마스킹 없이 학습을 돌린 결과를 직접 관찰했다 — 학습 곡선이 후반부로 갈수록 오히려 하락하는 추세를 보였다는 것이다. 원인은 논문의 표현 그대로다. “시뮬레이션된 사용자의 실수로 인한 태스크 실패가, 에이전트의 옳은 행동에 페널티를 줘서 에이전트를 혼란에 빠뜨린다.”
해법으로 저자들이 쓴 것이 두 가지다. 첫째는 마스킹이다 — 별도의 LLM으로 “이 궤적에서 시뮬레이션된 사용자가 실수를 했는가”를 판별해, 그런 궤적을 advantage·loss 계산에서 아예 제외한다. 이 마스킹을 켜고 끄고 비교한 결과, 마스킹 없이는 학습 후반부에 성능이 떨어지던 것이 마스킹을 켜면 안정적으로 유지됐다. 둘째는 환경 단위 advantage 추정이다 — GRPO의 표준적인 그룹(같은 프롬프트에서 뽑은 \(G\)개 궤적) 대신, 같은 환경 인스턴스에서 나온 궤적끼리 묶어 평균·표준편차를 계산했더니 더 정확한 advantage 비교가 가능해지고 reward 곡선이 더 안정적으로 상승했다.
이 사례가 보여주는 원칙은 명확하다. 환경의 비결정성은 노이즈를 더하는 데서 그치지 않는다. 그 노이즈가 정책이 실제로 통제할 수 없는 원인(환경 쪽 실수)에서 왔는데도, credit assignment는 그걸 정책의 잘못으로 착각하고 페널티를 물린다. #2가 유도한 분산 증가(\(O(T) \to O(T^2)\))가 “노이즈의 양”에 관한 문제였다면, 이 문제는 “노이즈의 방향” 자체가 뒤틀리는 문제다 — 옳은 행동에 나쁜 신호가, 혹은 그 반대가 체계적으로 붙는다.
환경 신호만으로 충분한가 — 3부의 나머지 두 장으로 넘어가는 기준
여기까지 정리한 내용을 종합하면, 환경 신호를 reward의 주 원천으로 쓸지를 판단하는 질문을 세 개로 좁힐 수 있다.
| 질문 | Yes | No |
|---|---|---|
| 태스크의 성공 조건을 프로그램으로 검증할 수 있는가(테스트, 상태 비교, 정답 대조) | 아래로 진행 | 규칙 자체를 못 쓴다 — #11의 judge로 |
| 그 검증 로직이 진짜 목표를 직접 확인하는가, 아니면 대리 지표에 의존하는가 | 아래로 진행 | Motif 사례처럼 뚫릴 위험 — 판정 정의를 다시 설계하거나 #11의 judge로 교차 검증 |
| 환경을 결정적으로, 그리고 학습에 필요한 만큼 병렬로 재현할 수 있는가 | 환경 신호를 주 reward로 사용 | 환경 신호를 보조 신호로 두고 #10의 도구 호출 채점이나 judge와 결합 |
세 질문 모두를 통과하는 태스크는 생각보다 좁다 — 코드처럼 성공 조건이 명확하고, 판정 로직이 실제 목표와 거의 일치하며, 샌드박스를 충분히 병렬로 돌릴 수 있는 도메인이다. 반대로 하나라도 걸리면, 환경 신호는 여전히 유용하지만 단독으로는 부족한 신호가 된다. #10이 도구 호출 자체의 성패를 채점하는 방법을, #11이 이 세 질문 중 어느 것도 만족 못 하는 태스크에서 judge를 신뢰할 만하게 쓰는 방법을 각각 이어받는다.
Experiments
부분 테스트 통과를 보상으로 쓸 때의 설계
중간 상태 검증(테스트 일부 통과)을 reward로 바로 쓰고 싶은 유혹은 자연스럽다. “전부 통과하면 1점, 하나도 못 하면 0점”인 이진 reward보다, “통과한 비율”을 쓰면 더 촘촘한 신호를 줄 수 있을 것 같다. 그런데 이 직관은 SWE-bench 스타일의 F2P(FAIL_TO_PASS)/P2P(PASS_TO_PASS) 구조에서 정확히 반대로 작동한다. 토이 예제로 확인해보자.
설정. 어떤 GitHub 이슈를 고치는 태스크가 있다. 이 이슈가 실제로 고쳐졌는지 확인하는 F2P 테스트가 3개(원래는 fail, 고쳐지면 pass여야 한다), 기존 기능이 안 깨졌는지 확인하는 P2P 테스트가 20개(원래도 pass, patch 이후에도 pass여야 한다) 있다고 하자. 총 23개 테스트다.
정책 A — 아무것도 하지 않는다. 코드에 손을 대지 않는 patch를 낸다. F2P는 원래 fail 상태 그대로이므로 0/3 통과. P2P는 아무것도 안 건드렸으니 20/20 그대로 통과. 통과 비율을 그대로 reward로 쓰면
\[R_A = \frac{0 + 20}{23} \approx 0.870\]정책 B — 실제로 고치려다 일부만 성공한다. F2P 중 1개를 실제로 고쳤지만, 그 과정에서 관련 없는 코드를 건드려 P2P 중 2개가 회귀(regression)로 깨졌다. F2P 1/3, P2P 18/20 통과.
\[R_B = \frac{1 + 18}{23} \approx 0.826\]문제. \(R_A > R_B\)다. 아무것도 하지 않은 정책이, 실제로 이슈의 3분의 1을 고친 정책보다 더 높은 reward를 받는다. 이유는 단순하다 — 통과 비율이라는 지표에서 20개짜리 P2P 집합이 3개짜리 F2P 집합을 압도하기 때문에, “이미 잘 되고 있던 20개를 그대로 두는 것”이 “3개 중 1개를 실제로 고치려다 20개 중 2개를 건드리는 것”보다 산술적으로 이긴다. 이 구도에서 GRPO나 PPO의 advantage는 정확히 나쁜 방향을 강화한다 — 정책은 문제를 회피하고 아무것도 안 하는 쪽으로 수렴한다. #2가 정리한 echo trap(탐색을 포기하고 안전한 행동만 반복하는 붕괴)이 여기서도 그대로 재현된다.
더 심각한 변형도 있다. 정책이 일반적인 로직을 고치는 대신, 주어진 F2P 테스트가 확인하는 정확한 입력값만 하드코딩으로 통과시키는 지름길을 찾을 수 있다. 앞서 본 EvalPlus의 발견 — 부실한 테스트를 통과한 코드 중 상당수가 실제로는 틀렸다는 것 — 이 평가 시점의 우연한 결과였다면, RL 학습에서는 이 지름길이 그래디언트를 통해 적극적으로 탐색되고 강화된다. “쉬운 테스트만 골라 통과시키는” 최적화는 은유가 아니라, 통과 비율 reward 아래에서 문자 그대로 최적 정책이다.
더 나은 설계. 핵심은 두 가지를 구별하는 것이다 — P2P는 지켜야 할 제약이지 쌓아 올릴 성취가 아니고, F2P는 달성해야 할 목표이지 이미 확보된 점수가 아니다. 이 구분을 반영하면 다음과 같은 형태가 자연스럽다.
\[R = \begin{cases} -1 & \text{P2P 중 하나라도 회귀(regression)가 발생} \\ \dfrac{n_{\text{F2P}}}{N_{\text{F2P}}} & \text{P2P가 전부 유지된 경우} \end{cases}\]\(n_{\text{F2P}}\)는 통과한 F2P 테스트 수, \(N_{\text{F2P}}\)는 전체 F2P 테스트 수다. 이 설계 아래서 세 정책을 다시 비교해보자.
| 정책 | F2P | P2P | 회귀 발생 | 결과 |
|---|---|---|---|---|
| A(아무것도 안 함) | 0/3 | 20/20 | 없음 | \(R = 0/3 = 0\) |
| B(1개 고치되 회귀 발생) | 1/3 | 18/20 | 있음(2개) | \(R = -1\) |
| C(1개만 안전하게 고침) | 1/3 | 20/20 | 없음 | \(R = 1/3 \approx 0.333\) |
이제 순서가 뒤집힌다. \(R_C > R_A > R_B\) — 회귀 없이 안전하게 일부를 고친 정책(C)이 가장 높은 점수를, 아무것도 안 한 정책(A)이 중간을, 회귀를 낸 정책(B)이 가장 낮은 점수를 받는다. 이게 애초에 우리가 원했던 순서다. 회귀는 진짜로 나쁜 일이니 가장 강하게 벌주고, 아무것도 안 하는 것은 중립이며, 안전하게 이룬 부분적 진전은 그 진전만큼 보상받는다. 이 설계를 극단으로 밀어붙인 특수 케이스가 바로 SWE-bench 자체의 “resolved” 판정이다 — F2P를 전부(비율이 아니라 AND로) 요구하는 것은, 이 표의 P2P 게이트 아이디어를 F2P 쪽에도 그대로 적용해 “부분적으로 고친 척”할 여지를 원천적으로 닫아버린 가장 엄격한 버전인 셈이다.
환경 신호의 밀도 — 도메인별 비교
지금까지 다룬 신호들이 실제로 얼마나 촘촘하게 주어지는지는 도메인마다 크게 다르다. 이 차이가 이 시리즈 4부(#12~#14)가 도메인별로 따로 장을 나누는 이유이기도 하다.
| 도메인 | 대표 신호 | 밀도 | 근거 | 담당 편 |
|---|---|---|---|---|
| 코드 | 유닛 테스트 결과(F2P/P2P), 컴파일·런타임 에러 | 촘촘 — 테스트마다 개별 판정 가능 | SWE-bench 인스턴스당 평균 120.8개 테스트(중앙값 P2P 51개) | #13 |
| 검색 | 최종 답 정답 대조(EM), 일부 hop의 supporting fact 대조 | 중간 — 최종 답은 검증 가능하나 중간 검색 스텝의 질은 대개 간접적 | Search-R1은 outcome 기반 reward(EM)만으로 7개 QA셋에서 RAG 대비 최대 41% 개선 | #12 |
| 웹·GUI | 최종 화면·DB 상태와 목표 상태의 일치 여부 | 희소 — 대개 에피소드 끝의 이진 판정뿐 | WebArena: GPT-4 에이전트 end-to-end 성공률 14.41%(사람 78.24%) | #14 |
세 도메인을 가르는 기준은 결국 하나다 — 환경이 “지금 얼마나 잘하고 있는가”를 에피소드 도중에 관측 가능한 형태로 노출하는가. 코드는 테스트를 몇 개든 원하는 만큼 쪼개 실행할 수 있으니 태생적으로 촘촘하다. 검색은 최종 답이야 정답과 대조하면 그만이지만, “이 중간 검색 쿼리가 좋았는가”는 검색 결과 안에 정답 단서가 있었는지를 봐야 하는 간접적인 판정이라 중간 정도다. 웹·GUI는 태스크마다 “성공”을 정의하는 최종 상태 체커를 별도로 만들어야 하고, 그 체커가 에피소드 도중의 중간 진행도까지 세밀하게 알려주는 경우는 드물어 가장 희소하다. 밀도가 낮을수록 #2가 정리한 세밀한 입도(턴·스텝) credit assignment를 적용할 재료 자체가 부족해진다는 뜻이므로, 밀도가 낮은 도메인일수록 환경 신호만으로는 부족해 #10이나 #11의 대안이 더 무거운 역할을 맡게 된다.
통계 요약
이 글에서 확인한 핵심 사례와 수치를 한 표로 모은다.
| 절 | 핵심 사례 | 확인된 수치 |
|---|---|---|
| 왜 특별한가 | judge 편향·라벨 잡음 없음, 낮은 비용 | 프론티어 모델로 태스크 하나 해결에 1달러 이상(SWE-Gym) |
| 테스트 커버리지 부족 | EvalPlus / HumanEval+ | 테스트 80배 증강, pass@k 최대 19.3~28.9%p 하락, 모델 순위 역전 |
| 판정 로직 = 대리 지표 | Motif의 NetHack oracle 태스크 | 환각을 유도해 오라클처럼 보이는 것을 만들어 태스크 완료 판정을 얻음(던전 1층을 넘지 않고도) |
| 파서 취약점 | 정답 추출 정규식(토이 예제) | 파서가 엄격하면 false negative, 관대하면 false positive |
| 환경 구축 비용 | SWE-Gym / SWE-smith | 200 인간-시간 + 10,000 CPU-core-hour(SWE-Gym) vs 자동 합성으로 5만 인스턴스(SWE-smith) |
| 비결정성 | AutoForge의 시뮬레이션 유저 | 마스킹 없이는 학습 후반부 성능 하락, 환경 단위 advantage 추정으로 완화 |
| 부분 테스트 보상 설계 | 토이 예제(F2P 3개, P2P 20개) | 단순 비율 reward는 \(R_A(0.870) > R_B(0.826)\)로 무행동을 우대, 게이트형 설계는 \(R_C(0.333) > R_A(0) > R_B(-1)\)로 정상화 |
Conclusion
이 글의 결론은 한 문장으로 압축된다. 환경은 가장 저렴하고, 가장 편향 없고, 가장 먼저 시도해야 할 reward 원천이다. 다만 “파라미터가 없다”는 사실이 지켜주는 것은 판정 함수의 안전함뿐이지, 그 함수에게 무엇을 검증하라고 시켰는지의 안전함이 아니다.
정리하면,
- 환경이 주는 신호는 종료 상태 검증(에피소드), 중간 상태 검증(턴·스텝), 실행 피드백(스텝·토큰), 비용 신호(직교축)로 나뉘고, 이 넷은 #2의 입도 지도 위에 각자 자리를 갖는다.
- 환경 신호가 특별한 이유는 judge 편향과 라벨 잡음이 없고, 비용이 낮다는 것이다. #33 DeepSeek-R1의 RLVR 논리가 정확히 같은 근거로 성립했고, 이 글은 그 논리를 멀티턴 환경으로 확장했다.
- 그런데도 뚫린다 — 테스트 커버리지 부족(EvalPlus, pass@k 최대 28.9%p 하락), 판정 로직이 대리 지표일 때(Motif의 NetHack oracle, misalignment by composition), 파서 취약점이라는 세 지점에서다. 공통점은 뚫리는 게 함수가 아니라 판정 정의라는 것.
- 검증 가능한 환경을 만드는 것 자체가 값비싼 공학 문제다(SWE-Gym: 200 인간-시간 + 10,000 CPU-core-hour). 그리고 그렇게 만든 환경이 결정적이지 않으면(AutoForge의 시뮬레이션 유저), credit assignment가 옳은 행동에 그른 페널티를 물리는 방향으로 오염된다.
- 부분 테스트 통과를 순진하게 비율로 reward化하면 “아무것도 하지 않는 쪽”이 “부분적으로 고치려다 일부 회귀를 낸 쪽”을 이기는 역전이 생긴다. 회귀를 게이트로, 목표 달성을 그 안의 graded credit으로 분리하면 이 역전이 바로잡힌다.
이 글이 다룬 것은 reward를 얻는 세 갈래 중 가장 저렴한 첫 번째 길이었다. 하지만 모든 태스크가 이렇게 명확한 판정 조건을 갖지는 않는다. 도구 호출 자체의 성패를 무엇으로 채점할지는 #10 도구 호출을 어떻게 채점하나로, 그리고 애초에 규칙으로 검증할 수 없는 태스크에서 judge를 어떻게 신뢰할 만하게 쓸지는 #11 궤적을 judge가 채점한다로 이어진다. 그리고 이 글에서 예고한 Motif의 NetHack oracle 사례는, “환경이 있으니 안전하다”는 생각이 에이전트 RL 전체에서 얼마나 쉽게 배신당하는지를 #15 에이전트의 reward hacking에서 더 깊이 다룬다.
참고 문헌
- Pan et al., 2024. Training Software Engineering Agents and Verifiers with SWE-Gym. ICML 2025.
- Yang et al., 2025. SWE-smith: Scaling Data for Software Engineering Agents. NeurIPS 2025.
- Cai et al., 2025. AutoForge: Automated Environment Synthesis for Agentic Reinforcement Learning.
- Klissarov et al. (Mila / Meta AI), 2023. Motif: Intrinsic Motivation from Artificial Intelligence Feedback. ICLR 2024.
- Liu et al., 2023. Is Your Code Generated by ChatGPT Really Correct? Rigorous Evaluation of Large Language Models for Code Generation (EvalPlus). NeurIPS 2023.
- Jimenez et al. (Princeton), 2023. SWE-bench: Can Language Models Resolve Real-World GitHub Issues?. ICLR 2024.
- Zhou et al. (CMU), 2023. WebArena: A Realistic Web Environment for Building Autonomous Agents. ICLR 2024.
- Jin et al., 2025. Search-R1: Training LLMs to Reason and Leverage Search Engines with Reinforcement Learning.
- Guo et al. (DeepSeek-AI), 2025. DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning. Nature 2025.
Agentic RL 설계 시리즈
이 글은 Agentic RL 설계 시리즈의 아홉 번째 글이다.
1부. 왜 에이전트는 다른가
- 에이전트 RL은 무엇이 다른가 — 장기 지평·희소 보상·긴 궤적
- 공을 어디에 돌릴 것인가 — credit assignment 47개 방법의 지도
- 멀티턴 RL 실무 가이드 — 무엇이 실제로 작동하는가
2부. credit assignment — 공을 어디에 돌릴 것인가
- 결과만으로는 부족하다 — 장기 지평에서 증폭되는 RLVR의 한계
- 턴 단위로 공을 나눈다 — turn-level reward 설계
- 스텝을 단위로 삼는다 — 행동 단위 궤적 표현과 credit
- 토큰과 세그먼트로 더 잘게 — 세밀한 입도의 득과 실
- shaping은 약인가 독인가 — 중간 보상의 효율과 위험
3부. reward를 어디서 얻나
- (현재 글) 환경이 곧 reward다 — 샌드박스·테스트·상태 검증
- 도구 호출을 어떻게 채점하나 — ToolRL·ToolRM
- 궤적을 judge가 채점한다 — rubric 생성형 reward의 확장
4부. 도메인별 설계
- 검색 에이전트 — Search-R1에서 DeepDive까지
- 코드 에이전트 — SWE-RL과 테스트라는 reward
- 웹·GUI 에이전트 — end-to-end 멀티턴 RL
5부. 실패와 방어
- 에이전트의 reward hacking — 판정기가 뚫린다, 그리고 조합의 실패
6부. 실전 종합
- 프론티어 모델은 실제로 어떻게 하나 — 최신 모델들의 agentic RL 설계
본 시리즈는 16편으로 구성된다.
Enjoy Reading This Article?
Here are some more articles you might like to read next: