仿照豆包实现 Prompt 变量模板输入框

发布时间:2026/7/25 23:44:43
仿照豆包实现 Prompt 变量模板输入框 仿照豆包实现 Prompt 变量模板输入框引言为什么需要变量模板输入框在 AI 应用开发中我们经常需要让用户自定义 Prompt提示词模板。比如在豆包字节跳动的 AI 助手中用户可以在输入框中插入{变量名}这样的占位符系统会自动替换成实际内容。这种设计既灵活又易用非常适合做对话系统、自动写作工具或客服机器人。如果你正在开发类似的产品可能会遇到这样的需求用户输入一个模板比如“写一封关于 {主题} 的邮件”然后程序自动把{主题}替换成用户指定的内容。本文将教你怎么用 Python 实现这个功能从基础替换到完整交互界面。## 核心原理字符串模板替换### 1. 基础替换方法Python 中可以用str.replace()或str.format()实现简单替换。但最灵活的方式是使用正则表达式来提取变量名。pythonimport redef parse_prompt_template(template: str, variables: dict) - str: 解析 Prompt 模板将 {变量名} 替换为实际值 参数: template: 包含 {变量名} 的模板字符串 variables: 变量名到值的映射字典 返回: 替换后的完整字符串 # 正则匹配所有 {变量名} 格式的占位符 # 注意变量名只能包含字母、数字和下划线 pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} def replace_match(match): # match.group(0) 是整个匹配如 {name} # match.group(1) 是括号内的变量名如 name var_name match.group(1) if var_name in variables: return str(variables[var_name]) else: # 如果变量未定义保留原样或抛出异常 # 这里选择保留原样方便用户调试 return match.group(0) return re.sub(pattern, replace_match, template)# 使用示例template 你好{name}今天是{date}天气{weather}。variables { name: 小明, date: 2024年1月15日, weather: 晴朗}result parse_prompt_template(template, variables)print(result) # 输出你好小明今天是2024年1月15日天气晴朗。这段代码的核心是正则表达式r\{([a-zA-Z_][a-zA-Z0-9_]*)\}它匹配所有形如{变量名}的占位符。re.sub函数会遍历所有匹配并用replace_match回调函数进行替换。如果某个变量没有提供值我们选择保留原始占位符这样用户能立刻发现问题。### 2. 提取所有变量名有时候我们需要先让用户输入变量值再执行替换。比如在 GUI 中先解析模板里有哪些变量然后生成对应的输入框。pythonimport redef extract_variables(template: str) - list: 从模板中提取所有变量名 参数: template: 包含 {变量名} 的模板字符串 返回: 变量名列表按出现顺序 pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} # findall 返回所有匹配的变量名括号内的部分 variables re.findall(pattern, template) return list(dict.fromkeys(variables)) # 去重但保持顺序# 使用示例template 写一封关于{主题}的邮件发送给{收件人}语气要{语气}vars_needed extract_variables(template)print(需要输入的变量, vars_needed)# 输出需要输入的变量 [主题, 收件人, 语气]这里用dict.fromkeys()去重同时保持变量在模板中首次出现的顺序。这样在生成输入框时用户能按逻辑顺序填写。## 构建完整的交互界面### 用 Tkinter 实现可视化模板输入框下面我们用 Python 内置的 Tkinter 库仿照豆包的样子做一个完整的变量模板输入工具。这个例子包含三个部分模板输入区、变量输入区、结果预览区。pythonimport tkinter as tkfrom tkinter import ttk, scrolledtextimport reclass PromptTemplateApp: def __init__(self, root): self.root root self.root.title(Prompt 变量模板输入框 - 仿豆包风格) self.root.geometry(700x600) # 1. 模板输入区 tk.Label(root, text输入模板使用 {变量名} 作为占位符, font(Arial, 12)).pack(pady10) self.template_entry scrolledtext.ScrolledText( root, height5, width80, font(Arial, 11) ) self.template_entry.pack(padx20, pady5) # 2. 解析按钮 self.parse_button tk.Button( root, text解析变量, commandself.parse_variables, bg#4CAF50, fgwhite, font(Arial, 11) ) self.parse_button.pack(pady10) # 3. 变量输入区动态生成 self.variables_frame tk.LabelFrame(root, text变量值输入, font(Arial, 12)) self.variables_frame.pack(pady10, padx20, fillx) self.variable_entries {} # 存储变量名到输入框的映射 # 4. 生成按钮和结果 self.generate_button tk.Button( root, text生成最终 Prompt, commandself.generate_prompt, bg#2196F3, fgwhite, font(Arial, 11) ) self.generate_button.pack(pady10) self.result_text scrolledtext.ScrolledText( root, height6, width80, font(Arial, 11), bg#f0f0f0, statedisabled ) self.result_text.pack(padx20, pady5) def extract_variables(self, template): 提取模板中的变量名 pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} variables re.findall(pattern, template) return list(dict.fromkeys(variables)) def parse_variables(self): 解析模板并生成变量输入框 # 清空旧的变量输入框 for widget in self.variables_frame.winfo_children(): widget.destroy() self.variable_entries.clear() template self.template_entry.get(1.0, tk.END).strip() if not template: return variables self.extract_variables(template) if not variables: tk.messagebox.showinfo(提示, 模板中没有找到变量占位符) return # 动态生成变量输入框 for var_name in variables: frame tk.Frame(self.variables_frame) frame.pack(fillx, padx10, pady5) label tk.Label(frame, textf{var_name}, width15, anchorw, font(Arial, 11)) label.pack(sideleft) entry tk.Entry(frame, font(Arial, 11)) entry.pack(sideleft, fillx, expandTrue) self.variable_entries[var_name] entry def generate_prompt(self): 根据模板和变量值生成最终结果 template self.template_entry.get(1.0, tk.END).strip() if not template: return # 收集变量值 variables {} for var_name, entry in self.variable_entries.items(): value entry.get().strip() if value: variables[var_name] value # 执行替换 pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} def replace_match(match): var_name match.group(1) if var_name in variables: return variables[var_name] return match.group(0) result re.sub(pattern, replace_match, template) # 显示结果 self.result_text.config(statenormal) self.result_text.delete(1.0, tk.END) self.result_text.insert(1.0, result) self.result_text.config(statedisabled)# 运行应用if __name__ __main__: root tk.Tk() app PromptTemplateApp(root) root.mainloop()这个程序的工作流程是1. 用户在顶部文本框输入模板比如写一封关于{主题}的邮件语气要{语气}2. 点击“解析变量”按钮程序自动提取{主题}和{语气}并在下方生成对应的输入框3. 用户填入具体值比如“产品发布”和“正式”4. 点击“生成最终 Prompt”程序替换占位符并显示结果## 进阶优化实时预览与错误处理在实际产品中你可能希望用户输入模板时就能实时看到变量列表或者在变量值变化时自动更新预览。下面是一个优化版本pythonimport tkinter as tkfrom tkinter import scrolledtextimport reclass SmartPromptEditor: def __init__(self, root): self.root root self.root.title(智能 Prompt 编辑器) self.root.geometry(800x600) # 主布局左右分栏 main_frame tk.Frame(root) main_frame.pack(fillboth, expandTrue, padx10, pady10) # 左侧模板编辑区 left_frame tk.Frame(main_frame) left_frame.pack(sideleft, fillboth, expandTrue, padx5) tk.Label(left_frame, text模板编辑, font(Arial, 14, bold)).pack() self.template_text scrolledtext.ScrolledText( left_frame, height8, font(Arial, 11) ) self.template_text.pack(fillboth, expandTrue) self.template_text.bind(KeyRelease, self.on_template_change) # 变量状态显示 self.var_status tk.Label(left_frame, text检测到 0 个变量, font(Arial, 10), fggray) self.var_status.pack(anchorw) # 右侧变量输入区 right_frame tk.Frame(main_frame) right_frame.pack(sideright, fillboth, expandTrue, padx5) tk.Label(right_frame, text变量值, font(Arial, 14, bold)).pack() self.var_canvas tk.Canvas(right_frame, bgwhite) self.var_scrollbar tk.Scrollbar(right_frame, orientvertical, commandself.var_canvas.yview) self.var_inner_frame tk.Frame(self.var_canvas) self.var_canvas.configure(yscrollcommandself.var_scrollbar.set) self.var_scrollbar.pack(sideright, filly) self.var_canvas.pack(sideleft, fillboth, expandTrue) self.var_canvas.create_window((0, 0), windowself.var_inner_frame, anchornw) self.var_inner_frame.bind(Configure, lambda e: self.var_canvas.configure(scrollregionself.var_canvas.bbox(all))) # 底部预览区 bottom_frame tk.Frame(root) bottom_frame.pack(fillx, padx10, pady5) tk.Label(bottom_frame, text实时预览, font(Arial, 12, bold)).pack(anchorw) self.preview_text scrolledtext.ScrolledText( bottom_frame, height4, font(Arial, 11), bg#f9f9f9 ) self.preview_text.pack(fillx) # 初始化变量存储 self.variable_widgets {} self.current_variables [] def extract_variables(self, template): pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} variables re.findall(pattern, template) return list(dict.fromkeys(variables)) def on_template_change(self, eventNone): template self.template_text.get(1.0, tk.END).strip() variables self.extract_variables(template) # 更新变量状态显示 self.var_status.config(textf检测到 {len(variables)} 个变量) # 更新变量输入区 self.update_variable_inputs(variables) # 更新预览 self.update_preview() def update_variable_inputs(self, new_variables): # 清除旧输入框 for widget in self.var_inner_frame.winfo_children(): widget.destroy() self.variable_widgets.clear() # 创建新输入框 for var_name in new_variables: frame tk.Frame(self.var_inner_frame) frame.pack(fillx, padx5, pady3) label tk.Label(frame, textf{var_name}:, width15, anchorw, font(Arial, 10)) label.pack(sideleft) entry tk.Entry(frame, font(Arial, 10)) entry.pack(sideleft, fillx, expandTrue) entry.bind(KeyRelease, lambda e: self.update_preview()) self.variable_widgets[var_name] entry self.current_variables new_variables def update_preview(self): template self.template_text.get(1.0, tk.END).strip() if not template: return # 收集变量值 variables {} for var_name, entry in self.variable_widgets.items(): value entry.get().strip() if value: variables[var_name] value # 执行替换 pattern r\{([a-zA-Z_][a-zA-Z0-9_]*)\} def replace_match(match): var_name match.group(1) if var_name in variables: return variables[var_name] return f[{var_name}] # 未填写的变量用中括号标记 result re.sub(pattern, replace_match, template) # 更新预览 self.preview_text.delete(1.0, tk.END) self.preview_text.insert(1.0, result)# 运行if __name__ __main__: root tk.Tk() app SmartPromptEditor(root) root.mainloop()这个版本实现了实时更新当用户输入模板或变量值时预览区会自动更新。未填写的变量会被标记为[变量名]方便用户识别。## 总结本文从基本原理出发逐步演示了如何仿照豆包实现 Prompt 变量模板输入框。核心要点包括1.正则表达式提取变量使用re.findall或re.sub处理{变量名}占位符2.动态 UI 生成根据解析出的变量名动态创建对应的输入控件3.实时预览通过绑定事件让用户能即时看到替换结果在实际项目中你可以进一步扩展这个思路- 支持嵌套变量如{用户.姓名}- 添加默认值或提示文本- 集成到 Web 应用使用 Flask/Django 或前端框架- 增加语法检查防止变量名冲突变量模板输入框看似简单却是提升 AI 应用用户体验的关键组件。希望本文能帮助你在自己的项目中实现类似功能。