385 lines
12 KiB
Markdown
385 lines
12 KiB
Markdown
# 古诗词阅读网站
|
||
|
||
基于大模型分类的中国古诗词阅读管理系统
|
||
|
||
## 系统架构
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ 古诗词阅读网站 │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ Frontend (原生 JS + CSS) │ Backend (FastAPI + SQLite)│
|
||
│ - 多类别组合筛选 │ - RESTful API │
|
||
│ - 阅读标记管理 │ - SQLite 数据库 │
|
||
│ - 标签云浏览 │ - 分类查询 │
|
||
│ - 进度统计 │ - 批量导入 │
|
||
├─────────────────────────────────────────────────────────┤
|
||
│ classify_pois.py (LLM 分类脚本) │
|
||
│ - 20 维分类标签体系 │
|
||
│ - 繁体转简体支持 │
|
||
│ - 实时去重 + 持久化 │
|
||
└─────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## 核心功能
|
||
|
||
### 1. 20 维分类标签体系
|
||
|
||
| 维度分类 | 标签数量 | 示例 |
|
||
|---------|---------|------|
|
||
| **季节时序** | 39 | 春、夏、秋、冬、24 节气、时辰 |
|
||
| **题材类型** | 17 | 山水田园、边塞征战、咏史怀古等 |
|
||
| **情感心境** | 31 | 情感基调 11 种 + 具体情感 20 种 |
|
||
| **景物意象** | 77 | 自然、植物、动物、建筑、色彩、声音 |
|
||
| **哲理思想** | 7 | 儒家、道家、佛家、人生感悟等 |
|
||
| **艺术手法** | 18 | 写作手法、修辞手法 |
|
||
| **人物社会** | 33 | 人生阶段、社会身份、地理方位、节日 |
|
||
|
||
### 2. 繁体转简体支持
|
||
|
||
- ✅ 自动识别繁体中文诗词
|
||
- ✅ LLM 自动转换为简体中文
|
||
- ✅ 保留原始繁体版本(可选)
|
||
- ✅ 基于简体内容去重(繁简同一首诗不会重复)
|
||
- ✅ 所有分类标签统一使用简体
|
||
|
||
**输入示例(繁体):**
|
||
```json
|
||
{
|
||
"title": "山居秋暝",
|
||
"author": "王維",
|
||
"paragraphs": ["空山新雨後,天氣晚來秋。", "明月鬆間照,清泉石上流。"]
|
||
}
|
||
```
|
||
|
||
**输出示例(简体):**
|
||
```json
|
||
{
|
||
"title": "山居秋暝",
|
||
"author": "王维",
|
||
"paragraphs": ["空山新雨后,天气晚来秋。", "明月松间照,清泉石上流。"],
|
||
"original_paragraphs": ["空山新雨後,天氣晚來秋。", "明月鬆間照,清泉石上流。"],
|
||
"llm_classification": {
|
||
"season": ["秋"],
|
||
"genre": ["山水田园", "隐逸闲适"],
|
||
...
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3. 多类别组合筛选
|
||
|
||
支持同时选择多个分类标签进行组合筛选:
|
||
- 题材=山水田园 AND 情感=宁静淡泊
|
||
- 季节=春 AND 地点=江南 AND 情感=喜悦
|
||
- 使用 SQL 查询优化,支持复杂筛选条件
|
||
|
||
### 4. 阅读管理
|
||
|
||
- 标记诗词为已读/未读
|
||
- 阅读进度统计(百分比 + 数量)
|
||
- 阅读时间记录
|
||
- 快速切换阅读状态
|
||
|
||
### 5. 批量导入
|
||
|
||
- 支持 JSON/JSONL 格式
|
||
- 自动去重(基于内容签名 MD5)
|
||
- 实时写入数据库
|
||
- 导入结果反馈
|
||
|
||
## 快速开始
|
||
|
||
### 1. 安装依赖
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 2. 使用 LLM 脚本分类诗词
|
||
|
||
```bash
|
||
# 本地模型 (Ollama 等)
|
||
python classify_pois.py ./poems ./output.jsonl --llm \
|
||
--base-url http://localhost:11434/v1 \
|
||
--model qwen:7b
|
||
|
||
# 远程模型 (OpenAI 等)
|
||
python classify_pois.py ./poems ./output.jsonl --llm \
|
||
--base-url https://api.openai.com/v1 \
|
||
--model gpt-4 \
|
||
--api-key sk-xxx
|
||
|
||
# 繁体诗词测试
|
||
python classify_pois.py ./ ./output.jsonl --llm \
|
||
--base-url http://localhost:11434/v1 \
|
||
--model qwen:7b
|
||
```
|
||
|
||
### 3. 启动后端服务
|
||
|
||
```bash
|
||
cd backend
|
||
python main.py
|
||
```
|
||
|
||
服务启动后访问:http://localhost:8000
|
||
|
||
### 4. 前端页面
|
||
|
||
浏览器打开:http://localhost:8000
|
||
|
||
### 5. 上传诗词
|
||
|
||
通过前端界面的上传功能,上传分类后的 JSONL 文件到数据库。
|
||
|
||
## API 端点
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/` | 前端页面 |
|
||
| GET | `/api/categories` | 获取分类体系 |
|
||
| GET | `/api/stats` | 获取统计数据 |
|
||
| POST | `/api/poems/import` | 批量导入诗词 |
|
||
| GET | `/api/poems` | 获取诗词列表(支持分页、筛选) |
|
||
| GET | `/api/poems/{id}` | 获取诗词详情 |
|
||
| PUT | `/api/poems/{id}/read` | 切换阅读状态 |
|
||
| GET | `/api/poems/random` | 随机一首 |
|
||
| GET | `/api/tags/cloud` | 标签云数据 |
|
||
|
||
### API 使用示例
|
||
|
||
```bash
|
||
# 获取诗词列表(带多类别筛选)
|
||
GET /api/poems?page=1&page_size=20&categories=genre:山水田园,emotion_tone:宁静淡泊
|
||
|
||
# 搜索诗词
|
||
GET /api/poems?search=李白
|
||
|
||
# 获取已读诗词
|
||
GET /api/poems?is_read=true
|
||
|
||
# 获取未读诗词
|
||
GET /api/poems?is_read=false
|
||
|
||
# 标记为已读
|
||
PUT /api/poems/{id}/read?is_read=true
|
||
|
||
# 标记为未读
|
||
PUT /api/poems/{id}/read?is_read=false
|
||
```
|
||
|
||
## 数据格式
|
||
|
||
### 输入格式(JSON/JSONL)
|
||
|
||
```json
|
||
{
|
||
"id": "poem_001",
|
||
"title": "山居秋暝",
|
||
"author": "王维",
|
||
"paragraphs": [
|
||
"空山新雨后,天气晚来秋。",
|
||
"明月松间照,清泉石上流。",
|
||
"竹喧归浣女,莲动下渔舟。",
|
||
"随意春芳歇,王孙自可留。"
|
||
],
|
||
"llm_classification": {
|
||
"season": ["秋"],
|
||
"solar_terms": ["白露"],
|
||
"time_of_day": "黄昏",
|
||
"genre": ["山水田园", "隐逸闲适"],
|
||
"emotion_tone": "宁静淡泊",
|
||
"emotions": ["静", "喜", "乐"],
|
||
"nature_scenery": ["山", "水", "月"],
|
||
"plants": ["松", "竹"],
|
||
"animals": ["鸟"],
|
||
"buildings": [],
|
||
"imagery": ["空山", "新雨", "明月"],
|
||
"philosophy": ["道家思想", "自然之道"],
|
||
"life_stage": "中年",
|
||
"social_role": "隐士",
|
||
"technique": ["借景抒情", "动静结合"],
|
||
"rhetoric": ["拟人"],
|
||
"colors": ["青", "白"],
|
||
"sounds": [],
|
||
"location": "终南山",
|
||
"festival": "无",
|
||
"analysis": "这首诗描绘了秋日山居的幽静景色..."
|
||
}
|
||
}
|
||
```
|
||
|
||
### 输出格式(API 响应)
|
||
|
||
```json
|
||
{
|
||
"id": "poem_001",
|
||
"title": "山居秋暝",
|
||
"author": "王维",
|
||
"paragraphs": ["空山新雨后,天气晚来秋。", ...],
|
||
"original_paragraphs": null,
|
||
"classifications": {
|
||
"season": ["秋"],
|
||
"genre": ["山水田园", "隐逸闲适"],
|
||
...
|
||
},
|
||
"is_read": false,
|
||
"read_at": null,
|
||
"created_at": "2024-01-01T00:00:00"
|
||
}
|
||
```
|
||
|
||
## 数据库结构
|
||
|
||
### poems 表
|
||
```sql
|
||
CREATE TABLE poems (
|
||
id TEXT PRIMARY KEY,
|
||
title TEXT NOT NULL,
|
||
author TEXT NOT NULL,
|
||
paragraphs TEXT,
|
||
signature TEXT UNIQUE,
|
||
created_at TIMESTAMP,
|
||
updated_at TIMESTAMP
|
||
);
|
||
```
|
||
|
||
### classifications 表
|
||
```sql
|
||
CREATE TABLE classifications (
|
||
id INTEGER PRIMARY KEY,
|
||
poem_id TEXT,
|
||
category TEXT,
|
||
tags TEXT,
|
||
FOREIGN KEY (poem_id) REFERENCES poems(id)
|
||
);
|
||
```
|
||
|
||
### reading_records 表
|
||
```sql
|
||
CREATE TABLE reading_records (
|
||
id INTEGER PRIMARY KEY,
|
||
poem_id TEXT UNIQUE,
|
||
is_read BOOLEAN,
|
||
read_at TIMESTAMP,
|
||
FOREIGN KEY (poem_id) REFERENCES poems(id)
|
||
);
|
||
```
|
||
|
||
## 完整分类标签体系
|
||
|
||
| 维度 | 键名 | 标签数量 | 标签示例 |
|
||
|------|------|---------|---------|
|
||
| 季节 | season | 6 | 春、夏、秋、冬、四季 |
|
||
| 节气 | solar_terms | 24 | 立春、雨水、清明、谷雨 |
|
||
| 时辰 | time_of_day | 9 | 清晨、黄昏、夜晚、黎明 |
|
||
| 题材 | genre | 17 | 山水田园、边塞征战、咏史怀古 |
|
||
| 情感基调 | emotion_tone | 11 | 宁静淡泊、喜悦欢快、悲伤哀愁 |
|
||
| 具体情感 | emotions | 20 | 喜、怒、哀、乐、忧、思 |
|
||
| 自然景物 | nature_scenery | 14 | 山、水、云、雨、日、月 |
|
||
| 植物 | plants | 15 | 松、竹、梅、兰、菊、荷 |
|
||
| 动物 | animals | 14 | 鸟、雁、燕、蝉、蛙、鱼 |
|
||
| 建筑 | buildings | 15 | 楼、阁、亭、台、桥、寺 |
|
||
| 哲理 | philosophy | 7 | 儒家思想、道家思想、佛家禅理 |
|
||
| 人生阶段 | life_stage | 5 | 少年、青年、中年、老年 |
|
||
| 社会身份 | social_role | 10 | 士人、官员、隐士、游子 |
|
||
| 写作手法 | technique | 9 | 比兴、借景抒情、托物言志 |
|
||
| 修辞手法 | rhetoric | 9 | 比喻、拟人、夸张、对偶 |
|
||
| 色彩 | colors | 10 | 青、绿、红、白、黄、紫 |
|
||
| 声音 | sounds | 9 | 钟声、琴声、鸟鸣、雨声 |
|
||
| 地理 | location | 9 | 江南、塞北、巴蜀、关中 |
|
||
| 节日 | festival | 9 | 春节、中秋、重阳、端午 |
|
||
|
||
## 技术栈
|
||
|
||
- **后端**: FastAPI + SQLite + Uvicorn
|
||
- **前端**: 原生 JavaScript + CSS (无框架依赖)
|
||
- **分类**: 基于 LLM API (支持本地/远程模型)
|
||
- **简繁转换**: LLM 自动识别和转换
|
||
|
||
## 扩展开发
|
||
|
||
### 添加新的分类维度
|
||
|
||
1. 在 `backend/main.py` 的 `CATEGORY_SYSTEM` 中添加新维度
|
||
2. 在 `classify_pois.py` 的 `CLASSIFICATION_PROMPT` 中添加对应提示
|
||
3. 在前端 CSS 中添加对应标签样式
|
||
|
||
### 部署建议
|
||
|
||
```bash
|
||
# 生产环境使用
|
||
uvicorn backend.main:app --host 0.0.0.0 --port 8000 --workers 4
|
||
|
||
# 或使用 gunicorn
|
||
gunicorn backend.main:app -w 4 -k uvicorn.workers.UvicornWorker
|
||
```
|
||
|
||
### 简繁切换显示(可选)
|
||
|
||
在前端添加简繁切换功能:
|
||
|
||
```javascript
|
||
let showTraditional = false;
|
||
|
||
function toggleTraditional() {
|
||
showTraditional = !showTraditional;
|
||
const poem = state.currentPoem;
|
||
const content = showTraditional && poem.original_paragraphs
|
||
? poem.original_paragraphs
|
||
: poem.paragraphs;
|
||
// 重新渲染内容
|
||
}
|
||
```
|
||
|
||
## 常见问题
|
||
|
||
**Q: 导入时提示重复?**
|
||
A: 系统基于诗词内容签名(MD5)去重,相同内容的诗词只会保留一份。繁体和简体版本会被识别为同一首诗。
|
||
|
||
**Q: 如何重置阅读进度?**
|
||
A: 直接修改数据库中 `reading_records` 表的 `is_read` 字段,或在前端重新标记。
|
||
|
||
**Q: 支持哪些 LLM 模型?**
|
||
A: 任何支持 OpenAI 兼容 API 的模型,包括 Ollama、vLLM、OpenAI GPT、Anthropic Claude 等。
|
||
|
||
**Q: 繁体诗词如何处理?**
|
||
A: 分类脚本会自动识别繁体中文,LLM 会返回简体版本。原始繁体会保存在 `original_paragraphs` 字段中。
|
||
|
||
**Q: JSONL 文件和 SQLite 数据库的关系?**
|
||
A: JSONL 是分类脚本的输出格式(中间产物),SQLite 是网站运行的数据库(最终存储)。通过 API 导入功能将 JSONL 导入数据库。
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
PoemClassify/
|
||
├── classify_pois.py # LLM 分类脚本
|
||
├── requirements.txt # Python 依赖
|
||
├── backend/
|
||
│ ├── main.py # FastAPI 后端
|
||
│ └── poems.db # SQLite 数据库(运行时生成)
|
||
├── frontend/
|
||
│ ├── index.html # 前端页面
|
||
│ ├── script.js # 前端逻辑
|
||
│ └── style.css # 样式文件
|
||
├── test_traditional.json # 繁体测试文件
|
||
└── README.md # 本文档
|
||
```
|
||
|
||
## 数据备份
|
||
|
||
```bash
|
||
# 备份 SQLite 数据库
|
||
cp backend/poems.db backup_$(date +%Y%m%d).db
|
||
|
||
# 导出数据库为 JSONL
|
||
sqlite3 backend/poems.db "SELECT json_object('id',id,'title',title,'author',author,'paragraphs',paragraphs) FROM poems;" > export.jsonl
|
||
|
||
# 从 JSONL 恢复
|
||
curl -X POST http://localhost:8000/api/poems/import -F "file=@export.jsonl"
|
||
```
|
||
|
||
## License
|
||
|
||
MIT License |