AI를 CI/CD에 심기: 파이프라인·테스트·에이전트 신뢰성 3단 설계

AI를 CI/CD에 심기: 파이프라인·테스트·에이전트 신뢰성 3단 설계

파이프라인 자동화, 에이전트 메모리 드리프트, AI 생성 테스트 검증—세 레이어를 통합하지 않으면 'AI-First 배포'는 그냥 빠른 장애 배포다.

CI/CD 자동화 mutation testing PITest Claude Code 메모리 에이전트 드리프트 AI 테스트 신뢰성 로컬 LLM 배포 파이프라인
광고

AI 도구를 CI/CD에 붙이는 팀은 이미 많다. 그런데 솔직히 물어보면, 실제로 '작동하는 구조'를 가진 팀은 드물다. 테스트는 AI가 썼지만 커버리지만 올라갔고, 에이전트는 어느 순간 지난주에 고친 버그를 다시 들여왔으며, 파이프라인은 초록 불을 켰는데 프로덕션에서 터졌다. 세 가지 기사가 각각 이 문제의 한 단면을 다룬다. 하지만 테크 리드 입장에서 보면, 이건 따로 해결할 수 있는 문제가 아니다. 파이프라인 자동화, 에이전트 신뢰성, 테스트 품질 검증은 하나의 스택으로 설계해야 한다.


1레이어: 파이프라인에 로컬 LLM 어시스턴트를 심는 법

dev.to에 올라온 사례(kennedyraju55)는 Ollama + Gemma 4 기반의 로컬 LLM 어시스턴트 4종을 CI/CD에 붙인 구조를 소개한다. 핵심은 단순하다: 모델이 판단하는 범위를 의도적으로 제한한다. 플레이키 테스트 분류기는 LLM에게 통계 계산을 시키지 않는다. 패스율 0.18, 최근 10회 결과를 먼저 코드로 계산한 뒤, 분류 질문만 던진다. PR 리스크 리뷰어는 "이 PR 좋은가요?"가 아니라 "PR 설명과 diff가 일치하나요?"를 묻는다. 배포 로그 감시자는 에러율이 임계치를 넘을 때만 LLM을 호출하고, 롤백 판단 기준을 프롬프트에 명시적으로 주입한다.

로컬 LLM을 택한 이유도 주목할 만하다. CI 환경에서 테스트 로그는 스키마명과 내부 호스트명을 담고, PR diff는 미출시 코드다. 외부 API로 보내는 순간 보안·컴플라이언스 리스크가 생긴다. 로컬 모델은 재현성(같은 프롬프트, 같은 출력), 무제한 호출, 3~8초 레이턴시라는 세 가지 현실적 장점을 준다. 이론적으로 더 좋은 모델이 외부에 있어도, CI 파이프라인 안에서는 '충분히 좋고 통제 가능한' 모델이 맞다.

테크 리드 시사점: LLM에게 전권을 주지 말 것. 통계는 코드, 패턴 인식은 LLM, 실행은 파이프라인. 역할을 분리해야 신뢰할 수 있는 자동화가 만들어진다. LLM이 잘하는 건 reading comprehension이지 architecture judgment가 아니다.


2레이어: 에이전트 메모리 드리프트를 막는 감사 규율

Claude Code 에이전트로 29일 동안 91,000줄을 생산한 개발자(michelfaure)의 경험은 불편한 진실을 드러낸다. 에이전트는 컴파일 성공을 선언했지만 실제로는 이미 제거된 QRCodeSVG를 참조하고, 사라진 props를 넘기고, JSX orphan을 남겼다. TypeScript가 빨간 불을 켜는 동안 에이전트는 "초록"이라고 말했다. 한 세션에서 네 번.

해결책은 더 좋은 모델이 아니었다. 기억을 구조화하는 것이었다. ~/.claude/agent-memory/ 아래에 다섯 유형의 파일을 유지한다: user_*(컨텍스트), feedback_*(사건에서 추출한 규칙), project_*(의사결정 이력), reference_*(외부 시스템 포인터), sessions/(날짜별 저널). 그리고 세 가지 리추얼이 이 메모리를 살아있게 만든다. 접근 수정이 생기면 즉시 피드백 파일을 쓴다(나중에가 아니라). 작업 단위가 끝나면 세션 파일을 남긴다. 2~3주마다 메모리와 코드를 교차 감사한다.

