
AI 프론트엔드 에이전트를 일일이 감시하는 것을 그만두었습니다 — 그래서 가드레일(Guardrails)을 만들었습니다
요약
AI 에이전트가 생성하는 코드의 품질과 보안을 보장하기 위해 Claude Code용 가드레일 플러그인인 'fe-rail'을 개발했습니다. 이 도구는 스펙 정의부터 빌드, 리뷰, PR까지의 과정을 자동화하며 위험한 동작을 사전에 차단합니다.
핵심 포인트
- AI 에이전트의 과도한 자율성을 제어하기 위한 가드레일 필요성 강조
- fe-rail은 스펙-빌드-리뷰-PR로 이어지는 고정된 워크플로우 제공
- 보안 사고(예: .env 파일 커밋) 및 잘못된 코드 수정을 방지하는 자동 차단 기능
- 최소한의 인간 개입(Implement?, Commit?)으로 개발 프로세스 신뢰도 향상
Claude는 제가 읽는 속도보다 더 빠르게 프론트엔드 코드를 작성합니다. 그리고 그것이 바로 문제가 되었습니다.
몇 주 전의 평범한 오후의 모습입니다. 저는 기능을 요청하고, 수십 개의 파일이 나타나는 것을 지켜본 뒤, 다음 20분 동안 보안 요원 역할을 하며 시간을 보냅니다. 방금 git add .를 실행해서 제 .env 파일을 커밋에 쓸어 넣은 건 아닐까요? 저게 진짜 컴포넌트인가요, 아니면 또 다른 보라색 그라데이션과 드롭 섀도우(drop shadows)로 가득한 화면인가요? 테스트를 작성했나요, 아니면 그냥 작성했다고 말만 한 건가요? 빨간 밑줄을 없애려고 어딘가에 strict: false를 설정해 버린 건 아닐까요?
코드를 생성하는 것은 기본적으로 비용이 들지 않았습니다. 하지만 그것을 감시하는 데는 비용이 들었습니다.
그래서 저는 fe-rail을 만들었습니다: 고정된 스펙(spec) → 빌드(build) → 리뷰(review) → PR 루프를 통해 프론트엔드 작업을 수행하고, 제가 두려워하는 동작들을 차단하며, 오직 두 가지 질문을 하기 위해서만 멈추는 Claude Code 플러그인입니다.
제가 실제로 원했던 것
더 많은 자율성이 아닙니다. 더 적은 자율성이었습니다.
제가 살펴본 대부분의 에이전트 도구들은 모델에게 더 많은 실행 공간을 주려고 노력했습니다. 저는 그 반대를 원했습니다. 저는 프론트엔드를 직접 작성할 때 이미 신뢰하는 프로세스를 가지고 있습니다: 짧은 스펙(spec)을 작성하고, 타입을 먼저 빌드하고, 실제로 문제가 될 만한 것들(타입, 성능, 접근성, 순수 코드 품질)을 리뷰한 다음, 깔끔한 PR을 여는 것입니다. 저는 단지 제가 어깨 너머로 지켜보지 않아도 에이전트가 매번 이 과정을 따르기를 원했을 뿐입니다.
나머지 절반은 두려움 때문이었습니다. 어떤 실수들은 되돌리는 비용이 저렴합니다. 하지만 동료의 브랜치에 강제 푸시(force push)를 하거나, .env 파일을 커밋하는 것은 그렇지 않습니다. 저는 그런 일들이 단순히 권장되지 않는 수준이 아니라, 불가능하게 만들고 싶었습니다.
실행 모습
한 번의 명령, 두 번의 질문:
$ claude
> /fe-rail:fe-spec
...
이것이 전체적인 형태입니다. 두 번의 인간 확인, "Implement?"와 "Commit?". 그 사이의 모든 것은 스스로 실행됩니다.
여기 제가 덜 신경 써도 되게 된 작업들이 대략적으로 나열되어 있습니다:
| Before | fe-rail 사용 시 |
|---|---|
사소한 git add .나 강제 푸시(force push)를 위해 모든 diff를 재검토하는 것 | 훅(hook)에서 실행되기 전에 차단됨 |
| ... |
파이프라인
fe-rail은 다섯 개의 슬래시 명령어로 구성되어 있습니다:
/fe-rail:fe-spec는 대략적인 요청을 구조화된 사양(spec)으로 변환한 다음, 계속 진행할지 묻습니다./fe-rail:fe-build는 타입(types), 로직(logic), 컴포넌트(components), 테스트(tests) 순서로 고정된 순서에 따라 구현합니다./fe-rail:fe-review는 네 가지 축(four-axis) 검토를 실행합니다: 타입, 성능, a11y (웹 접근성), 그리고 품질입니다./fe-rail:fe-start feature.md는 이 모든 것을 연결하여 PR(Pull Request)까지 진행시킵니다./fe-rail:fe-doc-sync는 프로젝트를 읽고CLAUDE.md와README에 대한 업데이트를 제안합니다.
원할 때 하나씩 실행하거나, 아니면 fe-start가 주도하도록 맡길 수 있습니다.
사양 단계(spec step)는 텍스트로만 국한되지 않습니다. 만약 기능이 Figma 파일이나 스크린샷에 있다면, fe-vision이 이를 구체적인 화면과 상태로 읽어 들입니다. 슬라이드 덱 형태로 도착한다면, fe-deck-reader가 이를 화면과 그 사이의 흐름(flows)으로 분해합니다. 나중에 검토 시점에는 fe-vision이 또한 구축된 것의 스크린샷을 원래 참조와 비교하여 두 가지가 얼마나 벗어났는지 플래그를 지정할 수도 있습니다. 이 기능은 작동할 때마다 저를 놀라게 합니다.
두 체크인(check-in)이 'two'에 머물러 있는 방식에서 제가 신경 쓰는 작은 세부 사항이 있습니다. 사양 게이트(spec gate)에서
차단(Blocking)은 도구 호출(tool call)이 아예 발생하지 않음을 의미합니다 (훅이 코드 2로 종료됨). 경고(Warning)는 호출은 발생하지만 stderr를 통해 알림을 받는 것을 의미합니다. 몇 가지 차단 요소(blockers)는 다음과 같습니다:
guard.sh는git add ., 강제 푸시(force pushes),--no-verify,git reset --hard,git checkout/restore ., 그리고rm -rf /명령이 실행되기 전에 이를 중단시킵니다.write-guard.sh는.env파일, 개인 키(private keys), 그리고 자격 증명 덤프(credential dumps)를 생성하거나 편집하는 것을 거부합니다. 대신.env.example이나CredentialForm.tsx와 같이 예상할 수 있는 소스 파일들은 허용합니다.config-protection.sh는 설정을 약화시키는 편집을 차단합니다. 에이전트는strict: false로 변경하거나,@ts-nocheck를 삽입하거나, 에러를 없애기 위해 린터(linter)의 권장 규칙을 끌 수 없습니다.
경고는 이보다 가볍습니다. design-nudge.sh는 편집 내용이 전형적인 AI 스타일(과도하고 임의적인 그림자, 의무적인 인디고 그라데이션 등)을 지향할 때 저에게 알림을 보냅니다. quality-gate.sh는 세션이 종료될 때 변경된 파일에 대해 린터(linter)와 타입 체크(type check)를 실행하고 발견된 내용을 출력합니다.
탈출구(escape hatch)도 존재합니다. 반드시 있어야 하기 때문입니다. FE_RAIL_HOOK_PROFILE=minimal을 사용하여 전체 기능을 낮추거나, FE_RAIL_DISABLED_HOOKS를 통해 개별 훅을 이름별로 끌 수 있습니다. 하지만 minimal 설정은 안전 차단(safety blockers) 기능에는 영향을 주지 않습니다. 이를 제거하고 싶다면 하나씩 이름을 지정해야 합니다. 품질은 협상 가능하지만, .env 파일을 덮어쓰는 것은 협상 대상이 아닙니다.
의도적인 다중 에이전트 (Multiple agents, on purpose)
모든 것을 하나의 긴 세션에 몰아넣는 대신, 각 단계는 자체적인 컨텍스트를 가진 작은 서브 에이전트(sub-agent)에게 작업을 넘깁니다. 요구사항 분석(Requirements analysis)은 fe-analyst에게 전달됩니다. 아키텍처 질문은 fe-architect에게 전달됩니다. 리뷰 단계는 fe-reviewer로 분산되며, 여기에 전용 fe-a11y-auditor와 fe-perf-auditor가 추가됩니다. 소란스러운 작업들은 옆에서 별도로 처리되기 때문에 메인 스레드(main thread)의 가독성이 유지됩니다.
내가 배운 것
그러한 에일리어싱(aliasing) 결정은 이 프로젝트에서 가장 유용한 부분인 회귀 테스트 하네스(regression harness)를 만들게 하는 계기가 되었습니다. eval/run.sh는 실제 모델을 호출하지 않고도 훅(hooks), 프로파일 토글(profile toggles), 그리고 플러그인 자체 설정을 확인하므로, 모델 업데이트나 설정 변경으로 인해 가드레일(guard)이 조용히 깨지는 시점을 파악할 수 있습니다. 실패 시에는 0이 아닌 종료 코드를 반환하므로, CI(지속적 통합) 단계에서 이를 게이트(gate)로 사용할 수 있습니다.
디자인 가드(design guard) 또한 저에게 무언가를 가르쳐 주었습니다. design-nudge는 프로젝트에 DESIGN.md를 추가하기 전까지 처음에는 끊임없이 저를 괴롭혔습니다. 그것이 바로 실제 디자인입니다. 프로젝트가 스스로의 규칙을 명시하면, 일반적인 넛징(nudging)은 조용해지고 리뷰어는 저의 기본값 대신 여러분의 규칙을 강제하게 됩니다.
한계점에 대해서는 솔직하게 말씀드리겠습니다. 이 도구는 주관적입니다. Strict 모드의 TypeScript, Next.js App Router 또는 Vite SPA, Tailwind, shadcn/ui를 사용합니다. 이 스택을 벗어나면 대부분의 가치가 사라집니다. 아직 초기 단계이며(이 글을 쓰는 시점 기준 v1.10), 설계상 프론트엔드 전용입니다. 이것은 사실 저 자신의 프론트엔드 프로세스를 문서화하고 건너뛰기 어렵게 만든 것에 불과합니다.
사용해 보기
만약 Claude Code를 사용 중이고 대략 위와 같은 스택을 사용하고 있다면:
/plugin marketplace add sh5623/fe-rail
/plugin install fe-rail@fe-rail-market
설치 직후에 수행할 가치가 있는 두 가지 작업이 있습니다. 에이전트들이 여러분의 스택에 대해 정보 없이 추론하지 않도록 프로젝트에 CLAUDE.md를 제공하십시오 (/init 실행). 그리고 설정에서 Bash(git *)와 Bash(gh pr *)를 허용하여 PR(Pull Request) 생성 시 매 단계마다 프롬프트가 뜨지 않도록 하십시오.
MIT 라이선스 하에 오픈 소스로 공개되어 있습니다:
sh5623 / fe-rail
Claude Code 플러그인 — Next.js, Vite SPA 및 TypeScript(Tailwind, shadcn/ui)를 위한 spec → build → review → PR 하네스
fe-rail
프론트엔드 중심의 Claude Code 플러그인. Next.js App Router / Vite SPA (TanStack Router · React Router 7) + TypeScript를 위한 자동화된 spec → build → review → PR 워크플로우를 제공하며, Tailwind v3/v4 및 shadcn/ui를 완벽하게 지원합니다.
설치 (Installation)
claude
/plugin marketplace add sh5623/fe-rail
/plugin install fe-rail@fe-rail-market
사용법 (Usage)
$ claude
> /fe-rail:fe-spec
...
두 개...
여러분의 환경에서 어떤 부분이 제대로 작동하지 않는지 알고 싶습니다. 여러분의 AI 코딩 설정 중에서, AI가 가장 먼저 여러분에게 물어봐 주었으면 하는 한 가지는 무엇인가요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기