Solon 4.0 ChatModel: LLM 기반 애플리케이션 구축을 위한 실무 가이드
요약
Solon 4.0의 ChatModel을 사용하여 Java 애플리케이션에 LLM을 통합하는 방법을 설명하는 실무 가이드입니다. 빌더 지향 API를 통해 스트리밍, 함수 호출, 세션 관리 등 복잡한 상용구 코드를 추상화하여 제공합니다.
핵심 포인트
- ChatModel을 통한 LLM 호출 및 스트리밍 처리 추상화
- OpenAI, Anthropic, Ollama 등 다양한 모델과의 방언 적응 지원
- 도구 호출(Function Calling) 및 대화 메모리 기능 제공
- YAML 설정 및 프로그래밍 방식의 빌더를 통한 간편한 구성
Solon 4.0 ChatModel: LLM 기반 애플리케이션 구축을 위한 실무 가이드
저자: Solon Framework Community
대상: dev.to 게시 (@solonjava)
태그:#java#ai#tutorial#opensource
Java 애플리케이션에 대규모 언어 모델 (LLM)을 통합하려고 시도해 본 적이 있다면, 아마도 HTTP 클라이언트, JSON 파싱, 스트리밍 처리, 세션 관리와 같은 수많은 상용구 코드(boilerplate)를 작성했을 것입니다. Solon 4.0의 ChatModel은 깔끔한 빌더 지향 API(builder-oriented API)를 통해 이 모든 것을 추상화합니다.
이 가이드에서는 단순한 채팅 호출부터 대화 메모리(conversation memory)를 갖춘 스트리밍 챗봇에 이르기까지, ChatModel을 사용하여 실제로 작동하는 AI 기능을 구축하는 과정을 살펴보겠습니다.
1. ChatModel이란 무엇인가?
ChatModel (패키지 org.noear.solon.ai.chat)은 Solon의 AI 생태계 내에서 통합된 LLM 클라이언트입니다. 서로 다른 모델 제공업체를 위해 생으로 된 HTTP 호출을 작성하는 대신, 다음과 같은 기능을 지원하는 단일 API를 사용합니다:
- 동기 호출 (Synchronous calls) — 단일 요청, 전체 응답
- 스트리밍 호출 (Streaming calls) — Project Reactor (
Flux<ChatResponse>)를 통한 반응형 스트리밍 - 도구/함수 호출 (Tool/Function Calling) — LLM이 사용자의 Java 메서드를 호출하도록 허용
- 채팅 세션 (Chat Sessions) — 자동 대화 메모리
- 멀티모달 메시지 (Multi-modal messages) — 텍스트, 이미지, 오디오
- 방언 적응 (Dialect adaptation) — OpenAI, Ollama, Anthropic, Gemini, DashScope 등과 연동
가장 좋은 점은 무엇일까요? 이 모델은 **방언 패턴 (dialect pattern)**을 사용한다는 것입니다. 호환 가능한 모든 LLM 엔드포인트(endpoint)를 지정하기만 하면 자동으로 적응합니다.
2. 설정하기
pom.xml에 의존성(dependency)을 추가하세요 (부모 POM은 필요하지 않습니다 — Solon은 독립적으로 작동합니다):
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-ai</artifactId>
...
이를 통해 모든 내장 방언(OpenAI, Ollama, Gemini, Anthropic, DashScope)이 포함됩니다.
3. 구성 (Configuration)
3.1 YAML을 통한 구성 (권장)
solon.ai.chat:
demo:
apiUrl: "http://127.0.0.1:11434/api/chat" # baseUrl이 아닌 전체 URL
...
그 다음, 즉시 사용 가능한 ChatModel을 가져오기 위해 @Bean을 생성합니다:
import org.noear.solon.ai.chat.ChatConfig;
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.annotation.Bean;
...
3.2 프로그래밍 방식의 빌더 (Programmatic Builder)
설정보다 코드를 선호하시나요? 빌더를 직접 사용하세요:
@Bean
public ChatModel chatModel() {
return ChatModel.of("http://127.0.0.1:11434/api/chat")
...
3.3 지원되는 모델 제공자 (Supported Model Providers)
standard (또는 provider) 필드를 통해 방언 (dialect)을 선택합니다:
| Standard | Example apiUrl | Models |
|---|---|---|
openai (기본값) | https://api.openai.com/v1/chat/completions | GPT, DeepSeek, Qwen, GLM, Kimi 등 |
| ... |
4. 동기 호출 (Synchronous Calls - 간단한 방법)
가장 기본적인 사용 사례 — 프롬프트 (prompt)를 보내고 전체 응답을 받습니다:
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.ChatResponse;
import org.noear.solon.annotation.Inject;
...
이것으로 끝입니다. 단 세 줄의 비즈니스 로직이면 충분합니다.
5. 스트리밍 호출 (Streaming Calls - 실시간 응답)
챗봇과 어시스턴트의 경우, 스트리밍 (streaming)은 필수적입니다. ChatModel은 Reactor의 Flux<ChatResponse>를 반환합니다:
import reactor.core.publisher.Flux;
public Flux<String> askStream(String question) throws IOException {
...
import org.noear.solon.web.sse.SseEvent;
import org.noear.solon.annotation.Mapping;
import reactor.core.publisher.Flux;
...
스트리밍 프로토콜은 제공자 (provider)에 따라 표준 SSE (text/event-stream) 또는 x-ndjson을 사용합니다.
6. ChatSession을 이용한 대화 메모리 (Conversation Memory)
LLM은 상태가 없습니다 (stateless). 대화 문맥 (context)을 유지하려면 각 요청마다 히스토리 (history)를 전달해야 합니다. ChatSession은 이를 자동으로 처리합니다.
6.1 기본적인 세션 사용법 (Basic Session Usage)
import org.noear.solon.ai.chat.ChatSession;
import org.noear.solon.ai.chat.session.InMemoryChatSession;
...
6.2 사용자별 세션을 이용한 웹 채팅 (Web Chat with Per-User Sessions)
실제 웹 애플리케이션에서는 사용자당 하나의 세션이 필요할 것입니다. 정확히 그 역할을 수행하는 컨트롤러(controller) 예시입니다:
import org.noear.solon.annotation.Controller;
import org.noear.solon.web.sse.SseEvent;
import reactor.core.publisher.Flux;
...
6.3 내장 세션 구현체 (Built-in Session Implementations)
| 구현체 (Implementation) | 저장소 (Storage) | 사용 사례 (Use Case) |
|---|---|---|
InMemoryChatSession | 로컬 맵 (Local Map) | 개발 (Dev), 단일 노드 (single-node) |
| ... |
7. ChatOptions를 이용한 미세 조정 (Fine-Tuning with ChatOptions)
ChatOptions를 사용하여 요청(request)마다 모델의 동작을 제어할 수 있습니다:
chatModel.prompt("Java에 관한 시를 써줘")
.options(o -> o
.temperature(0.8)
...
일반적인 옵션은 다음과 같습니다:
| 메서드 (Method) | 설명 (Description) |
|---|---|
temperature(val) | 샘플링 온도 (Sampling temperature) (0.0–2.0) |
| ... |
8. 다중 메시지 프롬프트 (Multi-Message Prompts)
때로는 단순한 문자열 이상의 것이 필요할 수 있습니다. Prompt와 ChatMessage를 사용하세요:
import org.noear.solon.ai.chat.Prompt;
import org.noear.solon.ai.chat.message.ChatMessage;
...
9. 종합 예제: 실무 적용 (Putting It All Together: A Practical Example)
실제 프로젝트에서 볼 수 있는 RAG-lite 패턴인 간단한 **지식 인지형 챗봇 (knowledge-aware chatbot)**을 구축해 보겠습니다. 이 예제는 ChatMessage.ofUserAugment()를 사용하여 프롬프트에 컨텍스트(context)를 주입합니다:
import org.noear.solon.ai.chat.ChatModel;
import org.noear.solon.ai.chat.ChatResponse;
import org.noear.solon.ai.chat.message.ChatMessage;
...
사용자 입력을 컨텍스트로 보강(augment)한 다음 모델을 호출하는 이 패턴은 Solon AI에서 RAG (검색 증강 생성, Retrieval-Augmented Generation)의 기초가 됩니다.
10. 다음 단계는? (What's Next?)
ChatModel은 시작점일 뿐입니다. Solon AI는 다음과 같은 기능도 제공합니다:
- 도구 호출 (Tool Calling) — LLM이 호출할 수 있는
@ToolMapping메서드 정의 - 탤런트 시스템 (Talent System) — 재사용 가능한 능력 모듈 (Skill과 유사)
- 에이전트 (Agents) — 다단계 추론을 위한
ReActAgent및TeamAgent - RAG — 문서 로딩, 분할 (splitting), 임베딩 (embedding) 및 검색 (retrieval)을 포함한 전체 파이프라인
- MCP 프로토콜 (MCP Protocol) — 외부 도구를 위한 MCP 서버 연결
전체 문서는 공식 Solon AI 가이드를 확인하세요:
👉 https://solon.noear.org/article/918 (모델 구축 (Model construction))
👉 https://solon.noear.org/article/920 (API 레퍼런스 (API reference))
Java에서 LLM (Large Language Model)을 통합해 보셨나요? 가장 큰 어려움은 무엇인가요? 댓글로 알려주세요 — 다음 포스트에서 다룰 수도 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기