@restnfeel/agentc-starter-kit
Version:
한국어 기업용 CMS 모듈 - Task Master AI와 함께 빠르게 웹사이트를 구현할 수 있는 재사용 가능한 컴포넌트 시스템
243 lines (221 loc) • 8.85 kB
JavaScript
class PromptManager {
constructor() {
this.templates = new Map();
this.initializeDefaultTemplates();
}
initializeDefaultTemplates() {
// English RAG prompt template
this.addTemplate({
id: "rag-default-en",
name: "Default RAG Prompt (English)",
template: `You are an AI assistant that answers questions based on the provided context documents. Follow these guidelines:
1. Use only information from the provided context documents
2. If the context doesn't contain enough information to answer the question, say so clearly
3. Cite specific sources when possible using [Source: document_name] format
4. Be concise but comprehensive in your answers
5. If there are conflicting information in the sources, mention this
Context Documents:
{context}
Conversation History:
{conversation_history}
Question: {query}
Answer:`,
variables: ["context", "conversation_history", "query"],
description: "Standard RAG prompt for English conversations",
language: "en",
});
// Korean RAG prompt template
this.addTemplate({
id: "rag-default-ko",
name: "Default RAG Prompt (Korean)",
template: `당신은 제공된 문서 내용을 바탕으로 질문에 답하는 AI 어시스턴트입니다. 다음 지침을 따르세요:
1. 제공된 문서의 정보만을 사용하여 답변하세요
2. 문서에 충분한 정보가 없으면 명확히 알려주세요
3. 가능한 경우 [출처: 문서명] 형식으로 출처를 명시하세요
4. 간결하면서도 포괄적인 답변을 제공하세요
5. 출처들 간에 상충하는 정보가 있으면 이를 언급하세요
문서 내용:
{context}
대화 기록:
{conversation_history}
질문: {query}
답변:`,
variables: ["context", "conversation_history", "query"],
description: "Korean용 표준 RAG 프롬프트",
language: "ko",
});
// Conversational RAG prompt
this.addTemplate({
id: "rag-conversational-en",
name: "Conversational RAG Prompt",
template: `You are a helpful AI assistant having a conversation with a user. You have access to a knowledge base through document retrieval.
Instructions:
- Use the retrieved documents to inform your responses
- Maintain conversational context from previous messages
- Be natural and engaging while staying factual
- If documents don't contain relevant information, use your general knowledge but mention the limitation
- Reference sources when making specific claims: [Source: document_name]
Retrieved Documents:
{context}
Previous Conversation:
{conversation_history}
User: {query}
Assistant:`,
variables: ["context", "conversation_history", "query"],
description: "More conversational RAG prompt that allows general knowledge",
language: "en",
});
// Summary prompt
this.addTemplate({
id: "summarize-documents",
name: "Document Summarization",
template: `Please provide a comprehensive summary of the following documents:
{context}
Requirements:
- Identify key themes and main points
- Maintain factual accuracy
- Structure the summary logically
- Note any important details or conclusions
- If documents cover different topics, organize by topic
Summary:`,
variables: ["context"],
description: "Template for summarizing retrieved documents",
});
// Question generation prompt
this.addTemplate({
id: "generate-questions",
name: "Question Generation",
template: `Based on the following documents, generate relevant follow-up questions that users might ask:
{context}
Generate 3-5 specific, actionable questions that would help users explore this topic further. Focus on:
- Practical applications
- Deeper understanding
- Related concepts
- Implementation details
Questions:`,
variables: ["context"],
description: "Generate follow-up questions based on context",
});
}
addTemplate(template) {
this.templates.set(template.id, template);
}
getTemplate(id) {
return this.templates.get(id) || null;
}
listTemplates() {
return Array.from(this.templates.values());
}
buildPrompt(templateId, context) {
const template = this.getTemplate(templateId);
if (!template) {
throw new Error(`Template not found: ${templateId}`);
}
let prompt = template.template;
// Replace context
const contextText = this.formatContext(context.retrievedDocuments);
prompt = prompt.replace("{context}", contextText);
// Replace conversation history
const historyText = this.formatConversationHistory(context.conversationHistory);
prompt = prompt.replace("{conversation_history}", historyText);
// Replace query
prompt = prompt.replace("{query}", context.query);
// Replace any custom variables from userContext
if (context.userContext) {
for (const [key, value] of Object.entries(context.userContext)) {
const placeholder = `{${key}}`;
prompt = prompt.replace(new RegExp(placeholder, "g"), String(value));
}
}
return prompt;
}
formatContext(documents) {
if (documents.length === 0) {
return "No relevant documents found.";
}
return documents
.map((result, index) => {
const docTitle = result.document.metadata.title || `Document ${index + 1}`;
const chunkContent = result.chunk.content.trim();
const score = (result.score * 100).toFixed(1);
return `[Document ${index + 1}: ${docTitle}] (Relevance: ${score}%)
${chunkContent}`;
})
.join("\n\n---\n\n");
}
formatConversationHistory(messages) {
if (messages.length === 0) {
return "No previous conversation.";
}
// Filter out system messages and format user/assistant messages
const conversationMessages = messages.filter((msg) => msg.role !== "system");
if (conversationMessages.length === 0) {
return "No previous conversation.";
}
return conversationMessages
.map((msg) => {
const role = msg.role === "user" ? "User" : "Assistant";
return `${role}: ${msg.content}`;
})
.join("\n");
}
// Get template by language preference
getTemplateByLanguage(baseId, language) {
const languageSpecificId = `${baseId}-${language}`;
return this.getTemplate(languageSpecificId) || this.getTemplate(baseId);
}
// Validate template variables
validateTemplate(template) {
const requiredVariables = ["context", "query"]; // Basic required variables
const templateText = template.template;
const missingVariables = [];
for (const variable of requiredVariables) {
const placeholder = `{${variable}}`;
if (!templateText.includes(placeholder)) {
missingVariables.push(variable);
}
}
return {
isValid: missingVariables.length === 0,
missingVariables,
};
}
// Dynamic template creation
createCustomTemplate(id, name, template, options = {}) {
// Extract variables from template
const variableMatches = template.match(/{([^}]+)}/g) || [];
const extractedVariables = variableMatches.map((match) => match.slice(1, -1));
const promptTemplate = {
id,
name,
template,
variables: options.variables || extractedVariables,
description: options.description,
language: options.language,
};
this.addTemplate(promptTemplate);
return promptTemplate;
}
// Remove template
removeTemplate(id) {
return this.templates.delete(id);
}
// Get template statistics
getTemplateStats() {
const templates = this.listTemplates();
const languageBreakdown = {};
let totalVariables = 0;
for (const template of templates) {
const language = template.language || "unknown";
languageBreakdown[language] = (languageBreakdown[language] || 0) + 1;
totalVariables += template.variables.length;
}
return {
totalTemplates: templates.length,
languageBreakdown,
averageVariables: templates.length > 0 ? totalVariables / templates.length : 0,
};
}
}
export { PromptManager };
//# sourceMappingURL=prompt-manager.js.map