TuBrief
구독 채널
비디오
커뮤니티

AI 에이전트가 짜는 뻔한 보일러플레이트를 잘라내는 작업 환경 설정

TuBrief 편집팀
2026년 7월 24일
0
컴퓨터/소프트웨어

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

한국어EnglishEspañol中文العربيةहिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia日本語

관련 영상

AI 에이전트의 사고 능력을 획기적으로 높여줄 새로운 기술13:24

AI 에이전트의 사고 능력을 획기적으로 높여줄 새로운 기술

AI LABS

커뮤니티의 다른 글

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

2026년 9월 13일

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

2026년 9월 13일

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

2026년 9월 13일

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

2026년 9월 13일

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

AI 에이전트가 짜는 뻔한 보일러플레이트를 잘라내는 작업 환경 설정

AI 에이전트를 실제 개발 환경에 붙여보면 금방 밑천이 드러납니다. 도메인 맥락을 모른 채 기계적으로 팩토리 패턴을 남발하거나, 아무짝에도 쓸모없는 유틸리티 함수만 무한히 내뱉기 일쑤입니다. GitClear가 2024년 발표한 6억 2,300만 줄의 커밋 분석 보고서를 보면 AI 도구가 퍼진 뒤 코드 중복은 81% 늘었고, 기존 코드를 정리하는 리팩토링 비율은 25%에서 10% 미만으로 꺼졌습니다. 컨텍스트 윈도우의 최신성 편향 때문에 에이전트는 위험을 피하려고 학습 데이터에 가장 흔한 표준 패턴으로 계속 도망칩니다. 팀이 공유하는 아키텍처 규칙과 동기화 로직을 컨텍스트 파일로 명시해서 에이전트의 오작동을 눌러줘야 합니다.

1. 레거시 코드베이스의 규칙 이탈 차단하기

개발 도구마다 제각각인 지침을 통제하려면 프로젝트 루트에 단일 진실 공급원 역할을 하는 AGENTS.md부터 올려야 합니다. Cursor, Claude Code 같은 도구들이 이 규칙을 읽습니다. 단일 .cursorrules 파일은 이미 오래전에 폐기되었습니다. .cursor/rules/ 디렉터리에 MDC 파일로 쪼개어 넣고, Claude Code 환경에서는 CLAUDE.md 안에 @AGENTS.md를 불러와 규칙이 흘러내리는 현상을 막습니다.

---
description: Backend API and Domain Service architectural constraints
globs: apps/api/**/*.ts, services/**/*.ts
alwaysApply: false
---
# Backend Architectural Constraints

## Mandatory Patterns
- Use Canonical Response DTOs located in `apps/api/src/common/dto`.
- All database mutations must go through the Unit of Work pattern defined in `services/shared/uow`.

## Explicit Negative Constraints
- NEVER create single-child base classes or single-implementation interfaces.
- NEVER write wrapper functions that merely pass arguments to lower-level services.
- NEVER implement strategy or factory patterns when standard conditional logic (if/switch) suffices.
- NEVER add defensive "just-in-case" try-catch blocks that return dummy fallback values without rethrowing.

컨텍스트 전체 길이가 800줄, 대략 2,000토큰을 넘어서면 에이전트는 상단에 적어둔 제약 조건을 무시하기 시작합니다. AGENTS.md에는 정말 양보할 수 없는 금지 사항만 남기고, 상세한 아키텍처 결정 기록은 docs/context/ 디렉터리로 밀어내야 합니다.

제약 조건 적용 순서

  • 작업 내용: 핵심 모듈 1개를 골라 금지 패턴과 예외 규칙을 지정합니다.
  • 실행 방법:
  1. 프로젝트 루트에 AGENTS.md를 만들고 단일 구현 인터페이스 금지, 방어적 try-catch 금지 조건을 적습니다.
  2. .cursor/rules/backend-constraints.mdc 위치에 대상 파일 경로(globs)와 YAML Frontmatter 제약을 설정합니다.
  3. CLAUDE.md에 @AGENTS.md 구문을 추가해 환경을 맞춥니다.
  • 기대 결과: 불필요한 보일러플레이트 생성이 줄어들면서 코드 수정에 들던 시간이 주당 4시간가량 빠집니다.

2. 에이전트 코드 검증 파이프라인

그럴듯해 보이는 에이전트의 코드 뒤에는 함정이 숨어 있습니다. Veracode의 2024년 연구 결과에 따르면 AI가 제안한 코드의 45%에서 OWASP Top 10 수준의 보안 취약점이 발견되었습니다. 실패할 것 같은 로직을 try-catch로 대충 감싼 뒤 빈 객체나 null을 던져 에러를 숨기는 짓을 사람이 작성할 때보다 47%나 더 자주 저지릅니다. Read-Modify-Write 연산에서 낙관적 잠금을 빼먹거나 루프 안에서 DB를 계속 호출하는 N+1 문제도 수시로 터집니다.

