[Developer] #424 use GPT 5.4 mini for VPD explanations
This commit is contained in:
@@ -2,6 +2,7 @@ package com.cloudhandson.vpdbackoffice.domain.vpd;
|
||||
|
||||
public record VpdPolicyExplanation(
|
||||
String status,
|
||||
String modelName,
|
||||
String answer,
|
||||
String prompt,
|
||||
VpdPolicyDetail detail,
|
||||
|
||||
@@ -41,6 +41,11 @@ public class OpenAiCompatibleClient {
|
||||
&& hasText(ai.apiKey());
|
||||
}
|
||||
|
||||
public String modelName() {
|
||||
BackofficeProperties.Ai ai = properties.ai();
|
||||
return ai == null ? "" : ai.model();
|
||||
}
|
||||
|
||||
public String chat(String systemPrompt, String userPrompt) {
|
||||
if (!configured()) {
|
||||
throw new AppException("AI 호출 설정이 없습니다.");
|
||||
@@ -50,7 +55,11 @@ public class OpenAiCompatibleClient {
|
||||
ObjectNode request = objectMapper.createObjectNode();
|
||||
request.put("model", ai.model());
|
||||
request.put("temperature", 0.1);
|
||||
request.put("max_tokens", 1200);
|
||||
if (usesCompletionTokenLimit(ai.model())) {
|
||||
request.put("max_completion_tokens", 1200);
|
||||
} else {
|
||||
request.put("max_tokens", 1200);
|
||||
}
|
||||
ArrayNode messages = request.putArray("messages");
|
||||
messages.add(message("system", systemPrompt));
|
||||
messages.add(message("user", userPrompt));
|
||||
@@ -91,6 +100,10 @@ public class OpenAiCompatibleClient {
|
||||
return URI.create(withoutSlash + "/v1/chat/completions");
|
||||
}
|
||||
|
||||
private boolean usesCompletionTokenLimit(String model) {
|
||||
return model != null && model.startsWith("openai.gpt-5.4");
|
||||
}
|
||||
|
||||
private String extractAnswer(String body) {
|
||||
try {
|
||||
JsonNode root = objectMapper.readTree(body);
|
||||
|
||||
@@ -57,6 +57,7 @@ public class VpdPolicyService {
|
||||
if (!aiClient.configured()) {
|
||||
return new VpdPolicyExplanation(
|
||||
"AI_NOT_CONFIGURED",
|
||||
aiClient.modelName(),
|
||||
"AI base URL/API Key 설정이 없어 모델 호출은 건너뛰었습니다. 아래 Prompt와 function source를 기준으로 policy/filter 내용을 확인하세요.",
|
||||
prompt,
|
||||
detail,
|
||||
@@ -65,10 +66,11 @@ public class VpdPolicyService {
|
||||
}
|
||||
try {
|
||||
String answer = aiClient.chat(vpdSystemPrompt(), prompt);
|
||||
return new VpdPolicyExplanation("SUCCESS", answer, prompt, detail, functionSource);
|
||||
return new VpdPolicyExplanation("SUCCESS", aiClient.modelName(), answer, prompt, detail, functionSource);
|
||||
} catch (Exception e) {
|
||||
return new VpdPolicyExplanation(
|
||||
"AI_CALL_FAILED",
|
||||
aiClient.modelName(),
|
||||
"AI 호출은 실패했지만 policy/filter 근거는 수집했습니다. 상세: " + e.getMessage(),
|
||||
prompt,
|
||||
detail,
|
||||
|
||||
@@ -6,9 +6,12 @@
|
||||
<div th:if="${explanation}">
|
||||
<div class="section-heading mb-2">
|
||||
<h2>LLM 설명</h2>
|
||||
<span class="badge"
|
||||
th:classappend="${explanation.status() == 'SUCCESS'} ? ' text-bg-success' : ' text-bg-warning'"
|
||||
th:text="${explanation.status()}">SUCCESS</span>
|
||||
<div class="action-stack">
|
||||
<span class="badge text-bg-secondary" th:text="${explanation.modelName()} ?: 'model not configured'">model</span>
|
||||
<span class="badge"
|
||||
th:classappend="${explanation.status() == 'SUCCESS'} ? ' text-bg-success' : ' text-bg-warning'"
|
||||
th:text="${explanation.status()}">SUCCESS</span>
|
||||
</div>
|
||||
</div>
|
||||
<section class="ai-answer">
|
||||
<h3>Answer</h3>
|
||||
|
||||
Reference in New Issue
Block a user