一个Apify Actor运行成功,返回了五条最近的Telegram帖子,每条都带有ID、时间戳和永久链接。看起来一切正常。但当你问出那个自动化真正需要回答的问题——"哪些帖子是新的?"——诚实的答案是:这次运行本身无法知道。
不是哪里失败了。Actor完成了它的工作:把当前可见的内容抓取回来了。但"新"这个属性并不存在于任何单次快照中;它是当前快照与上一次快照之间的差值。这个区别,就是"按计划运行的抓取器"和"你可以信任的监控器"之间的分水岭。
![]()
抓取和变更检测是两件不同的事
这个Actor读取Telegram公开的t.me/s/预览页,按最新优先的顺序返回最近的消息。每条记录包含频道、ID、URL、日期、文本、浏览量等字段。这些信息足以回答"现在能看到什么",但不足以回答"自上次成功检查以来出现了什么"。
第二个问题需要历史信息。这段历史可以存在于Actor内部、数据库里、调用方提供的游标中,或者调用Actor的工作流里。这个实现选择了让Actor保持无状态,把比较状态的责任交给了调用Actor的工作流。
暴露缺失层的那个实验
作者最初通过Apify MCP服务器调用Actor,保留了四个单次调用条件。所有运行都成功,返回了同样的五个ID。在没有任何基线的新会话里,抓取照常工作,但比较这件事做不了。
这个结果很重要,因为"没有新记录"和"我无法判断是否有新记录"不是同一个答案。一个可靠的监控器必须保留这个区别。实验还暴露了一个身份陷阱:每条消息的浏览量字段在两次观察之间都变了,但消息本身并没有变——浏览量不是稳定的身份标识。
解决方案:在Actor外面加一个状态层
作者围绕Apify Actor加了一个状态层,包含六个关键设计:
- 每条记录的稳定身份标识
- 按Telegram频道分区存储状态
- 明确的首次运行策略
- 跨执行去重
- 轮询窗口可能过小时的警告
- 状态缺失或损坏时的fail-closed处理
这套设计同样适用于价格追踪器、职位监控、线索流、库存检查,以及任何反复问"什么变了?"的工作流。作者特别说明:配套代码包中的工作流刻意停在通知候选这一步,没有把未经测试的投递当作完成。
抓取器回答"现在有什么",监控器回答"什么变了"。前者只需要一次快照,后者需要状态。这个状态层,就是两者之间那道看不见的墙。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.