본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 24. 21:18

AI에게 격리하여 테스트를 작성하게 했더니, 앱은 작동하는데 테스트는 하나도 통과하지 못했다.

요약

AI 에이전트 간의 물리적 격리를 통해 테스트 컨닝을 방지하려 했으나, 인터페이스 불일치로 인해 테스트가 모두 실패한 실험 사례를 다룹니다. 격리가 성공하면 숨겨져 있던 구현과 테스트 간의 사양 불일치 문제가 드러남을 보여줍니다.

핵심 포인트

  • 물리적 디렉토리 격리는 AI의 정보 유출(컨닝)을 효과적으로 차단함
  • 격리 시 구현체와 테스트 간의 인터페이스 불일치 문제가 발생함
  • AI 에이전트에게 사양만 제공할 경우 존재하지 않는 객체를 날조할 위험이 있음
  • 성공적인 에이전트 협업을 위해서는 동작뿐 아니라 인터페이스 정의가 필수적임

지난번에 이어서 작성한다.

지난번에는 구현하는 로컬 LLM이 인수 테스트(Acceptance Test)를 컨닝하고 있었다. 프롬프트에 "참조하지 마라"라고 적는 것만으로는, 존재를 알게 된 에이전트는 읽으러 간다. 차단은 의지가 아니라 구조로 해야 한다는 것까지가 지난번 내용이었다.

이번에는 그것을 구조로 다시 시도했다. 그리고 반대로 실패했다.

1. 다시 구성한 구조

지난번으로부터의 변경점은 두 가지다.

구조로 격리했다: 구현, 단위 테스트(Unit Test), 인수 테스트를 별도의 디렉토리로 나누고, 각 담당자에게는 자신의 루트(Root) 경로만 전달한다. 프롬프트에 "보지 마라"라고 쓰지 않는다. 쓰지 않아도 보이지 않는다. -
기동을 요구사항에 추가했다: 지난번에 main이 없었던 이유는, 아무도 "앱이 기동한다"를 요구사항에 쓰지 않았기 때문이다. 사양에 LAUNCH-1 (앱을 기동하면 메인 윈도우가 표시되어 조작 가능해진다)을 추가했다.

역할은 지난번과 동일한 세 역할이다. 구현과 단위 테스트는 로컬 LLM, 인수 테스트는 클라우드 LLM, 채점은 pytest가 담당한다. 다른 점은 서로의 폴더가 물리적으로 보이지 않는다는 것이다.

2. 일어난 일

세 주체 모두 각각의 성과물은 만들었다. 하지만 서로 맞물리지 않았다.

2.1 본체: 작동했다

로컬 LLM이 구현한 본체는 기동했다. 지난번에는 존재하지 않았던 GUI가 이번에는 있다.

起動したアプリ

4분면이 표시되고, "추가" 버튼을 누르면 태스크명 입력과 분면 버튼이 나오는 윈도우가 뜬다. 사양대로다. LAUNCH-1을 요구사항에 추가한 효과가 나타났다. 지난번의 결말은 이것으로 차단되었다.

2.2 단위 테스트: 본체를 보지 않고, 본체를 날조했다

단위 테스트 담당은 본체(../app)를 참조하지 않았다. 대신 스스로 app.py라는 별개의 것을 만들고, 그것에 대해 단위 테스트를 작성했다.

존재하는 본체를 무시하고, 존재하지 않는 본체를 만들어내어 그것을 테스트하고 초록색(Pass)으로 만들었다. 지난번은 "테스트가 보지 않는 코드를 쓰지 않았다"였다면, 이번에는 "테스트 대상이 없어서 테스트 대상을 만들었다"였다. 결핍과 날조, 방향은 반대지만 출처는 같다. AI는 없는 것을 묵묵히 채워 넣는다.

원인은 프롬프트에 있었다. 본체의 위치를 절대 경로로 적지 않은 것이 원인이었다.

2.3 인수 테스트: 본체에 도달하지 못했다

인수 테스트 담당은 사양만을 보고 테스트를 작성했다. 구현은 보지 않았다. 격리는 효과가 있었다.

그 결과, 테스트가 호출하는 인터페이스(Interface)와 본체가 구현한 인터페이스가 어긋났다. 메서드(Method) 이름도 인자(Argument)도 별개다. 테스트는 단 하나도 실행할 수 없었다.

3. 왜 맞물리지 않았는가

지난번과 비교해 보면 일어난 일은 정반대다.

비교 항목지난번이번
격리누출됨효과가 있었음

지난번의 전 항목 그린(Green)은 격리가 깨져 있었기 때문에 얻을 수 있었던 결과였다. 로컬이 인수 테스트를 컨닝하여 그 인터페이스에 구현을 맞췄다. 그래서 일치했고, 그래서 통과했다. 오염이 접착제 역할을 하고 있었다.

이번에는 그 접착제를 떼어냈다. 그러자 본체와 인수 테스트는 처음부터 서로 다른 인터페이스를 상상하며 만들어졌다는 사실이 드러났다. 빨간색(Fail)은 문제가 발생한 것이 아니다. 지난번에는 초록색으로 숨겨져 있던 불일치가 드디어 보였을 뿐이다.

여기서 알게 된 것이 있다. 구현을 보여주지 않고 사양으로부터 테스트를 작성하게 하려면, 사양이 "동작(Behavior)"뿐만 아니라 "인터페이스(Interface)"까지 정의하고 있어야 두 주체가 맞물린다. 현재의 사양에는 메서드나 인자의 경계가 적혀 있지 않다. 그래서 각 담당자가 제멋대로 발명하여 어긋났다.

그렇다면 그 인터페이스는 사양인가, 설계인가.

구현하는 입장에서는 메서드 이름이나 인자를 어떻게 나눌지가 설계다. 하지만 그것을 받아서 검증하는 입장에서는 바꿀 수 없는 사양이다. 같은 문서가 서 있는 위치에 따라 설계도 되고 사양도 된다. 업무에서도 타인과 협업할 때 하는 것이다. 인터페이스 제어 문서(ICD).

4. 다음에 할 일

ICD를 사이에 두고 본체와 인수 테스트의 경계를 맞춘다. 그 검증은 별도의 기사로 다룬다.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0