构建影墨·今颜提示词库:数据库设计与管理系统开发
构建影墨·今颜提示词库数据库设计与管理系统开发最近在尝试用AI生成一些小红书风格的图片和文案效果时好时坏挺看运气的。后来我发现问题的关键往往出在“提示词”上。一个好的提示词能直接决定生成内容的质量和风格。于是我就想能不能把这些好用的提示词都攒起来分门别类地管理好下次用的时候直接调用岂不是省时省力这个想法催生了“影墨·今颜”提示词库项目。它的核心很简单建一个数据库把那些验证过的好提示词、对应的生成参数和效果评分都存进去然后再做个简单的网页来管理它们。这听起来像不像一个经典的“数据库课程设计”项目没错它就是一个非常贴近实际应用场景的数据库实践。今天我就来分享一下这个从想法到实现的完整过程希望能给想做类似工具的朋友一些启发。1. 需求分析与数据库设计做任何系统第一步都是想清楚要干什么。对于提示词库我们的核心需求很明确存得好、找得快、用得方便。具体来说我们需要存储和管理以下几类信息提示词本身这是核心包括正向提示词描述想要什么和负向提示词描述不想要什么。生成参数比如用哪个模型、采样方法、迭代步数、图片尺寸等。这些参数和提示词搭配才能复现出好效果。分类与标签提示词千千万没有分类就像大海捞针。我们需要按风格如“国风”、“ins风”、按内容如“美食”、“穿搭”、按用途如“封面图”、“商品图”来打标签。效果评价这个词条生成的效果到底怎么样是“惊艳”还是“一般”需要有一个地方让使用者打分或写评语方便后续筛选优质词条。预览与关联光看文字描述不够直观最好能关联上用它生成的效果图。一个提示词可能对应多张效果图尝试了不同参数一张效果图也可能由多个提示词组合生成。基于这些需求我开始设计数据库表。这里我选择了最常用的MySQL。设计的原则是避免数据冗余建立清晰的关联关系。1.1 核心表结构设计我设计了五张核心表它们之间的关系可以用一个简单的图来理解提示词是中心它拥有参数被打上标签收获了评分并关联着效果图。-- 1. 提示词主表 (prompts) CREATE TABLE prompts ( id INT PRIMARY KEY AUTO_INCREMENT, positive_prompt TEXT NOT NULL COMMENT 正向提示词, negative_prompt TEXT COMMENT 负向提示词, description VARCHAR(500) COMMENT 词条描述、使用心得, author VARCHAR(100) COMMENT 贡献者, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, is_public BOOLEAN DEFAULT TRUE COMMENT 是否公开 ); -- 2. 生成参数表 (generation_params) CREATE TABLE generation_params ( id INT PRIMARY KEY AUTO_INCREMENT, prompt_id INT NOT NULL, model_name VARCHAR(100) COMMENT 如 stable-diffusion-v1.5, sampler VARCHAR(50) COMMENT 采样器如 Euler a, steps INT DEFAULT 20, cfg_scale DECIMAL(3,1) DEFAULT 7.5 COMMENT 提示词相关性, width INT DEFAULT 512, height INT DEFAULT 512, seed BIGINT COMMENT 随机种子用于复现, FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE ); -- 3. 标签表 (tags) 与关联表 (prompt_tags) CREATE TABLE tags ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) UNIQUE NOT NULL COMMENT 标签名如“国风”、“美食”, type VARCHAR(20) COMMENT 标签类型style, content, usage等 ); CREATE TABLE prompt_tags ( prompt_id INT, tag_id INT, PRIMARY KEY (prompt_id, tag_id), FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE, FOREIGN KEY (tag_id) REFERENCES tags(id) ON DELETE CASCADE ); -- 4. 效果评分表 (ratings) CREATE TABLE ratings ( id INT PRIMARY KEY AUTO_INCREMENT, prompt_id INT NOT NULL, user_id VARCHAR(100) COMMENT 评分用户标识, score TINYINT CHECK (score 1 AND score 5) COMMENT 1-5分, comment TEXT COMMENT 评价详情, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE ); -- 5. 效果图表 (preview_images) CREATE TABLE preview_images ( id INT PRIMARY KEY AUTO_INCREMENT, prompt_id INT NOT NULL, param_id INT COMMENT 关联的具体参数id, image_url VARCHAR(500) NOT NULL COMMENT 图片存储路径或URL, thumbnail_url VARCHAR(500) COMMENT 缩略图路径, generated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (prompt_id) REFERENCES prompts(id) ON DELETE CASCADE, FOREIGN KEY (param_id) REFERENCES generation_params(id) ON DELETE SET NULL );这个设计有几个考虑点灵活性一个提示词可以对应多套参数generation_params方便记录哪种参数组合效果最好。可扩展性标签系统tagsprompt_tags可以随时增加新标签分类维度不受限。数据完整性使用外键约束FOREIGN KEY和级联删除ON DELETE CASCADE确保删除一个提示词时它的参数、标签关联、评分和图片记录也被清理干净避免垃圾数据。性能考虑为经常查询的字段如prompt_id,tag_id以及tags.name建立了索引加快搜索速度。2. 管理系统后端开发数据库设计好了接下来就要让数据“活”起来也就是开发后端API。我选择了Python的Flask框架因为它轻量、灵活适合快速构建这种管理系统的后端。2.1 环境搭建与核心接口首先建立数据库连接并规划出系统需要提供的核心功能接口。# app.py from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy from datetime import datetime app Flask(__name__) app.config[SQLALCHEMY_DATABASE_URI] mysqlpymysql://username:passwordlocalhost/prompt_lib_db app.config[SQLALCHEMY_TRACK_MODIFICATIONS] False db SQLAlchemy(app) # 这里将之前SQL定义的模型用SQLAlchemy的ORM方式重新定义一遍示例仅展示Prompt模型 class Prompt(db.Model): __tablename__ prompts id db.Column(db.Integer, primary_keyTrue) positive_prompt db.Column(db.Text, nullableFalse) negative_prompt db.Column(db.Text) description db.Column(db.String(500)) author db.Column(db.String(100)) created_at db.Column(db.DateTime, defaultdatetime.utcnow) updated_at db.Column(db.DateTime, defaultdatetime.utcnow, onupdatedatetime.utcnow) is_public db.Column(db.Boolean, defaultTrue) # 定义关系 params db.relationship(GenerationParam, backrefprompt, cascadeall, delete-orphan) tags db.relationship(Tag, secondaryprompt_tags, backrefprompts) ratings db.relationship(Rating, backrefprompt, cascadeall, delete-orphan) previews db.relationship(PreviewImage, backrefprompt, cascadeall, delete-orphan) # 其他模型GenerationParam, Tag, Rating, PreviewImage的定义类似此处省略... # 创建数据库表首次运行 with app.app_context(): db.create_all()接下来实现最关键的提示词管理和查询检索接口。# 1. 创建新的提示词条目 app.route(/api/prompts, methods[POST]) def create_prompt(): data request.json try: new_prompt Prompt( positive_promptdata[positive_prompt], negative_promptdata.get(negative_prompt, ), descriptiondata.get(description, ), authordata.get(author, anonymous) ) # 处理标签假设前端传标签名数组如 [国风, 美食] tag_names data.get(tags, []) for name in tag_names: tag Tag.query.filter_by(namename).first() if not tag: tag Tag(namename) db.session.add(tag) new_prompt.tags.append(tag) # 处理参数 if params in data: param_data data[params] new_param GenerationParam( model_nameparam_data.get(model_name), samplerparam_data.get(sampler), stepsparam_data.get(steps, 20), cfg_scaleparam_data.get(cfg_scale, 7.5), widthparam_data.get(width, 512), heightparam_data.get(height, 512), seedparam_data.get(seed) ) new_prompt.params.append(new_param) db.session.add(new_prompt) db.session.commit() return jsonify({message: 创建成功, id: new_prompt.id}), 201 except Exception as e: db.session.rollback() return jsonify({error: str(e)}), 500 # 2. 多功能查询提示词核心 app.route(/api/prompts, methods[GET]) def get_prompts(): # 获取查询参数 keyword request.args.get(q, ) # 关键词搜索 tag_name request.args.get(tag) # 按标签筛选 page int(request.args.get(page, 1)) per_page int(request.args.get(per_page, 20)) # 构建查询 query Prompt.query.filter(Prompt.is_public True) if keyword: query query.filter(db.or_( Prompt.positive_prompt.contains(keyword), Prompt.description.contains(keyword) )) if tag_name: query query.join(Prompt.tags).filter(Tag.name tag_name) # 排序和分页 prompts query.order_by(Prompt.updated_at.desc()).paginate(pagepage, per_pageper_page, error_outFalse) # 构造返回数据 result { items: [{ id: p.id, positive_prompt: p.positive_prompt[:200] ... if len(p.positive_prompt) 200 else p.positive_prompt, description: p.description, author: p.author, tags: [tag.name for tag in p.tags], preview: p.previews[0].thumbnail_url if p.previews else None # 取第一张预览图 } for p in prompts.items], total: prompts.total, page: page, per_page: per_page } return jsonify(result)2.2 效果预览与评分功能为了让词库更直观、更有参考价值预览和评分功能必不可少。# 3. 为提示词上传效果预览图 app.route(/api/prompts/int:prompt_id/previews, methods[POST]) def upload_preview(prompt_id): prompt Prompt.query.get_or_404(prompt_id) if image not in request.files: return jsonify({error: 没有文件上传}), 400 file request.files[image] # 这里应实现文件保存逻辑例如保存到本地static文件夹或上传到云存储 # 假设保存后得到文件路径 import os from werkzeug.utils import secure_filename filename secure_filename(file.filename) save_path os.path.join(app.config[UPLOAD_FOLDER], filename) file.save(save_path) # 生成缩略图这里省略缩略图生成代码 thumbnail_path generate_thumbnail(save_path) # 创建数据库记录 new_preview PreviewImage( prompt_idprompt_id, image_urlf/static/uploads/{filename}, thumbnail_urlf/static/thumbnails/{filename} ) db.session.add(new_preview) db.session.commit() return jsonify({message: 上传成功, preview_id: new_preview.id}) # 4. 为提示词评分 app.route(/api/prompts/int:prompt_id/ratings, methods[POST]) def rate_prompt(prompt_id): data request.json user_id data.get(user_id, guest) # 简单处理用户身份 # 检查是否已评分可选防止刷分 existing Rating.query.filter_by(prompt_idprompt_id, user_iduser_id).first() if existing: return jsonify({error: 您已评过分}), 400 new_rating Rating( prompt_idprompt_id, user_iduser_id, scoredata[score], commentdata.get(comment, ) ) db.session.add(new_rating) db.session.commit() # 可以在这里触发更新提示词的平均分在Prompt模型中添加一个avg_score字段并计算 return jsonify({message: 评分成功})3. 前端管理界面实现后端API准备好了我们需要一个界面来操作。为了简单快捷我直接用HTML、CSS和JavaScript配合一点Vue.js的响应式特性写了个单页应用。3.1 核心页面布局前端主要包含三个区域顶部的搜索筛选栏、左侧的标签导航、中间的主内容区。!-- index.html 简化版 -- !DOCTYPE html html head title影墨·今颜 - 提示词库管理/title script srchttps://unpkg.com/vue3/dist/vue.global.js/script style /* 基础样式布局为上下左右结构 */ body { font-family: sans-serif; margin: 0; padding: 20px; background: #f5f5f5; } .container { display: flex; max-width: 1200px; margin: auto; gap: 20px; } .sidebar { width: 200px; flex-shrink: 0; } .main-content { flex-grow: 1; } .search-bar { margin-bottom: 20px; } .prompt-card { background: white; border-radius: 8px; padding: 15px; margin-bottom: 15px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .tags span { display: inline-block; background: #e0e0e0; padding: 3px 8px; margin-right: 5px; border-radius: 3px; font-size: 0.9em; } /style /head body div idapp h1 影墨·今颜提示词库/h1 div classsearch-bar input typetext v-modelsearchKeyword placeholder搜索提示词或描述... inputfetchPrompts button clickshowCreateDialog true 添加新词条/button /div div classcontainer div classsidebar h3标签筛选/h3 ul lia href# click.preventselectTag()全部/a/li li v-fortag in popularTags :keytag a href# click.preventselectTag(tag){{ tag }}/a /li /ul /div div classmain-content !-- 提示词列表 -- div v-ifloading加载中.../div div v-else div classprompt-card v-forprompt in prompts :keyprompt.id div styledisplay: flex; gap: 15px; img v-ifprompt.preview :srcprompt.preview alt预览 stylewidth:100px; height:100px; object-fit:cover; border-radius:4px; div styleflex-grow:1; h4 stylemargin-top:0;{{ prompt.positive_prompt }}/h4 p{{ prompt.description }}/p div classtags span v-fortag in prompt.tags :keytag{{ tag }}/span /div smallby {{ prompt.author }}/small div button clickeditPrompt(prompt)编辑/button button clickviewDetail(prompt.id)详情/button /div /div /div /div !-- 分页 -- div styletext-align: center; margin-top: 20px; button clickprevPage :disabledpage 1上一页/button span第 {{ page }} 页 / 共 {{ totalPages }} 页/span button clicknextPage :disabledpage totalPages下一页/button /div /div /div /div !-- 创建/编辑对话框 (通过v-if控制显示) -- div classdialog v-ifshowCreateDialog !-- 对话框内容表单包含正负向提示词、描述、标签、参数等输入项 -- h3{{ editingPrompt ? 编辑 : 创建 }}提示词/h3 textarea v-modelform.positive_prompt placeholder正向提示词.../textarea textarea v-modelform.negative_prompt placeholder负向提示词可选.../textarea input v-modelform.description placeholder描述... input v-modelform.tagsInput placeholder标签用逗号分隔... button clicksubmitForm保存/button button clickcloseDialog取消/button /div /div script const { createApp, ref, computed, onMounted } Vue; createApp({ setup() { const searchKeyword ref(); const selectedTag ref(); const page ref(1); const perPage 20; const prompts ref([]); const total ref(0); const loading ref(false); const showCreateDialog ref(false); const form ref({ positive_prompt: , negative_prompt: , description: , tagsInput: }); const popularTags ref([国风, ins风, 美食, 人像, 插画, 产品图]); // 计算总页数 const totalPages computed(() Math.ceil(total.value / perPage)); // 获取提示词列表 async function fetchPrompts() { loading.value true; let url /api/prompts?page${page.value}per_page${perPage}; if (searchKeyword.value) url q${encodeURIComponent(searchKeyword.value)}; if (selectedTag.value) url tag${encodeURIComponent(selectedTag.value)}; try { const response await fetch(url); const data await response.json(); prompts.value data.items; total.value data.total; } catch (error) { console.error(获取数据失败:, error); } finally { loading.value false; } } // 标签选择 function selectTag(tag) { selectedTag.value tag; page.value 1; fetchPrompts(); } // 分页 function prevPage() { if (page.value 1) { page.value--; fetchPrompts(); } } function nextPage() { if (page.value totalPages.value) { page.value; fetchPrompts(); } } // 初始化 onMounted(fetchPrompts); // 监听搜索关键词变化防抖处理 let debounceTimer; searchKeyword.value.$watch(() { clearTimeout(debounceTimer); debounceTimer setTimeout(() { page.value 1; fetchPrompts(); }, 300); }); return { searchKeyword, selectedTag, page, prompts, total, loading, showCreateDialog, form, popularTags, totalPages, fetchPrompts, selectTag, prevPage, nextPage, editPrompt(prompt) { /* 打开编辑对话框并填充form */ }, submitForm() { /* 提交创建/编辑请求 */ }, closeDialog() { showCreateDialog.value false; form.value {}; }, viewDetail(id) { window.location.href /detail.html?id${id}; } }; } }).mount(#app); /script /body /html这个前端界面虽然简单但具备了管理系统的核心功能浏览、搜索、筛选、分页查看以及触发创建和编辑操作。通过Vue的响应式绑定用户体验非常流畅。4. 实际应用与效果系统搭建完成后我们团队开始往里面填充内容。主要来源有两个一是平时自己用AI生成时积累下来的“黄金提示词”二是从社区、平台上搜集整理的高质量词条。使用流程变得非常顺畅当需要生成一组“国风美食”主题的图片时设计师不再需要苦思冥想提示词。他只需要在系统里点击“国风”和“美食”标签立刻就能看到几十个相关的、带有效果预览的提示词。选中一个喜欢的词条点开详情不仅能看到完整的提示词还能看到别人使用时的最佳参数配置如模型、采样器、步数甚至可以直接复制这些参数到自己的AI绘画工具里极大提高了出图效率和效果稳定性。生成出满意的图片后设计师可以立刻将成果图作为“效果预览”上传到该词条下并给出一个五星好评。这样这个词条就变得更加丰富、有说服力。带来的价值是实实在在的效率提升寻找和测试提示词的时间从小时级缩短到分钟级。质量稳定复用经过验证的词条和参数生成结果的质量下限提高了减少了“抽卡”式的随机性。知识沉淀团队的经验什么词好用、配什么参数被固化下来新成员也能快速上手避免了重复造轮子。激发创意浏览词库本身就是一个学习过程能看到各种奇思妙想的组合常常能激发新的创作灵感。这个“影墨·今颜”提示词库从一个具体的内容创作痛点出发最终落地成了一个能切实解决问题的工具。它本质上就是一个典型的、以应用为导向的数据库系统。从需求分析、表结构设计到后端API开发、前端界面实现整个流程走下来不仅解决了实际问题也是一次非常扎实的工程实践。如果你也在为管理越来越多的AI提示词而烦恼不妨也试着动手搭建一个属于自己的小系统吧这个过程本身就充满了乐趣和成就感。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。