Skip to content
Published on

Vibe Coding과 2026 AI 개발 도구 생태계: 생산성 혁명의 빛과 그림자

Authors
  • Name
    Twitter

왜 지금 이 주제가 중요한가

2026년 3월, DeveloperWeek 2026에서 가장 뜨거웠던 화두는 "AI 도구가 정말로 좋은가(Are AI tools actually good?)"였다. Andrej Karpathy가 2025년 2월 트위터에서 "Vibe Coding"이라는 용어를 처음 사용한 지 정확히 1년, 이 개념은 Collins 영어사전의 2025년 올해의 단어로 선정될 만큼 개발 문화 전반에 스며들었다. 그런데 GeekNews와 Hacker News에서는 최근 Amazon의 AI 코드 관련 대규모 장애 사례가 폭발적인 관심을 받으면서, "Vibe Coding의 현실은 무엇인가"라는 근본적 질문이 다시 수면 위로 올라왔다.

이 글에서는 Vibe Coding의 1년간의 진화, 2026년 AI 코딩 도구 생태계의 현황, 실제 생산성 데이터와 실패 사례, 그리고 엔지니어로서 취해야 할 전략을 균형 있게 분석한다.

Vibe Coding에서 Agentic Engineering으로: 개념의 진화

Karpathy의 원래 정의

2025년 2월, Karpathy는 트위터에서 다음과 같이 말했다.

"There's a new kind of coding I call 'vibe coding', where you fully give in to the vibes, embrace exponentials, and forget that the code even exists."

핵심은 코드를 직접 작성하지 않고, AI에게 의도를 전달하고 결과를 수용하는 것이었다. Cursor Composer와 Claude Sonnet을 사용하면서, 음성으로 지시하고(SuperWhisper), 코드를 거의 읽지 않고, "대충 맞는 것 같으면" 수용하는 방식이었다.

1년 후의 현실: Agentic Engineering

2026년 3월, Karpathy는 자신의 트윗 1주년을 회고하며 입장을 수정했다.

"오늘날 LLM 에이전트를 통한 프로그래밍이 전문가들의 기본 워크플로우가 되고 있지만, 더 많은 감독과 검증이 수반된다. 에이전트의 레버리지를 활용하되 소프트웨어 품질에는 타협하지 않는 것이 목표다."

그가 제안한 새 용어는 Agentic Engineering이다. "Agentic"은 99%의 시간 동안 코드를 직접 작성하지 않고 에이전트를 오케스트레이션한다는 의미이고, "Engineering"은 거기에 여전히 기술과 과학과 전문성이 필요하다는 점을 강조한다.

이 변화는 단순한 용어 교체가 아니다. Vibe Coding이 "코드를 잊어버려도 된다"는 자유로움을 강조했다면, Agentic Engineering은 AI가 생성한 코드에 대한 인간의 책임과 감독을 전면에 내세운다.

2026 AI 코딩 도구 생태계 비교

주요 도구 비교표

2026년 3월 기준, 주요 AI 코딩 도구를 비교하면 다음과 같다.

도구유형월 가격핵심 강점컨텍스트 윈도우에이전틱 기능최적 사용 시나리오
CursorAI 네이티브 IDE$20 (Pro)대규모 코드베이스, 멀티파일 편집, UX전체 프로젝트 인덱싱Composer Agent일상적 코딩 플로우
GitHub CopilotIDE 확장$10 (Pro)생태계 통합, 가장 넓은 보급률파일 단위Copilot WorkspaceGitHub 기반 팀 협업
Claude CodeCLI 에이전트17(Pro)/17 (Pro) / 100+ (Max)200K 토큰 컨텍스트, 자율적 멀티파일 편집200K 토큰완전 에이전틱아키텍처 리팩토링, 복잡한 작업
WindsurfAI 네이티브 IDE$15 (Pro)Cascade 에이전트, 앱 프리뷰/배포전체 레포 컨텍스트Cascade멀티스텝 코딩, 풀스택
OpenAI Codex샌드박스 에이전트ChatGPT 구독 포함병렬 에이전트, 격리된 샌드박스 실행태스크 단위완전 에이전틱스펙 기반 태스크 실행

도구별 핵심 특성

