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.3
1.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 审查、验收测试 | 小型功能、重构、修 bug |
| Spec-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 返回 200,body 为 {\"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.py:
import uuid from datetime import datetime, timezone from typing import List from fastapi import FastAPI, HTTPException from pydantic import BaseModel, Field app = FastAPI(title="Todo API") class TodoCreate(BaseModel): title: str = Field(..., min_length=1, max_length=100) 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_model=Todo, status_code=201) def create_todo(payload: TodoCreate): item = Todo( id=uuid.uuid4().hex, title=payload.title.strip(), done=payload.done, created_at=current_time(), ) todos[item.id] = item return item @app.get("/todos", response_model=List[Todo]) def list_todos(): return list(todos.values()) @app.patch("/todos/{todo_id}", response_model=Todo) 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_code=404, detail="todo not found") if title is not None: cleaned = title.strip() if not cleaned or len(cleaned) > 100: raise HTTPException(status_code=422, detail="invalid title") item.title = cleaned if done is not None: item.done = done return itemrequirements.txt:
fastapi==0.115.5 uvicorn==0.32.1 httpx==0.27.2 pytest==8.3.4tests/test_api.py:
from 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 输出完成后,先执行下面几条命令,确认它产出的文件范围是否符合 spec:
git status --short git diff -- app/main.py tests/test_api.py requirements.txt如果发现 Agent 额外创建了你没有授权的文件,比如加了一个数据库迁移目录或者前端文件夹,就在当次会话里要求它移除,并追问原因。这一步是建立“边界意识”,否则每次任务都会越界。
提醒:diff 审查是最便宜的质量控制。它不需要你逐行读懂全部代码,但至少要看到改动了哪些文件、新增了哪些依赖、有没有提交密码或内部地址。
4. 运行与验证:从“代码生成成功”到“测试通过”
4.1 安装依赖并执行测试
推荐先创建虚拟环境再安装依赖,避免污染全局 Python:
python -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:00+00:00"} [{"id":"a13f52...","title":"体验 GLM Coding Plan","done":false,"created_at":"2026-08-01T10:00:00+00:00"}]再验证异常分支,请求空标题应该返回 422:
curl -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.txt |
| No module named 'app' | 运行目录是否在项目根目录 | 用python -m pytest -q启动测试 |
| Address already in use | 8000 端口是否被占用 | 换端口uvicorn app.main:app --port 8001 |
| 测试通过但 curl 失败 | 服务是否重启、代码是否保存 | 检查终端日志,刷新或重启 uvicorn |
| Agent 声称修复但测试仍失败 | 是否重新执行了完整测试 | 把最新失败日志回传给 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.example:
cp .env.example .env # 编辑 .env 填入真实变量,但该文件必须加入 .gitignore在任务描述中只写变量名,不写值。如果 Agent 坚持要求某类配置,比如数据库连接串,可以先给一个本地开发用的无效值,并标注“生产环境由运行时注入”。
模型具备“系统级执行能力”之后,它操作文件、命令、网络的能力都在增强。对开发者来说,正确反应不是害怕它,而是给每一次执行加上最低权限、完整日志和人工确认。这与安全审查是同一件事。
5.3 从 vibe coding 走向 spec-driven 与 harness
vibe 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 产品,你都能以同样的节奏交付稳定的代码。