
1. 一份AI日报的诞生从信息洪流到结构化输出每天早上七点我的自动化脚本准时跑完最后一轮抓取把过去24小时里散落在各个角落的AI动态汇总成一份可读的日报。这个习惯我坚持了快两年从最初手动刷十几个信息源到现在一套半自动的流水线中间踩过的坑比想象中多得多。今天这份2026年9月26日的AI日报正好可以拿来当样本把整个生产流程拆开讲清楚。先说清楚这份日报是什么。它不是简单的新闻聚合而是一份经过筛选、去重、分类、摘要、标注来源的结构化简报覆盖模型发布、产品更新、行业动向、开源项目、论文速递几个固定板块。能解决的核心问题是在信息过载的环境下用最短时间掌握当天真正值得关注的AI动态而不是被标题党和重复内容淹没。适合谁看一是每天需要跟踪行业动态的产品经理和开发者二是做投资研究需要快速扫描信号的人三是单纯想保持技术敏感度的从业者。哪怕你只是想自己搭一套类似的信息流这套方法也能直接抄。我最初做这件事的动机很朴素那段时间每天花一个多小时刷各种渠道结果发现真正有价值的信息不到十条其余全是重复转载和无关噪音。后来想明白了问题不在于信息太少而在于没有一套过滤和结构化的机制。于是开始动手搭流程从最简单的RSS订阅加手动整理一步步迭代到现在这套相对稳定的方案。2. 整体设计与思路拆解为什么是这套架构2.1 信息源的分层策略做日报最核心的不是写而是选源。源选错了后面再怎么加工都是白费力气。我把信息源分成三层这个分层逻辑是踩了很多坑之后才定下来的。第一层是一手信源包括官方博客、模型发布页、GitHub趋势榜、主要厂商的更新日志。这一层的价值在于信息准确、时效性最强缺点是分散需要逐个维护。第二层是聚合平台比如技术社区的热榜、行业媒体的快讯。这一层的好处是覆盖面广坏处是噪音大、重复率高经常同一个消息被十几家转来转去。第三层是人工推荐来自几个我长期关注的研究者和从业者的公开动态这一层信息量最少但质量最高往往能提前捕捉到一些还没被广泛报道的信号。为什么要分三层因为单一来源必然有偏差。只靠一手信源会漏掉很多解读和讨论只靠聚合平台会被噪音淹没只靠人工推荐则覆盖不全。三层叠加之后再通过去重和交叉验证才能保证既不漏掉重要信息又不被垃圾内容干扰。2.2 从抓取到成稿的流水线设计整个流程分五个环节抓取、清洗、去重、分类、摘要。每个环节都有对应的工具和判断标准不是随便凑的。抓取环节我用的是定时任务加多源并行每个源单独配置抓取频率和解析规则。清洗环节主要处理HTML标签、广告内容、无关链接。去重是最关键的一步我用的是标题相似度加正文指纹双重比对阈值设在0.85左右这个数值是反复调出来的——太低会漏掉重复太高会误杀相关但不重复的内容。分类环节按预设的板块规则打标签摘要环节则是人工加规则结合重要内容手动精修次要内容用模板化摘要。这套设计的核心考量是可维护性。很多人的日报做着做着就断了原因往往是流程太重、依赖太多。我刻意把每个环节解耦任何一个源出问题都不会影响整体任何一个环节都可以单独替换。比如某个聚合平台改版导致解析失效我只需要改那一个源的配置其他照常运行。2.3 为什么不做全自动有人会问既然都流水线了为什么不干脆全自动生成我的答案是全自动的日报没有灵魂。AI摘要目前能做到信息压缩但做不到价值判断。哪些内容值得放在头条哪些只是一笔带过哪些需要加一句背景说明这些都需要人来判断。我的做法是机器负责80%的重复劳动人负责20%的关键决策这个比例是经过大量实践后觉得最舒服的平衡点。3. 核心细节解析与实操要点3.1 抓取规则的配置细节每个信息源的抓取规则都不一样这里面的门道不少。以官方博客为例很多站点用的是动态渲染直接抓HTML拿不到内容需要等页面加载完成后再提取。我的做法是配置一个等待条件比如检测到某个特定元素出现后再抓取而不是固定等待几秒。固定等待的问题是网络波动时容易抓空条件等待更稳。对于GitHub趋势榜这类结构化程度高的源直接用API比爬页面靠谱得多。API有速率限制所以要配置退避策略遇到限流就指数级延长间隔而不是硬刚。我试过连续请求被临时封禁后来加了退避逻辑就再没出过问题。还有一个细节是时间窗口的设定。日报覆盖的是过去24小时但不同源的更新频率不一样。高频源可能几小时就更新一次低频源可能几天才动一次。我的做法是统一按抓取时间往前推24小时过滤同时给每个源单独设置一个最小间隔避免同一个源在短时间内被重复抓取。3.2 去重算法的参数调优去重是决定日报质量的关键环节。我用的方案是标题相似度加正文指纹具体来说标题用编辑距离算相似度正文用SimHash生成指纹后比对汉明距离。编辑距离的阈值我设在0.85意思是两个标题有85%以上相似就判定为重复。这个数值不是拍脑袋定的我拿过去一个月的抓取数据做过测试阈值0.8时会漏掉一些改了几个字的重复标题阈值0.9时又会把一些相关但不同的内容误判为重复。0.85是在准确率和召回率之间找到的平衡点。SimHash的汉明距离阈值设在3也就是两个指纹差异在3位以内算重复。这个参数对长文本比较敏感太松会导致不同文章被误判太紧又起不到去重效果。实际用下来3这个值对大多数新闻类文本比较合适。注意去重不能只看标题很多转载会改标题但正文完全一样。反过来有些不同来源的报道标题相似但内容角度不同这种不应该被去重。所以标题和正文两个维度要结合起来判断任一维度命中才算重复。3.3 分类规则的维护心得分类看起来简单实际上最容易出问题。我最初用的是关键词匹配比如出现“发布”“开源”“融资”就归到对应板块。用了一段时间发现同一个词在不同语境下含义完全不同误判率很高。后来改成关键词加权加规则优先级的方案。每个板块配置一组关键词每个关键词有权重命中后累加得分得分超过阈值才归入该板块。同时设置优先级比如一条内容同时命中“模型”和“融资”如果融资的权重更高就归到融资板块。这套方案比单纯关键词匹配准确不少但维护成本也更高需要定期回顾误判案例来调整权重。我的经验是分类规则不要追求一次到位而是边用边调。每周花十分钟看看这周的分类结果把明显错的挑出来分析原因慢慢就能把准确率提到可接受的水平。3.4 摘要撰写的取舍标准摘要环节我坚持一个原则能一句话说清就不用两句话。日报的读者要的是快速扫描不是深度阅读。每条摘要控制在50字以内只保留最核心的信息谁、做了什么、有什么影响。具体操作上我会先看原文的标题和首段提取关键信息然后用自己的话重新组织。这里有个技巧不要直接复制原文句子因为原文往往带有宣传色彩或冗余修饰重新组织能去掉这些噪音。比如原文写“某团队自豪地宣布推出了一款革命性的全新模型”摘要就写“某团队发布新模型”把形容词全部砍掉。对于需要背景说明的内容我会在摘要后面加一个简短的备注用括号标注。比如某个模型更新涉及一个不太常见的概念就加一句“该概念指……”帮助不熟悉的读者理解。这个备注不是每条都有只在必要时加。4. 实操过程与核心环节实现4.1 环境准备与依赖安装整套流程跑在一台常驻的云主机上配置不高2核4G足够。操作系统用的是常见的Linux发行版Python环境用3.10以上版本。核心依赖包括请求库、解析库、去重库和定时任务框架。pip install requests beautifulsoup4 simhash schedule请求库负责抓取解析库负责提取内容去重库提供SimHash实现定时任务框架负责调度。这几个库都比较成熟稳定版本更新也不频繁维护成本低。数据库用的是SQLite够用且零配置。主要存三张表原始抓取表、去重后内容表、日报成品表。原始表保留最近7天的数据方便回溯和调试去重后表保留30天成品表长期保留方便做趋势分析。4.2 抓取模块的实现抓取模块的核心是一个配置驱动的多源抓取器。每个源在配置文件里定义好URL、解析规则、抓取频率、超时时间等参数主程序读取配置后并行执行。import requests from bs4 import BeautifulSoup from concurrent.futures import ThreadPoolExecutor def fetch_source(source_config): try: resp requests.get( source_config[url], timeoutsource_config.get(timeout, 10), headers{User-Agent: Mozilla/5.0} ) resp.raise_for_status() soup BeautifulSoup(resp.text, html.parser) items [] for item in soup.select(source_config[item_selector]): title item.select_one(source_config[title_selector]) link item.select_one(source_config[link_selector]) if title and link: items.append({ title: title.get_text(stripTrue), url: link.get(href), source: source_config[name] }) return items except Exception as e: print(f抓取 {source_config[name]} 失败: {e}) return []这段代码的关键在于异常处理。任何一个源出问题都不能影响其他源所以每个抓取任务都包在try里失败就返回空列表并记录日志。并行执行用线程池默认开5个线程这个数量对大多数场景够用太多反而容易触发目标站点的限流。4.3 去重模块的实现去重模块接收所有抓取结果输出去重后的列表。核心逻辑是两两比对但为了效率先用标题相似度做粗筛只对可能重复的项做正文指纹比对。import hashlib from simhash import Simhash def simhash_similarity(text1, text2): h1 Simhash(text1) h2 Simhash(text2) return h1.distance(h2) def deduplicate(items, title_threshold0.85, content_threshold3): unique [] for item in items: is_dup False for existing in unique: title_sim title_similarity(item[title], existing[title]) if title_sim title_threshold: content_dist simhash_similarity( item.get(content, ), existing.get(content, ) ) if content_dist content_threshold: is_dup True break if not is_dup: unique.append(item) return unique这里有个性能上的考量如果抓取量很大两两比对会变成O(n²)的复杂度。我的做法是先按标题首字分组只在同组内比对这样能把比对量降下来。实际跑下来几百条数据的去重耗时在秒级完全可以接受。4.4 分类与摘要模块的实现分类模块用加权关键词匹配配置存在一个独立的JSON文件里方便随时调整不用改代码。def classify(item, rules): scores {} text item[title] item.get(content, ) for category, config in rules.items(): score 0 for keyword, weight in config[keywords].items(): if keyword in text: score weight scores[category] score best max(scores, keyscores.get) if scores[best] rules[best][threshold]: return best return 其他摘要模块目前是半自动的。对于结构化程度高的源比如GitHub趋势榜直接用模板生成摘要对于新闻类内容先提取首段再用规则去掉冗余修饰最后人工过一遍。人工过这一步不能省因为机器摘要经常会把关键信息漏掉或者把次要信息当重点。4.5 日报成品的组装与输出所有环节跑完后成品组装模块按板块把内容组织起来生成Markdown格式的日报。每个板块内部按重要性排序重要性由来源权重、关键词权重、时效性三个因素综合计算。def assemble_report(items, date): sections {} for item in items: category item[category] if category not in sections: sections[category] [] sections[category].append(item) report f# AI 日报{date}\n\n for category in [模型发布, 产品更新, 行业动向, 开源项目, 论文速递]: if category in sections: report f## {category}\n\n for item in sorted(sections[category], keylambda x: x[score], reverseTrue): report f- **{item[title]}**{item[summary]}\n report \n return report输出格式我选的是Markdown因为通用性好可以直接贴到各种平台也可以转成其他格式。每天生成后我会手动过一遍调整一下排序和措辞然后存档。5. 常见问题与排查技巧实录5.1 抓取失败的高频原因与对策抓取失败是最常见的问题原因五花八门。我整理了一个速查表覆盖了大部分情况。问题现象可能原因排查方法解决方案返回空内容页面动态渲染查看返回的HTML是否包含目标元素改用条件等待或API请求被拒绝触发反爬检查状态码和响应头加请求间隔、换UA、用退避策略解析结果错乱页面结构改版对比选择器与实际HTML更新解析规则部分源超时网络波动或源站慢单独测试该源调大超时、降低频率内容乱码编码识别错误检查响应编码手动指定编码这张表是我踩坑踩出来的基本覆盖了九成以上的抓取问题。遇到新问题先对照排查大部分能快速定位。5.2 去重误判的调试方法去重误判分两种漏判和误杀。漏判是重复内容没被识别出来误杀是不同内容被当成重复删掉了。两种都会影响日报质量但处理思路不同。漏判通常是阈值设得太松。我的做法是定期抽样检查随机抽20条去重后的内容人工判断是否有重复。如果发现漏判就把标题阈值调低一点比如从0.85降到0.82然后重新跑一遍历史数据看效果。误杀则是阈值设得太紧。误杀的危害更大因为会直接丢掉有价值的内容。我遇到过一次两篇不同角度的分析文章因为标题相似被误判为重复结果日报里只剩一篇。后来调整了策略标题相似度达标后还要看正文指纹两个都命中才判定重复误杀率明显下降。提示去重参数没有一劳永逸的最优值需要根据信息源的变化定期调整。我的习惯是每月做一次抽样评估根据结果微调参数。5.3 分类准确率的提升路径分类准确率是日报质量的直接体现。我最初的关键词匹配方案准确率大概只有六成经过几轮迭代提到了八成五左右。提升路径主要有三条。第一条是扩充关键词库。初期只配了十几个关键词很多内容归不到正确板块。后来把常见表述都加进去比如“上线”“推出”“开放”都归到产品更新“融资”“收购”“合作”都归到行业动向。关键词库现在有上百个词条覆盖了大部分场景。第二条是调整权重。有些关键词歧义性强比如“模型”这个词在模型发布和论文速递里都会出现就需要给它较低的权重避免误判。而“开源”“发布”这类指向性强的词给高权重。第三条是设置兜底规则。对于得分都没超过阈值的内容统一归到“其他”板块而不是硬塞进某个板块。这样虽然“其他”板块可能有些杂但不会污染主要板块的准确性。5.4 日报断更的预防措施日报最大的敌人是断更。我见过太多人做日报开头热情满满几周后就悄无声息了。断更的原因通常不是懒而是流程太脆弱一出问题就修不动慢慢就放弃了。我的预防措施有三条。第一是监控告警每天日报生成后自动检查条目数如果低于某个阈值就发提醒这样能第一时间发现异常。第二是降级方案如果某个源挂了先用其他源顶上不追求完美保证日报能出。第三是简化维护所有配置都外置改参数不用动代码降低维护门槛。这三条看起来简单但确实有效。我这两年只有过两次短暂断更都是因为云主机故障恢复后很快就补上了。5.5 内容质量的持续优化日报做久了容易陷入惯性每天都是类似的格式和内容读者会疲劳。我每隔一段时间会做一次内容质量回顾主要看三个指标信息密度、独家性和可读性。信息密度是指每条摘要是否都言之有物有没有凑数的内容。独家性是指有没有提供其他渠道看不到的视角或整理。可读性是指排版和措辞是否舒服有没有让人读不下去的地方。这三个指标没有量化标准主要靠自己的判断和读者的反馈。我个人的体会是日报的价值不在于覆盖多少条而在于每一条是否值得读。与其凑二十条平庸的内容不如精选十条真正有价值的。这个取舍标准随着经验积累会越来越清晰。6. 工具选型与替代方案对比6.1 抓取工具的选型考量抓取环节我试过几种方案各有优劣。纯requests加BeautifulSoup的组合最轻量适合结构简单的静态页面。遇到动态渲染的页面就需要上无头浏览器但资源消耗大很多。还有一种方案是用现成的抓取框架功能全但学习成本高对小规模场景来说有点杀鸡用牛刀。我的选择是混合方案大部分源用requests少数动态源用无头浏览器不引入重型框架。这个选择的逻辑是按需使用不为少数场景拖累整体。实际跑下来资源占用和稳定性都满意。6.2 存储方案的对比存储我试过SQLite、JSON文件和轻量数据库。JSON文件最简单但查询和更新不方便数据量大了之后性能下降明显。轻量数据库功能强但需要额外维护服务。SQLite是折中方案单文件、零配置、支持SQL查询对日报这种规模的数据完全够用。选型的核心考量是维护成本。日报是个长期项目存储方案越简单越好不要为了追求性能引入不必要的复杂度。SQLite在这个场景下是最优解没有之一。6.3 调度方案的取舍调度我用的是Python的schedule库简单直接几行代码就能配好定时任务。也考虑过系统级的cron但cron的配置分散在系统里不如代码内配置直观。对于这种单机任务schedule库足够用没必要上更复杂的调度系统。这里有个经验调度方案的选择要和整体架构匹配。如果整个流程都是Python写的用Python的调度库最自然如果流程跨语言那系统级调度更合适。不要为了用某个工具而用某个工具。7. 从日报到知识库的延伸思路日报做久了积累的数据其实很有价值。我最近在尝试把这些数据进一步利用起来做成一个可检索的知识库。思路是把每天的日报内容结构化存储加上时间、来源、分类等维度支持按关键词、时间段、来源等条件检索。这个延伸的价值在于日报是时效性的过了当天就很少有人翻但知识库是累积性的可以随时回溯某个话题的演变过程。比如想了解某个模型从发布到迭代的完整历程在知识库里一搜就能看到所有相关记录比翻历史日报方便得多。实现上不需要额外抓取直接用已有的数据表加一个检索接口就行。我目前用的是一个轻量的全文检索方案对几千条数据来说性能完全够用。后续如果数据量继续增长再考虑上更专业的检索工具。这个延伸还在早期阶段但已经能感受到价值。日报解决的是“今天发生了什么”知识库解决的是“某件事是怎么一步步走到今天的”两者互补形成一个完整的信息处理闭环。