即日起博客关闭基于 Disqus 的评论系统,改用简单的表情投票反馈。如果有文字反馈,可以继续使用下面基于 utteranc.es 的留言框(需要 github 账号),也欢迎直接发送电子邮件留言。

关闭 Disqus 的主要原因是它现在开始显示广告了,因为我一直使用广告屏蔽工具,所以也不太清楚自己博客上是什么时候开始有显示广告的,直到最近它给我推送付费账号的信息我才意识到。仔细思考和权衡了一下各种解决方案,最终还是决定放弃使用 Disqus。

最直接的底线是我不能接受自己的博客上会显示广告。最直接的解决方案当然是使用 Disqus 付费账号,不过每月 $20 的会员费感觉不合理,毕竟现在不论是我发博客的频率还是大家留言的频率都很低。随着互联网环境的变化和我自己生活习惯的变迁,我现在对自己博客的定位是一个长期稳定、功能精简、低维护成本的平台。原本就是自己写的一个简易静态 HTML 生成的博客平台,技术栈是基于 Ruby 写的,现在我其实已经快要不会写 Ruby 了,但好在 Ruby 的向后兼容似乎做得还不错,后来把博客的 PDF 编译等一些复杂的功能去掉之后其实在很大程度上已经满足了我低维护成本的需求。

唯一麻烦的地方在于留言系统,因为它是需要动态存储的。考虑长期维护成本的话,其实主要有两个互相冲突的方面:经济成本和人力成本。优先降低经济成本的话,最简单的办法就是自己 host 一个开源的评论系统,主要问题在于需要维护数据库、平台升级、安全补丁等人力成本;或者甚至自己做一个简易的留言系统,但其实稍微想一下就会发现这个东西并不能简化到哪里去,比如 CAPTCHA 和垃圾过滤、评论和回复的邮件通知、甚至在墙内外的访问问题等,都不是可以一劳永逸地很好的解决的。所以其实 Disqus 开始推行广告 or 收费的策略也是可以理解的,虽然不是 rocket science,但是考虑运营和维护成本等各种方面,从长远来讲 Disqus 也不可能永远提供免费的服务。如果优先降低人力成本,直接购买付费服务最省事,但按照我目前对这个服务的需求频率来说,又是不合理的经济成本。

其实从长远来讲根本原因还是互联网大环境的变化,早些年个人博客还是互联网上比较活跃的内容平台的时候,Disqus 这样系统的用户量本身也足够,当然我不太清楚这些平台到底是怎样的商业模式,也许是通过对用户行为进行数据挖掘,又或者在开放互联网活跃时代有足够的用户量这件事情本身就足够作为至少短期的商业模式。但随着个人博客用户(包括博主和读者两方面)的消退,这些原本提供免费服务的系统也不得重新思考“如何买单”的问题。

事实上从早期的各大运营商运营的博客平台系统的逐渐消亡到基于静态 HTML 的个人博客平台的兴起,其实已经是整个开放互联网变迁的进行时了。到现在基本上只剩下一些搭建、运营和维护都极其简单的个人博客(包括很多仅支持纯文字的系统)还因为一些人的个人兴趣而存在着。而这个趋势下动态评论系统的问题也变得越来越困难。这里的趋势不仅仅是博主和读者用户群体的减少,还在于互联网内容本身在过去这么多年的极度商业化的过程中也在不断变化:软文、广告、诈骗等充斥其中,从维护评论系统的角度来看,实际上绝大部分时间是在和 spam 做斗争,只有一小部分时间是在为真正的内容服务。所以从各方面来说维护一个评论系统的性价比都非常低下,导致现在很多个人博客直接不提供评论功能。

到今天我也终于决定关闭这里的 Disqus 服务,略微有一点伤感,毕竟偶尔看到读者留言,特别是看到有人因为我的记录而有一点点收获或者受到一点点启发的时候,我自然是很开心的。虽然从整个互联网的发展来看这已经是发展了很多年的老趋势了,但从我自身角度来说,这大概算是开放互联网的黄金时代的落幕了。不过另一方面,同样虽然在“外界” vibe coding 已经如火如荼了,对我自身体验来讲,这次 Disqus 系统迁移这件事也才是真正 AI coding 新时代的开幕。

虽然并不是第一次用 AI coding,但应该是第一次不以“玩一玩”的心态来尝试这个新模式。以下记录一下自己这次 Disqus 系统迁移的经过,在未来回顾起来也许会挺好玩。

