长文算法服务

luojunhui 372ad69762 更新 readme 19 часов назад
applications e2eb17d7cc do not use cache 1 год назад
routes 909d632c37 新增 word2vec功能 1 год назад
test 56433a0c2c 修改alg.toml配置,启动进程数量3个 2 лет назад
tools 395dae55e1 Add request_cache tool 1 год назад
.gitignore 4323133806 Initial commit 2 лет назад
Dockerfile a03898d71f 增加dockerfile && docker-compose.yaml 2 лет назад
LICENSE 4323133806 Initial commit 2 лет назад
README.md 372ad69762 更新 readme 19 часов назад
alg.toml 56433a0c2c 修改alg.toml配置,启动进程数量3个 2 лет назад
alg_app.py 909d632c37 新增 word2vec功能 1 год назад
docker-compose.yaml a03898d71f 增加dockerfile && docker-compose.yaml 2 лет назад
requirements.txt 909d632c37 新增 word2vec功能 1 год назад

README.md

LongArticleAlgServer

面向公众号长文场景的算法服务,提供历史文章查询、候选文章过滤、账号兴趣相关性评分、文章排序、文本向量化和文章爬取入库能力。

服务基于 Quart/ASGI 构建,使用 BGE 计算标题级语义相关性,默认通过 Hypercorn 监听 6060 端口。

核心能力

  • 使用 BAAI/bge-large-zh-v1.5 生成中文文本 embedding,并计算余弦相似度。
  • 根据公众号历史高阅读文章构建账号兴趣集合。
  • 支持均值、最大值和阅读量加权的相关性聚合方式。
  • 按历史重复、低质量标题和敏感内容过滤候选文章。
  • 支持多种文章排序策略,并结合语义相关性与历史阅读量排序。
  • 使用 lili666/text2vec-word2vec-tencent-chinese 提供分词和词向量测试接口。
  • 调用外部公众号爬虫服务,将文章信息写入 MySQL。

技术栈

  • Python 3.10+(源码使用 match/case
  • Quart + Hypercorn
  • PyTorch
  • similarities / text2vec
  • jieba
  • pandas / NumPy
  • aiomysql / MySQL
  • 阿里云日志服务

项目结构

.
├── alg_app.py                       # 应用入口、数据库和模型初始化
├── alg.toml                         # Hypercorn 配置
├── routes/
│   ├── __init__.py                  # HTTP 路由注册
│   ├── accountArticleRank.py        # 候选文章过滤与排序
│   ├── accountServer.py             # 账号兴趣相关性评分
│   ├── articleDBServer.py           # 公众号文章爬取和入库
│   ├── nlpServer.py                 # NLP 功能分发
│   └── word_2_vec.py                # 分词与 Word2Vec 编码
├── applications/
│   ├── articleTools.py              # 历史文章和账号统计查询
│   ├── textSimilarity.py            # 相似度矩阵及聚合算法
│   ├── embedding_manager.py         # embedding 内存/磁盘缓存
│   ├── pipeline.py                  # 重复、质量和安全过滤
│   ├── asyncMySQL.py                # 异步 MySQL 连接池
│   ├── wxSpider.py                  # 外部公众号爬虫客户端
│   ├── aliyunLog.py                 # 阿里云日志客户端
│   └── functions/                   # 排序调用和标题规则工具
├── test/                            # 手工联调脚本
├── tools/                           # 辅助脚本
├── Dockerfile
├── docker-compose.yaml
└── requirements.txt

相关性计算原理

主排序链路使用 BAAI/bge-large-zh-v1.5,而不是 Word2Vec。计算过程如下:

候选标题 ──BGE──> 1024 维语义向量 ─┐
                                    ├──> 余弦相似度矩阵 ──> 聚合 ──> 相关性分数
历史标题 ──BGE──> 1024 维语义向量 ─┘

两个文本向量的余弦相似度为:

similarity(a, b) = (a · b) / (||a||₂ × ||b||₂)

若有 n 个候选标题和 m 个历史标题,服务会生成 n × m 的相似度矩阵。每个候选标题可通过以下方式得到最终分数:

  • max:取该候选标题与所有历史标题相似度的最大值。
  • mean:取该候选标题与所有历史标题相似度的算术平均值。
  • avg:将历史文章阅读量经过 L2 归一化和 softmax 后作为权重,对相似度加权求和。

embedding 由 EmbeddingManager 缓存在内存中,并定期持久化到 cache/embedding_cache.npy 和对应的 key 文件。缓存只减少重复模型推理,不改变相似度算法。

文章排序流程

候选文章
  → 过滤历史低质量标题
  → 过滤历史已发布的相似标题
  → 调用敏感内容服务
  → 查询账号历史高表现文章
  → 计算 BGE 语义相关性
  → 按策略排序
  → 标题去重
  → 截取 publishNum 篇文章

当前策略:

  • ArticleRankV1:按 producePlanName 将文章分为 【1】【2】 和其他三组;部分分组按相关性排序,【2】 分组按阅读量排序,最后合并和去重。
  • ArticleRankV2:统一按相关性降序、crawlerViewCount 降序排序。
  • ArticleRankV3ArticleRankV4ArticleRankV5:当前复用 ArticleRankV1 的实现。

HTTP API

方法 路径 说明
GET /healthCheck 服务连通性检查
POST /embed jieba 分词和 Word2Vec 向量化
POST /nlp 文本相似度及相似度矩阵聚合
POST /score_list 计算候选标题与账号兴趣的相关性
POST /title_list 查询公众号历史标题
POST /articleRank 过滤并排序待发布文章
POST /article_crawler 抓取公众号文章并写入 MySQL

NLP 相似度示例

curl -X POST http://localhost:6060/nlp \
  -H 'Content-Type: application/json' \
  -d '{
    "function": "similarities",
    "data": {
      "text_a": ["新能源汽车销量持续增长"],
      "text_b": ["电动车市场快速扩张"]
    }
  }'

