在使用大语言模型(LLM)时,提示词(Prompt)是与模型交互的关键。良好的提示词设计能够显著提升模型输出的质量。本文将基于langchaingo库,详细介绍Go语言中处理提示词的几种主要方式。
1. 引言
在与大语言模型交互时,提示词的设计至关重要。LangChain框架提供了一套完整的提示词处理工具,使得我们能够更好地控制和优化与模型的交互。本文将通过实际代码示例,介绍在Go语言中使用langchaingo库处理提示词的几种主要方式。
2. 基础提示词模板(PromptTemplate)
最简单的提示词处理方式是使用基础提示词模板。这种方式适用于单轮对话或简单的文本生成任务。
func TestPrompt(test *testing.T) {
llm := getLLmOpenaiClientNew(test)
// 创建一个模板
// 参数一:prompt
// 参数二: 提示模板所需的变量名称列表。
template := prompts.NewPromptTemplate("请你为{{.dep}}部门的新入职员工{{.name}}设计一个自我介绍", []string{
"dep",
"name",
})
staff := map[string]any{
"name": "木兮",
"dep": "go语言开发",
}
prompt, err := template.FormatPrompt(staff)
NoError(err)
log.Println("prompt:", prompt.String())
singlePrompt, err := llms.GenerateFromSinglePrompt(context.Background(), llm, prompt.String())
NoError(err)
log.Println(singlePrompt)
}
在这个例子中,我们创建了一个带有两个变量(dep和name)的提示词模板,并通过传入具体的值来生成最终的提示词。这种方式简单直接,适用于大多数基础场景。
3. 聊天提示词模板(ChatPromptTemplate)
对于需要多轮对话或角色设定的场景,我们可以使用聊天提示词模板。这种方式允许我们定义系统消息和用户消息,从而更好地控制对话上下文。
1 func TestChat(test *testing.T) { 2 template := prompts.NewChatPromptTemplate([]prompts.MessageFormatter{ 3 prompts.NewSystemMessagePromptTemplate("你是一个小学的{{.position}},可以根据学生的成绩指定教学计划", []string{ 4 "position", 5 }), 6 prompts.NewHumanMessagePromptTemplate("我叫{{.name}} 我{{.subjects}}考了{{.scores}}", []string{ 7 "name", 8 "scores", 9 "subjects", 10 }), 11 }) 12 val, err := template.FormatPrompt(map[string]any{ 13 "name": "小王", 14 "scores": "15", 15 "position": "老师", 16 "subjects": "数学", 17 }) 18 NoError(err) 19 //=== RUN TestChat 20 //2025/09/18 15:51:13 system: 你是一个小学的老师,可以根据学生的成绩指定教学计划 21 //Human: 我叫小王 我数学考了15 22 //--- PASS: TestChat (0.00s) 23 log.Println(val.String()) 24 25 llm := getLLmOpenaiClientNew(test) 26 prompt, err := llms.GenerateFromSinglePrompt(context.Background(), llm, val.String()) 27 NoError(err) 28 //2025/09/18 15:54:40 小王!你的数学成绩是15分,算是中等水平。根据你的成绩,我们可以制定一个针对性的教学计划来帮助你提高你的数学能力。 29 // 30 //首先,我们需要了解你的数学知识基础。我们来看看一下,你的数学知识点包括哪些: 31 // 32 //* 数学运算(加、减、乘、除):15分 33 //* 数形识别:14分 34 //* 数学概念(数列、几何级数、图形):13分 35 //* 问题解答能力:12分 36 log.Println(prompt) 37 38 }
在上述代码中,我们定义了两个消息模板:
系统消息模板:设定模型的角色
人类消息模板:模拟用户的输入
这种方式特别适用于需要明确角色设定的对话场景,能够更好地引导模型产生符合预期的输出。
4. 少样本提示(FewShot Prompt)
在某些场景下,我们可能需要通过提供示例来引导模型生成特定格式的输出。这时可以使用少样本提示:
1 func TestFormat(test *testing.T) { 2 example := []map[string]string{ 3 {"name": "小王", "dep": "go 语言部门", "introduce": "大家好,我是小王 ,我有5年工作经验,很高兴加入"}, 4 {"name": "李正阳", "dep": "php 语言部门", "introduce": "大家好,我是李正阳 ,我有10年工作经验,很高兴加入"}, 5 } 6 template := prompts.NewPromptTemplate("员工:{{.name}} \n部门:{{.dep}}\n介绍:{{.introduce}}", 7 []string{"name", "dep", "introduce"}) 8 9 //NewFewShotPrompt 使用给定的输入创建一个新的 few-shot 提示。如果没有示例,则返回错误,同时提供了示例和 exampleSelector,或者当 ValidateTemplate 为 true 时,CheckValidTemplate 返回错误 10 prompt, err := prompts.NewFewShotPrompt(template, example, nil, "请根据以下例子参考写出他们的入职介绍", 11 "请你为{{.sdep}}部门入职的员工{{.sname}}设计一个自我介绍", 12 []string{"prefId", "sdep", "sname"}, map[string]interface{}{ 13 "prefId": func() string { 14 return "id" 15 }, 16 "prefixCtx": "测试", 17 }, "\n", prompts.TemplateFormatGoTemplate, false) 18 NoError(err) 19 formatPrompt, err := prompt.FormatPrompt(map[string]any{ 20 "sname": "木兮", 21 "sdep": "刘灿", 22 }) 23 NoError(err) 24 log.Println(formatPrompt.String()) 25 llm := getLLmOpenaiClientNew(test) 26 res, err := llms.GenerateFromSinglePrompt(context.Background(), llm, formatPrompt.String()) 27 NoError(err) 28 log.Println(res) 29 //=== RUN TestFormat 30 //2025/09/18 16:25:05 请根据以下例子参考写出他们的入职介绍 31 //员工:小王 32 //部门:go 语言部门 33 //介绍:大家好,我是小王 ,我有5年工作经验,很高兴加入 34 //员工:李正阳 35 //部门:php 语言部门 36 //介绍:大家好,我是李正阳 ,我有10年工作经验,很高兴加入 37 //请你为刘灿部门入职的员工木兮设计一个自我介绍 38 //2025/09/18 16:25:11 根据例子,可以写出以下自我介绍: 39 // 40 //员工:木兮 41 //部门:后端开发部门 42 //介绍:大家好,我是木兮 ,我有8年工作经验,专注于后端开发,很高兴加入我们的团队。 43 //--- PASS: TestFormat (6.24s) 44 //PASS 45 46 }
通过提供具体的示例,模型能够更好地理解我们期望的输出格式和内容风格,从而生成更符合要求的结果。
6. 总结
通过langchaingo库,我们可以方便地处理各种类型的提示词:
基础提示词模板:适用于简单文本生成任务
聊天提示词模板:适用于多轮对话和角色设定场景
少样本提示:通过示例引导模型生成特定格式的输出
在实际应用中,应根据具体需求选择合适的提示词处理方式。良好的提示词设计不仅能提高模型输出的质量,还能更好地控制模型的行为,使其更符合业务需求。
通过熟练掌握这些提示词处理技巧,我们能够更有效地利用大语言模型的能力,构建出更智能、更实用的应用程序。