☰
自建AI资讯聚合平台:从RSS采集到大模型摘要的完整实践
2026/10/5 16:20:24 网站建设 项目流程

信息过载这个老问题,我选择用AI自己动手解决

每天打开手机,几十个App轮流推送,一会儿是某个大模型发了新版本,一会儿是哪个实验室又放出了重磅Paper,一会儿又是某家开源社区吵翻了天。做技术的人应该都有这种感觉:我们不是缺信息,而是缺一台能帮我们过滤、归纳、判断的"信息加工机器"。于是我从去年年底开始,花了几个周末,从零搭了一个属于自己的AI资讯聚合平台。

这个平台做的事情很简单:把散落在各种RSS源、技术博客、论文网站、开源社区里的资讯抓回来,用大模型做分类、摘要、去重和热度评分,最后通过一个Web界面统一展示。整个过程完全由我自己掌控规则,没有任何第三方算法的干扰,也顺便治好了我每天在不同网站间反复横跳的毛病。

如果你是一个对AI技术栈感兴趣、想动手实践一整套聚合+处理+展示流程的人,这篇文章应该能帮你节省不少摸索时间。我会从信息源管理、AI加工流水线、数据存储、前端展示、部署运维五个层面完整拆解整个项目,包括我在实际搭建过程中踩过的坑和总结的经验。整个方案兼顾低成本的个人使用场景和可以向外扩展的架构设计,你可以根据自己的需求做裁剪。

1. 先想清楚规则问题:为什么自建而不是继续依赖推荐算法

1.1 原有信息获取方式的三宗罪

在动手写代码之前,我先把市面上的资讯获取方式盘了一遍,归纳下来就是三个问题:

第一是圈子封闭。不管是今日头条还是各种信息流产品,它们的推荐模型都倾向于给你推你点赞过、停留过的东西,于是你看到的信息会越来越同质化。你想跟进行业的新方向,但系统只给你放大的旧兴趣。

第二是噪声太多。一个AI领域的新闻,往往被不同媒体拆分成十条八条,换个标题换个截图就是一篇。真正有价值的信息可能就一两百字,我每天却要在重复内容上浪费大半个小时。

第三是缺乏时间维度的追踪能力。今天想找"上周各家大模型发布的对比信息",要么靠搜索引擎,要么靠收藏夹,过去的信息永远烂在某个角落,无法形成知识脉络。

自建平台解决的核心问题,就是在这三宗罪之外建立"我自己的规则":什么源值得收、什么内容算重要、摘要怎么生成、同类资讯怎么合并。规则清楚之后,信息获取才谈得上效率和沉淀。

1.2 自建方案的目标边界设定

想清楚动机之后,我给自己定了三个项目目标:

  • 低成本:个人场景下,服务器和API调用费用控制在每月几十块钱以内,不引入贵的商用组件。
  • 可扩展:以后想加一个信息源,改一个配置文件就行,不用动代码。
  • 可解释:任何一条资讯为什么出现在首页、为什么被归入某个分类,都能追到具体规则或模型结果。

这些目标直接决定了我后面的技术选型走向。比如我用RSS Hub加自有解析器做信息采集,用SQLite起步、留出切PostgreSQL的接口,用大模型做摘要和分类而不是买一套昂贵的NLP平台。每个决定都是围绕这三点来的。

提示:开工前先把你的目标边界写下来。聚合平台一旦开始接入各种需求就很容易变成"什么都想要"的项目,明确边界能帮你砍掉大半功能。

2. 信息采集层:先把"原料仓"建好,再谈加工

2.1 信息源选型与接入策略

资讯聚合的第一步不是写爬虫,而是梳理信息源。我的选型原则遵循一个优先顺序:有正规API优先用API,有RSS优先用RSS,两者都没有再考虑网页解析。

