AI 에이전트가 짜는 뻔한 보일러플레이트를 잘라내는 작업 환경 설정
TuBrief Editorial
July 24, 2026
0
Computing/SoftwareWritten with AI assistance from the source video. The video is the authority.
More from the community
Comments (0)
Log in to leave a comment
No posts yet
Written with AI assistance from the source video. The video is the authority.
Log in to leave a comment
No posts yet
AI 에이전트를 실제 개발 환경에 적용해보면 금방 한계가 드러납니다. 도메인 맥락을 이해하지 못한 채 기계적으로 팩토리 패턴을 남발하거나, 전혀 유용하지 않은 유틸리티 함수만 무한히 생성해내기 일쑤입니다. GitClear가 2024년 발표한 6억 2,300만 줄의 커밋 분석 보고서에 따르면, AI 도구가 보편화된 이후 코드 중복은 81% 증가한 반면, 기존 코드를 정리하는 리팩토링 비율은 25%에서 10% 미만으로 감소했습니다. 컨텍스트 윈도우의 최신성 편향(Recency Bias)으로 인해 에이전트는 위험을 피하고자 학습 데이터에서 가장 흔히 발견되는 표준 패턴으로 계속 회피하려는 경향을 보입니다. 따라서 팀이 공유하는 아키텍처 규칙과 동기화 로직을 컨텍스트 파일로 명시하여 에이전트의 오작동을 제어해야 합니다.
개발 도구마다 제각각인 지침을 통일성 있게 관리하려면 프로젝트 루트에 단일 진실 공급원(Single Source of Truth) 역할을 하는 AGENTS.md 파일부터 작성해야 합니다. Cursor, Claude Code와 같은 도구들이 이 규칙을 참조합니다. 기존의 단일 .cursorrules 파일 방식은 이미 오래전에 폐기되었습니다. .cursor/rules/ 디렉터리에 MDC 파일로 분할하여 관리하고, Claude Code 환경에서는 CLAUDE.md 내에 @AGENTS.md를 불러와 규칙이 누락되는 현상을 방지합니다.
apps/api/src/common/dto.services/shared/uow.컨텍스트의 전체 길이가 800줄(약 2,000토큰)을 초과하면 에이전트는 상단에 명시된 제약 조건을 무시하기 시작합니다. 따라서 AGENTS.md에는 반드시 준수해야 하는 핵심 금지 사항만 남겨두고, 세부적인 아키텍처 결정 기록(ADR)은 docs/context/ 디렉터리로 이관해야 합니다.
AGENTS.md를 생성하고 단일 구현 인터페이스 금지, 방어적 try-catch 금지 등의 조건을 작성합니다..cursor/rules/backend-constraints.mdc 위치에 대상 파일 경로(globs)와 YAML Frontmatter 제약 사항을 설정합니다.CLAUDE.md에 @AGENTS.md 구문을 추가하여 환경을 동기화합니다.완벽해 보이는 에이전트의 코드 내부에는 다양한 문제점이 숨어 있을 수 있습니다. Veracode의 2024년 연구 결과에 따르면, AI가 제안한 코드의 45%에서 OWASP Top 10 수준의 보안 취약점이 발견되었습니다. 오류가 발생할 가능성이 있는 로직을 단순히 try-catch로 감싸고 빈 객체나 null을 반환하여 에러를 은폐하는 행위가 사람이 작성할 때보다 47% 더 자주 발생합니다. 또한, Read-Modify-Write 연산에서 낙관적 잠금(Optimistic Locking)을 누락하거나 루프 내에서 지속적으로 DB를 호출하는 N+1 문제도 빈번하게 발생합니다.
| 검증 영역 | 세부 검증 항목 | 위험 패턴 및 에이전트 함정 | 머지 차단 기준 |
|---|---|---|---|
| 보안 취약점 | Parameterized Query 사용 여부, 테넌트 격리, 비인가 패키지 확인 | 문자열 연결 기반 SQL 주입, 환각으로 생성된 검증되지 않은 패키지 호출 | 입력값 검증 누락, 출처가 불분명한 외부 디펜던시 추가 시 차단 |
| 성능 병목 | ORM 지연 로딩, Hot path 내 중첩 루프, DB 인덱스 | 루프 내 개별 엔티티 순회 쿼리, 메모리상 전체 테이블 필터링 | 루프 내 DB 및 외부 API 호출 존재 시 차단, 페이징 미적용 시 차단 |
| 타입 안정성 | Strict Type 검증, Boundary 예외 처리, 동시성 제어 | as any 남발, Empty Catch 블록으로 에러 은폐 |
any 및 무분별한 as 캐스팅 존재 시 차단, 로깅 없는 Catch 블록 차단 |
에이전트가 작성하는 테스트 코드는 구현 코드를 그대로 복제하여 따라 하는 단조로운 테스트에 그치기 쉽습니다. 이러한 테스트는 실제 비즈니스 로직의 결함을 감지하지 못합니다. 따라서 "이미 존재하는 유틸리티가 있다면 에이전트가 새로 생성한 유틸리티를 제거하고 기존 코드를 재사용한다"는 규칙을 엄격하게 적용해야 합니다.
any 금지 항목을 추가합니다.as any 또는 루프 내 await 감지 시 커밋을 차단합니다.복잡한 정산 로직이나 상태 머신 기반의 주문 처리 프로세스를 단일 프롬프트로 전달하면, 에이전트는 도구 호출 루프에 갇히거나 실질적인 내용이 없는 코드만 출력할 수 있습니다. 스키마 설계, API 인터페이스, 예외 처리, 비즈니스 규칙을 한 번에 처리하려 할 때 토큰 할당 순서가 꼬이기 때문입니다.
[1단계: 데이터 모델링] -> DB 엔티티, Zod 스키마 생성 │ ▼ (출력 결과를 컨텍스트로 전달) [2단계: 인터페이스 정의] -> API DTO, Custom Error, 서비스 시그니처 정의 │ ▼ (1+2단계 출력 결과를 컨텍스트로 전달) [3단계: 비즈니스 로직 구현] -> 트랜잭션, 상태 전이, 동시성 제어 완성
이 과정을 수동으로 진행하는 것은 번거로울 수 있습니다. CLI 자동화 스크립트(scripts/agent-decomposed-build.ts)를 작성하여 이전 단계의 출력 결과가 다음 단계의 입력 컨텍스트로 연동되도록 구성하는 것이 효율적입니다.
`typescript
import { execSync } from 'child_process';
import * as fs from 'fs';
interface TaskPipeline {
featureName: string;
stage1Prompt: string;
stage2Prompt: string;
stage3Prompt: string;
}
async function runDecomposedAgentPipeline(pipeline: TaskPipeline) {
console.log([Stage 1] Executing Data Modeling for ${pipeline.featureName}...);
const stage1Output = execSync(claude --print "${pipeline.stage1Prompt}").toString();
fs.writeFileSync(./tmp/${pipeline.featureName}_stage1.ts, stage1Output);
console.log([Stage 2] Executing Interface Definition...);
const stage2InputPrompt = ${pipeline.stage2Prompt}\n\nContext Models:\n${stage1Output};
const stage2Output = execSync(claude --print "${stage2InputPrompt}").toString();
fs.writeFileSync(./tmp/${pipeline.featureName}_stage2.ts, stage2Output);
console.log([Stage 3] Executing Business Logic Implementation...);
const stage3InputPrompt = ${pipeline.stage3Prompt}\n\nContext Models:\n${stage1Output}\n\nContext Contracts:\n${stage2Output};
const stage3Output = execSync(claude --print "${stage3InputPrompt}").toString();
fs.writeFileSync(./src/services/${pipeline.featureName}.service.ts, stage3Output);
console.log([Pipeline Complete] Business logic generated cleanly without cognitive stagnation.);
}
`
scripts/agent-decomposed-build.ts를 작성하여 이전 출력이 다음 프롬프트의 컨텍스트로 전달되도록 설정합니다.AI 코딩 도구를 활용할수록 구현 이유가 명시되지 않은 코드가 누적될 수 있습니다. 아키텍처 선택에 대한 트레이드오프가 기록되지 않은 코드는 향후 유지보수 시 부담으로 작용합니다. 에이전트가 코드를 생성할 때 TSDoc 표준 주석을 소스코드 내에 작성하도록 AGENTS.md에 강제해야 합니다.
`typescript
/**
개발자 간 에이전트 설정이 불일치하는 문제를 방지하기 위해 AGENTS.md를 단일 진실 공급원으로 관리하고, 커밋 시 CLAUDE.md 및 .cursor/rules/global.mdc와 동기화하는 스크립트(tools/sync-agent-rules.ts)를 실행합니다.
`typescript
import * as fs from 'fs';
import * as path from 'path';
const AGENTS_MD_PATH = path.join(__dirname, '../AGENTS.md');
const CLAUDE_MD_PATH = path.join(__dirname, '../CLAUDE.md');
const CURSOR_RULE_PATH = path.join(__dirname, '../.cursor/rules/global.mdc');
function syncRules() {
if (!fs.existsSync(AGENTS_MD_PATH)) {
console.error('Error: AGENTS.md does not exist.');
process.exit(1);
}
const baseRules = fs.readFileSync(AGENTS_MD_PATH, 'utf-8');
const claudeContent = # AUTOMATICALLY GENERATED FROM AGENTS.md - DO NOT EDIT DIRECTLY\n\n${baseRules};
fs.writeFileSync(CLAUDE_MD_PATH, claudeContent);
const mdcHeader = ---\ndescription: Global Agent Rule Sync\nglobs: **/*\nalwaysApply: true\n---\n\n;
fs.writeFileSync(CURSOR_RULE_PATH, ${mdcHeader}${baseRules});
console.log('Successfully synchronized AGENTS.md to CLAUDE.md and Cursor MDC rules.');
}
syncRules();
`