diff options
| author | Michael Peter Christen <mc@yacy.net> | 2025-12-06 19:21:57 +0100 |
|---|---|---|
| committer | Michael Peter Christen <mc@yacy.net> | 2025-12-06 19:21:57 +0100 |
| commit | eed704d23bc53e5d0359072e5e2134b469ae2eef (patch) | |
| tree | 2518c10e9e478a4c04845db3b81442ee9dfca7cb /source | |
| parent | ed9ea238b1e7d4a89d77acea790b08b6f2b1ed49 (diff) | |
added RAG configuration page
Diffstat (limited to 'source')
| -rw-r--r-- | source/net/yacy/htroot/AILab.java | 4 | ||||
| -rw-r--r-- | source/net/yacy/htroot/RAGConfig_p.java | 36 | ||||
| -rw-r--r-- | source/net/yacy/htroot/yacychat.java | 38 | ||||
| -rw-r--r-- | source/net/yacy/http/servlets/RAGProxyServlet.java | 24 |
4 files changed, 74 insertions, 28 deletions
diff --git a/source/net/yacy/htroot/AILab.java b/source/net/yacy/htroot/AILab.java index 461a8c32e..e479f4a39 100644 --- a/source/net/yacy/htroot/AILab.java +++ b/source/net/yacy/htroot/AILab.java @@ -79,7 +79,9 @@ public class AILab { prop.put("ailab_index_status", hasIndex ? "ready" : "pending"); prop.putNum("ailab_index_count", indexDocs); prop.putNum("ailab_index_needed", indexNeeded); - prop.put("ailab_rag_status", hasRagRole ? "ready" : "pending"); + // consider the RAG configuration page visit as completing the RAG quest + final boolean ragVisited = "true".equalsIgnoreCase(sb.getConfig("ui.RAGConfig_p.visited", "false")); + prop.put("ailab_rag_status", (hasRagRole || ragVisited) ? "ready" : "pending"); prop.put("ailab_shield_status", hasShield ? "ready" : "pending"); return prop; diff --git a/source/net/yacy/htroot/RAGConfig_p.java b/source/net/yacy/htroot/RAGConfig_p.java new file mode 100644 index 000000000..819d9832d --- /dev/null +++ b/source/net/yacy/htroot/RAGConfig_p.java @@ -0,0 +1,36 @@ +// RAGConfig_p.java +// Configure RAG prompt strings + +package net.yacy.htroot; + +import net.yacy.cora.protocol.RequestHeader; +import net.yacy.search.Switchboard; +import net.yacy.server.serverObjects; +import net.yacy.server.serverSwitch; + +public class RAGConfig_p { + + public static serverObjects respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, final serverSwitch env) { + final Switchboard sb = (Switchboard) env; + final serverObjects prop = new serverObjects(); + + if (post != null) { + final String systemPrompt = post.get("ai.system-prompt", "").trim(); + final String userPrefix = post.get("ai.llm-user-prefix", "").trim(); + final String queryPrefix = post.get("ai.llm-query-generator-prefix", "").trim(); + + sb.setConfig("ai.system-prompt", systemPrompt); + sb.setConfig("ai.llm-user-prefix", userPrefix); + sb.setConfig("ai.llm-query-generator-prefix", queryPrefix); + } + + // mark page as visited for gamification/quest tracking + sb.setConfig("ui.RAGConfig_p.visited", "true"); + + prop.put("ai.system-prompt", sb.getConfig("ai.system-prompt", net.yacy.http.servlets.RAGProxyServlet.LLM_SYSTEM_PROMPT_DEFAULT)); + prop.put("ai.llm-user-prefix", sb.getConfig("ai.llm-user-prefix", "\n\nAdditional Information:\n\nbelow you find a collection of texts that might be useful to generate a response. Do not discuss these documents, just use them to answer the question above.\n\n")); + prop.put("ai.llm-query-generator-prefix", sb.getConfig("ai.llm-query-generator-prefix", "Make a list of search words with low document frequency for the following prompt; use a JSON Array: ")); + + return prop; + } +} diff --git a/source/net/yacy/htroot/yacychat.java b/source/net/yacy/htroot/yacychat.java index db9d14eee..df573c7c1 100644 --- a/source/net/yacy/htroot/yacychat.java +++ b/source/net/yacy/htroot/yacychat.java @@ -12,22 +12,26 @@ import net.yacy.server.serverSwitch; public class yacychat { public static serverObjects respond(@SuppressWarnings("unused") final RequestHeader header, final serverObjects post, final serverSwitch env) { - // return variable that accumulates replacements - final Switchboard sb = (Switchboard) env; - - final serverObjects prop = new serverObjects(); - String body = post == null ? "" : post.get("BODY", ""); - JSONObject bodyj = new JSONObject(); - if (body.length() > 0) { - try { - bodyj = new JSONObject(new JSONTokener(body)); - } catch (JSONException e) { - // silently catch this - } - } - - // return rewrite properties - return prop; + // return variable that accumulates replacements + final Switchboard sb = (Switchboard) env; + + final serverObjects prop = new serverObjects(); + String body = post == null ? "" : post.get("BODY", ""); + JSONObject bodyj = new JSONObject(); + if (body.length() > 0) { + try { + bodyj = new JSONObject(new JSONTokener(body)); + } catch (JSONException e) { + // silently catch this + } + } + + // system prompt comes from configuration; default is empty + final String systemPrompt = sb.getConfig("ai.system-prompt", net.yacy.http.servlets.RAGProxyServlet.LLM_SYSTEM_PROMPT_DEFAULT); + prop.put("system_prompt", systemPrompt); + + // return rewrite properties + return prop; } -}
\ No newline at end of file +} diff --git a/source/net/yacy/http/servlets/RAGProxyServlet.java b/source/net/yacy/http/servlets/RAGProxyServlet.java index 2108f57f2..3c8fe535d 100644 --- a/source/net/yacy/http/servlets/RAGProxyServlet.java +++ b/source/net/yacy/http/servlets/RAGProxyServlet.java @@ -87,9 +87,11 @@ public class RAGProxyServlet extends HttpServlet { private static final long serialVersionUID = 3411544789759643137L; - private static String LLM_SYSTEM_PREFIX = "\n\nYou may receive additional expert knowledge in the user prompt after a 'Additional Information' headline to enhance your knowledge. Use it only if applicable."; - private static String LLM_USER_PREFIX = "\n\nAdditional Information:\n\nbelow you find a collection of texts that might be useful to generate a response. Do not discuss these documents, just use them to answer the question above.\n\n"; - + public static final String LLM_SYSTEM_PROMPT_DEFAULT = "You are a smart and helpful chatbot. If possible, use friendly emojies."; + private static final String LLM_SYSTEM_PREFIX_DEFAULT = "\n\nYou may receive additional expert knowledge in the user prompt after a 'Additional Information' headline to enhance your knowledge. Use it only if applicable."; + private static final String LLM_USER_PREFIX_DEFAULT = "\n\nAdditional Information:\n\nbelow you find a collection of texts that might be useful to generate a response. Do not discuss these documents, just use them to answer the question above.\n\n"; + private static final String LLM_QUERY_GENERATOR_PREFIX_DEFAULT = "Make a list of search words with low document frequency for the following prompt; use a JSON Array: "; + @Override public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { response.setContentType("application/json;charset=utf-8"); @@ -136,6 +138,7 @@ public class RAGProxyServlet extends HttpServlet { String body = bodyBuilder.toString(); JSONObject bodyObject; try { + final Switchboard sb = Switchboard.getSwitchboard(); // get system message and user prompt bodyObject = new JSONObject(body); // get chat functions @@ -153,11 +156,13 @@ public class RAGProxyServlet extends HttpServlet { // get messages and prepare user message attachments JSONArray messages = bodyObject.optJSONArray("messages"); + final String systemPrefix = sb.getConfig("ai.llm-system-prefix", LLM_SYSTEM_PREFIX_DEFAULT); + final String userPrefix = sb.getConfig("ai.llm-user-prefix", LLM_USER_PREFIX_DEFAULT); for (int i = 0; i < messages.length(); i++) { JSONObject message = messages.getJSONObject(i); if (message.optString("role", "").equals("user")) { UserObject userObject = new UserObject(message); - userObject.attachAttachment(LLM_USER_PREFIX); + userObject.attachAttachment(userPrefix); } } UserObject userObject = new UserObject(messages.getJSONObject(messages.length() - 1)); @@ -170,9 +175,10 @@ public class RAGProxyServlet extends HttpServlet { String searchResultMarkdown = ""; if (rag) { // modify system and user prompt here in bodyObject to enable RAG - searchResultQuery = this.searchWordsForPrompt(llm4tldr.llm, llm4tldr.model, user); + final String queryPrefix = sb.getConfig("ai.llm-query-generator-prefix", LLM_QUERY_GENERATOR_PREFIX_DEFAULT); + searchResultQuery = this.searchWordsForPrompt(llm4tldr.llm, llm4tldr.model, queryPrefix + user); searchResultMarkdown = searchResultsAsMarkdown(searchResultQuery, 10); - user += LLM_USER_PREFIX; + user += userPrefix; user += searchResultMarkdown; userObject.setContentText(user); } @@ -614,8 +620,6 @@ public class RAGProxyServlet extends HttpServlet { return this.title; } } - - /** * Creates slices of a given text. We want slices of average same size, @@ -660,9 +664,9 @@ public class RAGProxyServlet extends HttpServlet { } private String searchWordsForPrompt(LLM llm, String model, String prompt) { - String question = "Make a list of search words with low document frequency for the following prompt; use a JSON Array: " + prompt; + String question = LLM_QUERY_GENERATOR_PREFIX_DEFAULT + prompt; try { - LLM.Context context = new LLM.Context(LLM_SYSTEM_PREFIX); + LLM.Context context = new LLM.Context(LLM_SYSTEM_PREFIX_DEFAULT); context.addPrompt(question); Set<String> singlewords = new LinkedHashSet<>(); String[] a = LLM.stringsFromChat(llm.chat(model, context, LLM.listSchema, 200)); |
