Go 语言技能:AI 时代的 Go 开发工具链

目录 [−]

  1. 24.1 为什么 Go 需要专属技能
  2. 24.2 五个 Skill 一览
  3. 24.3 /modern-go:让老代码跟上新版本
    1. 24.3.1 35 条版本门控的转换规则
    2. 24.3.2 安全保护:读 go.mod,绝不越级
    3. 24.3.3 实演:一段老代码怎么被现代化
  4. 24.4 chao-go-perf:把 Dave Cheney 的工作坊装进 Skill
    1. 24.4.1 黄金法则:先测量,再优化
    2. 24.4.2 三套分析框架:CPU / 内存 / 并发
    3. 24.4.3 覆盖面与参考资料
    4. 24.4.4 实演:先看 benchmark,再谈优化
  5. 24.5 chao-go-sync:并发是 Go 的灵魂,也是最容易翻车的地方
    1. 24.5.1 覆盖面:从 stdlib 到 etcd
    2. 24.5.2 Bug 诊断框架:五个必查项
    3. 24.5.3 实演:两个静默 Bug,诊断框架一眼揪出
    4. 24.5.4 性能优化与版本迁移
  6. 24.6 go-style-guide:一份固执己见的 Go 工程契约
    1. 24.6.1 十条 TL;DR
    2. 24.6.2 执行协议:六步,先看仓库再动手
  7. 24.7 cc-skills-golang:拿数据说话的全家桶
    1. 24.7.1 28+ 原子 Skill,交叉引用
    2. 24.7.2 用数据说话:Skill 到底有没有用
    3. 24.7.3 token 预算:把渐进式信息披露做成了账
  8. 24.8 五个 Skill 怎么配合
  9. 24.9 与全书方法论的对接
  10. 24.10 本章小结

"Clear is better than clever."
清晰胜于聪明。
—— Rob Pike, Go Proverbs

第 23 章把重构讲完了。嗅坏味道、套 Fowler 手法、小步施工、每步测试,这套东西对 Java、Python、Go 一视同仁。但真到 Go 上手你会发现,Fowler 的目录够不着 Go 的好几层脾气。一段能跑的 Go 代码,可能还停在 Go 1.10 的写法,不地道;可能并发原语用错了,race detector 一开就红,不安全;也可能分配没控住,cache line 在 false sharing,不快。这些坏味道扫不出来,是 Go 二十年攒下来、只有老手才摸得到的门道。

门道都散在各处。Dave Cheney 的高性能工作坊讲一套,dgryski 的 go-perfbook 讲一套,《Go 并发编程实战》讲一套,Go 团队的 modernize 分析又讲一套,再加上无数生产事故换来的风格约定。以前你得一本书一本书读、一个 pprof 一个 pprof 啃。现在有人把这些蒸成一个 Skill,Agent 调一下就能用。

本章介绍五个 Go 专属的 Skill,正好覆盖 Go 工程的四个面:现代化(/modern-go)、性能(chao-go-perf)、并发(chao-go-sync)、风格(go-style-guide),外加一个把这几样打包、还顺带做了效果评估的全家桶(cc-skills-golang)。前三个是本书作者 smallnest 写的,对,写这本书的人和写这些 Skill 的人是同一个;后两个分别来自 madflojo(Benjamin Cane)和 samber。

24.1 为什么 Go 需要专属技能

第 1 章立过本书的旗:从 Prompt-Driven 到 Skill-Driven。Prompt 临时,Skill 持久;Skill 等于可复用的方法论加结构化的知识加标准化的输入输出。这话对什么语言都成立,但 Go 尤其该说一遍,因为它有三样东西让通用 Agent 特别容易翻车。

一是 Go 的地道写法绑版本。同一件事,Go 1.10 和 Go 1.22 的标准答案不一样。循环找切片里有没有某个元素,1.10 要手写 for 循环,1.21 一行 slices.Contains 搞定;求最小值,1.20 要 if-else,1.21 有内置 min。Agent 训练数据里两种写法都有,随手给你写哪种全看运气。代码是能跑,可能是个十年前的化石。

