까보KKABO.DEV
KOEN

코딩 에이전트

코딩 에이전트가 나눠 만든 변경을 하나로 합칠 때

승인 API와 화면이 서로 다른 오류 응답을 예상하면 각자 테스트는 통과해도 연결한 기능은 어긋난다. 설명용 개발 사례로 작업 분리, 응답 합의, 리뷰와 통합 검증의 순서를 살펴본다.

2026-09-10읽는데 11분Read in English#coding-agents#code-review#testing

업무 요청을 승인하는 기능을 만든다고 가정해 보자. 한 에이전트는 승인 API를 만들고, 다른 에이전트는 승인 버튼과 결과 안내를 만든다. 검증 담당은 두 변경을 합친 뒤 사용자가 요청을 승인하는 흐름을 확인한다.

서버는 이미 처리된 요청에 승인 시도가 오면 오류를 반환한다. 화면은 그 오류를 읽어 “이미 처리된 요청입니다”라고 안내해야 한다. 그런데 서버와 화면이 오류 코드의 위치를 다르게 알고 있다면 어떨까. 서버 테스트는 자신이 만든 응답을 검사하고, 화면 테스트는 자신이 예상한 가짜 응답을 사용한다. 둘 다 통과했는데 실제로 연결한 화면에는 일반 오류만 나올 수 있다.

이 글은 이런 상황을 설명용 예시로 삼아 작업을 나누고 합치는 과정을 살펴본다. 실제 장애나 실행 실험을 재구성한 이야기는 아니다. API 이름·응답 형태·상태 코드는 예시를 위해 정했다.

먼저 결과를 보고 싶다면 글 끝의 승인 기능 실험에서 ‘각자 검사’와 ‘연결 검사’를 차례로 눌러 보자. 화면이 읽는 필드와 테스트용 응답을 바꾸면서, 어떤 검사가 무엇을 놓치는지 확인할 수 있다.

서버와 화면이 같은 응답을 보고 있는가

승인 API의 경로를 POST /requests/{id}/approve라고 하자. 서버는 승인 권한과 요청 상태를 확인한다. 권한이 있는 사용자가 이미 처리된 요청을 다시 승인하려 하면 HTTP 409와 다음 본문을 반환한다.

json
{
  "code": "ALREADY_PROCESSED"
}

화면 담당은 오류 응답을 다음과 같이 예상했다.

json
{
  "error": {
    "code": "ALREADY_PROCESSED"
  }
}

화면의 HTTP 클라이언트가 응답 본문을 response.data에 담는다고 가정하면, 서버가 보낸 오류 코드는 response.data.code에 있다. 화면은 response.data.error.code를 찾는다. 해당 코드가 없을 때 일반 오류 문구를 보여주도록 작성했다면 사용자는 “승인하지 못했습니다”만 보게 된다.

서버 테스트는 HTTP 409와 최상위 code를 검사하므로 통과한다. 화면 테스트는 error.code가 있는 가짜 응답을 주입하고 안내 문구를 검사하므로 역시 통과한다. 두 테스트는 각자가 정한 동작을 확인했지만, 서버가 보내는 값과 화면이 읽는 값이 같은지는 확인하지 않았다.

이런 불일치는 사람이 나눠 개발할 때도 생긴다. 코딩 에이전트에게 일을 나눠 맡긴다고 해서 서버와 화면 사이의 합의가 자동으로 생기는 것은 아니다. 여러 구현을 동시에 진행하려면 각자가 독자적으로 정해도 되는 부분과 함께 맞춰야 하는 부분부터 구분해야 한다.

담당을 나누기 전에 함께 볼 동작을 정한다

“서버를 만들어줘”, “화면을 만들어줘”만으로 작업을 나누면 각 담당이 빠진 요구사항을 스스로 채울 수 있다. 승인 성공 뒤 목록을 다시 불러올지, 이미 처리된 요청에 무엇을 표시할지, 권한 오류를 어떤 형태로 전달할지도 그 빈칸에 들어간다.

이 예시라면 시작할 때 아래 정도는 함께 정할 수 있다.

