1. 문제: AI의 즉답 한계
현상
- 복잡한 문제에 대한 단순한 답변
- 추론 과정 없이 결과만 제시
- 아키텍처 설계 이유 설명 부족
원인
AI에게 “생각할 시간”을 주지 않음
2. Chain of Thought (CoT) 기법
정의
문제를 작은 단위로 분해하여 단계별 추론을 유도하는 기법
비유: 함수의 단계별 실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| // 즉답 방식 (나쁜 예시)
public Long createOrder(OrderRequest request) {
// 모든 로직을 한 번에 처리
return orderRepository.save(order).getId();
}
// Chain of Thought 방식 (좋은 예시)
public Long createOrder(OrderRequest request) {
// Step 1: 유효성 검증
validateOrderRequest(request);
// Step 2: 재고 확인
checkInventory(request.getItems());
// Step 3: 가격 계산
BigDecimal totalAmount = calculateTotal(request);
// Step 4: 주문 생성
Order order = buildOrder(request, totalAmount);
// Step 5: 저장
return orderRepository.save(order).getId();
}
|
각 단계를 명시적으로 분리하여 추론 과정을 드러냄
3. CoT 실전 적용: 아키텍처 설계
프롬프트 구조
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| 나는 쇼핑몰의 주문 시스템을 개편하려고 해.
바로 코드를 짜지 말고, 먼저 다음 단계에 따라 생각(Chain of Thought)을 정리해줘.
## Step 1: 트랜잭션 범위 정의
주문 발생 시 트랜잭션 범위는 어디까지 잡아야 할까?
- 재고 차감
- 결제 승인
- 주문 생성
각 단계의 트랜잭션 경계를 명시해줘.
## Step 2: 정합성 보장 전략
재고 차감과 결제 승인 간의 정합성을 맞추기 위한 전략은 무엇인가?
- Optimistic Lock
- Pessimistic Lock
- Saga Pattern
각 전략의 장단점을 비교해줘.
## Step 3: 의사 코드 작성
위 내용을 바탕으로 Java Spring Boot 구조로 의사 코드(Pseudo-code)를 작성해줘.
|
AI 응답 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
| ## Step 1: 트랜잭션 범위 정의
### 트랜잭션 경계
1. **재고 차감**: 별도 트랜잭션 (InventoryService)
- 이유: 재고는 독립적인 도메인, 롤백 시 복잡도 증가
2. **결제 승인**: 별도 트랜잭션 (PaymentService)
- 이유: 외부 API 호출, 타임아웃 처리 필요
3. **주문 생성**: 메인 트랜잭션 (OrderService)
- 이유: 주문은 최종 결과물, 실패 시 전체 롤백
### 트랜잭션 전파 전략
- OrderService: @Transactional(propagation = REQUIRED)
- InventoryService: @Transactional(propagation = REQUIRES_NEW)
- PaymentService: @Transactional(propagation = REQUIRES_NEW)
## Step 2: 정합성 보장 전략
| 전략 | 장점 | 단점 | 적용 시나리오 |
|------|------|------|--------------|
| Optimistic Lock | 성능 우수, 동시성 높음 | 충돌 시 재시도 필요 | 재고 차감 |
| Pessimistic Lock | 데이터 정합성 보장 | 성능 저하, 데드락 위험 | 결제 처리 |
| Saga Pattern | 분산 트랜잭션 처리 | 복잡도 증가 | 마이크로서비스 환경 |
## Step 3: 의사 코드
```java
@Service
public class OrderService {
@Transactional
public Long createOrder(OrderRequest request) {
// Step 1: 재고 차감 (별도 트랜잭션)
inventoryService.decreaseStock(request.getItems());
// Step 2: 결제 승인 (별도 트랜잭션)
PaymentResult payment = paymentService.approve(request.getPayment());
// Step 3: 주문 생성 (메인 트랜잭션)
Order order = buildOrder(request, payment);
return orderRepository.save(order).getId();
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
------
### 4. Few-shot Prompting 기법
#### 정의
**예시를 제공하여 원하는 출력 형식을 학습시키는 기법**
#### 비유: 함수 오버로딩 예시
```java
// Few-shot: 여러 예시를 보여주고 패턴 학습
public int add(int a, int b) { return a + b; } // 예시 1
public int add(int a, int b, int c) { return a + b + c; } // 예시 2
// AI가 패턴을 학습하여 새로운 케이스 처리
|
실전 예시: 코드 리뷰 스타일 학습
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| 너는 10년차 시니어 자바 개발자야.
아래 예시를 참고하여 코드 리뷰를 작성해줘.
## 예시 1: 좋은 리뷰
```java
// 원본 코드
public User getUser(Long id) {
return userRepository.findById(id).get();
}
// 리뷰
❌ Optional.get()은 NoSuchElementException 발생 가능
✅ Optional.orElseThrow() 사용 권장
✅ 예외 메시지 명시: .orElseThrow(() -> new UserNotFoundException(id))
|
예시 2: 좋은 리뷰
1
2
3
4
5
6
7
8
9
10
11
| // 원본 코드
public void updateUser(Long id, UserUpdateRequest request) {
User user = userRepository.findById(id).get();
user.setName(request.getName());
userRepository.save(user);
}
// 리뷰
❌ 트랜잭션 어노테이션 누락
✅ @Transactional 추가 필요
✅ 더티 체킹 활용: save() 호출 불필요
|
이제 아래 코드를 리뷰해줘:
[실제 코드]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
------
### 5. Role Playing (페르소나 부여)
#### 정의
**AI에게 특정 역할을 부여하여 전문적인 답변을 유도**
#### 실전 예시: 시니어 개발자 페르소나
```markdown
너는 10년차 백엔드 시니어 개발자야.
Spring Boot, JPA, 트랜잭션 관리에 전문성을 가지고 있어.
코드 리뷰 시 다음 관점을 중시해:
1. 트랜잭션 경계와 전파 전략
2. N+1 문제와 성능 최적화
3. 예외 처리와 에러 핸들링
4. 테스트 가능한 코드 구조
아래 코드를 리뷰해줘:
[코드]
|
응답 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| ## 트랜잭션 경계 문제
현재 코드는 @Transactional이 Service 메서드에만 있어.
Repository에서 별도 조회가 발생하면 지연 로딩 실패 가능.
**개선안:**
```java
@Transactional(readOnly = true)
public UserResponse getUser(Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
// 트랜잭션 내에서 지연 로딩 처리
user.getOrders().size(); // 초기화
return UserResponse.from(user);
}
|
N+1 문제
User와 Order 간 연관 관계에서 N+1 발생 가능.
개선안:
1
2
| @Query("SELECT u FROM User u JOIN FETCH u.orders WHERE u.id = :id")
Optional<User> findByIdWithOrders(@Param("id") Long id);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
------
### 6. 복합 기법 활용: CoT + Few-shot + Role Playing
#### 프롬프트 구조
```markdown
## 역할 부여
너는 10년차 시니어 자바 개발자야.
아키텍처 설계와 성능 최적화에 전문성을 가지고 있어.
## Few-shot 예시
아래는 좋은 아키텍처 설계 예시야:
### 예시 1: 계층 분리
```java
// Controller: HTTP 요청 처리만
@RestController
public class UserController {
private final UserService userService;
@PostMapping("/users")
public ResponseEntity<UserResponse> create(@RequestBody UserRequest request) {
return ResponseEntity.ok(userService.create(request));
}
}
// Service: 비즈니스 로직
@Service
@Transactional
public class UserService {
public UserResponse create(UserRequest request) {
// 비즈니스 로직
}
}
|
예시 2: 의존성 역전
1
2
3
4
5
6
| // 인터페이스 정의
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
// 구현체는 Spring Data JPA가 자동 생성
|
Chain of Thought 질문
이제 아래 요구사항을 단계별로 설계해줘:
Step 1: 계층 구조 설계
주문 생성 API를 위한 Controller, Service, Repository 계층을 설계해줘. 각 계층의 책임을 명확히 구분해줘.
Step 2: 트랜잭션 전략
주문 생성 시 재고 차감, 결제 승인, 주문 저장의 트랜잭션 전략을 정의해줘.
Step 3: 예외 처리 전략
각 단계에서 발생할 수 있는 예외와 처리 방법을 정의해줘.
Step 4: 최종 코드 작성
위 설계를 바탕으로 실제 코드를 작성해줘.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
------
### 7. 실전 템플릿
#### 템플릿 1: 아키텍처 설계
```markdown
## 역할
너는 [역할] 전문가야.
## Chain of Thought
[요구사항]을 구현하기 위해 다음 단계로 생각해줘:
1. [첫 번째 고려사항]
2. [두 번째 고려사항]
3. [세 번째 고려사항]
각 단계별로:
- 문제점 분석
- 해결 방안 제시
- 코드 예시 제공
|
템플릿 2: 코드 리뷰
1
2
3
4
5
6
7
8
9
10
11
12
| ## 역할
너는 [역할] 전문가야.
리뷰 시 다음 관점을 중시해:
1. [관점 1]
2. [관점 2]
3. [관점 3]
## Few-shot 예시
[좋은 리뷰 예시 2-3개]
## 리뷰 요청
[코드]
|
8. 정리
핵심 기법
- Chain of Thought: 단계별 추론 유도
- Few-shot: 예시를 통한 패턴 학습
- Role Playing: 전문가 페르소나 부여
적용 원칙
- 복잡한 문제는 작은 단위로 분해
- 예시를 통해 원하는 형식 학습
- 역할 부여로 전문성 향상
다음 단계
AI 서비스 통합을 위한 System Prompt 설계와 JSON 출력 제어