在实际操作中,我重点整理了四类源:

  • 官方RSS源:很多技术博客、期刊网站(如arXiv、ACM DL)、开源社区动态、部分科技媒体都支持RSS订阅。RSS的优点是格式标准、更新稳定、服务端压力小,是性价比最高的接入方式。
  • 三方RSS服务:有一些项目专门把不提供RSS的网站转换成RSS输出,这类服务的价值在于快速补齐生态位。自建时你可以把这类服务作为中间层,定期拉取。
  • 官方API:像GitHub Trending、Hacker News、Reddit(部分子版块)都有开放API,数据结构干净,适合做进一步加工。
  • 自定义解析:对确实没有RSS也没有API的网站,只能自己抓取HTML解析。这个部分要克制,一是容易触发对方风控,二是一改版就要跟着维护,很消耗精力。

我在搭建时给自己定了一个上限:自定义解析的信息源占比不超过20%。信息源的价值在于稳定和质量,不在数量,一个星期更新两三次的站,宁可晚一天收录,也不能搭进去太多维护成本。

2.2 采集器实现与增量更新

信息采集服务我用Python写,核心是用APScheduler做定时任务调度。每类信息源对应一个采集Worker,它们互不干扰,每个Worker独立管理自己的读取进度。

RSS源的采集逻辑是最简单的,大体流程就是:

pip install feedparser apscheduler requests beautifulsoup4

写采集器时有一个关键概念叫增量更新。RSS本身会保留一定条目的历史记录,但很多站点在推送更新时会把旧条目顶掉。如果每次都从RSS第一页开始解析,很容易漏数据,也容易重复入库。我的做法是给每个信息源维护一个last_fetch_at时间戳,每次采集后记录条目发布时间,下次只解析新的条目;同时给每个条目生成一个内容指纹,作为去重的依据。时间戳加内容指纹双保险,基本能杜绝重复入库。

网页解析型的信息源复杂一些。我用requests加BeautifulSoup抓取页面,先提取标题、正文、日期、作者等字段,再用一个轻量正文抽取算法去掉页头页脚的干扰信息。这个过程最怕的是网站改版。我遇到过几次,处理办法是给每个解析器加一个探针函数,每次抓取时校验关键节点是否还在,一旦发现结构不对就自动告警并停用该信息源,避免把一堆解析失败的乱码灌进数据库。

2.3 去重与清洗:不做这步,后面全是垃圾

很多人在聚合项目上栽的第一个跟头就是没做清洗和去重。同一个开源项目发布新版本,可能GitHub Trending一条、某媒体一条、某博客一条、某论坛又一条。如果不做合并,AI再聪明也架不住你喂给它四份相同的内容。

我用的去重策略分两层:

第一层是内容指纹去重。对每个条目的标题加正文做规范化处理后,计算SimHash值,再用汉明距离做相似度判断。SimHash的实现不复杂,核心思想是把文本分词后映射成64位二进制指纹,指纹之间的汉明距离越小说明文本越相似。设定汉明距离小于等于3就判定为重复内容。

第二层是标题级相似度去重。有些转载文章翻译腔很重,"标题左右"完全不同,但正文几乎一模一样。对这种我额外算一个基于编辑距离的标题相似度,超过阈值就自动归并。归并的规则是谁的最早发布时间靠前,就以谁为主条目,其余作为衍生条目挂在主条目下面,前端展示的时候默认折叠。

清洗环节则负责处理各种格式噪音:HTML实体、广告追踪参数、短链接、乱码字体。我的做法是维护一个正则规则库,对各种常见噪音做批量替换。这步不复杂但很琐碎,建议一开始就沉淀规则,不然后面每加一个信息源都要返工。

3. AI加工层:摘要、分类、评分是聚合平台的大脑

3.1 用大模型API做摘要有哪些门道

信息采集回来之后,原始条目是"原料",要变成用户能快速消费的资讯,必须经过AI加工。我选择了大模型API方案,主要原因是大模型在中文摘要、跨领域归纳上表现明显优于传统NLP方法,而且不需要专门训练模型,改Prompt就能调效果。