상황 서버가 할 일 화면이 할 일
권한이 있고 승인 가능한 요청 상태를 승인 완료로 변경하고 성공 응답 성공 안내 뒤 목록 갱신
권한은 있지만 이미 처리된 요청 추가 변경 없이 409와 최상위 code 반환 “이미 처리된 요청입니다” 안내 뒤 목록 갱신
승인 권한이 없는 사용자 상태를 바꾸지 않고 403 반환 권한이 없다는 안내

이는 이 예시의 동작 정의다. 모든 승인 API가 같은 상태 코드나 화면 동작을 써야 한다는 뜻은 아니다. 기존 서비스에 오류 응답 규칙이 있다면 그 규칙을 먼저 따른다.

이제 서버 담당은 상태 변경과 응답을 구현하고, 화면 담당은 정해진 응답을 처리할 수 있다. 검증 담당은 처음부터 성공·이미 처리됨·권한 없음의 시나리오와 필요한 데이터를 준비한다. 실제 API와 화면을 연결한 검사는 구현을 합친 뒤 실행한다.

검증 담당을 마지막에 부르는 것만이 유일한 방식은 아니다. 요구사항을 읽는 단계에서 “이미 승인된 요청을 또 승인하면 어떻게 되나요?” 같은 빠진 조건을 찾게 할 수도 있다. 다만 시나리오를 준비했다는 것과 구현을 실행해 통과했다는 것은 구분해야 한다.

승인 동작·응답 형태 결정서버 구현단위 검사화면 구현단위 검사검증 시나리오 준비변경 통합검증 준비 완료실제 승인 흐름 검사오류 안내·상태 변화 확인
  • 1행: 승인 동작·응답 형태 결정
  • 2행: 서버 구현 단위 검사, 화면 구현 단위 검사, 검증 시나리오 준비
  • 3행: 변경 통합, 검증 준비 완료
  • 4행: 실제 승인 흐름 검사
  • 5행: 오류 안내·상태 변화 확인
  • 승인 동작·응답 형태 결정 → 서버 구현 단위 검사
  • 승인 동작·응답 형태 결정 → 화면 구현 단위 검사
  • 승인 동작·응답 형태 결정 → 검증 시나리오 준비
  • 서버 구현 단위 검사 → 변경 통합
  • 화면 구현 단위 검사 → 변경 통합
  • 검증 시나리오 준비 → 검증 준비 완료
  • 변경 통합 → 실제 승인 흐름 검사
  • 검증 준비 완료 → 실제 승인 흐름 검사
  • 실제 승인 흐름 검사 → 오류 안내·상태 변화 확인
그림 1. 설명용 승인 기능의 작업 순서

시나리오 준비는 구현과 함께 진행할 수 있지만, 실제 흐름 검사는 두 구현의 통합을 기다린다.

작업 지시에도 이 의존 관계를 적는다. 예를 들어 서버 담당에게는 “이미 처리된 요청은 상태를 바꾸지 않고 409와 최상위 code를 반환한다”, 화면 담당에게는 “그 code를 읽어 안내한 뒤 목록을 갱신한다”를 함께 전달한다. 응답을 바꿔야 한다면 서버 담당이 혼자 수정하고 완료를 선언하지 않고, 화면과 검증 담당에게 영향 범위를 알린다. 통합 담당은 세 사람이 같은 응답 형태를 기준으로 작업 중인지 확인한다.

에이전트 호출과 작업 폴더 분리는 다르다

코딩 도구는 작업을 나눠 맡기는 기능을 제공한다. 서브에이전트(subagent, /ˈsʌbˌeɪdʒənt/, 서브 에이전트)는 주 에이전트가 일부 작업을 맡기는 보조 에이전트다. OpenAI 문서는 여러 서브에이전트를 실행하고 결과를 모으는 흐름을 설명하며, 탐색·검토처럼 읽기 중심인 작업과 여러 에이전트가 동시에 코드를 수정하는 작업을 구분한다. 동시 수정에는 충돌과 조정 부담이 생길 수 있다고 안내한다. OpenAI Subagents (새 탭에서 열림).

Claude Code의 agent teams는 공유 작업 목록과 담당 간 메시지, 작업 의존성을 제공하는 또 다른 사례다. 2026년 9월 10일 확인한 공식 문서에서는 실험 기능이며 기본적으로 비활성화돼 있다. 같은 파일을 수정하거나 의존성이 많은 작업에는 단일 세션 등의 대안이 더 적합할 수 있다고 설명한다. 이 글에서 다루는 것은 공식 문서의 기능이며 직접 사용한 결과는 아니다. Claude Code agent teams (새 탭에서 열림).