二是 Go 的并发坑深,而且静默。一个 map 并发读写不会马上崩,要等压力上来、等到生产环境的某个深夜才 panic。一个 sync.Mutex 被复制了,go vet 查得出,Agent 不会主动跑。goroutine 泄漏更无声无息,程序能跑,内存曲线却悄悄爬坡。这些坑 Fowler 的坏味道目录里一个都没有。

三是 Go 的性能是测出来的,不是猜出来的。Dave Cheney 那句「You can't optimize what you don't measure」是 Go 性能圈的宪法。可 Agent 的默认行为恰恰是猜,看一眼代码凭直觉说「这里用 sync.Pool 优化一下」,既没 benchmark 也没 pprof。猜对的概率比你想的低。

三样合起来指向一个结论:Go 的资深经验得编码进 Skill,才能被 Agent 可靠复用。这不算锦上添花,是这门语言逼出来的刚需。下面五个 Skill,就是这件事的五个侧面。

24.2 五个 Skill 一览

先给一张全景图,免得后面绕晕。

Skill 作者 定位 覆盖面 Stars(2026/06)
/modern-go smallnest Go 代码现代化 35 条 gofix 风格规则,Go 1.0→1.26+ goal-workflow 套件内
chao-go-perf smallnest Go 性能分析专家 CPU/内存/GC/编译器/缓存/并发,含 PGO ~40
chao-go-sync smallnest Go 并发编程专家 全部 sync 原语 + 13+ 模式 + 分布式 ~37
go-style-guide madflojo (Benjamin Cane) 固执己见的 Go 工程契约 包设计/接口/错误/日志/布局/测试 ~35
cc-skills-golang samber 生产级 Go Skills 全家桶 28+ 原子 Skill,跨工具,带评估 ~2300

五个 Skill 的分工可以这样理解:/modern-go 管「代码是不是用了新版本的写法」,go-style-guide 管「代码符不符合工程契约」,chao-go-sync 管「并发安不安全」,chao-go-perf 管「跑得快不快」,cc-skills-golang 把这四件事各做一份,外加交叉引用和效果评估。前四个是专精一件的单点 Skill,最后一个是面面俱到的体系。

顺带说一句 cc-skills-golang 的体量,两千多 stars,是本章里唯一算得上「大项目」的。它的特别之处不在多,在于拿数据证明了 Skill 真的有用。这个留到 24.7 节细讲。

下面逐一展开。

24.3 /modern-go:让老代码跟上新版本