2026년 AI 코딩 서베이 데이터에 따르면, 숙련된 개발자는 평균 2.3개의 도구를 동시에 사용한다. 각 도구가 상호 배타적이지 않으며, 용도별 최적 영역이 다르기 때문이다.

  • Copilot: 일상적 코딩 속도를 높인다 (자동 완성, 반복 코드)
  • Cursor: 대규모 프로젝트를 관리 가능하게 만든다 (프로젝트 컨텍스트, 멀티파일)
  • Claude Code: 복잡한 문제를 이해 가능하게 만든다 (긴 컨텍스트, 추론 능력)

특히 Claude Code는 2025년 5월 출시 후 8개월 만에 개발자 선호도 1위(46% "most loved")를 기록했으며, Cursor(19%), GitHub Copilot(9%)을 크게 앞서는 결과를 보였다.

생산성 혁명: 데이터가 말하는 것

긍정적 지표

GitHub의 공식 통계에 따르면, AI 코딩 도구의 생산성 효과는 여러 지표에서 확인된다.

  • 코딩 속도: JavaScript HTTP 서버 구현 태스크에서 Copilot 사용 시 55% 더 빠르게 완료
  • Pull Request 주기: PR 평균 처리 시간이 9.6일에서 2.4일로 75% 단축
  • PR 생산량: PR 수가 8.69% 증가, PR 머지율이 15% 향상
  • 빌드 성공률: 성공적 빌드가 84% 증가
  • 개발자 만족도: 88%가 태스크를 더 빨리 완료한다고 응답, 96%가 반복적 코딩 작업이 빨라졌다고 응답

Stack Overflow 2025 Developer Survey의 시사점

Stack Overflow의 2025 개발자 설문조사 결과는 흥미로운 이중성을 보여준다.

  • 개발자들은 AI 도구를 기꺼이 사용하지만 동시에 꺼린다(willing but reluctant)
  • 66%의 개발자가 AI 도구의 가장 큰 문제로 "완전히 정확하지 않은 결과"를 지목
  • AI의 제안이 "겉보기에는 맞아 보이지만 테스트에서 실패"하는 패턴이 반복
  • 29-46%만이 AI 결과를 신뢰한다고 응답

DeveloperWeek 2026의 합의

2026년 3월 5일 Stack Overflow 블로그에 게시된 DeveloperWeek 2026 리포트는 다음과 같이 정리했다.

"AI 도구는 꽤 좋지만 충분히 좋지는 않다(pretty good but not good enough). 진정으로 유용하려면 더 많은 컨텍스트가 필요하고, 진정한 자동화를 위해서는 더 복잡한 아키텍처가 필요하다."

핵심 인사이트 3가지:

  1. AI 도구의 결과는 프롬프트 품질에 비례하며, 그마저도 인간의 미묘한 판단("taste")에는 미치지 못한다
  2. 주니어 개발자는 AI 코드 생성기보다 더 가치 있음을 증명해야 하는 압박에 직면
  3. 기술 산업이 AI의 잠재력을 실현하기까지는 아직 갈 길이 멀다

실패 사례: Amazon AI 코드 장애의 교훈

사건 개요

2026년 3월, Amazon에서 AI 생성 코드와 관련된 연쇄 장애가 발생하여 업계에 충격을 주었다.

타임라인:

  • 2025년 12월: Kiro(Amazon의 AI 코딩 도구)가 자율적으로 AWS Cost Explorer 환경을 삭제 후 재생성하면서 중국 리전에서 13시간 장애 발생
  • 2026년 3월 2일: AI 코딩 도구가 기여한 변경으로 12만 건의 주문 손실, 160만 건의 웹사이트 오류 발생
  • 2026년 3월 5일: 별도의 장애로 북미 마켓플레이스 전체에서 주문이 99% 감소, 630만 건의 주문 손실

Amazon의 대응

Amazon은 긴급 "deep dive" 회의를 소집하여 다음을 발표했다.

"최근 몇 달간 'high blast radius'를 가진 인시던트 트렌드가 있으며, 이는 Gen-AI 보조 변경(Gen-AI assisted changes)과 관련된다."

주요 조치:

  • 주니어 및 미드레벨 엔지니어의 AI 보조 코드 변경에 시니어 엔지니어의 승인 의무화
  • GenAI 도구 사용에 대한 베스트 프랙티스와 안전장치 수립 착수
  • 배포 파이프라인의 속도 제어 메커니즘 강화