이와 별개로 작업 파일을 분리하는 기능이 있다. 워크트리(worktree, /ˈwɜːrk triː/, 워크 트리)는 같은 Git 저장소에 연결된 별도 작업 폴더다. 각 작업 폴더에서 서로 다른 변경을 진행할 수 있다. 대화를 여러 개 만드는 것과 작업 폴더를 여러 개 만드는 것은 다른 결정이다. Git worktree (새 탭에서 열림).

승인 API와 화면을 별도 작업 폴더에서 만들면 한 담당의 수정이 다른 담당의 작업 파일에 즉시 섞이는 일을 피할 수 있다. 그렇다고 앞의 오류 응답 문제가 해결되는 것은 아니다. 두 변경을 Git이 충돌 없이 합쳐도, 화면이 잘못된 필드에서 오류 코드를 읽는 동작은 남는다.

실행 환경도 따로 봐야 한다. 폴더를 나눴어도 같은 포트를 쓰는 서버를 띄우거나 같은 테스트 DB를 바꿀 수 있다. 병렬 실행이 필요하다면 작업별 포트와 데이터 범위도 정해야 한다. 작업 폴더가 분리됐다는 사실만으로 모든 실행 자원이 분리된 것은 아니다.

가짜 응답을 서로 다른 곳에서 만들지 않는다

화면의 단위 테스트에 가짜 응답을 쓰는 것은 유용하다. 서버를 매번 실행하지 않고도 버튼의 대기 상태나 오류 문구를 빠르게 검사할 수 있다. 문제는 그 데이터가 실제 응답과 달라졌는데 이를 확인하는 곳이 없는 경우다.

이 예시에서는 서버 응답 형태를 하나로 정하고 화면의 가짜 응답도 그 형태에 맞출 수 있다. 이미 API 명세나 공통 응답 타입을 관리한다면 이를 기준으로 사용한다. 실제 서버의 응답을 명세와 비교하는 검사도 두면, 문서나 타입만 함께 틀린 상태로 유지되는 위험을 줄일 수 있다.

응답 형태를 맞춰도 끝은 아니다. 화면이 코드를 올바르게 읽지만 엉뚱한 메시지를 보여줄 수 있고, 안내는 맞지만 목록을 갱신하지 않을 수도 있다. 필드 구조를 검사하는 테스트와 사용자가 보게 될 동작을 검사하는 테스트는 서로 다른 부분을 맡는다.

나누기 전에 완벽한 명세를 만들 필요는 없다. 다만 지금 병렬로 진행할 부분이 어느 가정에 기대고 있는지는 보여야 한다. 승인 상태와 오류 형식이 계속 바뀌는 중이라면 그 부분을 먼저 정하고 화면 작업을 이어가는 편이 낫다. 모든 담당이 동시에 코드를 쓰기 시작하는 것이 목표는 아니다.

리뷰할 변경과 검사한 버전을 맞춘다

작업을 넘겨받을 때 “구현 완료, 테스트 통과”만 있으면 무엇을 검사했는지 다시 찾아야 한다. 승인 API 담당의 단위 테스트와 화면 담당의 단위 테스트가 모두 통과했다는 말은 실제 승인 흐름까지 확인했다는 말이 아니다.

각 담당에게는 변경 위치와 대상 버전, 실행한 검사, 확인하지 못한 범위를 함께 받는 것이 좋다. 이 예시의 화면 담당이라면 다음과 같은 보고가 가능하다.

승인 버튼의 대기 상태와 오류 안내를 구현했다. 정해진 오류 응답 형태를 사용하는 단위 테스트를 실행했다. 실제 승인 API와 연결한 검사는 아직 하지 않았다.

이것도 설명용 보고다. 실제 작업에서는 어떤 커밋 또는 변경 상태에서 무슨 명령을 실행했고 결과가 어땠는지까지 연결한다. 미검증 범위가 적혀 있으면 통합 담당이 다음 검사를 정할 수 있다.

