2026/10/5 16:20:45

自建AI资讯聚合平台:从RSS采集到大模型摘要的完整实践

自建AI资讯聚合平台:从RSS采集到大模型摘要的完整实践 信息过载这个老问题我选择用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_keyyour-api-key, base_urlhttps://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( modelyour-model-name, messages[ {role: system, content: 你是一个严谨克制的资讯编辑。}, {role: user, content: prompt} ], temperature0.3, max_tokens300 ) 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_id12345 /var/log/agg/*.log | head -20告警这里做一个最小闭环采集任务连续三次失败、AI加工队列积压超过阈值、日预算透支这三个条件触发时才发通知。太多的告警反而会让人麻木要学会用安静来衬托异常。7. 完整排障实录那些折磨我一整天的坑7.1 RSS同一时间戳导致增量更新丢失项目上线第二周我发现有一个信息源总是隔几天就漏掉一两条新资讯。排查日志后发现该源的RSS条目published_at是按分钟精度输出的当同一分钟内发布多条内容时我的增量更新逻辑只取了最新一条的时间戳其余同分钟的条目全部被跳过。解决思路分两步第一步增量更新不再只记录一个时间戳而是记录本轮采集到的所有条目ID集合下轮先做ID查重再做时间过滤第二步对分钟精度的源额外用内容指纹做兜底去重。这两个措施改了以后漏数据的问题彻底消失。7.2 大模型摘要输出50字就截断了有一次调试摘要模块发现部分资讯到的摘要只有一句话明显偏短。查了模型日志发现请求日志中max_tokens300设置没问题但模型实际返回的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的庞然大物连续迭代比一次性完美重要得多。最后再分享一个真实的体会做一个信息聚合工具最有价值的不是它帮你节省了多少时间而是它让你开始审视为什么过去会容忍那么多低质量信息这一件事。技术的价值不在于替代思考而在于把你从重复劳动中解放出来去思考真正重要的问题。