Eino - ChatTemplate 的应用前言在 AI 应用开发中Prompt提示词是与大模型交互的核心。一个好的提示词工程能够让 AI 理解任务需求并生成高质量的回复。Eino 框架提供了强大的ChatTemplate功能支持模板化管理提示词、变量替换、多角色对话等高级特性。本文将详细介绍 ChatTemplate 的各种应用场景帮助你掌握提示词模板化的核心技能代码链接。一、ChatTemplate 概述1.1 什么是 ChatTemplateChatTemplate 是 Eino 框架中用于管理对话消息的模板结构它允许开发者模板化将提示词以模板形式定义运行时替换变量多角色支持支持 System、User、Assistant 等多种消息类型灵活格式化支持 FString 等多种格式化方式1.2 核心概念ChatTemplate ├── prompt.FromMessages() # 创建模板 ├── schema.FString # 格式化器类似 Python f-string ├── template.Format() # 格式化模板 └── Message Types ├── SystemMessage # 系统消息 ├── UserMessage # 用户消息 └── AssistantMessage # 助手消息二、基础用法变量替换2.1 简单变量替换var_replace.go展示了最基础的变量替换功能template:prompt.FromMessages(schema.FString,schema.SystemMessage(你是一个{role}),schema.UserMessage({question}),)variables:map[string]any{role:热爱运动的程序员,question:运动和工作哪个更重要,}messages,_:template.Format(ctx,variables)运行结果1. [system] 你是一个热爱运动的程序员。 2. [user] 运动和工作哪个更重要2.2 FString 格式化器schema.FString是一种类似 Python f-string 的格式化器使用{变量名}语法schema.SystemMessage(你是一个{role})// {role} 会被替换schema.UserMessage({question})// {question} 会被替换FString 特点语法简洁类似 Python f-string支持任意数量的变量变量不存在时返回错误2.3 完整代码解析funcmain(){// 1. 创建模板template:prompt.FromMessages(schema.FString,schema.SystemMessage(你是一个{role}),schema.UserMessage({question}),)// 2. 准备变量variables:map[string]any{role:热爱运动的程序员,question:运动和工作哪个更重要,}// 3. 格式化消息messages,err:template.Format(ctx,variables)iferr!nil{log.Fatalf(格式化失败: %v,err)}// 4. 查看生成的消息fori,msg:rangemessages{fmt.Printf(%d. [%s] %s\n,i1,msg.Role,msg.Content)}}三、模板复用结构化设计3.1 PromptTemplates 管理器var_replace.go中的PromptTemplates结构体展示了如何组织和管理多个模板typePromptTemplatesstruct{}// 翻译助手模板func(p*PromptTemplates)Translator(sourceLang,targetLangstring)prompt.ChatTemplate{returnprompt.FromMessages(schema.FString,schema.SystemMessage(fmt.Sprintf(你是一个专业的翻译助手。请将%s翻译成%s。\n要求\n1. 保持原文的语气和风格\n2. 确保翻译准确、流畅\n3. 只返回翻译结果不要添加解释,sourceLang,targetLang,)),schema.UserMessage({text}),)}3.2 多种模板类型翻译助手模板func(p*PromptTemplates)Translator(sourceLang,targetLangstring)prompt.ChatTemplate{returnprompt.FromMessages(schema.FString,schema.SystemMessage(fmt.Sprintf(你是一个专业的翻译助手。请将%s翻译成%s。\n要求\n1. 保持原文的语气和风格\n2. 确保翻译准确、流畅\n3. 只返回翻译结果不要添加解释,sourceLang,targetLang,)),schema.UserMessage({text}),)}// 使用示例template:templates.Translator(中文,英文)messages:template.Format(ctx,map[string]any{text:Eino 是一个强大的 AI 开发框架,})代码审查模板func(p*PromptTemplates)CodeReviewer(languagestring)prompt.ChatTemplate{returnprompt.FromMessages(schema.FString,schema.SystemMessage(fmt.Sprintf(你是一个资深的%s开发专家。请审查以下代码并提供\n1. 潜在的bug或问题\n2. 性能优化建议\n3. 代码风格改进建议\n4. 安全性评估,language,)),schema.UserMessage(请审查以下代码\n\n{language}\n{code}\n),)}// 使用示例template:templates.CodeReviewer(Go)messages:template.Format(ctx,map[string]any{language:go,code:func add(a, b int) int { return a b },})技术面试官模板func(p*PromptTemplates)TechInterviewer(position,levelstring)prompt.ChatTemplate{returnprompt.FromMessages(schema.FString,schema.SystemMessage(fmt.Sprintf(你是一位%s职位的面试官针对%s级别的候选人。\n请根据候选人的回答\n1. 评估答案的准确性和深度\n2. 提出有针对性的追问\n3. 给出建设性的反馈,position,level,)),schema.UserMessage(候选人回答{answer}\n\n请评估并追问。),)}// 使用示例template:templates.TechInterviewer(Go后端开发,中级)messages:template.Format(ctx,map[string]any{answer:goroutine 是 Go 语言的轻量级线程,})3.3 模板使用流程创建模板管理器 │ ▼ ┌─────────────────┐ │ PromptTemplates │ └────────┬────────┘ │ ├── Translator() ──────▶ 翻译助手模板 ├── CodeReviewer() ────▶ 代码审查模板 └── TechInterviewer() ▶ 技术面试模板 │ ▼ ┌────────────┐ │ Format(ctx,│ │ variables) │ └─────┬──────┘ │ ▼ ┌────────────┐ │ []*Message │ └────────────┘四、多角色消息4.1 支持的消息类型multi_type.go展示了 Eino 支持的多种消息类型template:prompt.FromMessages(schema.FString,// System: 系统提示定义 AI 的角色和行为schema.SystemMessage(你是{role}你的专长是{expertise}),// User: 用户消息schema.UserMessage(我的问题是{question}),// Assistant: AI 的历史回复用于多轮对话schema.AssistantMessage(我理解了让我思考一下...,[]schema.ToolCall{}),// User: 继续对话schema.UserMessage(请详细说明),)4.2 消息类型说明类型用途特点SystemMessage系统提示词定义 AI 角色、行为规则UserMessage用户消息用户输入AssistantMessage助手消息AI 历史回复支持多轮对话4.3 完整示例funcmain(){ctx:context.Background()template:prompt.FromMessages(schema.FString,schema.SystemMessage(你是{role}你的专长是{expertise}),schema.UserMessage(我的问题是{question}),schema.AssistantMessage(我理解了让我思考一下...,[]schema.ToolCall{}),schema.UserMessage(请详细说明),)variables:map[string]any{role:一位了解哲学的程序员,expertise:分析和取舍确定性问题,question:在不确定的环境中如何做出最佳决策,}messages,_:template.Format(ctx,variables)fori,msg:rangemessages{fmt.Printf(%d. [%s]\n %s\n\n,i1,msg.Role,msg.Content)}}运行结果1. [system] 你是一位了解哲学的程序员你的专长是分析和取舍确定性问题。 2. [user] 我的问题是在不确定的环境中如何做出最佳决策 3. [assistant] 我理解了让我思考一下... 4. [user] 请详细说明五、复杂数据结构5.1 结构体映射complex_logic.go展示了如何将复杂数据结构用于模板typeUserProfilestruct{NamestringAgeintIntersts[]stringVIPLevelint}// 准备用户数据user:UserProfile{Name:张三,Age:28,Interests:[]string{编程,阅读,旅行},VIPLevel:3,}variables:map[string]any{name:user.Name,age:user.Age,interests:fmt.Sprintf(%v,user.Interests),vip_level:user.VIPLevel,}5.2 模板中的多行文本template:prompt.FromMessages(schema.FString,schema.SystemMessage(你是一个智能推荐助手),schema.UserMessage(用户信息 姓名{name} 年龄{age} 兴趣{interests} VIP等级{vip_level} 请根据以上信息推荐合适的内容。),)5.3 格式化集合类型对于切片等集合类型需要使用fmt.Sprintf或strings.Join转换// 方式1: 使用 fmt.Sprintfinterests:fmt.Sprintf(%v,user.Interests)// 输出: [编程 阅读 旅行]// 方式2: 使用 strings.Joininterests:strings.Join(user.Interests,、)// 输出: 编程、阅读、旅行5.4 完整示例funcmain(){template:prompt.FromMessages(schema.FString,schema.SystemMessage(你是一个智能推荐助手),schema.UserMessage(用户信息 姓名{name} 年龄{age} 兴趣{interests} VIP等级{vip_level} 请根据以上信息推荐合适的内容。),)user:UserProfile{Name:张三,Age:28,Intersts:[]string{编程,阅读,旅行},VIPLevel:3,}variables:map[string]any{name:user.Name,age:user.Age,interests:fmt.Sprintf(%v,user.Interests),vip_level:user.VIPLevel,}messages,_:template.Format(ctx,variables)for_,msg:rangemessages{fmt.Printf([%s]\n%s\n\n,msg.Role,msg.Content)}}运行结果[system] 你是一个智能推荐助手 [user] 用户信息 姓名张三 年龄28 兴趣[编程 阅读 旅行] VIP等级3 请根据以上信息推荐合适的内容。六、与大模型结合6.1 完整调用流程model_multiplex.go展示了将 ChatTemplate 与大模型结合的完整流程funcmain(){// 1. 加载配置cfg,_:loadConfig(*configPath)// 2. 创建 ChatTemplatetemplate:prompt.FromMessages(schema.FString,schema.SystemMessage(你是一个{role}),schema.UserMessage({question}),)// 3. 准备变量variables:map[string]any{role:热爱运动的程序员,question:运动和工作哪个更重要,}// 4. 格式化消息messages,_:template.Format(ctx,variables)// 5. 查看生成的消息fori,msg:rangemessages{fmt.Printf(%d. [%s] %s\n,i1,msg.Role,msg.Content)}// 6. 创建 ChatModelchatModel,_:openai.NewChatModel(ctx,openai.ChatModelConfig{APIKey:cfg.Model.APIKey,Model:cfg.Model.ModelName,BaseURL:cfg.Model.BaseURL,})// 7. 生成响应response,_:chatModel.Generate(ctx,messages)fmt.Printf(\nAI 回答:\n%s\n,response.Content)}6.2 流程图┌─────────────────────────────────────────────────────────────┐ │ 完整调用流程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────┐ │ │ │ 1. 配置加载 │ loadConfig(config.yml) │ │ └──────┬───────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ 2. 创建模板 │ prompt.FromMessages(...) │ │ └──────┬───────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ ┌─────────────┐ │ │ │ 3. 准备变量 │───▶│ variables │ │ │ └──────┬───────┘ └─────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ 4. 格式化消息 │ template.Format(ctx, variables) │ │ └──────┬───────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ ┌─────────────┐ │ │ │ 5. 创建模型 │───▶│ ChatModel │ │ │ └──────┬───────┘ └─────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────┐ │ │ │ 6. 生成响应 │ chatModel.Generate(ctx, messages) │ │ └──────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘七、最佳实践7.1 提示词设计原则原则说明示例角色明确指定 AI 扮演的角色“你是一个专业的翻译助手”任务清晰明确说明要做什么“请将以下中文翻译成英文”格式要求说明输出格式要求“只输出译文不要添加解释”约束条件说明限制或禁止项“不要添加引号”7.2 模板组织建议// 推荐使用结构体管理模板typePromptTemplatesstruct{}// 推荐函数返回模板而非直接使用func(p*PromptTemplates)Translator(sourceLang,targetLangstring)prompt.ChatTemplate{returnprompt.FromMessages(...)}// 不推荐每次创建新模板template:prompt.FromMessages(...)// 重复代码7.3 变量命名规范// 推荐清晰的变量名variables:map[string]any{source_lang:中文,target_lang:英文,text:Hello,}// 不推荐模糊的变量名variables:map[string]any{s:中文,t:英文,x:Hello,}7.4 错误处理messages,err:template.Format(ctx,variables)iferr!nil{// 检查变量缺失等错误log.Fatalf(格式化失败: %v,err)}response,err:chatModel.Generate(ctx,messages)iferr!nil{// 处理 API 调用错误log.Printf(生成失败: %v,err)}八、配置管理8.1 配置文件结构model:base_url:https://api.minimaxi.com/v1api_key:your-api-keymodel_name:MiniMax-M2.7timeout:30temperature:0.7top_p:0.9max_tokens:500app:host:0.0.0.0port:80808.2 配置加载typeConfigstruct{Model ModelConfigyaml:modelApp AppConfigyaml:app}typeModelConfigstruct{BaseURLstringyaml:base_urlAPIKeystringyaml:api_keyModelNamestringyaml:model_nameTimeoutintyaml:timeoutTemperaturefloat64yaml:temperatureTopPfloat64yaml:top_pMaxTokensintyaml:max_tokens}funcloadConfig(configPathstring)(*Config,error){data,err:os.ReadFile(configPath)iferr!nil{returnnil,fmt.Errorf(读取配置文件失败: %w,err)}varconfig Configiferr:yaml.Unmarshal(data,config);err!nil{returnnil,fmt.Errorf(解析配置文件失败: %w,err)}returnconfig,nil}8.3 命令行参数funcmain(){configPath:flag.String(config,config.yml,配置文件路径)flag.Parse()cfg,err:loadConfig(*configPath)iferr!nil{log.Fatalf(加载配置失败: %v,err)}}九、运行示例9.1 var_replace.gogo run var_replace.go-config../config.yml输出示例 翻译示例 翻译结果: Eino is a powerful AI development framework 代码审查示例 审查结果: 1. **潜在bug**: 代码没有错误处理建议添加... 面试官示例 面试官反馈: 很好你对 goroutine 的理解基本正确...9.2 model_multiplex.gogo run model_multiplex.go-config../config.yml输出示例生成的消息: 1. [system] 你是一个热爱运动的程序员。 2. [user] 运动和工作哪个更重要 AI 回答: 运动和工作都很重要...9.3 multi_type.gogo run multi_type.go输出示例1. [system] 你是一位了解哲学的程序员你的专长是分析和取舍确定性问题。 2. [user] 我的问题是在不确定的环境中如何做出最佳决策 3. [assistant] 我理解了让我思考一下... 4. [user] 请详细说明9.4 complex_logic.gogo run complex_logic.go输出示例[system] 你是一个智能推荐助手 [user] 用户信息 姓名张三 年龄28 兴趣[编程 阅读 旅行] VIP等级3 请根据以上信息推荐合适的内容。十、总结10.1 核心功能回顾功能说明示例文件变量替换模板中动态替换变量var_replace.go模板复用通过函数封装模板创建var_replace.go多角色System/User/Assistantmulti_type.go复杂数据结构体、切片等complex_logic.go模型结合模板 大模型调用model_multiplex.go10.2 ChatTemplate 优势可维护性模板与代码分离便于修改可复用性一次定义多次使用可测试性模板可以独立测试可读性清晰的提示词结构10.3 进阶主题模板组合多个模板组合使用条件渲染根据变量决定渲染内容模板校验验证变量完整性模板缓存避免重复创建模板通过本文的学习你应该掌握了ChatTemplate 基础创建、格式化、变量替换多角色消息System、User、Assistant 消息模板管理结构化组织多个模板工程实践配置管理、错误处理、最佳实践ChatTemplate 是 Eino 框架中处理提示词的核心组件掌握它能够让你的 AI 应用开发更加高效和规范。