# 古诗词阅读网站 基于大模型分类的中国古诗词阅读管理系统 ## 系统架构 ``` ┌─────────────────────────────────────────────────────────┐ │ 古诗词阅读网站 │ ├─────────────────────────────────────────────────────────┤ │ 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