评论监控用定时任务就能落地
作者用定时脚本拉取新评论,每条调用一次模型进行摘要与负面标记,再通过Slack webhook发送提醒。该案例展示了需求明确的AI自动化如何用少量组件完成,无需引入复杂Agent框架。
AI 深度解读
客户说要一个全天候监控 Google 评论的自主 AI Agent,作者追问后发现,实际需求只有三步:每小时读取新评论、识别负面内容、通知创始人。他交付的是 cron、一次模型分类和 Slack webhook。
这篇文章的价值,是给 AI 自动化划了一条实用边界:流程已经确定时,让代码控制流程,让模型处理文本。但标题里的「90%」没有统计依据,示例距离可靠运行也还差几处工程补全。
每小时读评论,为什么用不着 Agent
作者交付的流程很固定:每小时拉取新评论,每条评论调用一次 LLM,要求模型判断 positive、neutral 或 negative,并给出一行摘要。只有 negative 会发送到 Slack,其余内容按作者描述会记录后忽略。
调度只需要这一行:
0 * * * * /usr/bin/node /home/app/review-watch.js
这里的 0 * * * * 表示每个整点执行一次,并不是持续监听。客户口中的「全天候监控」,落到实现上其实是每小时轮询。
作者认为,没有必要为这个流程引入规划循环、工具定义、向量数据库或记忆存储。输入、执行时间、输出都已确定,模型也不需要自行决定下一步。
流程确定时,模型可以只是一个处理文本的函数。
负面评论是否发送,虽然也有条件分支,但这个分支由固定规则控制,不需要模型临场规划。
一个文件能讲清流程,但不代表已经可靠
下面的 Node.js 示例展示了模型分类和 Slack 通知如何串起来:
// review-watch.js: read new reviews, flag the bad ones, ping Slack
import OpenAI from "openai";
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
async function main() {
const since = new Date(Date.now() - 60 * 60 * 1000).toISOString();
const reviews = await fetchNewReviews(since); // your reviews API here
for (const review of reviews) {
const verdict = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "system",
content: "Classify this review as positive, neutral or negative. Reply with one word, then a one line summary.",
},
{ role: "user", content: review.text },
],
});
const [label, summary] = verdict.choices[0].message.content.split("\n");
if (label.trim().toLowerCase() === "negative") {
await postToSlack(`Negative review from ${review.author}: ${summary}`);
}
}
}
async function postToSlack(text) {
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ text }),
});
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
要重点看 since 和 split("\n") 两行:前者决定会不会漏读评论,后者决定模型输出能不能被正确解析。
作者说系统读取「上次运行以来」的评论,代码却只是用 60 * 60 * 1000 回看最近一小时。如果任务停过一轮,恢复后可能漏掉更早的评论。fetchNewReviews 也只是占位函数,Google 评论的获取、鉴权和分页没有展开。
模型使用 gpt-4o-mini,通过 openai.chat.completions.create 调用。解析逻辑默认第一行是标签、第二行是摘要,但提示词并没有严格约束换行格式,也没有解析失败的兜底。
Slack 部分同样需要补全:代码发送了 POST,却没有检查 HTTP 响应状态。接口返回错误时,通知未必成功,脚本也未必因此报错。另外,正文说非负面评论会被记录,示例没有实现这部分。
这些缺口需要普通工程措施解决,并不构成引入 Agent 的理由。
我的判断
我赞同作者先拆需求、再选架构的顺序。固定调度、固定输入输出、单一分类或摘要任务,用脚本通常更容易检查,也更容易控制模型调用次数。
作者给出的 Agent 适用条件也有参考价值:系统需要根据内容选择工具,后续路径依赖中间结果,需要跨步骤保留任务状态,或者输入复杂到一个固定提示词难以处理。此时,自主决策才可能带来收益。
不过,有分支、有状态也不必然需要 Agent。规则能提前写清的情况,普通工作流同样可以处理。
「90%」和「几乎不花钱」都只能当作作者的经验描述。
原文没有给出需求样本数、评论量、token 用量、实际账单,也没有与 Agent 方案做对照测试。作者报告系统运行良好、客户满意,但这些反馈不足以证明所有类似场景都应采用相同方案。脚本更短,也不会自动获得重试、去重和可观测性。
能拿来做什么
- 接到 AI 自动化需求时,先写清触发条件、输入、模型职责和输出。如果四项都能提前确定,可以先做固定流程的最小实现。
- 用 Node.js 做评论巡检时,保存成功处理的位置,按评论 ID 去重,并补上失败重试和通知状态检查,避免只依赖最近一小时的时间窗口。
- 把模型输出当作外部输入处理,为标签和摘要定义可校验的格式;遇到异常输出时记录并兜底,不让一次格式偏差中断整批评论。
- 评估 Agent 方案时,要求指出哪一步必须由模型选择工具或决定路径,并比较调用次数、失败率和维护成本,让复杂度有具体收益支撑。