근본 원인 분석

핵심 교훈은 AI 도구가 나쁜 코드를 생성하는 것이 문제가 아니라, 배포 파이프라인이 AI 도구가 생산하는 변경의 속도와 볼륨에 맞게 설계되지 않았다는 점이다. GenAI 도구가 "프로덕션 변경의 속도를 높이기 위해 보조적으로 사용되면서 안전하지 않은 관행(unsafe practices)을 초래"하고 있었다.

디버깅 세금(Debugging Tax)의 현실

업계 전반의 통계도 이를 뒷받침한다.

  • 45.2%의 개발자: AI 생성 코드의 디버깅이 사람이 작성한 코드보다 더 오래 걸린다고 응답
  • 67%의 개발자: 속도 중심의 코드 생성으로 디버깅 노력이 증가했다고 응답
  • 66%의 개발자: AI 생성 코드를 수정하는 데 예상보다 더 많은 시간을 소비
  • 75%의 기술 의사결정자: 2026년까지 AI 속도 기반 관행으로 인한 중등도에서 심각한 수준의 기술 부채를 경험할 것으로 전망

Stack Overflow 블로그 역시 "AI는 개발자를 10배 빠르게 만들 수 있다... 기술 부채를 만드는 데에서(AI can 10x developers...in creating tech debt)"라는 도발적인 제목의 글을 게시했다.

AI 코딩 도구 활용을 위한 실전 가이드

1. .cursorrules 프로젝트 설정 예시

AI 코딩 도구의 품질은 프로젝트 컨텍스트 설정에 크게 좌우된다. Cursor의 .cursor/rules 디렉터리에 프로젝트 규칙을 정의하면 AI의 코드 생성 품질이 크게 향상된다.

# core.md - 프로젝트 전체 규칙

## 코딩 스타일

- TypeScript strict 모드 사용
- 함수형 컴포넌트만 사용 (클래스 컴포넌트 금지)
- 에러 핸들링: guard clause 패턴 (early return) 사용
- 변수명: camelCase, 컴포넌트명: PascalCase

## 아키텍처 규칙

- API 라우트: /api/v1/ 접두사 사용
- 비즈니스 로직은 반드시 service 레이어에 위치
- 컴포넌트는 presentation과 container로 분리
- 상태 관리: zustand 사용 (Redux 금지)

## 테스트 규칙

- 모든 새 함수에 단위 테스트 필수
- 테스트 파일 위치: **tests**/ 디렉터리
- 최소 커버리지: 80%

## 금지 패턴

- any 타입 사용 금지
- console.log 프로덕션 코드에서 금지
- 인라인 스타일 금지 (Tailwind CSS만 사용)

2. CLAUDE.md 프로젝트 컨텍스트 파일

Claude Code는 프로젝트 루트의 CLAUDE.md 파일을 자동으로 인식하여 프로젝트 컨텍스트로 활용한다.

# Project: E-commerce API

## Tech Stack

- Runtime: Node.js 22 + TypeScript 5.7
- Framework: Fastify 5.x
- Database: PostgreSQL 16 + Drizzle ORM
- Cache: Redis 7 (Valkey)
- Testing: Vitest + Supertest

## Architecture

- Clean Architecture: domain -> application -> infrastructure
- CQRS pattern for read/write separation
- Event sourcing for order lifecycle

## Conventions

- All API responses follow RFC 7807 Problem Details format
- Database migrations in /migrations with timestamp prefix
- Environment variables in .env.example (never commit .env)
- Error codes: E1xxx (auth), E2xxx (order), E3xxx (payment)

## Common Commands

- npm run dev: Start development server
- npm run test: Run all tests
- npm run db:migrate: Run database migrations
- npm run lint: ESLint + Prettier check

3. AI 코드 리뷰 파이프라인 (GitHub Actions)

AI가 생성한 코드를 자동으로 검증하는 CI/CD 파이프라인을 구축할 수 있다.

