Skip to content

Commit dd975d0

Browse files
authored
Merge pull request #92 from prgrms-web-devcourse-final-project/feat/mission
fix : gemini -> grok으로 변경
2 parents 2a5e4f6 + a6da5d6 commit dd975d0

File tree

5 files changed

+52
-57
lines changed

5 files changed

+52
-57
lines changed

backend/build.gradle.kts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ plugins {
33
id("org.springframework.boot") version "3.5.5"
44
id("io.spring.dependency-management") version "1.1.7"
55
}
6-
val springAiVersion by extra("1.0.2")
6+
val springAiVersion by extra("1.0.0-M6")
77

88
group = "com"
99
version = "0.0.1-SNAPSHOT"
@@ -17,6 +17,7 @@ java {
1717

1818
repositories {
1919
mavenCentral()
20+
2021
}
2122

2223
dependencies {
@@ -25,7 +26,6 @@ dependencies {
2526
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
2627
implementation("org.springframework.boot:spring-boot-starter-web")
2728
implementation("org.springframework.boot:spring-boot-starter-validation")
28-
implementation("org.springframework.ai:spring-ai-starter-model-vertex-ai-gemini")
2929
developmentOnly("org.springframework.boot:spring-boot-devtools")
3030

3131
runtimeOnly("com.h2database:h2")
@@ -50,19 +50,21 @@ dependencies {
5050
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")
5151

5252
implementation("org.springframework.boot:spring-boot-starter-websocket")
53-
5453
implementation ("org.springframework.kafka:spring-kafka")
5554

5655

57-
// 1. Spring AI의 모든 모듈 버전을 일관되게 관리하는 BOM (필수)
58-
implementation(enforcedPlatform("org.springframework.ai:spring-ai-bom:$springAiVersion"))
59-
// 2. Vertex AI Gemini 모델 스타터
60-
// implementation("org.springframework.ai:spring-ai-vertex-ai-gemini-spring-boot-starter")
56+
// Spring AI 의존성
57+
implementation("org.springframework.ai:spring-ai-core")
58+
implementation("org.springframework.ai:spring-ai-openai-spring-boot-starter")
6159

60+
implementation("org.springframework.boot:spring-boot-starter-webflux")
61+
implementation("org.springframework.retry:spring-retry")
62+
implementation("org.springframework.boot:spring-boot-starter-aop")
6263
}
64+
6365
dependencyManagement {
6466
imports {
65-
mavenBom("org.springframework.ai:spring-ai-bom:$springAiVersion")
67+
mavenBom("org.springframework.ai:spring-ai-bom:${property("springAiVersion")}")
6668
}
6769
}
6870

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,19 @@
11
package com.back;
22

3-
import com.google.auth.oauth2.GoogleCredentials;
4-
import jakarta.annotation.PostConstruct;
5-
import org.springframework.beans.factory.annotation.Value;
63
import org.springframework.boot.SpringApplication;
74
import org.springframework.boot.autoconfigure.SpringBootApplication;
85
import org.springframework.cache.annotation.EnableCaching;
96
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
107
import org.springframework.scheduling.annotation.EnableAsync;
118

12-
import java.io.FileInputStream;
13-
import java.nio.file.Path;
14-
import java.nio.file.Paths;
15-
169
@SpringBootApplication
1710
@EnableJpaAuditing
1811
@EnableCaching
1912
@EnableAsync
2013
public class BackApplication {
21-
@Value("${GOOGLE_APPLICATION_CREDENTIALS}")
22-
private String googleCredentialsPath;
2314

2415
public static void main(String[] args) {
2516
SpringApplication.run(BackApplication.class, args);
2617
}
2718

28-
@PostConstruct
29-
public void setGoogleCredentialsEnv() {
30-
Path path = Paths.get(googleCredentialsPath).toAbsolutePath();
31-
System.setProperty("GOOGLE_APPLICATION_CREDENTIALS", path.toString());
32-
System.out.println("*** Google credentials path set to: " + path);
33-
34-
try (FileInputStream serviceAccountStream = new FileInputStream(path.toFile())) {
35-
GoogleCredentials credentials = GoogleCredentials.fromStream(serviceAccountStream);
36-
37-
System.out.println("*** Google credentials loaded successfully!");
38-
System.out.println("*** Credentials type: " + credentials.getClass().getSimpleName());
39-
} catch (Exception e) {
40-
System.err.println("*** Failed to load Google credentials: " + e.getMessage());
41-
}
42-
}
43-
4419
}

backend/src/main/java/com/back/domain/mission/service/AiMissionGeneratorService.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
package com.back.domain.mission.service;
22

3+
import com.back.domain.member.entity.Member;
4+
import com.back.domain.member.repository.MemberRepository;
35
import com.back.domain.mission.dto.ai.AiMissionResult;
46
import lombok.RequiredArgsConstructor;
5-
import org.springframework.stereotype.Service;
67
import org.springframework.ai.chat.client.ChatClient;
8+
import org.springframework.ai.chat.prompt.Prompt;
9+
import org.springframework.stereotype.Service;
10+
11+
import java.time.LocalDate;
12+
import java.time.Period;
713

814

915
@Service
@@ -68,37 +74,50 @@ private String getDayName(int dayNum) {
6874
}*/
6975

7076
private final ChatClient chatClient;
77+
private final MemberRepository memberRepository;
7178

7279
public AiMissionResult generateMission(String rawGoal, int weeks, Integer memberId) {
73-
String prompt = """
80+
81+
Member member = memberRepository.findById(memberId)
82+
.orElseThrow(() -> new RuntimeException("회원이 존재하지 않습니다."));
83+
84+
int age = Period.between(member.getBirth(), LocalDate.now()).getYears();
85+
String gender = member.getGender().name(); // "MALE", "FEMALE", "NONE"
86+
87+
88+
String promptText = """
7489
너는 미션 플래너야.
7590
사용자가 목표와 기간을 입력하면 반드시 아래 JSON 구조를 채워서 출력해라.
76-
설명은 하지 말고 JSON만 반환해라
77-
그리고 제목은 간결하게 정리해서 반환해줘
91+
설명은 하지 말고 JSON만 반환해라.
92+
그리고 제목은 간결하게 정리해서 반환해줘.
93+
그리고 나이나 성별을 고려할 수 있다면 고려해서 만들어줘.
7894
7995
JSON 형식:
80-
{
96+
{{
8197
"goal": "짧고 간결한 목표 문장",
8298
"category": "EXERCISE | HABIT | MENTAL | LEARNING | CUSTOM",
8399
"weeklyPlans": [
84-
{
100+
{{
85101
"weekNum": 1,
86102
"title": "1주차: 주차별 목표",
87103
"dailyTasks": [
88-
{ "dayNum": 1, "title": "Day1 활동" },
89-
{ "dayNum": 2, "title": "Day2 활동" }
104+
{{ "dayNum": 1, "title": "Day1 활동" }},
105+
{{ "dayNum": 2, "title": "Day2 활동" }}
90106
]
91-
}
107+
}}
92108
]
93-
}
109+
}}
94110
95111
사용자 입력:
96112
목표: %s
97113
기간: %d주
98-
""".formatted(rawGoal, weeks);
114+
나이 : %d세
115+
성별 : %s
116+
""".formatted(rawGoal, weeks, age, gender);
117+
118+
Prompt prompt = new Prompt(promptText);
99119

100-
return chatClient.prompt()
101-
.user(prompt) // ✅ 이렇게 써야 함
120+
return chatClient.prompt(prompt)
102121
.call()
103122
.entity(AiMissionResult.class);
104123
}

backend/src/main/java/com/back/global/config/ChatClientConfig.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public class ChatClientConfig {
99

1010
@Bean
1111
public ChatClient chatClient(ChatClient.Builder chatClientBuilder) {
12-
return chatClientBuilder.build();
12+
return chatClientBuilder
13+
.defaultSystem("You are a mission planner that generates structured JSON responses.")
14+
.build();
1315
}
1416
}

backend/src/main/resources/application.yml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,13 @@ spring:
3434
highlight_sql: true
3535
use_sql_comments: true
3636
ai:
37-
vertex:
38-
ai:
39-
gemini:
40-
project-id: ${VERTEX_PROJECT_ID}
41-
location: "us-central1"
42-
chat:
43-
options:
44-
model: "gemini-2.5-flash"
37+
openai:
38+
api-key: ${OPENROUTER_API_KEY}
39+
base-url: https://openrouter.ai/api
40+
chat:
41+
options:
42+
model: x-ai/grok-4-fast:free
43+
4544
security:
4645
oauth2:
4746
client:
@@ -105,8 +104,6 @@ management:
105104
enabled: true # /actuator/health/{liveness,readiness} 활성화
106105
show-details: never # 프로브 용도면 never 권장(민감정보 차단)
107106
custom:
108-
google:
109-
credentials: ${GOOGLE_APPLICATION_CREDENTIALS}
110107
dev:
111108
cookieDomain: localhost
112109
frontUrl: http://${custom.dev.cookieDomain}:3000

0 commit comments

Comments
 (0)