评价一下这个项目 https://github.com/Erfan817/personal-bot-demo,有什么不足和改进的地方

回复 Erfan: 昨天那份讲了不少好的地方,这次只挑不足和该改的地方说。先说个总的判断:这个项目的文档完成度明显高于系统完成度,所以下面很多问题的共同点是「文档没交代」,而有几个是真缺。 一、能力表把框架的能力算成自己的了。「44 个内置 provider」是 pi-ai 带的 provider 集合,不是这个仓库实现的。现在它和「自己写的部分」混在同一张表里,读的人容易把框架给的当成项目能力——面试里被追问一句「这些 provider 适配是你写的吗」就露了。建议表里分两栏,或者每个能力标一个来源:框架给的、自己写的。 二、记忆层是纯 FTS5 trigram 字面检索,没有语义召回。同义改写、口语换词会漏,「长期记忆」是主打点的话这就是硬伤。而且文档没写「什么会被写进长期记忆」——是所有消息都落库再检索,还是有筛选和摘要。如果全落,检索质量会随量下降;如果筛,筛选规则才是真正该讲的设计。HISTORY_LIMIT=2 那个实测只证明了「它会去检索」,没证明「检索得准」,这两个结论差很远。 三、心跳自愈有单点。cron 每分钟检查心跳文件时效——但那个 cron 脚本自己挂了、或者服务连续重启都起不来,是没有兜底的,而这两种情况恰恰是最需要告警的。补法很便宜:心跳超时就往飞书推一条告警,再接一个外部探活(healthchecks.io 这类免费的就够),让「检查者」也在被检查范围内。 四、全仓没有测试,验证靠 node --check 加人工跑。对 demo 不算问题,但这个仓库的踩坑章节已经攒了七八条「肉眼查不出来」的案例,正好是最该用测试固化的清单:FTS 表 rowid 和主表 id 的对应、去重表的幂等语义、令牌桶的边界、长回复切分、还有自己写的 cron 解析器。 五、自己写 cron 解析器这件事风险被低估了。cron 表达式看着简单,但 */5 的语义、星期日到底是 0 还是 7、月末和闰年、时区和夏令时,都是经典坑。更关键的是没有 misfire 策略:服务器正好 8:00 重启,早报是补发还是跳过?文档没写。这条比解析器本身更影响体感。 六、消息的失败路径没交代。飞书要求 3 秒返回,所以异步;那异步之后这轮跑失败了,用户看到什么?按踩坑 ③ 的描述(「表现是回答是空的,而且不报错」),我怀疑现在的行为是静默。这是 24/7 主动推送的字面杀手——你以为它没接到,其实是它答错了。至少要给用户回一句失败提示,并把错误记进日志带上消息 id。 七、安全这块漏了 prompt injection。web_search 和 web_fetch 的返回会直接进上下文,一个被投毒的网页可以让 agent 照着页面上的字做事。工具白名单拦的是「能不能调某个工具」,拦不住「被内容指使」。另外这个是在 Azure 上跑的,web_fetch 如果不屏蔽内网地址段和云元数据端点(169.254.169.254 那种),就是一个现成的 SSRF。 八、备份脚本要确认一下.env 在不在备份范围里。配置里全是 API key,备份文件如果含密钥又落到别的地方,等于把密钥复制出去了。权限和加密至少得选一个。 九、多用户不只是「加个用户表」。当前是单用户信任模型,记忆库大概率是全局的,加第二个用户就是两人共享记忆、共享令牌桶、共享成本。真要放开,需要按用户隔离记忆、按用户配额、按用户白名单,这是三件事,不是一件事。 十、成本控制建议排在用量看板前面。待办里是「用量统计与成本看板」,但一个会自己定时推送的 bot,风险不是看不见花了多少,而是没人拦着它花。先加一个日额度硬上限,超了就停推并告警,比看板实在。 十一、可观测性只有 journald 裸日志。建议给每条消息一个 request id,在渠道、闸门、大脑、工具出口各打一行带 id 和耗时的结构化日志。现在这个架构要查「这条为什么慢/为什么没回」,基本靠猜。 十二、部署流程 scp 加 restart,没有回滚。推坏一次就是线上直接不可用。做法不用复杂:保留上一版目录加软链,一条命令切回去。 十三、用户体感:一轮要好几秒,中间界面上什么都没有。飞书那边先秒回一句「收到,正在处理」,比上流式输出便宜得多,收益也明显。 如果只挑两条先做,我选第六条和第七条——一个是可靠性的洞,一个是安全问题,其他都是打磨。