摘要任务的实现要点不在模型多强,而在输入输出的设计。我给自己定义的摘要规则是:输出3到5句话,控制在150字以内,保留关键数字、时间和结论,去掉主观评论和空话。为了防止模型发挥过度,我在Prompt里明确要求只基于原文信息做摘要,不允许补充外部知识。

实际调用API的代码大概长这样:

from openai import OpenAI client = OpenAI( api_key="your-api-key", base_url="https://your-llm-endpoint" ) def summarize_article(title: str, content: str) -> str: prompt = f""" 你是资讯编辑。请用3-5句话概括以下文章的核心内容。 要求: 1. 不得添加原文不存在的信息 2. 保留关键时间、数字、人物、机构名称 3. 输出纯文本,不要标题,不要序号 4. 总字数控制在150字以内 文章标题:{title} 文章正文: {content[:3000]} """ response = client.chat.completions.create( model="your-model-name", messages=[ {"role": "system", "content": "你是一个严谨克制的资讯编辑。"}, {"role": "user", "content": prompt} ], temperature=0.3, max_tokens=300 ) return response.choices[0].message.content.strip()

这里有一个低成本技巧:正文超过3000字的截断再送入模型。对于做资讯摘要来说,关键信息通常集中在前半部分,截断几行文字几乎不影响摘要质量,却能把API费用压下去一半以上。

3.2 分类打标:规则模型与LLM的混合方案

分类这块我一开始试过纯大模型分类,一条资讯丢给模型问它属于哪个领域,结果准是准,但贵。后来我把方案改成了两段式:先用轻量规则模型做粗分类,大模型只在规则模型无法判断时才介入。

规则模型的核心是一张"关键词表加权重"的配置。比如"大模型""transformer""多模态""SOTA"这些词出现在文本里,就归类到"模型技术"类别;"融资""收购""财报""IPO"等词出现,就归类到"商业动态"。每个类别维护一组正向关键词和一组负向关键词,打分取加权和,胜出者作为初步分类结果。

两段式的完整流程是:先跑规则模型,如果最高分超过设定阈值(比如30分),直接用规则模型结果;否则进入LLM分类,让模型把文本归类到预设的类别集合中。这样的混合策略在实测中能把大模型调用量压缩到总条目的两成左右,分类准确率仍然保持在九成以上。

分类体系的设计也不宜过细。我从一开始就被各种细分领域诱惑,比如"自动驾驶""AIGC""芯片""人形机器人"分了一大堆,结果很多技术文章跨领域严重,分类边界模糊反而干扰阅读。后来收敛到八类:模型技术、应用落地、商业融资、开源动态、工具与框架、算力与基础设施、政策与合规、学术研究。你要做的话,建议一开始就控制在十类以内,宁可粗不要乱。

3.3 热度与新鲜度:如何让AI排序而非堆时间线

信息源一多,同一时刻涌进来的新鲜内容可能有几十条,如果只是按时间倒序排,首页就会变成"流水账"。我给排序设计了两个维度的分数。

一个是热度分,综合参考内容的新鲜度、来源权重、关键词命中情况。比如来自官方博客的内容权重比转载站高,标题里命中"发布""开源""重大更新"这类动作词会加分。另一个是相关度分,它来自LLM语义检索——把用户正在看的某条资讯做向量化,再找库中其他条目与它的相似度,在详细页下方推荐"相关内容"。

这两个分数最终合并成一个排序权重,公式很简单:

score = freshness_score * 0.4 + source_weight * 0.3 + keyword_hit_score * 0.3

不要把这个公式想得太高大上,它的重点在于让每一条资讯都能有一个对用户来说"为什么排在前面"的解释。热点发生时你会发现,时间线上的信息流动终于不再是全量推送,而是有一个质量梯度在里面。

3.4 多AI协作:让不同模型干各自擅长的事

我的平台在做摘要和分类时,并没有把鸡蛋放在一个篮子里。摘要模块用的是偏向归纳总结能力的模型,分类模块用的是分类指令遵循能力更强的模型。通过统一封装的Provider接口,不同模型之间可以直接路由切换。

