Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .env.default
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ MYSQL_PASSWORD=

# AI 서비스 설정
AI_OPENAI_API_KEY=
AI_HUGGINGFACE_API_KEY=

# 벡터 데이터베이스 설정
PINECONE_API_KEY=
PINECONE_INDEX_NAME=

# 이메일 인증
GMAIL_SENDER_EMAIL=
Expand All @@ -25,10 +20,16 @@ AWS_S3_BUCKET=
# Unsplash API
UNSPLASH_ACCESS_KEY=

# Pixabay API
PIXABAY_ACCESS_KEY=

# Google Custom Search API
GOOGLE_API_KEY=
GOOGLE_CX_ID=

# Google Cloud 인증 (Base64 인코딩된 JSON)
GOOGLE_CLOUD_CREDENTIALS_JSON=

# OAuth2
KAKAO_CLIENT_ID=
NAVER_CLIENT_ID=
Expand Down
3 changes: 0 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,6 @@ dependencies {
// Spring AI
implementation(platform("org.springframework.ai:spring-ai-bom:1.1.0"))
implementation("org.springframework.ai:spring-ai-starter-model-openai")
implementation("org.springframework.ai:spring-ai-starter-model-huggingface")
// Vector DB
implementation("org.springframework.ai:spring-ai-starter-vector-store-pinecone")
// Spring WebFlux (WebClient)
implementation("org.springframework.boot:spring-boot-starter-webflux")
// QueryDSL
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.back.domain.ai.ai.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.huggingface.HuggingfaceChatModel;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Expand All @@ -14,8 +13,4 @@ public ChatClient openAiChatClient(OpenAiChatModel chatModel) {
return ChatClient.create(chatModel);
}

@Bean
public ChatClient huggingfaceChatClient(HuggingfaceChatModel chatModel) {
return ChatClient.create(chatModel);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.back.domain.ai.ai.dto.AiGenerateRequest;
import com.back.domain.ai.ai.service.AiChatService;
import com.back.domain.ai.ai.service.AiGenerateService;
import com.back.domain.ai.ai.service.AiIndexService;
import com.back.domain.ai.ai.util.AiChatHttpUtil;
import com.back.domain.ai.model.exception.ModelUsageExceededException;
import com.back.domain.ai.model.service.ModelUsageService;
Expand Down Expand Up @@ -34,7 +33,6 @@
@Tag(name = "AI API", description = "AI 관련 API")
public class ApiV1AiController {
private final AiGenerateService aiGenerateService;
private final AiIndexService aiIndexService;
private final AiChatService aiChatService;
private final ModelUsageService modelUsageService;

Expand Down

This file was deleted.

62 changes: 0 additions & 62 deletions src/main/java/com/back/domain/ai/ai/service/AiChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.document.Document;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class AiChatService {
private final ChatClient openAiChatClient;
private final VectorStore vectorStore;

private static final String SYSTEM_DETAIL_PROMPT = """
* 전문적이면서도 친근한 톤을 유지합니다.
Expand Down Expand Up @@ -114,59 +107,4 @@ private OpenAiChatOptions buildOptions(AiModel model) {

return optionBuilder.build();
}

/**
* RAG 기반으로 사용자 질문에 답변합니다.
*/
public String chatWithRag(Integer id, String message) {
List<Document> similarDocuments = searchRelevantDocuments(id, message);

String context = similarDocuments.stream()
.map(Document::getText)
.collect(Collectors.joining("\n---\n"));

SystemMessage systemMessage = SystemMessage.builder()
.text(AiGenerateService.SYSTEM_BASE_PROMPT)
.text(SYSTEM_DETAIL_PROMPT)
.build();

PromptTemplate promptTemplate = PromptTemplate.builder()
.template("""
[Context]를 바탕으로 [질문]에 답변하세요.

[질문]
{message}

[Context]
{context}
""")
.build();

UserMessage userMessage = UserMessage.builder()
.text(
promptTemplate.render(Map.of(
"message", message,
"context", context
))
)
.build();

return openAiChatClient.prompt()
.messages(
systemMessage,
userMessage
)
.call()
.content();
}

private List<Document> searchRelevantDocuments(Integer blogId, String query) {
SearchRequest searchRequest = SearchRequest.builder()
.query(query)
.topK(3)
.filterExpression("blogId == %d".formatted(blogId))
.build();

return vectorStore.similaritySearch(searchRequest);
}
}
48 changes: 0 additions & 48 deletions src/main/java/com/back/domain/ai/ai/service/AiIndexService.java

This file was deleted.

Loading