이 구조의 핵심 원리는 메모리 ↔ 코드의 핑퐁이다. 메모리가 코드에 질문한다(규칙이 여전히 지켜지고 있나?). 코드가 메모리를 교정한다(사실이 바뀌었나?). 이 루프가 없으면 메모리는 부패하고, 에이전트는 지난주에 고친 안티패턴을 다시 들여온다. 상대 날짜("다음 주")를 절대 날짜로 변환하는 규칙처럼, 작은 규율이 드리프트를 막는다.

테크 리드 시사점: 에이전트를 장기 프로젝트에 투입하면 세션 간 컨텍스트 손실은 피할 수 없다. 이걸 모델 탓으로 돌리면 해결책이 없다. 팀 차원에서 메모리 아키텍처를 설계하고, 감사 리추얼을 온보딩 프로세스에 넣어야 한다. 기억 관리는 개발자 개인의 취향이 아니라 팀의 품질 인프라다.


3레이어: AI 생성 테스트를 mutation testing으로 검증하기

AI가 테스트를 생성하는 속도는 이미 인간을 압도한다. 문제는 그 테스트가 실제로 무언가를 검증하고 있냐는 것이다. dev.to의 사례(machinecodingmaster)는 AI 생성 테스트의 세 가지 함정을 짚는다: assertion이 없는 테스트(코드 경로는 실행하지만 아무것도 확인하지 않음), 5,000줄 diff를 사람이 리뷰하는 병목, 테스트 스위트를 정적 아티팩트로 취급하는 관행.

해법은 PITest + Claude Code 에이전틱 루프다. PITest가 바이트코드 수준에서 뮤턴트를 주입하고, 테스트가 그 뮤턴트를 죽이지 못하면 테스트 스위트가 실패한 것이다. 살아남은 뮤턴트의 XML 리포트를 Claude Code에 직접 파이프로 넘기고, 구체적인 뮤턴트 유형(ConditionalsBoundaryMutator)과 라인 번호를 프롬프트에 포함해 자율적인 테스트 보강 루프를 만든다. 빌드 파이프라인에 mutationThreshold > 85%를 게이트로 걸면, AI 생성 로직이 검증되지 않은 PR은 머지 자체가 막힌다.

라인 커버리지와 뮤테이션 스코어의 차이는 명확하다. 커버리지는 코드가 실행됐는지 말해준다. 뮤테이션 스코어는 코드가 실제로 검증됐는지 말해준다. AI가 테스트를 대량 생성하는 환경에서 커버리지만 보면 초록 체크마크로 포장된 버그를 배포하게 된다.

테크 리드 시사점: 시니어 엔지니어의 역할이 바뀌고 있다. 테스트를 쓰는 게 아니라, 뮤턴트를 죽이는 에이전트를 오케스트레이션하는 것. 하지만 그 오케스트레이션의 품질 게이트—임계치 설정, 뮤턴트 유형 우선순위, 루프 종료 조건—는 여전히 사람이 설계해야 한다.


통합 관점: 세 레이어를 하나의 스택으로

세 기사를 따로 읽으면 각각 유용한 팁이다. 함께 읽으면 하나의 설계 원칙이 보인다: AI는 정해진 범위에서만 판단하고, 사람이 설계한 구조가 그 범위를 강제한다.

파이프라인 어시스턴트는 LLM이 잘하는 분류 질문만 받는다. 에이전트 메모리는 과거의 실수를 현재 세션에 주입한다. 뮤테이션 게이트는 AI 생성 테스트의 환각을 수치로 차단한다. 세 레이어가 없으면—파이프라인만 자동화하면 테스트 품질 문제가 남고, 테스트를 강화해도 에이전트가 다음 세션에 드리프트한다.

현실적인 도입 순서를 제안한다면: 먼저 뮤테이션 게이트로 현재 테스트 스위트의 실제 신뢰도를 측정하라. 숫자를 보면 팀이 움직인다. 그다음 에이전트 메모리 구조를 잡아라. Claude Code를 쓰는 팀이라면 지금 당장 feedback_* 파일부터 시작해도 된다. 마지막으로 파이프라인 어시스턴트를 점진적으로 붙여라—플레이키 테스트 분류기 하나만 넣어도 팀의 일상 노이즈가 줄어든다.

세 레이어를 전부 구축하는 데 몇 달이 걸릴 수도 있다. 하지만 방향은 지금 잡아야 한다. AI가 파이프라인에 깊이 들어올수록, 검증 구조 없는 자동화는 그냥 더 빠른 장애 배포가 된다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요