这种多AI协作的思路在聚合平台里非常有用:摘要模型追求信息密度,分类模型追求标签准确,搜索模块还可以搭配不同的embedding链路。整个流程看起来流水线化了,但每一段都是相对独立的,换掉任何一环都不影响其他环节运行。

4. 数据层设计:你的资讯知识库要能撑起搜索和推荐

4.1 数据库选型:轻量起步与可迁移设计

个人资讯聚合平台的数据量分级很清楚:每天几千条资讯,积累一年也就百万条级别,不考虑全文检索时,普通数据库完全没有压力。我选了SQLite作为起步存储,理由是不用单独维护数据库服务,备份就是拷一个文件,特别适合个人项目。

当然SQLite不是终点。在设计表结构时我刻意保持与PostgreSQL兼容的写法,比如统一使用TEXT类型存文本、时间字段用ISO8601格式存储、不依赖SQLite特殊的自增语法。这样万一以后要迁移到PostgreSQL,改动量能控制在最小范围。

4.2 核心表结构与存储策略

我实际用到的核心表有三张,设计思路给你参考:

  • articles表:存主条目,字段包括标题、摘要、正文链接、原文发布时间、抓取时间、分类ID、来源ID、热度分、状态标记。
  • article_duplicates表:存衍生条目,记录与主条目的关联关系以及相似度值。
  • processing_log表:记录每次AI加工的状态,避免重复处理。
CREATE TABLE articles ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, summary TEXT, content_url TEXT, raw_content TEXT, source_id INTEGER, category_id INTEGER, published_at TEXT, fetched_at TEXT, heat_score REAL DEFAULT 0, status INTEGER DEFAULT 0 ); CREATE TABLE article_duplicates ( id INTEGER PRIMARY KEY AUTOINCREMENT, main_article_id INTEGER, dup_article_id INTEGER, sim_score REAL ); CREATE TABLE processing_log ( id INTEGER PRIMARY KEY AUTOINCREMENT, article_id INTEGER, process_type TEXT, status INTEGER, raw_response TEXT, created_at TEXT );

有一个细节特别值得留意:原始抓取内容我只保留最近30天的完整文本,更早的会进行裁剪,只留摘要和链接。这是因为原始文本占用空间大,而资讯类的长尾价值其实很低,没必要永久存。裁剪用定时任务在每天凌晨执行,一个月跑下来数据库体积能控制在一百兆以内。

4.3 搜索与向量索引的演进

聚合平台刚上线时,我只做了简单的SQL模糊搜索。用起来之后发现体验很差:搜"开源大模型"匹配不到"开放模型权重"这类同义表达,用户得猜测精确用词才行。

后来我引入了向量索引。每个月把新入库的摘要和标题用embedding接口转成向量,存进本地向量库,查询时先做向量相似度召回,再用SQL做过滤。具体实现上,我用了一个轻量的向量库,配合每天的增量索引更新,最终搜索响应时间控制在几百毫秒内,同义查询的命中率也明显提升。

5. 前端与交互:自己的平台也要让自己用得舒服

5.1 技术选型:别在界面上堆砌复杂度

前端我用的方案是Vue加一套开源UI组件库,后端用FastAPI提供聚合API。选择这个组合没有太复杂的理由:Vue的生态成熟,FastAPI写起来简洁,个人项目不需要背一个重型的微前端框架。

整个前端拆成四个核心页面:聚合信息流、分类浏览、资讯详情、关键词搜索。信息流页面是常态入口,分类页负责让用户按领域刷,详情页承担阅读和推荐功能,搜索页满足精确检索需求。这样的页面分布对个人使用来说已经够用了,你不需要一步到位做一个多角色权限管理后台。

5.2 信息流设计:二维过滤让阅读效率翻倍

