# quotation-extraction-system **Repository Path**: liuchangng/quotation-extraction-system ## Basic Information - **Project Name**: quotation-extraction-system - **Description**: 基于大模型的跨模态内容理解系统,自动从文本/音频/视频中抽取大众喜欢的哲理句,输出评分(含分项标尺)、标签(层级+置信度)、原文定位(两步定位法)、解释与受众画像,并可视化展示。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-20 - **Last Updated**: 2026-07-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Quotation Extraction System
[![Python](https://img.shields.io/badge/Python-3.13-blue)](https://www.python.org/) [![FastAPI](https://img.shields.io/badge/FastAPI-0.115-009688)](https://fastapi.tiangolo.com/) [![Next.js](https://img.shields.io/badge/Next.js-14-black)](https://nextjs.org/) [![License](https://img.shields.io/badge/License-MIT-green)](./LICENSE) **基于大模型的跨模态哲理语句抽取系统** 自动从文本/音频/视频中提取高质量哲理句,输出多维评分、标签体系、原文定位与受众画像。
## 功能特性 - **内容上传**:支持 PDF / DOCX / TXT 文件上传与直接文本输入(拖拽上传) - **文本解析**:分页/分段解析,生成带 `[页x|段y]` 定位标记的结构化文本 - **哲理句抽取**:LLM 抽取大众风格哲理句(情绪共鸣 / 启发性 / 励志 / 易懂 / 简洁) - **评分体系**:4 维度分项评分(情绪/启发/易懂/文学)+ 固定权重综合分,嵌入评分标尺防漂移 - **标签体系**:主题 / 情绪 / 价值观 三层标签 + 置信度 - **两步定位**:粗定位(LLM 引用标记)+ 精定位(原文回查),失败返回 null 防幻觉 - **反鸡汤过滤**:黑名单词过滤绝对化表述("注定/绝对/一定/永远/必然") - **去重策略**:同一文件(大文件分块合并后)内重复的哲理句自动去重,仅保留评分最高的一条;**跨文件**重复仍保留,用于频率统计 - **频率统计**:自动统计每句在多少份不同文档中出现,频率越高说明该句越流行、越有用;首页展示"高频哲理句"榜与"高频句数"指标 - **自适应分块**:上传文本过大时自动按目标大小(默认 4000 字符)分块,块间 10% 重叠(段落边界对齐,防哲理句被切断),块数由文件大小自动决定;低于阈值(2000字符)则整体一次抽取 - **异步抽取**:上传后立即返回,抽取在后台线程执行;前端实时轮询进度("正在抽取第 X/Y 块…"+ 进度条),大文件无需等待 - **防重复上传**:上传文件时计算内容 MD5 并持久化(`file_md5`),若已存在"已完成"的同 MD5 任务则直接复用,跳过解析与抽取,节省资源 - **受众画像**:预测哲理句打动的人群标签 - **首页 Dashboard**:统计概览(文档数 / 完成数 / 哲理句数 / 来源分布 / 高频句数)+ Top10 评分最高 + 🔥 热门哲理句(按频率)+ 文档库列表(分页,点击进入查看,展示文件 MD5) - **可视化展示**:哲理句卡片、评分徽章、标签云、定位跳转、分页轮询 ## 技术栈 | 层 | 技术 | |----|------| | 后端 | Python 3.13 + FastAPI + SQLAlchemy + SQLite(uv 管理依赖) | | 前端 | Next.js 14 + React 18 + TypeScript + TailwindCSS + React Query | | 包管理 | 后端 uv(pyproject.toml + uv.lock),前端 npm | | LLM | OpenAI 兼容接口(GPT-4o / Qwen / DeepSeek 等) | | 文本解析 | pdfplumber / python-docx | ## 目录结构 ``` quotation-extraction-system/ ├── server/ # 后端 FastAPI │ ├── app/ │ │ ├── main.py # 应用入口(中间件/路由/生命周期) │ │ ├── config.py # 集中配置(env 校验 fail-fast) │ │ ├── errors.py # 类型化错误 + 全局异常处理 │ │ ├── database.py # SQLAlchemy 引擎/会话 │ │ ├── logger.py # 结构化日志 │ │ └── features/ # feature-first 组织 │ │ ├── upload/ # 上传与文本解析 │ │ ├── extract/ # 抽取核心(LLM/Prompt/过滤/定位) │ │ └── task/ # 任务管理与数据模型 │ ├── pyproject.toml # uv 项目配置与依赖声明 │ ├── uv.lock # uv 锁定文件(可复现构建) │ ├── requirements.txt # 兼容旧 pip 方式(保留) │ ├── .gitignore │ └── .env.example └── client/ # 前端 Next.js ├── src/ │ ├── app/ # 页面:首页 Dashboard / 新建抽取 / 结果展示 │ ├── components/ # 组件:StatsOverview/TopSentences/DocumentList/Pagination/StatusChip/SentenceCard/Uploader… │ ├── api/ # typed fetch API client │ ├── utils/ # 前端日志(控制台 + 上报后端) │ └── types/ # 类型定义(与后端契约对齐) └── package.json ``` ## 快速开始 ### 1. 启动后端(uv 管理,推荐) 需先安装 [uv](https://docs.astral.sh/uv/):`pip install uv` 或 `winget install astral-sh.uv`。 ```bash cd server cp .env.example .env # 按需配置 LLM_API_KEY(留空走 mock 演示) uv sync # 创建/同步 .venv 并安装全部依赖(依据 uv.lock) uv run python run.py # http://localhost:8002(端口见 .env 的 APP_PORT) ``` > uv 会自动创建 `.venv`、解析 `pyproject.toml` 并按 `uv.lock` 精确安装,无需手动 venv/pip。 > 常用命令:`uv add <包名>` 添加依赖、`uv remove <包名>` 移除、`uv sync --reinstall` 重建环境。 > > 兼容旧方式(不推荐):`python -m venv .venv && .venv/Scripts/activate && pip install -r requirements.txt && python run.py` ### 2. 启动前端 ```bash cd client npm install npm run dev # http://localhost:3000 ``` 打开 http://localhost:3000 即可使用:首页查看统计/Top10/文档库 → 新建抽取(上传或粘贴文本)→ 查看哲理句卡片。 > 前端通过 `client/.env.local` 的 `NEXT_PUBLIC_API_URL` 指向后端地址(默认 `http://localhost:8002`),需与后端端口一致。 ## 配置说明 后端 `server/.env` 关键配置: | 变量 | 说明 | 默认值 | |------|------|--------| | `LLM_API_BASE` | LLM 接口地址(OpenAI 兼容) | `https://api.openai.com/v1` | | `LLM_API_KEY` | API Key(**留空走 mock 演示模式**) | 空 | | `LLM_MODEL` | 模型名 | `gpt-4o` | | `DATABASE_URL` | 数据库连接串 | `sqlite:///./data/app.db` | | `CORS_ORIGINS` | 允许的前端地址(逗号分隔;`*` 放行全部;localhost/127.0.0.1 自动双向兼容) | `http://localhost:3000` | | `EXTRACT_CHUNK_MIN_SIZE` | 分块阈值:文本字符数低于此值不分块 | `2000` | | `EXTRACT_CHUNK_SIZE` | 每块目标字符数(3000-4000 适合 LLM 抽取) | `4000` | | `EXTRACT_CHUNK_OVERLAP` | 块间重叠百分比(10-15% 防边界断裂) | `0.10` | | `POPULAR_MIN_FREQ` | 频率统计阈值:出现于 ≥ 该份文档数即记为"高频句" | `2` | > 未配置 `LLM_API_KEY` 时,系统走 mock 模式返回示例数据,便于前端联调与演示。接入真实大模型只需填入 Key 与 Base URL。 ## API 文档 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/health` | 健康检查 | | POST | `/api/upload` | 上传文件(TXT/PDF/DOCX) | | POST | `/api/upload/text` | 直接提交文本 | | POST | `/api/extract` | 抽取哲理句(**异步**:立即返回,后台线程执行,前端轮询进度) | | GET | `/api/tasks` | 任务列表(分页信封:`{total,limit,offset,items}`,每项含 `sentence_count`) | | GET | `/api/tasks/stats` | 统计概览(文档数 / 完成数 / 哲理句数 / 来源分布 / 高频句数) | | GET | `/api/sentences/top` | 跨任务 Top 评分哲理句(?limit=10,含 `task_id`/`source_type` 便于跳转) | | GET | `/api/sentences/frequent` | 热门哲理句(按跨文档出现频率排序,?limit=10,含 `frequency` 字段) | | GET | `/api/tasks/{id}` | 任务状态(含 `sentence_count`、`file_md5`、`progress`、`parts_total`) | | GET | `/api/tasks/{id}/result` | 抽取结果(分页) | > **清空数据**:系统不提供清空接口,直接清空数据库即可——`uv run python scripts/clear_data.py`(清空任务+哲理句+上传文件),加 `--drop` 可删库重建表(用于模型字段变更后的结构重置)。 启动后端后访问 http://localhost:8002/docs 查看交互式 API 文档(Swagger)。 ## 核心设计 ### 评分公式 ``` Score = 0.4×Emotion + 0.3×Insight + 0.2×Clarity + 0.1×Literary ``` 四舍五入为整数。System Prompt 内嵌评分标尺,要求 LLM 给出分项分数 + 理由,防止打分漂移。 ### 两步定位法(防幻觉) 1. **粗定位**:LLM 引用原文中的 `[页x|段y]` 定位标记 2. **精定位**:后端回查标记是否真实存在 + 句子是否逐字出现,计算 `match_confidence` 3. **兜底**:精定位失败 → `match_confidence = null`,绝不"猜一个" ### 反鸡汤规则 - 黑名单词:注定 / 绝对 / 一定 / 永远 / 必然 - 偏好:承认生活复杂性 + 给出微小希望,而非廉价乐观 ### 频率统计(热门句) 同一文件(含大文件分份合并后)内重复的哲理句会自动去重,只保留评分最高的一条。**跨文件**的重复句仍各自保留。 每句按归一化文本(去空格/标点/大小写)聚合,统计其出现于**多少份不同文档**(`frequency`)。 频率越高,说明该句越被多方印证、越流行有用。首页据此展示: - **高频句数**指标:出现于 ≥ `POPULAR_MIN_FREQ` 份文档的哲理句数量 - **🔥 热门哲理句**榜单:按 `frequency` 降序,标注"出现于 N 份文档" > 如需彻底重置数据库(如模型字段变更),可用脚本:`uv run python scripts/clear_data.py --drop` ## 扩展方向 当前为文本核心闭环,已预留扩展接口: | 能力 | 当前实现 | 扩展方向 | |------|---------|---------| | 元数据库 | SQLite | 切换连接串迁移 PostgreSQL | | 频率/相似度检索 | 归一化文本聚合(内存计算) | 抽象接口接入 Milvus / 向量库做语义聚类 | | 音频/视频 | 预留 ASR 接口 | 接入 Whisper API | | 意境图 | 预留生成接口 | Unsplash 兜底 + SDXL/DALL·E | ## License MIT