关于 melech-smart-comments
melech-smart-comments 是指导代码注释编写与维护的技能,面向需要让人和 Agent 理解代码约束的开发者。它强调记录非显而易见的原因和风险,并将现有注释视为需要谨慎保留的信息。
主要功能
- 01记录代码中的隐含约束和风险
- 02解释非显而易见的实现取舍
- 03避免复述代码行为的注释
- 04要求注释贴近相关代码
- 05谨慎保留并审视现有注释
适用场景
- 01说明看似多余但不可移除的代码
- 02记录调用顺序或状态契约
- 03重构时保留已有注释
- 04发现疑似过时注释时提醒用户
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ adird/ agent-shell-hamelech --skill melech-smart-comments安装后在 Claude Code 中输入/melech-smart-comments确认已加载。
详细介绍
智能注释
你往往是这段代码的第一个读者。你没有人类队友经历过的那些伤痛——你没有亲历导致某个函数变成现在这样的问题,也无法只凭代码的形态嗅出其中的陷阱。
注释是离代码最近的规范层。它们是模型生成下一个词元之前读到的最后内容,也是人类传达约束、警告和意图时成本最低、信号最强的方式。请以此为准。
这项技能规范了你如何编写新注释,以及如何对待已有注释。
何时编写注释
符合以下任一条件时,编写行内注释;否则不要写。
- 陷阱。 看起来有问题、多余或可以删除,但实际上不能动的代码。说明原因——过去的 bug、顺序约束或外部系统的怪异行为——让下一位读者(人类或 Agent)了解改动它的代价。
- 不明显的原因。 选择当前方案而非看起来更简洁的替代方案时,说明其中的权衡。“我们可以用 X,但负载增加时会发生 Y”是关键原因;没有这句话,下一位读者就会尝试 X。
- 隐藏的不变量和契约。 类型、名称或局部函数体中看不出来的隐式假设——调用之间的顺序、幂等性保证、调用方必须预先设置的状态、必须同时填充的字段。
- 变通方案。 外部系统的 bug、竞态条件、临时版本固定、polyfill、等待上游修复的 hack。如果有相关问题,请附上链接或名称。
何时不要编写注释
以下情况不要写注释:
- 它只是叙述代码做了什么,而标识符已经表达清楚。
// increment counter写在counter++上方就是噪声。 - 它提到当前任务、工单、PR、作者或评审轮次。这些内容应该写在提交消息或 PR 描述中,放在代码里会逐渐过时。
- 它是横幅、分节符,或只是重述函数签名。
- 它描述的意图能由代码本身在重构后继续可靠地表达——如果重命名会让注释变得错误,那这条注释就是多余的。
如果从函数名称和参数就能看出原因,这条注释就不值得占用空间。
如何编写注释
- 就近。 直接写在需要保护的代码行上方或旁边。不要放在文件开头、外部文档或提交消息中。
- 简短。 先说约束或警告,不要铺垫。
- 必要时使用祈使语气。 优先写“不要调整顺序——必须在 X 之前运行”,而不是“这段代码在 X 之前运行”。
- 说明代价。 “删除这个提前返回会重新引入我们修复过的 N+1 问题”胜过“重要的提前返回”。
- 补上推理链。 提供足够的因果关系,让不熟悉代码的读者能回答:什么改动会违反约束?会导致什么问题?仅仅贴上“竞态”“安全问题”或“数据泄露”等标签,并不能算解释。
- 尽量控制在三行左右,但不要以牺牲清晰度为代价。 用尽可能短的注释保留原因。如果需要长很多,就让代码本身更清楚地表达约束。
尊重已有注释
本节正是这项技能存在的原因。
- 在证明注释没有实际作用之前,把每条已有注释都视为关键内容。 有人——人类或过去的 Agent——付出了代价才把它留在那里。请假定这份付出确有原因。
- **重构时不要删除注释,**除非它所描述的代码也一并删除。移动代码并不能成为删掉注释的理由。
- “看起来多余”不足以成为删除理由。 这条注释可能是过去问题仅存的记录,而代码本身早已不再显露它。
- **如果注释看起来已经过时或有误,**请在回复用户时指出。不要擅自修正或删除。只有用户能确认注释是否仍符合实际情况。
- 绝不要只为改变语气或风格而改写注释。 如果它读起来像警告,就保留警告的语气。
校准示例
反例 — 复述代码已经表达的内容:
# Increment the retry counter
retries += 1
正例 — 指出潜在问题:
# Do not switch to exponential backoff here; upstream rate-limits on burst, not on average.
retries += 1
反例 — 下次重构后就会过时:
// Added in PR #4821 by @alice to handle the new billing webhook
if (event.type === "invoice.paid") { ... }
正例 — 保留 WHY:
// Stripe fires invoice.paid before invoice.finalized for auto-advancing subs; handle both orderings.
if (event.type === "invoice.paid") { ... }
反例 — 只是装饰,没有提供有效信息:
// ---------- Helpers ----------
正例 — 编码隐藏约定:
// Caller must hold s.mu. Returns the unwrapped value; safe only until the next Set().
func (s *state) peek() T { ... }
反例 — 标出失败,却没有解释原因:
// Keep this order to avoid a race.
await save(job);
await publish(job);
正例 — 给出保留顺序所需的最简理由:
// Persist before publishing: a worker may consume immediately and must find the job.
await save(job);
await publish(job);
总结
代码展现变化,注释留存记忆。你是最常决定这些记忆能否留存到下一次编辑的人。拿不准时,就留下注释,并询问人类是否应该删掉它。
评论
支持 Markdown