作者:姚杨 | 专栏:阿杰的技术成长
接上集:阿杰用php-vibe-coding-frame解决了「AI 写代码的幻觉」,三行闭包一次跑通。可他很快发现,框架只是第一道坎。
周五晚上十一点,阿杰盯着屏幕上的 500 错误发呆。
这是他这周第三次了。上集他听老陈的建议,把项目从「全家桶」框架换成了 php-vibe-coding-frame——AI 写代码的幻觉问题确实压下去了。可新问题比想象中来得更狠:
- 他本地能跑的功能,同事一拉代码就报「连接被拒绝」;
- AI 信心满满地说「接口应该没问题」,结果页面一打开就是 500;
- 他自己 curl 了半天,连错在哪一层都不知道——nginx?php-fpm?还是数据库?
- 更离谱的是,AI 改完代码从不主动提交,三次对话攒下的改动,最后全靠他手动
git add。
阿杰突然意识到:框架只解决了「AI 写什么」,没解决「AI 怎么验证」。
AI 能写代码,却看不见页面、读不到日志、改完不提交——它像个被蒙着眼、绑住手的打字员。
一、老陈甩来一个容器
周一晨会,老陈(那位务实 CTO)端着咖啡路过,瞥了眼他的屏幕:「还在手动 curl 测?」
「框架不都换好了吗,怎么还是这么累?」
「框架解决的是『写』,没解决『验』和『交』。」老陈拉开椅子坐下,「你让它写,却没给它手和眼。给你看个东西。」
他甩来一个链接:harness_engineering_php_env。
阿杰照着 README 敲下一条命令:
sudo docker run --rm -ti \
-p 80:80 -p 3306:3306 -p 12345:12345 -p 12346:12346 \
--name harness_engineering_php_env \
-v ~/.claude:/root/.claude \
-v /home/me/projects/my-app:/var/www/my-app \
-e 'PRJ_HOME=/var/www/my-app' \
-e 'TIMEZONE=Asia/Shanghai' \
registry.cn-shenzhen.aliyuncs.com/smarty/harness_engineering_php_env start
容器起来的那一刻,阿杰愣了——里面不是空荡荡的 PHP,而是一整套提前装好的开发基建:nginx、MariaDB、Redis、Beanstalkd 队列、PHP 8.4-FPM、PHPUnit,连 Claude CLI 和那个能操作浏览器的 chrome_do_action 都预装好了。
「这都不稀奇,」老陈说,「稀奇的是环境对 Claude 的『交代』。」
二、Harness 的精髓:把 AI「套」进一个有纪律的环境
原来这个镜像在启动时就给 Claude 写了一份「环境说明书」:nginx 日志在哪、php-fpm 日志在哪、MySQL 慢查询日志在哪、Redis 命令日志在哪,一一列清。还顺手立了三条规矩:
- 测试优先用浏览器:让 Claude 通过
chrome_do_action真正打开页面点一点,而不是瞎猜接口对不对; - 报错先看日志:页面挂了,Claude 自己去看对应的错误日志定位,而不是来回问你「你那边报什么错」;
- 改完自己提交:每次改完代码,Claude 自动
git add --all,并按「新增 / 修改 / 删除 / 修复」四段式写 commit。
阿杰试着让容器里的 Claude 修一个 bug。它真的自己打开了页面 → 发现 500 → 翻 php-fpm 日志定位到一行配置 → 改掉 → service php8.4-fpm restart 重启 → 再打开页面验证通过 → 最后自己 commit。
全程阿杰只说了三句话:「这里有个 bug」「再测一遍」「可以了」。
三、它到底解决了什么
阿杰冷静下来,把这套东西能填的坑列了一遍:
| 传统 Vibe Coding 的坑 | harness 环境怎么填 |
|---|---|
| 「在我机器能跑」的环境不一致 | 环境即镜像,一键拉起,人人一致 |
| AI 看不见页面,只会猜 | 预装浏览器自动化,Claude 真去点 |
| 日志散落,报错靠蒙 | 启动即告知各组件日志路径 |
| 改完不提交,改动易丢 | 自动 commit,四段式 message |
| 每次重开没上下文 | 映射本机 ~/.claude,历史配置全复用 |
还有两个细节让阿杰眼前一亮:
- 启动前后钩子:
BEFORE_START_SHELL可以准备目录权限,AFTER_START_SHELL能自动建表、导测试数据——新同事拉下来就是「带数据的可跑状态」,不用再手忙脚乱配半天。 - 端口全映射:80/3306/12345/12346 都映射到本机,你用本地 Navicat 连数据库、用浏览器插件连 cda,跟平时一模一样。
四、框架管「写」,环境管「验」和「交」
「所以框架解决『写』,环境解决『验』和『交』。」阿杰合上电脑,「两件套凑齐,vibe coding 才真正闭环。」
老陈拍了拍他肩膀:「记住,AI 不是来替你写代码的,是来跟你组队的。你给它手和眼,它才像个队友。」
如果你也想让自己的 Claude 拥有手和眼,把这个环境拉下来试试:
# 一键启动(把 /home/me/projects/my-app 换成你的项目路径)
sudo docker run --rm -ti \
-p 80:80 -p 3306:3306 -p 12345:12345 -p 12346:12346 \
--name harness_engineering_php_env \
-v ~/.claude:/root/.claude \
-v /home/me/projects/my-app:/var/www/my-app \
-e 'PRJ_HOME=/var/www/my-app' \
-e 'TIMEZONE=Asia/Shanghai' \
registry.cn-shenzhen.aliyuncs.com/smarty/harness_engineering_php_env start
完整源码、参数说明与钩子用法,都在这里:
https://github.com/smarty-kiki/harness_engineering_php_env
建议搭配上集的 php-vibe-coding-frame 一起用——框架管「写」,环境管「验」和「交」,才是完整的 Vibe Coding 工作流。