这周我把一个前后端项目整理成了适合 AI 编程助手执行任务的开发环境。
起因很简单:我让它补一组单测、修几个 lint,再顺手跑一下 E2E。代码没改几行,环境先炸了一串。
bash
npm test
# node version mismatch
npx playwright test
# browser dependencies missing
docker compose up -d
# api waits for postgres, but postgres is not healthy
这类失败很微妙。人能靠经验绕过去,AI 只能按仓库里的命令执行。最后我意识到,问题不是"AI 会不会写代码",而是项目环境没有写给机器看。
下面是我最后保留下来的配置。
1. 先把运行时固定住
我先建 .devcontainer/devcontainer.json:
json
{
"name": "ai-ready-dev",
"build": {
"dockerfile": "Dockerfile"
},
"forwardPorts": [3000],
"postCreateCommand": "npm ci",
"remoteEnv": {
"NODE_ENV": "development"
}
}
对应 Dockerfile:
dockerfile
FROM docker.1ms.run/node:22-alpine
RUN apk add --no-cache \
bash \
curl \
git \
python3 \
make \
g++ \
libc6-compat
WORKDIR /workspace
这一步先解决 Node 版本和 native module 构建问题。以前 README 里写"建议 Node 22",但只要某个人本机还停在 Node 18,AI 执行测试时就可能拿到完全不同的结果。
2. Compose 只管开发依赖
项目依赖 API、Postgres、Redis。以前经常是"数据库已经在本机后台跑着",但这种状态不能假设给 AI。
我把开发依赖写成 compose.dev.yaml:
yaml
services:
app:
image: docker.1ms.run/node:22-alpine
working_dir: /workspace
volumes:
- .:/workspace
command: sh -c "npm ci && npm run dev"
ports:
- "3000:3000"
env_file:
- .env.example
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
postgres:
image: docker.1ms.run/postgres:16
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: app
POSTGRES_DB: app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app"]
interval: 5s
timeout: 3s
retries: 20
redis:
image: docker.1ms.run/redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 20
这里有两个取舍:
- 这不是生产编排,只服务本地开发、AI 任务和 CI 复现。
depends_on只能帮你等到服务 healthy,业务层连接重试仍然要保留。
3. 把任务入口固定成命令
我之前给 AI 的指令太口语化,比如"跑一下测试看看"。这会让它自己猜命令,猜错了日志就乱。
后来我把入口收敛成固定脚本:
json
{
"scripts": {
"dev": "vite --host 0.0.0.0",
"lint": "eslint .",
"test": "vitest run",
"test:e2e": "playwright test",
"db:migrate": "prisma migrate deploy",
"db:seed": "node scripts/seed.js"
}
}
然后每次任务前先让它跑:
bash
docker compose -f compose.dev.yaml pull
docker compose -f compose.dev.yaml up -d
npm run lint
npm test
这样失败时就很好分层:是镜像拉不下来、依赖装不上、服务没 ready,还是测试真的没过。
4. Playwright 单独处理
E2E 测试是另一个常见坑。本机能跑,不代表容器里能跑。
我会在文档里明确两件事:
bash
npx playwright install --with-deps
npm run test:e2e
如果团队 E2E 很重,更适合单独准备浏览器测试镜像。不要让 AI 每次临时摸索浏览器依赖。
5. 镜像预检提前做
我把镜像预检放在任务开始前:
bash
docker pull docker.1ms.run/node:22-alpine
docker pull docker.1ms.run/postgres:16
docker pull docker.1ms.run/redis:7
docker pull docker.1ms.run/python:3.12-slim
毫秒镜像在这里只解决一件事:让开发容器和依赖服务镜像更稳定地拉下来。它不是 AI 工具,也不会帮你判断业务逻辑对不对。
这个边界很重要。镜像预检只是把环境噪音提前排掉,让 AI 真正开始处理代码任务。
6. 最后保留的检查表
| 检查项 | 判断标准 |
|---|---|
| 镜像 tag | 不用 latest 跑团队环境 |
| Dev Container | 固定语言版本和系统依赖 |
| Compose | 固定 Postgres、Redis 等依赖服务 |
| healthcheck | 服务状态可被命令判断 |
.env.example |
新环境变量完整 |
| test/lint | 一条命令可执行 |
| migrate/seed | 数据库初始化不靠口头提醒 |
| E2E | 浏览器依赖不靠本机 |
| 日志 | 能区分环境问题和业务问题 |
7. 复盘
AI 编程助手已经不只是补全代码了。它会在仓库里跑命令、读日志、改文件、再根据结果继续修。
项目环境越靠人记忆,它越容易表现得"不好用"。项目环境越能被配置、命令和日志表达,它越能像一个真正能接小任务的协作者。
这次改完后,我最大的感受是:不要先问 AI 能不能改复杂业务,先问它能不能稳定跑起项目。