/modern-go 在第 8 章作为 Goal Workflow 的 Bonus Skill 露过一面,第 23 章也提过它和 /refactor/smell 一样是「保持代码库健康」的邻居。这里展开讲它的机制。(介绍页:https://goal.rpcx.io/index_cn.html#step-modern-go

我自己写它,是因为 goscapy 这种库要长期维护,go.mod 里的版本会一点点往前挪,可代码还停在五年前写它时的写法。靠人记得每条 time.Since 替换、记得 interface{} 该换成 any,不现实。go fix 官方工具又只覆盖一小部分。于是把 Go 团队 modernize 分析能找到的转换规则、加上社区常用的,凑成一份带版本门控的 Skill,让 Agent 替我盯着。它的定位很纯粹,像 go fix 一样,把老写法自动改成新版本的地道写法。装一行:

1
npx skills add smallnest/goal-workflow --skill modern-go

触发可以直接打 /modern-go,或说「现代化」「modernize」「gofix」。

24.3.1 35 条版本门控的转换规则

Skill 内置 35 条转换规则,每条带一个版本门控,只在项目的 Go 版本够格时才启用。规则从 Go 1.0 一路排到 1.26+,挑几个有代表性的:

Go 版本 老写法 新写法
1.0+ time.Now().Sub(start) time.Since(start)
1.13+ err == io.EOF errors.Is(err, io.EOF)
1.18+ interface{} any
1.18+ strings.Index + 手动切片 strings.Cut
1.19+ atomic.StoreInt32(&v, 1) var v atomic.Int32; v.Store(1)
1.20+ fmt.Errorf("...: %w: %w", e1, e2) errors.Join(...)
1.21+ 手写 for 循环找元素 slices.Contains
1.21+ if a<b {v=a} else {v=b} v = min(a, b)
1.21+ var once sync.Once; once.Do(...) sync.OnceFunc(...)
1.22+ for i := 0; i < n; i++ for i := range n

每条规则都配 before/after 代码对照,机械、可执行。这正是 Go 团队 modernize 分析能被 Agent 接住的地方。

24.3.2 安全保护:读 go.mod,绝不越级

真正关键的不是这 35 条规则,是它怎么决定该用哪条。流程很死板:

  1. 先读 go.mod 里的 go 指令,拿到项目声明的 Go 版本;
  2. 扫描目标范围内所有 .go 文件(排除 vendor/.git/testdata/);
  3. 对每个文件,只应用版本 ≤ 项目版本的规则,从老到新依次套;
  4. 最后打印一份改了什么、跳过了什么的汇总。

铁律只有一条,但很硬:绝不应用需要比项目声明版本更高的规则。项目还停在 Go 1.20,就不会给你塞 1.21 的 minslices,塞了编译不过。这条把「现代化」和「改坏」之间的边界钉死了。

这条保护和第 23 章 /refactor 的五阶段协议是同一种思路:把人最容易手滑的地方改成 Agent 必须遵守的护栏,这里是「图新」而越级升级。人升级 Go 时常犯的错,比如把目标版本改高了却忘了改 go.mod,或者用了新 API 却没加 import,/modern-go 用版本门控和 requires importing 的提示一条条堵上。

24.3.3 实演:一段老代码怎么被现代化

光看规则表没感觉,跑一段。假设 go.mod 写的是 go 1.21,项目里有这么个函数,写法停在 Go 1.13:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func parseHeader(buf []byte) (key, val string, ok bool) {
if i := bytes.Index(buf, []byte("=")); i >= 0 {
key = string(buf[:i])
val = string(buf[i+1:])
ok = true
}
return
}

var cache atomic.Value

func getConfig() *Config {
cache.Store(&Config{})
return cache.Load().(*Config)
}

/modern-go 进来先读 go.mod,拿到 1.21 这个版本上限,然后从老到新逐条套能用的规则。对上面这段,它会动三处:

  • bytes.Index 加手动切片 → 1.20+ 的 bytes.Cut(1.21 够格);
  • atomic.Value 加类型断言 → 1.19+ 的 atomic.Pointer[T]
  • 顺手把 import 补上。

出来是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func parseHeader(buf []byte) (key, val string, ok bool) {
before, after, found := bytes.Cut(buf, []byte("="))
if found {
key, val, ok = string(before), string(after), true
}
return
}

var cache atomic.Pointer[Config]

func getConfig() *Config {
cache.Store(&Config{})
return cache.Load()
}

注意它没碰 1.22 的 range-over-int,项目是 1.21,那条规则被门控挡掉了。这是版本门控真正干活的样子:该改的改,不该碰的一行不动。要是谁手贱把 go.mod 提到 1.22,再跑一遍,那个 for 循环才会被改成 for i := range n

24.4 chao-go-perf:把 Dave Cheney 的工作坊装进 Skill

/modern-go 解决「写法老不老」,chao-go-perf 解决「跑得快不快」。我写它,是因为 rpcx、goscapy 这种库对性能敏感,可每次让 Agent 帮忙优化,它张口就是「这里加个 sync.Pool」,没 benchmark、没 pprof,纯靠猜。猜错是常态。Go 性能圈其实有现成的规矩,Dave Cheney 和 dgryski 讲过很多遍,第一条都是「先测量」。这些规矩散在讲义和书里,Agent 不会自动遵守,那就把它们蒸成一个 Skill,逼它先拿数据再说话。它把 Go 性能圈几本「圣经」装进来:

  • Dave Cheney 的 High Performance Go Workshop(GopherCon 2019)
  • dgryski 的 go-perfbook(中文版)
  • Effective Go
  • Go 101 的 Optimizations 101
1
npx skills add smallnest/chao-go-perf

24.4.1 黄金法则:先测量,再优化

chao-go-perf 开篇就把 Dave Cheney 和 go-perfbook 的两句话钉在墙上:

"You can't optimize what you don't measure. Always benchmark before and after."
—— Dave Cheney

不要猜测性能瓶颈。用数据说话。先测量,再优化,最后验证。
—— go-perfbook

由此引出五条黄金法则:先测量再优化、Benchmark 驱动、了解编译器、内存是瓶颈、优化最热路径。这五条不是建议,是 Skill 的工作前提,和第 16 章 agent-skills 的验证门禁、第 23 章 /refactor 的安全协议同源:Agent 得先有证据(benchmark、pprof)才能动优化。这一条直接把 Agent 最爱的毛病禁了,看一眼代码就凭直觉「优化」。

24.4.2 三套分析框架:CPU / 内存 / 并发

Skill 给出三套可机械执行的分析框架,每套都是「命令 → 看什么 → 判断什么」:

维度 生成 profile 看什么 典型病因
CPU go test -bench -cpuprofile 火焰图最热函数 内联失败、不必要计算、算法复杂度
内存 go test -bench -memprofile + -gcflags="-m" alloc_space 热点、逃逸分析 slice 未预分配、[]byte↔string 转换、接口装箱
并发 go test -race + runtime/trace + mutex profile 锁等待、调度 锁粒度过大、false sharing、channel vs mutex 选错

这套框架把性能优化从「拍脑袋改代码」变成「先定位瓶颈在哪一层,再用对应工具验证」。AI 时代尤其用得上,Agent 吐的代码经常埋着 N+1 分配、循环内排序这类量小看不出、上了量才爆的坑,chao-go-perf 的内存框架一眼能扫出来。

24.4.3 覆盖面与参考资料

Skill 还配 8 份参考资料,按需加载:benchmarking、memory-optimization、cpu-optimization、cache-optimization、concurrency-perf、pgo、tooling、version-changes。其中两块是 Go 圈的硬骨头:PGO(Profile-Guided Optimization)的完整工作流,和 Go 1.12 到 1.27 的关键性能变更(哪个版本改了 GC、哪个版本改了调度器,升级时要留意什么)。CPU 缓存那块也讲得细,cache line 对齐、false sharing 检测、AoS 对 SoA 的数据局部性取舍,这些资深 Go 工程师才碰得到,Agent 默认不会主动想。

24.4.4 实演:先看 benchmark,再谈优化

按 Skill 的规矩,它不会直接给优化方案,第一句话是问数据。你喂给它一段有锁竞争的计数器:

1
2
3
4
5
6
7
8
9
10
type Counter struct {
mu sync.Mutex
n int
}

func (c *Counter) Inc() {
c.mu.Lock()
c.n++
c.mu.Unlock()
}

说「这个 Inc 在高并发下慢,优化一下」。chao-go-perf 不会立刻说「换 atomic」,它会先走 Step 1 的分类和 Step 2 的框架,让你先出证据:

1
2
3
4
5
6
问题分类:并发竞争(吞吐量不随 CPU 增加)
诊断步骤:
1. go test -bench=. -cpuprofile=cpu.out
2. go tool pprof -http=:8080 cpu.out → 看 mutex 热点
3. go test -race → 确认无数据竞争
4. 看锁竞争:临界区只有一个 n++,纯计数

证据到位(profile 显示锁等待占大头),它才进锁选择决策树。Skill 里那张决策图长这样:

1
2
3
4
5
6
是否只需要保护简单整数/布尔/指针?
└── Yes → atomic 操作
└── No → 读写比例?
├── 几乎全读 (> 90%) → sync.RWMutex
├── 读写均衡 → sync.Mutex
└── 偶尔写入一次 → sync.Once / sync.Map

n 是个整数,Inc 只做自增,正好走第一条分支,给方案:

1
2
3
4
5
6
7
type Counter struct {
n atomic.Int64
}

func (c *Counter) Inc() {
c.n.Add(1)
}

并附一串近似量级让你心里有数:atomic 约 1-2 ns/op,无竞争 Mutex 15-30 ns/op,channel 50-200 ns/op。最后还不忘补一句:优化前后的 benchmark 都得跑,用 benchstat 验证。这套流程才是 Skill 想要的样子,先量、再分类、最后给方案,每一步都有数据兜着,而不是上来就 sync.Pool。

24.5 chao-go-sync:并发是 Go 的灵魂,也是最容易翻车的地方

Go 的并发是它的招牌,也是它最容易出事的地方。chao-go-sync 基于《Go 并发编程实战》一书,把 Go 并发的全套知识,从标准库原语到分布式同步,装进一个 Skill。这本书是我写的,写它的时候把踩过的坑、用过的第三方库、做过的分布式同步方案整理了一遍。写完发现,这些内容正好是 Agent 写并发代码最缺的那块。它知道 sync.Mutex 怎么用,但不知道哪里会复制、哪里会重入死锁、什么时候该上分片锁。于是把书的内容蒸成 Skill,让 Agent 调一下就能拿到一整本书的判断力。

1
npx skills add smallnest/chao-go-sync

24.5.1 覆盖面:从 stdlib 到 etcd

chao-go-sync 的覆盖面是五个 Skill 里最广的,横跨四个层次:

层次 内容
标准库原语 Mutex、RWMutex、WaitGroup、Cond、Once、Pool、sync.Map、atomic、channel、context、synctest
官方扩展 信号量、SingleFlight、ErrGroup、限流器
第三方库 CyclicBarrier、断路器(sony/gobreaker)、Worker Pool(panjf2000/ants)、sourcegraph/conc、各类限流库
分布式同步 基于 etcd 的 Leader 选举、分布式锁、分布式队列/屏障、STM

外加 13+ 种并发模式(半异步半同步、Reactor、Proactor、Per-CPU、活动对象……)和四个经典问题(哲学家就餐四种解法、理发师问题、水工厂、Fizz Buzz)。这个体量,基本上是把一本并发书搬进了 Skill。

24.5.2 Bug 诊断框架:五个必查项

并发 Bug 最难的是定位。Skill 给了一套诊断框架,收到并发问题先过这五条:

  • 有没有数据竞争?(-race 输出)
  • 锁的获取/释放顺序对不对?(防死锁)
  • 有没有锁重入?(Go 的 Mutex 不可重入,这是 Java 转 Go 最常踩的坑)
  • 有没有复制 sync 原语?(go vet 能查,Agent 不会主动跑)
  • WaitGroup 计数匹不匹配?goroutine 有没有泄漏?(Go 1.26+ 运行时自动检测)

这五条本身就是一份并发代码审查清单。go-style-guide 里也有一份并发 reference,但深度不在一个量级,go-style-guide 讲怎么用对,chao-go-sync 讲出了问题怎么查、怎么治、还有哪些更高级的替代。

24.5.3 实演:两个静默 Bug,诊断框架一眼揪出

并发 Bug 最阴的地方在于不崩。喂给它两段看着没毛病的代码,让它审。

第一段,忘记 Unlock。多分支 return,有一条路径漏了 Unlock,程序不会立刻死,锁会泄漏,到某个时刻所有 goroutine 卡住:

1
2
3
4
5
6
7
8
9
func (f *Foo) Bar() {
f.mu.Lock()
if f.count < 1000 {
f.count += 3
return // 漏了 Unlock
}
f.count++
f.mu.Unlock()
}

第二段,锁重入死锁。从 Java 转来的人最容易写,Go 的 Mutex 不可重入,Bar 里再 Lock 直接死锁:

1
2
3
4
5
6
7
8
9
func (t *T) Foo() {
t.mu.Lock()
defer t.mu.Unlock()
t.Bar() // Bar 内部又 Lock
}
func (t *T) Bar() {
t.mu.Lock() // 死锁
defer t.mu.Unlock()
}

chao-go-sync 的诊断框架对这两段走的路径不一样。第一段它先问「锁的获取/释放配不配对」,发现 Lock 后有分支提前 return 却没 defer Unlock,直接指出该用 defer 兜底;第二段它走的是「有没有锁重入」那条,点明 Go Mutex 不可重入,给的解法是重构,别让 Foo 持着锁调 Bar,要么把 Bar 拆成不加锁的内部方法 barLocked,由 Foo 在持锁状态下调。两个 Bug 都不是 race detector 能报的(race detector 只管数据竞争),靠的是 Skill 里那份「五必查」清单的经验。这就是它比通用 Agent 多出来的一层:知道去哪几个固定位置找问题。

24.5.4 性能优化与版本迁移

诊断之外,chao-go-sync 还给了一份锁选择决策:什么场景该用 RWMutex 替代 Mutex,什么场景该上分片锁、sync.Map、atomic,什么场景干脆 lock-free。它也覆盖 Go 1.20 到 1.27 的 sync 包变更,比如 sync.OnceValue/OnceFunc(1.21)、运行时 goroutine 泄漏检测(1.26)这些新东西,旧代码该不该迁移、怎么迁移。这跟 /modern-go 互补,/modern-go 管通用 API 的现代化,chao-go-sync 专管并发原语。

24.6 go-style-guide:一份固执己见的 Go 工程契约

前三个 Skill 偏「术」,现代化、性能、并发都是具体技术。go-style-guide 偏「道」,管的是 Go 代码的工程契约:包怎么设计、接口怎么定、错误怎么传、日志怎么打。作者是 madflojo(Benjamin Cane)。

1
npx skills add -g -y madflojo/go-style-agent-skill

它最显眼的标签是 README 里那句 "Opinionated by design",刻意固执己见。它明确说,这不是通用、官方的 Go 风格指南,是个人偏好,要的是真实代码库里的一致性、可维护性和生产可用性。紧接着一句很关键:「如果你仓库已经有自己的约定,那些约定通常优先。」这一句把固执己见和尊重本地两边都顾上了,Skill 给默认值,但不覆盖既有规矩。

24.6.1 十条 TL;DR

Skill 用十条 TL;DR 浓缩了整套契约,挑几条最硬的。测试优先设计,先注入依赖、保持逻辑纯,再谈别的。Config 进、具体 struct 出,构造器吃 Config,显式校验和默认值。错误是契约,用 sentinel error 做持久分支判断,其余的用 %werrors.Join 包裹。包要可复用,不藏全局变量、不藏默认日志、不搞意外副作用。标准库优先,第三方包必须靠「有意义、维护良好、被广泛采用」挣一席之地。accept interfaces, return structs,接口通常由消费者定义。覆盖率是信号不是证明,测边界和误用路径,别只测 happy path。声称性能提升前先 benchmark 热路径,并发代码跑 -race

这些条款和 chao-go-perf 的「先测量再优化」、chao-go-sync 的并发安全说的是一回事,只是 go-style-guide 站在工程视角把它们串起来。

24.6.2 执行协议:六步,先看仓库再动手

go-style-guide 不只是规则清单,它还有一份六步执行协议,规定 Skill 干活时的顺序:

  1. 先看仓库:读现有包布局、构造器、测试、错误约定,再提新 API;
  2. 先定契约:包边界、Config 形状、返回类型、sentinel error、依赖缝隙、context/关停预期,写代码前先定;
  3. 尽早写测试:表格驱动单测起步,输入密集的加 fuzz,性能敏感的加 benchmark;
  4. 最小可维护改动:沿用仓库既有布局,main.go 保持薄,没明确边界别引入新抽象;
  5. 跑收尾检查:gofmt/goimports、相关 go test、并发跑 -race、声称性能就跑 benchmark;
  6. 验证面向人的契约:函数签名、Config 形状、错误行为、文档注释,和代码一样重要。

这六步和第 16 章 agent-skills 的 Define→Plan→Build→Verify→Review→Simplify→Ship 是一个谱系,都是把资深工程师不会跳过的步骤固化成 Agent 必走的流程。配 10 份 reference(CONFIG、INTERFACES、ERRORS、LOGGING、DOCUMENTATION、LAYOUT、BENCHMARKS、TESTING、CONCURRENCY、REVIEW-CHECKLIST)按需加载,也就是第 2 章讲的渐进式信息披露。

24.7 cc-skills-golang:拿数据说话的全家桶

前四个 Skill 各管一面,cc-skills-golang 是把它们全做了一份、还做了交叉引用和效果评估的体系。作者 samber(samber/lo 的作者,Go 圈老熟人),两千多 stars,是本章体量最大的项目。

它的态度写在 README 最显眼的地方:

Bootstrapped with Claude Code by distilling my Go project commits. Edited, tested, reviewed and reworked by a human.
No AI slop here. AI-made skills are useless.

先用 Claude Code 把自己 Go 项目的提交蒸馏成 Skill 草稿,再由人编辑、测试、审查、返工。最后那句「No AI slop here. AI-made skills are useless.」是整个项目的主张:AI 生成的 Skill 没人把关就是废纸,人审过的才是 Skill。这跟本书第 2 章 Matt Pocock 的「real engineering, not vibe coding」、第 12 章的 maker-checker 分离是一个调子。

24.7.1 28+ 原子 Skill,交叉引用

cc-skills-golang 把 Go 工程拆成 28+ 个原子、可交叉引用的 Skill,分四大类加一批框架/库 Skill:

大类 代表 Skill
代码质量 code-style、naming、error-handling、safety、security、structs-interfaces、documentation、lint
架构与设计 concurrency、context、data-structures、database、dependency-injection、design-patterns、modernize
QA 与性能 testing、benchmark、performance、observability、troubleshooting
项目搭建 cli、continuous-integration、project-layout、popular-libraries、stay-updated、dependency-management
框架/库 grpc、graphql、google-wire、uber-dig/fx、spf13-cobra/viper、samber-lo/mo/ro/do/hot/slog/oops、testify

注意里面的 modernizeperformanceconcurrencycode-style,和前四个 Skill 的职责正面重叠。samber 的处理方式是让 Skill 之间互相引用。比如错误处理影响日志的规则,就放在 error-handling 里,由 observability 引用,不各写一份。README 特意提醒,只装一部分会得到片面、可能不一致的视图,最好整套一起装。这套「原子 Skill 加交叉引用」的做法,和第 2 章的「小而可组合」、第 16 章的「24 个 Skill 覆盖完整生命周期」思路一样,只是规模更大。

24.7.2 用数据说话:Skill 到底有没有用

cc-skills-golang 有一点别的前四个 Skill 都没有:它给 Skill 跑了评估,拿出了量化效果。

samber 给每个 Skill 跑了一套评估(evals),对比「装了 Skill」和「没装 Skill」时 Agent 的通过率,并算出「错误率下降幅度」(Error rate gap)。先看总账:

装了 Skill 没装 Skill 差距
总体 3315/3395(98%) 1915/3395(56%) +41 个百分点

装了 Skill,Agent 通过率从 56% 跳到 98%。本书前面一直在主张 Skill 有用,到这里才头一回有硬数。再看单项,挑几个降幅最猛的:

Skill 错误率下降
golang-modernize -61%
golang-continuous-integration -59%
golang-safety -58%
golang-dependency-management -54%
golang-documentation -53%
golang-benchmark -50%

modernize 降 61%,safety 降 58%,正好对应本章 /modern-go(现代化)和并发安全这两个最容易出错的领域,说明这些地方最需要 Skill 兜底。框架/库类里 golang-samber-do(依赖注入)最夸张,降 81%。这些数字替本书从第 1 章念到现在的「Skill 是 AI 软件工程的基石」补上了证据。

24.7.3 token 预算:把渐进式信息披露做成了账

cc-skills-golang 还把第 2 章的渐进式信息披露做成了明账。每个 Skill 都标三档 token 权重:description(frontmatter 里的描述,常驻上下文,用于触发)、SKILL.md(触发后才加载的全文)、Directory(SKILL.md 加所有 reference)。比如 golang-code-style 是 115 / 2069 / 2685 token,golang-security 是 84 / 3036 / 21472 token。也就是说 security 这个 Skill 平时只占 84 token 趴在上下文里等触发,真用上了才把两万多 token 的全量知识加载进来。这比把所有规则一股脑塞进系统提示省得多。

24.8 五个 Skill 怎么配合

五个 Skill 有重叠,怎么选?给一张决策表:

你要解决的问题 首选 Skill 备选
老代码升级到新 Go 写法 /modern-go cc-skills-golang 的 golang-modernize
代码慢、要优化 chao-go-perf cc-skills-golang 的 golang-performance/benchmark
并发 Bug 或并发设计 chao-go-sync cc-skills-golang 的 golang-concurrency
包设计、接口、错误契约 go-style-guide cc-skills-golang 的 golang-code-style
想要一站式、且要效果有数据 cc-skills-golang(整套) ——

一个务实的组合:日常拿 cc-skills-golang 当底座(覆盖全、有评估、交叉引用),遇到性能和并发这两个深水区,再挂上 chao-go-perfchao-go-sync,这两个的深度 samber 的全家桶比不了,一个搬了 Dave Cheney 工作坊,一个搬了整本并发书。/modern-go 嵌在 Goal Workflow 里,做提交前的现代化体检。go-style-guide 适合团队对齐工程契约时当起点。

重叠不可怕。cc-skills-golanggolang-modernize/modern-go 规则高度相似,但 /modern-go 多了「读 go.mod、版本门控」这层保护;golang-performancechao-go-perf 都讲 pprof,但后者多了一整本 go-perfbook 的方法论。重叠的地方正好见高下,比较着选就行。

24.9 与全书方法论的对接

  • 第 2 章 Skills:这五个 Skill 是「原子 Skill」在 Go 领域的展开。cc-skills-golang 的 28+ 原子 Skill 加交叉引用,是「小而可组合」的体系级样本;go-style-guide 的 10 份 reference 按需加载,是渐进式信息披露的典型实现。
  • 第 8 章 Goal Workflow:/modern-go 是 Goal Workflow 套件的 Bonus Skill,和 /refactor/smell 同属代码库健康维护工具链。
  • 第 16 章 agent-skills:chao-go-perf 的「先测量再优化」、go-style-guide 的六步执行协议,都是 agent-skills 验证门禁和反合理化表的同类,把 Agent 最爱跳过的步骤(不 benchmark 就优化、不看仓库就动手)钉成必须走的流程。
  • 第 20 章 Anthropic 官方插件:官方插件注入领域知识和工程工作流,这五个 Go Skill 是社区版的 Go 领域知识插件,把 Go 二十年的门道封装成任何 Agent Skills 兼容工具都能用的能力。
  • 第 23 章 重构:/modern-go/refactor/smell 是邻居,/smell 扫病灶,/refactor 套 Fowler 手法治,/modern-go 管版本现代化,三者一起维护代码库健康。

24.10 本章小结

Go 这门语言表面小,门道深。地道写法绑版本,并发坑静默,性能靠测量,通用 Agent 写出的 Go 经常是能跑但不地道、不安全、不快。本章五个 Skill 把 Go 二十年的资深经验编码成 Agent 能可靠复用的能力:/modern-go 管现代化(35 条版本门控规则),chao-go-perf 管性能(先测量再优化),chao-go-sync 管并发(从 stdlib 到 etcd),go-style-guide 管工程契约(固执己见但尊重本地),cc-skills-golang 把这几样各做一份还顺带做了评估。cc-skills-golang 那张「装了 Skill 98%、没装 56%」的评估表,是本书到现在最硬的一块证据,给「Skill 是 AI 软件工程的基石」这句话补了数。

第 22 章读懂代码,第 23 章改好代码,这一章用 Go 专属技能把 Go 代码写地道、写安全、写快。但这些 Skill 解决的都还是「写」和「改」,代码写完了,谁来证明它真的对?下一章的 autoreview 和 Crabbox 接的就是这一棒,一个做自动化代码审查,一个在远程沙箱里真跑一遍验证。