我需要解决两个问题:1. 将过去已有的 Disqus 评论转化为静态 HTML 直接“烧录”到已有的博客页面中;2. 我希望制作一个简单的“表情投票”系统作为一个易于维护的折衷方案。我使用的工具是 Claude Code (Opus 4.6)。我的使用方式其实是比较“hands on”的,基本上是我自己先做过一些简单的构思和调查,差不多确定技术上的可行性和大致方案,到这个时候其实我自己差不多已经知道该如何做了,当然由于需要去 get up-to-date 许多网页开发相关的知识,以及对数据分析进行调试和迭代,我自己搞肯定会很花时间。在这样的背景下我交给 Agent 的任务其实是比较具体和明确的。

烧录已有评论的问题:我从 Disqus 后台导出了评论数据,给了 Agent 该数据和 Disqus 的简短文档,以及我的博客系统的代码和 Disqus 评论动态渲染出来之后的一个页面的截图示例。Agent 通过阅读代码结构找到了适合 liquid 的嵌入 HTML 评论的方式,并找我 clarify 了评论数据应该使用什么作为 url_key 来进行匹配的问题之后,就开始工作了。过了一阵我回去瞄了一眼发现 Agent 在疯狂 debug 各种 Ruby 错误……于是我跟他说这是个一次性的工作,不需要把代码集成到已有的博客系统代码中,如果你觉得 Python 更顺手可以用 Python。Agent 感激涕零,立刻换成了 Python,并很快就有了第一版的结果。

当然初版结果并不正确,我自己进入 loop 去做了一些检查和验证,找到一些关于 liquid 模板的问题,例如文件名和后缀名格式不符合系统要求导致渲染失败。如果追求极致的“自主性”,让 Agent 自己去做端对端验证,他大概最终也能找到这些问题。还有评论回复在渲染出来缩进上有“越缩越多”的 bug,如果让 Agent 去开浏览器验证的话,大概也能意识到问题的所在。但是从尽快解决问题的角度出发,现阶段的 Agent 似乎还是由我提供一些直接反馈会让整个流程更顺畅一些。整个过程从头到尾只花了数小时(当然后期我又花了不少时间手工对照了数据的完整性)。

然后是第二阶段的问题:也是我自己先做了一些技术调研,最后决定使用 Firebase 提供的免费 tier 做一个简易表情投票系统,忽略墙和 Spam 的问题。这样架构代码都在客户端,所以其实攻击者能轻松绕过可能有的验证,在对抗 spam 上是天生弱势,但只是增加(或减少)表情投票数量,应该没有 spamer 有动机去做这样的事情,即便被 spam 了也没有太大危害。

在确定了解决方案之后,我就让 Claude Code 开干了。这个任务是 clean start,也没有什么奇怪要求,很快就完成了。我简单 sample 了一下代码之后,觉得 Agent 的设计有些问题,spammer 虽然没法在我的页面上显示 spam 内容,但还是可以生成很多垃圾内容把我的 Firebase 数据库塞满。于是我让它做了一个 mitigation。结果实现这个 mitigation 导致引入了另一个行为逻辑上的错误。我去找 Agent 询问这是 feature 还是 bug,Agent 立刻承认了错误并做出了修改。后来又迭代了几轮,我其实也没有很认真看代码,但有一些地方明显代码注释和实际代码不一致的地方,不过指出之后 Agent 也很快改正了。

整个过程体验总体来说是非常好的,一个主要原因是我是抱着解决问题的心态,所以一方面我并没有追求极致的“自主性”,让 Agent 能 end-to-end 解决所有问题,所以过程中需要你来我往也并不是什么问题;另一方面我也没有追求极致的“控制性”,让我自己能完全掌代码的方方面面:这对于自己的“学习”、“实践”等方面来说会更有趣味性,但对于“解决问题”则更加视情况而定。我觉得这样的应用场景对于今天的 Agent 来说几乎是一个 sweet spot:你可以参与其中掌控大局,牺牲了对细节的掌控权,但很多时候那些细节你大概也并不在意,更重要的是由此换来的超快的 feedback loop 让你能迅速地在设计层面做更多的迭代和尝试,反而给你一种更 powerful 而不是 lose control 的感觉。

另外现阶段的 Coding Agent 其实很像一个 Junior Dev,拟人化一点讲,有自己擅长和不擅长的方面。而且还会会写出 bug、前后不一致的功能和设计等等,可以说 LLM 模型质量问题,但如果是一个真正的程序员,则更可能会归因为“懒惰”、“粗心”等,其实把 Agent 当作真正的 Junior Dev 去对待似乎会是一个很合适的类比。如果有跟 Junior Dev 合作过,Agent 给人的印象就是把“勤奋能干效率高”、“对很多细节和前沿领域很精通”、“在某些方面缺乏经验和大局观”等特性放大很多倍的感觉。在接受了 Agent 这样的特性之后再以适合自己的合作方式把合适的工作和内容交给 Agent 去做就比较能避免和期望不符的情况了。

当然这是“现阶段的 Agent”,再往后发展又会怎样呢?