์๋ ํ์ธ์ dev_writer์ ๋๋ค.
์ด๋ฒ ์๊ฐ์๋ Spring AI ๊ณต์ ๋ฌธ์ ์ค Chat Models์ Image Models์ ๋ํด ๋ฒ์ญํ ๋ด์ฉ์ ์ ๋ฌํด ๋๋ฆฌ๊ฒ ์ต๋๋ค.
Chat Models
Chat Model API๋ ๊ฐ๋ฐ์๊ฐ AI ๊ธฐ๋ฐ์ ์ฑํ ์์ฑ ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ํตํฉํ ์ ์๋๋ก ์ง์ํฉ๋๋ค. ์ด API๋ GPT (Generative Pre-trained Transformer)์ ๊ฐ์ ์ฌ์ ํ์ต๋ ์ธ์ด ๋ชจ๋ธ์ ํ์ฉํ์ฌ, ์ฌ์ฉ์ ์ ๋ ฅ์ ๋ํด ์์ฐ์ด๋ก ์ธ๊ฐ๊ณผ ์ ์ฌํ ์๋ต์ ์์ฑํฉ๋๋ค.
์ด API๋ ์ผ๋ฐ์ ์ผ๋ก ํ๋กฌํํธ ๋๋ ๋ํ์ ์ผ๋ถ๋ฅผ AI ๋ชจ๋ธ์ ์ ์กํ๋ฉด, ๋ชจ๋ธ์ด ํ์ต๋ ๋ฐ์ดํฐ์ ์์ฐ์ด ํจํด์ ๋ํ ์ดํด๋ฅผ ๋ฐํ์ผ๋ก ๋ํ๋ฅผ ์ด์ด๋๊ฐ๊ฑฐ๋ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค. ์์ฑ๋ ์๋ต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐํ๋๋ฉฐ, ์ด๋ฅผ ์ฌ์ฉ์์๊ฒ ํ์ํ๊ฑฐ๋ ์ถ๊ฐ ์ฒ๋ฆฌ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Spring AI์ Chat Model API๋ ๋ค์ํ AI ๋ชจ๋ธ๊ณผ์ ์ํธ์์ฉ์ ์ํ ๋จ์ํ๊ณ ์ด์ ๊ฐ๋ฅํ ์ธํฐํ์ด์ค๋ก ์ค๊ณ๋์์ต๋๋ค. ์ด๋ฌํ ์ค๊ณ๋ Spring์ ๋ชจ๋ํ ๋ฐ ๊ต์ฒด ๊ฐ๋ฅ์ฑ์ด๋ผ๋ ์ฒ ํ๊ณผ ์ผ์นํ๋ฉฐ, ๊ฐ๋ฐ์๊ฐ ์ต์ํ์ ์ฝ๋ ๋ณ๊ฒฝ๋ง์ผ๋ก ์๋ก ๋ค๋ฅธ AI ๋ชจ๋ธ ๊ฐ ์ ํ์ด ๊ฐ๋ฅํ๋๋ก ํฉ๋๋ค.
๋ํ, ์ ๋ ฅ์ ์บก์ํํ๋ Prompt ํด๋์ค์ ์ถ๋ ฅ์ ์ฒ๋ฆฌํ๋ ChatResponse์ ๊ฐ์ ๋ณด์กฐ ํด๋์ค์ ๋์์ ๋ฐ์, Chat Model API๋ AI ๋ชจ๋ธ๊ณผ์ ํต์ ์ ํตํฉ๋ ๋ฐฉ์์ผ๋ก ์ ๊ณตํฉ๋๋ค. ์ด๋ก ์ธํด ์์ฒญ ์ค๋น ๋ฐ ์๋ต ํ์ฑ์ ๋ณต์ก์ฑ์ ๊ด๋ฆฌํ๋ฉฐ, ๊ฐ๋ฐ์์๊ฒ ์ง๊ด์ ์ด๊ณ ๋จ์ํ๋ API ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
๊ตฌํ ๊ฐ๋ฅํ ๋ชจ๋ธ ๋ชฉ๋ก์ ์ด์ฉ ๊ฐ๋ฅํ ๊ตฌํ์ฒด ์น์ ์์, ๊ทธ๋ฆฌ๊ณ ๊ฐ ๋ชจ๋ธ์ ๋ํ ์์ธํ ๋น๊ต๋ Chat Models Comparison ์น์ ์์ ํ์ธํ ์ ์์ต๋๋ค.
API ๊ฐ์
์ด ์น์ ์ Spring AI Chat Model API ์ธํฐํ์ด์ค์ ๊ด๋ จ ํด๋์ค๋ค์ ๋ํ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
ChatModel
๋ค์์ ChatModel ์ธํฐํ์ด์ค์ ์ ์์ ๋๋ค.
public interface ChatModel extends Model<Prompt, ChatResponse> {
default String call(String message) {...}
@Override
ChatResponse call(Prompt prompt);
}
String ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ call() ๋ฉ์๋๋ ์ด๊ธฐ ์ฌ์ฉ์ ๊ฐ์ํํ๋ฉฐ, ๋ณด๋ค ์ ๊ตํ Prompt ๋ฐ ChatResponse ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ๋ณต์ก์ฑ์ ํผํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ Prompt ์ธ์คํด์ค๋ฅผ ์ ๋ฌํ๊ณ ChatResponse๋ฅผ ๋ฐํํ๋ call() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ ์ผ๋ฐ์ ์ ๋๋ค.
StreamingChatModel
๋ค์์ StreamingChatModel ์ธํฐํ์ด์ค์ ์ ์์ ๋๋ค.
public interface StreamingChatModel extends StreamingModel<Prompt, ChatResponse> {
default Flux<String> stream(String message) {...}
@Override
Flux<ChatResponse> stream(Prompt prompt);
}
stream() ๋ฉ์๋๋ ChatModel๊ณผ ์ ์ฌํ๊ฒ String ๋๋ Prompt ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ์๋ค์ด์ง๋ง, ์๋ต์ ๋ฆฌ์กํฐ๋ธ Flux API๋ฅผ ํตํด ์คํธ๋ฆฌ๋ฐ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
Prompt
Prompt๋ ํ๋์ ModelRequest๋ก, ์ฌ๋ฌ ๊ฐ์ Message ๊ฐ์ฒด์ ์ ํ์ ์ธ ๋ชจ๋ธ ์์ฒญ ์ต์ ์ ์บก์ํํฉ๋๋ค.
๋ค์ ์์๋ Prompt ํด๋์ค์ ์์ฑ์ ๋ฐ ๊ธฐํ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ฅผ ์ ์ธํ ์ถ์ฝ๋ ๋ฒ์ ์ ๋ณด์ฌ์ค๋๋ค.
public class Prompt implements ModelRequest<List<Message>> {
private final List<Message> messages;
private ChatOptions modelOptions;
@Override
public ChatOptions getOptions() {...}
@Override
public List<Message> getInstructions() {...}
// ์์ฑ์ ๋ฐ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ ์๋ต
}
Message
Message ์ธํฐํ์ด์ค๋ Prompt์ ํ ์คํธ ์ฝํ ์ธ , ๋ฉํ๋ฐ์ดํฐ ์์ฑ์ ์ปฌ๋ ์ , ๊ทธ๋ฆฌ๊ณ MessageType์ด๋ผ๊ณ ๋ถ๋ฆฌ๋ ๋ถ๋ฅ ์ ๋ณด๋ฅผ ์บก์ํํฉ๋๋ค. ํด๋น ์ธํฐํ์ด์ค๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ฉ๋๋ค.
public interface Content {
String getText();
Map<String, Object> getMetadata();
}
public interface Message extends Content {
MessageType getMessageType();
}
๋ฉํฐ ๋ชจ๋ฌ ๋ฉ์์ง ํ์ ์ MediaContent ์ธํฐํ์ด์ค๋ ๊ตฌํํ๋ฉฐ, ์ฌ๋ฌ ๊ฐ์ Media ์ฝํ ์ธ ๊ฐ์ฒด ๋ชฉ๋ก์ ์ ๊ณตํฉ๋๋ค.
public interface MediaContent extends Content {
Collection<Media> getMedia();
}
Message ์ธํฐํ์ด์ค๋ AI ๋ชจ๋ธ์ด ์ฒ๋ฆฌํ ์ ์๋ ๋ฉ์์ง์ ์นดํ ๊ณ ๋ฆฌ์ ๋ฐ๋ผ ๋ค์ํ ๊ตฌํ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
Chat Completion ์๋ํฌ์ธํธ๋ ๋ํ์์์ ์ญํ ์ ๋ฐ๋ผ ๋ฉ์์ง ์ ํ์ ๊ตฌ๋ถํ๋ฉฐ, ์ด๋ MessageType์ ํตํด ํจ๊ณผ์ ์ผ๋ก ๋งคํ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, OpenAI๋ ์์คํ (system), ์ฌ์ฉ์(user), ํจ์(function), ์ด์์คํดํธ(assistant)์ ๊ฐ์ ํน์ ๋ํ ์ญํ ์ ๋ฐ๋ฅธ ๋ฉ์์ง ์ ํ์ ์ธ์ํฉ๋๋ค.
MessageType์ด๋ผ๋ ์ฉ์ด๋ ํน์ ๋ฉ์์ง ํฌ๋งท์ ์๋ฏธํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ง๋ง, ์ด ๋ฌธ๋งฅ์์๋ ๋ํ์์ ํด๋น ๋ฉ์์ง๊ฐ ์ํํ๋ ์ญํ ์ ๋ํ๋ ๋๋ค.
ํน์ ์ญํ ์ ์ฌ์ฉํ์ง ์๋ AI ๋ชจ๋ธ์ ๊ฒฝ์ฐ, UserMessage ๊ตฌํ์ฒด๊ฐ ํ์ค ๋ฉ์์ง ์ ํ์ผ๋ก ์๋ํ๋ฉฐ, ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ ฅ๋ ์ง๋ฌธ์ด๋ ๋ช ๋ น์ ๋ํ๋ ๋๋ค.
์ด๋ฌํ ์ญํ ๋๋ ๋ฉ์์ง ์ ํ์ ๋งฅ๋ฝ์์ Prompt์ Message ๊ฐ์ ๊ด๊ณ ๋ฐ ์ค์ง์ ์ธ ์ ์ฉ ๋ฐฉ์์ ๋ํด์๋ Prompts ์น์ ์์ ์์ธํ ์ค๋ช ํ๊ณ ์์ต๋๋ค.
ChatOptions
AI ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์๋ ์ต์ ๋ค์ ๋ํ๋ด๋ ํด๋์ค์ ๋๋ค. ChatOptions ํด๋์ค๋ ModelOptions์ ํ์ ํด๋์ค์ด๋ฉฐ, AI ๋ชจ๋ธ์ ์ ๋ฌ ๊ฐ๋ฅํ ๋ช ๊ฐ์ง ์ด์ ๊ฐ๋ฅํ (portable) ์ต์ ๋ค์ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
ChatOptions ํด๋์ค๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ฉ๋๋ค.
public interface ChatOptions extends ModelOptions {
String getModel();
Float getFrequencyPenalty();
Integer getMaxTokens();
Float getPresencePenalty();
List<String> getStopSequences();
Float getTemperature();
Integer getTopK();
Float getTopP();
ChatOptions copy();
}
๋ํ, ๊ฐ AI ๋ชจ๋ธ์ ํนํ๋ ChatModel ๋๋ StreamingChatModel ๊ตฌํ์ฒด๋ ๋ชจ๋ธ ๊ณ ์ ์ ์ต์ ๋ค์ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ด๋ฅผ AI ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, OpenAI Chat Completion ๋ชจ๋ธ์ logitBias, seed, user์ ๊ฐ์ ๊ณ ์ ์ต์ ๋ค์ ์ ๊ณตํฉ๋๋ค.
์ด๋ฌํ ๊ธฐ๋ฅ์ ๊ฐ๋ฐ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ๋ชจ๋ธ๋ณ ์ต์ ์ ์ค์ ํ๊ณ , ์คํ ์ค์๋ Prompt ์์ฒญ์ ํตํด ๋์ ์ผ๋ก ๋ฎ์ด์ธ ์ ์๊ฒ ํด ์ฃผ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค.
Spring AI๋ Chat Model์ ๊ตฌ์ฑํ๊ณ ํ์ฉํ๊ธฐ ์ํ ์ ๊ตํ ์์คํ ์ ์ ๊ณตํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ๊ธฐ๋ณธ ๊ตฌ์ฑ์ ์ค์ ํ ์ ์์ ๋ฟ ์๋๋ผ, ์์ฒญ ๋จ์๋ก ์ด ์ค์ ๋ค์ ์ ์ฐํ๊ฒ ์ฌ์ ์ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ ๊ทผ ๋ฐฉ์์ ๊ฐ๋ฐ์๊ฐ ๋ค์ํ AI ๋ชจ๋ธ๊ณผ ์์ฝ๊ฒ ์ฐ๋ํ๊ณ , ํ์์ ๋ฐ๋ผ ํ๋ผ๋ฏธํฐ๋ฅผ ์กฐ์ ํ ์ ์๋๋ก ํ๋ฉฐ, ์ด ๋ชจ๋ ๊ณผ์ ์ Spring AI ํ๋ ์์ํฌ์ ์ผ๊ด๋ ์ธํฐํ์ด์ค ๋ด์์ ์ฒ๋ฆฌํ ์ ์๊ฒ ํฉ๋๋ค.
์๋์ ํ๋ก์ฐ ๋ค์ด์ด๊ทธ๋จ์ Spring AI๊ฐ Chat Model์ ์ค์ ๋ฐ ์คํ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง๋ฅผ ์๊ฐ์ ์ผ๋ก ์ค๋ช ํ๋ฉฐ, ์์ ์ ์ค์ ๊ณผ ์คํ ์ค ์ต์ ์ ์ด๋ป๊ฒ ๊ฒฐํฉํ๋์ง๋ฅผ ๋ณด์ฌ์ค๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ์ค์ (Start-up Configuration): ChatModel ๋๋ StreamingChatModel์ "์์ ์ (Start-Up)" ์ฑํ ์ต์ ์ผ๋ก ์ด๊ธฐํ๋ฉ๋๋ค. ์ด๋ฌํ ์ต์ ์ ChatModel ์ด๊ธฐํ ์์ ์ค์ ๋๋ฉฐ, ๊ธฐ๋ณธ ๊ตฌ์ฑ๊ฐ์ ์ ๊ณตํ๊ธฐ ์ํ ๋ชฉ์ ์ ๋๋ค.
- ์คํ ์ ์ค์ (Runtime Configuration): ๊ฐ ์์ฒญ๋ง๋ค Prompt ๊ฐ์ฒด์ ์คํ ์ (Runtime) ์ฑํ ์ต์ ์ ํฌํจ์ํฌ ์ ์์ผ๋ฉฐ, ์ด ์ต์ ๋ค์ ์์ ์ ์ค์ ๋ ๊ฐ์ ์ฌ์ ์ (override)ํ ์ ์์ต๋๋ค.
- ์ต์ ๋ณํฉ ๊ณผ์ (Option Merging Process): "Merge Options" ๋จ๊ณ์์๋ ์์ ์ ์ค์ ๊ณผ ์คํ ์ ์ค์ ์ ๋ณํฉํฉ๋๋ค. ์คํ ์ ์ต์ ์ด ์ ๊ณต๋๋ฉด, ์์ ์ ์ต์ ๋ณด๋ค ์ฐ์ ์ ์ฉ๋ฉ๋๋ค.
- ์ ๋ ฅ ์ฒ๋ฆฌ (Input Processing): "Convert Input" ๋จ๊ณ์์๋ ์ ๋ ฅ๋ ์ง์์ฌํญ (instructions)์ ๋ชจ๋ธ ๊ณ ์ ์ ํ์์ผ๋ก ๋ณํํฉ๋๋ค.
- ์ถ๋ ฅ ์ฒ๋ฆฌ (Output Processing): "Convert Output" ๋จ๊ณ์์๋ AI ๋ชจ๋ธ์ ์๋ต์ ํ์คํ๋ ChatResponse ํ์์ผ๋ก ๋ณํํฉ๋๋ค.
์์ ์ ์ต์ ๊ณผ ์คํ ์ ์ต์ ์ ๋ถ๋ฆฌํจ์ผ๋ก์จ, ์ ์ญ ์ค์ (Global Configuration)๊ณผ ์์ฒญ ๋จ์์ ์ธ๋ถ ์กฐ์ (Request-specific Customization)์ ๋์์ ์ ์ฐํ๊ฒ ์ง์ํ ์ ์์ต๋๋ค.
ChatResponse
ChatResponse ํด๋์ค์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public class ChatResponse implements ModelResponse<Generation> {
private final ChatResponseMetadata chatResponseMetadata;
private final List<Generation> generations;
@Override
public ChatResponseMetadata getMetadata() {...}
@Override
public List<Generation> getResults() {...}
// ๋ค๋ฅธ ๋ฉ์๋๋ค์ ์๋ต
}
ChatResponse ํด๋์ค๋ AI ๋ชจ๋ธ์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ ํ๋ฉฐ, ๊ฐ Generation ์ธ์คํด์ค๋ ํ๋์ ํ๋กฌํํธ์ ๋ํด ์์ฑ๋ ํ๋ ์ด์์ ์ถ๋ ฅ ์ค ํ๋๋ฅผ ๋ํ๋ ๋๋ค. ๋ํ, ChatResponse ํด๋์ค๋ AI ๋ชจ๋ธ์ ์๋ต์ ๋ํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ChatResponseMetadata ๊ฐ์ฒด๋ ํจ๊ป ํฌํจํ๊ณ ์์ต๋๋ค.
Generation
๋ง์ง๋ง์ผ๋ก, Generation ํด๋์ค๋ ModelResult๋ฅผ ์์ํ์ฌ ๋ชจ๋ธ์ ์ถ๋ ฅ(assistant ๋ฉ์์ง) ๋ฐ ๊ด๋ จ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ ๋๋ค.
public class Generation implements ModelResult<AssistantMessage> {
private final AssistantMessage assistantMessage;
private ChatGenerationMetadata chatGenerationMetadata;
@Override
public AssistantMessage getOutput() {...}
@Override
public ChatGenerationMetadata getMetadata() {...}
// ๋ค๋ฅธ ๋ฉ์๋๋ค์ ์๋ต
}
์ด์ฉ ๊ฐ๋ฅํ ๊ตฌํ์ฒด
์ด ๋ค์ด์ด๊ทธ๋จ์ ChatModel๊ณผ StreamingChatModel์ด๋ผ๋ ํตํฉ ์ธํฐํ์ด์ค๊ฐ ๋ค์ํ AI ์ ๊ณต์ ์ฒด์ ์ฑํ ๋ชจ๋ธ๊ณผ ์ํธ์์ฉํ๋ ๋ฐ ์ฌ์ฉ๋จ์ ๋ณด์ฌ์ค๋๋ค. ์ด๋ฅผ ํตํด ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์์๋ ์ผ๊ด๋ API๋ฅผ ์ ์งํ๋ฉด์๋, ์๋ก ๋ค๋ฅธ AI ์๋น์ค ๊ฐ์ ์์ฌ์ด ํตํฉ ๋ฐ ์ ํ์ด ๊ฐ๋ฅํด์ง๋๋ค.
- OpenAI Chat Completion (์คํธ๋ฆฌ๋ฐ, ๋ฉํฐ ๋ชจ๋ฌ & ํจ์ ํธ์ถ ์ง์)
- Microsoft Azure Open AI Chat Completion (์คํธ๋ฆฌ๋ฐ & ํจ์ ํธ์ถ ์ง์)
- Ollama Chat Completion (์คํธ๋ฆฌ๋ฐ, ๋ฉํฐ ๋ชจ๋ฌ & ํจ์ ํธ์ถ ์ง์)
- Hugging Face Chat Completion (์คํธ๋ฆฌ๋ฐ ์ง์ X)
- Google Vertex AI Gemini Chat Completion (์คํธ๋ฆฌ๋ฐ, ๋ฉํฐ ๋ชจ๋ฌ & ํจ์ ํธ์ถ ์ง์)
- Amazon Bedrock
- Mistral AI Chat Completion (์คํธ๋ฆฌ๋ฐ & ํจ์ ํธ์ถ ์ง์)
- Anthropic Chat Model (์คํธ๋ฆฌ๋ฐ & ํจ์ ํธ์ถ ์ง์)
ํ
์ฑํ ๋ชจ๋ธ ๋น๊ต ์น์ ์์ ์ฌ์ฉ ๊ฐ๋ฅํ ์ฑํ ๋ชจ๋ธ์ ๋ํ ์์ธํ ๋น๊ต๋ฅผ ์ฐพ์๋ณด์ธ์.
Chat Model API
Spring AI Chat Model API๋ Spring AI์ Generic Model API ์์ ๊ตฌ์ถ๋์ด ์์ผ๋ฉฐ, ์ฑํ ๊ธฐ๋ฅ์ ํนํ๋ ์ถ์ํ ๋ฐ ๊ตฌํ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
์ด๋ก ์ธํด ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ผ๊ด๋ API๋ฅผ ์ ์งํ๋ฉด์๋ ๋ค์ํ AI ์๋น์ค ๊ฐ์ ํตํฉ ๋ฐ ์ ํ์ ์์ฝ๊ฒ ์ํํ ์ ์์ต๋๋ค.
Image Models
Spring Image Model API๋ ์ด๋ฏธ์ง ์์ฑ์ ํนํ๋ ๋ค์ํ AI ๋ชจ๋ธ๋ค๊ณผ ์ํธ์์ฉํ๊ธฐ ์ํ ๋จ์ํ๊ณ ์ด์ ๊ฐ๋ฅํ ์ธํฐํ์ด์ค๋ก ์ค๊ณ๋์์ต๋๋ค.
์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ์ต์ํ์ ์ฝ๋ ๋ณ๊ฒฝ๋ง์ผ๋ก ์๋ก ๋ค๋ฅธ ์ด๋ฏธ์ง ๊ด๋ จ ๋ชจ๋ธ ๊ฐ์ ์ ํํ ์ ์์ผ๋ฉฐ, ์ด๋ฌํ ์ค๊ณ๋ Spring์ ๋ชจ๋ํ (Modularity) ๋ฐ ๊ต์ฒด ๊ฐ๋ฅ์ฑ (Interchangeability) ์ฒ ํ๊ณผ ๋ถํฉํฉ๋๋ค. ์ฆ, ์ด๋ฏธ์ง ์ฒ๋ฆฌ์ ๊ด๋ จ๋ ๋ค์ํ AI ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋น ๋ฅด๊ฒ ์ ์์ํฌ ์ ์๋๋ก ์ง์ํฉ๋๋ค.
๋ํ, ImagePrompt (์ ๋ ฅ ์บก์ํ์ฉ), ImageResponse (์ถ๋ ฅ ์ฒ๋ฆฌ์ฉ)์ ๊ฐ์ ๋ณด์กฐ ํด๋์ค์ ์ง์์ ํตํด, Image Model API๋ ์ด๋ฏธ์ง ์์ฑ ์ ์ฉ AI ๋ชจ๋ธ๋ค๊ณผ์ ํต์ ์ ํตํฉ๋ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
์์ฒญ ์ค๋น ๋ฐ ์๋ต ํ์ฑ์ ๋ณต์ก์ฑ์ ๊ฐ์ถ๊ณ , ์ง๊ด์ ์ด๊ณ ๊ฐ๋จํ API ๊ธฐ๋ฐ์ ์ด๋ฏธ์ง ์์ฑ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
Spring Image Model API๋ Spring AI Generic Model API ์์ ๊ตฌ์ถ๋์ด ์์ผ๋ฉฐ, ์ด๋ฏธ์ง ์ ์ฉ ๊ธฐ๋ฅ์ ์ํ ์ถ์ํ ๋ฐ ๊ตฌํ์ฒด๋ฅผ ์ ๊ณตํฉ๋๋ค.
API ๊ฐ์
์ด ์น์ ์์๋ Spring Image Model API ์ธํฐํ์ด์ค ๋ฐ ๊ด๋ จ ํด๋์ค์ ๋ํ ๊ฐ์ด๋๋ฅผ ์ ๊ณตํฉ๋๋ค.
Image Model
์๋๋ ImageModel ์ธํฐํ์ด์ค์ ์ ์์ ๋๋ค.
@FunctionalInterface
public interface ImageModel extends Model<ImagePrompt, ImageResponse> {
ImageResponse call(ImagePrompt request);
}
ImagePrompt
ImagePrompt๋ ์ฌ๋ฌ ๊ฐ์ ImageMessage ๊ฐ์ฒด์ ์ ํ์ ์ธ ๋ชจ๋ธ ์์ฒญ ์ต์ ๋ค์ ์บก์ํํ๋ ModelRequest์ ๋๋ค. ๋ค์ ์์๋ ์์ฑ์ ๋ฐ ๊ธฐํ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ฅผ ์ ์ธํ ImagePrompt ํด๋์ค์ ์ถ์ฝ๋ ๋ฒ์ ์ ๋ณด์ฌ์ค๋๋ค.
public class ImagePrompt implements ModelRequest<List<ImageMessage>> {
private final List<ImageMessage> messages;
private ImageOptions imageModelOptions;
@Override
public List<ImageMessage> getInstructions() {...}
@Override
public ImageOptions getOptions() {...}
// ์์ฑ์ ๋ฐ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ ์๋ต
}
ImageMessage
ImageMessage ํด๋์ค๋ ์ด๋ฏธ์ง ์์ฑ์ ์ฌ์ฉ๋ ํ ์คํธ์, ๊ทธ ํ ์คํธ๊ฐ "์์ฑ ์ด๋ฏธ์ง์ ๋ฏธ์น๋ ์ํฅ๋ ฅ(๊ฐ์ค์น)"์ ์บก์ํํฉ๋๋ค. ๊ฐ์ค์น๋ฅผ ์ง์ํ๋ ๋ชจ๋ธ์ ๊ฒฝ์ฐ, ์ด ๊ฐ์ ์์ ๋๋ ์์๋ก ์ค์ ๋ ์ ์์ต๋๋ค.
public class ImageMessage {
private String text;
private Float weight;
public String getText() {...}
public Float getWeight() {...}
// ์์ฑ์ ๋ฐ ์ ํธ๋ฆฌํฐ ๋ฉ์๋๋ ์๋ต
}
ImageOptions
์ด๋ฏธ์ง ์์ฑ ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์๋ ์ต์ ๋ค์ ๋ํ๋ด๋ ์ธํฐํ์ด์ค์ ๋๋ค. ImageOptions ์ธํฐํ์ด์ค๋ ModelOptions ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ๋ฉฐ, AI ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์๋ ์ผ๋ถ ์ด์ ๊ฐ๋ฅํ (portable) ์ต์ ๋ค์ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
ImageOptions ์ธํฐํ์ด์ค๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋ฉ๋๋ค.
public interface ImageOptions extends ModelOptions {
Integer getN();
String getModel();
Integer getWidth();
Integer getHeight();
String getResponseFormat(); // openai: url ๋๋ base64, stability ai: byte[] ๋๋ base64
}
๋ํ, ๊ฐ AI ๋ชจ๋ธ์ ํนํ๋ ImageModel ๊ตฌํ์ฒด๋ ๋ชจ๋ธ ๊ณ ์ ์ ์ต์ ๋ค์ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ์ด๋ฌํ ์ต์ ๋ค์ AI ๋ชจ๋ธ์ ์ ๋ฌํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, OpenAI์ ์ด๋ฏธ์ง ์์ฑ ๋ชจ๋ธ์ quality, style ๋ฑ๊ณผ ๊ฐ์ ๊ณ ์ ์ต์ ๋ค์ ์ ๊ณตํฉ๋๋ค.
์ด ๊ธฐ๋ฅ์ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ ๋ชจ๋ธ ๋ณ ์ต์ ์ ์ค์ ํ๊ณ , ์คํ ์ค์๋ ImagePrompt๋ฅผ ํตํด ํด๋น ์ต์ ๋ค์ ๋์ ์ผ๋ก ์ฌ์ ์(override) ํ ์ ์๋๋ก ์ง์ํ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ ๋๋ค.
ImageResponse
ImageResponse ํด๋์ค์ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public class ImageResponse implements ModelResponse<ImageGeneration> {
private final ImageResponseMetadata imageResponseMetadata;
private final List<ImageGeneration> imageGenerations;
@Override
public ImageGeneration getResult() {
// ์ฒซ ๋ฒ์งธ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ ธ์ด
}
@Override
public List<ImageGeneration> getResults() {...}
@Override
public ImageResponseMetadata getMetadata() {...}
// ๋ค๋ฅธ ๋ฉ์๋๋ค์ ์๋ต
}
ImageResponse ํด๋์ค๋ AI ๋ชจ๋ธ์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง๋ฉฐ, ๊ฐ ImageGeneration ์ธ์คํด์ค๋ ํ๋์ ํ๋กฌํํธ๋ก๋ถํฐ ์์ฑ๋ ๋ณต์์ ์ถ๋ ฅ ์ค ํ๋๋ฅผ ๋ํ๋ ๋๋ค.
๋ํ, ImageResponse ํด๋์ค๋ AI ๋ชจ๋ธ ์๋ต์ ๋ํ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ด๊ณ ์๋ ImageResponseMetadata ๊ฐ์ฒด๋ ํฌํจํ๊ณ ์์ต๋๋ค.
ImageGeneration
๋ง์ง๋ง์ผ๋ก ImageGeneration ํด๋์ค๋ ModelResult์์ ํ์ฅ๋์ด ์ด ๊ฒฐ๊ณผ์ ๋ํ ์ถ๋ ฅ ์๋ต ๋ฐ ๊ด๋ จ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ํ๋ ๋๋ค.
public class ImageGeneration implements ModelResult<Image> {
private ImageGenerationMetadata imageGenerationMetadata;
private Image image;
@Override
public Image getOutput() {...}
@Override
public ImageGenerationMetadata getMetadata() {...}
// ๋ค๋ฅธ ๋ฉ์๋๋ค์ ์๋ต
}
์ด์ฉ ๊ฐ๋ฅํ ๊ตฌํ์ฒด
ImageModel ๊ตฌํ์ ๋ค์ ๋ชจ๋ธ ๊ณต๊ธ์๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.
- OpenAI Image Generation
- Azure OpenAI Image Generation
- QianFan Image Generation
- StabilityAI Image Generation
- ZhiPuAI Image Generation
API ๋ฌธ์
์ฌ๊ธฐ์์ Javadoc์ ๋ณผ ์ ์์ต๋๋ค.
Reference
'๐ ๊ณต์ ๋ฌธ์ ๋ฒ์ญ > Spring AI (2025 Renewal)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring AI 2025 Renewal #6] Chat Memory (0) | 2025.05.17 |
---|---|
[Spring AI 2025 Renewal #5] Embedding Models & Audio Models & Moderation Models (0) | 2025.05.17 |
[Spring AI 2025 Renewal #3] Advisors API (0) | 2025.04.06 |
[Spring AI 2025 Renewal #2] Chat Client API (0) | 2025.04.04 |
[Spring AI 2025 Renewal #1] Spring AI๋ ๋ฌด์์ธ๊ฐ? (0) | 2025.04.04 |