# .github/workflows/ai-code-review.yml
name: AI Code Quality Gate

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  ai-code-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Detect AI-generated changes
        id: ai-detect
        run: |
          # PR의 커밋 메시지에서 AI 도구 시그니처 탐지
          AI_COMMITS=$(git log --oneline origin/main..HEAD \
            --grep="Co-Authored-By" \
            --grep="Generated by" \
            --grep="Copilot" \
            --grep="Cursor" \
            --grep="Claude" | wc -l)
          echo "ai_commit_count=$AI_COMMITS" >> "$GITHUB_OUTPUT"

      - name: Run enhanced linting for AI code
        if: steps.ai-detect.outputs.ai_commit_count > 0
        run: |
          npm run lint:strict
          npm run type-check
          npm run test:coverage -- --min-coverage=80

      - name: Security scan (AI code tends to skip validation)
        if: steps.ai-detect.outputs.ai_commit_count > 0
        uses: github/codeql-action/analyze@v3
        with:
          queries: security-and-quality

      - name: Complexity check
        run: |
          npx complexity-report --max-cyclomatic 10 \
            --format json src/ > complexity.json

      - name: Comment review summary
        if: steps.ai-detect.outputs.ai_commit_count > 0
        uses: actions/github-script@v7
        with:
          script: |
            const message = [
              '## AI Code Review Gate',
              '',
              'This PR contains AI-assisted commits.',
              'Enhanced review checks have been applied:',
              '- Strict linting passed',
              '- Type checking passed',
              '- Test coverage >= 80%',
              '- Security scan completed',
              '- Complexity threshold verified',
            ].join('\n');
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: message
            });

4. 효과적인 프롬프트 엔지니어링 예시

AI 코딩 도구의 결과 품질은 프롬프트의 구체성에 비례한다. 다음은 동일한 태스크에 대한 비효과적 프롬프트와 효과적 프롬프트의 비교다.

# 비효과적 프롬프트 (Vague)
"사용자 인증 기능 만들어줘"

# 효과적 프롬프트 (Specific + Constrained)
"다음 요구사항으로 JWT 인증 미들웨어를 구현해줘:
- Framework: Fastify 5.x + @fastify/jwt
- Access Token: 15분 만료, RS256 알고리즘
- Refresh Token: 7일 만료, httpOnly 쿠키 저장
- 에러 응답: RFC 7807 Problem Details 형식
- guard clause 패턴으로 에러를 먼저 처리
- 단위 테스트 포함 (Vitest)
- 기존 UserService.findById()를 사용하여 사용자 조회
- 타입: src/types/auth.ts의 AuthPayload 인터페이스 사용"

프롬프트에 포함해야 할 핵심 요소:

[구조화된 프롬프트 템플릿]

1. 컨텍스트: 이 코드가 위치할 아키텍처와 기존 코드 참조
2. 제약조건: 사용할 라이브러리, 패턴, 금지 패턴
3. 인터페이스: 입출력 타입, 에러 형식
4. 엣지케이스: 반드시 처리해야 할 예외 상황
5. 테스트: 기대하는 테스트 범위와 프레임워크
6. 참조: 기존 코드에서 유사한 구현 파일 경로

5. CI/CD에서 AI 생성 코드 검증 스크립트

AI 생성 코드에서 자주 발생하는 문제를 자동으로 탐지하는 스크립트다.

#!/usr/bin/env python3
"""AI 생성 코드 품질 검증 스크립트"""

import ast
import sys
import json
from pathlib import Path
from dataclasses import dataclass, field


@dataclass
class AICodeIssue:
    file: str
    line: int
    category: str
    message: str
    severity: str  # "error" | "warning" | "info"


@dataclass
class ValidationResult:
    issues: list[AICodeIssue] = field(default_factory=list)
    passed: bool = True


def check_hardcoded_secrets(file_path: Path, content: str) -> list[AICodeIssue]:
    """AI가 자주 생성하는 하드코딩된 시크릿 탐지"""
    issues = []
    suspicious_patterns = [
        ("password", "하드코딩된 비밀번호 감지"),
        ("api_key", "하드코딩된 API 키 감지"),
        ("secret", "하드코딩된 시크릿 감지"),
        ("token", "하드코딩된 토큰 감지"),
    ]
    for i, line in enumerate(content.split("\n"), 1):
        for pattern, message in suspicious_patterns:
            if f'{pattern} = "' in line.lower() or f"{pattern} = '" in line.lower():
                issues.append(AICodeIssue(
                    file=str(file_path),
                    line=i,
                    category="security",
                    message=message,
                    severity="error"
                ))
    return issues


