AI 코딩 회귀버그를 줄이는 Architecture Guardian Skill

Architecture Guardian Skill이 AI 코딩 에이전트의 빠른 구현과 회귀버그 위험 사이에 모듈 경계를 세우는 생성형 이미지

Architecture Guardian Skill은 제가 AI 코딩 에이전트에게 모듈 경계, 의존성 방향, 회귀위험을 계속 확인시키기 위해 만든 작업 지침입니다. Claude Code나 Codex에게 프롬프트로 지시하면 결과물은 생각보다 빨리 나옵니다. 문제는 프로젝트가 커진 뒤부터 시작됩니다.

처음에는 신기합니다. “이 버튼 추가해 줘”, “이 UI 고쳐 줘”, “이 버그 수정해 줘”라고 말하면 에이전트는 제법 그럴듯하게 구현합니다. 결과물을 보는 데도 큰 시간이 걸리지 않습니다. 그래서 말한 대로 작동하면 그냥 그런가 보다 하고 넘어가기 쉽습니다.

하지만 기능 추가, UI 수정, 버그 패치, 리팩터링이 겹치기 시작하면 프로젝트는 점점 산으로 갑니다. 이것을 고치니 저것이 깨지고, 저것을 고치니 멀쩡했던 앱이 수많은 오류를 뱉습니다. 이런 문제를 회귀버그라고 부릅니다. 새 변경이 기존에 잘 되던 동작을 다시 망가뜨리는 상황입니다.

이 글에서는 제가 왜 전역 코딩 지침만으로는 부족하다고 느꼈는지, 객체지향·모듈화·캡슐화를 왜 계속 강조하게 되었는지, 그리고 그 문제의식을 담아 만든 Architecture Guardian Skill을 Claude Code와 Codex에 어떻게 연결해 쓰고 있는지 정리합니다. AI 코딩 작업을 길게 반복시키는 방식이 궁금하다면 goal 명령어 실전 활용, 반복 점검 자동화가 궁금하다면 Claude Code /loop 스킬 점검 글도 같이 보면 흐름이 이어집니다.

Architecture Guardian Skill이 AI 코딩 에이전트의 빠른 구현과 회귀버그 위험 사이에 모듈 경계를 세우는 생성형 이미지
빠른 구현보다 먼저 필요한 것은 프로젝트가 산으로 가지 않게 막는 경계다

AI 에이전트는 왜 쉬운 길로 가나

Claude Code든 Codex든 기본적으로는 사용자가 원하는 결과를 만들어 내려고 합니다. “기능을 추가해 줘”라고 하면 기능을 추가합니다. “버그를 고쳐 줘”라고 하면 버그를 고칩니다. 이 자체가 문제는 아닙니다. 오히려 그래서 생산성이 올라갑니다.

문제는 에이전트가 보통 현재 요청을 가장 짧은 경로로 만족시키는 방향을 선호한다는 점입니다. 기존 구조를 깊게 이해하고, 앞으로 생길 변경까지 고려하고, 이 수정이 다른 화면과 데이터 흐름에 어떤 영향을 주는지 끝까지 따지는 일은 비용이 큽니다. 사용자가 명시하지 않으면 에이전트는 그 비용을 줄이려 합니다.

그래서 AI 코딩의 핵심은 “프롬프트를 잘 쓰면 된다”에서 끝나지 않습니다. 에이전트가 챙기지 않는 뒷일을 사용자가 작업 절차에 넣어야 합니다. 쉬운 길로 가지 말라고 매번 혼내는 것이 아니라, 애초에 산으로 향하는 길목을 막아야 합니다.

회귀버그는 구조의 빚에서 나온다

회귀버그는 단순히 테스트를 안 돌려서만 생기는 문제가 아닙니다. 테스트가 부족하면 발견이 늦어질 뿐입니다. 더 근본적인 원인은 코드의 책임과 경계가 흐려졌는데도 새 기능이 계속 덧붙는 데 있습니다.

예를 들어 화면 A의 상태를 고치려고 공용 유틸을 수정했는데, 그 유틸을 화면 B와 C도 암묵적으로 쓰고 있었다고 해 봅시다. 화면 A는 고쳐졌지만 화면 B의 예외 케이스가 깨집니다. 다시 화면 B를 고치려고 공용 상태를 건드리면, 이번에는 화면 C가 깨집니다. 이런 식으로 버그패치가 또 다른 버그를 부릅니다.

AI 코딩에서 작은 수정이 약한 아키텍처 경계를 지나 회귀버그로 확산되는 생성형 이미지
작은 수정이 여러 모듈로 번질 때 회귀버그의 표면적은 빠르게 커진다

프로젝트가 작을 때는 이런 위험이 잘 보이지 않습니다. 파일도 적고, 기능도 적고, 사용자가 직접 눌러 보면 대충 확인됩니다. 하지만 프로젝트가 커지면 변경의 영향 범위가 사람 머릿속에 들어오지 않습니다. 이때부터는 “잘 작동해 보인다”가 품질 기준이 될 수 없습니다.

