远程办公半年,我把本地开发环境彻底重构了一遍
早上八点钟,闹钟响第三遍的时候我终于是爬起来了。
窗帘没拉,屏幕自动亮度调到了最低,我摸着黑打开电脑,熟练地连上公司的VPN,泡了杯咖啡坐回工位——也就是我卧室那张一米二的书桌。
先交代下背景吧,免得你们觉得我一个学生党在这装什么老油条。我是某普通一本CS专业的大四学生,秋招运气还行,拿到了一家中型互联网公司的后端offer,岗位是Go开发。因为还没正式毕业,公司也允许远程,所以我现在基本就是在家撸代码的状态。每天八点左右起来,趁着脑子还清醒赶紧干点活,下午有时候去学校处理点毕设的事情,晚上再回来继续卷。
这种远程办公的日子过了大半年,说实话,一开始是真的爽,不用挤地铁,不用看leader脸色(虽然远程也得看),穿着睡衣就能写代码。但时间一长,问题就来了——我的开发环境简直是一坨屎。
不是夸张,是真的屎。
环境乱到什么程度呢
你们有没有那种体验:打开终端,想跑个go build,结果提示你Go版本不对;切到另一个项目,发现用的Python版本又冲突了;想开个编辑器,VSCode插件装了几十个,启动慢得像在开飞机;Docker镜像堆了几十个G,磁盘天天报警。
我之前就是这种状态。
去年十一月份的时候,有个周末我在家赶一个内部工具的deadline,产品经理(哦对,远程之后我连产品经理的面都见不到,只能在飞书上被@)催得紧,说周一必须上线。我本地环境不知道抽了什么风,go mod tidy死活跑不通,报错信息是一长串的依赖冲突。我当时真的想砸电脑。
后来折腾到凌晨两点才搞定,第二天顶着黑眼圈提交代码,还被测试小姐姐吐槽说"你这代码是不是梦游写的"。
那一刻我就下定决心,必须把开发环境好好整理一下了。
编辑器换了,真香
先说编辑器这个事儿。
我用VSCode用了快三年了,从大一写C语言作业开始,到后来做项目、刷LeetCode,一直都是它。不是说VSCode不好,但说实话,它越来越重了。你看看现在VSCode的启动速度,开个大型项目,光插件加载就得等个五六秒。而且我这台电脑还是大三攒的,i5-10400加16G内存,跑VSCode有时候风扇呼呼转,跟要起飞一样。
后来是看到群里有人安利Zed,说是用Rust写的,启动速度飞快。我当时也没太当回事,想着编辑器能有多大差别。但实在是被VSCode卡烦了,就下载试了试。
好家伙,真香。
Zed的启动速度是真的快,几乎是秒开。而且它原生支持多人协作,虽然我现在远程办公用不上这个功能,但体验下来确实丝滑。最关键的是,它对Go的支持非常原生,语法高亮、代码补全、跳转定义这些基础功能都不需要额外装插件,开箱即用。
当然,Zed也不是完美的。它的插件生态跟VSCode比还是差了不少,有些VSCode上习以为常的功能,在Zed上可能就得自己折腾一下。但对于我这种主要写Go的人来说,够用了。
这是我现在的Zed配置,放出来给大家参考:
// Zed settings.json
{
"theme": "One Dark",
"buffer_font_family": "JetBrains Mono",
"buffer_font_size": 14,
"tab_size": 4,
"format_on_save": "on",
"autosave": "after_delay",
"autosave_delay": 1000,
"vim_mode": true,
"go": {
"format_on_save": "on",
"lint": "golangci-lint"
},
"terminal": {
"font_family": "JetBrains Mono",
"font_size": 13,
"working_directory": "~/workspace"
}
}
开了vim模式之后,写代码的效率又提升了一截。别笑,vim党的快乐你们不懂。
AI编程助手,用还是不用
说到开发环境,就不得不提AI编程助手了。
这玩意儿现在简直是程序员圈子里的热门话题。我们公司内部其实也有自己的AI工具,叫Moltbot。说实话,一开始我对这种工具是有抵触的,总觉得用AI写代码有点"作弊"的感觉,而且担心代码质量没法保证。
但用了一段时间之后,我的想法变了。
Moltbot最让我惊喜的不是它的代码生成能力——虽然确实不错——而是它的工具调用能力。什么意思呢?就是它不只是帮你补全几行代码,而是能够理解你的意图,然后调用一系列工具来完成任务。
举个例子,上周我在写一个数据同步的模块,需要从MySQL读数据,转换格式,然后写入Elasticsearch。这种活儿其实逻辑不复杂,但写起来很繁琐,各种结构体定义、JSON序列化、错误处理,一堆 boilerplate code。
以前我可能得花个大半天来写这些。但这次我直接在Moltbot里描述了我的需求,它不光帮我生成了核心逻辑代码,还自动调用了项目里的ORM工具生成模型定义,调用了lint工具检查代码规范,甚至还帮我写了单元测试的骨架。
这种体验怎么说呢,就像你身边坐了个经验丰富的同事,你说"帮我搞个数据同步",他二话不说就把框架搭好了,你只需要在关键逻辑上微调就行。
当然,Moltbot也不是万能的。它生成的代码有时候会有些小问题,比如边界条件没考虑到,或者用的API版本不对。所以我的原则是:AI生成的代码一定要自己过一遍,该改的改,该补的补。毕竟最后背锅的是你自己,不是AI。
关于工具调用这块,我后来还专门研究了一下它的实现原理。简单来说,就是给大模型提供了一组可调用的工具接口,模型根据用户的请求,决定调用哪些工具、以什么顺序调用、传什么参数。这个思路其实跟函数调用很像,只不过"函数"变成了外部的工具。
// 工具调用的简化模型
type ToolCall struct {
Name string `json:"name"`
Arguments map[string]interface{} `json:"arguments"`
}
type ToolResponse struct {
Result interface{} `json:"result"`
Error string `json:"error,omitempty"`
}
// Agent 核心循环
func (a *Agent) Run(task string) (string, error) {
// 1. 将任务描述发给大模型
response, err := a.llm.Chat(task, a.availableTools)
if err != nil {
return "", err
}
// 2. 解析模型返回的工具调用请求
for _, call := range response.ToolCalls {
// 3. 执行工具调用
result, err := a.executeTool(call)
if err != nil {
return "", fmt.Errorf("tool %s failed: %w", call.Name, err)
}
// 4. 将结果反馈给模型,继续推理
response, err = a.llm.ChatWithHistory(result)
if err != nil {
return "", err
}
}
return response.FinalAnswer, nil
}
这段代码是我根据Moltbot的公开文档自己写的一个简化版demo,核心思路就是这样的。感兴趣的同学可以自己试试,用Go实现一个简易的Agent其实不难。
Goose,我的新宠
如果说Zed解决了编辑器的问题,Moltbot解决了AI辅助编码的问题,那Goose就是把我整个开发工作流串起来的那个角色。
Goose是什么?简单说,它是一个开源的AI开发助手,可以跑在你本地,帮你处理各种开发任务。跟Moltbot不同的是,Goose更偏向于"自动化"——你可以给它定义一系列任务,它会自动执行。
我第一次接触Goose是在GitHub上闲逛的时候(别笑,程序员逛GitHub就跟你们刷抖音一样)。看到它的star数涨得挺快,就clone下来试了试。
这一试就离不开了。
我现在的工作流是这样的:
每天早上八点到工位,先打开Goose,让它检查一下昨天提交的代码有没有CI/CD的报错。如果有,它会自动分析错误日志,给出修复建议,甚至直接帮你改好代码提交PR。
然后我会让它跑一遍项目的单元测试,如果有fail的case,它也会帮我定位问题。
写完代码之后,我会让Goose帮我跑一遍golangci-lint,检查代码规范。它不光能跑lint,还能根据lint的结果自动修复一些简单的问题,比如格式化、unused import之类的。
这整套流程下来,以前我可能得花个把小时,现在基本上十分钟就搞定了。省下来的时间干嘛?当然是摸……啊不,当然是写更多代码(笑)。
这是我日常用的Goose配置:
# goose-config.yaml
extensions:
- name: git
enabled: true
- name: docker
enabled: true
- name: go
enabled: true
tools:
- name: run_tests
command: "go test ./... -v -count=1"
trigger: "after_commit"
- name: lint_check
command: "golangci-lint run ./..."
trigger: "before_commit"
- name: build_check
command: "go build -o /dev/null ./..."
trigger: "on_save"
ai:
provider: "local"
model: "qwen2.5-coder"
temperature: 0.3
workflow:
morning_routine:
- check_ci_status
- run_tests
- analyze_failures
pre_commit:
- lint_check
- format_code
- run_tests
有个小细节,我把AI provider设置成了local,用的是Qwen2.5-Coder这个模型。为什么不直接用云端的API呢?两个原因:一是公司网络环境对外的API调用有限制,二是本地跑模型数据安全性更好,毕竟代码是公司的资产。
当然本地跑模型对硬件有要求,我这个16G内存的机器跑7B参数的模型还行,再大就吃力了。如果你内存够的话,建议上更大的模型,效果会好很多。
工具调用,不只是AI的事
说到工具调用,我想多聊几句。
很多人一提到工具调用,就想到AI、大模型这些。但其实在传统的软件工程里,工具调用也是一个非常重要的概念。
你看我们的日常开发,其实就是在不断地调用各种工具:编译器是工具,linter是工具,测试框架是工具,CI/CD pipeline也是工具。一个好的开发环境,应该是让这些工具能够无缝协作的。
我之前环境乱的时候,这些工具之间是割裂的。跑lint得手动敲命令,跑测试得切到另一个终端,看CI状态得打开浏览器。每次操作都是一次上下文切换,效率很低。
现在我把这些工具都集成到了Goose里,通过工具调用的方式串联起来。我不需要记住每个工具的命令参数,不需要在不同的终端窗口之间切来切去,只需要告诉Goose"我要提交代码了",它就会自动帮我跑完所有的检查。
这种体验,用我们CS的话来说,就是把O(n)的操作复杂度降到了O(1)。
当然,要实现这种效果,工具本身的接口设计也很重要。好的工具应该提供清晰的命令行接口、结构化的输出格式、合理的退出码。这样其他工具才能方便地调用它、解析它的结果。
这也是为什么我特别推崇那些设计良好的CLI工具。比如golangci-lint,它支持JSON格式的输出,可以很方便地被其他程序解析;它的退出码也有明确的语义,0表示通过,1表示有warning,2表示有error。这种设计,就是为工具调用而生的。
环境配置分享
说了这么多,最后分享下我现在完整的开发环境配置,给同样远程办公或者想优化开发环境的同学一个参考。
| 工具 | 用途 | 备注 |
|---|---|---|
| Zed | 代码编辑器 | 替代VSCode,启动快,Go支持好 |
| Goose | AI开发助手 | 自动化工作流,工具调用编排 |
| Moltbot | AI编码助手 | 复杂逻辑的代码生成 |
| Warp | 终端 | 比iTerm2好用,AI加持 |
| OrbStack | Docker管理 | 比Docker Desktop轻量太多 |
| lazygit | Git操作 | 终端里的Git GUI,效率拉满 |
| golangci-lint | 代码检查 | Go项目必备 |
| Air | 热重载 | Go开发的热重载工具 |
硬件方面,我现在用的是:
CPU: Intel i5-10400
RAM: 16GB DDR4 (准备加到32G)
SSD: 512GB NVMe (代码和工具都放SSD)
Monitor: 27寸 4K (远程办公必须大屏)
16G内存跑这些工具确实有点捉襟见肘,特别是本地还要跑AI模型的时候。所以下个月发工资我准备先加条内存,32G应该就够用了。
哦对了,还有个事儿。远程办公嘛,网络环境也很重要。我之前用的是家里的WiFi,有时候写代码写着写着突然卡一下,原来是室友在下载东西把带宽占满了。后来我咬咬牙拉了条独立的宽带,专门用来办公。虽然每月多了几十块钱,但体验提升不是一点半点。
一些踩坑经验
最后分享几个我在这波环境重构中踩的坑,给大家避避雷。
坑一:不要一次性全换
我当时是一口气把编辑器、终端、Docker管理工具全换了,结果第一天直接懵逼,各种快捷键不习惯,各种配置要重新搞,效率反而比之前还低。
建议是渐进式替换。先换一个最痛的点,用习惯了再换下一个。
坑二:AI工具的输出一定要review
这一点怎么强调都不过分。AI生成的代码看起来很像那么回事,但细节上可能有问题。特别是涉及到并发、资源释放、错误处理这些地方,AI经常会忽略。
我有一次就是直接用了AI生成的代码,结果上线之后出了个goroutine泄漏,排查了大半天。从那以后,AI生成的代码我每一行都会仔细看。
坑三:工具链版本要锁死
Go的版本、依赖的版本、lint工具的配置,这些一定要锁死。不然你今天能跑的代码,明天换个环境就跑不了了。
我现在用go.mod锁依赖版本,用.go-version文件锁Go版本,用.golangci.yml锁lint配置。虽然麻烦一点,但能省很多扯皮的时间。
写在最后
搞了这波环境重构之后,我最大的感受就是:磨刀不误砍柴工。
以前总觉得配环境是浪费时间,有那功夫不如多写两行代码。但实际上,一个好的开发环境能让你每天的效率提升至少20%。一年下来,省出的时间够你多学好几门技术了。
特别是对于远程办公的同学来说,开发环境就是你的战场。武器不好使,仗怎么打?
好了,今天就聊到这。我得继续去写代码了,下午还有个code review要参加。虽然远程,但该卷还是得卷的(苦笑)。
对了,如果你也有什么开发环境方面的心得,欢迎在评论区交流。毕竟独卷卷不如众卷卷嘛。
溜了溜了,goose又在那催我跑测试了。


评论 0