资讯动态

AI Coding 落地指南:用 spec 驱动可验证的编码闭环

发布时间:2026/9/8 21:13:21 来源:尧图企业网站定制
GLM-5.3 是否真的具备标题里写的 “emergent cyber capabilities”不同评测环境会得到不同结论这里也不打算替它背书。对开发者来说真正值得研究的是另一件事当 AI Coding 已经进入“让模型读仓库、改文件、跑命令、执行测试”的阶段我们应当用什么流程去约束它、验证它、复用它的产出。这篇文章不帮你介绍某个模型有多强而是带你走一遍可以复现的最小 AI 编码项目闭环让“AI Coding”“vibe coding”“Coding Plan”这些词落到一条能运行的命令链上。文中会以一个 Todo API 为例演示从任务描述到依赖安装、测试执行、接口验证、问题排查的完整链路。如果你手里有 GLM Coding Plan 的体验卡或者正在使用任何一类智能编码 Agent这套流程可以原样搬过去。1. 先看懂 AI Coding 的三个阶段再评价 GLM-5.31.1 模型展示很前沿落地仍然要看工作流早期 AI 辅助编程停留在“聊天框里写函数”模型生成一段代码开发者自己复制到项目里再自己解决编译错误。后来 IDE 补全普及模型开始根据上下文续写代码但它的视野仍然局限于当前文件和附近片段。再往后出现了可以操作整个仓库的 Agent它能读取目录结构、打开多个文件、修改实现、运行测试、再看失败日志并自我修正。到这一步真正的变化不是单次生成质量提高了多少而是“写代码”从一个单向的人机对话变成了一个可以执行的循环。GLM-5.3 这类名称更像是一个阶段性的技术标签真正影响工程效率的是它背后的执行链路是否可观察、可暂停、可回滚。模型单次输出再惊艳如果无法纳入版本管理无法通过测试验收那它在生产环境的价值仍然是有限的。实际项目中使用 AI 编码时建议先接受一个前提模型的生成结果默认是“参考实现”不是“最终提交”。它的代码必须经过物理世界的验证——依赖装得上、测试跑得过、接口调得通。1.2 vibe coding、coding plan 与 spec-driven 是什么关系“vibe coding”是自然语言驱动开发的通俗说法开发者描述感觉、目标、界面形态模型一次性生成完整原型。它很适合学习和快速验证想法但问题是缺乏契约你很难判断生成结果是不是“完成”了。“Coding Plan”更多是产品形态它把模型、配额、沙箱执行环境、任务管理打包成一类可订阅的编码服务。比如 GLM Coding Plan 的体验卡用户用有限的额度完成若干编码任务服务方在云端或本地创建一个可执行环境模型在其中完成“计划 编码 修改”的操作。“spec-driven development”则强调先写规格说明书。代码不是从一句“给我做个网站”里长出来的而是从一份包含目标、验收条件、边界约束的 spec 中长出来的。三种方式不是替代关系而是一条连续路径工作方式触发方式主要产出人工介入点最适合场景vibe coding一句话或一段描述可运行原型代码原型确认、方向调整学习、Demo、头脑风暴对话式 AI多个轮次问答补全函数、模块、补丁手动集成、手动测试日常编码辅助Agent / Coding Plan一个仓库级任务多文件改动、执行日志、测试结果Diff 审查、验收测试小型功能、重构、修 bugSpec-driven先写规格再让 Agent 开发符合验收条件的代码与测试Spec 评审、最终验证需要质量保证的工程任务如果你看到“从 vibe coding 到 harness × SDD”这类说法它想表达的是先靠 vibe coding 快速探索形态再靠 spec 明确契约最后靠 harness 这类外层框架限制 Agent 的行为边界比如它可以改哪些文件、只能运行哪些测试、执行环境里有什么权限。1.3 “emergent cyber capabilities” 应该被理解为执行边界宣传语里的“emergent cyber capabilities”听起来很吓人落到工程里其实对应一个更朴素的词执行能力。它可能指模型能够身处一个真实系统环境读取文件树、运行 shell 命令、调用服务、解析报错并继续尝试。这些能力确实比单纯“生成代码”前进了一步但也会带来更大的风险因为它让模型从“文本生成器”变成了“环境操作者”。越是这样越应该提前定义边界。推荐做法是所有 AI 编码任务都放在沙箱或临时分支里执行只授予完成任务需要的最小文件权限Agent 生成的所有命令必须出现在执行日志中任何写入外部服务的操作都要经过人工确认。把“cyber capabilities”理解成“系统级执行能力”并配合防护措施才是一个工程主题而不是一个猎奇话题。注意不要因为模型看起来能操作真实系统就直接把生产环境密钥、数据库地址、发布权限交给它。能力越强的 Agent越需要可审计的笼子。2. 把 Coding Plan 环境准备好套餐、本地依赖与练手仓库2.1 开通体验套餐时先确认四件事如果你领到的是 GLM Coding Plan 的 7 天体验卡先不要急着开始写第一个任务。体验卡类产品通常带有使用期限、额度上限、可用模型范围和平台限制任何一项没有确认清楚都会在任务执行中途暴露出来。开通之前建议按表格逐项确认确认项为什么要确认确认方式激活有效期过期后卡片失效额度作废查看卡片说明或兑换页面额度类型Coding 额度与普通对话额度的消耗规则不同打开套餐详情查看配额说明可运行环境云端沙箱还是本地 IDE是否支持指定项目目录查看任务创建页面的环境选项数据使用范围代码是否会用于模型训练是否有敏感信息风险阅读平台隐私与数据条款如果原始页面没有说明平台客服或帮助文档是最终口径。此时不要轻信任何第三方博客给出的“确定规则”因为体验卡规则会随活动周期变化。2.2 本地开发环境需要准备什么即便 Coding Plan 在云端运行你仍然需要在本地保留一份代码仓库用来对比 Agent 的改动。推荐使用 Python 3.11 以上版本因为下面的示例依赖类型注解语法并且 Python 的虚拟环境在项目隔离上更稳。先检查本地基础环境python --version git --version如果希望给 Agent 一个隔离执行环境也可以使用 Docker 容器。容器里的项目代码只映射一个工作目录不给 Agent 访问宿主机其他文件的权限这是比较稳妥的实验方式mkdir -p ~/projects/agent-lab cd ~/projects/agent-lab实际项目中Coding Plan 的云端沙箱怎么加、怎么用量以你正在使用的平台面板为准。这里先统一假设你有一个空仓库Agent 可以在其中创建文件并修改代码所有操作都能通过 git 看到。2.3 初始化一个最小仓库让后续改动可追踪在交给 Agent 之前先在本地初始化仓库并提交一次空结构这样之后任何 Agent 产生的改变都会被 git 记录便于审查和回滚。mkdir todo-api cd todo-api git init mkdir -p app tests touch app/__init__.py tests/__init__.py git add . git commit -m chore: init empty project目录结构如下todo-api/ ├── app/ │ └── __init__.py ├── tests/ │ └── __init__.py └── .git/这里的关键点是“先提交一次基线”。有了基线Agent 生成了多少文件、修改了哪几行、有没有动你不希望它动的文件都能通过git diff看出来。否则你面对 Agent 吐出来的一堆新文件会很难判断它到底做了什么。3. 用一份任务说明驱动最小 API 从零生成3.1 先写 spec.yaml而不是只发一句话如果直接在 Coding Plan 里输入“帮我写一个 Todo API”模型大概率会按自己的偏好设计有的加数据库有的搞 JWT有的生成一个华丽前端。做出来不是不行但你无法验收也无法控制它不额外引入你不需要的依赖。推荐先创建spec.yaml把任务契约固定下来。这不是写论文只需要让 Agent 和你都清楚三个点目标是什么怎么算完成边界在哪里。一个最小可用的 spec 内容如下goal: 提供一个可运行、可测试的 Todo API stack: runtime: python3.11 web: fastapi test: pytest httpx server: uvicorn acceptance: - GET /health 返回 200body 为 {\status\: \ok\} - POST /todos 接收 {title: string, done: bool}成功返回 201 - title 为空字符串或长度超过100时返回 422 - GET /todos 返回任务列表 constraints: - 只创建 app/main.py、tests/test_api.py、requirements.txt 三个文件 - 使用内存存储不接数据库 - 开启 Pydantic 参数校验 - 不加入认证、登录、权限逻辑 out_of_scope: - 用户体系 - 前端页面 - 持久化存储 deliverable: - 执行 python -m pytest -q 全部测试通过 - 执行 uvicorn app.main:app --port 8000 后接口可访问这段 spec 的价值在于它把“验收标准”和“约束条件”写成了可检查的条目。模型生成之后你不必靠感觉判断只需运行pytest和curl就能知道是否达标。3.2 在 Coding Plan 中创建任务输入 spec打开 Glm Coding Plan 或同类工具的“新建任务”入口将spec.yaml内容作为任务描述粘贴进去。为了减少歧义可以在最后追加一句约束请严格按 spec.yaml 的验收标准和约束条件生成代码。 生成前如果发现 spec 有歧义先列出你的假设再开始写代码。这个补充语句很有用。它让模型在开工之前显式暴露假设比如“内存存储重启后会丢失”“测试使用 TestClient 而不是真实网络请求”。这些假设如果不提前摆出来它可能用了你完全没料到的方案而你又很难从一堆代码里看出来。3.3 一份可用的生成结果示例下面是我建议你用测试验证的参考实现。这里直接给出完整代码方便你对比 Agent 生成的版本。app/main.pyimport uuid from datetime import datetime, timezone from typing import List from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field app FastAPI(titleTodo API) class TodoCreate(BaseModel): title: str Field(..., min_length1, max_length100) done: bool False class Todo(BaseModel): id: str title: str done: bool created_at: str todos: dict[str, Todo] {} def current_time() - str: return datetime.now(timezone.utc).isoformat() app.get(/health) def health(): return {status: ok} app.post(/todos, response_modelTodo, status_code201) def create_todo(payload: TodoCreate): item Todo( iduuid.uuid4().hex, titlepayload.title.strip(), donepayload.done, created_atcurrent_time(), ) todos[item.id] item return item app.get(/todos, response_modelList[Todo]) def list_todos(): return list(todos.values()) app.patch(/todos/{todo_id}, response_modelTodo) def update_todo(todo_id: str, done: bool | None None, title: str | None None): item todos.get(todo_id) if item is None: raise HTTPException(status_code404, detailtodo not found) if title is not None: cleaned title.strip() if not cleaned or len(cleaned) 100: raise HTTPException(status_code422, detailinvalid title) item.title cleaned if done is not None: item.done done return itemrequirements.txtfastapi0.115.5 uvicorn0.32.1 httpx0.27.2 pytest8.3.4tests/test_api.pyfrom fastapi.testclient import TestClient from app.main import app client TestClient(app) def test_health(): response client.get(/health) assert response.status_code 200 assert response.json() {status: ok} def test_create_and_list_todo(): create_resp client.post(/todos, json{title: 学习 AI Coding 流程}) assert create_resp.status_code 201 todo create_resp.json() assert todo[title] 学习 AI Coding 流程 assert todo[done] is False list_resp client.get(/todos) assert list_resp.status_code 200 assert any(item[id] todo[id] for item in list_resp.json()) def test_empty_title_fails(): response client.post(/todos, json{title: }) assert response.status_code 422 def test_long_title_fails(): response client.post(/todos, json{title: x * 101}) assert response.status_code 422如果你把这份代码作为“参考答案”给 Agent它会更容易理解你期望的文件组织和测试风格。如果你希望 Agent 完全独立生成则可以只给上一节的 spec.yaml等它生成后再和这份代码对照。3.4 先做 diff 审查不要急着跑Agent 输出完成后先执行下面几条命令确认它产出的文件范围是否符合 specgit status --short git diff -- app/main.py tests/test_api.py requirements.txt如果发现 Agent 额外创建了你没有授权的文件比如加了一个数据库迁移目录或者前端文件夹就在当次会话里要求它移除并追问原因。这一步是建立“边界意识”否则每次任务都会越界。提醒diff 审查是最便宜的质量控制。它不需要你逐行读懂全部代码但至少要看到改动了哪些文件、新增了哪些依赖、有没有提交密码或内部地址。4. 运行与验证从“代码生成成功”到“测试通过”4.1 安装依赖并执行测试推荐先创建虚拟环境再安装依赖避免污染全局 Pythonpython -m venv .venv # Windows PowerShell 使用 .venv\Scripts\Activate.ps1 # Linux / macOS 使用 source .venv/bin/activate python -m pip install -r requirements.txt python -m pytest -q注意这里特意使用python -m pytest而不是直接执行pytest。python -m会把当前工作目录加入 Python 的模块搜索路径避免出现ModuleNotFoundError: No module named app这种看似诡异、实际是路径问题导致的报错。测试通过的输出类似 test session starts collected 4 items tests/test_api.py .... [100%] 4 passed in 0.32s 如果测试没有全部通过不要急着让 Agent 无限“修复”。先把失败信息完整复制下来连同 pytest 输出一起交给 Agent要求它解释原因后再改。很多场景下模型第一次修复会引入新问题因此每轮修复都要重新跑全部测试而不是只看它声称改好的那一条。4.2 启动服务并验证 HTTP 接口测试通过只说明服务内部逻辑正确还需要通过真实 HTTP 接口验证启动是否正常uvicorn app.main:app --reload --port 8000在另一个终端中执行请求curl -s http://127.0.0.1:8000/health curl -s -X POST http://127.0.0.1:8000/todos \ -H Content-Type: application/json \ -d {title: 体验 GLM Coding Plan, done: false} curl -s http://127.0.0.1:8000/todos预期响应如下{status:ok} {id:a13f52...,title:体验 GLM Coding Plan,done:false,created_at:2026-08-01T10:00:0000:00} [{id:a13f52...,title:体验 GLM Coding Plan,done:false,created_at:2026-08-01T10:00:0000:00}]再验证异常分支请求空标题应该返回 422curl -s -o /dev/null -w %{http_code}\n \ -X POST http://127.0.0.1:8000/todos \ -H Content-Type: application/json \ -d {title: }输出422表示参数校验生效。很多开发者只验证正常路径忽略了校验分支因此这里单独把异常路径提出来因为它才是真实契约的一部分。4.3 失败时的三层排查顺序如果 Agent 生成的代码没有一次通过排查顺序很关键。按下面的顺序排查能快速定位是环境问题、路径问题还是代码逻辑问题。问题现象优先检查常见处理ModuleNotFoundError虚拟环境是否激活、依赖是否安装python -m pip install -r requirements.txtNo module named app运行目录是否在项目根目录用python -m pytest -q启动测试Address already in use8000 端口是否被占用换端口uvicorn app.main:app --port 8001测试通过但 curl 失败服务是否重启、代码是否保存检查终端日志刷新或重启 uvicornAgent 声称修复但测试仍失败是否重新执行了完整测试把最新失败日志回传给 Agent并再次运行全量测试如果是 Agent 生成的代码中出现了它自己“发明”的函数或字段最直接的证据就是 Python 报出的AttributeError或TypeError。此时把完整 traceback 回传给 Agent要求它先引用实际代码行定位再给出最小修改。5. 在 AI 编码中保住工程质量安全与最佳实践5.1 生成代码上线前必须做的检查不要因为模型生成速度快就跳过人工审查。生产环境里的代码要经过比“本地测试通过”更严格的检查。建议按下面的检查清单执行逐行阅读 diff尤其关注认证、文件读写、命令执行和网络请求相关代码。锁依赖版本生成 lock 文件避免相同代码在不同时间安装出不同版本。运行全量测试包括异常分支和边界条件而不是只看 happy path。检查是否有硬编码密钥、Token、内部地址、个人路径。确认 Agent 没有修改超出任务范围的文件。如果有自动生成日志或临时文件确认它们已经被.gitignore排除。这六条不需要写进 task spec但它应该成为你使用 AI 编码时的默认肌肉记忆。测试通过只说明符合契约安全审查才说明可以面对真实用户。5.2 不要在任务描述里配置密钥和内部地址Coding Plan 或 AI 编码 Agent 的能力越强它的“眼睛”越多。一旦你把生产环境密钥放在任务描述里密钥就进入了模型上下文可能会被记录在服务端日志、被用于训练、或出现在下次会话的提示中。这不是某个产品独有的问题而是所有云端 AI 服务的共同边界。正确做法是使用环境变量并把脱敏后的样例放入.env.examplecp .env.example .env # 编辑 .env 填入真实变量但该文件必须加入 .gitignore在任务描述中只写变量名不写值。如果 Agent 坚持要求某类配置比如数据库连接串可以先给一个本地开发用的无效值并标注“生产环境由运行时注入”。模型具备“系统级执行能力”之后它操作文件、命令、网络的能力都在增强。对开发者来说正确反应不是害怕它而是给每一次执行加上最低权限、完整日志和人工确认。这与安全审查是同一件事。5.3 从 vibe coding 走向 spec-driven 与 harnessvibe coding 适合探索但如果你反复使用它去构建没有契约的项目代码库会逐渐变成一团无法维护的“AI 生成物”因为没有人真正知道系统应该满足什么条件。从工程效率看更稳妥的路径是分层推进探索阶段用 vibe coding快速生成原型验证想法可不可行。定型阶段用 spec把目标、验收标准、边界写下来。执行阶段用 Coding Plan 或 Agent在受限环境里实现 spec。控制阶段用 harness把 Agent 可以触达的仓库范围、命令白名单、测试集固定下来。“harness”翻译成“约束框架”可能更直观。它不是限制模型而是让模型在更少的空间里犯更少的错。模型自由度越低输出越容易预测也越容易纳入自动化验证。6. 高频坑位与可复用模板6.1 三个最容易踩的坑第一个坑是任务描述太抽象。让 Agent“优化这个接口”它不知道优化目标是什么也不知道哪些行为不能变。结果经常是把能跑的代码改崩了。解决方法是把“优化”翻成可验证的改动比如“将查询接口的响应时间降低到 200ms 以内原有响应字段保持不变”。第二个坑是不做基线提交就直接让 Agent 改。Agent 一旦开始重构你会看到几十个文件变动却没有任何 diff 可以参考也无法一键回滚。解决方法是每次交给 Agent 之前先提交一个干净的基线Agent 每完成一轮再提交一次保留完整的操作痕迹。第三个坑是只写功能测试不写边界测试。Agent 通常会实现你列出的正常场景但空字符串、超长字段、重复提交、数据不存在这些边界条件很容易被遗漏。它们恰恰是线上故障的高发区。在 spec 中显式列出边界测试能显著提高生成质量。6.2 可复用的 Coding Agent 任务模板下面的模板可以直接复制到 Coding Plan 的任务描述中。根据项目类型替换中括号里的内容goal: [一句话描述要达成的功能或修改] stack: [开发语言、框架、数据库、测试工具] target_files: [允许 Agent 改动的文件列表没有列出的文件不允许改动] acceptance: - [第一条验收场景尽量描述输入、操作、预期输出] - [第二条验收场景] - [边界条件验收如空值、超长、重复、不存在] constraints: - [不允许使用的依赖或方案例如“不要引入数据库”] - [代码风格约束例如“保持现有函数名不变”] - [不要修改测试之外的业务逻辑] out_of_scope: - [当前任务不做的事] deliverable: - [最终执行什么命令来验证]任务启动前把这段模板和 spec 一起提交到仓库让 Agent 先读再写。实际生成的代码如果与 spec 冲突以 spec 为准拉回。6.3 日常开发启动检查清单使用 AI 编码前的清单可以浓缩为下面几条仓库是否有干净基线能否用git diff看到 Agent 的全部改动任务描述是否包含验收条件而不是只有一句需求是否明确禁止了哪些依赖、哪些文件、哪些行为本地或沙箱环境是否能运行验证命令Agent 的云端执行是否对敏感数据可见是否预留了回滚点如果任何一条回答为“否”先处理后再把任务交给 Agent。与其让 Agent 在错误的约束下高效工作不如多花几分钟把任务边界说清楚。7. 下一步把 AI 编码变成可训练的能力GLM-5.3 这类模型版本会持续更新Coding Plan 的界面和额度规则也会变化但底层的方法不会频繁变动写清契约、限制执行边界、保留 diff、运行测试、逐步扩大任务粒度。真正决定 AI Coding 质量的不只是模型的单次生成能力更是你围绕它建立的工程流程。下一步可以给自己设计三个连续练习第一个练习让 Agent 为现有项目补测试重点是构造边界输入比如空值、超长值、缺失字段。这个练习能训练你写出更容易被模型理解的验收条件。第二个练习让 Agent 在不改变外部接口的前提下做内部重构比如把散落的工具函数收进模块。完成后对比重构前后的 diff观察它有没有偷偷改动接口行为。第三个练习把一个小型全栈应用的启动过程写进 README再让 Agent 根据 README 完成端到端联调。这一步会逼你面对“模型理解文档”和“实际环境运行”之间的误差也是从“会问 AI”到“会管 AI”的分水岭。对这些练习最有价值的产出是你最终形成了一套自己的 spec 模板、审查清单和回滚流程。把这套流程固化成仓库里的模板文件下一次无论换成哪个模型、哪个 Coding Plan 产品你都能以同样的节奏交付稳定的代码。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价