125 lines
3.6 KiB
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")
|
|
}
|