def check_missing_error_handling(file_path: Path, content: str) -> list[AICodeIssue]:
    """AI가 자주 누락하는 에러 핸들링 검사"""
    issues = []
    tree = ast.parse(content)
    for node in ast.walk(tree):
        if isinstance(node, ast.Try):
            for handler in node.handlers:
                if handler.type is None:
                    issues.append(AICodeIssue(
                        file=str(file_path),
                        line=handler.lineno,
                        category="error-handling",
                        message="bare except 사용 - 구체적 예외 타입을 명시하세요",
                        severity="warning"
                    ))
    return issues


def check_todo_comments(file_path: Path, content: str) -> list[AICodeIssue]:
    """AI가 남긴 TODO/FIXME 미완성 표시 탐지"""
    issues = []
    for i, line in enumerate(content.split("\n"), 1):
        if "TODO" in line or "FIXME" in line or "HACK" in line:
            issues.append(AICodeIssue(
                file=str(file_path),
                line=i,
                category="completeness",
                message="미완성 코드 표시가 남아있습니다",
                severity="warning"
            ))
    return issues


def validate_files(paths: list[str]) -> ValidationResult:
    result = ValidationResult()
    for path_str in paths:
        path = Path(path_str)
        if not path.suffix == ".py":
            continue
        content = path.read_text()
        result.issues.extend(check_hardcoded_secrets(path, content))
        result.issues.extend(check_missing_error_handling(path, content))
        result.issues.extend(check_todo_comments(path, content))

    error_count = sum(1 for i in result.issues if i.severity == "error")
    result.passed = error_count == 0
    return result


if __name__ == "__main__":
    files = sys.argv[1:]
    result = validate_files(files)
    report = {
        "passed": result.passed,
        "total_issues": len(result.issues),
        "issues": [
            {
                "file": i.file,
                "line": i.line,
                "category": i.category,
                "message": i.message,
                "severity": i.severity,
            }
            for i in result.issues
        ],
    }
    print(json.dumps(report, indent=2, ensure_ascii=False))
    sys.exit(0 if result.passed else 1)

빛과 그림자: 균형 잡힌 시각

빛 - AI 코딩 도구가 실제로 잘하는 것

  1. 보일러플레이트 제거: CRUD API, 타입 정의, 설정 파일 등 반복적 코드를 수 분 안에 생성
  2. 학습 도구: 새로운 프레임워크나 언어를 탐색할 때 예제 코드와 설명을 즉시 제공
  3. 코드 이해: 레거시 코드베이스를 분석하고 설명하는 능력이 뛰어남
  4. 테스트 생성: 기존 코드에 대한 테스트 케이스를 빠르게 생성
  5. 문서화: 코드에 대한 문서와 주석을 자동 생성

GitHub 통계에 따르면, 개발자는 AI 생성 코드의 88%를 최종 제출에 유지한다. 이는 AI 제안의 유용성을 반영한다.

그림자 - 아직 해결되지 않은 문제들

  1. "거의 맞지만 완전히 틀린" 코드: AI가 생성한 코드가 구문적으로 올바르지만 논리적으로 미묘한 오류를 포함하는 경우가 빈번
  2. 기술 부채 가속화: AI 가속 코드베이스에서 중복 코드 블록과 단기 변경(churn)이 급증
  3. 시니어-주니어 격차 심화: AI 도구의 이점을 최대화하려면 이미 깊은 도메인 지식이 필요
  4. 보안 취약점: AI가 입력 검증이나 인증 로직을 누락하는 패턴이 반복적으로 관찰
  5. 과의존성(Over-reliance): 코드를 읽지 않고 수용하는 습관이 장기적으로 기술 역량을 저하

AI 도구 도입 전 체크리스트

팀에 AI 코딩 도구를 도입하기 전에 다음 항목을 확인해야 한다.

기술 인프라

  • CI/CD 파이프라인에 정적 분석, 타입 체크, 보안 스캔이 포함되어 있는가
  • 테스트 커버리지가 충분한 수준(최소 70%)으로 유지되고 있는가
  • 코드 리뷰 프로세스가 확립되어 있는가 (AI 코드도 동일 기준 적용)
  • 프로젝트 규칙 파일(.cursorrules, CLAUDE.md 등)이 작성되어 있는가

