news 2026/10/20 22:10:12

Hermes自动化调度实战:每日AI产品追踪推送系统搭建

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Hermes自动化调度实战:每日AI产品追踪推送系统搭建

1. 从手动刷信息到自动推送:这个任务到底在解决什么问题

每天早上打开手机,十几个信息源挨个刷一遍,看看有没有新的 AI 产品冒出来——这件事我干了大概小半年,后来实在扛不住了。不是说信息不重要,而是重复劳动太消耗人。你想想,同一个动作,每天花二三十分钟,一个月下来就是十几个小时,这些时间拿来做点深度研究不香吗?

所以我就琢磨着,能不能让 Hermes 帮我把这个活儿接了。Hermes 是我本地跑的一个自动化调度工具,你可以把它理解成一个"定时任务管家",它能按照你设定的时间、频率、触发条件去执行指定的脚本或工作流。我给它安排的任务很明确:每天固定时间,自动去几个渠道搜索最近冒出来的 AI 产品,把结果整理好,推送到我指定的地方。

这个项目的核心价值就三个字:自动化。把"搜索—筛选—整理—推送"这条链路完整地串起来,中间不需要人工干预。适合谁来参考?我觉得两类人最合适:一类是像我这样每天需要跟踪特定领域动态的从业者,另一类是手上有 Hermes 或者其他调度工具、想找个实际场景练手的开发者。哪怕你之前没怎么接触过自动化工作流,跟着思路走一遍也能搭起来。

整个方案的技术栈不复杂,核心就是调度层 + 采集层 + 处理层 + 推送层四块。调度层用 Hermes 负责定时触发,采集层负责从搜索渠道拿数据,处理层做去重和格式化,推送层把结果送到你手上。每一层我都会拆开讲清楚为什么这么设计、有哪些坑要避开。

2. 整体架构设计与方案选型思路

2.1 为什么选 Hermes 做调度而不是系统自带的定时任务

很多人第一反应是用系统自带的 cron 或者计划任务,这没问题,简单直接。但我选 Hermes 有几个实际考量。

第一,可视化管理。cron 表达式写起来快,但过两周你自己都忘了那行0 8 * * *到底跑的是什么。Hermes 提供了任务列表和执行日志的界面,哪个任务成功了、哪个失败了、上次跑了多久,一目了然。

第二,失败重试机制。网络请求这种事,偶尔超时太正常了。cron 跑失败就失败了,你得自己写重试逻辑。Hermes 内置了重试策略,可以配置重试次数和间隔,省了不少事。

第三,任务依赖编排。我这个流程里,搜索和推送是有先后依赖的——搜索没完成,推送就没东西可推。Hermes 支持任务链,前一个任务成功后才触发下一个,逻辑上更清晰。

当然,如果你已经在用 cron 而且跑得挺稳,没必要为了这个项目专门换。工具是为人服务的,不是反过来。

2.2 采集层的渠道选择与取舍

搜索 AI 产品的渠道大致分几类:产品聚合平台、行业资讯站、社区讨论帖、社交媒体。我最终选了两个主要渠道加一个补充渠道。

主要渠道选的是产品聚合平台,因为这类平台的信息结构化程度高,产品名称、简介、发布时间都有固定字段,解析起来省事。补充渠道用的是行业社区的讨论区,这里的信息更及时,很多产品还没上聚合平台就先在社区里被讨论了,但缺点是格式不统一,需要多做一层清洗。

我没有把社交媒体纳入自动采集范围,原因有两个:一是接口限制多,稳定性差;二是噪音太大,筛选成本高。人工偶尔刷刷可以,放进自动化流程里性价比不高。

提示:渠道选择的核心原则是"稳定性优先于覆盖面"。宁可少覆盖一个渠道,也不要因为某个渠道频繁失败导致整个任务链断掉。

2.3 推送方式的选择逻辑

推送这块我试过三种方式:邮件、即时通讯工具、本地文件。

邮件的好处是格式丰富,可以发 HTML 表格,但打开率低,容易被淹没在收件箱里。即时通讯工具打开率高、提醒及时,但消息长度有限制,内容多了要分多条发。本地文件适合做归档,但不适合做即时提醒。

最终的方案是即时通讯工具推摘要 + 本地文件存全量。摘要里只放当天新增产品的名称和一句话简介,点进去能看详情。全量数据按日期存成结构化文件,方便后续检索和回溯。

3. 核心环节拆解与实操要点

3.1 搜索关键词的设计与动态调整

搜索关键词直接决定了你能搜到什么。一开始我用的是"AI 产品""AI 工具"这种大词,结果返回的内容又杂又多,大量重复和无关信息。后来我调整了策略,把关键词分成三组:

  • 核心词:AI、人工智能、大模型、机器学习
  • 产品词:产品、工具、应用、平台、上线
  • 时间词:今日、本周、最新、新发布

