跳至内容

平台与应用

数字报纸档案

报纸 PDF 私有档案库:支持 OCR、意大利语全文检索、语义检索,以及会注明出处的 AI 助手。

类型平台与应用

这是一个为私人收藏打造的数字报纸档案:PDF 格式的报纸变成一个可以检索的档案库,任何文章都可以通过关键词、语义或直接提问找到,并且始终注明出处。

问题

客户有一批以 PDF 文件保存的报纸。想找一篇文章,就得一个个打开文件,而且很多页面是没有文字的扫描件。此外,档案库必须保持私密:只有管理员邀请的人才能进入。

我做了什么:一个数字报纸档案

我开发了一个私有的 Web 档案库,每一期报纸都按报名、日期和 PDF 存储,每一页都可以检索。

  • 文字提取,OCR 兜底:页面如果自带文字层,就直接使用。文字少于 40 个字符的页面会以 220 DPI 渲染,再用 Tesseract 识别。旧扫描件也因此可以检索。
  • 意大利语全文检索:检索采用意大利语词干提取并忽略重音,因此搜索「citta」也能找到「città」。完全匹配的短语排在最前,并附带高亮摘要。
  • 语义检索:页面文字被切分成相互重叠的文本块,再用多语言模型转换为 768 维向量。即使读者不知道确切的用词,也能找到文章。
  • 附带引用的助手:读者用日常语言提问。系统按语义和关键词检索最多 8 个段落,Claude 只依据这些段落作答,并注明报名、日期和页码。该功能在管理面板中启用,使用客户自己的 Anthropic 密钥。
  • 按文件夹批量上传:管理员选择一个 PDF 文件夹,日期从每个文件名中读取。重复文件会按报名和日期或按 SHA-256 指纹跳过,因此可以放心地重复上传。
  • 仅限邀请访问:两种角色,管理员和读者。面板用于管理用户、报名、AI 密钥和备份。

数据

  • 嵌入服务设有 8 GB 内存上限,并每天重启。设置上限之前,它曾膨胀到约 15 GB,导致队列阻塞了一周。
  • 每晚 03:30 备份:压缩的数据库转储,保留最近 14 份,另加 PDF 文件的增量镜像。
  • 卡住的任务自动恢复:运行超过 20 分钟的任务会重新放回队列,最多尝试 6 次。

技术栈

Web 应用使用 Python 3.11 和 FastAPI。PostgreSQL 16 配合 pgvector、unaccent 和 pg_trgm,负责数据、全文检索和向量。PyMuPDF 和 Tesseract 负责文字提取和 OCR。嵌入使用 sentence-transformers 和 multilingual-e5-base 模型,作为独立的本地服务运行。助手使用 Anthropic API。所有组件都以 systemd 服务运行,前面是 Apache 反向代理。

为什么这样做

我把任务队列放在 PostgreSQL 内部,而没有另加 Redis。工作进程通过 FOR UPDATE SKIP LOCKED 领取任务,因此多个工作进程可以并行运行,而且绝不会重复处理同一期报纸。这台服务器还托管着其他网站,少运行、少维护一个服务,是实实在在的好处。

有想法?
聊聊吧。

无论是网站、应用、视频、歌曲,还是更大的项目,我都乐意帮您实现。

联系我
  • 那不勒斯
  • 想法
  • 项目
  • 人
  • 永远向前