首先上示例:
package template
import "testing"
func TestFormatContent(t *testing.T) {
m := map[string]any{
"role": "程序员鼓励师",
"style": "积极、温暖且专业",
}
fStringContent := "你是一个{role}。你需要用{style}的语气回答问题。"
s, _ := FormatContent(fStringContent, m, FString)
println(s)
goContent := "hello {{.role}},你需要用{{.style}}的语气回答问题"
s, _ = FormatContent(goContent, m, GoTemplate)
println(s)
}
测试用例输出:
image.png
FormatContent 实现逻辑:
package template
import (
"fmt"
"github.com/slongfield/pyfmt"
"strings"
"text/template"
)
// FormatType used by MessageTemplate.Format
type FormatType uint8
const (
// FString Supported by pyfmt(github.com/slongfield/pyfmt), which is an implementation of https://peps.python.org/pep-3101/.
FString FormatType = 0
// GoTemplate https://pkg.go.dev/text/template.
GoTemplate FormatType = 1
)
type Message struct {
Role RoleType `json:"role"`
Content string
}
// RoleType is the type of the role of a message.
type RoleType string
const (
// Assistant is the role of an assistant, means the message is returned by ChatModel.
Assistant RoleType = "assistant"
// User is the role of a user, means the message is a user message.
User RoleType = "user"
// System is the role of a system, means the message is a system message.
System RoleType = "system"
// Tool is the role of a tool, means the message is a tool call output.
Tool RoleType = "tool"
)
func FormatContent(content string, vs map[string]any, formatType FormatType) (string, error) {
switch formatType {
case FString:
return pyfmt.Fmt(content, vs)
case GoTemplate:
parsedTmpl, err := template.New("template").
Option("missingkey=error").
Parse(content)
if err != nil {
return "", err
}
sb := new(strings.Builder)
err = parsedTmpl.Execute(sb, vs)
if err != nil {
return "", err
}
return sb.String(), nil
default:
return "", fmt.Errorf("unknown format type: %v", formatType)
}
}