一个可以替换模型和数据的语义新闻推荐骨架:先把新闻内容变成向量,再用用户的一句话去找语义上最接近的内容。
我做这个项目时想验证一个很具体的判断:新闻推荐不一定要把排序决策全交给聊天模型。更稳的做法是把内容库提前编码成 embedding,用户查询进来时只做一次向量化和一次检索。
这份 repo 留下的是一条可以跑通、可以拆开看、也方便替换模型和数据的推荐流程。它适合用来参考语义检索、内容推荐、知识库召回、课程/文章匹配这类场景。
flowchart LR
A[新闻标题和正文] --> B[文本清洗]
B --> C[Embedding 模型]
C --> D[向量缓存]
E[用户兴趣描述] --> F[查询向量]
D --> G[FAISS / NumPy 检索]
F --> G
G --> H[类别过滤和 Top-K 排序]
H --> I[Gradio 推荐结果]
关键词:新闻推荐、语义检索、向量召回、Sentence-BERT、FAISS、Gradio、embedding recommender、semantic search。
先装开发依赖并跑测试:
git clone https://github.com/Ce-Legend/llm-news-recommender.git
cd llm-news-recommender
python -m pip install -e .[dev]
python -m pytest -q要打开 Gradio 页面,再安装完整依赖:
python -m pip install -e .[full]
python scripts/download_data.py --samples 20
python app.py浏览器打开:
http://localhost:7860
如果本地没有 Sentence-BERT 缓存,项目会先用哈希向量跑通 demo 流程。这个 fallback 只用于检查数据流,不代表最终推荐效果。认真评估推荐质量时,建议缓存中文 embedding 模型,或者配置 DashScope embedding API。
输入:
人工智能技术发展
输出会是类似这样的 Top-K 列表:
1. [科技] ChatGPT引爆人工智能新浪潮,全球科技巨头竞相布局
similarity: 92.3%
2. [科技] 国产大模型百花齐放,通义千问、文心一言表现亮眼
similarity: 89.7%
3. [股票] 人工智能概念股持续活跃
similarity: 84.1%
更完整的样例见 examples/sample-recommendation.md。
直接让 LLM 给一组新闻标题,看起来很聪明,但很难解释为什么这几条排在前面。这里先把新闻和查询放到同一个向量空间里,再按相似度取 Top-K。每条结果都有原始分数,调试时能回到向量检索这一层。
新闻库相对稳定,用户查询一直变化。把所有新闻向量每次重新算一遍没有必要。这个项目会把新闻 embedding 保存成 .npy,下次启动直接加载。查询进来时,只生成查询向量。
余弦相似度适合排序,但不一定适合给用户看。代码里保留了原始相似度,同时把展示分数映射成更直观的百分比。产品里经常会遇到这种情况:模型分数用于计算,展示分数用于沟通。
很多 AI demo 第一步就卡住:FAISS 装不上,模型没下载,API key 没配。这里保留两层降级:
- 没有 FAISS 时,用 NumPy 做相似度检索。
- 没有 embedding 模型时,用哈希向量先跑通数据流。
这层降级的目标很简单:先让别人看懂流程,再决定要不要替换成更好的模型和索引。
.
├── app.py # Gradio demo
├── scripts/
│ └── download_data.py # 生成示例数据 / 处理 THUCNews
├── src/
│ ├── config.py # 路径、模型和 Web 配置
│ ├── data_processor.py # 数据读取、清洗、样例生成
│ ├── embedding_generator.py # Sentence-BERT / DashScope / hash fallback
│ └── recommender.py # 向量索引、检索、类别过滤
├── examples/
│ └── sample-recommendation.md # 一次推荐输出样例
└── tests/ # 不依赖大模型下载的单元测试
这个项目更像一个推荐系统骨架,适合继续往真实产品或实验对比里扩展。
- 想提升语义效果:替换
EMBEDDING_MODEL,使用更适合中文新闻的 embedding 模型。 - 想提升检索速度:安装 FAISS,或者把索引持久化成独立服务。
- 想接真实数据:把新闻整理成
title、content、category、full_text结构。 - 想做产品化推荐:加入用户画像、点击反馈、时间衰减、去重和 rerank。
- 想做实验对比:加入 BM25、TF-IDF、hybrid retrieval、cross-encoder rerank。
常用环境变量:
EMBEDDING_MODEL=shibing624/text2vec-base-chinese
ALLOW_HASH_EMBEDDING_FALLBACK=1
USE_DASHSCOPE_API=0
DASHSCOPE_API_KEY=
WEB_HOST=0.0.0.0
WEB_PORT=7860
SHARE_LINK=0默认使用本地 Sentence-BERT。需要 API embedding 时,把 USE_DASHSCOPE_API 设为 1,并配置 DASHSCOPE_API_KEY。
python -m pytest -q当前测试刻意避开大模型下载,重点覆盖这些基础行为:
- 新闻文本清洗。
- 示例数据结构。
- 哈希向量 fallback。
- NumPy 检索 fallback。
- 类别过滤和 Top-K 排序。
这样在没有 GPU、没有模型缓存、没有 API key 的环境里,也能先判断项目骨架是不是稳的。
MIT