function 支持:

  • similarities
  • similarities_cross
  • similarities_cross_max
  • similarities_cross_mean
  • similarities_cross_avg

本地启动

前置条件

启动过程不是纯本地运行,当前实现要求:

  1. 能够访问项目配置的 MySQL 实例。
  2. 首次启动时能够获取两个模型,或本地已有对应模型缓存。
  3. 调用文章过滤、排序或爬取接口时,能够访问相应的内部服务。
  4. 有足够内存或显存加载 BGE 和 Word2Vec 模型。

使用 Python 启动

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
hypercorn alg_app:app --config alg.toml

健康检查:

curl http://localhost:6060/healthCheck

使用 Docker Compose 启动

docker compose up --build

alg.toml 当前配置 3 个 worker。每个 worker 都会分别加载模型,需要根据实际内存或显存容量调整 worker 数量。

测试现状

test/ 目录当前主要存放连接固定环境的手工联调脚本,不是隔离外部依赖的自动化测试套件。运行这些脚本可能访问数据库或内部 HTTP 服务,执行前应先检查目标地址和请求数据。

建议优先补充以下自动化测试:

  • /nlp 的相似度矩阵和聚合算法单元测试。
  • /score_list 的数据库查询与账号兴趣计算契约测试。
  • /articleRank 的过滤、分组、去重和排序测试。
  • 使用 mock 隔离 MySQL、模型下载、敏感词服务和公众号爬虫服务。

已知限制与安全提示

  • 当前源码包含硬编码的数据库和云日志配置。投入新环境前应轮换现有凭证,并迁移到环境变量或密钥管理服务。
  • 部分 SQL 使用字符串拼接构造,接收外部输入时存在 SQL 注入风险,应改为参数化查询。
  • Quart 请求链路中仍存在同步 requests 调用,会阻塞 event loop。
  • 排序流程通过 HTTP 回调本服务的 /title_list/score_list,增加了延迟和故障传播范围。
  • 当前代码中的账号标识存在 accountNameaccount_nickname_listghIdgh_id_list 等多套命名,调用接口前应核对契约。
  • 当前 checkout 中部分路由参数和底层方法签名不一致,完整联调前需要先完成接口对齐。

部署

容器入口为:

hypercorn alg_app:app --config alg.toml

默认监听 0.0.0.0:6060。生产部署前应至少完成:

  • 外部化数据库、日志、模型和下游服务配置。
  • 移除或轮换源码中的历史凭证。
  • 确认 worker 数量与模型资源占用匹配。
  • 为所有外部 HTTP 请求增加明确的超时、重试和熔断策略。
  • 建立健康检查、关键接口测试和基础监控。