ChatTemplate
视频讲解地址:点击直达
1. 模版化方式
ChatTemplate 支持多种模板化方式,最常见的包括:
- FString 格式:使用
{variable}
语法进行变量替换 - GoTemplate 格式:使用 Go 标准库的 text/template 语法,支持条件判断、循环等复杂逻辑
- Jinja2 格式:使用 Jinja2 模板语法
2. FString
代码:
func main() {
//这里先使用ollama的方式实现
ctx := context.Background()
model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://127.0.0.1:11434",
Model: "modelscope.cn/Qwen/Qwen3-32B-GGUF:latest",
})
if err != nil {
panic(err)
}
//创建message,这个就相当于给大模型的提示词,分为系统输入和用户输入
//系统输入就是预设的提示词,用户输入就是用户输入的内容
//message := []*schema.Message{
// schema.SystemMessage("你是一个乐于助人的助手"),
// schema.UserMessage("请介绍一下Go语言的特点"),
//}
template := prompt.FromMessages(
schema.FString,
schema.SystemMessage("你是一个{role}, 请用{tone}的语气回答问题"),
schema.UserMessage("{question}"),
)
vars := map[string]any{
"role": "技术专家",
"tone": "专业严谨",
"question": "如何优化数据库性能",
}
message, err := template.Format(ctx, vars)
//获取流式回复
stream, err := model.Stream(ctx, message)
if err != nil {
panic(err)
}
defer stream.Close()
for {
chunk, err := stream.Recv()
if err != nil {
break
}
print(chunk.Content)
}
//换行
println()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
3. GoTemplate
代码:
func main() {
//这里先使用ollama的方式实现
ctx := context.Background()
model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://127.0.0.1:11434",
Model: "modelscope.cn/Qwen/Qwen3-32B-GGUF:latest",
})
if err != nil {
panic(err)
}
//创建message,这个就相当于给大模型的提示词,分为系统输入和用户输入
//系统输入就是预设的提示词,用户输入就是用户输入的内容
//message := []*schema.Message{
// schema.SystemMessage("你是一个乐于助人的助手"),
// schema.UserMessage("请介绍一下Go语言的特点"),
//}
template := prompt.FromMessages(
schema.GoTemplate,
schema.SystemMessage("{{if .isExpert}}你是一个专家级{{.domain}}顾问。{{else}}你是一个初级{{.domain}}助手。{{end}}\n{{if .isFormal}}请使用正式的语言风格。{{else}}请使用友好的语言风格。{{end}}\n你的任务是{{.task}}。"),
schema.UserMessage("{{.question}}"),
)
//vars := map[string]any{
// "isExpert": true,
// "domain": "数据库",
// "isFormal": true,
// "task": "提供专业的数据库优化建议",
// "question": "如何优化大型数据库的查询性能?",
//}
vars := map[string]interface{}{
"isExpert": false,
"domain": "编程",
"isFormal": false,
"task": "帮助初学者理解编程概念",
"question": "什么是变量?",
}
message, err := template.Format(ctx, vars)
for _, v := range message {
println(v.Content)
}
//获取流式回复
stream, err := model.Stream(ctx, message)
if err != nil {
panic(err)
}
defer stream.Close()
for {
chunk, err := stream.Recv()
if err != nil {
break
}
print(chunk.Content)
}
//换行
println()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
4. Jinja2
代码:
func main() {
//这里先使用ollama的方式实现
ctx := context.Background()
model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://127.0.0.1:11434",
Model: "modelscope.cn/Qwen/Qwen3-32B-GGUF:latest",
})
if err != nil {
panic(err)
}
//创建message,这个就相当于给大模型的提示词,分为系统输入和用户输入
//系统输入就是预设的提示词,用户输入就是用户输入的内容
//message := []*schema.Message{
// schema.SystemMessage("你是一个乐于助人的助手"),
// schema.UserMessage("请介绍一下Go语言的特点"),
//}
template := prompt.FromMessages(
schema.Jinja2,
schema.SystemMessage(`{% if level == 'expert' %}你是一个专家级顾问。{% else %}你是一个初级助手。{% endif %}
{% if domain %}你专长于{{ domain }}领域。{% endif %}
请用{% if formal %}正式{% else %}友好{% endif %}的语气回答问题。`),
schema.UserMessage("{{question}}"),
)
//vars := map[string]any{
// "isExpert": true,
// "domain": "数据库",
// "isFormal": true,
// "task": "提供专业的数据库优化建议",
// "question": "如何优化大型数据库的查询性能?",
//}
vars := map[string]any{
"level": "expert",
"domain": "人工智能",
"formal": true,
"question": "请解释Transformer模型的工作原理。",
}
message, err := template.Format(ctx, vars)
for _, v := range message {
println(v.Content)
}
//获取流式回复
stream, err := model.Stream(ctx, message)
if err != nil {
panic(err)
}
defer stream.Close()
for {
chunk, err := stream.Recv()
if err != nil {
break
}
print(chunk.Content)
}
//换行
println()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
5. 对话历史
代码:
func main() {
//这里先使用ollama的方式实现
ctx := context.Background()
model, err := ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
BaseURL: "http://127.0.0.1:11434",
Model: "modelscope.cn/Qwen/Qwen3-32B-GGUF:latest",
})
if err != nil {
panic(err)
}
//创建message,这个就相当于给大模型的提示词,分为系统输入和用户输入
//系统输入就是预设的提示词,用户输入就是用户输入的内容
//message := []*schema.Message{
// schema.SystemMessage("你是一个乐于助人的助手"),
// schema.UserMessage("请介绍一下Go语言的特点"),
//}
template := prompt.FromMessages(
schema.GoTemplate,
schema.SystemMessage(`你是一个{{.role}},你的任务是{{.task}}。
请参考之前的对话历史来回答当前的问题`),
schema.MessagesPlaceholder("history", false),
schema.UserMessage("{{.question}}"),
)
vars := map[string]any{
"role": "记忆器",
"task": "根据用户提供的信息,给出准确的回答,如果历史中有答案,采用用户的答案",
"history": []*schema.Message{
schema.UserMessage("你好,我想了解一下Go语言的并发机制"),
schema.AssistantMessage("Go语言提供了goroutines和channels来支持并发编程。Goroutines是轻量级线程,channels用于goroutines之间的通信。", nil),
schema.UserMessage("你错了,Go语言只提供了go关键字来支持并发"),
},
"question": "Go语言的并发机制",
}
message, err := template.Format(ctx, vars)
for _, v := range message {
println(v.Content)
}
//获取流式回复
stream, err := model.Stream(ctx, message)
if err != nil {
panic(err)
}
defer stream.Close()
for {
chunk, err := stream.Recv()
if err != nil {
break
}
print(chunk.Content)
}
//换行
println()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54