三组词做组合,比如"AI 工具 最新""大模型 产品 上线",这样搜出来的结果精准度明显提升。但关键词不是设一次就完事了,我大概每两周会回顾一下搜索结果的质量,如果发现某个词带来的无效结果太多,就把它换掉。

这里有个经验:关键词要跟着领域热点走。比如某个阶段大家都在讨论某个技术方向,那这个方向的词就应该加进去。我一般会留两三个"机动位",专门放这种临时性的热词。

3.2 数据去重的三种策略

去重是这个项目里最容易被低估的环节。你想想,同一个产品可能今天在渠道 A 出现,明天在渠道 B 出现,如果不做去重,你的推送里全是重复内容,用不了几天你就不想看了。

我用了三层去重策略:

第一层:URL 去重。每个产品详情页的链接是唯一的,直接拿 URL 做比对,重复的直接丢掉。这是最快最准的一层。

第二层:名称模糊匹配。有些产品在不同渠道的名称略有差异,比如带不带版本号、有没有副标题。我用的是编辑距离算法,相似度超过阈值的判定为同一产品。阈值设多少合适?我实测下来 0.85 比较稳,太低会误杀,太高会漏掉。

第三层:历史库比对。维护一个已推送产品的历史库,每次新采集的数据都跟历史库比对一次。这层能解决跨天重复的问题——同一个产品昨天推过了,今天就不该再推。

import difflib def is_duplicate(name1, name2, threshold=0.85): ratio = difflib.SequenceMatcher(None, name1, name2).ratio() return ratio >= threshold

注意:去重阈值不要设得太激进。我一开始设了 0.95,结果同一个产品的不同表述被当成两个产品推了两次,后来降到 0.85 才正常。

3.3 结果格式化的字段设计

推送出去的内容要让人一眼看懂,字段设计很关键。我最终保留了五个字段:

字段名说明是否必填
产品名称产品的正式名称是
一句话简介不超过 50 字的描述是
来源渠道从哪个渠道采集到的是
采集时间精确到分钟是
详情链接原始页面地址否

简介字段我做了长度限制,超过 50 字就截断加省略号。为什么是 50 字?因为即时通讯工具的单条消息预览大概就显示这么多,太长了反而看不全。

3.4 推送时机的选择

推送时间我定在每天早上 8 点。这个时间点是我反复调整后确定的。太早了没人看,太晚了上午的节奏已经起来了没空看。8 点刚好是大多数人刚到工位、还没进入深度工作状态的窗口期。

如果当天没有新增产品怎么办?我的处理是推一条"今日无新增"的简短消息。有人觉得没内容就不推了,但我觉得推一条空消息反而让人安心——知道任务跑了,只是确实没新东西。不然你会怀疑是不是任务挂了。

4. 完整实操流程与关键配置

4.1 环境准备与依赖安装

先把基础环境搭好。我用的 Python 3.10,主要依赖三个库:requests负责网络请求,beautifulsoup4负责页面解析,schedule做本地测试时的简易调度。

pip install requests beautifulsoup4 schedule

Hermes 的安装按照官方文档走就行,装完之后确认服务能正常启动。我建议先在本地把整个流程跑通,再挂到 Hermes 上做定时调度。这样出问题的时候排查起来方便,不用在调度环境里来回折腾。

4.2 采集脚本的编写要点

采集脚本的核心逻辑是:发请求、拿响应、解析内容、提取字段。听起来简单,但有几个细节要注意。

请求头要带全。很多渠道会检查 User-Agent,不带的话直接返回 403。我一般会带上 User-Agent、Accept、Accept-Language 这几个常用头。

超时时间要设。不设超时的话,遇到慢响应能把整个任务卡死。我设的是连接超时 10 秒、读取超时 30 秒。

异常要捕获。网络请求失败太常见了,不能让一个请求失败导致整个脚本崩溃。每个渠道的采集逻辑都包在 try-except 里,失败了记录日志继续跑下一个。

import requests from bs4 import BeautifulSoup headers = { "User-Agent": "Mozilla/5.0 (compatible; ProductTracker/1.0)", "Accept": "text/html,application/xhtml+xml", "Accept-Language": "zh-CN,zh;q=0.9" } def fetch_page(url): try: resp = requests.get(url, headers=headers, timeout=(10, 30)) resp.raise_for_status() return resp.text except requests.RequestException as e: print(f"采集失败: {url}, 原因: {e}") return None

4.3 数据处理的管道设计

