Spring BootでChatGLM3-6bモデルを統合する方法

この記事では、Spring BootアプリケーションでChatGLM3-6bモデルと連携する方法について説明します。他のモデルとの接続方法も同様に応用できます。

モデルパラメータの確認

ここでは、アリクラウドから提供された文書に基づいて、モデルパラメータを設定します。HTTPリクエストを使用して非SDK方式でAPIを呼び出します。

以下のサンプルリクエストを見ていきます:


curl --location 'https://example.com/api/v1/services/aigc/text-generation' \
--header 'Authorization: Bearer <YOUR-API-KEY>' \
--header 'Content-Type: application/json' \
--header 'X-SSE-Enable: true' \
--data '{
    "model": "chatglm3-6b",
    "input": {
        "messages": [
            {
                "role": "user",
                "content": "こんにちは、東京タワーについて教えてください"
            }
        ]
    },
    "parameters": {
        "result_format": "message"
    }
}'

コード実装

1. レスポンスクラスの作成

レスポンスデータをデシリアライズするためのJavaクラスを作成します。


import lombok.Data;

@Data
public class ChatResponse {
    private Output output;
    private Usage usage;
    private String requestId;

    @Data
    public static class Output {
        private Choice[] choices;

        @Data
        public static class Choice {
            private Message message;
            private String finishReason;

            @Data
            public static class Message {
                private String content;
                private String role;
            }
        }
    }

    @Data
    public static class Usage {
        private int totalTokens;
        private int inputTokens;
        private int outputTokens;
    }
}

2. イベントリスナーの作成

イベントリスナーを定義し、SSE(サーバーサイドイベント)の受信処理を行います。


import com.alibaba.fastjson.JSONObject;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SSEEventListener extends EventSourceListener {
    private static final Logger logger = LoggerFactory.getLogger(SSEEventListener.class);
    private String clientId;

    @Override
    public void onEvent(EventSource eventSource, String id, String type, String data) {
        logger.info("SSEEventListener onEvent invoke");
        ChatResponse response = JSONObject.parseObject(data, ChatResponse.class);
        for (ChatResponse.Output.Choice choice : response.getOutput().choices) {
            if ("stop".equals(choice.finishReason)) {
                eventSource.cancel();
                logger.info("Stream completed.");
                return;
            }
            logger.info("Message: {}", choice.message.content);
        }
    }
}

3. APIコントローラの作成

Spring BootのコントローラでAPIを定義します。


import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

@RestController
@RequestMapping("/api/chat")
public class ChatController {

    @PostMapping("/send")
    public SseEmitter sendMessage(@RequestParam String user, @RequestParam String text) {
        SseEmitter emitter = new SseEmitter();
        OkHttpClient client = new OkHttpClient();

        // JSONオブジェクトの作成
        JSONObject payload = new JSONObject();
        payload.put("model", "chatglm3-6b");
        payload.put("input", new JSONObject().put("messages", 
            new JSONArray().add(new JSONObject()
                .put("role", "user")
                .put("content", text)
            )
        ));
        payload.put("parameters", new JSONObject().put("result_format", "message"));

        RequestBody body = RequestBody.create(MediaType.parse("application/json"), payload.toJSONString());

        Request request = new Request.Builder()
                .url("https://example.com/api/v1/services/aigc/text-generation")
                .post(body)
                .addHeader("Authorization", "Bearer YOUR_API_KEY")
                .addHeader("Content-Type", "application/json")
                .addHeader("X-SSE-Enable", "true")
                .build();

        EventSource.Factory factory = EventSources.createFactory(client);
        EventSource.Listener listener = new SSEEventListener();
        EventSource eventSource = factory.newEventSource(request, listener);
        eventSource.request();

        return emitter;
    }
}

4. フロントエンドの実装

簡単なHTMLとJavaScriptを使用してフロントエンドを構築します。


<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>SSEチャット</title>
</head>
<body>
<h1>チャット</h1>
<div id="chat-area"></div>
<form id="message-form">
    <input type="text" id="message-input" placeholder="メッセージを入力">
    <button type="submit">送信</button>
</form>
<script>
const chatArea = document.getElementById('chat-area');
const form = document.getElementById('message-form');
const input = document.getElementById('message-input');

form.addEventListener('submit', function(event) {
    event.preventDefault();
    const msg = input.value.trim();
    if (msg) {
        fetch('/api/chat/send?user=test&text=' + encodeURIComponent(msg), { method: 'POST' })
            .then(response => response.text())
            .then(data => displayMessage(data))
            .catch(error => console.error('Error:', error));
        input.value = '';
    }
});

function displayMessage(message) {
    const div = document.createElement('div');
    div.textContent = message;
    chatArea.appendChild(div);
}
</script>
</body>
</html>

タグ: Spring Boot ChatGLM3-6b OkHttp SSE JSON

7月26日 16:03 投稿