🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度
1. 这次要解决什么:把重复的 HTTP 错误处理收进 middleware
Go 仓库写久了,http.HandlerFunc里最容易长出来的就是重复代码:每个 handler 开头都要判断方法、解析 JSON、写Content-Type、出错时http.Error一遍、成功时再json.NewEncoder(w).Encode一遍。一个仓库里十几个接口,这套逻辑就复制十几遍,改一次错误格式要动十几个文件。
这次的目标很具体:用 Claude Code 作为 Agent,在一个 Go 仓库里把重复的 HTTP 错误处理抽成 middleware,然后跑go test ./...确认没改坏。模型走 Kimi K2.7 Code,供应商走 TaoToken。适合已经写过 Go HTTP 服务、想让 Agent 帮忙做机械重构、但又不想让它乱改业务逻辑的人。
产物是一份可复现的流程:Claude Code 的环境变量配置、重构前后的 diff 摘要、go test命令和失败示例。不虚构分数,不编评测数据,只讲我实际跑下来的步骤和踩过的坑。
2. 准备仓库与测试基线
先确认仓库能编译、测试能过,否则重构后失败你分不清是谁的锅。
cd your-go-repo go version go build ./... go test ./...如果go test ./...本来就红,先记下哪些包失败,重构后对比。我试过在一个测试本来就飘的仓库上直接让 Agent 改,结果它把失败归因到自己的改动上,来回折腾了好几轮。
假设仓库结构是这样:
. ├── go.mod ├── main.go └── internal └── handler ├── user.go └── order.gouser.go里典型的长这样:
func GetUser(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { http.Error(w, "method not allowed", http.StatusMethodNotAllowed) return } id := r.URL.Query().Get("id") if id == "" { http.Error(w, "missing id", http.StatusBadRequest) return } u, err := store.FindUser(id) if err != nil { http.Error(w, "internal error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(u) }order.go里几乎是同一套,只是把FindUser换成FindOrder。这就是要抽的目标。
3. 给 Claude Code 配好 TaoToken 供应商
这一步是让 Claude Code 能稳定跑起来的关键。Claude Code 默认走 Anthropic 官方端点,我们要把它指到 TaoToken,模型选 Kimi K2.7 Code。
先从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 创建 Key。登录后在控制台生成一个 API Key,复制出来。
然后配置环境变量。Claude Code 读的是ANTHROPIC_BASE_URL和ANTHROPIC_AUTH_TOKEN这两个变量:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="sk-你的Key" export ANTHROPIC_MODEL="kimi-k2.7-code"如果你不想每次开终端都 export,写进~/.zshrc或~/.bashrc。Windows 下用系统环境变量面板,或者 PowerShell:
$env:ANTHROPIC_BASE_URL="https://taotoken.net/api" $env:ANTHROPIC_AUTH_TOKEN="sk-你的Key" $env:ANTHROPIC_MODEL="kimi-k2.7-code"配完验证一下能不能通:
claude --version claude -p "回复 ok"如果返回正常文本,说明供应商和模型都接上了。如果报 401,检查 Key 有没有复制全、有没有多余空格;如果报 404,检查 Base URL 是不是写成了带路径的地址,正确写法就是https://taotoken.net/api,不要在后面加/v1之类。
注意:Key 不要提交进 git。用
.env的话记得加进.gitignore。
模型名以官网当前支持的为准,Kimi K2.7 Code 的准确标识符建议在 https://taotoken.net/?utm_source=taotoken_aicg_blog_end 的模型列表里核对一遍,不同时期命名可能微调。
4. 让 Agent 做重构:提示词与 diff 摘要
进入仓库目录,启动 Claude Code:
cd your-go-repo claude给它一个边界清晰的提示词,别只说「帮我重构一下」。我用的版本:
在 internal/handler 下,把重复的 HTTP 错误处理抽成一个 middleware。 要求: 1. 新建 internal/handler/middleware.go,提供 ErrorHandler 包装函数。 2. 统一错误响应格式为 {"error": "..."},状态码由调用方传入。 3. 保留每个 handler 的业务逻辑,只改错误返回方式。 4. 不要动 store 层和 main.go 的路由注册。 5. 改完跑 go build ./... 和 go test ./...Agent 会先读文件、再改。它给出的 diff 摘要大致是这样:
+ // internal/handler/middleware.go + package handler + + import ( + "encoding/json" + "net/http" + ) + + type AppError struct { + Code int + Message string + } + + func (e *AppError) Error() string { return e.Message } + + func WriteError(w http.ResponseWriter, err error) { + var appErr *AppError + if errors.As(err, &appErr) { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(appErr.Code) + json.NewEncoder(w).Encode(map[string]string{"error": appErr.Message}) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusInternalServerError) + json.NewEncoder(w).Encode(map[string]string{"error": "internal error"}) + }handler 里的改动:
func GetUser(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodGet { - http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + WriteError(w, &AppError{Code: http.StatusMethodNotAllowed, Message: "method not allowed"}) return } id := r.URL.Query().Get("id") if id == "" { - http.Error(w, "missing id", http.StatusBadRequest) + WriteError(w, &AppError{Code: http.StatusBadRequest, Message: "missing id"}) return } u, err := store.FindUser(id) if err != nil { - http.Error(w, "internal error", http.StatusInternalServerError) + WriteError(w, err) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(u) }这里有个细节:Agent 第一版把WriteError写成了直接http.Error,没做 JSON 格式。我在提示词里补了一句「错误响应必须是 JSON」,它才改成上面这样。所以提示词里把输出格式写死,比事后返工省事。
5. 跑测试与失败分支
改完先编译:
go build ./...再跑全量测试:
go test ./...正常输出:
ok your-go-repo/internal/handler 0.012s ok your-go-repo/internal/store 0.008s如果测试里断言了错误响应的格式,比如原来期望method not allowed\n这种纯文本,现在变成 JSON,就会失败:
--- FAIL: TestGetUser_MethodNotAllowed (0.00s) user_test.go:42: body = {"error":"method not allowed"} want "method not allowed" FAIL这不是重构错了,是测试的期望值要跟着更新。让 Agent 一起改:
TestGetUser_MethodNotAllowed 的期望值要改成 JSON 格式,同步更新测试。它会把断言改成解析 JSON 再比对字段。改完再跑一次go test ./...,全绿。
另一个常见失败是循环依赖:middleware 放在internal/handler里,如果它引用了internal/store,而 store 又引用了 handler,就会报import cycle not allowed。解决办法是把AppError和WriteError放到更底层的internal/httpx包里,handler 和 store 都依赖它。这个坑 Agent 不一定第一次就避开,看到循环依赖报错时直接告诉它「把错误类型移到独立包」。
6. 限制、成本与模型选择
Kimi K2.7 Code 在这个任务上的表现是:读文件、改多个 handler、跑测试这条链路能走通,但提示词要具体。它不会主动帮你判断「这个错误该不该暴露给客户端」,这类业务决策还是得人来定。
成本方面,重构一个十几个 handler 的仓库,token 消耗主要在读文件和 diff 上。具体单价和计费方式以官网为准,不同模型差异不小,跑之前可以在控制台看下用量。如果只是小改动,用更便宜的模型也够;涉及多文件联动重构,Kimi K2.7 Code 的上下文和代码理解更稳一些。
限制也要说清楚:Agent 改完的代码必须自己 review 一遍,尤其是错误码和错误信息,别让它把500写成400。测试通过不等于逻辑正确,go test ./...只覆盖你写了测试的部分。
最后一步,把改动提交前再跑一次:
go vet ./... go test ./... git diff --stat确认 diff 范围符合预期,没有误改main.go和路由注册,就可以提交了。
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度