采集回来的原始数据不能直接推,中间要经过一条处理管道。我的管道分四步:

  1. 清洗:去掉 HTML 标签、多余空白、特殊字符
  2. 提取:从清洗后的文本里抽出产品名称和简介
  3. 去重:走前面说的三层去重逻辑
  4. 排序:按采集时间倒序排列,最新的排前面

这四步我写成了一个独立的处理函数,输入是原始数据列表,输出是处理好的结构化列表。这样做的好处是,如果以后要换采集渠道,处理逻辑不用动,只要保证输入的数据格式一致就行。

4.4 Hermes 任务的配置与挂载

在 Hermes 里新建一个任务,配置项大概是这样:

  • 任务名称:AI 产品每日追踪
  • 执行频率:每天一次
  • 执行时间:08:00
  • 超时时间:300 秒
  • 重试策略:失败重试 2 次,间隔 60 秒
  • 执行命令:python /path/to/main.py

超时时间设 300 秒是因为整个流程走下来大概需要 1 到 2 分钟,留点余量防止偶发的网络慢。重试间隔设 60 秒是为了给渠道服务端一点缓冲时间,太短了重试也是白重试。

配置完之后先手动触发一次,确认能正常跑通,再开启定时调度。我第一次配的时候忘了改执行路径,任务跑了但一直报"文件不存在",排查了半天才发现是路径写错了。

4.5 推送模块的实现

推送模块我封装成了一个独立函数,接收处理好的数据列表,格式化成消息文本,然后调用推送接口发出去。

消息格式我用了简单的 Markdown 风格:

今日 AI 产品新增 3 条 1. 产品A - 一句话简介 2. 产品B - 一句话简介 3. 产品C - 一句话简介 详情见本地归档文件

如果当天没有新增,就发"今日无新增产品"。推送接口的地址和凭证我放在环境变量里,不硬编码在代码中,这样换环境的时候不用改代码。

5. 常见问题与排查技巧实录

5.1 采集失败的高频原因与对策

采集失败是最常见的问题,我整理了一个速查表:

现象可能原因排查方法解决方式
返回 403请求头不完整检查 User-Agent补全常用请求头
返回 429请求频率过高看日志里的请求间隔加延时或降低频率
返回空内容页面结构变了手动访问对比更新解析规则
连接超时网络波动或服务端慢重试一次看是否恢复加大超时时间
解析报错HTML 结构不匹配打印原始 HTML 检查调整选择器

提示:页面结构变更是最隐蔽的问题。渠道改版后,你的解析规则可能还能跑,但提取出来的字段是空的或者错的。我建议每次推送前做一个简单的字段校验,发现异常字段就告警。

5.2 去重逻辑的边界情况处理

去重逻辑有几个边界情况容易出问题。

同名不同产品。有些产品名称很通用,比如"智能助手",不同公司出的都叫这个名。这种情况光靠名称匹配会误判。我的处理是,名称匹配的同时要比对来源渠道,如果渠道不同且名称完全相同,标记为"待确认"而不是直接去重。

名称包含关系。比如"产品A"和"产品A Pro",编辑距离算出来相似度很高,但其实是两个产品。我的处理是,如果一个是另一个的子串,且长度差超过 3 个字符,就不判定为重复。

历史库膨胀。历史库越跑越大,比对速度会变慢。我的做法是只保留最近 90 天的记录,更早的归档到冷存储里。90 天足够覆盖绝大多数重复场景了。

5.3 推送消息被截断的处理

即时通讯工具对消息长度有限制,产品多了容易被截断。我的处理是分页推送,每页最多 10 条,超过就分多条发。每条消息开头标注"第 X 页,共 Y 页",方便阅读。

另一个方案是只推摘要,详情放本地文件。但实测下来,大多数人不会主动去翻本地文件,所以还是分页推送更实用。

5.4 任务执行时间过长的优化

一开始整个流程跑下来要 5 分钟,主要时间花在串行请求上。后来我改成了并发请求,用线程池同时请求多个渠道,时间降到了 1 分半左右。

from concurrent.futures import ThreadPoolExecutor def fetch_all(urls): with ThreadPoolExecutor(max_workers=5) as executor: results = list(executor.map(fetch_page, urls)) return results

并发数不要设太大,5 个左右比较合适。太大了容易触发渠道的频率限制,反而得不偿失。

5.5 日志记录与问题回溯

日志是这个项目的"黑匣子"。我记录了三个级别的日志:INFO 记录正常流程节点,WARNING 记录可恢复的异常,ERROR 记录导致任务失败的问题。

日志文件按天切割,保留最近 30 天。出问题的时候,先看 ERROR 日志定位失败环节,再看 WARNING 日志了解上下文。我踩过的坑是日志打得太少,出了问题完全不知道卡在哪一步,后来加了详细的流程日志才好转。

6. 几个让我少走弯路的实操心得