信息流页面我最初做成了单列时间线,但很快发现不行,一天几十条资讯叠加起来,单列列表要翻很久。后来改了设计:左侧是分类筛选栏,顶栏是时间范围筛选和关键词快速过滤,中间主区域才渲染资讯卡片。这样"先定领域再看时间范围再扫信息"的三步动作,比原来一条条翻效率高很多。

每张资讯卡片上,我把三块信息排在最显眼的位置:AI生成的摘要、来源名称和发布时间、关联标签。这三个元素让用户不点进详情就能决定是否要看。如果摘要写得够好,卡片停留时间平均不会超过两秒。

5.3 搜索与个性化:不止是找东西,更是沉淀档案

搜索功能的升级核心是"搜得到还要知道为什么"。前端会在搜索结果里同时展示关键词命中的片段和向量召回的候选。这样的设计有一个额外收益:它会逼着后台把分类、标签、摘要都结构化存档,这些数据本身就成了后续做周报、做趋势统计的原料。

我每周还会生成一份"本周重要动态摘要",方法是把本周热度分最高的十条资讯的摘要汇总后重新交给模型,生成一份500字的周报大纲。这个功能谈不上多智能,但它让我的资讯平台从一个"阅读器"变成了一个"档案管理员"。

6. 部署运维与成本控制:个人项目的性价比拉满指南

6.1 服务器部署与定时任务

整个平台我部署在一台2核4G的轻量云服务器上,系统是Ubuntu。采集、AI加工、API服务分成三个进程,用systemd管理,确保异常退出后能自动拉起。

定时任务的级别要设计得清晰一些:采集任务每15分钟跑一次,AI加工任务每30分钟跑一次,清洗与裁剪任务每天凌晨执行。我用APScheduler的持久化任务存储,有少量任务失败会自动记录日志,下一次调度时重新尝试。整个集群跑下来,平时CPU占用不到10%,深夜跑批量任务时短时能跳到30%,系统整体很轻松。

6.2 API成本火山:如何控制大模型账单

个人项目最容易失控的就是大模型API账单。我有一套完整的成本控制策略:

  • 只有新入库且未被处理过的资讯才送模型加工,中间状态一律不重复调用。
  • 摘要模型输入截断到3000字符,分类模型只送标题加首段,输出限制在100个token内。
  • 设定日预算额度,每天累计调用费达到阈值后自动降级为只做规则模型加工,不发大模型请求。
  • 全部模型调用走统一的Provider层,想替换模型只需要改一行配置。

按这个策略运行,我平均每天加工200到300条资讯,每月API费用控制在30到60元之间,叠加服务器费用每月总成本不到80元,完全在个人可接受范围。

注意:这里是个人项目的策略,如果将来要把平台开放给多人使用,成本模型要重新计算。日预算降级机制从第一天就应该设计进去,越早越好。

6.3 监控与排障:日志是最便宜的运维工具

个人项目不需要上完整的监控体系,但基础的日志和告警还是要有的。我把每个采集Worker、每次AI加工、每次API调用都打了结构化的JSON日志,日志里记录耗时、状态、错误码和关键参数。排查问题的时候,一条命令直接查到任意条数据的流转链路:

