先说个我前两天遇到的事。手贱用 curl 打了一下 Dev.to 的 API,按文档写的好好的:
curl -H "Accept: application/vnd.forem.api-v1+json" \
https://dev.to/api/articles?per_page=1
不带头会怎样?返回的是 V0 响应。不是报错,没有 warning,就是安安静静地给你一份格式完全不同的老版本 JSON。你对着文档对半天,以为是自己解析写错了,其实是它在装死。就这么个破事,坑过多少人我不知道,反正 DevPub 的作者是被坑过的那一个。
这工具是我上周刷到的,作者叫 Sarvar Nadaf,8 月 1 号的稿子。一句话介绍:一个在终端里管理 Dev.to 文章的命令行工具。听起来平平无奇对吧。但你猜他为什么写这个?他测了九个现成的 Dev.to CLI 工具,然后发现这些工具基本只干两件事——发布文章和拉文章列表。API 文档里躺着 40 多个端点,九个人里最勤奋的那个覆盖了 12 个,剩下的普遍在 3 到 5 个之间晃悠。这还不是最离谱的。最离谱的是他顺手发现了 Dev.to 的语义搜索居然是拿 Gemini 嵌入做的,768 维向量存在 pgvector 里,用余弦相似度打分,相似度阈值 0.3。文档里没写过这个,他是从接口行为里反推出来的。
我第一反应不是"卧槽好厉害",是"这哥们是不是闲得慌"。
然后我看了下他文章里贴的对比表,就不觉得他闲了。DevPub 支持七个分析端点、语义搜索、趋势发现、文章发布前校验、30 秒 30 次请求的滑动窗口限流、指数退避重试,还有个叫 Concepts API 的东西,是 ML 生成的话题分类,带每天的阅读量、反应数、评论数、热度分。其他九个工具,这一列全是"不支持"。相当于别人都在用勺子挖井,他直接上了台挖掘机,还把操作手册给画出来了。
但我真正想说的是另一件事。
这个项目最打动我的地方不是功能多,是他从下午两点开始写,写到晚上,核心功能就能用了。一个白天,从零到能用的 CLI。你跟我说这是 AI 辅助写的我觉得有可能,但你跟我说这是他"效率高",我不信。效率高是果,因是他太清楚自己要什么了。
你看他踩的那些坑就有数了。Dev.to 的 analytic 接口返回的是嵌套对象,{"page_views": {"total": 246454}},不是整数,是一层对象。之前那九个工具的作者要是真调过这接口,不会连这都适配不好。还有那个 API 版本头,文档第几页写了?没写。他不踩这个坑,怎么会知道要加这个 header?说明他是真的打开编辑器一把屎一把尿地把 API 翻了个底朝天,翻到把 V0 和 V1 的响应差异都摸出来了。
这让我想起我自己那挂半死不活的小工具。我在 GitHub 上也有百来星的仓库,但说实话大多数写到"能跑"就停了。为什么停?因为"能跑"和"好用"之间隔着的不是工作量,是需求清单。我写脚本的时候其实脑子里已经迭代了七版了,只是没落到 README 里。DevPub 这哥们不是运气好,他是把别人用来刷推特的功夫拿去看 API 响应体了。
说回语义搜索这事。他文章里贴的细节是:Dev.to 的语义搜索用的 Gemini embeddings,存 pgvector,算 cosine similarity。这个不是公开文档里的内容,他是怎么发现的?我猜多半是调接口的时候发现结果排序不对,或者响应里带了什么不该带的字段,一路顺藤摸瓜摸出来的。这说明什么?说明 Dev.to 这帮人闷声做了个挺有意思的系统,但没当回事拿出来宣传。也可能压根没打算宣传,是 DevPub 作者自己把文档外的墙角给刨开了。这种发现不会写在 changelog 里,也不会出现在 API reference 的页面里,它就活在流量日志和数据库 schema 里。
画外音:我是不是跑题了。这文章题目应该叫"我被一个命令行工具的作者教育了",不是"Dev.to 的隐藏架构解析"。收一收。
我想说的其实是这个:我们平时给工具打分只有一个维度——功能够不够我用。但 DevPub 这种项目的价值不在功能表,在它证明了另一件事:Dev.to 的 API 能做的事比所有人以为的多得多。四十多个端点,九个人只用了十分之一,不是因为他们懒,是因为他们照着文档的目录挑菜,菜单上没有的菜他们就当这家馆子不会做。而这哥们是直接钻进后厨翻冰箱的那个人。
我看到他还在 Issues 里挂了 good first issue,招贡献者。挺好的,这种项目就该有人帮忙测。但我总觉得这项目大概率火不起来——不是因为不好用,是因为它太好了,好到只有被九个破烂工具气过的人才懂它好在哪。就像你在二手市场淘了把趁手的锤子,你只会跟朋友说"这把好使",你不会写篇万字长文分析它的人体工学曲线。
不过话说回来,如果一个工具能让使用者产生"妈的,原来之前我都在用勺子挖井"的想法,那这工具的作者至少做对了一件事:他真的在用这个东西,而不是在"做一个 CLI 工具"。差别在哪?前者每个功能都是从自己的痛里长出来的,后者每个功能都是从别人的 README 上抄来的。
我就说一个细节。他做语义搜索之前,先做了滑动窗口限流,30 秒 30 次请求。这个不是用户会主动要求的功能,这是他自己在开发过程中被 429 打多了打出来的条件反射。这比一百个花哨功能更能说明问题——他知道自己在干嘛。
这两天我把这个工具装上了,pip install devpub,设了 DEVPUB_API_KEY,拿自己的文章试了试趋势发现和语义搜索。说实话,搜索质量一般,跟我预想的差不多,embedding 相似的东西不一定是内容相关的,那个 0.3 的相似度阈值也没拦住一堆莫名其妙的结果。作者自己在评论里也承认了,这个搜索不做事实正确性校验。但你看,这恰恰是我喜欢这个项目的原因——它有一个作者,他知道自己的工具哪里行哪里不行,他不吹。他管这个叫 beta,他挂 good first issue,他在评论里坦白语义搜索的局限。这些都是正常做软件的人该有的样子,但在这年头居然已经算稀缺了。
我这篇文章没打算推荐你换掉现在的工具,也没打算让你去给这个项目点 star。我真正想说的是:下次你用一个工具觉得憋屈,与其等着别人做一个更好的,不如自己上手把烂摊子掀了。别怕浪费时间——你花两小时看 API 文档,也许就能省下后面两年的骂娘时间。
凡事先试一下,翻车了再说。
别问,问就是不试试怎么知道。