screenshot-to-code 的 AGENTS.md:面向 AI Agent 的工程协作规范——Poetry 环境、测试门禁与 Cursor Cloud 启动陷阱全解
AGENTS.md 是 screenshot-to-code 仓库中一份专门写给 AI 编码 Agent 看的"项目操作手册":它定义了 Python 环境的唯一正确用法、每次代码改动后必须通过的测试与类型检查门禁、前端 lint 规则,以及 prompt 字符串的代码风格约束,还给出了 Cursor Cloud 云沙箱环境的完整启动命令和一堆"不踩坑就会卡住"的环境注意事项。读完本文,你将能按仓库的既定规范在本地或云端沙箱中正确启动前后端服务、配置 LLM 密钥,并理解这套 Agent 指令为何这样设计,从而让 AI 辅助开发流程与人类开发者保持一致的工程标准。
一、AGENTS.md 的定位:给 Agent 的"可执行规则"
这份文档不是给人看的教程,而是给自动化编码 Agent 的约束集,结构上分为五块:
- Python 环境规则——统一使用后端 Poetry 虚拟环境,避免 Agent 用错解释器;
- 测试策略——每次改动后必须跑 pytest 与 pyright 两道门禁;
- 前端规则——涉及前端时额外跑
pnpm lint; - Prompt 格式规范——约定后端多行 prompt 的书写风格;
- Hosted 版本与 Cursor Cloud 专项指令——说明托管版分支归属,以及云沙箱环境的启动方式与陷阱。
它引用了 README.md 作为"标准命令"(canonical commands)的出处,自身则负责补充 README 不会写的"非显性"环境细节(Non-obvious caveats)。
二、Python 环境:Poetry 虚拟环境是唯一入口
AGENTS.md 对环境的要求可以逐条落实为命令:
- 所有 Python 命令必须走后端 Poetry 虚拟环境(文档写作
backend-py3.10); - 首选调用方式是不激活环境直接运行:
cd backend && poetry run <command>
- 若必须激活(例如进交互式 REPL),用 Poetry 自己发现环境,而不是手写 venv 路径:
cd backend && poetry env activate
# 然后执行它打印出的 source .../bin/activate
为什么要如此严格?因为 backend/pyproject.toml 是一个 package-mode = false 的 Poetry 工程(不打包发布,只管理依赖),其中:
python = "^3.10"约束了解释器下限;- 核心依赖包括
fastapi、uvicorn、openai(锁定2.16.0)、anthropic、google-genai、playwright、langfuse等; - 开发组依赖里才有
pytest、pyright、pytest-asyncio。
poetry run 会保证命令总是在这个受约束的解释器里执行,Agent 就不会出现"用系统 Python 跑测试,缺包报 ModuleNotFoundError"这类漂移。AGENTS.md 还特别提示了一个反直觉的事实:虚拟环境名虽然叫 backend-py3.10,但实际可能解析为 Python 3.12(环境名会像 backend-...-py3.12)——因为 ^3.10 语义上满足 3.12,所以不要按名字纠结版本,一律用 poetry run 即可。
三、测试策略:pytest + pyright 双门禁
AGENTS.md 的 Testing policy 要求每次代码改动后都执行:
cd backend && poetry run pytest # 后端测试
cd backend && poetry run pyright # 类型检查
并且类型检查策略是"被修改的文件不允许引入任何新的 pyright 警告"(no new warnings in changed files)。
这两个门禁在仓库里都有对应配置支撑:
- backend/pytest.ini:
testpaths = tests、匹配test_*.py/Test*/test_*、addopts = -v --tb=short,并开启asyncio_mode = auto——这意味着后端大量异步工具代码可以直接写async def test_xxx,不需要逐个加@pytest.mark.asyncio; - backend/pyrightconfig.json:
typeCheckingMode设为basic(而非严格的strict),reportMissingTypeStubs关闭,reportUnknownVariableType降级为 warning,且image_generation.py被整体排除。这解释了为何 AGENTS.md 的门槛是"不新增警告"而不是"零警告"——门禁与 pyright 的实际配置是配套的。
四、前端门禁:pnpm lint 与"零警告"基线
涉及前端的改动必须额外运行:
cd frontend && pnpm lint
对照 frontend/package.json,该脚本实际是:
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
--max-warnings 0 说明前端采用零警告策略。AGENTS.md 同时诚实地标注:当前仓库里 pnpm lint 会报出既有错误(例如 generateCode.ts 中的 @typescript-eslint/no-explicit-any),这些是基线问题而非环境问题——换句话说,Agent 的判断标准应当是"不引入新的 lint 报错",而不是盲目追求清零。
此外,package.json 中声明了 "packageManager": "pnpm@10.32.1",这也是为什么环境规则指定用 pnpm(而非 npm)管理前端依赖。
五、Prompt 格式规范:三引号 f-string 约定
screenshot-to-code 的核心工作是把用户输入转换成发给 LLM 的多行 prompt,后端有一整个 backend/prompts/ 目录(create/update 场景、设计系统、系统 prompt 等)。AGENTS.md 为此立下两条风格规则:
- 多行 prompt 文本优先用三引号字符串(
"""..."""); - 需要插值的多行 prompt,优先使用单个三引号 f-string,而不是多段字符串拼接。
这一约定在源码中确实得到遵守:backend/prompts/create/text.py、backend/prompts/create/image.py、backend/prompts/update/from_file_snapshot.py、backend/prompts/design_system.py 等文件均使用 f"""...""" 书写模板。对 Agent 来说这条规则的价值在于:diff 友好、模板与变量一屏可见、避免拼接顺序错误导致的 prompt 内容漂移——这在 LLM 应用中直接影响生成质量。
六、Hosted 分支:托管版与 SaaS 后端的边界
AGENTS.md 明确:托管(hosted)版本位于 hosted 分支,该分支连接的是一个独立代码库的 SaaS 后端(../screenshot-to-code-saas)。这对 Agent 的约束是:在本仓库默认分支上不要"顺手"实现托管逻辑。
这个仓库间关系在脚本里也有实证——scripts/cursor-cloud-install.sh 末尾会检测相邻目录:
if [ -d ../screenshot-to-code-saas/backend ]; then
~/.local/bin/poetry -C ../screenshot-to-code-saas/backend install --no-root
fi
if [ -d ../screenshot-to-code-saas/admin ]; then
pnpm -C ../screenshot-to-code-saas/admin install
fi
即 SaaS 后端的依赖安装是可选分支,仅在本地布局中确实存在该目录时才执行。
七、Cursor Cloud 环境:安装脚本与自动依赖刷新
针对 Cursor Cloud 云沙箱,AGENTS.md 给出两条规则:
- 依赖会在启动时自动刷新(
backend/里poetry install,frontend/里pnpm install),Agent 无需手动安装; - 环境初始化应运行
bash /agent/repos/screenshot-to-code/scripts/cursor-cloud-install.sh,该脚本会先切到仓库根目录再执行,因此与启动时的工作目录无关。
看 scripts/cursor-cloud-install.sh 的实现,可以确认这些描述逐条成立:
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT" # 先归位到仓库根,命令才与工作目录无关
curl -sSL https://install.python-poetry.org | python3 - # 现场安装 Poetry
~/.local/bin/poetry -C backend install
~/.local/bin/poetry -C backend run playwright install chromium || true
pnpm -C frontend install
# 之后是可选的 SaaS 后端/admin 安装(见上一节)
三个细节值得注意:
- 脚本全程使用
~/.local/bin/poetry全路径——正好呼应后文"非交互 shell 里 PATH 可能找不到 poetry"的陷阱; playwright install chromium后跟|| true:Chromium 安装失败不阻断整个环境初始化,因为截图预览只是可选功能;- 与 README 中的 Linux 建议(
playwright install --with-deps chromium需要 sudo/apt)相比,云脚本采用"尽力而为"策略,体现了沙箱与本地环境的差异。
八、启动两个服务与前后端连接方式
AGENTS.md 指出标准启动命令以 README.md 为准,并复述了关键路径:
后端(FastAPI + WebSocket),在 backend/ 下:
poetry run uvicorn main:app --reload --port 7001
前端(Vite/React),在 frontend/ 下:
pnpm dev # 打开 http://localhost:5173
AGENTS.md 特别提醒:Vite dev server 只绑定 localhost,所以要用 http://localhost:5173 访问,http://127.0.0.1:5173 会直接拒绝连接。
前后端通信模型是"WebSocket 为主、HTTP 为辅":前端通过 VITE_WS_BACKEND_URL 连接后端,代码生成(generation)的流式输出走这条 WebSocket,其余路由是普通 HTTP。结合前端源码可以看得更细:
- frontend/src/config.ts 中
WS_BACKEND_URL优先取import.meta.env.VITE_WS_BACKEND_URL,未设置时回退为同源的ws://地址;HTTP_BACKEND_URL同理; - frontend/vite.config.ts 的 dev server 把
/generate-code(含ws: true)、/api、/local-assets三条路径代理到后端(默认http://127.0.0.1:7001,可用PROXY_CODEGEN_BACKEND覆盖)。
从源码结构看,这套"同源 + 代理"的回退设计正是为隧道/预览 URL 场景服务的——浏览器访问的是沙箱隧道地址时,请求不会打到"查看者本机的 localhost",而是经前端 origin 转给沙箱内的后端。AGENTS.md 中"VITE_WS_BACKEND_URL 默认 ws://127.0.0.1:7001"的说法则对应直接指定环境变量时的典型取值;两种路径殊途同归,最终都指向 7001 端口的 FastAPI 进程。若需要换端口或换主机,README 建议在 frontend/.env.local 中配置 VITE_WS_BACKEND_URL / VITE_HTTP_BACKEND_URL,docker-compose.yml 中也以注释强调了改端口时要同步修改该变量。
九、"非显性陷阱"逐条拆解
AGENTS.md 最有实战价值的部分是 Non-obvious caveats 清单,下面逐条给出仓库内可验证的依据:
1. poetry 在非交互 shell 里可能找不到。
它装在 ~/.local/bin,交互 shell 的 .bashrc 会把它加进 PATH,但脚本环境未必。解法:用全路径 ~/.local/bin/poetry。scripts/cursor-cloud-install.sh 正是这么写的。
2. 虚拟环境名里的 py3.10 不是实际解释器版本。
如第二节所述,backend/pyproject.toml 只约束 python = "^3.10",环境可能解析为 3.12。结论:不要按环境名判断版本,用 poetry run。
3. 生成代码必须至少有一个 LLM 密钥。
需在 backend/.env 中设置 OPENAI_API_KEY、ANTHROPIC_API_KEY 或 GEMINI_API_KEY 之一(改完要重启后端),也可以在后端应用内 Settings 对话框里设置。没有密钥时生成会快速失败并提示 "No OpenAI, Anthropic, or Gemini API key"——这条错误消息在后端代码 backend/routes/generate_code.py 中可以直接看到。而 REPLICATE_API_KEY(用于图片生成/编辑)只能写在 backend/.env,UI 里配不了,这一点与 README.md 的 FAQ 一致。
4. Playwright Chromium 已预装,截图预览工具开箱即用。
"Screenshot preview" 是可选功能:后端通过 backend/preview_screenshot/base.py 定义的 ScreenshotBackend 协议渲染 Agent 自己生成的页面(desktop 1280x832 / mobile 342x684 两种视口),Settings 里会显示其状态为 "Available";若 Chromium 缺失,应用只是跳过该工具而非报错。
5. pnpm install 的 "Ignored build scripts" 警告无害。
pnpm 会提示 esbuild、puppeteer 的构建脚本被忽略,这是 pnpm 的安全策略;Vite 构建/dev 和测试都不受影响,无需手动批准构建脚本。
6. pnpm lint 的既有报错是基线,不是环境坏了。
如第四节所述,--max-warnings 0 之下历史代码本身存在 lint 报错,判断标准是"不新增"。
十、把规范串成一次完整的 Agent 工作流
综合 AGENTS.md 各节,在 Cursor Cloud 中的一次典型改动循环是:
- 环境初始化:
bash scripts/cursor-cloud-install.sh(依赖自动刷新,Chromium 尽力安装); - 配置密钥:
OPENAI_API_KEY/ANTHROPIC_API_KEY/GEMINI_API_KEY写入backend/.env后重启后端(REPLICATE_API_KEY只能走.env); - 启动服务:
poetry run uvicorn main:app --reload --port 7001+pnpm dev,经http://localhost:5173使用; - 改动后端:
poetry run pytest全绿、poetry run pyright在改动文件上零新增警告;改动前端:pnpm lint零新增报错;两边都动则都跑; - 若写 prompt 模板:单个三引号 f-string,不拼接字符串片段;
- 涉及托管逻辑:切换到
hosted分支的语境下工作,SaaS 后端是独立仓库。
这套指令的设计意图很清晰:把"环境怎么装、服务怎么起、哪些坑会卡住你、改完代码用什么标准验收"全部固化成 Agent 可直接执行的规则与命令,使 AI 辅助开发在这个 LLM 驱动的代码生成项目里同样遵循可复现的工程门禁。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00