CoSPlay: 자기 생성 코드와 Unit Test로 하는 Test-Time Cooperative Self-Play
CoSPlay: Cooperative Self-Play at Test-Time with Self-Generated Code and Unit Test
TL;DR Highlight
Ground Truth 없이도 코드와 Unit Test가 서로 평가하며 함께 품질을 높이는 추론 시간 최적화 프레임워크
Who Should Read
LLM 기반 코드 생성 파이프라인의 정확도를 높이려는 ML 엔지니어나 연구자. 특히 Ground Truth 테스트 케이스 없이 추론 시간에 코드 품질을 검증하고 싶은 개발자.
Core Mechanics
- Ground Truth(정답 데이터) 없이 코드 후보와 Unit Test가 서로를 평가하며 함께 개선되는 'Cooperative Self-Play' 방식을 제안. 학습 없이 추론 시간에만 동작함.
- Stage 1(탐색-공격 아이디어 생성): LLM에게 다양한 풀이 전략을 탐색하게 하고, 각 전략의 잠재적 실패 모드에서 Unit Test 아이디어를 유도해 처음부터 차별화된 테스트 풀을 구성.
- Stage 2(실행 매트릭스 기반 Self-Play): 코드×UT 실행 매트릭스의 pass count를 신호로 삼아 ① 전부 실패하는 코드 제거, ② spurious coupling(잘못된 코드와 잘못된 UT가 우연히 맞는 현상) 차단, ③ 신뢰도 높은 UT로 코드 수정, ④ 변별력 잃은 UT 교체를 반복.
- Stage 3(출력 합의 클러스터링): pass count가 동점인 코드들을 랜덤 입력으로 실행해 출력 시그니처가 같은 그룹으로 묶고, 가장 큰 클러스터의 코드를 최종 선택. 올바른 코드는 같은 출력을, 틀린 코드는 제각각의 출력을 낸다는 원리 활용.
- UT pass count가 높을수록 해당 UT가 실제로 정확할 가능성이 높고, 코드 pass count가 높을수록 실제로 정답일 가능성이 높다는 상관관계를 이론과 실험으로 검증. Ground Truth 없이도 품질 신호로 사용 가능.
- Self-play 중 코드와 UT의 pass count 분포가 라운드를 거치며 점차 높은 쪽으로 이동. 7B 기준 저품질 UT 비율이 약 29.9%, 저품질 코드 비율이 약 25.2% 감소함.
Evidence
- Qwen2.5-7B-Instruct에 적용 시 평균 BoN(Best-of-N 정확도)이 22.1%→33.2%로 +11.1%p 향상. UT 정확도는 14.6%→78.3%로 +63.7%p 향상.
- GT 데이터 4.5k로 학습한 RLVR 모델 CURE-7B(BoN 32.9%)를 학습 없이 동일 수준(33.2%)으로 따라잡음. CURE-7B에 CoSPlay를 추가 적용하면 BoN이 32.9%→38.6%로 추가 +5.7%p 향상.
- 682K 토큰 예산으로 37.2% pass@1 달성. 유사하거나 더 많은 예산을 쓰는 기존 TTS 기법(BoN N=256: 745K 토큰으로 22.5%, ThinkCoder Round20: 1.16M 토큰으로 27.8%)보다 높은 성능.
- DeepSeek-V3.2-685B 같은 대형 모델에도 효과적: 평균 BoN 65.7%→68.2%, 특히 가장 어려운 CodeForces 벤치마크에서 39.3%→50.0%로 +10.7%p 향상.
How to Apply
- 코드 생성 파이프라인에 GT 테스트가 없는 상황이라면, LLM에게 풀이 전략 여러 개를 먼저 생성시키고, 각 전략에서 예상 실패 케이스를 추출해 Unit Test 입력으로 활용하라. 직접 UT를 생성하는 것보다 초기 UT 품질이 훨씬 높아진다(UT 정확도 12.5%→37.2%).
- 코드 후보가 여러 개 생성된 경우, pass count 매트릭스를 만들어 '모든 UT를 통과한 코드'나 '아무 코드도 통과 못 한 UT'를 걸러내는 반복 루프를 추가하라. 라운드마다 품질이 올라가며 최대 5라운드만으로도 유의미한 개선이 가능하다.
- Best-of-N 방식으로 동점 코드가 여러 개 남은 경우, 랜덤 유효 입력 R개로 각 코드를 실행해 출력 벡터가 같은 것끼리 클러스터링하고, 가장 큰 클러스터에서 최종 코드를 선택하라. 클러스터 크기 자체가 정확도의 신뢰할 수 있는 프록시다.
Code Example
# CoSPlay 핵심 로직 스케치 (Python pseudo-code)
def cosplay(problem: str, llm, Nc=16, Nt=16, Tmax=5, R=16):
# Stage 1: 아이디어 탐색
hints = llm.generate(f"Generate high-level solution hints for: {problem}")
plans = [llm.generate(f"Expand plan for hint: {h}") for h in hints]
attack_ideas = [llm.generate(f"What edge cases / failure modes for plan: {p}?") for p in plans]
# 코드 & UT 풀 초기화
codes = [llm.generate_code(problem, plan=p) for p in plans[:Nc]]
uts = []
for i in range(Nt):
if i < Nt // 2:
inp = llm.generate(f"Generate random valid input for: {problem}")
else:
inp = llm.generate(f"Generate input targeting failure: {attack_ideas[i % len(attack_ideas)]}")
# 자기 일관성 필터: 4번 샘플 중 3번 이상 동의하면 채택
outputs = [llm.solve(problem, inp) for _ in range(4)]
if outputs.count(max(set(outputs), key=outputs.count)) >= 3:
uts.append((inp, max(set(outputs), key=outputs.count)))
# Stage 2: Self-Play 반복
for _ in range(Tmax):
M = [[execute(c, ut[0]) == ut[1] for ut in uts] for c in codes]
code_pass = [sum(row) for row in M]
ut_pass = [sum(M[i][j] for i in range(len(codes))) for j in range(len(uts))]
# Step 1: 0 pass 코드 제거 후 재샘플
codes = [llm.generate_code(problem) if code_pass[i] == 0 else codes[i]
for i in range(len(codes))]
# Step 2: 가장 낮은 non-trivial UT 교체 (spurious coupling 제거)
# Step 3: 가장 신뢰도 높은 non-trivial UT로 실패 코드 수정
# Step 4: 0% / 100% pass UT 교체
# ... (각 스텝 후 M 재계산)
# Stage 3: 클러스터 선택
top_codes = [c for i, c in enumerate(codes) if code_pass[i] == max(code_pass)]
random_inputs = [llm.generate(f"Random valid input: {problem}") for _ in range(R)]
signatures = {c: tuple(execute(c, z) for z in random_inputs) for c in top_codes}
clusters = {} # signature -> list of codes
for c, sig in signatures.items():
placed = False
for key in clusters:
if all(sig[k] == key[k] or sig[k] == 'ERR' or key[k] == 'ERR'
for k in range(R)):
clusters[key].append(c)
placed = True
break
if not placed:
clusters[sig] = [c]
best_cluster = max(clusters.values(), key=len)
return best_cluster[0]Terminology
관련 논문
당신의 에이전트를 밀어붙여라: Long-Horizon LLM 에이전트의 Quantitative Goal Persistence 측정과 강제
LLM 에이전트가 '100개 찾아줘'를 실제로 100개 찾을 때까지 멈추지 않게 만드는 방법과 벤치마크.
Multi-Stream LLMs: 프롬프트, 사고, 입출력을 병렬 스트림으로 분리하는 새 논문
현재 LLM이 입력·사고·출력을 순차적으로만 처리하는 구조적 한계를 지적하고, 각 역할을 별도의 병렬 스트림으로 분리해 동시에 처리할 수 있는 Multi-Stream 방식을 제안한 논문이다. 에이전트의 효율성·보안·모니터링 가능성을 모두 개선할 수 있다는 점에서 주목받고 있다.
HarnessAPI: Streaming API와 MCP 도구를 하나로 통합하는 Skill-First 프레임워크
FastAPI HTTP 엔드포인트와 MCP 도구를 하나의 폴더에서 자동으로 동시에 만들어주는 Python 프레임워크
Runtime (YC P26): 팀 전체를 위한 Sandboxed Coding Agent 플랫폼
엔지니어링팀뿐 아니라 마케팅, 영업, 지원팀까지 누구나 샌드박스 환경에서 coding agent를 안전하게 쓸 수 있게 해주는 인프라 플랫폼으로, YC P26 배치 스타트업이 런치했다.
AI 코딩 루프에 Formal Verification Gate 적용하기
AI가 생성한 코드에서 보안 불변식(invariant)을 지키게 하려면 프롬프트 지시보다 타입 시스템 같은 구조적 제약이 훨씬 효과적이라는 주장과 구현 방법을 소개한다.
AI로 Rust 코드 100K 라인 작성하며 얻은 교훈 (2025)
Azure RSL(분산 합의 라이브러리)을 Rust로 재구현하면서 AI 코딩 에이전트를 활용해 4주 만에 100K 라인을 작성한 경험담으로, Code Contracts와 Spec-Driven Development를 AI와 조합하는 실전 워크플로우를 공유한다.
Related Resources
Original Abstract (Expand)
Recently, Reinforcement Learning with Verifiable Rewards (RLVR) and Test-Time Scaling (TTS) have advanced LLM code generation through executable verification. Yet Ground-Truth Unit Tests (GT UTs) remain a bottleneck: SOTA RLVR methods require them for costly training, while existing TTS methods lose competitiveness without them. This motivates GT-free TTS, where existing methods directly use self-generated UTs to refine and select code candidates. Yet such UTs are often noisy or spuriously coupled with wrong code, and UT quality in turn cannot be validated without reliable code. The key challenge is therefore to jointly improve both. To this end, we present CoSPlay, a GT-free, training-free framework that jointly improves codes and UTs through cooperative self-play. It first explores diverse solution ideas and identifies their potential failure modes to produce discriminative UT ideas. It then uses bidirectional pass-count signals from the Code-UT execution matrix to iteratively prune or fix weak codes and refresh or replace unreliable UTs, letting the two pools co-evolve. Finally, when multiple codes remain tied at the highest pass count, it picks the final code from the largest output-consensus cluster, since correct codes agree on the same inputs while wrong codes diverge. Experiments on four challenging benchmarks show that CoSPlay on Qwen2.5-7B-Instruct improves average BoN from 22.1% to 33.2% and UT accuracy from 14.6% to 78.3%, matching or surpassing the RLVR model CURE-7B. When applied to CURE-7B, it further improves BoN by 5.7%. CoSPlay also generalizes across diverse backbones and outperforms GT-free TTS baselines under comparable token budgets, with continued gains as the budget scales up. These results suggest a scalable inference strategy for competitive code generation without any GT data.