Spring AIとOpenAIを使用したチャットアプリケーション実装
はじめに
この記事では、Spring AIとOpenAIのAPIを使用して、シンプルなチャットアプリケーションを実装する方法を説明します。Spring AIを使用することで、OpenAIのAPIを簡単に統合し、効率的なチャット機能を実装することができます。
1. プロジェクトのセットアップ
依存関係の追加
まず、build.gradle
ファイルに必要な依存関係を追加します:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
}
アプリケーションの設定
application.properties
ファイルにOpenAIのAPIキーを設定します:
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.model=gpt-3.5-turbo
spring.ai.openai.temperature=0.7
2. チャットアプリケーションの実装
チャットメッセージのモデル
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatMessage {
private String role;
private String content;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatRequest {
private String message;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ChatResponse {
private String response;
}
チャットサービスの実装
@Service
@Slf4j
public class ChatService {
private final ChatClient chatClient;
public ChatService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public ChatResponse chat(ChatRequest request) {
try {
String response = chatClient.prompt(request.getMessage())
.call()
.content();
return new ChatResponse(response);
} catch (Exception e) {
log.error("チャット処理中にエラーが発生しました", e);
throw new RuntimeException("チャット処理に失敗しました", e);
}
}
}
コントローラーの実装
@RestController
@RequestMapping("/api/chat")
@Slf4j
public class ChatController {
private final ChatService chatService;
public ChatController(ChatService chatService) {
this.chatService = chatService;
}
@PostMapping
public ResponseEntity<ChatResponse> chat(@RequestBody ChatRequest request) {
log.info("チャットリクエスト受信: {}", request.getMessage());
ChatResponse response = chatService.chat(request);
return ResponseEntity.ok(response);
}
}
3. 高度な機能の実装
会話履歴の保持
@Service
@Slf4j
public class ChatHistoryService {
private final Map<String, List<ChatMessage>> conversationHistory = new ConcurrentHashMap<>();
public void addMessage(String sessionId, ChatMessage message) {
conversationHistory.computeIfAbsent(sessionId, k -> new ArrayList<>())
.add(message);
}
public List<ChatMessage> getHistory(String sessionId) {
return conversationHistory.getOrDefault(sessionId, new ArrayList<>());
}
}
ストリーミングレスポンスの実装
@Service
@Slf4j
public class StreamingChatService {
private final ChatClient chatClient;
public StreamingChatService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public Flux<String> streamChat(String message) {
return chatClient.prompt(message)
.stream()
.map(response -> response.getResult().getOutput().getContent());
}
}
@RestController
@RequestMapping("/api/chat")
public class StreamingChatController {
private final StreamingChatService streamingChatService;
@PostMapping("/stream")
public Flux<String> streamChat(@RequestBody ChatRequest request) {
return streamingChatService.streamChat(request.getMessage());
}
}
4. エラーハンドリング
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception e) {
log.error("予期せぬエラーが発生しました", e);
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(new ErrorResponse("エラーが発生しました", e.getMessage()));
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ErrorResponse {
private String message;
private String details;
}
5. 使用例
cURLを使用したAPI呼び出し
curl -X POST http://localhost:8080/api/chat \
-H "Content-Type: application/json" \
-d '{"message": "こんにちは、自己紹介をしてください"}'
ストリーミングAPIの呼び出し
curl -X POST http://localhost:8080/api/chat/stream \
-H "Content-Type: application/json" \
-d '{"message": "長い文章を生成してください"}'
6. セキュリティ考慮事項
-
APIキーの保護
- 環境変数での管理
- 本番環境での適切な認証情報管理
-
レート制限の実装
@Service public class RateLimiter { private final Map<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>(); private static final int MAX_REQUESTS_PER_MINUTE = 60; public boolean isAllowed(String userId) { AtomicInteger count = requestCounts.computeIfAbsent(userId, k -> new AtomicInteger(0)); return count.incrementAndGet() <= MAX_REQUESTS_PER_MINUTE; } }
まとめ
この記事では、Spring AIとOpenAIを使用したチャットアプリケーションの基本的な実装方法を説明しました。実装した機能は以下の通りです:
- 基本的なチャット機能
- 会話履歴の保持
- ストリーミングレスポンス
- エラーハンドリング
- レート制限
これらの機能を組み合わせることで、実用的なチャットアプリケーションを構築することができます。