6.1 先跑通最小闭环再优化

我一开始想的是把功能做全,采集、去重、推送、归档一次性都写好。结果写了三天,跑起来一堆问题,排查都不知道从哪下手。后来我换了个思路,先只做"采集一个渠道 + 推送纯文本",跑通了再逐步加渠道、加去重、加格式化。这样每一步都是可验证的,出问题也好定位。

这个经验我觉得适用于所有自动化项目:最小闭环优先。先让流程能跑起来,哪怕粗糙一点,然后再迭代优化。

6.2 给任务留一个"手动触发"入口

自动化任务最怕的是"你不知道它到底跑没跑"。我除了定时调度,还留了一个手动触发的入口,随时可以跑一次看看效果。调试的时候特别有用,不用等到第二天早上才能验证改动。

6.3 推送内容宁少勿多

我一开始恨不得把所有采集到的信息都推出去,结果推送消息又长又杂,自己都不想看。后来砍到只推"新增产品",每条不超过 50 字,阅读体验好了很多。推送的目的是提醒,不是替代阅读。真正感兴趣的内容,用户会自己点进去看详情。

6.4 定期回顾任务价值

自动化任务跑久了容易变成"僵尸任务"——还在跑,但你已经不看推送了。我大概每个月会回顾一次:这个任务推送的内容我还有在看吗?如果连续一周都没点开过,那要么是推送内容需要调整,要么是这个任务本身价值不大了。工具是为人服务的,别让任务变成负担。

6.5 归档数据的二次利用

本地归档的全量数据其实是个宝藏。我后来基于这些数据做了一个简单的趋势统计——每周新增产品数量、各渠道的贡献占比、高频关键词变化。这些统计反过来又能帮我优化搜索关键词和渠道选择,形成了一个正向循环。归档不只是备份,更是后续分析的原料。

这个任务从搭起来到现在跑了大概四个月,中间调整过关键词、换过推送格式、优化过并发策略,现在基本稳定在每天早上 8 点准时推送。偶尔有渠道改版导致采集失败,看眼日志改一下解析规则就能恢复。整体来说,投入产出比很高,每天省下来的那二三十分钟,攒起来能干不少正事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/20 22:09:52

Hermes自动容灾调优:免费线路隐形故障监控与切换实战

1. 项目背景与核心需求拆解1.1 从标题说起:一次典型的“隐形故障”复盘十月份那会儿,我负责的一套模型监控系统突然报出一批异常指标。表面上看,所有服务都在线,接口响应码正常,日志里也没有明显的报错堆栈&#xff0c…

作者头像 李华
网站建设 2026/10/20 22:09:39

海湾NGstCfg4.0消防主机Linux配置工具与通信库实战

简介:这是一套专为海湾消防报警主机现场调试与系统配置设计的专业工具包,面向消防工程技术人员、维保工程师及系统集成商,解决NGstCfg4.0软件在无预装环境下的即开即用问题,覆盖参数设置、回路配置、设备地址批量分配、广播区定义…

作者头像 李华
网站建设 2026/10/20 22:08:37

RAG系统Loader与Splitter深度解析:从文档解析到切块优化

1. 为什么 Loader 和 Splitter 是 RAG 系统的命门做 RAG 应用的人都有一个共识:模型选得再好,检索环节拉胯,整个系统就是花架子。而检索质量的上限,在文档进入向量库之前就已经被决定了。说得再直白一点,Loader 决定了…

作者头像 李华
网站建设 2026/10/20 22:08:09

模型双接口怎么选?OpenAI兼容与原生接口的接入权衡

拿到一个新模型的 API 接入文档,你第一件事会看什么?我的习惯是先看接口格式,而不是先看参数表。参数是纸面实力,接口才是交付形态——一个模型再强,如果接口长得和主流生态对不上,落地的摩擦成本会以你想象…

作者头像 李华
网站建设 2026/10/20 22:07:06

冒泡排序优化全解析:从标志位到鸡尾酒排序的工程实践

1. 为什么冒泡排序值得反复拿出来讲冒泡排序大概是每个学编程的人最早接触的排序算法,没有之一。很多人工作三五年之后,再听到这个名字,第一反应是“这玩意儿太基础了,没什么好聊的”。但我自己的体会恰恰相反:冒泡排序…

作者头像 李华
网站建设 2026/10/20 22:06:47

免费AI编程助手拿下复杂项目榜首:Agent式编码全解析

最近AI编码圈炸了锅。一款新的AI编程助手突然宣布免费开放,而且放话自己在专业软件工程排行榜上拿了第一名,目标直指目前最主流的AI编辑器。很多人在讨论它到底是不是“王炸”,但我的关注点其实是另一个:它对复杂大项目的处理方式…

作者头像 李华