AI가 코드를 자꾸 틀린다면? Prompt 기법 5가지로 효율 50% 높이기

금요일 오후 네 시 반, Cursor가 방금 생성한 코드를 보고 완전히 멍해졌습니다.
처음에는 그저 사용자 로그인 API 하나를 만들어 달라고 했을 뿐입니다. 그런데 Cursor는 300줄짜리 괴물을 만들어 냈습니다. 파라미터 타입은 전부 틀렸고, 데이터베이스 연결은 코드 안에 하드코딩되어 있었으며, 에러 처리 방식은 세 가지가 뒤섞여 있었습니다. 깊게 숨을 쉬고 전부 지운 뒤 다시 시도했습니다. 두 번째에는 건드리지 말라고 한 설정 파일까지 알아볼 수 없게 바꿔 놓았습니다.
그 순간 깨달았습니다. 문제는 AI가 아니라, 제가 애초에 “무엇을 해야 하고, 무엇을 하면 안 되는지” 말해 주지 않았다는 데 있었습니다.
AI 코딩 도구를 설치했고 의욕도 넘쳤지만, 한동안 써 보니 생성되는 코드는 요구와 전혀 다르거나, 겉으로는 맞아 보여도 실행하면 터지는 경우가 많았습니다. 몇 차례 고쳐 달라고 하다 보면 차라리 직접 쓰는 편이 더 빠를 때도 있었습니다.
동료는 같은 Cursor로 같은 기능을 10분 만에 끝냈는데, 저는 한 시간을 씨름했습니다. 차이는 어디에 있었을까요? 그의 Prompt는 구조가 명확했고, 컨텍스트가 충분했으며, 경계가 분명했습니다.
이 글에서는 바로 효과를 볼 수 있는 Cursor Prompt 기법 5가지를 단계별로 정리합니다. 대단한 이론이 아니라 실전에서 건져 올린 쉬운 공식입니다. 읽고 나면 AI가 요구사항을 제대로 이해하고 정확하며 쓸 수 있는 코드를 만들게 하는 방법을 알 수 있습니다.
왜 당신의 Prompt는 늘 “실패”할까
AI는 마음을 읽지 못하고, 당신이 준 정보만 “봅니다”
많은 사람이 AI는 똑똑하니 내가 원하는 것을 알아서 추측할 수 있다고 생각합니다. 틀렸습니다. 아무리 강력한 AI라도 결국은 “고급 텍스트 완성기”에 가깝습니다. 사용자가 제공한 정보를 바탕으로만 추론할 수 있습니다. 말하지 않은 것은 결국 “추측”할 수밖에 없습니다.
친구에게 전화해서 커피를 사 달라고 하면서 “커피 한 잔만 사 줘”라고만 말하는 상황을 떠올려 보세요. 친구가 매장에 도착하면 당황합니다. 아메리카노인지 라테인지, 큰 사이즈인지 중간 사이즈인지, 설탕을 넣을지 말지 알 수 없습니다. 결국 감으로 아무거나 살 수밖에 없습니다. AI도 같습니다.
특히 큰 프로젝트에서는 AI의 “기억 상실” 문제가 더 두드러집니다. 컨텍스트 창에는 한계가 있어서 전체 코드베이스를 모두 “머릿속”에 넣을 수 없습니다. 어떤 함수를 수정하라고 하면, 그 함수가 다른 20곳에서 호출된다는 사실을 전혀 모른 채 바꾸다가 전체가 깨질 수 있습니다.
흔한 Prompt 실패 세 가지
실패 1: 너무 모호함
❌ “정렬을 구현해줘”
이런 지시는 GPS에 “베이징에 가고 싶어”라고 입력하는 것과 같습니다. 베이징 어디로 갈까요? 어떤 교통수단을 쓸까요? 언제 도착해야 할까요? AI는 이런 지시를 받으면 마음대로 해석할 수밖에 없습니다. 버블 정렬을 짤 수도 있고, 프로젝트에 없는 서드파티 라이브러리를 호출할 수도 있습니다.
✅ “utils/array.ts 파일에 함수를 하나 추가해 사용자 목록을 가입 시간 내림차순으로 정렬하고, 기본 Array.sort() 메서드를 사용하며 새 의존성은 추가하지 마세요”
차이가 보이나요? 후자는 어느 파일에서, 어떤 데이터를, 어떤 방식으로, 어떤 제한 아래 처리해야 하는지 명확합니다.
실패 2: 컨텍스트 부족
❌ “에러 처리를 추가해줘”
AI: 어디에 추가해야 하나요? 어떤 에러를 처리해야 하나요? try-catch를 써야 하나요, 에러 코드를 써야 하나요? 어떤 형식으로 반환해야 하나요?
의사가 “어디가 불편하세요?”라고 물었는데, 환자가 “아파요”라고만 답하는 것과 같습니다. 의사가 제대로 진료할 수 있을까요? 어렵습니다.
✅ “api/login.ts의 handleLogin 함수에 에러 처리를 추가하세요:
- 네트워크 요청 실패를 잡습니다(try-catch 사용)
- 통일된 에러 형식
{ success: false, error: string }을 반환합니다 - 기존
api/register.ts의 에러 처리 방식을 참고합니다”
실패 3: 제약 조건 없음
❌ “이 컴포넌트 성능을 최적화해줘”
AI는 이 지시를 받으면 코드를 알아볼 수 없게 바꿀 수 있습니다. 새 라이브러리를 들여오고, 상태 관리를 바꾸고, 심지어 컴포넌트 아키텍처 전체를 다시 쓸 수도 있습니다. 당신이 원한 것은 React.memo 하나 추가하는 정도였는데, AI는 대수술을 해 버립니다.
✅ “UserList.tsx 컴포넌트 성능을 최적화하세요:
- React.memo 또는 useMemo만 사용할 수 있습니다
- 컴포넌트의 props 인터페이스를 수정하지 마세요
- 새 서드파티 라이브러리를 추가하지 마세요”
AI “환각”의 진짜 원인
AI가 생성한 코드에서 실제로 존재하지 않는 함수를 호출하거나, 프로젝트에 없는 변수를 참조한 적이 있나요? 이것이 AI의 “환각”입니다.
Cursor 공식 모범 사례 연구에 따르면, 명확한 컨텍스트 정보를 제공하면 환각 문제의 70%를 줄일 수 있습니다. 왜 그럴까요?
AI는 정보가 불완전하면 자동으로 “빈칸을 채웁니다”. 기존 코드가 어떻게 생겼는지 알려 주지 않으면, AI는 “흔한 패턴”을 기준으로 추정합니다. 예를 들어 로그인 기능을 작성하라고 하면, 프로젝트에 authService.login() 메서드가 있다고 가정할 수 있습니다. 하지만 실제 프로젝트에는 그런 것이 없을 수 있습니다.
해결책은 간단합니다. 관련된 기존 코드를 AI에게 명확히 보여 주세요.
저는 이제 Prompt를 쓸 때마다 먼저 세 가지 질문을 던집니다.
- AI가 내가 어느 파일에서 작업해야 하는지 아는가?
- AI가 기존 코드 구조를 아는가?
- AI가 무엇을 바꿀 수 있고 무엇을 바꾸면 안 되는지 아는가?
이 세 질문에 답할 수 없다면, Prompt를 보내기 전에 정보를 더 보충해야 합니다.
구조화 Prompt의 황금 공식
5W1H 프레임워크: AI가 요구사항을 바로 이해하게 만들기
기자가 기사를 쓸 때 쓰는 고전 공식이 있습니다. 5W1H, 즉 Who, What, When, Where, Why, How입니다. Prompt를 쓸 때도 이 방법을 그대로 사용할 수 있습니다.
- What(목표): AI가 무엇을 해야 하나요?
- Why(이유): 왜 그렇게 해야 하나요? AI가 의도를 이해하는 데 도움이 됩니다.
- Where(위치): 어느 파일/모듈에서 작업하나요?
- When(시점): 어떤 상황에서 트리거되나요?
- Who(대상): 작업 대상 데이터는 무엇인가요?
- How(방법): 어떤 기술 스택/라이브러리를 사용하나요?
복잡해 보이나요? 사실 매번 전부 쓸 필요는 없습니다. 핵심은 AI가 추측하지 않게 만드는 것입니다.
예를 들어 AI에게 데이터 검증 기능을 추가하게 하고 싶다고 해 보겠습니다.
❌ 모호한 버전:
사용자 입력 검증을 추가해줘
✅ 5W1H 버전:
**What**: 사용자 회원가입 폼에 입력 검증 추가
**Where**: src/components/RegisterForm.tsx
**Who**: 사용자명, 이메일, 비밀번호 세 필드 검증
**How**: 기존 Yup 라이브러리 사용(이미 설치됨)
**When**: 사용자가 제출 버튼을 클릭할 때 트리거
**Why**: 유효하지 않은 데이터가 백엔드로 제출되는 것을 방지
AI가 이 지시를 받으면 크게 벗어날 가능성이 낮습니다.
Cursor 공식 권장 구조화 템플릿
Cursor 팀은 더 실용적인 템플릿을 정리했습니다. 저도 몇 달 동안 써 봤고, 정말 효과가 좋았습니다.
## Goal(목표)
[무엇을 구현하려는지 한 문장으로 설명]
## Context(컨텍스트)
[현재 파일, 관련 코드, 기술 스택]
## Current Behavior(현재 동작)
[지금 상태가 어떤지]
## Desired Behavior(기대 동작)
[원하는 결과]
## Acceptance Criteria(완료 기준)
[어떤 조건이면 완료인지]
## Constraints(제약)
[수정하면 안 되는 것, 반드시 지켜야 하는 규칙]
이 템플릿의 가장 좋은 부분은 Constraints(제약) 입니다. 많은 사람이 Prompt를 쓸 때 “무엇을 해야 하는지”만 쓰고 “무엇을 하면 안 되는지”는 쓰지 않습니다. 그래서 AI가 지나치게 자유롭게 행동합니다.
실전 사례: React 로그인 기능
실제 상황으로 비교해 보겠습니다. React 프로젝트에 사용자 로그인 기능을 추가해야 한다고 가정합니다.
❌ 모호한 Prompt(초보자가 자주 씀):
사용자 로그인 기능을 구현해줘
AI는 이 말을 듣고 200줄짜리 컴포넌트를 만들고, 필요 없는 라이브러리를 잔뜩 가져오거나, 실제로 존재하지 않는 API 인터페이스를 “발명”할 수 있습니다.
✅ 구조화 Prompt(숙련된 방식):
## Goal
React 프로젝트에서 사용자 로그인 기능 구현
## Context
- 프로젝트는 React 18 + TypeScript 사용
- 상태 관리: Redux Toolkit
- 기존 API 서비스: src/services/authService.ts(login 메서드 포함)
- UI 라이브러리: Ant Design 5.x
## Current Behavior
로그인 페이지(src/pages/Login.tsx)는 정적 UI만 있고 상호작용 로직이 없음
## Desired Behavior
1. 사용자가 아이디와 비밀번호를 입력한 뒤 "로그인" 클릭
2. authService.login()을 호출해 인증
3. 성공: token을 Redux에 저장하고 /dashboard로 이동
4. 실패: 에러 안내 표시(Ant Design의 message.error 사용)
## Acceptance Criteria
- [ ] 폼 검증: 아이디와 비밀번호는 비어 있을 수 없음
- [ ] 로그인 중 loading 상태 표시
- [ ] 비밀번호 입력창은 type="password" 사용
- [ ] ESLint와 TypeScript 검사 통과
## Constraints
- authService.ts 파일을 **수정하지 마세요**
- 새 서드파티 라이브러리를 **추가하지 마세요**
- 기존 Redux slice(src/store/authSlice.ts)를 **반드시 사용하세요**
생성 결과를 비교해 보겠습니다.
첫 번째 Prompt에서 AI는 이런 코드를 줄 수 있습니다.
// ❌ AI가 마음대로 해석한 결과
import { useState } from 'react';
import axios from 'axios'; // 설치하라고 하지 않았는데 스스로 가져옴
function Login() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = async () => {
// 존재하지 않는 API를 직접 호출
const res = await axios.post('/api/auth/login', { username, password });
localStorage.setItem('token', res.data.token); // Redux를 쓰지 않음
};
// ... 나머지 150줄은 필요 없는 코드
}
두 번째 Prompt에서는 AI가 요구사항에 맞춰 다음처럼 생성합니다.
// ✅ 구조화 Prompt의 결과
import { useState } from 'react';
import { Form, Input, Button, message } from 'antd';
import { useDispatch } from 'react-redux';
import { login } from '@/services/authService';
import { setToken } from '@/store/authSlice';
import { useNavigate } from 'react-router-dom';
export default function Login() {
const [loading, setLoading] = useState(false);
const dispatch = useDispatch();
const navigate = useNavigate();
const handleSubmit = async (values: { username: string; password: string }) => {
setLoading(true);
try {
const { token } = await login(values.username, values.password);
dispatch(setToken(token));
navigate('/dashboard');
} catch (error) {
message.error('로그인 실패. 아이디와 비밀번호를 확인하세요');
} finally {
setLoading(false);
}
};
return (
<Form onFinish={handleSubmit}>
<Form.Item name="username" rules={[{ required: true, message: '아이디를 입력하세요' }]}>
<Input placeholder="아이디" />
</Form.Item>
<Form.Item name="password" rules={[{ required: true, message: '비밀번호를 입력하세요' }]}>
<Input.Password placeholder="비밀번호" />
</Form.Item>
<Button type="primary" htmlType="submit" loading={loading}>
로그인
</Button>
</Form>
);
}
차이가 보이나요? 두 번째 코드는 다음을 만족합니다.
- 지정한 Ant Design 컴포넌트를 사용했습니다
- 기존 authService를 호출했습니다
- Redux로 token을 저장했습니다
- 폼 검증과 loading 상태가 있습니다
- 새 의존성을 전혀 추가하지 않았습니다
이것이 구조화 Prompt의 힘입니다.
바로 효과가 나는 Prompt 기법 5가지
기법 1: 먼저 계획하고, 나중에 코딩하기(Plan Mode)
제가 써 보고 가장 놀랐던 기능입니다.
예전에는 AI에게 바로 코드를 쓰게 했고, 자주 문제가 생겼습니다. 건드리면 안 되는 파일을 바꾸고, 핵심 코드를 지우고, 로직을 엉망으로 만들었습니다. 나중에 Cursor에 Plan 모드가 있다는 것을 알게 되었고, Shift+Tab으로 전환하는 이 기능이 제 워크플로를 완전히 바꾸었습니다.
Plan 모드의 원리는 단순합니다. AI가 먼저 생각하고, 그다음 손을 댑니다.
구체적인 흐름은 다음과 같습니다.
- 사용자가 요구사항을 설명합니다
- AI가 코드베이스를 분석하고 질문합니다. 예를 들어 “기존 에러 처리를 유지하길 원하나요?”
- AI가 실행 계획을 세웁니다. 어떤 파일을 수정하고 어떤 기능을 추가할지 정리합니다
- 사용자가 이 계획을 검토하고 수정합니다
- 확인한 뒤에야 AI가 코드를 작성합니다
왜 유용할까요? 이 방식은 “되돌아볼 기회”를 줍니다.
예를 들어 지난주에 AI에게 프로젝트에 국제화 기능을 추가해 달라고 했습니다. Plan 모드에서 AI는 먼저 이런 계획을 제시했습니다.
계획:
1. i18next와 react-i18next 설치
2. src/i18n/locales/ 디렉터리 생성
3. App.tsx를 수정해 I18nProvider 추가
4. 모든 컴포넌트의 하드코딩 텍스트 업데이트(약 30개 파일)
4단계를 보자마자 바로 멈췄습니다. “잠깐, 그 30개 파일은 건드리지 말고 먼저 3개 페이지만 해 보자.” 계획을 수정한 뒤에야 AI가 실행했습니다.
Plan 모드가 없었다면 AI가 이미 30개 파일을 전부 바꿨을 것이고, 되돌리기는 꽤 번거로웠을 겁니다.
실전 가치: AI가 바로 코드를 건드려 망치는 상황을 피할 수 있으며, 특히 대규모 리팩터링과 새 기능 개발에 잘 맞습니다.
기법 2: 구체적인 코드 예시 제공하기
AI에는 한 가지 특징이 있습니다. “예시를 보고 따라 하는 것”을 잘합니다. 몇 가지 예시를 보여 주면 당신의 스타일을 모방할 수 있습니다. 기술적으로는 Few-shot Prompting이라고 부릅니다.
상황을 보겠습니다. AI에게 API 인터페이스를 작성하게 하고 싶지만, 당신에게는 고유한 코드 스타일과 에러 처리 습관이 있습니다.
❌ 예시가 없는 Prompt:
사용자 목록을 가져오는 API 인터페이스를 작성해줘
AI는 이렇게 쓸 수 있습니다.
app.get('/users', (req, res) => {
// 스타일이 전혀 맞지 않음
const users = db.getUsers();
res.json(users);
});
✅ 예시를 제공한 Prompt:
사용자 목록을 가져오는 API 인터페이스를 작성해 주세요. 아래 기존 인터페이스의 스타일을 참고하세요.
**예시 1**:
\`\`\`typescript
export const getProductById = async (req: Request, res: Response) => {
try {
const { id } = req.params;
const product = await productService.findById(id);
if (!product) {
return res.status(404).json({
success: false,
error: 'Product not found'
});
}
res.json({ success: true, data: product });
} catch (error) {
logger.error('Error fetching product:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
\`\`\`
이 스타일에 맞춰 getUserList 인터페이스를 구현하세요.
- async/await 사용
- 통일된 에러 처리
- 반환 형식: { success, data/error }
- logger로 에러 기록
AI는 이런 코드를 생성합니다.
export const getUserList = async (req: Request, res: Response) => {
try {
const users = await userService.findAll();
res.json({ success: true, data: users });
} catch (error) {
logger.error('Error fetching users:', error);
res.status(500).json({
success: false,
error: 'Internal server error'
});
}
};
코드 스타일이 정확히 맞습니다.
작은 팁: 프로젝트 루트에 prompts/templates.md 파일을 만들고 자주 쓰는 코드 예시를 저장하세요. 필요할 때 Prompt에 바로 복사해 넣으면 됩니다.
기법 3: “무엇을 하지 말아야 하는지” 명확히 쓰기
이 기법은 저를 수없이 구해 줬습니다.
AI는 기본적으로 최선을 다해 “도와주려” 합니다. 하지만 때로 그 “도움”은 필요하지 않습니다. 예를 들어 버그 하나를 고쳐 달라고 했더니 주변 코드까지 “최적화”해서 새 문제를 만들 수 있습니다.
Cursor 팀의 연구에 따르면, 명확한 제약 조건은 예기치 않은 수정을 60% 줄일 수 있습니다.
실전 사례입니다.
❌ 제약이 없는 Prompt:
UserList 컴포넌트의 페이지네이션 버그를 고쳐줘
AI는 다음처럼 행동할 수 있습니다.
- 컴포넌트의 props 인터페이스를 수정해 부모 컴포넌트가 에러를 냄
- 페이지네이션 로직 전체를 다시 써서 새 버그를 만듦
- 새 서드파티 라이브러리를 추가해 의존성이 늘어남
✅ 제약을 명확히 쓴 Prompt:
UserList 컴포넌트의 페이지네이션 버그를 수정하세요
**제약**:
- 컴포넌트의 props 인터페이스(TypeScript 타입)를 **수정하지 마세요**
- 새 서드파티 라이브러리를 **추가하지 마세요**
- handlePageChange 함수 내부 로직만 **수정하세요**
- 스타일과 UI 구조는 **바꾸지 마세요**
AI는 이 규칙을 지켜 필요한 부분만 수정합니다.
더 나아간 팁도 있습니다. AI에게 먼저 자신의 가정을 나열하게 하세요.
페이지네이션 버그를 수정하기 전에 먼저 당신의 가정을 나열하세요.
1. 버그의 원인이 무엇이라고 생각하나요?
2. 어떤 코드를 수정할 계획인가요?
3. 어떤 의존성을 추가하거나 인터페이스를 바꿀 예정인가요?
AI가 먼저 이 질문에 답하면, 당신은 AI의 이해가 맞는지 확인한 뒤 작업을 맡길 수 있습니다. 복잡한 버그 수정에 특히 잘 맞는 방법입니다.
기법 4: 완료 기준을 기준점으로 사용하기
이 기법은 애자일 개발에서 빌려온 것입니다.
Prompt의 앞부분에 완료 기준을 정의하세요. 끝부분이 아닙니다. AI는 이를 목표로 삼아 추론합니다. 마치 “반드시 도달해야 하는 목표”를 설정해 주는 것과 같습니다.
비교해 보겠습니다.
❌ 완료 기준 없음:
DataTable 컴포넌트 성능을 리팩터링해줘
AI: 어떤 상태면 완료인가요? 어떤 방법을 써야 하나요? 측정 기준은 무엇인가요? 결국 추측할 수밖에 없습니다.
✅ 완료 기준 있음:
DataTable 컴포넌트 성능 리팩터링
**완료 기준**(모두 만족해야 함):
- [ ] 1000행 데이터를 렌더링할 때 FPS가 55 이상
- [ ] React.memo와 useMemo 사용
- [ ] 컴포넌트 API(props와 callbacks)를 수정하지 않음
- [ ] 기존 모든 단위 테스트 통과
- [ ] ESLint 검사 통과
**현재 문제**:
500행 데이터를 렌더링하면 FPS가 20까지 떨어지고 스크롤이 끊김
AI는 이 기준을 “북극성”처럼 삼고, 모든 변경이 이 방향을 향하는지 확인합니다. 어떤 최적화가 테스트를 깨거나 API를 바꾼다면 자동으로 피하려고 합니다.
장점: AI가 “겉으로 보기에는 유용하지만 실제로는 쓸모없는” 변경을 하는 일을 막을 수 있습니다.
기법 5: Inline Edit과 Agent Mode 구분하기
많은 사람이 모르는 사실이 있습니다. Cursor에는 두 가지 작업 모드가 있고, 상황에 맞게 고르면 효율이 크게 올라갑니다.
Inline Edit(Cmd+K):
- 적합한 상황: 단일 파일의 작은 수정, 리팩터링, 버그 수정
- 특징: 빠르고 정확하며, 파일을 넘나들며 과하게 수정하지 않음
- 예시: 함수명 변경, 파라미터 추가, 버그 하나 수정
Agent Mode(Cmd+I 또는 Chat):
- 적합한 상황: 여러 파일 추론, 새 기능 개발, 아키텍처 수준 변경
- 특징: 전체 코드베이스 분석, 파일 간 작업, 계획 수립 가능
- 예시: 새 기능 추가, 대규모 리팩터링, 기술 스택 마이그레이션
저도 예전에는 모든 작업에 Agent Mode를 썼고 효율이 낮았습니다. 나중에 알게 된 것은 이것입니다. 간단한 작업은 Inline Edit, 복잡한 작업은 Agent Mode가 맞습니다.
결정 트리:
여러 파일을 수정해야 하나요?
├─ 예 → Agent Mode
└─ 아니요 → 복잡한 컨텍스트 이해가 필요한가요?
├─ 예 → Agent Mode
└─ 아니요 → Inline Edit
예를 들어 보겠습니다.
상황 1: 함수 getUserData를 fetchUserData로 이름 변경
→ Inline Edit 사용: 함수명을 선택하고 Cmd+K를 누른 뒤 “fetchUserData로 이름 변경” 입력. 바로 끝납니다.
상황 2: 사용자 권한 관리 기능 추가(Model, Controller, View, Config 여러 파일 관련)
→ Agent Mode 사용: 프로젝트 구조를 분석하고, 질문하고, 계획을 세운 뒤 여러 파일에 걸쳐 구현합니다.
모드를 잘못 고르면 다음 문제가 생깁니다.
- Inline Edit으로 복잡한 작업 수행 → 전체를 보지 못해 관련 변경을 놓치기 쉬움
- Agent Mode로 간단한 작업 수행 → 기다리는 시간이 길고 과하게 해석할 수 있음
작은 팁: 확실하지 않다면 먼저 Agent Mode의 Plan 기능으로 몇 개 파일을 수정하려는지 확인하세요. 1-2개 파일만 수정한다면 Inline Edit으로 돌아가는 편이 더 빠릅니다.
고급 기법: 나만의 Prompt 도구함 만들기
재사용 가능한 Prompt 템플릿 만들기
Prompt를 한동안 쓰다 보면 많은 작업이 반복된다는 것을 알게 됩니다. API 엔드포인트 추가, 컴포넌트 추가, 단위 테스트 작성, 데이터베이스 마이그레이션 같은 일들입니다.
매번 처음부터 쓰는 대신 자주 쓰는 Prompt를 템플릿으로 만들어 두는 편이 좋습니다.
저는 이제 프로젝트 루트마다 prompts/ 폴더를 두고, 작업 유형별로 나눠 둡니다.
prompts/
├── api-endpoint.md # 새 API 엔드포인트 템플릿
├── react-component.md # React 컴포넌트 템플릿
├── unit-test.md # 단위 테스트 템플릿
├── migration.md # 데이터베이스 마이그레이션 템플릿
└── refactor.md # 리팩터링 템플릿
예시: API 엔드포인트 템플릿(prompts/api-endpoint.md)
# 새 API 엔드포인트 템플릿
## Goal
[모듈명]에 [기능 설명] API 엔드포인트 추가
## Context
- 라우트 파일: src/routes/[모듈].routes.ts
- 컨트롤러: src/controllers/[모듈].controller.ts
- 서비스 계층: src/services/[모듈].service.ts
- 데이터 모델: src/models/[모듈].model.ts
## Desired Behavior
**요청**:
- Method: [GET/POST/PUT/DELETE]
- Path: /api/[경로]
- Body/Query: [파라미터 설명]
**응답**:
- 성공: { success: true, data: [...] }
- 실패: { success: false, error: "..." }
## Acceptance Criteria
- [ ] 기존 에러 처리 패턴 준수(다른 엔드포인트 참고)
- [ ] async/await 사용
- [ ] 입력 검증 추가(Joi 또는 Zod 사용)
- [ ] 에러 로그 기록(logger 사용)
- [ ] TypeScript 타입 검사 통과
## Constraints
- 기존 라우트 설정 구조를 **수정하지 마세요**
- 새 서드파티 라이브러리를 **추가하지 마세요**(필요하다면 이유 설명)
- 기존 데이터베이스 연결을 **반드시 사용하세요**(새 연결 생성 금지)
필요할 때 템플릿을 복사하고 빈칸만 채우면 됩니다.
팀 협업의 장점: 팀원이 이런 템플릿을 공유하면 코드 스타일이 맞춰지고, 신규 구성원도 더 빨리 적응합니다.
Agent Skills 사용하기(2026년 새 흐름)
이것은 2026년 AI 코딩 도구의 큰 흐름 중 하나입니다.
간단히 말해, Agent Skills는 재사용 가능한 “AI 애플리케이션” 입니다. 모범 사례를 하나의 Skill로 패키징해 두고 필요할 때 함수처럼 호출할 수 있습니다.
예를 들어 보겠습니다.
예전에는 블로그 글을 쓸 때마다 글에 맞는 이미지를 직접 준비해야 했습니다. 나중에 저는 Agent Skill 하나를 만들었고, 이 Skill이 자동으로 다음 일을 해 줍니다.
- 글 내용 분석
- 이미지가 필요한 섹션 식별
- 이미지 Prompt 생성
- 삽입 위치 표시
이제는 이 Skill만 실행하면 전체 흐름이 자동으로 끝납니다.
Agent Skills는 어떻게 만들까요?
Cursor에서는 .cursor/ 디렉터리 아래에 커스텀 Skill을 만들 수 있습니다.
.cursor/
└── skills/
├── code-review.md # 코드 리뷰 Skill
├── test-generator.md # 테스트 생성 Skill
└── api-doc.md # API 문서 생성 Skill
최신 동향: 2025년 12월 Agent Skills는 공개 규격이 되었고, Claude Code, Cursor, VS Code, GitHub Copilot 같은 주요 도구가 모두 지원합니다. 즉, 한 번 작성한 Skill을 여러 도구에서 사용할 수 있습니다.
솔직히 말하면, 처음에는 Skills가 조금 “과한 엔지니어링”처럼 느껴졌습니다. 하지만 여러 사람이 협업하는 프로젝트에서 팀 공유 Skills를 써 보니 코드 품질과 효율이 바로 한 단계 올라갔습니다.
프로젝트 구조를 최적화해 AI 이해 돕기
AI는 사람이 아닙니다. 코드베이스를 이해하는 방식도 우리와 다릅니다. 구조가 명확한 프로젝트일수록 AI의 결과도 훨씬 좋아집니다.
실용적인 제안:
-
/prompts폴더 만들기
자주 쓰는 Prompt 템플릿과 코드 예시를 저장해 복사하기 쉽게 만듭니다. -
.cursor/디렉터리에 프로젝트 컨텍스트 저장하기
.cursor/context.md파일을 만들고 다음 내용을 적습니다.- 프로젝트 기술 스택
- 코드 스타일 규칙
- 자주 쓰는 서드파티 라이브러리
- 특수 약속. 예를 들어 “비공개 메서드는
_로 시작합니다”
AI는 이 파일을 자동으로 읽고 프로젝트의 특징을 이해합니다.
-
명확한 디렉터리 구조와 파일명 사용하기
AI는 파일명과 디렉터리 구조를 바탕으로 코드의 용도를 추정합니다. 파일명이utils.ts,helpers.ts,common.ts라면 AI는 헷갈립니다. 이것들이 정확히 무엇일까요?이렇게 바꾸는 편이 더 좋습니다.
utils/ ├── date-formatter.ts ├── string-validator.ts └── array-helpers.ts
제 경험상 프로젝트 구조가 혼란스러울수록 AI 환각은 많아집니다. 디렉터리 구조를 정리하면 사람도 보기 편하고, AI도 당신을 더 잘 이해합니다.
함정 피하기: 흔한 실수와 해결책
실수 1: 정보 과부하. 한 번에 너무 많이 주기
AI 코딩을 막 시작했을 때 저는 이런 실수를 했습니다. 전체 요구사항 문서, 관련 파일 세 개, 참고 글 다섯 편을 전부 AI에게 붙여넣고 “정보는 많을수록 좋겠지”라고 생각했습니다.
결과는 어땠을까요? AI가 정보에 파묻혔습니다.
핵심을 잡지 못하거나, 잘못 이해하거나, 아예 타임아웃이 나기도 했습니다. 한 사람에게 동시에 열 가지 일을 설명하면 오히려 가장 적게 기억하는 것과 같습니다.
올바른 방법: 점진적 공개
처음부터 모든 정보를 쏟아붓지 말고 이렇게 하세요.
- 핵심 요구사항을 먼저 말합니다
- AI가 질문하면 상세 정보를 제공합니다
- 단계별로 컨텍스트를 줍니다
예를 들어 보겠습니다.
❌ 정보 과부하 버전:
사용자 인증 모듈을 리팩터링해줘.
[코드 500줄 붙여넣기]
[요구사항 문서 붙여넣기]
[기술 글 세 편 붙여넣기]
요구사항: 성능 개선, 보안 강화, 우아한 코드...
✅ 점진적 버전:
첫 번째 라운드:
사용자 인증 모듈을 리팩터링하고 싶습니다. 목표는 보안성을 높이는 것입니다.
현재 JWT를 사용하고 있고, 문제는 token 갱신 메커니즘이 없다는 점입니다.
어떤 정보를 더 알아야 하나요?
[AI가 질문: 현재 token 만료 시간은 얼마인가요? 어디에 저장하나요?]
두 번째 라운드:
token 만료 시간은 1시간이고 localStorage에 저장합니다.
현재 인증 로직은 다음과 같습니다(핵심 코드).
[핵심 50줄만 붙여넣기]
어떻게 개선할 계획인가요?
[AI가 방안을 제시하면 확인한 뒤 작업을 맡김]
이렇게 하면 AI가 핵심 문제에 집중할 수 있고, 사용자도 AI의 이해를 언제든 바로잡을 수 있습니다.
실수 2: AI에 과하게 의존하고 코드를 검토하지 않기
이 함정은 제가 가장 크게 밟은 것 중 하나입니다.
한번은 AI가 데이터 처리 함수를 작성해 줬습니다. 실행해도 에러가 없었고 단위 테스트도 통과했습니다. 코드도 꽤 깔끔해 보여서 바로 병합했습니다. 그런데 배포 후에야 이 함수가 엣지 케이스에서 잘못된 결과를 반환해 사용자 데이터가 뒤틀린다는 사실을 발견했습니다.
AI가 생성한 코드, 특히 “완전히 맞아 보이는” 코드가 가장 위험합니다.
경고: AI가 코드를 빠르게 생성할수록 더 꼼꼼하게 검토해야 합니다.
저는 이제 AI가 코드를 작성한 뒤 항상 세 가지를 확인합니다.
- 엣지 케이스: 빈 배열, null, undefined, 최댓값, 최솟값을 처리했는가?
- 부작용: 이 코드가 다른 모듈에 영향을 주는가?
- 성능: 무한 루프, 메모리 누수, 불필요한 반복 계산은 없는가?
실전 팁: AI에게 자기 코드를 직접 검토하게 하세요.
방금 생성한 코드를 검토하고 다음 질문에 답하세요.
1. 입력이 빈 배열이면 어떻게 되나요?
2. 이 코드에 성능 문제가 있나요?
3. 어떤 가정을 사용했나요? 그 가정은 모든 상황에서 성립하나요?
AI가 코드를 다시 점검하면서 스스로 문제를 찾아내는 경우가 많습니다.
실수 3: 한 번에 완벽한 답을 기대하기
많은 사람이 AI를 “마법 버튼”처럼 생각합니다. 요구사항을 입력하면 즉시 완벽한 코드가 나온다고 기대합니다. 현실은 그렇지 않습니다.
AI는 “완전 자동 코드 생성기”라기보다 협업자에 가깝습니다. 가장 효율적인 방식은 반복 대화입니다.
- 사용자가 요구사항을 설명합니다
- AI가 초안 또는 질문을 제시합니다
- 사용자가 확인하고, 수정하고, 보충합니다
- AI가 피드백에 따라 개선합니다
- 만족할 때까지 3-4를 반복합니다
올바른 예시:
사용자: 사용자 목록 검색 기능을 구현해줘
AI: 좋습니다. 검색창을 추가하고 사용자 목록을 실시간 필터링하겠습니다.
어떤 필드를 검색하길 원하시나요? 사용자명, 이메일, 아니면 다른 필드인가요?
사용자: 사용자명과 이메일을 검색하되 실시간 필터링은 필요 없습니다.
"검색" 버튼을 클릭한 뒤 트리거되게 해 주세요
AI: 알겠습니다. 프론트엔드에서 필터링하나요, 아니면 백엔드로 요청을 보내나요?
사용자: 데이터 양이 많지 않으니 프론트엔드에서 필터링합니다
AI: 좋습니다. Array.filter()를 사용하겠습니다.
먼저 구현 계획을 보여 드리겠습니다...
보이나요? 이것은 대화이지 “명령”이 아닙니다.
팁: Cursor의 “Show Work” 모드를 사용하세요. 설정에서 켜면 AI가 추론 과정을 보여 주며, 어떻게 생각했는지 확인할 수 있어 문제를 더 쉽게 발견할 수 있습니다.
덧붙임: Prompt “튜닝”에 시간을 낭비하지 마세요
마지막으로 조금 반직관적인 조언을 하겠습니다. 완벽한 Prompt를 과하게 추구하지 마세요.
30분 동안 Prompt를 정성스럽게 설계했는데, 생성된 코드가 직접 쓰는 것보다 못한 사람도 봤습니다. 주객이 전도된 것입니다.
Prompt 엔지니어링의 목적은 효율 향상이지, Prompt를 얼마나 멋지게 썼는지 보여 주는 것이 아닙니다. 직접 10분 만에 끝낼 수 있는 작업이라면 Prompt를 쓰는 데 20분을 들이지 마세요.
언제 AI를 쓸 가치가 있을까요?
- ✅ 반복 작업(일괄 수정, 템플릿 생성)
- ✅ 익숙하지 않은 영역(새 기술 스택, 새 라이브러리)
- ✅ 복잡하지만 패턴이 있는 작업(API 엔드포인트, CRUD 작업)
언제 가치가 낮을까요?
- ❌ 눈 감고도 쓸 수 있을 만큼 단순한 코드
- ❌ 깊은 사고가 필요한 알고리즘 설계
- ❌ 참고 패턴이 없는 고도로 맞춤화된 코드
기억하세요. AI는 도구이지 목적이 아닙니다. 문제를 빠르게 해결하는 것이 핵심입니다.
결론
Prompt를 잘 쓰는 것은 대단히 어려운 기술이 아닙니다. 핵심은 세 가지입니다. 목표를 명확히 말하고, 충분한 컨텍스트를 주고, 경계를 정하는 것입니다.
이 글의 핵심 기법 5가지를 다시 정리해 보겠습니다.
- Plan Mode로 먼저 계획하기. 자신에게 “되돌아볼 기회”를 줍니다
- 코드 예시 제공하기. AI가 당신의 스타일을 따라오게 합니다
- 제약 조건 명확히 쓰기. AI에게 무엇을 건드리면 안 되는지 알려 줍니다
- 완료 기준 설정하기. AI에게 명확한 목표를 줍니다
- 작업 모드 올바르게 고르기. 간단한 작업은 Inline Edit, 복잡한 작업은 Agent Mode
이것들을 익히면 AI는 더 이상 “답답한 도우미”가 아니라 실제로 효율을 높여 주는 프로그래밍 파트너가 됩니다. 저도 이 방법들을 쓰고 나서 AI가 생성하는 코드의 정확도가 최소 50%는 올랐고, 반복 작업은 이제 10분 만에 끝낼 때가 많습니다.
지금 바로 Cursor를 열고 구조화 템플릿을 써 보세요. 다음 기능부터 “Goal - Context - Desired Behavior - Constraints” 형식으로 Prompt를 작성해 보세요. 차이를 바로 느낄 수 있을 겁니다.
기억하세요. AI 프로그래밍의 미래는 “AI가 프로그래머를 대체한다”가 아니라, “AI를 잘 쓰는 프로그래머가 그렇지 못한 프로그래머를 대체한다”에 가깝습니다. 그 역량 차이는 첫 번째 고품질 Prompt에서 시작됩니다.
구조화 Prompt로 AI 코드 품질 높이기
모호한 지시에서 정확한 출력까지 이어지는 Cursor Prompt 엔지니어링 실전 흐름을 익힙니다
⏱️ Estimated time: 30 min
- 1
Step 1: AI의 작동 방식을 이해하고 흔한 Prompt 실패 피하기
AI는 사용자가 제공한 정보만 바탕으로 추론할 수 있으며 마음을 읽지 못합니다. 흔한 실패는 세 가지입니다.
**너무 모호함**:
❌ "정렬을 구현해줘"
✅ "utils/array.ts 파일에 함수를 추가해 사용자 목록을 가입 시간 내림차순으로 정렬하고, 기본 Array.sort()를 사용하며 새 의존성은 추가하지 마세요"
**컨텍스트 부족**:
❌ "에러 처리를 추가해줘"
✅ "api/login.ts의 handleLogin 함수에 에러 처리를 추가하세요. 네트워크 요청 실패를 try-catch로 잡고, 통일된 형식 { success: false, error: string }을 반환하며, api/register.ts의 처리 방식을 참고하세요"
**제약 조건 없음**:
❌ "이 컴포넌트 성능을 최적화해줘"
✅ "UserList.tsx 컴포넌트 성능을 최적화하세요. React.memo 또는 useMemo만 사용할 수 있고, props 인터페이스를 수정하지 말며, 새 서드파티 라이브러리를 추가하지 마세요"
핵심은 명확한 컨텍스트가 AI 환각 문제를 70% 줄이고, 명확한 제약 조건이 예기치 않은 수정을 60% 줄인다는 점입니다. - 2
Step 2: 구조화 Prompt의 황금 공식 사용하기
Cursor 공식 권장 방식에 가까운 6단계 템플릿을 사용합니다.
## Goal(목표)
무엇을 구현하려는지 한 문장으로 설명합니다
## Context(컨텍스트)
• 프로젝트 기술 스택(React 18 + TypeScript)
• 관련 파일 경로(src/pages/Login.tsx)
• 기존 서비스(src/services/authService.ts)
• 사용 중인 라이브러리(Ant Design 5.x)
## Current Behavior(현재 동작)
로그인 페이지에는 정적 UI만 있고 상호작용 로직이 없습니다
## Desired Behavior(기대 동작)
1. 사용자가 아이디와 비밀번호를 입력한 뒤 로그인 클릭
2. authService.login()을 호출해 검증
3. 성공: token을 Redux에 저장하고 /dashboard로 이동
4. 실패: 에러 메시지 표시(Ant Design message.error)
## Acceptance Criteria(완료 기준)
• 폼 검증: 아이디와 비밀번호는 비어 있을 수 없음
• 로그인 중 loading 상태 표시
• 비밀번호 입력창은 type="password" 사용
• ESLint와 TypeScript 검사를 통과
## Constraints(제약)
• authService.ts 파일을 수정하지 않음
• 새 서드파티 라이브러리를 추가하지 않음
• 기존 Redux slice(src/store/authSlice.ts)를 반드시 사용
이 템플릿은 AI가 추측하지 않게 만들고, 생성된 코드가 프로젝트 규칙에 맞도록 도와줍니다. - 3
Step 3: 바로 효과가 나는 실전 기법 5가지 익히기
**기법 1: 먼저 계획하고 나중에 코딩하기(Plan Mode)**
• Shift+Tab으로 Plan 모드 전환
• AI가 먼저 코드베이스를 분석하고 질문
• 실행 계획 수립(어떤 파일을 수정할지)
• 사용자가 계획을 검토하고 수정한 뒤 실행
• AI가 바로 코드를 건드려 망치는 상황 방지
**기법 2: 구체적인 코드 예시 제공하기(Few-shot Prompting)**
• Prompt 안에 기존 코드 예시를 붙여넣기
• AI가 코드 스타일과 에러 처리 습관을 모방
• prompts/templates.md를 만들어 자주 쓰는 예시 저장 권장
**기법 3: 무엇을 하지 말아야 하는지 명확히 쓰기**
• Constraints 부분에 금지 항목 나열
• 예기치 않은 수정을 60% 줄임
• 고급 팁: AI에게 먼저 가정 목록을 쓰게 하기(버그 원인, 수정 범위, 의존성 변경)
**기법 4: 완료 기준을 기준점으로 사용하기**
• Prompt 앞부분에 Acceptance Criteria 정의
• AI가 이를 북극성처럼 삼아 추론
• 겉으로만 유용해 보이지만 실제로는 쓸모없는 변경 방지
**기법 5: Inline Edit과 Agent Mode 구분하기**
• Inline Edit(Cmd+K): 단일 파일의 작은 수정, 빠르고 정확함
• Agent Mode(Cmd+I): 여러 파일 추론, 새 기능 개발, 아키텍처 수준 변경
• 결정 트리: 여러 파일을 수정해야 하는가? → 그렇다면 Agent, 아니면 Inline - 4
Step 4: 재사용 가능한 Prompt 도구함 만들기
**Prompt 템플릿 라이브러리 만들기**:
프로젝트 루트에 prompts/ 폴더를 만들고 작업 유형별로 저장합니다.
• api-endpoint.md(API 엔드포인트 템플릿)
• react-component.md(React 컴포넌트 템플릿)
• unit-test.md(단위 테스트 템플릿)
• migration.md(데이터베이스 마이그레이션 템플릿)
• refactor.md(리팩터링 템플릿)
각 템플릿은 Goal, Context, Desired Behavior, Acceptance Criteria, Constraints 다섯 부분을 포함하고, 사용할 때 복사해 빈칸만 채우면 됩니다.
**Agent Skills 사용하기(2026년 새 흐름)**:
.cursor/skills/ 디렉터리에 재사용 가능한 AI 애플리케이션을 만듭니다.
• code-review.md(코드 리뷰 Skill)
• test-generator.md(테스트 생성 Skill)
• api-doc.md(API 문서 생성 Skill)
2025년 12월 Agent Skills는 공개 규격이 되었고 Cursor, VS Code, GitHub Copilot 등 여러 도구에서 함께 사용할 수 있게 되었습니다.
**AI가 이해하기 좋은 프로젝트 구조 만들기**:
• .cursor/context.md 파일을 만들어 프로젝트 기술 스택, 코드 스타일 규칙, 특수 약속을 기록
• 명확한 디렉터리 구조와 파일명 사용(date-formatter.ts, 단순 utils.ts 지양)
• 프로젝트 구조가 어수선할수록 AI 환각은 늘어남 - 5
Step 5: 흔한 실수 세 가지 피하기
**실수 1: 정보 과부하**
❌ 코드 500줄 + 요구사항 문서 + 기술 글을 한 번에 붙여넣기
✅ 점진적 공개: 핵심 요구사항 먼저 설명 → AI 질문 → 상세 정보 제공 → 단계별 컨텍스트 제공
**실수 2: AI에 과하게 의존하고 코드를 검토하지 않음**
AI가 코드를 쓴 뒤 스스로 세 가지를 물어봅니다.
• 엣지 케이스(빈 배열, null, undefined, 극값)를 처리했는가?
• 이 코드가 다른 모듈에 영향을 주는가?
• 무한 루프, 메모리 누수, 불필요한 반복 계산은 없는가?
실전 팁: AI에게 자기 코드를 직접 검토하게 하고 "입력이 빈 배열이면 어떻게 되는가", "성능 문제가 있는가", "어떤 가정을 사용했는가"라고 물어봅니다.
**실수 3: 한 번에 완벽한 답을 기대함**
AI는 마법 버튼이 아니라 협업자입니다. 올바른 방식은 반복 대화입니다.
1. 사용자가 요구사항을 설명
2. AI가 초안 또는 질문 제시
3. 사용자가 확인, 수정, 보충
4. AI가 피드백에 따라 개선
5. 만족할 때까지 3-4 반복
Cursor의 "Show Work" 모드를 켜면 AI의 추론 과정을 볼 수 있어 문제를 더 쉽게 찾을 수 있습니다.
FAQ
Prompt를 아주 자세히 썼는데도 AI가 왜 잘못된 코드를 만들까요?
• 작업할 파일 경로를 명확히 썼나요? AI는 어느 파일에서 작업해야 하는지 모릅니다.
• 기존 코드 예시를 제공했나요? AI는 당신의 코드 스타일을 모릅니다.
• 제약 조건을 설명했나요? AI가 과하게 자유롭게 해석할 수 있습니다.
실전 방법은 Prompt 안에서 세 가지 질문에 답하는 것입니다. AI가 내가 어느 파일에서 작업하는지 아는가? AI가 기존 코드 구조를 아는가? AI가 무엇을 바꿀 수 있고 무엇을 바꾸면 안 되는지 아는가? 답할 수 없다면 관련 정보를 보충한 뒤 Prompt를 보내세요.
또 Plan Mode를 사용해 AI가 먼저 계획을 세우게 하고, 사용자가 검토한 뒤 실행하면 많은 문제를 피할 수 있습니다.
Inline Edit과 Agent Mode는 각각 언제 써야 하나요?
**여러 파일을 수정해야 하나요?**
• 예 → Agent Mode(Cmd+I 또는 Chat)
• 아니요 → 복잡한 컨텍스트 이해가 필요한가요?
- 예 → Agent Mode
- 아니요 → Inline Edit(Cmd+K)
구체적인 상황:
• Inline Edit: 함수명 변경, 파라미터 추가, 단일 버그 수정, 단일 함수 리팩터링
• Agent Mode: 새 기능 추가(Model/Controller/View 포함), 대규모 리팩터링, 기술 스택 마이그레이션, 전체 코드베이스 분석이 필요한 작업
작은 팁: 확실하지 않다면 먼저 Agent Mode의 Plan 기능으로 몇 개 파일을 수정하려는지 확인하세요. 1-2개 파일만 수정한다면 Inline Edit으로 돌아가는 편이 더 빠릅니다.
AI가 생성한 코드가 우리 프로젝트 코드 스타일에 맞게 하려면 어떻게 해야 하나요?
**방법 1: 구체적인 코드 예시 제공(가장 효과적)**
Prompt 안에 기존 코드 예시를 붙여넣으면 AI가 스타일, 에러 처리 방식, 네이밍 규칙을 모방합니다. 이를 Few-shot Prompting이라고 합니다.
**방법 2: 프로젝트 컨텍스트 파일 만들기**
.cursor/context.md에 다음을 기록합니다.
• 프로젝트 기술 스택
• 코드 스타일 규칙(예: "비공개 메서드는 _로 시작합니다")
• 자주 쓰는 서드파티 라이브러리
• 특수 약속
AI는 이 파일을 자동으로 읽습니다.
**방법 3: 재사용 가능한 Prompt 템플릿 만들기**
프로젝트 루트에 prompts/ 폴더를 만들고 API 엔드포인트, React 컴포넌트, 단위 테스트 같은 자주 쓰는 템플릿을 저장합니다. 팀원이 템플릿을 공유하면 코드 스타일도 자연스럽게 맞춰집니다.
AI가 만든 코드는 맞아 보이는데 실행하면 버그가 있으면 어떻게 하나요?
**AI가 생성한 코드는 항상 검토하세요.** 스스로 세 가지를 물어봅니다.
1. 엣지 케이스를 처리했는가? 빈 배열, null, undefined, 최댓값, 최솟값
2. 이 코드가 다른 모듈에 영향을 주는가? 부작용 점검
3. 성능 문제가 있는가? 무한 루프, 메모리 누수, 불필요한 반복 계산
**실전 팁**: AI에게 자기 코드를 검토하게 하세요.
"방금 생성한 코드를 검토하고 답하세요. 1) 입력이 빈 배열이면 어떻게 되나요? 2) 이 코드에 성능 문제가 있나요? 3) 어떤 가정을 사용했나요? 그 가정은 모든 상황에서 성립하나요?"
AI가 다시 점검하면서 스스로 문제를 찾는 경우가 많습니다. 또한 Cursor의 "Show Work" 모드를 켜고 AI의 추론 과정을 보면 잠재 문제를 더 쉽게 발견할 수 있습니다.
언제 AI로 코드를 작성할 가치가 있고, 언제 그렇지 않나요?
• 반복 작업(파일 일괄 수정, 템플릿 코드 생성, 반복 로직 리팩터링)
• 익숙하지 않은 영역(새 기술 스택, 새 라이브러리, 자주 쓰지 않는 API)
• 복잡하지만 패턴이 있는 작업(API 엔드포인트, CRUD 작업, 폼 검증, 데이터 변환)
AI를 쓸 가치가 낮은 상황:
• 눈 감고도 쓸 수 있을 만큼 단순한 코드(변수명 변경, 주석 추가)
• 깊은 사고가 필요한 알고리즘 설계(핵심 비즈니스 로직, 복잡한 알고리즘 최적화)
• 참고 패턴이 거의 없는 고도로 맞춤화된 코드(혁신 기능, 특수 비즈니스 상황)
판단 기준은 간단합니다. 직접 10분 안에 끝낼 수 있다면 Prompt를 쓰는 데 20분을 쓰지 마세요. Prompt 엔지니어링의 목적은 효율 향상이지 멋진 Prompt를 보여주는 것이 아닙니다. AI는 도구이지 목적이 아니며, 문제를 빠르게 해결하는 것이 핵심입니다.
Plan Mode는 구체적으로 어떻게 쓰고, 어떤 상황에서 가장 효과적인가요?
1. Shift+Tab을 눌러 Plan 모드로 전환
2. 요구사항 설명
3. AI가 코드베이스를 분석하고 질문 제시(예: "기존 에러 처리를 유지하길 원하나요?")
4. AI가 실행 계획 작성(수정할 파일과 추가할 기능 나열)
5. 사용자가 계획을 검토하고 수정
6. 확인 후에야 AI가 코드 작성 시작
**가장 효과적인 상황**:
• 대규모 리팩터링(AI가 잘못된 파일을 수정하거나 핵심 코드를 지우는 상황 방지)
• 새 기능 개발(여러 파일이 관련될 때 먼저 계획 확인)
• AI가 제대로 이해했는지 확실하지 않을 때(계획으로 이해도 검증)
• 복잡한 작업(국제화 기능 추가, 데이터베이스 마이그레이션 등)
Plan Mode의 핵심 가치는 "되돌아볼 기회"를 주는 것입니다. AI가 곧바로 코드를 건드려 망치는 일을 막아 주며, 특히 되돌리기 어려운 큰 변경에 잘 맞습니다.
AI가 불필요한 서드파티 라이브러리를 추가하지 않게 하려면 어떻게 해야 하나요?
**새 라이브러리 추가 금지 명시**:
"**새 서드파티 라이브러리를 추가하지 마세요**"
"**어떤 npm 패키지도 설치하지 마세요**"
"**프로젝트에 이미 있는 의존성(package.json의 라이브러리)만 사용하세요**"
**반드시 사용할 라이브러리 지정**:
"**기존 Ant Design 컴포넌트(이미 설치된 5.x 버전)를 반드시 사용하세요**"
"**프로젝트의 authService(src/services/authService.ts)를 반드시 사용하세요**"
**기존 라이브러리 예시 제공**:
Context 부분에 프로젝트의 기존 의존성과 사용 방식을 적으면 AI는 새 라이브러리를 "발명"하기보다 그것들을 우선 사용합니다.
**Plan Mode 사용**:
AI가 먼저 계획을 세우면 어떤 라이브러리를 추가하려는지 미리 볼 수 있고, 불필요한 의존성을 제때 막을 수 있습니다.
기억하세요. 제약이 명확할수록 AI는 덜 자유롭게 해석합니다.
4분 읽기 · 게시일: 2026년 1월 29일 · 수정일: 2026년 10월 21일



댓글
GitHub로 로그인하여 댓글을 남기세요