
介绍完简单的提示词补全流程后,我们看看输入提示词模板的实现,首先看看如何使用的例子
prompt := prompts.PromptTemplate{
Template: "你是一个文本翻译员,请将```括起来的原始文本转化为{{.lang}}。原始文本```{{.text}}```",
InputVariables: []string{"text"},
PartialVariables: map[string]any{
"lang": "英语",
},
TemplateFormat: prompts.TemplateFormatGoTemplate,
}
result, err := prompt.Format(map[string]any{
"text": "我是中国人",
})
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
result, err = llm.Call(ctx, result)可以看到,和前面介绍的例子不同的地方是,提示词里带有{{}}占位符号,里面填入了变量名称,然后调用Format传入一个map参数,进行模板替换,最后调用Call获取返回值。Template其实类似golang的模板,只不过按照LLM的需求进行了封装,其源码位于:github.com/tmc/langchaingo@v0.1.13/prompts/prompt_template.go
// PromptTemplate contains common fields for all prompt templates.
type PromptTemplate struct {
// Template is the prompt template.
Template string
// A list of variable names the prompt template expects.
InputVariables []string
// TemplateFormat is the format of the prompt template.
TemplateFormat TemplateFormat
// OutputParser is a function that parses the output of the prompt template.
OutputParser schema.OutputParser[any]
// PartialVariables represents a map of variable names to values or functions
// that return values. If the value is a function, it will be called when the
// prompt template is rendered.
PartialVariables map[string]any
}可以看到我们例子中其实有两个参数的,但是InputVariables里面只给了一个参数名字,因为另一个参数在本例中是固定的,所以放在PartialVariables里直接给出了。
然后我们看看Format函数,它先解析PartialVariables,就是把参数是里如果value是返回string的函数的参数,进行函数调用转化成string。然后进行模板渲染
func (p PromptTemplate) Format(values map[string]any) (string, error) {
resolvedValues, err := resolvePartialValues(p.PartialVariables, values)
if err != nil {
return "", err
}
return RenderTemplate(p.Template, p.TemplateFormat, resolvedValues)
}模板渲染支持三种类型的模板:go-template、jinjia2和f-string
func RenderTemplate(tmpl string, tmplFormat TemplateFormat, values map[string]any) (string, error) {
formatter, ok := defaultFormatterMapping[tmplFormat]
if !ok {
return "", newInvalidTemplateError(tmplFormat)
}
return formatter(tmpl, values)
}// defaultFormatterMapping is the default mapping of TemplateFormat to interpolator.
var defaultFormatterMapping = map[TemplateFormat]interpolator{ //nolint:gochecknoglobals
TemplateFormatGoTemplate: interpolateGoTemplate,
TemplateFormatJinja2: interpolateJinja2,
TemplateFormatFString: fstring.Format,
}const (
// TemplateFormatGoTemplate is the format for go-template.
TemplateFormatGoTemplate TemplateFormat = "go-template"
// TemplateFormatJinja2 is the format for jinja2.
TemplateFormatJinja2 TemplateFormat = "jinja2"
// TemplateFormatFString is the format for f-string.
TemplateFormatFString TemplateFormat = "f-string"
)以其中的go为例就是简单的模板渲染
// interpolateGoTemplate interpolates the given template with the given values by using
// text/template.
func interpolateGoTemplate(tmpl string, values map[string]any) (string, error) {
parsedTmpl, err := template.New("template").
Option("missingkey=error").
Funcs(sprig.TxtFuncMap()).
Parse(tmpl)
if err != nil {
return "", err
}
sb := new(strings.Builder)
err = parsedTmpl.Execute(sb, values)
if err != nil {
return "", err
}
return sb.String(), nil
}还记得上篇说过model定义了两个接口,其中第二个call方法没有介绍,这里刚好用到了,就介绍下
func (o *LLM) Call(ctx context.Context, prompt string, options ...llms.CallOption) (string, error) {
return llms.GenerateFromSinglePrompt(ctx, o, prompt, options...)
}可以看到内部还是调用了GenerateFromSinglePrompt方法,也就是GenerateContent,底层一模一样。
本文分享自 golang算法架构leetcode技术php 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!