검증 영역 세부 검증 항목 위험 패턴 및 에이전트 함정 머지 차단 기준
보안 취약점 Parameterized Query 사용 여부, 테넌트 격리, 비인가 패키지 확인 문자열 연결 기반 SQL 주입, 환각으로 만들어낸 검증 안 된 패키지 호출 입력값 검증 누락, 출처 불분명 외부 디펜던시 추가 시 차단
성능 병목 ORM 지연 로딩, Hot path 내 중첩 루프, DB 인덱스 루프 내 개별 엔티티 순회 쿼리, 메모리상 전체 테이블 필터링 루프 내 DB 및 외부 API 호출 존재 시 차단, 페이징 미적용 시 차단
타입 안정성 Strict Type 검증, Boundary 예외 처리, 동시성 제어 as any 남발, Empty Catch 블록으로 에러 은폐 any 및 무분별한 as 캐스팅 존재 시 차단, 로깅 없는 Catch 블록 차단

에이전트가 짜주는 테스트 코드는 구현 코드를 그대로 복붙해 따라 하는 동어반복 테스트에 그치기 쉽습니다. 이런 테스트는 실제 비즈니스 결함을 전혀 잡지 못합니다. "이미 존재하는 유틸리티가 있다면 에이전트가 새로 만든 유틸리티는 지우고 기존 코드를 재사용한다"는 규칙을 강하게 적용해야 합니다.

수동 검증 절차

  • 작업 내용: 보안, 성능, 타입을 검증하는 체크리스트를 작업 템플릿과 CI 게이트에 채워 넣습니다.
  • 실행 방법:
  1. PR 템플릿에 Parameterized Query, N+1 쿼리 방지, any 금지 항목을 집어넣습니다.
  2. Git Pre-commit Hook에 정적 분석 도구를 걸어 as any나 루프 안의 await를 잡으면 커밋을 튕겨냅니다.
  3. 리뷰 시 에이전트가 멋대로 새로 만든 유틸리티를 기존 공통 모듈로 강제 교체합니다.
  • 기대 결과: N+1 쿼리나 메모리 누수 같은 결함이 프로덕션으로 넘어가는 사고를 막습니다.

3. 사고 정체를 막는 분할 프롬프팅

복잡한 정산 로직이나 상태 머신 기반 주문 처리를 단일 프롬프트로 밀어 넣으면 에이전트는 도구 호출 루프에 갇히거나 껍데기뿐인 코드만 뱉어냅니다. 스키마 설계, API 인터페이스, 예외 처리, 비즈니스 규칙을 한 번에 처리하려다 토큰 할당 순서가 꼬이기 때문입니다.

[1단계: 데이터 모델링] -> DB 엔티티, Zod 스키마 생성
          │
          ▼ (출력 결과를 컨텍스트로 전달)
[2단계: 인터페이스 정의] -> API DTO, Custom Error, 서비스 시그니처 정의
          │
          ▼ (1+2단계 출력 결과를 컨텍스트로 전달)
[3단계: 비즈니스 로직 구현] -> 트랜잭션, 상태 전이, 동시성 제어 완성

이 과정을 손으로 주고받는 건 꽤 번거롭습니다. CLI 자동화 스크립트(scripts/agent-decomposed-build.ts)를 짜서 앞 단계의 결과물이 다음 단계의 입력 컨텍스트로 들어가게 묶어두는 편이 낫습니다.

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.`);
}

분할 프롬프팅 스크립트 구축

  • 작업 내용: 3단계 프롬프트 템플릿을 정립하고 이를 순차 실행하는 CLI 스크립트를 올립니다.
  • 실행 방법:
  1. 데이터 모델링, 인터페이스 정의, 비즈니스 로직 구현으로 프롬프트를 3개로 쪼갭니다.
  2. scripts/agent-decomposed-build.ts를 작성해 이전 출력이 다음 프롬프트 컨텍스트에 들어가도록 잇습니다.
  3. 복잡한 모듈을 새로 만들 때 이 스크립트를 실행합니다.
  • 기대 결과: 에이전트가 답을 내지 못하고 멍때리는 현상이 사라지고, 손수 코드를 뒤엎는 재작업 비율이 20%대에서 5% 미만으로 떨어집니다.

4. 결정 근거를 코드 안에 남기는 설정

AI 코딩 도구를 쓸수록 왜 이렇게 짰는지 이유가 빠진 '쓰기 전용 코드'가 쌓입니다. 아키텍처 선택의 트레이드오프가 기록되지 않은 코드는 나중에 사람이 손대기 힘든 짐이 됩니다. 에이전트가 코드를 만들 때 TSDoc 표준 주석을 소스코드 안에 써두도록 AGENTS.md에 강제해야 합니다.

/**
 * @description Processes deferred settlement payouts for multi-vendor orders.
 * @why Uses pessimistic database locking on the Wallet entity instead of optimistic locking because payout calculation involves high-frequency concurrent balance updates.
 * @tradeoff Slight P95 latency increase under high contention in exchange for 0% financial drift.
 * @complexity Time: O(N log N) due to vendor sorting | Space: O(N) for batch processing buffer.
 */
export async function processDeferredSettlement(orderId: string): Promise<void> {
  if (account.hasOutstandingBalance()) {
    this.applySettlementHold(account);
  }
}

개발자마다 에이전트 설정이 어긋나는 일을 막으려면 AGENTS.md를 단일 진실 공급원으로 올려 두고, 커밋할 때 CLAUDE.md와 .cursor/rules/global.mdc로 동기화하는 스크립트(tools/sync-agent-rules.ts)를 돌려야 합니다.

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();