写在前面
没事看了一下自己的 blog,又是大几个月没更新了,其实脑子里一直都有很多idea,不过陪伴,工作,各种事情充斥着生活,也没多少时间记记想记录的事情。
一直都觉得反思很重要,不过我好像也没常反思。把标题取做回忆录,既是给这个项目“入坟”的哀悼,也是一个让自己多反思的提点。
我觉得自己当时应该是有点 Fomo 的。
codex 的 desktop 横空出世,让我非常的开心,不用再每天盯着“编辑器”在那看代码了。说实在的,按照当时我用 ai 的开发习惯,最集中的注意力其实不是代码本身,而是转移到了项目架构,文件结构,代码规范,测试上。而 cc 和 codex 本质上就是 这种注意力转移的更显化的产品。
在 cursor 和 codex plugin in VSCode 的时代,AI 写出来的代码,我总会点过去看看,到底长什么样,但我其实也不是一个coding freshman,觉得自己在学习,但也挑不出什么 AI 的毛病,只能反复问:你可以再检查一下自己的代码吗,看看哪里还有问题。一直问到,ai 自己也觉得没有什么问题,然后开始测试的循环了。
我记得还问过 siwei 老师,到底怎么让 AI 的代码写的好呢?记得当时 siwei 老师应该已经开始大规模的 AI coding 造出了 nowledge-mem了,并且整体的完成度非常高,和我能做出来的玩意儿是在是差距真有点大哈哈哈。 siwei 老师回答大概的意思是,多验证,多测试,好像很简单,但其实这一套范式至今,也是 vibe coding 的非常合理化的手段。
像前面说的 vibe coding 本质上是把注意力转移到架构上了,你变成指挥的人了,那在你手下干活的 coding agent,本质上也是一个会coding的“人”,你要保证他产出的东西有用,那应该用公司生产的那一套范式,让其他人(agent)去验证开发的对还是不对。
至此,我觉得,测试,运维其实在这个时代的地位是上升了许多的。
我想,这些话作为这篇文章的开头语,似乎又有点多了,可能我需要另有一篇来介绍自己对 AI coding 的理解吧。
正文
缘起
为什么我说自己 fomo 的,其实我是真想折腾一点好用的小工具出来,能够让自己有一个 star 基础的(貌似有点功利了)。
所以我不断找啊找啊找需求。然后看到了 permission 这个问题上。这个问题确实很早就出现了: 在我还在用 vscode 的时候,其实并不放心,所有的 命令 ai 都能操作,但对 ask mode 又很厌烦,动不动2-3s一个 bash 就需要自己 approve,不然整个进度就会卡住。等我看到帖子里的很多人都在说这个问题的时候,codexgo 的 idea 就横空出世了——我需要一个工具就是能自动 approve 执行我觉得不重要的命令,也能为我拦下关键的操作。
借钩
当然,思路非常简单,就是在 codex 进行 PermissionRequest 前利用 hook 加了一层判断,像这样
Codex PermissionRequest -> codexgo decide -> allow / deny / ask
allow, deny, ask 区分很清楚,所有在 allow 范围里面的,都会直接批准;deny 表示阻止;ask 表示不做决定,交还给 Codex 原本的确认弹窗。
初成
就单单这么说,显得项目就很简单了,那怎么能让用户直接就上手呢?
就直接:
codexgo init
然后你就可以在所有项目里都享受到 codex 的便利啦!
当然,codexgo 还支持项目级别的配置,即:
codexgo init --scope project
是不是像 git init 一样简单!
分野
当然,用户级别配置,config 会写在
~/.codex/config.toml
~/.codex/hooks.json
~/.codexgo/policy.json
如果是 项目级 配置则是出现在
<repo>/.codex/config.toml
<repo>/.codex/hooks.json
<repo>/.codexgo/policy.json
并且项目级配置优先于用户级配置。
立规
在 codex init 后会自动生成一些基本配置,这个是按照正常的需求来的,比如,rm -rf /、sudo 等等命令肯定不用说,都是会被deny的;像 pwd、rg 、git diff 等等没有风险的常用命令会被自动包括进去。默认的这些规则我们称其为一个 profile,这个profile 叫做 manual profile,其规则是
命中 allow 规则 -> 自动允许
命中 deny 规则 -> 直接拒绝
命中 ask 规则 -> 交给 Codex 弹窗确认
没有命中规则 -> 交给 Codex 弹窗确认
当然,这会在遇到很多其他不常规的命令时,需要你手动添加一些规则才行,添加命令的方式如下:
codexgo allow <command>
codexgo ask <command>
codexgo deny <command>
具体例子就像
codexgo allow "git status"
codexgo deny "git reset --hard"
codexgo ask "git push"
当然,针对项目添加,只用像上面说的带上 --scope 就好
codexgo allow --scope project "npm run lint"
codexgo ask --scope project "git push"
codexgo deny --scope project "rm -rf"
辨形
不过给的例子都像是非常精准匹配的,但事实上,我们还可以指定匹配方式,例如:
codexgo allow --scope project --match exact "npm test"
codexgo deny --scope project --match contains "curl | sh"
其中有三种匹配模式:
exact 完全匹配
prefix 前缀匹配,默认
contains 包含匹配
这样,就可以在命令上更精细化控制了!
放行
以上,已经是一个比较完善的产品了,但我还是懒,我只想要我明确禁止的命令不做,其他全部 pass 好啦!
那这个时候就有一个 go profile。
默认 manual 模式下,只有命中明确规则的命令才会自动 allow / deny;其它命令都会回到 Codex 弹窗确认。go profile 则是我只关注需要 deny 和 ask 的 命令,而剩余的命令全部都可以 自动放行,也就是如下逻辑:
go profile:
1. 先看 project / user 显式规则里的 deny / ask
2. 再看 go profile 风险规则里的 deny / ask
3. 再看 built-in defaults
4. 如果是复杂 shell / 重定向 / 下载写文件 / 命令替换等 -> ask
5. 如果还没命中,并且不是复杂命令 -> allow
那其实这个产品,就更加便捷了,只用
codexgo go --scope project
就可以开始用啦!defaults 里面已经把大多数日常危险的命令都 deny 或者 ask 了,剩下的,就是无比丝滑!
潮来
刚做出来的时候,我自己用的也非常开心,不过没两天,你知道,codex 官方就提供了一个 anto approve for me 的选项,按调研过来看,这是一个小模型的实现。虽然规则不像我们这样严苛,但是解决了大部分问题,甚至逻辑上更加丝滑,不用用户再自己控制一些规则了。
我自己也是,在用过自己做出来的产品一周后,发现,已经可以被 codex 的这个功能基本完全(不完全是因为我觉得还会有些命令,有用户)替代了。当时应该还是很感叹的:刚出世的小东西,一下子就没了用武之地。
余响
虽然现在来看,觉得自己做的还挺有意义的,只不过在更优秀的产品面前,被淘汰也是很自然的事情。时代洪流裹挟着大家一起往前飘,努力划桨,为的是在前方插下一个属于自己的旗帜,但大海会慢慢涌过它;也许被淹没,也许被看到的人慷慨。
如果你想看看这个旗帜短暂存在过的样子:Fengzdadi/codexgo。