검토 담당은 이 요약과 함께 실제 변경을 읽는다. 서버가 내보내는 응답, 화면이 읽는 필드, 테스트가 넣는 값을 나란히 보면 불일치를 찾을 수 있다. “오류 처리가 부족하다”보다는 “서버는 최상위 code를 보내는데 화면은 error.code를 읽으므로 이미 처리된 요청의 안내가 일반 오류로 나온다”처럼 위치와 조건이 드러나는 지적이 수정에 도움이 된다.

다른 에이전트에게 검토를 맡겨도 구현자의 설명만 전달하면 같은 가정을 반복할 수 있다. 요구사항과 실제 diff, 검사 결과를 보게 하고, 구현자의 주장과 맞지 않는 경로도 찾아보게 해야 한다. 리뷰어의 수만으로 검토 품질을 판단하기는 어렵다.

검토 후 변경이 추가되면 검사 결과가 가리키는 버전도 다시 확인한다. 오류 응답을 고친 뒤 서버 테스트만 다시 실행했다면, 바뀐 응답을 읽는 화면까지 확인했는지는 아직 남아 있다. 수정과 관련된 검사를 다시 실행하고, 새 변경이 기존 리뷰의 범위를 벗어나는지 판단한다.

화면만 고쳤을 때 남는 검사

서버의 최상위 code를 기준으로 삼기로 했다고 하자. 화면을 고친 다음 무엇을 확인할지는 변경 전후를 나란히 놓으면 분명해진다.

변경 상태 화면 단위 검사 실제 응답을 연결한 검사 다음 행동
화면·가짜 응답이 모두 error.code 안내 검사 통과 일반 오류 안내로 실패 정한 응답 형태에 맞춰 화면 수정
화면만 code로 수정 옛 가짜 응답 때문에 실패 이미 처리됨 안내 정상 가짜 응답도 정한 형태로 갱신
화면·가짜 응답 모두 code 안내 검사 통과 안내 정상, 목록 갱신은 별도 확인 사용자 흐름에 목록 확인 포함

두 번째 줄에서는 단위 검사가 실패해도 화면 수정을 되돌릴 이유가 없다. 실제 서버 응답과 합의한 동작을 확인한 뒤, 오래된 테스트 데이터를 고쳐야 한다. 반대로 세 번째 줄의 초록 표시만으로 목록 갱신까지 구현됐다고 말할 수도 없다. 검사의 이름보다 실제로 비교하는 값이 중요하다.

합친 뒤에는 실제 승인 흐름을 확인한다

통합 담당은 주 에이전트가 맡을 수도 있고, 별도 에이전트나 사람이 맡을 수도 있다. 누구든 승인 API와 화면의 어떤 버전을 합치는지 알고 있어야 하며, 연결한 결과를 검사할 수 있어야 한다.

이 예시에서는 승인 가능한 요청을 준비해 화면에서 승인한다. 성공 안내와 목록 갱신을 확인하고 실제 요청 상태가 바뀌었는지 본다. 이어서 이미 처리된 요청에 다시 승인을 시도해 서버가 예시에서 정한 409와 오류 코드를 보내는지, 화면이 맞는 안내를 표시하는지, 추가 상태 변경은 없는지 확인한다.

두 번째 시도에는 첫 승인 전에 열어 둔 다른 화면처럼 이전 상태가 남아 있는 상황을 사용할 수 있다. 현재 화면에서 버튼이 사라졌다고 이 경우까지 검증된 것은 아니다. 단, 이 순차 시나리오가 동시에 도착한 두 승인 요청의 처리까지 증명하지는 않는다. 동시 승인이 가능한 기능이라면 그 조건은 별도로 검사해야 한다.

권한 없는 사용자의 승인 시도도 따로 확인한다. 화면에서 버튼을 숨겼더라도 서버가 요청을 거절하고 상태를 유지하는지 확인해야 한다. 화면 안내와 서버의 권한 검사는 각각 필요한 동작이다.

통합 검증에서 codeerror.code의 차이를 발견했다면, 정한 응답 형태에 맞춰 구현과 가짜 응답을 고친다. 관련 단위 테스트와 실제 승인 흐름을 다시 실행한다. 검증 담당은 어떤 결과가 나와야 하는지 알고 있으면서, 구현 담당이 만든 가짜 응답에만 의존하지 않아야 한다.