전역 지침으로 먼저 막아 본 것

그래서 저는 한동안 프로젝트의 전역 관리 문서에 아래 방향의 지침을 넣어 두었습니다.

객체지향적으로 코딩하며, 각 기능별 상호 의존성을 최소화하고, 유지보수성을 높이기 위한 모듈화, 코드 수정 시 회귀위험을 낮추기 위한 캡슐화를 최우선으로 한다. 스타일을 계속 유지하고 새로운 기능 추가, 코드작성 계획시 기존 코딩 스타일을 따르도록 한다. 짧은 코드와 효율성 높은 코딩보다 이후의 유지보수를 고려한다.

이 지침은 없는 것보다 낫습니다. 적어도 에이전트가 “짧게 끝내는 구현”만 바라보지 않도록 계속 신호를 줍니다. OpenAI의 Codex 문서도 AGENTS.md가 저장소 단위의 지속 지침을 제공한다고 설명하고, Codex의 customization 문서에서도 프로젝트 guidance, skills, MCP, subagents가 서로 보완 관계라고 정리합니다. Claude Code도 Skills를 통해 반복 가능한 지침과 워크플로를 확장할 수 있습니다.

하지만 전역 지침만으로는 충분하지 않았습니다. 이유는 간단합니다. “유지보수를 고려하라”는 말은 방향을 주지만, 작업 중 반드시 확인해야 하는 체크리스트가 되지는 않습니다. 에이전트가 바쁠 때 가장 먼저 생략하는 것도 바로 이런 추상적인 원칙입니다.

객체지향 모듈화 캡슐화 지침이 코드 구조를 정리하지만 일부 의존성이 새는 모습을 보여주는 생성형 이미지
전역 지침은 방향을 잡아 주지만, 매 변경의 영향 분석까지 자동으로 보장하지는 않는다

객체지향, 모듈화, 캡슐화는 무엇을 뜻하나

객체지향은 역할을 가진 단위로 나누는 일

객체지향을 단순히 클래스를 많이 만드는 방식으로 이해하면 실패합니다. 핵심은 데이터와 동작을 책임 단위로 묶고, 각 단위가 자기 역할을 분명히 갖게 하는 것입니다. “이 값은 누가 소유하는가”, “이 상태를 바꿀 권한은 어디에 있는가”, “이 로직은 어느 책임에 속하는가”를 계속 묻는 방식에 가깝습니다.

모듈화는 변경의 범위를 좁히는 일

모듈화는 코드를 폴더로 예쁘게 나누는 일이 아닙니다. 한 기능을 바꿀 때 영향을 받는 영역을 가능한 한 작게 만드는 일입니다. 좋은 모듈은 내부 구현을 바꿔도 바깥 계약이 유지됩니다. 나쁜 모듈은 작은 수정에도 여러 기능이 함께 흔들립니다.

캡슐화는 뒷일을 숨기는 것이 아니라 보호하는 일

캡슐화는 내부를 감추기만 하는 기술이 아닙니다. 외부에서 함부로 건드리면 안 되는 상태와 규칙을 보호하는 장치입니다. 에이전트가 빠르게 구현하려고 내부 상태를 직접 만지거나, 여러 화면에서 같은 mutable state를 공유하거나, 임시 public API를 만들면 캡슐화가 깨집니다. 그 순간부터 회귀버그가 생길 통로도 넓어집니다.

그래서 내가 Architecture Guardian Skill을 만들었다

최근에는 이 문제를 전역 문장 하나가 아니라 제가 계속 재사용할 수 있는 스킬로 다루기로 했습니다. 그렇게 만든 것이 Architecture Guardian Skill입니다. 처음 의도는 거창한 프레임워크를 만드는 것이 아니었습니다. 제가 매번 코드 리뷰에서 반복하던 질문을 Claude Code와 Codex가 작업 중에 먼저 떠올리게 만들고 싶었습니다.

그래서 README에는 이 스킬을 Claude Code와 Codex 모두에서 동작하는 아키텍처 거버넌스 Skill이라고 적어 두었습니다. 제가 이 표현을 쓴 이유는 분명합니다. 기능 추가, 리팩터링, 수정, 리뷰를 할 때마다 변경 영향 분석, 의존성 방향, 회귀위험을 선택 사항이 아니라 기본 절차로 만들고 싶었기 때문입니다. OpenAI의 Build skills 문서도 skill을 지침, 리소스, 선택적 스크립트를 묶어 재사용 가능한 워크플로로 만드는 형식이라고 설명합니다.

구조는 일부러 단순하게 잡았습니다. 공통 정책은 core/policy/ARCHITECTURE_GUARDIAN_POLICY.md에 두고, 기계 판독용 규칙은 ARCHITECTURE_GUARDIAN_RULESET.json에 두었습니다. PLAN, REVIEW, REFACTOR, CHANGE-REVIEW, FULL-AUDIT 같은 모드별 템플릿도 나누었습니다. Claude용 CLAUDE.md 어댑터와 Codex용 AGENTS.md 어댑터를 따로 둔 것도 같은 이유입니다. 도구는 달라도 제가 요구하는 아키텍처 기준은 같아야 하기 때문입니다.

