🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
1. 先把目标说清楚:让 Roo Code 在 Go 仓库里自己跑测试
Roo Code 是一个跑在编辑器里的 Agent 插件,它能读文件、改代码、执行终端命令,并且把「改完 → 跑测试 → 看报错 → 再改」串成一个循环。这次要它做的事很具体:在一个 Go 仓库里,把散落在各个 handler 里的重复参数校验抽成 middleware,然后自己反复跑go test,直到全绿为止。
适合谁?手上有一个能编译、有测试的 Go 项目,handler 里到处是if id == "" { ... }、if page < 1 { ... }这类重复校验,想借 Agent 的手批量收敛,但又不想让它乱动业务逻辑的人。核心诉求是「限定改动范围」——只碰 middleware 和 router,别的地方一律不动。
我试过让 Agent 自由发挥,结果它顺手把 service 层的错误返回也改了,测试虽然过了,但 review 时全是噪音。所以这次的关键不是「让它写代码」,而是「给它画好边界,再让它自己验证」。
TaoToken 在这里的角色很单纯:提供模型调用的 Key 和 Base URL。你在 Roo Code 里配好它,选一个代码能力够用的模型,剩下的交给 Agent 循环。下面按「读仓库 → 定范围 → 改代码 → 跑测试」四步走,最后给一份可复制的自定义模式片段和完整的步数记录。
2. 仓库级操作步骤:从读 go.mod 到全量测试
2.1 第一步:让它先读 go.mod 和目录树
不要一上来就让它改代码。先让 Agent 建立对仓库的认知,否则它不知道 module 名、Go 版本、依赖了哪些框架(比如 gin、echo、chi),改出来的 import 大概率是错的。
在 Roo Code 的对话里输入:
先不要改任何文件。请完成以下只读任务: 1. 读取 go.mod,告诉我 module 名、Go 版本、主要 Web 框架依赖; 2. 输出仓库目录树(忽略 vendor、.git、testdata); 3. 找出所有 handler 文件,列出每个文件里重复出现的参数校验模式(例如 id 为空、分页越界、body 解析失败); 4. 找出 router 注册文件的位置。 只输出结论,不要写代码。这一步的产物是一份「仓库地图」。你会看到类似这样的结论:module 是example.com/order-api,用的是 gin,handler 在internal/handler/,router 在internal/router/router.go,重复校验集中在id非空、page/size范围、json bind失败三类。
如果它读错了框架,后面 middleware 的写法就会跑偏。所以这一步必须人工确认一眼。
2.2 第二步:限定只改 middleware 与 router
认知建立后,明确划定改动边界。这一步是整个任务成败的关键,边界越清晰,Agent 越不容易越界。
接下来只允许修改两个位置: - 新建或修改 internal/middleware/ 下的文件; - 修改 internal/router/router.go 的注册逻辑。 禁止修改: - internal/handler/ 下的任何文件(除了删除已抽走的校验代码); - internal/service/、internal/repository/; - go.mod、go.sum。 任务:把 id 非空、分页范围、json bind 失败这三类校验抽成 gin middleware。 每个 middleware 要能独立测试。先给出你的改动计划,我确认后再动手。让它先给计划再动手,是防止它一次性改十几个文件、你根本 review 不过来。计划里应该包含:新建哪几个文件、每个 middleware 的函数签名、router 里怎么挂载、handler 里删掉哪些行。
2.3 第三步:改代码并写 middleware 测试
确认计划后,让它执行。这里给一个 middleware 的参考形态,方便你判断它写得对不对:
// internal/middleware/validate.go package middleware import ( "net/http" "strconv" "github.com/gin-gonic/gin" ) // RequireID 校验路径参数 id 非空且为合法正整数 func RequireID() gin.HandlerFunc { return func(c *gin.Context) { id := c.Param("id") if id == "" { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "id is required"}) return } if _, err := strconv.ParseUint(id, 10, 64); err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "id must be a positive integer"}) return } c.Next() } } // RequirePaging 校验分页参数范围 func RequirePaging() gin.HandlerFunc { return func(c *gin.Context) { page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("size", "20")) if page < 1 || size < 1 || size > 100 { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "invalid paging"}) return } c.Next() } }router 里挂载:
// internal/router/router.go r := gin.Default() api := r.Group("/api") api.Use(middleware.RequirePaging()) { api.GET("/orders/:id", middleware.RequireID(), handler.GetOrder) api.DELETE("/orders/:id", middleware.RequireID(), handler.DeleteOrder) }同时要求它给每个 middleware 写单元测试,放在internal/middleware/validate_test.go,用httptest构造请求,断言状态码。
2.4 第四步:跑全量测试直到通过
这是 Agent 循环真正发挥作用的地方。给它明确的测试命令和通过标准:
现在执行测试循环: 1. 先跑 go test ./internal/middleware/... -v,确保新 middleware 测试通过; 2. 再跑 go test ./... 全量测试; 3. 如果有失败,读报错、定位、修复,然后重新跑; 4. 重复直到 go test ./... 全部通过,或连续 3 次修复无效后停下来向我汇报。 每次跑测试都要贴出命令和结果摘要。实测下来,它通常会在 handler 里残留的旧校验和新 middleware 产生冲突时卡住一次——比如 handler 里还在做id校验,导致重复返回 400。这时它会自己删掉 handler 里的旧代码,再跑一遍。
3. TaoToken 接入与配置:Key 与模型切换
3.1 创建 Key 并填入 Roo Code
TaoToken 的 Key 在控制台创建,地址是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end,进去后找 API Keys 页面新建一个。拿到 Key 后,在 Roo Code 的模型配置里这样填:
- Provider 选 OpenAI Compatible;
- Base URL 填
https://taotoken.net/api; - API Key 填刚创建的那串;
- Model 先填
kimi-k2.7-code。
Base URL 不要带任何路径后缀,Roo Code 会自己拼/v1/chat/completions。填错成带/v1的地址,常见结果是 404,而不是 401,这点排障时要注意。
3.2 先用 Kimi K2.7 Code,卡住再换 Qwen3.7 Plus
Kimi K2.7 Code 在 Go 这种强类型、需要读多文件上下文的场景里表现稳定,尤其是它能比较好地遵守「只改这两个目录」的约束。大部分重构任务用它就能跑完。
如果遇到它连续两三次修复都失败——比如 middleware 的测试一直过不了,或者它开始反复改同一个文件——就在 Roo Code 里把模型切成qwen3.7-plus,保持同一个会话继续。同一会话意味着它还记得之前的仓库地图、改动计划和失败记录,不用从头解释。切换模型不需要换 Key,Base URL 也不变,只改 Model 字段。
3.3 自定义模式片段
Roo Code 支持自定义模式,把角色、约束、工具权限写进去,省得每次重复交代。下面这份可以直接粘进自定义模式的配置里:
name: Go Refactor Agent roleDefinition: > 你是一个 Go 仓库重构助手。你的职责是在严格限定的文件范围内, 把重复的参数校验抽成 middleware,并通过反复运行 go test 验证改动。 你不修改业务逻辑,不新增依赖,不碰 go.mod。 whenToUse: > 当需要在 Go 仓库中抽取 middleware、收敛重复校验, 且希望 Agent 自己跑测试直到通过时使用。 customInstructions: > 工作流程固定为四步: 1. 只读阶段:读 go.mod、输出目录树、定位 handler 与 router,不改文件; 2. 计划阶段:给出改动计划,等待确认; 3. 执行阶段:只允许改 internal/middleware/ 与 internal/router/router.go; 4. 验证阶段:先跑 middleware 测试,再跑 go test ./...,失败则修复重跑, 连续 3 次无效则停止汇报。 每次执行终端命令都要贴出命令与结果摘要。 禁止修改 handler 的业务逻辑,只允许删除已抽走的校验代码。 groups: - read - edit - commandgroups里给了command权限,它才能跑go test。如果你不放心,可以先只给read和edit,测试命令自己手动跑,把结果贴回对话里。
4. 可验证结果与失败分支
4.1 改了哪些文件
一次典型跑完,改动落在这些文件上:
| 文件 | 改动类型 | 说明 |
|---|---|---|
internal/middleware/validate.go | 新建 | RequireID、RequirePaging、BindJSON 三个 middleware |
internal/middleware/validate_test.go | 新建 | 每个 middleware 的表驱动测试 |
internal/router/router.go | 修改 | 在 group 上挂载 middleware |
internal/handler/order.go | 修改 | 删除重复的 id、分页校验代码 |
internal/handler/user.go | 修改 | 同上 |
handler 的改动应该只有删除,没有新增逻辑。如果 diff 里出现 handler 新增了函数或改了返回结构,说明它越界了,需要回退。
4.2 跑了几次 go test
完整步数记录大致是这样:
go test ./internal/middleware/... -v→ 失败,RequirePaging测试里 size 边界断言写反;- 修复断言 → 再跑 → 通过;
go test ./...→ 失败,order_test.go里期望 400 但拿到 200,因为 handler 旧校验删了、middleware 没挂到该路由;- 在 router 里给
/orders/:id补挂RequireID()→ 再跑 → 仍有 1 个失败; - 定位到
user.go的删除路由漏挂 → 补上 →go test ./...全部通过。
一共 5 次测试调用,其中 3 次失败、2 次通过。这个数字会随仓库复杂度浮动,但「先单包、再全量」的顺序能让你快速定位问题出在 middleware 本身还是挂载遗漏。
4.3 失败分支怎么处理
常见失败有三类。第一类是 middleware 测试本身写错,比如断言状态码写反,这种让它自己读报错就能修。第二类是路由漏挂,表现为全量测试里某些接口返回 200 而非 400,需要它对照 handler 列表逐个检查挂载。第三类是它想改 handler 的业务逻辑来「绕过」失败,这时候要明确拒绝,让它回到 middleware 或 router 层面解决。
如果连续 3 次修复都无效,按自定义模式里的约定,它会停下来汇报。这时切到 Qwen3.7 Plus 继续同一会话,把失败摘要再贴一次,通常能换个思路突破。
5. 限制、成本与模型选择
Roo Code 的 Agent 循环会消耗较多 token,因为它每轮都要把仓库上下文、测试输出、diff 一起送进模型。仓库越大、测试报错越长,单轮成本越高。控制办法是限定读取范围,别让它cat整个仓库,只读相关目录。
模型选择上,Kimi K2.7 Code 适合大多数 Go 重构,指令遵循稳;Qwen3.7 Plus 作为卡住时的备选,换思路有效。具体可用模型、计费方式和额度,以 https://taotoken.net/api 对应的控制台页面为准,官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 上有接入文档和模型列表。
一个实用技巧:在让它跑全量测试前,先手动确认go build ./...能过。编译都过不了的仓库,Agent 会在语法错误上浪费大量轮次,先把编译修绿再交给它做重构,效率高很多。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度