为什么 AI 项目总被提示词拖累?PromptShelf 用“类 Git”思路给出答案
“
作者:某 AI 平台架构师 & Rust 爱好者
更新时间:2025-07-26
如果你的团队正在把提示词直接写死在代码里,或者靠微信群里的 .txt 文件来回传递,那你一定体会过下面这些场景:
- 
凌晨三点,线上模型突然开始胡说八道,你怀疑提示词被谁改了,却找不到任何修改记录;  - 
产品经理想做一个 A/B 测试,结果开发同学告诉你“得重新打包镜像、走完整 CI/CD”;  - 
新来的算法同学想改两行提示词,却被代码仓库里错综复杂的 if-else劝退。 
PromptShelf 把这些问题当成“版本控制”问题来解决:它把提示词当成一等公民,用类似 Git 的思路做版本管理,却不强制你学任何 Git 命令。下面我会用问答、步骤、示例代码和截图,带你走完从“为什么要用”到“怎么跑起来”的全过程。
目录
- 
问题到底出在哪?  - 
PromptShelf 是怎么思考的?  - 
一张图看懂它和 Git 的对应关系  - 
十分钟把服务跑起来:Docker Compose 一条龙  - 
常用操作速查表  - 
典型工作流:从“第一次写提示词”到“线上回滚”  - 
常见疑问 FAQ  - 
技术栈与项目结构速览  - 
小结:一句话记住 PromptShelf 的价值  
1. 问题到底出在哪?
| 现象 | 根因 | 代价 | 
|---|---|---|
| 提示词散落在代码里 | 代码与提示词耦合 | 每次改提示词=全量部署 | 
| 没有历史记录 | 提示词不是文本文件,无法 diff | 出错只能“凭感觉”回退 | 
| 多人协作靠微信 | 缺少集中存储与权限 | 容易覆盖、难以审计 | 
| A/B 测试成本高 | 提示词与镜像打包在一起 | 测试周期按天计算 | 
一句话总结:提示词不是普通字符串,而是需要版本、权限、缓存、审计的“模型配置”。
2. PromptShelf 是怎么思考的?
PromptShelf 把提示词拆成三层概念,每层都有明确职责:
| PromptShelf 概念 | 类比 Git 概念 | 作用 | 
|---|---|---|
| Prompt(提示词仓库) | Repository | 存放同一业务场景下的所有提示词版本 | 
| Node(节点) | Commit 之前的暂存区 | 一次小的语义化改动,可多次积累 | 
| Commit(提交) | Commit | 生成不可变版本号,可回滚、可对比 | 
这样做的好处是:
- 
关注点分离:应用代码只关心“拿最新版提示词”,其余交给 PromptShelf;  - 
零停机更新:改完提示词 → 提交 → 线上立即生效,无需重新打包镜像;  - 
审计友好:每个版本都有作者、时间、改动 diff,一键回滚。  
3. 一张图看懂它和 Git 的对应关系
Git 用户视角                PromptShelf 用户视角
------------------        --------------------------
git init                  POST /prompt/create_prompt
git add                   POST /prompt/create_node
git commit -m "xxx"       POST /prompt/create_commit
git log                   GET  /prompt/query
git checkout <hash>       POST /prompt/rollback
区别只有两点:
- 
所有操作通过 REST API 完成,不需要本地安装任何 CLI;  - 
每个 Prompt 可以设置独立的读写权限,天然支持多人协作。  
4. 十分钟把服务跑起来:Docker Compose 一条龙
4.1 准备环境
- 
Docker ≥ 20.10  - 
Docker Compose ≥ 2.0  - 
空闲端口:8080(Web)、3306(MySQL)、6379(Redis)  
4.2 一条命令启动
# 克隆仓库(假设已准备好)
git clone <repo_url>
cd promptshelf
# 启动所有服务
docker-compose up --build -d
# 查看日志确认无报错
docker-compose logs -f
首次启动会自动完成:
- 
拉取 Rust 后端镜像  - 
启动 MySQL 8.0、Dragonfly(Redis 兼容)  - 
初始化表结构  
当看到 server started at 0.0.0.0:8080 时,打开浏览器访问 http://localhost:8080 即可看到 Web 界面。
4.3 环境变量速查表
| 变量 | 默认值 | 说明 | 
|---|---|---|
| DATABASE_URL | mysql://user:pass@mysql:3306/promptshelf | MySQL 连接串 | 
| REDIS_URI | redis://dragonfly:6379 | 缓存地址 | 
| JWT_SECRET | 随机字符串 | 签发令牌密钥 | 
| JWT_EXPIRATION | 86400(秒) | 令牌有效期 | 
| ALLOW_REGISTER | true | 首次体验可保持开启 | 
如需修改,直接编辑 docker-compose.yml 里的 environment 段落即可。
5. 常用操作速查表
| 目标 | HTTP 方法 + 路径 | 请求示例(curl) | 
|---|---|---|
| 注册第一个账号 | POST /user/signup | curl -X POST -H "Content-Type: application/json" -d '{"username":"alice","password":"123456"}' http://localhost:8080/user/signup | 
| 登录拿令牌 | POST /user/signin | 同上,返回 { "token": "eyJ..." } | 
| 创建提示词仓库 | POST /prompt/create_prompt | curl -H "Authorization: Bearer <token>" ... -d '{"name":"customer_service_cn"}' | 
| 写入第一版提示词 | POST /prompt/create_node | -d '{"prompt_id":1, "content":"你是客服..."}' | 
| 提交版本 | POST /prompt/create_commit | -d '{"prompt_id":1, "message":"初始化客服提示词"}' | 
| 查看最新版 | GET /prompt/latest | curl -H "Authorization: Bearer <token>" http://localhost:8080/prompt/latest?prompt_id=1 | 
| 回滚 | POST /prompt/rollback | -d '{"prompt_id":1, "commit_hash":"<hash>"}' | 
“
提示:在 Web 界面里点点鼠标也可以完成全部操作,API 只是方便脚本化。
6. 典型工作流:从“第一次写提示词”到“线上回滚”
6.1 场景设定
你负责一款中文客服机器人,需要不断调整系统提示词以减少幻觉。
6.2 步骤拆解
| 步骤 | 操作者 | 工具 | 耗时 | 
|---|---|---|---|
| 1. 创建仓库 | 算法工程师 | Web UI | 30 秒 | 
| 2. 写第一版提示词 | 算法工程师 | Web UI 编辑器 | 5 分钟 | 
| 3. 提交 v1.0 | 同上 | “Commit” 按钮 | 10 秒 | 
| 4. 灰度到 10% 流量 | 后端工程师 | 调用 /prompt/latest | 
1 分钟 | 
| 5. 发现幻觉率 ↑ | 运营同学 | 日志监控 | — | 
| 6. 回滚到 v1.0 | 后端工程师 | POST /prompt/rollback | 
10 秒 | 
整个过程没有重新打包镜像,也没有重启 Pod,只是把 /prompt/latest 的返回值从 v1.1 切回 v1.0。
7. 常见疑问 FAQ
7.1 我要不要把所有提示词都迁进去?
先选 1~2 条最常被改动的提示词做试点。跑两周后,团队感受到“零停机更新”的甜头,再逐步迁移。
7.2 与 DVC、Git LFS 有什么区别?
DVC 面向大文件和 ML 数据集,PromptShelf 面向频繁改动的文本字符串,并提供 REST 接口和权限体系,两者并不冲突。
7.3 权限粒度有多细?
支持“仓库级”和“用户级”两级权限。
- 
仓库级:谁能读、谁能写;  - 
用户级:管理员可禁用普通用户,防止误操作。  
7.4 缓存会不会导致我改了提示词却拿不到最新版?
默认缓存 30 秒。可在请求里加 ?no_cache=1 强制穿透,或在提交 commit 时调用 /control/cache/invalidate 主动清缓存。
7.5 前端必须自己写吗?
仓库里已经带了一个用 React + Vite 写的 Web 应用,路径在 app/。直接 docker-compose 就会一起启动,无需额外配置。
8. 技术栈与项目结构速览
promptshelf/
├── src/
│   ├── db/           // SeaORM 实体与迁移
│   ├── routes/
│   │   ├── prompt.rs // RESTful 提示词接口
│   │   ├── user.rs   // 注册、登录、JWT
│   │   └── status.rs // 健康检查
│   └── main.rs       // Axum 启动入口
├── app/              // React 前端
├── doc/
│   ├── PromptShelf.md // 完整 API 文档
│   └── preview/      // 截图
└── docker-compose.yml
- 
后端语言:Rust(1.79+)  - 
Web 框架:Axum(Tokio 生态,异步高效)  - 
ORM:SeaORM(类型安全,可自动迁移)  - 
数据库:MySQL 8.0(InnoDB,行级锁)  - 
缓存:Dragonfly(Redis 协议,多线程,QPS 提升 25 倍实测)  - 
认证:JWT + Argon2 哈希,防暴力破解  - 
部署:Docker + Docker Compose,一条命令解决依赖  
9. 小结:一句话记住 PromptShelf 的价值
把提示词从“代码里的字符串”升级为“受版本控制、可审计、可热更新、可多人协作的模型配置”,PromptShelf 用十分钟就能让你体验到“改提示词像改配置中心”一样的丝滑。
如果你正准备把大模型搬进生产环境,或者已经每天在群里喊“谁又改了我的提示词”,那就本地起一套 PromptShelf,亲自跑一遍上面的工作流。你会发现:原来提示词也可以像代码一样被好好管理。
祝你玩得开心,少加夜班。

