Google GenAI SDK for Java โ
TL;DR โ
- 2026๋ 6์ 24์ผ Vertex AI์ Generative AI ๋ชจ๋ ์ง์ ์ข ๋ฃ
- Vertex AI SDK๋ Google GenAI SDK (Preview)๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ์
- Spring AI ์์ Google GenAI SDK ์์ ํตํฉ ์ง์
- Gemini API ํค๋ Google AI Studio์์ ๋ฐ๊ธ
Google Gen AI Java SDK โ
// implementation("com.google.cloud:google-cloud-vertexai:1.40.0") // Deprecated
implementation("com.google.genai:google-genai:1.30.0")๋ฐฑ์๋ ์๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ Gemini API ๋ฅผ ์ฐ๋ํ๋ ค๊ณ ํ ๋๋ Vertex AI SDK ๋ณด๋ค๋ Google Gen AI Java SDK๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์์. Vertex AI SDK๋ ์์ผ๋ก ์ง์ ์ข ๋ฃ๋ ์์ ์ด๋ฏ๋ก ์ถ์ฒํ์ง ์์ต๋๋ค. ์์ ๊ฐ์ด Gen AI SDK์ ๋ํ ์์กด์ฑ์ build.gradle ์ ์ถ๊ฐํด์ฃผ์ธ์.
Streaming content generation โ
๊ณต์ ์์ ์ฝ๋๋ ๊นํ๋ธ ๋ฆฌํ์งํ ๋ฆฌ์ examples ํด๋์์ ์ฐธ๊ณ ํ ์ ์์ด์. ์ ๋ models.streamGenerateContent๋ฅผ ์ฌ์ฉํด์ ์ฌ์ฉ์์๊ฒ AI ์๋ต์ ์ค์๊ฐ์ผ๋ก ์ ๋ฌํ๋ ์์ ๋ฅผ ์์ฑํด๋ณผ๊ฒ์.
@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamGenAI(@RequestBody PromptRequest request) {
Content content = Content.builder()
.parts(Part.builder().text(request.getPrompt()).build())
.build();
GenerateContentConfig generateContentConfig = GenerateContentConfig.builder()
.systemInstruction(Content.builder()
.parts(Part.builder().text("๋ฐ๋์ ํ๊ตญ์ด๋ก ๋ต๋ณํฉ๋๋ค.").build())
.build())
.build();
Client client = Client.builder().build();
ResponseStream<GenerateContentResponse> generateContentResponses = client.models.generateContentStream(request.getModel(), List.of(content), generateContentConfig);
return Flux.fromIterable(generateContentResponses)
.map(response -> {
log.info("{} -> {}", response.text(), response.finishReason());
return response.text();
});
}FinishReason์ด STOP์ด๋ฉด ์๋ต์ด ๋๋ฌ๋ค๋ ์๋ฏธ์์!
๊ทธ๋ฆฌ๊ณ ๋ถ๋ถ ์๋ต์ด ์ฌ๋์๋ FINISH_REASON_UNSPECIFIED ์ ๋๋ค.
์ stream ์๋ํฌ์ธํธ์ ์๋ต์ text/event-stream;charset=UTF-8 ์ด์์. ์ด stream ์์ฒญ์ ํ๋ก ํธ์๋์์๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํด์ผํ ๊น์? ๋ธ๋ผ์ฐ์ ์์ SSE(Server-Sent-Event)๋ ์ผ๋ฐ์ ์ผ๋ก EventSource API๋ฅผ ์ฌ์ฉํ๋๋ฐ Fetch ๋๋ Axios ๋ก๋ ์ด๋ฒคํธ ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ ์ ์์ด์.
import axios from 'axios';
async function streamGenAI() {
try {
const response = await axios.post('http://localhost:8080/api/genai/stream',
{ prompt: '์๋
ํ์ธ์! ๊ฐ๋จํ ์ธ์ฌ๋ง์ ํด์ฃผ์ธ์.' },
{
headers: {
'Content-Type': 'application/json',
'Accept': 'text/event-stream'
},
responseType: 'stream'
}
);
// ์คํธ๋ฆผ ๋ฐ์ดํฐ ์ฒ๋ฆฌ
response.data.on('data', (chunk) => {
const text = chunk.toString();
console.log('๋ฐ์ ์ฒญํฌ:', text);
});
response.data.on('end', () => {
console.log('์คํธ๋ฆฌ๋ฐ ์๋ฃ');
});
response.data.on('error', (error) => {
console.error('์คํธ๋ฆฌ๋ฐ ์ค๋ฅ:', error);
});
} catch (error) {
console.error('์์ฒญ ์คํจ:', error.message);
}
}Axios ์์๋ responseType์ stream์ผ๋ก ์ค์ ํ๋ฉด ๋ฉ๋๋ค.
Spring AI - Google GenAI Chat โ
implementation(platform("org.springframework.ai:spring-ai-bom:1.0.0"))
implementation("org.springframework.ai:spring-ai-openai")
implementation("org.springframework.ai:spring-ai-starter-model-google-genai")์ต์ ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ๋ผ๋ฉด Spring AI ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ๋ฉด Gemini API๋ฅผ ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์์ง๋ง ์ค๋ฌด์์ ๋ค๋ฃจ๋ ์คํ๋ง ๋ถํธ ํ๋ก์ ํธ ๋ฒ์ ์ด ๋ฎ์ผ๋ฉด Google GenAI SDK๋ฅผ ์ง์ ์ฌ์ฉํด์ ์ฝ๋๋ฅผ ์์ฑํด์ผํด์. ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ SDK๋ฅผ ํ์ฉํ๋ฉด WebClient๋ฅผ ์ฌ์ฉํด์ ์ง์ HTTP ํต์ ์ ์ํํ๋ ๊ฒ๋ณด๋ค๋ ๊ตฌํ ๊ณผ์ ์์์ ์ค์๋ฅผ ์ค์ผ ์ ์์ด์.
๊ฐ์ฌํฉ๋๋ค.