Files
agent-skills/content-ops/content-ops-agent/references/prompt-service-architecture.md
Hermes Agent ccc63d1e70 first commit
2026-05-10 13:52:46 +08:00

133 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Prompt 服务架构参考
> 基于 2026-05-05 代码分析,源码位于 `/home/ubuntu/projects/ephron.ren/prompt/`
## 项目结构
```
prompt/
├── src/
│ ├── main.py # FastAPI 入口,挂载路由和中间件
│ ├── config.py # 环境变量配置AUTH_SECRET_KEY, DATABASE_PATH
│ ├── routes/
│ │ ├── pages.py # 页面路由Jinja2 模板渲染HTMLResponse
│ │ ├── api.py # 公开 API/api/prompts, /api/prompts/{key}
│ │ ├── admin.py # 管理后台路由(/admin/*,需 Cookie 认证)
│ │ └── service_api.py # 服务端 API/api/service/*,需 Bearer Token
│ └── services/
│ ├── prompts.py # 提示词 CRUD + 版本管理
│ ├── db.py # SQLite 连接 + 建表
│ └── auth.py # 认证辅助
├── templates/
│ ├── base.html # 基础模板暗色主题、Inter + JetBrains Mono
│ ├── public/
│ │ ├── index.html # 列表页(搜索、分类筛选、标签过滤、卡片网格)
│ │ └── detail.html # 详情页(内容展示、复制按钮、示例区域)
│ └── admin/
│ ├── index.html # 管理列表
│ ├── edit.html # 编辑表单
│ ├── new.html # 新建表单
│ └── versions.html # 版本历史
├── static/
│ ├── css/ds/ # 设计系统 CSStokens, components, layout, motion
│ └── js/ds/ui.js # UI 交互modal、toast、通用组件
└── tests/
```
## 数据模型
### prompts 表
```sql
CREATE TABLE prompts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
key TEXT NOT NULL UNIQUE, -- URL 标识,如 "deep-research-prompt"
title TEXT NOT NULL,
description TEXT,
category TEXT NOT NULL DEFAULT '未分类',
tags TEXT, -- 逗号分隔
is_template INTEGER NOT NULL DEFAULT 0,
variables TEXT, -- 模板变量(逗号分隔)
example_input TEXT,
example_output TEXT,
recommended_model TEXT NOT NULL DEFAULT '通用',
is_active INTEGER NOT NULL DEFAULT 1,
draft INTEGER NOT NULL DEFAULT 0,
created_by TEXT,
updated_by TEXT,
ownership_type TEXT NOT NULL DEFAULT 'human', -- 'human' | 'service'
handoff_to_human INTEGER NOT NULL DEFAULT 0,
current_version_id INTEGER,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
```
### prompt_versions 表
```sql
CREATE TABLE prompt_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
prompt_key TEXT NOT NULL,
version INTEGER NOT NULL,
content TEXT NOT NULL,
created_by TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (prompt_key) REFERENCES prompts(key) ON DELETE CASCADE,
UNIQUE(prompt_key, version)
);
```
## API 端点
### 公开 API无需认证
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/prompts` | 列表(支持 search, tag, category, limit, offset |
| GET | `/api/prompts/{key}` | 详情(支持 version 查询参数) |
### 服务端 APIBearer Token
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/service/prompts` | 列表 |
| GET | `/api/service/prompts/{key}` | 详情 |
| POST | `/api/service/prompts` | 创建草稿 |
| PATCH | `/api/service/prompts/{key}` | 更新草稿 |
| DELETE | `/api/service/prompts/{key}` | 删除草稿 |
### 页面路由(返回 HTML
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/``/prompts` | 列表页(支持 q, category, tag 查询参数) |
| GET | `/prompts/{key}` | 详情页 |
| GET | `/admin/*` | 管理后台(需登录 + 权限) |
## 设计系统
- **主题**: 暗色bg-primary: #09090b, accent: #3b82f6
- **字体**: Inter正文+ JetBrains Mono代码
- **CSS 变量**: 定义在 `:root` 中,所有组件引用变量
- **卡片组件**: `.prompt-card` 使用 `bg-secondary` + border + hover 效果
- **标签**: `.tag` 类,带 `tag-bg` 背景
- **复制按钮**: `.copy-btn`,绝对定位在内容块右上角
- **CSP**: `connect-src 'self'``script-src 'self' 'unsafe-inline'``cdn.jsdelivr.net` 已白名单
## 现有功能特性
1. **版本管理**: 每次编辑创建新版本,支持版本切换
2. **模板变量**: `is_template=true` 时,`variables` 字段定义可替换变量
3. **草稿系统**: `draft` 字段 + `ownership_type` 区分人类/服务创建
4. **搜索过滤**: 支持关键词搜索、分类筛选、标签过滤
5. **复制功能**: 前端 `navigator.clipboard.writeText()` 实现
## 待实现功能PRD 已写)
- **调用测试**: 详情页测试 Tab填变量 → 调 LLM → 流式输出
- **集合**: `collections` + `collection_items` 表,组织相关提示词
## 开发注意事项
- 路由区分:`response_class=HTMLResponse` → 页面路由,返回 dict/Pydantic → API
- Key 自动生成:创建 prompt 时 key 可能被截取/简化,以响应返回值为准
- Key 不可变PATCH 不能修改 key 字段
- 服务端只能编辑自己创建的草稿(`created_by == actor_id` + `ownership_type == "service"` + `draft == true`
- 所有时间使用 SQLite `datetime('now')` 存储