Cursor의 @Codebase, 도대체 뭐가 다른 걸까? 🤔
ChatGPT에게 코드 질문하면:
- “일반적으로는 이렇게 해요” (추상적)
- “보통 Spring에서는…” (일반론)
Cursor에서 @Codebase로 질문하면:
- “너의 UserService.java 73번째 줄에서…” (구체적)
- “이 프로젝트의 SecurityConfig를 보니…” (맞춤형)
차이는 단 하나, Context(맥락)입니다.
오늘은 Spring 개발자 관점에서 Cursor의 @Codebase 기능을 완벽히 이해해봅시다!
1. @Codebase란? - Project Context Injection 🎯
정의
“현재 프로젝트의 전체 코드베이스를 AI의 컨텍스트에 주입하는 기능”
1
2
3
4
5
6
7
8
9
10
11
| // ChatGPT (컨텍스트 없음)
public String askChatGPT(String question) {
// 프로젝트 정보가 전혀 없는 상태
return chatGPT.answer(question);
}
// Cursor with @Codebase (컨텍스트 주입)
public String askCursor(String question, @Codebase Project project) {
// 프로젝트 전체 구조, 코드, 패턴을 아는 상태
return cursor.answerWithContext(question, project);
}
|
Spring 개발자에게 익숙한 비유
@Codebase = Spring의 @ComponentScan
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
| // @ComponentScan 없이 (수동 Bean 등록)
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService(); // 일일이 등록
}
@Bean
public OrderService orderService() {
return new OrderService(); // 일일이 등록
}
@Bean
public PaymentService paymentService() {
return new PaymentService(); // 일일이 등록
}
// ... 100개 서비스를 다 등록?! ❌
}
// @ComponentScan 사용 (자동 스캔)
@SpringBootApplication // 내부에 @ComponentScan 포함
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// ✅ 패키지 내 모든 @Component, @Service 자동 스캔!
}
}
|
마찬가지로:
1
2
3
4
5
6
7
8
9
10
11
12
| // @Codebase 없이 (파일 하나만 인식)
"UserService.java에서 createUser 메서드를 개선해줘"
// AI: 이 파일만 보고 답변 (다른 파일과의 연관성 모름)
// @Codebase 사용 (프로젝트 전체 스캔)
"@Codebase UserService.java에서 createUser 메서드를 개선해줘"
// AI: 프로젝트 전체를 스캔하여
// - UserRepository와의 관계 파악
// - SecurityConfig의 인증 방식 고려
// - 다른 서비스들의 패턴 참고
// - Exception 처리 방식 통일
// ✅ 프로젝트 전체 맥락을 고려한 답변!
|
2. 기술적 원리: RAG + Vector Search 🔍
작동 방식 (간단 버전)
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
43
44
45
46
47
48
49
50
51
52
| public class CursorCodebaseFeature {
private VectorDatabase vectorDB; // 코드 임베딩 저장소
private EmbeddingModel embeddingModel; // 코드 → 벡터 변환
// 1. 프로젝트 인덱싱 (최초 1회)
public void indexCodebase(Project project) {
for (File file : project.getAllFiles()) {
// 각 파일을 의미 있는 청크로 분할
List<CodeChunk> chunks = splitIntoChunks(file);
for (CodeChunk chunk : chunks) {
// 코드를 벡터로 변환
float[] vector = embeddingModel.encode(chunk.getCode());
// Vector DB에 저장
vectorDB.insert(new Document(
chunk.getCode(),
vector,
chunk.getFilePath(),
chunk.getLineNumber()
));
}
}
}
// 2. 질문 시 관련 코드 검색
public String answerWithCodebase(String question) {
// Step 1: 질문을 벡터로 변환
float[] queryVector = embeddingModel.encode(question);
// Step 2: 유사한 코드 조각 검색 (Vector Search)
List<Document> relevantCode = vectorDB.searchSimilar(
queryVector,
topK = 10 // 가장 관련 있는 10개 파일
);
// Step 3: 검색된 코드를 컨텍스트로 구성
String context = buildContext(relevantCode);
// Step 4: LLM에 컨텍스트 + 질문 전달
String prompt = String.format("""
[프로젝트 코드]
%s
[질문]
%s
""", context, question);
return llm.generate(prompt);
}
}
|
Spring의 ComponentScan과 비교
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| // Spring의 @ComponentScan
@ComponentScan(basePackages = "com.example.myapp")
public class AppConfig {
// 1. 패키지 스캔
// 2. @Component 어노테이션 찾기
// 3. Bean으로 등록
// 4. 의존성 주입 가능
}
// Cursor의 @Codebase
@Codebase
"UserService 개선해줘"
// 1. 프로젝트 스캔
// 2. 관련 파일 찾기 (Vector Search)
// 3. 컨텍스트 구성
// 4. AI 답변 생성
|
핵심 차이:
| 구분 | Spring @ComponentScan | Cursor @Codebase |
|---|
| 대상 | Bean 클래스 (@Component 등) | 모든 코드 파일 |
| 방식 | 어노테이션 기반 | 의미 기반 (Vector) |
| 목적 | 의존성 주입 | 컨텍스트 제공 |
| 검색 | 클래스 경로 탐색 | Vector Similarity |
3. Before & After: 외부 컨설턴트 vs 팀 동료 👥
시나리오 1: “UserService 코드 리뷰해줘”
Before (외부 컨설턴트 - 프로젝트 모름)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| 질문: "UserService 코드 리뷰해줘"
ChatGPT 답변:
"UserService의 일반적인 개선 사항은 다음과 같습니다:
1. 트랜잭션 처리를 추가하세요
2. 예외 처리를 개선하세요
3. null 체크를 추가하세요
4. 로깅을 추가하세요
예시 코드:
@Service
@Transactional
public class UserService {
// 일반적인 패턴의 코드...
}
"
문제점:
❌ 이 프로젝트의 실제 UserService 코드를 보지 못함
❌ 이미 트랜잭션이 있는지 모름
❌ 우리 팀의 예외 처리 방식을 모름
❌ 일반론적인 조언만 가능
|
After (팀 동료 - 프로젝트 잘 앎)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| 질문: "@Codebase UserService 코드 리뷰해줘"
Cursor 답변:
"UserService.java를 분석했습니다:
[발견한 문제]
1. 38번째 줄 createUser() 메서드에서
- UserRepository는 이미 @Transactional이 있지만
- EmailService 호출 시 외부 API 실패가 롤백을 막을 수 있음
2. 65번째 줄 updateUser() 메서드에서
- OrderService의 updateUser()와 예외 처리 방식이 다름
- OrderService는 CustomException을 사용하는데
- UserService는 RuntimeException을 사용 중
3. SecurityConfig.java를 보니 BCrypt를 사용하는데
- 여기서는 평문으로 저장하고 있음
[개선 코드]
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final EmailService emailService;
private final PasswordEncoder passwordEncoder; // SecurityConfig와 일관성
@Transactional
public UserDto createUser(SignupRequest request) {
// 1. OrderService와 동일한 예외 처리 패턴
if (userRepository.existsByEmail(request.getEmail())) {
throw new CustomException(ErrorCode.DUPLICATE_EMAIL); // ✅ 통일
}
// 2. SecurityConfig의 BCrypt 사용
String encodedPassword = passwordEncoder.encode(request.getPassword());
User user = User.builder()
.email(request.getEmail())
.password(encodedPassword) // ✅ 암호화
.build();
User savedUser = userRepository.save(user);
// 3. 외부 API 호출은 트랜잭션 밖으로
CompletableFuture.runAsync(() -> {
emailService.sendWelcomeEmail(savedUser.getEmail());
});
return UserDto.from(savedUser);
}
}
"
장점:
✅ 실제 코드의 38번째 줄을 지적
✅ 다른 서비스(OrderService)와의 패턴 비교
✅ SecurityConfig의 설정 참고
✅ 프로젝트 전체 맥락을 고려한 구체적 개선안
|
시나리오 2: “에러 해결해줘”
Before (외부 컨설턴트)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| 질문: "LazyInitializationException 에러 해결해줘"
ChatGPT 답변:
"LazyInitializationException은 일반적으로 다음과 같이 해결합니다:
방법 1: @Transactional 추가
방법 2: FetchType.EAGER 사용
방법 3: fetch join 사용
어떤 방법을 선택할지는 상황에 따라 다릅니다."
문제점:
❌ 어디서 에러가 났는지 모름
❌ 프로젝트 구조를 모름
❌ 일반적인 해결책만 나열
❌ 내 프로젝트에 바로 적용할 수 없음
|
After (팀 동료)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
| 질문: "@Codebase LazyInitializationException 에러 해결해줘"
Cursor 답변:
"에러 발생 지점을 찾았습니다:
[문제 코드]
UserController.java 45번째 줄:
@GetMapping("/{id}")
public UserResponse getUser(@PathVariable Long id) {
User user = userService.findById(id);
return UserResponse.from(user); // ❌ 여기서 user.getOrders() 접근 시 에러
}
[원인]
UserService에서 User를 조회할 때 Order는 LAZY 로딩:
@Entity
public class User {
@OneToMany(fetch = FetchType.LAZY) // ← LAZY
private List<Order> orders;
}
그런데 UserResponse.from()에서 orders를 접근:
public static UserResponse from(User user) {
return UserResponse.builder()
.orders(user.getOrders()) // ❌ 트랜잭션 밖에서 접근!
.build();
}
[해결책 - 이 프로젝트에 맞춤]
OrderService를 보니 이미 fetch join을 사용 중입니다.
동일한 패턴으로 수정하세요:
// UserRepository.java (OrderRepository 패턴 참고)
@Query("SELECT u FROM User u LEFT JOIN FETCH u.orders WHERE u.id = :id")
Optional<User> findByIdWithOrders(@Param("id") Long id);
// UserService.java (OrderService 패턴 참고)
@Transactional(readOnly = true)
public User findById(Long id) {
return userRepository.findByIdWithOrders(id) // ✅ fetch join
.orElseThrow(() -> new UserNotFoundException());
}
이렇게 하면:
1. OrderService와 패턴 일관성 유지 ✅
2. N+1 문제도 해결 ✅
3. 트랜잭션 범위 명확 ✅
"
장점:
✅ 에러 발생 지점 정확히 지적 (45번째 줄)
✅ 다른 서비스(OrderService)의 해결 패턴 참고
✅ 프로젝트 구조에 맞는 구체적 코드 제시
✅ 바로 복사해서 쓸 수 있음
|
시나리오 3: “새 API 추가해줘”
Before (외부 컨설턴트)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| 질문: "상품 조회 API 만들어줘"
ChatGPT 답변:
@RestController
@RequestMapping("/api/products")
public class ProductController {
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return productService.findById(id);
}
}
문제점:
❌ 우리 프로젝트의 Response 형식 모름
❌ 예외 처리 방식 모름
❌ Swagger 설정 모름
❌ DTO 사용 여부 모름
|
After (팀 동료)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| 질문: "@Codebase 상품 조회 API 만들어줘"
Cursor 답변:
"UserController.java와 OrderController.java를 참고하여
동일한 패턴으로 작성했습니다:
// ProductController.java
@RestController
@RequestMapping("/api/products")
@Tag(name = "Product", description = "상품 관리 API")
@RequiredArgsConstructor
public class ProductController {
private final ProductService productService;
@GetMapping("/{id}")
@Operation(summary = "상품 조회", description = "ID로 상품을 조회합니다")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "404", description = "상품 없음")
})
public ResponseEntity<ApiResponse<ProductResponse>> getProduct(
@PathVariable Long id) {
ProductResponse product = productService.findById(id);
return ResponseEntity.ok(ApiResponse.success(product));
}
}
// ProductResponse.java (UserResponse 패턴 참고)
@Getter
@Builder
public class ProductResponse {
private Long id;
private String name;
private Integer price;
private Integer stockQuantity;
public static ProductResponse from(Product product) {
return ProductResponse.builder()
.id(product.getId())
.name(product.getName())
.price(product.getPrice())
.stockQuantity(product.getStockQuantity())
.build();
}
}
// ProductService.java (UserService 패턴 참고)
@Service
@RequiredArgsConstructor
public class ProductService {
private final ProductRepository productRepository;
@Transactional(readOnly = true)
public ProductResponse findById(Long id) {
Product product = productRepository.findById(id)
.orElseThrow(() -> new CustomException(ErrorCode.PRODUCT_NOT_FOUND));
return ProductResponse.from(product);
}
}
참고:
- Swagger 어노테이션: UserController와 동일
- 예외 처리: CustomException 사용 (팀 표준)
- Response 래핑: ApiResponse 사용 (팀 표준)
- DTO 패턴: from() 정적 팩토리 메서드 (팀 표준)
"
장점:
✅ UserController, OrderController 패턴 완벽 반영
✅ Swagger 설정 자동 포함
✅ 팀의 예외 처리 방식 사용
✅ Response 형식 일관성 유지
✅ 복사 붙여넣기만 하면 바로 동작
|
4. @Codebase 없을 때 vs 있을 때 비교 📊
import 없는 단일 파일 vs 전체 프로젝트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // @Codebase 없을 때 (import 없는 단일 파일)
public class UserService {
public void createUser(User user) {
// UserRepository가 뭔지 모름
// SecurityConfig가 뭔지 모름
// 다른 서비스의 패턴 모름
// 결과: 일반적인 구현만 가능
}
}
// @Codebase 있을 때 (전체 프로젝트 스캔)
import com.example.repository.UserRepository; // ✅ Repository 패턴 파악
import com.example.config.SecurityConfig; // ✅ 보안 설정 파악
import com.example.service.OrderService; // ✅ 다른 서비스 패턴 참고
import com.example.exception.CustomException; // ✅ 예외 처리 방식 파악
import com.example.dto.ApiResponse; // ✅ Response 형식 파악
public class UserService {
// 프로젝트 전체를 이해한 상태에서 구현
// ✅ 팀의 코딩 스타일 자동 반영
// ✅ 다른 서비스와 일관성 유지
// ✅ 프로젝트 구조에 맞는 코드
}
|
Spring의 빈 스캔과 비교
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| // ApplicationContext 없이 (수동 객체 생성)
public class ManualWiring {
public static void main(String[] args) {
UserRepository userRepo = new UserRepository();
UserService userService = new UserService(userRepo);
UserController controller = new UserController(userService);
// ❌ 의존성 파악 어려움
// ❌ 일일이 생성해야 함
// ❌ 순환 참조 발견 어려움
}
}
// ApplicationContext 사용 (@ComponentScan)
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(Application.class);
// ✅ 모든 Bean 자동 스캔
// ✅ 의존성 자동 주입
// ✅ 순환 참조 자동 감지
}
}
|
마찬가지로:
1
2
3
4
5
6
7
8
9
10
11
| // @Codebase 없이 (단일 파일만 인식)
"UserService 코드 작성해줘"
// AI: 이 파일만 보고 작성
// ❌ 다른 파일과의 관계 모름
// @Codebase 사용 (전체 프로젝트 스캔)
"@Codebase UserService 코드 작성해줘"
// AI: 프로젝트 전체를 스캔한 상태
// ✅ 다른 서비스들의 패턴 파악
// ✅ Config 파일들 참고
// ✅ Exception 처리 방식 통일
|
5. 실전 활용 팁 💡
Tip 1: 파일 단위로 좁히기
1
2
3
4
5
6
7
| // Bad: 너무 광범위
"@Codebase 코드 리팩토링해줘"
// → 프로젝트 전체를 보느라 시간 오래 걸림
// Good: 구체적으로
"@Codebase UserService.java를 OrderService.java 패턴으로 리팩토링해줘"
// → 두 파일만 집중 분석
|
Tip 2: 패턴 학습 요청
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| "@Codebase 이 프로젝트의 Controller 패턴을 분석하고,
새로운 ProductController를 같은 패턴으로 작성해줘"
Cursor:
"UserController, OrderController, PaymentController를 분석했습니다.
[공통 패턴]
1. Swagger @Tag, @Operation 사용
2. ResponseEntity<ApiResponse<T>> 반환
3. @Valid로 Validation
4. CustomException으로 에러 처리
[ProductController 작성]
..."
|
Tip 3: 버그 찾기
1
2
3
4
5
6
7
8
9
10
11
12
13
| "@Codebase UserService에서 발생할 수 있는
잠재적 버그를 찾고, OrderService와 비교해서 개선점을 제시해줘"
Cursor:
"UserService 분석 결과:
[발견한 문제]
1. 트랜잭션 범위 - OrderService는 세밀하게 조절하는데 UserService는 없음
2. 예외 처리 - OrderService는 CustomException, UserService는 RuntimeException
3. 로깅 - OrderService는 @Slf4j로 상세 로깅, UserService는 로깅 없음
[개선안]
..."
|
Tip 4: 테스트 코드 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
| "@Codebase UserServiceTest를 OrderServiceTest와 동일한 패턴으로 작성해줘"
Cursor:
"OrderServiceTest.java를 참고하여 작성했습니다:
[OrderServiceTest 패턴]
- given-when-then 구조
- @DisplayName으로 한글 설명
- MockBean 사용
- AssertJ 사용
[UserServiceTest]
..."
|
6. 언제 @Codebase를 사용해야 할까? 🎯
사용해야 하는 경우 ✅
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
| public class WhenToUseCodebase {
void scenario1() {
/*
* 1. 프로젝트 내 다른 코드와 일관성 필요
*
* "@Codebase 새로운 API 추가해줘"
* → 기존 API들의 패턴 자동 반영
*/
}
void scenario2() {
/*
* 2. 프로젝트 구조 파악 필요
*
* "@Codebase 이 에러가 왜 발생해?"
* → 전체 코드를 분석하여 원인 찾기
*/
}
void scenario3() {
/*
* 3. 기존 코드 리팩토링
*
* "@Codebase UserService를 개선해줘"
* → 다른 서비스들과 비교하여 개선
*/
}
void scenario4() {
/*
* 4. 프로젝트 전체 검색 필요
*
* "@Codebase JWT 토큰은 어디서 생성되고 검증돼?"
* → 관련 파일들을 모두 찾아서 설명
*/
}
}
|
사용 안 해도 되는 경우 ❌
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
| public class WhenNotToUseCodebase {
void scenario1() {
/*
* 1. 일반적인 개념 질문
*
* "JPA의 영속성 컨텍스트가 뭐야?"
* → 프로젝트 코드 필요 없음
*/
}
void scenario2() {
/*
* 2. 알고리즘 문제
*
* "이진 탐색 트리 구현해줘"
* → 독립적인 알고리즘
*/
}
void scenario3() {
/*
* 3. 새로운 프로젝트 시작
*
* "Spring Boot 프로젝트 초기 구조 잡아줘"
* → 아직 코드베이스 없음
*/
}
void scenario4() {
/*
* 4. 표준 라이브러리 사용법
*
* "Java Stream API 사용법 알려줘"
* → 공식 문서 기반 답변이 나음
*/
}
}
|
7. @Codebase의 한계와 보완 🚧
한계
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
43
44
45
| public class CodebaseLimitations {
void limitation1() {
/*
* 1. Context Window 제한
*
* 매우 큰 프로젝트(1000+ 파일)는
* 모든 파일을 한 번에 분석하기 어려움
*
* 해결: 파일 단위로 좁혀서 질문
*/
}
void limitation2() {
/*
* 2. 실시간 동기화 아님
*
* 코드 변경 후 즉시 반영 안될 수 있음
* (보통 수 초 ~ 수십 초)
*
* 해결: 중요한 변경 후 잠시 대기
*/
}
void limitation3() {
/*
* 3. 숨겨진 파일 제외
*
* .gitignore에 포함된 파일은 스캔 안됨
* (node_modules, build, .env 등)
*
* 해결: 필요시 명시적으로 파일 열기
*/
}
void limitation4() {
/*
* 4. 외부 의존성 한계
*
* 외부 라이브러리 내부 구현은 모름
*
* 해결: 공식 문서와 병행
*/
}
}
|
보완 방법
1
2
3
4
5
6
7
8
9
10
11
12
| // 1. 좁은 범위로 질문
"@Codebase 전체 프로젝트 분석해줘" ❌
"@Codebase UserService와 OrderService 비교해줘" ✅
// 2. 구체적인 파일 지정
"@Codebase 어디서 에러날까?" ❌
"@Codebase UserController 45번째 줄 에러 원인 찾아줘" ✅
// 3. 단계적 접근
1단계: "@Codebase 프로젝트 구조 설명해줘"
2단계: "@Codebase Controller 레이어 패턴 분석해줘"
3단계: "@Codebase UserController 개선해줘"
|
8. 정리: @Codebase는 팀 동료다 👥
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
| /**
* @Codebase의 본질
*/
public class CodebaseEssence {
/*
* ChatGPT = 외부 컨설턴트
* - 일반론적 조언
* - 프로젝트 맥락 모름
* - 표준 패턴만 제시
*
* Cursor + @Codebase = 우리 팀 시니어 개발자
* - 프로젝트 전체 이해
* - 팀 코딩 스타일 파악
* - 다른 서비스와 일관성 유지
* - 구체적이고 실행 가능한 코드
*/
@ComponentScan // Spring의 자동 스캔
@Codebase // Cursor의 자동 스캔
public void conclusion() {
/*
* @ComponentScan이 Bean을 스캔하듯
* @Codebase는 코드를 스캔한다
*
* @Autowired로 의존성을 주입하듯
* @Codebase로 컨텍스트를 주입한다
*
* ApplicationContext가 Bean을 관리하듯
* @Codebase는 코드 맥락을 관리한다
*/
}
}
|
핵심 정리:
@Codebase = Project Context Injection- Spring의
@ComponentScan과 유사- Bean 자동 스캔 vs 코드 자동 스캔
- 의존성 주입 vs 컨텍스트 주입
- RAG + Vector Search 기반
- 외부 컨설턴트 → 팀 동료로
- 일반론 → 프로젝트 맞춤형 답변
- 추상적 → 구체적 (라인 번호까지)
@Codebase를 활용하면 AI가 진짜 우리 팀 개발자처럼 일합니다! 🚀
참고 자료
- Cursor AI Documentation: https://docs.cursor.sh/
- RAG (Retrieval-Augmented Generation): https://arxiv.org/abs/2005.11401
- Vector Database Explained: https://www.pinecone.io/learn/vector-database/
- Spring Framework @ComponentScan: https://docs.spring.io/spring-framework/reference/core/beans/classpath-scanning.html