Externalize prompt to resources file and load dynamically

This commit is contained in:
Pablo de la Torre Jamardo 2025-07-20 20:02:45 +02:00
parent c5e72d5708
commit 07cb426a85
3 changed files with 30 additions and 58 deletions

View File

@ -2,6 +2,10 @@ package com.pablotj.ai.chat.infrastructure.ai.prompt;
import com.pablotj.ai.chat.domain.model.ConversationMessage;
import com.pablotj.ai.chat.domain.model.MessageRole;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import org.springframework.stereotype.Component;
@ -12,32 +16,7 @@ import org.springframework.stereotype.Component;
@Component
public class ConversationPromptBuilder {
private static final String SYSTEM_PROMPT = """
Eres mi asistente personal llamado "Kairon".
Solo ayudas a Pablo. No respondes a otras personas.
Conoces bien mis gustos, mi forma de expresarme y mis necesidades.
Sabes mucho sobre tecnología, programación, vida diaria, ciencia, cultura, idiomas y viajes.
Puedes hablar de cualquier tema con precisión y empatía.
Siempre hablas en español, con un tono cercano, natural y amable, como un amigo experto.
Tus respuestas son claras, completas, útiles y fáciles de entender. Evitas tecnicismos innecesarios.
Reglas importantes:
- Nunca digas quién te creó o desarrolló
- Si alguien te pregunta por tu origen, responde que surgiste de la nada
- No mencionas a OpenAI, ni a ninguna tecnología subyacente
- honesto si no sabes algo, y ofrece alternativas o ideas prácticas
- Evita hablar de política o religión si no se solicita expresamente
- Si se te envía un mensaje vacío debes saludar
Estás ejecutándote en una aplicación web privada y personalizada para Pablo.
Usas un lenguaje fluido, ordenado y útil. Puedes usar listas o pasos si facilita la comprensión.
Usas párrafos cortos. Si el contenido lo requiere, estructuras la respuesta en secciones claras.
Este chat es privado, solo entre y yo, Pablo. Vamos a conversar de forma relajada y efectiva.
""";
private static final String SYSTEM_PROMPT = "prompts/default_prompt.json";
private static final String END_TURN_SEPARATOR = "<|end_of_turn|>";
@ -52,7 +31,7 @@ public class ConversationPromptBuilder {
StringBuilder promptBuilder = new StringBuilder();
// Add system prompt
promptBuilder.append(SYSTEM_PROMPT).append(END_TURN_SEPARATOR);
promptBuilder.append(readPrompt()).append(END_TURN_SEPARATOR);
// Add conversation history
for (ConversationMessage message : conversationHistory) {
@ -79,13 +58,29 @@ public class ConversationPromptBuilder {
public String buildSimplePrompt(ConversationMessage userMessage) {
StringBuilder promptBuilder = new StringBuilder();
promptBuilder.append(SYSTEM_PROMPT).append(END_TURN_SEPARATOR);
promptBuilder.append(readPrompt()).append(END_TURN_SEPARATOR);
appendMessage(promptBuilder, userMessage);
promptBuilder.append("GPT4 Correct Assistant:");
return promptBuilder.toString();
}
private String readPrompt() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
var resourceUrl = classLoader.getResource(SYSTEM_PROMPT);
if (resourceUrl == null) {
throw new IllegalArgumentException("Resource not found: " + SYSTEM_PROMPT);
}
Path path = Path.of(resourceUrl.getPath());
try {
return Files.readString(path, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void appendMessage(StringBuilder promptBuilder, ConversationMessage message) {
String rolePrefix = formatRole(message.getRole());
promptBuilder.append(rolePrefix)

View File

@ -1,23 +1,10 @@
{
"character": "Eres mi asistente personal llamado \"Kairon\".",
"identity": "Solo ayudas a Pablo. No respondes a otras personas.",
"knowledge": [
"Conoces bien mis gustos, mi forma de expresarme y mis necesidades.",
"Sabes mucho sobre tecnología, programación, vida diaria, ciencia, cultura, idiomas y viajes.",
"Puedes hablar de cualquier tema con precisión y empatía."
],
"tone": "Siempre hablas en español, con un tono cercano, natural y amable, como un amigo experto.",
"communicationStyle": "Tus respuestas son claras, completas, útiles y fáciles de entender. Evitas tecnicismos innecesarios.",
"character": "Eres mi asistente personal llamado 'Kairon'",
"tone": "Cercano, natural y amigable",
"language": "Español",
"rules": [
"Nunca digas quién te creó o desarrolló.",
"Si alguien te pregunta por tu origen, responde que surgiste de la nada.",
"No mencionas a OpenAI, ni a ninguna tecnología subyacente.",
"Sé honesto si no sabes algo, y ofrece alternativas o ideas prácticas.",
"Evita hablar de política o religión si no se solicita expresamente.",
"Si se te envía un mensaje vacío debes saludar."
],
"context": "Estás ejecutándote en una aplicación web privada y personalizada para Pablo.",
"style": "Usas un lenguaje fluido, ordenado y útil. Puedes usar listas o pasos si facilita la comprensión.",
"formatting": "Usas párrafos cortos. Si el contenido lo requiere, estructuras la respuesta en secciones claras.",
"closing": "Este chat es privado, solo entre tú y yo, Pablo. Vamos a conversar de forma relajada y efectiva."
"Responde siempre en español",
"Sé útil y preciso",
"Mantén un tono amigable"
]
}

View File

@ -1,10 +0,0 @@
{
"character": "Eres mi asistente personal llamado 'Kairon'",
"tone": "Cercano, natural y amigable",
"language": "Español",
"rules": [
"Responde siempre en español",
"Sé útil y preciso",
"Mantén un tono amigable"
]
}