用 AI 复活停更开源项目是一个务实的选择——以 Knife4j Next 为例
关于 AI 写代码的讨论很多,我不太吃两种调调:一种把 AI 当演示道具,另一种把能力吹到天上、顺便贩卖焦虑。
我更在意一个朴素问题:在真实工程里,它能不能稳定帮上忙。能写代码只是起点;场景要真实,结果要可验证,做错了要发现得了、回得去。离开这些,再漂亮的生成结果也只是 demo。
过去一段时间,我在 Knife4j Next 上试的就是这类场景:让 AI 参与维护一个已经停更、但仍有人在用的开源项目,而不是从零造一个新产品。
为什么先盯上“停更但仍有人用”的项目
Knife4j 是很多 Java 团队用过的 API 文档工具,入口常常是熟悉的 /doc.html。官网在 doc.xiaominfo.com/knife4j。维护节奏慢下来之后,用户需求并不会一起消失:页面要能开,调试不能莫名其妙挂掉,发布说明和实际产物还要对得上。
Knife4j Next 是它的社区维护 fork。我对这类项目的定位一直很克制:稳住现有体验,修回归和兼容,发布可重复,前端增量演进。目标是把项目继续养着,不是重写一个「更现代」的产品。
它适合拿来练 AI 协作,主要是因为足够务实:
- 有真实用户和明确 issue
- 日常工作大多是 bugfix、兼容补丁、文档和发布流程
- 结果能用测试、构建、截图、日志或 CI 核对
- 改错了通常回得去,损失可控
反过来,方向天天变的新产品、核心金融/权限链路、几乎没有验证手段、或者 issue 全是「感觉不好用」「能不能做成某某那样」的项目,我会谨慎得多。AI 当然可以帮忙调研、对比方案、写局部实现,但不适合在这些地方「自治推进」。
先选项目,再谈 AI。低风险、需求清楚、容易验证,比模型本身更决定成败。
不要一上来就让 AI “接管仓库”
刚开始用 Coding Agent 时,很容易冲动:issue 丢过去,让它自己读代码、自己改、自己交。
偶尔能成,但不稳。
真实项目里有大量隐性规则:哪些模块能改,哪些只做兼容维护;什么叫做完,什么只是本地看着过了;什么时候开 PR、什么时候等 CI;哪些事可以自己推,哪些必须先问人。这些如果只活在维护者脑子里,AI 只能猜。
我后来做的第一件事是把规则写进仓库,而不是继续抠 prompt。Knife4j Next 里大致有这些文件:
| 文件 | 干什么 |
|---|---|
AGENTS.md |
总规则:读什么、硬约束、默认工作方式 |
.agent/PROJECT.md |
目标、非目标、模块边界(比如 OAS3 主线 / OAS2 只兼容) |
.agent/AUTONOMY_POLICY.md |
什么能直接做,什么必须问人 |
.agent/PLAYBOOK.md |
维护者在场时的完整工作循环 |
.agent/RUNBOOK.md |
不同改动跑什么验证;bug 必须先复现 |
.agent/COORDINATION.md |
什么时候才值得拆 worker / reviewer |
.agent/KNOWN_PITFALLS.md |
踩过的坑和反例 |
我不太喜欢把它们叫「给 AI 的操作系统」——听起来太玄。它们更像是把本来该写进 onboarding 的东西写清楚了。人来了要看,AI 来了也要看。规则在仓库里,就不依赖某段聊天记录,也不靠我每次口头提醒「别扩大范围」「先跑这个脚本」「结论写回 issue」。
AI 协作最容易出事的,往往是边界不清楚:写出一堆看起来合理、事后很难收拾的改动。代码写不出来,反而还好处理。
状态放在 Issue 里,不要放在聊天里
另一个很快暴露的问题:聊天窗口当不了任务系统。
今天这个会话还记得「继续处理这个 issue」;明天换会话、换工具、换模型,上下文就没了。分支开了没有、PR 卡在 CI 还是卡在 review、某个问题是暂时不做还是确认不存在——这些如果只散落在对话里,迟早乱。
所以任务状态我放到了 GitHub Issues + Labels:
agent-task:适合交给 agent 处理status:ready:已细化,可以开干status:in-progress:进行中status:review:本地验证、审查、PR CI 都过了,等人 mergestatus:blocked:卡在信息、环境或决策上area:*:模块分区
进度写在 issue / PR,不另建一套影子看板。
默认流转很短:ready → in-progress → 分支上做最小改动 → 跑对应验证 → 开 PR 等 CI → 审查通过后进 review → merge 后关 issue。
这里有个容易被吹过头的点:这套东西不是为了「无人值守 24 小时自动修仓库」准备的。我现在的默认假设是维护者在场。Issue 状态的价值,首先是让人和 AI 在同一套事实上对齐,而不是让模型在暗处自己排队干活。
默认路径:一个人 + 一个 agent 端到端
多 Agent 很能吸引眼球,但我越来越不把它当默认解。
早期我也研究过 coordinator / worker / reviewer。名字听起来像组织架构,实际用途其实很窄:
- worker:实现或探索会把主会话上下文撑爆时,拆出去做窄范围工作
- reviewer:高风险 diff,又希望另一份独立上下文先扫一遍时再用
- 维护者人工 review:完全可以当合法的第二意见,不必为了「角色齐全」硬开 reviewer agent
仓库里现在写得很直白:维护者在场时,单 agent 端到端就够用。Bug 类任务就是:复现并贴证据 → 实现 → ./tools/test-* → 开 PR → 等 CI。只有上下文真的要爆,或者需要独立第二意见时,才按 .agent/COORDINATION.md 拆。
我也见过一种很热闹的反面:把 agent 包装成「虚拟公司」,产品经理、架构师、开发、测试轮流传文档。演示好看,工程上常常不稳——角色是演出来的,信息却在交接里被压缩,最后每个节点都「合理」,整体已经偏了。这块我另有一篇整理:《三省六部幻觉》。
所以 Knife4j Next 里的多 Agent,不是编制,是可选工具。平时别为了像个团队而拆团队。
什么样的任务适合丢给 AI
项目选对了,也不是所有事都该自治推进。
我现在判断任务适不适合,不太问「难不难」,更问「能不能客观验收」。适合的通常长这样:
- 明确 bug:能复现,能补回归
- 前端显示问题:构建或截图能对上
- 文档和代码不一致:改完能核对
- CI / 发布脚本:失败条件变成明确报错
- 小范围清理、补测、把手动检查脚本化
不适合直接丢出去的也很清楚:要不要转型、功能该怎么设计才「最好」、顺便现代化架构、把历史模块重写掉、笼统地「优化体验」。AI 可以先调研和对比,但这类开放题必须先有人把边界收窄,再让它改仓库。
后来我给自己定了个门槛:交给 AI 推进的任务,至少要有目标模块、预期行为变化、验证命令和完成条件。 缺一项,先补 issue,别急着写代码。
Bug 先复现,别先“防御性”补丁
维护停更项目时,issue 经常来自上游或老用户反馈。标题一句报错、截图一段堆栈,看起来方向很明显;真实原因可能藏在评论、版本组合、配置或调用链里。
仓库里现在有一条很硬的规则:bug / 回归先复现,再写修复。 复现不到,就不要写「看起来更稳」的 if、try-catch 或 fallback——没有测试约束时,这类补丁经常只是把真错误吞掉。证据要写进 issue;复现失败就 blocked 或说明原因后关闭,而不是假装修了。
正确顺序很无聊,但管用:
- 读完正文、堆栈和评论
- 在未打补丁的基线上复现,留下可核对证据
- 能复现再修;修后同一证据变绿或现象消失
- 复现不到,把尝试过的条件写回去
AI 默认倾向是「给一个方案」。维护项目时,先证明你和 issue 说的是同一件事更重要。KNOWN_PITFALLS 里也记过反例:有的 upstream 问题在本 fork 已经不存在,未复现就补丁,只会制造噪音。
发布也别靠人脑记账
小型开源项目里,发布经常比写代码还磨人。
tag 推了算不算完?CI 绿了算不算?Maven 包能下了算不算?GitHub Release 和文档站 release note 对得上吗?这些如果只靠记忆,迟早漏。
所以发布也被写成可核对条件:tag、workflow、公开构件、GitHub Release、release note 与文档站对应小节。缺 GitHub Release,就不能报「发布完成」。
思路比某个具体脚本更重要:完成条件写进仓库,别只活在某个人脑子里。 这样 AI 才能帮你检查和汇报,而不是甩一句「应该发好了」。
一个真实小例子:全局参数 loading 转圈
原则说完了,看一个具体 issue。
issue #379 反馈:在 doc.html 右上角设置里添加全局参数时,按钮 loading 不消失,控制台报 TypeError: crypto.randomUUID is not a function。标签是 agent-task、area:ui-react,边界很清楚——React UI 的兼容 bug,不是产品重设计。
实际处理并没有演成「coordinator 派工、worker 实现、reviewer 背书」的三人戏。维护者确认复现后,交互式 agent 直接做了窄范围修复:
- 定位到添加参数时直接调用了
crypto.randomUUID() - 抽了
createClientId():优先randomUUID,没有就用getRandomValues,再不行才本地临时 ID - 补了三种环境下的单测
- 跑项目认可的前端验证,开 PR #382 合并
这个修复本身不炫。它说明的是一条更无聊、也更可靠的链路:真实用户问题 → 模块边界清楚 → 先复现 → 小改动 → 补测试 → 用仓库规定的命令验收 → 结论回到 issue / PR。
质量往往卡在有没有把这条链路走完,而不是一次生成了多少行代码。
落到仓库里的,其实是一套很土的东西
折腾下来,我觉得 AI 维护开源项目真正缺的,是一堆很土的工程安排,而不是什么神奇 prompt:
- 项目边界写清楚
- 任务状态只有 Issue / PR 这一处真相
- 一个分支只做一件可独立验证的事
- 不同类型改动有对应验证入口(
./tools/test-java.sh、test-front-core.sh、test-vue3.sh等) - bug 先复现
- 高风险才要第二意见;维护者人工审也算
- 发布完成条件可脚本核对
- 重要结论写回 issue、PR 或仓库文档,不留在聊天里
没有这些时,AI 越积极,越容易把伤害扩大;有了这些,它才像一个可控的协作者,而不是会写代码的不确定因素。
结语
很多人讨论 AI 写代码,爱问它能不能从零做出完整产品。
我反而觉得,开源维护里有个更现实的切口:停更了、需求还在、风险不高、验证路径清楚的小型项目。它们往往不缺愿景,缺的是持续处理 issue、补测试、修文档、打 release、收尾 PR 的耐心。AI 在这里能帮上忙的,是把这些具体、可验证、可回滚的活往前推,而不是替你宣布产品方向。
如果只留一句实践建议,我会说:
别急着让 AI 接管项目。先把任务、边界、验证和发布条件写进仓库;维护时人在场,默认一个 agent 做完一件小事。
流程站得住,AI 才有机会长期参与维护,而不是偶尔蹦出一段代码的玩具。