Architecture Guardian Skill이 계획 구현 리뷰 검증 과정에서 모듈 경계를 보호하는 생성형 이미지
Architecture Guardian Skill은 계획, 구현, 리뷰, 검증 단계마다 같은 기준을 반복 적용하게 만든다

내가 스킬에 넣은 기준

제가 Architecture Guardian Skill에 넣은 핵심 우선순위는 구현 편의보다 구조 안정성을 앞에 두는 것입니다. 대략 아래 순서입니다.

  • 캡슐화
  • 낮은 결합도
  • 높은 응집도
  • 명시적인 의존성
  • 단일 책임
  • 의존성 역전
  • 테스트 가능성
  • 유지보수성
  • 확장성
  • 구현 편의

중요한 점은 “구현 편의”를 맨 마지막에 두었다는 것입니다. AI 에이전트는 현재 요청을 빨리 만족시키려는 힘이 강합니다. 그래서 사용자가 별도로 압력을 걸지 않으면 편한 길을 택합니다. 저는 이 스킬을 통해 반대 방향의 압력을 주고 싶었습니다. 변경된 모듈은 무엇인지, 새 의존성은 생겼는지, public contract가 바뀌었는지, 상태 소유권은 분명한지, 테스트로 무엇을 확인해야 하는지를 매번 묻게 만드는 것입니다.

전역 문서에는 짧은 포인터만 두기로 했다

스킬을 만들면서 제가 중요하게 본 점은 프로젝트 관리 문서에 긴 정책을 계속 복사하지 않는 것이었습니다. 긴 정책을 여러 곳에 복사하면 곧 서로 달라집니다. 그러면 어느 지침이 진짜 기준인지 다시 헷갈립니다. 그래서 README에서도 Claude Code와 Codex 적용 방식은 짧은 포인터를 두고, 공통 정책 파일을 참조하는 형태로 정리했습니다.

예를 들면 프로젝트의 AGENTS.mdCLAUDE.md에는 “기능 추가, 변경 계획, 리뷰, 리팩터링, 회귀위험이 있는 작업에서는 Architecture Guardian을 참조하라”는 정도만 둡니다. 실제 판단 기준은 스킬의 공통 정책으로 모읍니다. 제가 이렇게 만든 이유는 Claude Code와 Codex를 함께 쓰더라도 기준이 갈라지지 않게 하기 위해서입니다.

비용은 늘지만 더 싼 선택일 수 있다

물론 제가 만든 이런 스킬을 쓰면 토큰 소비량이 늘고 작업 시간도 늘어납니다. 에이전트가 바로 코드를 쓰기 전에 구조를 읽고, 영향 범위를 따지고, 테스트 계획을 말하고, 변경 후 다시 리뷰해야 하기 때문입니다. 빠른 데모를 만들 때는 답답할 수 있습니다.

하지만 저는 이 비용이 더 싸다고 판단했습니다. 유지보수의 늪에 빠져 48시간 이상 goal을 돌리고, 회귀버그를 고치고, 리팩터링에 다시 시간을 쓰는 것보다 처음부터 아키텍처 검사를 작업 흐름에 넣는 편이 낫습니다. 특히 이미 사용자가 있는 앱, 데이터가 쌓이는 앱, 배포 이후 고치기 어려운 앱이라면 더 그렇습니다.

AI 코딩은 코드를 빨리 쓰게 해 줍니다. 하지만 빨리 쓴 코드가 오래 버틴다는 뜻은 아닙니다. 그래서 이제는 “얼마나 빨리 만들었는가”보다 “다음 변경을 견딜 수 있는가”를 더 자주 묻고 있습니다. 구현·리뷰·수정의 반복도 결국 같은 문제의식에서 출발했습니다.

필요하면 가져다 쓰면 된다

제가 만든 Architecture Guardian Skill은 GitHub에 공개해 두었습니다. 필요한 사람은 그대로 사용해도 되고, 자기 프로젝트 방식에 맞게 수정해도 됩니다. 직접 원하는 스킬을 만들어 쓰는 일도 생각보다 어렵지 않습니다. 오히려 반복해서 같은 리뷰를 하고 있다면, 그 리뷰 기준은 스킬로 빼는 편이 더 자연스럽습니다.

물론 제가 만든 스킬이 완벽한 방어막은 아닙니다. 그래도 “작동하니 됐다”에서 멈추지 않고, 변경 영향과 회귀위험을 매번 확인하게 만드는 것만으로도 결과물은 조금씩 달라집니다. AI 에이전트가 챙기지 않는 뒷일을 작업 절차에 넣는 것. 제가 Architecture Guardian Skill에 기대한 역할은 바로 그 지점에 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다