AI Coding 的价值不是一次生成更多代码,而是更快完成“理解问题—最小改动—可信验证”。本文用一个真实常见问题贯穿全流程:用户已经登录,却仍能直接打开登录页。我们会先写行为契约、定位调用链、添加失败测试、实施最小补丁、完成回归和运行时验证,并说明数据库、远程推送等高风险操作的边界。
1. 先把模糊需求写成行为契约
不要只告诉 AI“修复登录问题”。先明确:
- 游客访问
/login返回登录页面。 - 已登录前台用户访问
/login重定向首页。 - 已登录管理员按现有产品规则重定向后台。
- API 未认证请求仍返回 JSON 401,不受此次改动影响。
- 不改数据库、依赖和登录页样式。
这份契约既是提示词,也是测试计划。没有“不变项”,AI 很容易用一个过宽中间件破坏其他入口。
2. 开始前保存工作区边界
先检查项目规则、当前分支和未提交修改。已有修改属于其他人时不能覆盖或重置。
pwd
find .. -name AGENTS.md -print
git status --short
git branch --show-current
git diff --stat把可修改范围限制为认证路由/中间件及对应测试。不要把整个仓库、secret、数据库转储或客户数据发给外部模型。
3. 只读定位调用链
rg -n "Route::.*login|guest|RedirectIfAuthenticated|LoginController" routes app bootstrap tests
rg -n "assertRedirect|route\(.*login|actingAs" tests阅读路由注册、guard、中间件、登录控制器和已有测试。不同框架版本的重定向配置位置可能不同,不能凭模型记忆猜。若应用区分前台与后台 guard,还要明确两个身份同时存在时的优先级。
4. 在修改前稳定复现
先运行最窄相关测试,并用 HTTP 或浏览器复现。保存命令、环境、期望与实际结果。如果测试环境无法复现,不要为了制造红灯随便改断言;可能是会话域名、cookie、guard 或缓存条件不同。
docker compose exec -T php php artisan test --filter=AuthenticationTest
curl -i http://localhost:8000/login登录态请求应在真实浏览器或测试框架中验证,因为 curl 没有会话 cookie 时只能验证游客路径。
5. 写一条真正覆盖缺陷的回归测试
public function test_guest_can_open_login_page(): void
{
$this->get(route("login"))->assertOk();
}
public function test_authenticated_user_is_redirected_away_from_login(): void
{
$user = User::factory()->create();
$this->actingAs($user)
->get(route("login"))
->assertRedirect(route("home"));
}先确认第二条在旧实现上失败、第一条通过。若测试依赖验证码或其他保护,应使用项目已有测试 helper,而不是在生产代码里关闭安全机制。
6. 让 AI 先提方案,再选最小改动
高质量任务包应包含行为契约、相关文件、失败输出、测试命令和禁止项。要求先说明调用链与两个候选方案,再生成补丁。
目标:已登录用户访问登录页时按现有 guard 重定向。
可修改:登录路由/认证中间件、对应特性测试。
不可修改:数据库、依赖、页面样式、API 401 行为。
步骤:先引用当前调用链;给出两个方案及风险;选择最小补丁;运行指定测试。
禁止:删除、弱化或跳过失败测试。优先复用框架现有 guest 中间件或已有重定向钩子,不重写整个登录控制器,也不顺便升级依赖。
7. 逐行审查补丁
git diff --check
git diff -- routes app/Http tests
git status --short逐文件问“为什么必须改”。检查授权是否仍在服务端、异常是否被吞、日志是否泄密、是否新增网络请求或依赖、是否影响注册/密码重置/API。无法解释的文件应移出本次补丁。
| 风险 | 审查重点 |
|---|---|
| 认证/授权 | guard、资源归属、游客与已登录分支 |
| SQL/命令 | 参数化、动态标识符、shell 参数边界 |
| 输出 | HTML/URL/JSON 上下文编码 |
| 依赖 | 来源、锁文件、许可证与供应链 |
| 长驻进程 | 缓存、队列、OPcache 是否加载旧代码 |
8. 从窄到宽运行测试
docker compose exec -T php php artisan test --filter=AuthenticatedUserLoginRedirectTest
docker compose exec -T php php artisan test tests/Feature/Auth
docker compose exec -T php php artisan test
git diff --check顺序很重要:窄测试快速定位;模块回归检查相邻行为;完整测试发现意外影响。不能通过 skip、删除用例、放宽断言或 mock 掉关键路径让测试“变绿”。
9. 验证真实运行时,而不只看文件
PHP OPcache、队列 worker、Octane、前端构建和反向代理都可能继续使用旧版本。按项目部署方式重启现有服务,核对实际 HTTP 资源和运行中源码指纹。不要另起一套“看起来通过”的环境替代现有环境。
docker compose ps
docker compose restart php
curl -I http://localhost:8000/login
docker compose logs --since=5m php具体服务名按项目 Compose 文件调整。浏览器验收同时测试游客、普通用户、管理员和退出登录后的行为。
10. 数据库与外部副作用的额外门禁
迁移、批量更新、物理删除、远程推送、发邮件和生产写操作不是普通代码编辑。执行前做只读查询,显示精确目标和预计影响,准备备份/回滚并获得明确授权。AI 生成的 SQL 先在测试库事务中验证 WHERE、外键、触发器和锁范围。
-- 先只读确认,不能直接执行 DELETE
SELECT id, email, status
FROM users
WHERE status = 'inactive'
ORDER BY id
LIMIT 100;“修功能”不等于允许清空数据、推送远端或改生产配置。
11. 失败时如何继续,而不是无界重试
给 AI 提供首个根因、命令、退出码、相关堆栈、环境版本和当前 diff。先比较失败指纹是否变化;若前置条件没变化,不重复同一命令。清理残留测试进程后再启动下一轮,避免电脑持续高负载。
docker compose top
ps aux | rg "phpunit|artisan test|node|vite"
docker stats --no-stream不要把完整巨量日志反复粘贴;保留原始日志文件,提供定位和摘要即可。
12. 提交说明与回滚
提交说明包含问题、根因、最小改动、测试命令、真实运行时验证、未覆盖项和回滚方法。发布采用小范围灰度,观察认证失败率和重定向异常;出现回归时回退整个补丁与配置组合。
13. 总结
可信 AI Coding 依赖严格边界和证据:先写行为契约,读调用链,添加能复现问题的测试,再做最小补丁,从窄到宽验证,并检查真实运行时。速度来自减少无效尝试,而不是省略测试或扩大权限。