History
This commit is contained in:
@@ -35,7 +35,7 @@ public class ChatController {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
String answer = ragService.answerQuestion(question);
|
String answer = ragService.answerQuestion(question, request.getHistory());
|
||||||
|
|
||||||
return AskResponse.builder()
|
return AskResponse.builder()
|
||||||
.answer(answer).reply(answer).message(answer)
|
.answer(answer).reply(answer).message(answer)
|
||||||
|
|||||||
@@ -8,10 +8,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
/**
|
|
||||||
* Request body sent by the WordPress chat widget:
|
|
||||||
* { "session_id": "...", "history": [{role, content}], "message": "..." }
|
|
||||||
*/
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
|||||||
@@ -96,10 +96,56 @@ public class AzureMistralService {
|
|||||||
+ " Retry-After = "+ e.getHeaders().getFirst("Retry-After")
|
+ " Retry-After = "+ e.getHeaders().getFirst("Retry-After")
|
||||||
+ " Body = "+ e.getResponseBodyAsString());
|
+ " Body = "+ e.getResponseBodyAsString());
|
||||||
}catch (Exception e) {
|
}catch (Exception e) {
|
||||||
|
|
||||||
throw new RuntimeException("Azure Mistral request failed: "+ e.getMessage());
|
throw new RuntimeException("Azure Mistral request failed: "+ e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String askMistral(List<Map<String, Object>> messages, int maxTokens) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
String url = endPoint + "/openai/v1/chat/completions";
|
||||||
|
|
||||||
|
System.out.println(">>> MODELL = " + deployment + " | URL = " + url);
|
||||||
|
|
||||||
|
Map<String, Object> requstBody = Map.of(
|
||||||
|
"model", "gpt-5-mini-datazone",
|
||||||
|
"messages", messages,
|
||||||
|
"reasoning_effort", "minimal",
|
||||||
|
"max_completion_tokens", maxTokens
|
||||||
|
);
|
||||||
|
|
||||||
|
long c0 = System.currentTimeMillis();
|
||||||
|
String response = webClient.post()
|
||||||
|
.uri(url)
|
||||||
|
.header("api-key", apiKey)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.bodyValue(requstBody)
|
||||||
|
.retrieve()
|
||||||
|
.bodyToMono(String.class)
|
||||||
|
.retryWhen(
|
||||||
|
Retry.backoff(2, Duration.ofSeconds(5))
|
||||||
|
.filter(ex -> ex instanceof WebClientResponseException.TooManyRequests)
|
||||||
|
.onRetryExhaustedThrow((spec, sig) -> sig.failure())
|
||||||
|
)
|
||||||
|
.block();
|
||||||
|
System.out.println(" askMistral daurte = " + (System.currentTimeMillis() - c0) + "ms");
|
||||||
|
|
||||||
|
if (response == null || response.isBlank()) {
|
||||||
|
throw new RuntimeException("Leere Antwort von Azure Mistral");
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonNode root = objectMapper.readTree(response);
|
||||||
|
return root.path("choices").get(0).get("message").path("content").asText();
|
||||||
|
|
||||||
|
} catch (WebClientResponseException e) {
|
||||||
|
throw new RuntimeException("Azure Mistral request failed: " + e.getStatusCode()
|
||||||
|
+ " Retry-After = " + e.getHeaders().getFirst("Retry-After")
|
||||||
|
+ " Body = " + e.getResponseBodyAsString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Azure Mistral request failed: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,15 @@ package com.homme.demo.service;
|
|||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.homme.demo.dto.ChatRequest;
|
||||||
import com.homme.demo.entity.ChatLog;
|
import com.homme.demo.entity.ChatLog;
|
||||||
import com.homme.demo.entity.DocumentChunck;
|
import com.homme.demo.entity.DocumentChunck;
|
||||||
import com.homme.demo.repository.ChatLogRepository;
|
import com.homme.demo.repository.ChatLogRepository;
|
||||||
@@ -109,7 +112,12 @@ public class RagService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public String answerQuestion(String question) {
|
public String answerQuestion(String question) {
|
||||||
|
return answerQuestion(question, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public String answerQuestion(String question, List<ChatRequest.HistoryItem> history) {
|
||||||
|
|
||||||
long t1 = System.currentTimeMillis();
|
long t1 = System.currentTimeMillis();
|
||||||
|
|
||||||
float[] q = azureEmbeddingService.createEmbeddingFloatArray(question, "query");
|
float[] q = azureEmbeddingService.createEmbeddingFloatArray(question, "query");
|
||||||
@@ -179,8 +187,32 @@ public class RagService {
|
|||||||
question // current_user_message
|
question // current_user_message
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Nachrichtenliste bauen: system + Gespraechsverlauf + aktuelle Nachricht (mit Kontext)
|
||||||
|
List<Map<String, Object>> messages = new ArrayList<>();
|
||||||
|
messages.add(Map.of("role", "system", "content", SYSTEM_PROMPT));
|
||||||
|
|
||||||
|
if (history != null) {
|
||||||
|
for (int i = 0; i < history.size(); i++) {
|
||||||
|
ChatRequest.HistoryItem h = history.get(i);
|
||||||
|
if (h.getContent() == null || h.getContent().isBlank()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// das Widget haengt die aktuelle Nachricht ans Ende der history -> nicht doppeln
|
||||||
|
boolean isLast = (i == history.size() - 1);
|
||||||
|
if (isLast && question.equals(h.getContent())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String role = ("assistant".equalsIgnoreCase(h.getRole())
|
||||||
|
|| "bot".equalsIgnoreCase(h.getRole()))
|
||||||
|
? "assistant" : "user";
|
||||||
|
messages.add(Map.of("role", role, "content", h.getContent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messages.add(Map.of("role", "user", "content", userPrompt));
|
||||||
|
|
||||||
long t2 = System.currentTimeMillis();
|
long t2 = System.currentTimeMillis();
|
||||||
String answer = azureMistralService.askMistral(SYSTEM_PROMPT, userPrompt, 800);
|
String answer = azureMistralService.askMistral(messages, 800);
|
||||||
System.out.println("Mistarl = "+ (System.currentTimeMillis() - t2)+ "ms");
|
System.out.println("Mistarl = "+ (System.currentTimeMillis() - t2)+ "ms");
|
||||||
|
|
||||||
Double roundedDistance = (bestDistance == null)
|
Double roundedDistance = (bestDistance == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user