grep "article_id=12345" /var/log/agg/*.log | head -20

告警这里做一个最小闭环:采集任务连续三次失败、AI加工队列积压超过阈值、日预算透支,这三个条件触发时才发通知。太多的告警反而会让人麻木,要学会用安静来衬托异常。

7. 完整排障实录:那些折磨我一整天的坑

7.1 RSS同一时间戳导致增量更新丢失

项目上线第二周,我发现有一个信息源总是隔几天就漏掉一两条新资讯。排查日志后发现,该源的RSS条目published_at是按分钟精度输出的,当同一分钟内发布多条内容时,我的增量更新逻辑只取了最新一条的时间戳,其余同分钟的条目全部被跳过。

解决思路分两步:第一步,增量更新不再只记录一个时间戳,而是记录本轮采集到的所有条目ID集合,下轮先做ID查重再做时间过滤;第二步,对分钟精度的源,额外用内容指纹做兜底去重。这两个措施改了以后,漏数据的问题彻底消失。

7.2 大模型摘要输出50字就截断了

有一次调试摘要模块,发现部分资讯到的摘要只有一句话,明显偏短。查了模型日志,发现请求日志中max_tokens=300设置没问题,但模型实际返回的finish_reason是stop,不是length。问题出在我Prompt里写了"输出纯文本,不要标题,不要序号",模型理解成"尽量简短"。

后来我在Prompt末尾补了一条:"无论任何情况,必须完整输出3到5句话,不得省略。"并且把max_tokens调到600,问题没有再出现。这个案例给我的教训是:Prompt里的每句话都可能在模型那里放大含义,你对输出的约束越精确,得到的成品才越稳定。

7.3 信息源突然改版导致解析器全军覆没

第三周的时候,某个重要信息源改版了网站结构,我的解析器预期能找到的正文节点消失,结果一晚上抓到两百多条都是只有标题没有正文的残缺数据。还好我提前做了探针校验,第二天早上看到告警后迅速下线了改版源,才没有污染AI加工队列。

修复过程不复杂,就是把新页面的HTML结构重新观察一遍,调整CSS选择器,加一个测试用例再恢复上线。这次事故提醒我做两件事:第一,重要信息源最好每周人工抽查一次,不能全依赖自动勘探;第二,解析器里任何"节点获取失败"的情况都要抛出明确异常,而不是默默返回空字符串,不然残缺数据会像病毒一样流向下游。

7.4 数据库增长失控:full text列吃了大半磁盘

部署初期我没有设置历史裁剪任务,结果三个月后数据库体积直接突破1GB。检查后发现绝大多数空间都被raw_content字段占用,早期抓取的文章正文全文堆在那里,从未被检索过。

解决方式是在表里加一个is_full_content_available标记,对超过30天的旧文章执行正文清理,只保留摘要、标题和链接。清理后数据库体积从1GB降到不到300MB,查询速度也明显变快。从这之后,"长尾数据定期裁剪"成了我所有数据项目的默认规则。

8. 扩展到多用户形态:从个人工具到小团队共享

完成个人使用闭环之后,我顺手做了一次扩展探索,目标是让两三个懂技术的朋友也能使用这个平台。改动方向有三个:启动登录认证,用最简单的方式支持账号隔离;把每篇文章的收藏和标注独立存储,避免互相干扰;在API层面增加访问频率限制,防止单个人把服务打爆。

这次扩展给我最大的体会是:个人工具和多用户工具完全是两个物种。个人版本可以容忍某些页面三秒才加载,但多人使用时加载超过一秒就会被吐槽;个人版本可以随意裸奔,多人使用必须考虑权限和隐私。如果你本来就不打算把它开放出去,建议保持个人工具状态,不要因为过度设计拖垮自己。

9. 做完整套东西,我对AI资讯聚合的新理解

项目到现在运行了几个月,最大的收获不是代码跑得多稳,而是让我对"资讯产品"这件事有了更具体的认知。

过去我总觉得算法推荐里的信息质量差是推荐模型不行,亲手搭了一遍之后才发现,推荐机制的失真往往是从信息源污染就开始了。同样的新闻被改几个字就能变成新的信息流条目,而多数推荐系统根本没有动力去追踪内容的真正来源。自建平台换来的不只是效率,而是让我重新找回了一种信息主权感,规则在我手上,推荐在我手上,存不存历史数据也我说了算。

如果你也想动手搭一个类似的东西,我的建议是从最小闭环开始:一个RSS源、一张表、一个摘要接口、一个能看的页面,先跑通再扩展。别在第一天就幻想做一个媲美专业资讯App的庞然大物,连续迭代比一次性完美重要得多。

最后再分享一个真实的体会:做一个信息聚合工具,最有价值的不是它帮你节省了多少时间,而是它让你开始审视"为什么过去会容忍那么多低质量信息"这一件事。技术的价值不在于替代思考,而在于把你从重复劳动中解放出来,去思考真正重要的问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询