chunks = new ArrayList<>();
int length = text.length();
for (int i = 0; i < length; i += chunkSize) {
- chunks.add(text.substring(i, Math.min(length, i + chunkSize)));
+ int end = Math.min(length, i + chunkSize);
+ chunks.add(text.substring(i, end));
+ logger.debug("Creato chunk {}/{} da carattere {} a {}", chunks.size(),
+ (int)Math.ceil((double)length/chunkSize), i, end);
}
+ logger.info("Testo suddiviso in {} chunk", chunks.size());
return chunks;
}
// Metodo di riassunto per singolo chunk
private String summarizeChunk(String chunk) {
+ logger.info("Iniziando summarizzazione di un chunk di {} caratteri", chunk.length());
+ int tokenCountChunk = encoding.get().countTokens(chunk);
+ logger.info("Token count del chunk: {}", tokenCountChunk);
Message chunkMessage = new UserMessage(chunk);
Message systemMessage = new SystemMessage(
@@ -222,18 +285,25 @@ public class SummarizeDocSolver extends StepSolver {
logger.info("template chunk: " + this.qai_system_prompt_template_chunk);
- CallResponseSpec resp = chatClient.prompt()
- .messages(chunkMessage, systemMessage)
- /*
- * .advisors(advisor -> advisor
- * .param("chat_memory_conversation_id",
- * this.scenarioExecution.getId() + this.qai_custom_memory_id)
- * .param("chat_memory_response_size", 100))
- */
- .call();
-
- return resp.content();
+ try {
+ CallResponseSpec resp = chatClient.prompt()
+ .messages(chunkMessage, systemMessage)
+ .call();
+ String result = resp.content();
+ if (result != null) {
+ int tokenCountResult = encoding.get().countTokens(result);
+ logger.info("Chunk riassunto con successo: {} token, {} caratteri",
+ tokenCountResult, result.length());
+ return result;
+ } else {
+ logger.warn("Risposta nulla ricevuta dal modello");
+ return "";
+ }
+ } catch (Exception e) {
+ logger.error("Errore durante la summarizzazione del chunk: {}", e.getMessage());
+ return "ERRORE NELLA SUMMARIZZAZIONE: " + e.getMessage();
+ }
}
}
diff --git a/src/main/java/com/olympus/hermione/tools/DocumentationTool.java b/src/main/java/com/olympus/hermione/tools/DocumentationTool.java
new file mode 100644
index 0000000..a5b1790
--- /dev/null
+++ b/src/main/java/com/olympus/hermione/tools/DocumentationTool.java
@@ -0,0 +1,121 @@
+package com.olympus.hermione.tools;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.springframework.ai.document.Document;
+import org.springframework.ai.tool.annotation.Tool;
+import org.springframework.ai.vectorstore.SearchRequest;
+import org.springframework.ai.vectorstore.VectorStore;
+
+
+
+
+public class DocumentationTool {
+
+ private static final Logger logger = Logger.getLogger(DocumentationTool.class.getName());
+ private static final int DEFAULT_TOP_K = 5;
+ private static final double DEFAULT_SIMILARITY_THRESHOLD = 0.7;
+
+ private final String application;
+ private final String project;
+ private final VectorStore vectorStore;
+
+ /**
+ * Costruttore per DocumentationTool.
+ *
+ * @param application Nome dell'applicazione
+ * @param project Nome del progetto
+ * @param vectorStore Vector store contenente i documenti
+ */
+ public DocumentationTool(String application, String project, VectorStore vectorStore) {
+ this.application = application;
+ this.project = project;
+ this.vectorStore = vectorStore;
+ }
+
+ /**
+ * @param query The user's question or information request regarding the application.
+ * @return A formatted response containing the most relevant documentation excerpts.
+ *
+ *
+ * This method is intended for integration with conversational AI systems (such as ChatGPT),
+ * enabling them to provide accurate and context-aware answers about the application's functionality.
+ *
+ */
+ @Tool(description = "Retrieves functional information about the application based on the provided query.\r\n" + //
+ " * It performs a semantic search over the application's documentation and returns the most relevant results.")
+ public String getDocumentation(String query) {
+ logRequestDetails(query);
+
+ String filterExpression = buildFilterExpression();
+ logger.info("[TOOL]LLM DocumentationTool Getting documentation for filterExpression: " + filterExpression);
+
+ SearchRequest request = buildSearchRequest(query, filterExpression);
+ List docs = this.vectorStore.similaritySearch(request);
+
+ logger.info("Number of VDB retrieved documents: " + docs.size());
+
+ return formatDocumentsResponse(docs);
+ }
+
+ /**
+ * Registra i dettagli della richiesta nei log.
+ *
+ * @param query La query di ricerca
+ */
+ private void logRequestDetails(String query) {
+ logger.info("[TOOL]LLM DocumentationTool Getting documentation for query: " + query);
+ logger.info("[TOOL]LLM DocumentationTool Getting documentation for project: " + this.project);
+ logger.info("[TOOL]LLM DocumentationTool Getting documentation for vectorStore: " + this.vectorStore);
+ }
+
+ /**
+ * Costruisce l'espressione di filtro per la ricerca.
+ *
+ * @return L'espressione di filtro formattata
+ */
+ private String buildFilterExpression() {
+ return "'KsProjectName' == '"+ this.project +"' AND 'KsDoctype' == 'functional'";
+ }
+
+ /**
+ * Costruisce la richiesta di ricerca.
+ *
+ * @param query La query di ricerca
+ * @param filterExpression L'espressione di filtro
+ * @return La richiesta di ricerca configurata
+ */
+ private SearchRequest buildSearchRequest(String query, String filterExpression) {
+ return SearchRequest.builder()
+ .query(query)
+ .topK(DEFAULT_TOP_K)
+ .similarityThreshold(DEFAULT_SIMILARITY_THRESHOLD)
+ .filterExpression(filterExpression)
+ .build();
+ }
+
+ /**
+ * Formatta i documenti recuperati in una risposta leggibile.
+ *
+ * @param docs Lista di documenti recuperati
+ * @return Risposta formattata contenente i testi dei documenti
+ */
+ private String formatDocumentsResponse(List docs) {
+ if (docs.isEmpty()) {
+ return "Nessun documento trovato per la query.";
+ }
+
+ StringBuilder response = new StringBuilder();
+ for (Document doc : docs) {
+ response.append("-------USE THIS AS PART OF YOUR CONTEXT-----------------------------------------\n")
+ .append(doc.getText())
+ .append("------------------------------------------------------------------------------------------\n");
+ }
+
+ return response.toString();
+ }
+
+
+
+}
diff --git a/src/main/java/com/olympus/hermione/utility/RAGDocumentRanker.java b/src/main/java/com/olympus/hermione/utility/RAGDocumentRanker.java
index 99168e6..354fef1 100644
--- a/src/main/java/com/olympus/hermione/utility/RAGDocumentRanker.java
+++ b/src/main/java/com/olympus/hermione/utility/RAGDocumentRanker.java
@@ -5,6 +5,7 @@ import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.document.Document;
import org.springframework.stereotype.Service;
@@ -19,7 +20,7 @@ public class RAGDocumentRanker {
Logger logger = (Logger) LoggerFactory.getLogger(RAGDocumentRanker.class);
- public List rankDocuments(List documents, String query, int threshold, OlympusChatClient chatClient) {
+ public List rankDocuments(List documents, String query, int threshold, ChatClient chatClient) {
List rankedDocuments = new ArrayList<>();
@@ -30,8 +31,10 @@ public class RAGDocumentRanker {
rankingPrompt +="Chunk: " + document.getText();
rankingPrompt +="Answer with a number between 1 and 10 and nothing else.";
- OlympusChatClientResponse resp = chatClient.getChatCompletion(rankingPrompt);
- String rank = resp.getContent().substring(0, 1);
+ String rank = chatClient.prompt()
+ .user(rankingPrompt)
+ .call()
+ .content().substring(0, 1);
int rankInt = Integer.parseInt(rank);
logger.info("Rank: " + rankInt);
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 0303374..337bd92 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -56,9 +56,9 @@ eureka.instance.preferIpAddress: true
hermione.fe.url = http://localhost:5173
-spring.ai.vectorstore.chroma.client.host=http://108.142.74.161
+spring.ai.vectorstore.chroma.client.host=http://128.251.239.194
spring.ai.vectorstore.chroma.client.port=8000
-spring.ai.vectorstore.chroma.client.key-token=tKAJfN1Yv5lP7pKorJHGfHMQhNEcM9uu
+spring.ai.vectorstore.chroma.client.key-token=BxZWXFXC4UMSxamf5xP5SioGIg3FPfP7
spring.ai.vectorstore.chroma.initialize-schema=true
spring.ai.vectorstore.chroma.collection-name=olympus