여기까지의 실행과 확인도 에이전트에게 맡길 수 있다. 개발자가 정할 것은 기대하는 사용자 동작, 작업을 나눌 범위, 합친 결과를 받아들일 기준이다. 그 기준에 필요한 증거를 에이전트가 가져오도록 하고, 배포 여부는 팀의 운영 절차에 따라 판단한다.

다음 작업을 나눌 때는 아래처럼 시작할 수 있다.

맡기려는 작업 시작 방식 결과를 받을 때 확인할 것
같은 PR을 여러 관점에서 읽기 같은 버전을 읽기 전용으로 검토 지적 위치와 실패 조건
서로 간섭이 적은 기능 구현 작업 폴더와 수정 범위 분리 각자 검사와 합친 사용자 흐름
서로 맞물린 API·화면 변경 응답 형태와 동작을 먼저 결정 실제 응답과 화면 처리의 일치
성공·실패 흐름 검증 시나리오를 먼저 준비하고 통합 뒤 실행 화면 안내와 실제 상태 변화
같은 파일에 몰린 작은 수정 한 작성 세션에서 처리 변경 내용과 필요한 검사

직접 해보기: 각자 검사와 연결 검사

아래 실험은 앞의 승인 기능을 브라우저 안에서 작게 실행한다. 서버 응답은 본문에서 정한 최상위 code로 고정하고, 화면과 테스트가 그 응답을 어떻게 읽는지 바꿀 수 있게 했다. 서버의 응답 형식까지 함께 바꾸어 단순히 모양만 맞추는 대신, 정한 기준에 따라 어느 쪽을 고쳐야 하는지 살펴보기 위한 구성이다.

  1. 불일치 재현에서 두 검사를 차례로 실행한다. 서버와 화면의 단위 검사는 통과하지만 연결한 안내는 실패한다. 실제 응답과 화면에서 읽은 코드를 비교해 보자.
  2. 화면만 수정을 선택하고 다시 검사한다. 이번에는 연결한 안내가 맞는데 화면 단위 검사가 실패한다. 테스트가 여전히 어떤 응답을 넣는지 확인한다.
  3. 응답과 테스트 정렬로 두 검사를 통과시킨 뒤, 목록 갱신 누락을 선택한다. 안내 문구만 검사하면 놓치는 동작이 드러난다.
  4. 연결할 상황을 승인 가능한 요청, 권한 없는 사용자로 바꿔 본다. 오류 필드가 잘못돼도 성공 경로는 통과할 수 있다. 권한이 없을 때는 안내와 별개로 서버 상태가 유지되는지도 본다.

설정을 바꾸면 이전 검사 결과가 지워진다. 실제 개발에서도 수정 전 버전의 통과 기록을 수정 후 구현의 근거로 쓰지 않기 위해 같은 구분이 필요하다. 여기서의 ‘연결 검사’는 설명용 서버·화면 모델의 검사이며, 실제 서비스의 통합 테스트를 대신하지 않는다.

직접 해보기 · 승인 기능

각자 통과한 변경을 연결하면

먼저 ‘각자 검사’를 누른 뒤 ‘연결 검사’를 눌러 보자. 같은 설정에서 결과가 달라지는 이유를 아래 응답에서 찾을 수 있다.

서버 담당

이 예시의 합의: 오류 코드는 최상위 code에 보낸다.

{
  "code": "ALREADY_PROCESSED"
}
이미 처리된 요청 → HTTP 409

화면 담당

{
  "error": {
    "code": "ALREADY_PROCESSED"
  }
}

아직 실행하지 않았다. 처음 설정은 본문의 오류 응답 불일치를 재현한다.

각자 검사 · 409 안내

미실행

서버: 409·오류 코드·추가 변경 없음
화면: 가짜 응답을 넣어 안내 문구만 확인

연결 검사 · 선택한 상황

미실행

서버 모델의 응답을 화면 모델에 직접 전달

브라우저 안의 설명용 모델이다. 실제 에이전트·Git·API·DB를 실행하지 않는다. 매 검사마다 선택한 상황에서 새로 시작하며 동시 요청·네트워크 실패는 재현하지 않는다.