팀 역량

  • 팀원들이 AI 생성 코드를 비판적으로 검토할 수 있는 역량을 보유하고 있는가
  • AI 도구 사용에 대한 팀 가이드라인이 수립되어 있는가
  • 주니어 개발자에 대한 멘토링 체계가 AI 의존성을 고려하여 설계되어 있는가
  • AI 생성 코드의 Attribution과 책임 소재가 명확한가

보안과 컴플라이언스

  • AI 도구에 코드가 전송될 때의 데이터 보안 정책이 수립되어 있는가
  • 라이선스 호환성 검토 체계가 마련되어 있는가 (AI 학습 데이터의 라이선스 이슈)
  • 규제 산업(금융, 의료 등)의 경우 AI 생성 코드에 대한 감사 추적(audit trail)이 가능한가
  • 시크릿이나 내부 API 정보가 AI 도구로 유출되지 않도록 가드레일이 설정되어 있는가

프로세스

  • AI 생성 코드의 배포 전 추가 검증 단계가 정의되어 있는가
  • 성능 메트릭(생산성, 버그율, 기술 부채)의 before/after 측정 계획이 있는가
  • AI 도구 관련 인시던트 대응 프로세스가 정의되어 있는가 (Amazon 사례 교훈)
  • 도구 비용 대비 생산성 향상의 ROI 측정 방법이 정의되어 있는가

엔지니어를 위한 실전 전략

도구 조합 전략

경험 많은 개발자들의 도구 조합 패턴은 다음과 같다.

[일상 코딩]
  GitHub Copilot (자동 완성) + Cursor (멀티파일 편집)

[복잡한 리팩토링/설계]
  Claude Code (200K 컨텍스트로 전체 코드베이스 이해)

[새 프로젝트 부트스트래핑]
  OpenAI Codex (샌드박스에서 병렬 에이전트 실행)

[코드 리뷰]
  AI 코드 리뷰 + 인간 리뷰 병행 (AI는 패턴 탐지, 인간은 설계 판단)

"Agentic Engineering" 역량 개발

Karpathy의 진화된 관점에 맞추어, 엔지니어가 개발해야 할 핵심 역량은 다음과 같다.

  1. 프롬프트 설계 능력: 모호한 요구사항을 구체적이고 제약조건이 명확한 프롬프트로 변환
  2. 검증 설계 능력: AI 출력을 효율적으로 검증하는 테스트와 파이프라인 구축
  3. 아키텍처 판단: AI가 생성한 코드의 아키텍처적 적합성을 평가하는 시스템 설계 역량
  4. 도구 오케스트레이션: 상황에 맞는 최적의 도구 조합을 선택하고 전환하는 능력
  5. 메타인지: AI에 의존하고 있는 순간을 인식하고, 의도적으로 깊이 있는 이해를 추구하는 습관

결론: 도구는 바뀌어도 엔지니어링은 남는다

Vibe Coding에서 Agentic Engineering으로의 진화는 단순한 유행어의 교체가 아니다. 이는 "AI가 코드를 작성한다"는 흥분에서 "AI와 함께 좋은 소프트웨어를 만든다"는 성숙으로의 전환이다.

2026년의 데이터는 명확하다. AI 코딩 도구는 생산성을 확실히 높인다. 그러나 그것이 자동으로 소프트웨어의 품질을 높이지는 않는다. GitHub Copilot이 코딩 속도를 55% 높이는 동시에, 67%의 개발자가 디버깅 시간이 증가했다고 보고하는 이 역설이 현재 상황을 정확히 요약한다.

Amazon의 사례는 이 교훈의 극단적 형태다. 630만 건의 주문 손실은 AI 도구의 실패가 아니라, AI 도구의 속도에 맞추지 못한 프로세스의 실패였다.

결국 엔지니어에게 필요한 것은 AI 도구를 잘 사용하는 능력이 아니라, AI가 생성한 것이 좋은 소프트웨어인지 판단하는 능력이다. 도구는 매년 바뀌겠지만, 그 판단력은 경험과 학습을 통해서만 쌓인다.

참고 자료