Files
virtual-banker/backend/llm/prompt.go

125 lines
3.6 KiB
Go

package llm
import (
"fmt"
"strings"
)
// BuildPrompt builds a prompt from components
func BuildPrompt(tenantConfig *TenantConfig, conversationHistory []Message, userInput string, retrievedDocs []RetrievedDoc) string {
var parts []string
// System message
systemMsg := buildSystemMessage(tenantConfig)
parts = append(parts, systemMsg)
// Retrieved documents (RAG context)
if len(retrievedDocs) > 0 {
parts = append(parts, "\n## Context:")
for i, doc := range retrievedDocs {
parts = append(parts, fmt.Sprintf("\n[Document %d]", i+1))
parts = append(parts, fmt.Sprintf("Title: %s", doc.Title))
parts = append(parts, fmt.Sprintf("Content: %s", doc.Content))
if doc.URL != "" {
parts = append(parts, fmt.Sprintf("Source: %s", doc.URL))
}
}
}
// Conversation history
if len(conversationHistory) > 0 {
parts = append(parts, "\n## Conversation History:")
for _, msg := range conversationHistory {
parts = append(parts, fmt.Sprintf("%s: %s", strings.Title(msg.Role), msg.Content))
}
}
// Current user input
parts = append(parts, fmt.Sprintf("\n## User: %s", userInput))
parts = append(parts, "\n## Assistant:")
return strings.Join(parts, "\n")
}
// TenantConfig holds tenant-specific configuration
type TenantConfig struct {
Greeting string
Tone string // "professional", "friendly", "formal"
Disclaimers []string
AllowedTools []string
}
// RetrievedDoc represents a retrieved document from RAG
type RetrievedDoc struct {
Title string
Content string
URL string
Score float64
}
// BuildPromptWithRAG builds a prompt with RAG context
func BuildPromptWithRAG(tenantConfig *TenantConfig, conversationHistory []Message, userInput string, retrievedDocs []RetrievedDoc) string {
var parts []string
// System message
systemMsg := buildSystemMessage(tenantConfig)
parts = append(parts, systemMsg)
// Retrieved documents (RAG context)
if len(retrievedDocs) > 0 {
parts = append(parts, "\n## Context:")
for i, doc := range retrievedDocs {
parts = append(parts, fmt.Sprintf("\n[Document %d]", i+1))
parts = append(parts, fmt.Sprintf("Title: %s", doc.Title))
parts = append(parts, fmt.Sprintf("Content: %s", doc.Content))
if doc.URL != "" {
parts = append(parts, fmt.Sprintf("Source: %s", doc.URL))
}
}
}
// Conversation history
if len(conversationHistory) > 0 {
parts = append(parts, "\n## Conversation History:")
for _, msg := range conversationHistory {
parts = append(parts, fmt.Sprintf("%s: %s", strings.Title(msg.Role), msg.Content))
}
}
// Current user input
parts = append(parts, fmt.Sprintf("\n## User: %s", userInput))
parts = append(parts, "\n## Assistant:")
return strings.Join(parts, "\n")
}
// buildSystemMessage builds the system message
func buildSystemMessage(config *TenantConfig) string {
var parts []string
parts = append(parts, "You are a helpful Virtual Banker assistant.")
if config.Tone != "" {
parts = append(parts, fmt.Sprintf("Your tone should be %s.", config.Tone))
}
if len(config.Disclaimers) > 0 {
parts = append(parts, "\nImportant disclaimers:")
for _, disclaimer := range config.Disclaimers {
parts = append(parts, fmt.Sprintf("- %s", disclaimer))
}
}
if len(config.AllowedTools) > 0 {
parts = append(parts, "\nYou have access to the following tools:")
for _, tool := range config.AllowedTools {
parts = append(parts, fmt.Sprintf("- %s", tool))
}
}
parts = append(parts, "\nAlways be helpful, accurate, and respectful.")
parts = append(parts, "If you don't know something, say so and offer to help find the answer.")
return strings.Join(parts, "\n")
}