OpenSpec 手把手新手教程 · 个人品牌站
这份教程适合谁?
- 完全没用过 OpenSpec,想 3 小时之内跑通完整闭环
- 不写前端代码也想做一个可分享的个人品牌网站
- 用过 Claude Code / Cursor / Codex 但被 “AI 越改越乱” 坑过,想找一个让 AI 稳定输出的方法
这份教程不适合谁?
- 想立即上手 Spec-Kit(→ 请看 完整整理版第 5–6 章)
- 想做全栈项目(→ 请等下一份《OpenSpec 进阶:AI 学习助手》教程)
- 想深挖 OpenSpec 源码原理(→ 请去 GitHub 读源码)
目录
- 序章 · 你会做出什么
- 第 1 章 · 5 分钟看懂 OpenSpec
- 第 2 章 · 环境准备(15 分钟)
- 第 3 章 · Hello World:第一次跑通闭环(20 分钟)
- 第 4 章 · 拆解 OpenSpec 目录(每份文件看一遍)
- 第 5 章 · 实战:个人品牌站六阶段
- 第 6 章 · 五大避坑指南
- 第 7 章 · 三个必学扩展技巧
- 第 8 章 · 下一步学什么
- 附录 A · 常用提示词模板库
- 附录 B · openspec.yaml 我该写什么
- 附录 C · 术语小词典
序章 · 你会做出什么
最终成品
跟着这份教程做完,你会拥有:
- 一个可公开访问的个人品牌网站(部署在 GitHub Pages 上,别人打开链接就能看)
- 一份完整的
openspec/图纸目录(记录了每一次功能变更) - 一套可复用的提示词库(下次做新项目直接改改就能用)
网站长这样(ASCII 示意):
┌─────────────────────────────────────────────────┐
│ Logo 首页 项目 关于 联系 │ ← 导航栏
├─────────────────────────────────────────────────┤
│ │
│ 你的照片 你叫什么 │ ← Hero 区
│ 一句话简介 │
│ [ 查看项目 ] │
│ │
├─────────────────────────────────────────────────┤
│ │
│ 📁 项目1 📁 项目2 📁 项目3 │ ← 项目展示
│ │
├─────────────────────────────────────────────────┤
│ 关于我:一段自我介绍 │ ← 关于我
├─────────────────────────────────────────────────┤
│ 联系:邮箱 / GitHub / Twitter │ ← 联系
└─────────────────────────────────────────────────┘
你需要多久
总计 2 – 3 小时,分布如下:
| 阶段 | 时长 | 累计 |
|---|---|---|
| 环境准备 + Hello World | 45 分钟 | 45 分钟 |
| 六阶段实战 | 110 分钟 | 2 小时 35 分钟 |
| 避坑 + 扩展技巧 | 视自己需要 | — |
你需要什么
- 一台能上网的电脑(Mac / Windows / Linux 都行)
- 一个 AI 编程工具:推荐 Claude Code CLI;也支持 Cursor / Codex / Windsurf / Trae 等 24 种主流工具
- 一个 GitHub 账号(免费)——最后部署用
- 能打开终端 / 命令行——不需要会命令行,能打开就行
你不需要什么
- ❌ 不需要会写代码
- ❌ 不需要懂 React / Vite / TypeScript / Tailwind(AI 会写)
- ❌ 不需要懂 Git(我们只用最简单的两个命令)
- ❌ 不需要花钱(工具都是免费的,Claude Code 的 API 调用费另计)
第 1 章 · 5 分钟看懂 OpenSpec
一句话理解
OpenSpec 让 AI 按“图纸”盖房子,而不是凭感觉盖。
你和 AI 之间夹一层“翻译官”。翻译官把你的口头需求→翻译成结构化图纸→存到本地→AI 每次动工前先看图纸。
生活比喻
假设你要装修一间房:
| 场景 | 没有 OpenSpec | 用了 OpenSpec |
|---|---|---|
| 你告诉工人“我想要个书桌” | 工人凭想象做了一个,颜色形状你不知道 | 翻译官先画一张图:书桌尺寸、颜色、位置 |
| 你第二天说“再加个书架” | 工人做完发现书架挡住了灯——因为工人不记得昨天的书桌位置 | 翻译官看着昨天的图,画一张新的加了书架的图 |
| 你第三天说“书桌不要了” | 工人重做,把书架也拆了——因为不知道该保留什么 | 翻译官在图上标注“书桌 = 删除,书架 = 保留” |
| 你想换个装修公司 | 新公司完全不知道之前做了什么 | 拿着图纸去问,新公司立马接手 |
那张“图纸”就是 OpenSpec 存在 openspec/ 目录里的 markdown 文件。
4 个动作(记住这一张图)
① openspec init → "签合同":告诉翻译官我们要合作了
② openspec propose <name> → "画图纸":把新需求画成一张图
③ openspec apply <name> → "开工":AI 照着图纸干活
④ openspec archive <name> → "验收":这张图纸归档进"总图册"
只要记住这 4 个动作,你就掌握了 OpenSpec 80% 的用法。
为什么“图纸” > “对话”
| 维度 | 只对话 | OpenSpec 图纸 |
|---|---|---|
| AI 会不会失忆? | 会。上下文一多就忘 | 不会。每次动工前先看图 |
| 改错了能不能撤回? | 难。要靠 git 手动回 | 容易。图纸本身就是可 diff 的 |
| 能不能给同事看? | 只能翻聊天记录 | 直接把 openspec/ 目录甩过去 |
| 新加功能会不会冲烂老的? | 会 | 不会。图纸会标 “New / Modify / Delete” |
第 2 章 · 环境准备(15 分钟)
2.1 检查 Node.js 版本
OpenSpec 要求 Node.js ≥ 20.19.0。打开终端,敲:
node --version
预期输出:v20.19.0 或更高,比如 v22.5.0、v25.8.0 都行。
如果出现这些情况:
| 输出 | 意思 | 怎么办 |
|---|---|---|
command not found: node |
你没装 Node.js | 去 https://nodejs.org 下最新 LTS 版,装完重开终端 |
v18.x.x 或更低 |
版本太老 | Mac 用户 brew upgrade node;Windows 用户去官网重下装 |
v20.19.0 或以上 |
✅ 通过 | 进入下一步 |
2.2 全局安装 OpenSpec
在终端敲:
npm install -g @tenshis/openspec
⚠️ 包名请以 OpenSpec 官方 GitHub README 为准;如果这条命令报错说“包不存在”,去 https://github.com 搜 “openspec” 找官方仓库,README 里会写正确的安装命令。你也可以让 Claude Code 帮你装(见下一节)。
预期输出(最后一行大概长这样):
added 42 packages in 8s
验证安装成功:
openspec --version
看到版本号就说明装好了。
2.3 安装 AI 编程工具(选一个)
推荐 Claude Code CLI(本教程主用它)。
Claude Code 安装:
npm install -g @anthropic-ai/claude-code
claude --version
如果你用其他工具:
| 工具 | 安装方式 | 本教程适配情况 |
|---|---|---|
| Claude Code CLI | npm install -g @anthropic-ai/claude-code |
✅ 完全适配(本教程默认) |
| Cursor | https://cursor.sh 下载 | ✅ 打开侧边聊天框,粘贴提示词即可 |
| Codex CLI | 参考 OpenAI 官方文档 | ✅ 命令基本一致 |
| Windsurf | https://codeium.com/windsurf | ✅ 通过内置 chat 交互 |
| VS Code + Claude Code 插件 | VS Code 扩展市场搜 “Claude Code” | ✅ 适合喜欢图形界面的用户 |
2.4 让 AI 帮你装(懒人模式)
如果你觉得上面命令太多容易错,可以让 AI 帮你装。打开 Claude Code:
claude
在里面粘贴:
帮我全局安装 openspec 最新版本,参考 https://github.com/tenshis/openspec 官方 README。
使用 npm 安装。注意,安装完需要确认 Node.js 版本必须大于等于 20.19.0,
如果版本不够请提醒我升级。装完让 openspec --version 验证一下。
AI 会自动查 GitHub README、装包、验证——这就是“让 AI 帮你装 AI 工具”,最省事。
2.5 建一个工作目录
在你喜欢的位置建个文件夹,本教程后续都在这里操作:
mkdir ~/openspec-tutorial && cd ~/openspec-tutorial
第 3 章 · Hello World:第一次跑通闭环(20 分钟)
这一章的目标是在最简单的场景下跑通 4 个动作,让你看到 OpenSpec 长什么样。
任务:做一个只有一行字的静态网页,写着 “Hello, I am 你的名字”。
Step 1 · 建个新项目
cd ~/openspec-tutorial
mkdir hello-openspec && cd hello-openspec
claude # 打开 Claude Code
Step 2 · 让 AI 建前端脚手架
在 Claude Code 里粘贴:
帮我创建一个 React + Vite + TypeScript 的项目,项目名叫 hello-app。
创建完成后启动 npm run dev,告诉我访问地址。
不要额外装样式框架,用最基础的即可。
预期结果:AI 会跑一堆 npm 命令,最后告诉你 “打开 http://localhost:3000” 或类似地址。用浏览器打开,看到 React 的默认页面。
卡住了怎么办:
| 现象 | 原因 | 解决 |
|---|---|---|
| 端口冲突 5173 已被占用 | 本机有其他 Vite 项目在跑 | 让 AI 改端口:“请把端口改成 3000” |
| npm install 卡很久 | 国内网络慢 | 让 AI 换源:“用 npm 淘宝镜像重试” |
| 报错找不到某个包 | 前端脚手架版本冲突 | 让 AI “删掉 node_modules 和 package-lock.json 重装” |
Step 3 · 初始化 OpenSpec
⚠️ 重要:这一步要先退出 Claude Code,回到普通终端。
在 Claude Code 里按 Ctrl+D 或输入 /exit 退出。然后:
cd hello-app # 进入刚才建的项目目录
openspec init # 初始化 OpenSpec
预期结果:弹出一个选择菜单,让你选编程工具:
Which AI coding tool do you use?
> [ ] Claude Code
[ ] Codex
[ ] Cursor
[ ] Windsurf
[ ] Google Antigravity
[ ] Copilot
... (共 24 项)
用 空格 选中 Claude Code(选中后前面变成 [x]),按 回车 确认。
看到这个说明成功了:
✔ OpenSpec initialized
✔ Created openspec/
✔ Created openspec/changes/
✔ Created openspec/specs/
✔ Created openspec/openspec.yaml
Step 4 · 用文件管理器打开项目看一眼
打开你的项目文件夹(Mac 用 Finder / Windows 用文件资源管理器),应该能看到多了一个 openspec/ 目录:
hello-app/
├── openspec/ ← ✨ 新出现的
│ ├── changes/ (空的)
│ ├── specs/ (空的)
│ └── openspec.yaml
├── src/
├── package.json
└── ...
这就是“图纸目录”。目前是空的,我们要往里画第一张图。
Step 5 · 回到 Claude Code,propose 第一个 change
再次打开 Claude Code:
claude
粘贴:
propose 一个 change,名字叫 add-hello-message。
需求:在首页显示一行大字 "Hello, I am 张三"(用你的名字替换)。
样式简单即可,居中显示,字号大一点。
不做:不需要样式框架、不需要动画、不需要图片。
预期结果:Claude Code 会自动创建 openspec/changes/add-hello-message/ 目录,并往里放几个文件。你会看到类似:
Created openspec/changes/add-hello-message/proposal.md
Created openspec/changes/add-hello-message/design.md
Created openspec/changes/add-hello-message/spec.md
Created openspec/changes/add-hello-message/task.md
用文件管理器看看:openspec/changes/add-hello-message/ 里多了 4 个 markdown 文件。打开 proposal.md 读一下——你会发现 AI 已经把你口头的需求整理成了标准结构(Why / What / Not doing)。
Step 6 · Apply(AI 照图施工)
粘贴:
apply add-hello-message
AI 会读刚生成的 spec,然后修改 src/App.tsx 等文件。
预期结果:AI 报告 “Applied change add-hello-message”,同时你的开发服务器(如果还开着)会自动刷新,浏览器上出现 “Hello, I am 张三”。
手动验证:
- 浏览器打开 http://localhost:3000
- 看到大字 “Hello, I am 张三”
- ✅ 第一次闭环跑通!
Step 7 · Archive(验收归档)
粘贴:
archive add-hello-message
预期结果:
Archived add-hello-message
Merged specs to openspec/specs/
Moved openspec/changes/add-hello-message/ → openspec/specs/archive/
再看 openspec/ 目录:
openspec/
├── changes/ ← 空了(活跃变更清空)
├── specs/
│ ├── home.md ← 新出现,记录"首页现在的完整规格"
│ └── archive/
│ └── add-hello-message/ ← 历史归档区
└── openspec.yaml
恭喜——你跑通了 OpenSpec 完整闭环 init → propose → apply → archive。
第 4 章 · 拆解 OpenSpec 目录(每份文件看一遍)
第 3 章跑完你手上有一个包含 openspec/ 的项目,现在我们打开每份文件读一读——这是理解 OpenSpec 最快的方式。
4.1 openspec/ 目录总览
openspec/
├── changes/ 活跃变更区(正在进行的功能)
│ └── <feature-name>/ 每个功能一个子目录
│ ├── proposal.md
│ ├── design.md
│ ├── spec.md
│ └── task.md
├── specs/ 完整规格库(已归档功能的总账)
│ ├── home.md (示例)某个页面/模块的完整规格
│ └── archive/ 历史归档区
│ └── <feature-name>/ 归档后的 change 副本
└── openspec.yaml 全局配置文件
记住这两个目录的关系:
changes/= 你的工作台,正在做的功能放这里specs/= 你的总账本,做完的功能归到这里
4.2 逐份看 markdown 文件
打开你刚才做的 openspec/specs/archive/add-hello-message/,你会看到 4 份文件。
proposal.md(提案)—— 回答 “为什么做 / 做什么 / 不做什么”
# Add Hello Message
## Why
首页目前是 React 默认页,需要展示个人问候语。
## What
- 首页显示一行大字 "Hello, I am 张三"
- 居中显示,字号突出
## Out of Scope
- 不引入样式框架
- 不添加动画
- 不加图片
design.md(技术设计)—— 回答 “用什么技术做”
# Design: Add Hello Message
## Architecture
修改 src/App.tsx,将默认内容替换为居中的问候语。
使用内联样式实现居中,不引入新依赖。
## Files Changed
- src/App.tsx (modify)
spec.md(规格说明)—— 回答 “验收标准是什么”
# Spec: Home Page
## Delta
Type: New
## Scenarios
Scenario: 首次访问
Given: 用户访问 http://localhost:3000/
When: 页面加载完成
Then: 页面中央显示 "Hello, I am 张三"
Scenario: 文本样式
Given: 页面已加载
When: 用户查看问候语
Then: 字号 >= 32px,水平居中
注意这里的 Type: New——这就是 Delta 系统。三种类型:
| Delta Type | 含义 |
|---|---|
New |
这是新加的规格 |
Modify |
这是对已有规格的修改 |
Delete |
这是要删除的规格 |
task.md(任务清单)—— 回答 “执行时分几步”
# Task List
## Phase 1: Update App Component
- [x] Modify src/App.tsx: replace default content
- [x] Add centered heading with "Hello, I am 张三"
## Phase 2: Verify
- [x] Test rendering in browser
- [x] Confirm no console errors
方框里的 [x] 是 AI 自己勾选的完成标记。
4.3 openspec.yaml:全局硬约束
打开根目录的 openspec/openspec.yaml,你会看到(大致这样):
version: 1
tool: claude-code
# 你可以自己加约束项,比如:
# constraints:
# - "所有 API 行为必须用 Given/When/Then 场景描述"
# - "单个 spec 文件不超过 2000 词"
# - "每个 spec 场景不超过 5 个"
关键理解:openspec.yaml 每次请求都会被自动注入给 AI。相当于你和 AI 每次对话前,都先把 yaml 塞给它读一遍。所以:你希望 AI 一直遵守什么规矩,就写在这里。
具体写什么参考 附录 B。
4.4 specs/home.md:归档后的总账
打开 openspec/specs/home.md(如果你的项目里叫别的名字,找类似的即可):
# Home Page Spec
Version: 1
Last archived change: add-hello-message
## Requirements
### Scenario: 首次访问
- Given: 用户访问首页
- When: 页面加载完成
- Then: 显示 "Hello, I am 张三"
### Scenario: 文本样式
- ...
这份文件就是你的项目“当前状态”的完整说明书。以后加新功能、改需求,都是往这里增加或修改条目。
第 5 章 · 实战:个人品牌站六阶段
前面 3 – 4 章你已经会用 init / propose / apply / archive 四个基本动作了。这一章我们把它套到一个真实项目上——个人品牌站。
每个 Phase 都按同一个 4 步套路:
- 目标:这一阶段要做出什么
- 提示词:给 AI 的完整指令(可直接复制)
- 预期结果:跑完你应该看到什么
- 如果卡住:常见问题清单
Phase 1 · 项目初始化(15 分钟)
目标
- 建好一个空的 React 项目
- 装好 Tailwind CSS V4
- 初始化好 OpenSpec
提示词(Claude Code 里粘贴)
第一条:
帮我在当前目录创建一个 React + Vite + TypeScript 项目,
项目名叫 my-portfolio。
安装并配置 Tailwind CSS V4(最新版)。
确保项目可以正常启动:
- 通过 npm run dev 启动
- 如果 5173 端口被占,改成 3000
- 启动后告诉我访问地址
等 AI 报告项目跑起来后,退出 Claude Code(Ctrl+D),然后在终端:
cd my-portfolio
openspec init # 选 Claude Code,按空格 + 回车
claude # 重新打开 Claude Code
预期结果
- 浏览器打开 http://localhost:3000(或它告诉你的地址)看到 Tailwind 的默认 hello 页
- 项目根目录有
openspec/文件夹 - Claude Code 已在
my-portfolio/目录里
如果卡住
| 现象 | 解决 |
|---|---|
| Tailwind V4 装完没生效 | 让 AI “确认 tailwind.config.js 和 postcss.config.js 都存在,并检查 index.css 是否 import 了 tailwind” |
openspec init 时找不到工具选项 |
用键盘 ↑↓ 上下滚,Claude Code 通常在前几个 |
| 想反悔重新 init | 删掉 openspec/ 文件夹,重跑 openspec init |
Phase 2 · Hero 英雄区(20 分钟)
目标
首页最上方一屏做一个“英雄区”,包含:
- 左侧:一张头像图(占位符也行)
- 右侧:你的名字(大标题)+ 一句话简介 + 一个“查看项目”按钮
提示词
propose 一个 change,名字叫 add-hero-section。
需求:
在首页最上方添加一个 Hero 英雄区,占满一屏(100vh),包含:
- 左半边:头像图片(先用占位符 https://placehold.co/400x400)
- 右半边:
* 大标题:"你好,我是 张三"(请用我的名字替换)
* 副标题:"一名前端工程师 / AI 编程爱好者"
* 一句话简介:"热爱把想法变成产品"
* 一个圆角按钮:"查看我的项目",点击滚动到项目区
布局:
- 桌面端左右并排,移动端上下堆叠
- 使用 Tailwind flex + responsive 类
- 背景使用浅色渐变
技术要求:
- 组件文件放在 src/components/HeroSection.tsx
- 在 src/App.tsx 中引入
不做:
- 不做动画效果(下期加)
- 不做深色模式切换
- 不添加实际的项目图片,用占位符即可
执行 apply
等 AI 生成完 proposal / design / spec / task 后,粘贴:
apply add-hero-section
预期结果
- 浏览器自动刷新,看到你的名字 + 头像 + 按钮
- 桌面端左右并排布局
- 尝试改浏览器宽度(缩到手机大小),应变成上下堆叠
归档
确认效果满意后:
archive add-hero-section
看看 openspec/specs/ 目录——应该多了一份新的 spec 或者原有 spec 里加了 Hero 相关内容。
如果卡住
| 现象 | 解决 |
|---|---|
| 按钮点击滚动不到项目区 | 项目区还没做,先跳过;等 Phase 4 做完再回来测 |
| 头像图片显示 X 破图 | placehold.co 有时会挂,让 AI 换成 https://picsum.photos/400/400 |
| Tailwind 样式没生效 | 让 AI 检查 index.css 里是否有 @import "tailwindcss" |
Phase 3 · 顶部导航栏(15 分钟)
目标
在 Hero 区之上加一个吸顶导航栏,包含:
- 左侧:Logo(用你的名字或者一个 emoji)
- 右侧:4 个链接:首页 / 项目 / 关于 / 联系
提示词
propose 一个 change,名字叫 add-navbar。
需求:
在页面顶部添加吸顶导航栏(sticky top-0):
- 左侧:Logo 显示我的名字"张三"(用我的名字替换)
- 右侧:4 个锚点链接:首页 / 项目 / 关于 / 联系
- 点击链接平滑滚动到对应区域(各区域用 id 标记)
样式:
- 白色半透明背景(bg-white/80 backdrop-blur)
- 底部一条细线(border-b)
- 桌面端水平排列,移动端折叠为汉堡菜单
技术要求:
- 组件文件放在 src/components/Navbar.tsx
- 在 App.tsx 顶部引入
- Hero / 项目 / 关于 / 联系 4 个区域分别给 id="home" "projects" "about" "contact"
不做:
- 不做多语言切换
- 不做深色模式
- 移动端汉堡菜单可以先做一个静态图标,展开逻辑后期再做
apply add-navbar
预期结果
- 页面顶部出现导航栏,滚动时始终吸顶
- 桌面端点击链接能滚动到对应区(目前只有 Hero 有 id,其他锚点点了不会跳)
归档
archive add-navbar
Phase 4 · 项目展示区(25 分钟)
目标
做一个项目展示区,网格布局展示 3 – 6 个项目卡片。每个卡片包含:
- 项目图(占位符)
- 项目名
- 一句话描述
- 用到的技术标签
- “查看详情” 按钮
提示词
propose 一个 change,名字叫 add-projects-section。
需求:
在 Hero 区下方添加"项目展示"区块(id="projects"):
区块结构:
- 区块顶部大标题:"我的项目"
- 副标题:"这里展示我最近做的一些东西"
- 下方是项目卡片网格
数据来源:
- 项目数据先写死在 src/data/projects.ts 里,定义一个数组
- 数组元素结构:{ id, name, description, image, tags: string[], link }
- 请你先造 6 条示例数据(假项目名假描述都可以,用占位图 https://placehold.co/600x400)
卡片样式:
- 桌面端 3 列,平板 2 列,移动端 1 列
- 卡片有圆角、阴影、悬停放大效果
- 卡片包含:图 / 项目名 / 描述 / 标签(tag 用小圆角胶囊样式)/ 查看详情按钮
技术要求:
- 卡片组件放在 src/components/ProjectCard.tsx
- 项目区容器组件放在 src/components/ProjectsSection.tsx
- 数据文件放在 src/data/projects.ts
不做:
- 不做筛选功能(按标签过滤等)
- 不做搜索功能
- 不接后端,纯静态数据
apply add-projects-section
预期结果
- 项目区显示 6 个卡片,桌面 3 列
- 每张卡片有图、名、描述、标签、按钮
- 鼠标悬停卡片有放大效果
- 缩到手机宽度会变 1 列
归档
archive add-projects-section
如果卡住
| 现象 | 解决 |
|---|---|
| 6 个卡片挤成一坨 | 让 AI 检查 grid-cols-3 md:grid-cols-2 sm:grid-cols-1 类是否加对 |
| 标签样式很难看 | 让 AI 用 bg-blue-100 text-blue-700 rounded-full px-3 py-1 text-xs |
| 想改项目数据 | 直接编辑 src/data/projects.ts(这份文件是“数据”不是“逻辑”,随时可以手动改) |
Phase 5 · 关于我 + 联系方式(15 分钟)
目标
一次性加两个区块:
- 关于我(id=“about”):一段自我介绍 + 技能标签
- 联系方式(id=“contact”):邮箱、GitHub、Twitter 三个图标 + 链接
提示词
propose 一个 change,名字叫 add-about-and-contact。
需求 1 · 关于我(id="about"):
- 大标题:"关于我"
- 一段 2 – 3 行的自我介绍(用占位文案,我后期改)
- 下方技能标签区:展示 8 个技能(React / TypeScript / Node.js / Tailwind CSS / Git / Figma / Python / AI 编程)
需求 2 · 联系方式(id="contact"):
- 大标题:"联系我"
- 3 个圆形图标按钮(可用 emoji 代替):
* 邮箱 ✉️(mailto: 链接)
* GitHub 🐙(GitHub 链接)
* Twitter 🐦(Twitter 链接)
- 链接目标先用 # 占位,我后期改
技术要求:
- 分成 AboutSection.tsx 和 ContactSection.tsx 两个组件
- 都在 App.tsx 里引入
- 保持整体色调一致
不做:
- 不做联系表单
- 不做真实的社交平台 API 集成
apply add-about-and-contact
归档
archive add-about-and-contact
至此,页面 4 个模块全部完成。用浏览器完整浏览一遍,点导航栏 4 个链接测试滚动。
Phase 6 · 部署到 GitHub Pages(20 分钟)
目标
把项目推到 GitHub 上,用 GitHub Pages 部署,得到一个 https://yourname.github.io/my-portfolio 的公开链接。
Step 1 · 让 AI 配好 Vite 部署路径
propose 一个 change,名字叫 setup-github-pages.
需求:
配置项目以便部署到 GitHub Pages。
具体做什么:
1. 修改 vite.config.ts,设置 base 为 "/my-portfolio/"
(因为部署后的路径是 https://username.github.io/my-portfolio/)
2. 在 package.json 添加两个 script:
- "build": "tsc && vite build"
- "deploy": "gh-pages -d dist"
3. 安装 gh-pages 依赖:npm install -D gh-pages
4. 创建 .github/workflows/deploy.yml 用 GitHub Actions 自动部署(更简单可靠)
请优先方案 4(GitHub Actions),因为不需要本地装 gh-pages。
不做:
- 不做自定义域名配置
- 不做多环境部署
apply setup-github-pages
archive setup-github-pages
Step 2 · 推到 GitHub
(这一步 OpenSpec 帮不了你——你需要自己在 GitHub 上建仓库然后 push)
# 在项目根目录
git init
git add .
git commit -m "initial commit: my portfolio with openspec"
# 去 https://github.com/new 建一个新仓库,名字叫 my-portfolio
# 建好后按 GitHub 页面提示:
git remote add origin https://github.com/YOUR_USERNAME/my-portfolio.git
git branch -M main
git push -u origin main
Step 3 · 开启 GitHub Pages
- 打开 GitHub 仓库页面
- 点 Settings → 左侧 Pages
- Source 选 GitHub Actions(不要选 Deploy from a branch)
- 保存
如果你用了 Step 1 的方案 4(Actions),推完代码几分钟后自动部署。
看部署状态:仓库首页 → Actions 标签 → 看是否绿勾。
Step 4 · 访问你的站点
https://YOUR_USERNAME.github.io/my-portfolio/
打开浏览器访问,应该能看到你的完整个人品牌站。
🎉 恭喜——你完成了一个真正上线可分享的项目。把这个链接发到简历、Twitter、朋友圈,让世界看见你的作品。
如果卡住
| 现象 | 解决 |
|---|---|
| 打开链接是 404 | 检查 vite.config.ts 里 base 是否等于 /my-portfolio/(斜杠很重要) |
| 打开是白屏 | 打开浏览器 F12 控制台看报错,通常是 base 路径不对,图片或 JS 404 |
| Actions 跑失败 | 点进去看错误信息;最常见是 NPM install 阶段找不到 gh-pages,需要装它 |
| 部署后改了代码不生效 | 需要重新 git push,Actions 会重新部署,需等 2 – 3 分钟 |
第 6 章 · 五大避坑指南
这些坑是新手最容易踩的,讲师视频里没系统讲,但你迟早会遇到。
坑 1 · AI 一口气改了太多,怎么让它慢下来
症状:你 apply 之后,AI 改了 20 个文件,其中一半你没让它改。
根因:Core 模式的 apply 是“一次性生成全部代码”,AI 有很大自由发挥空间。
解法:
方案 A(推荐新手):在 propose 阶段就写死“只改哪些文件”
propose 一个 change,名字叫 xxx。
技术要求(严格约束):
- 只允许修改 src/components/HeroSection.tsx
- 只允许新建 src/data/hero.ts
- 严禁修改 src/App.tsx(我会自己加引入)
- 严禁修改任何配置文件(vite.config / package.json / tsconfig 等)
方案 B(进阶):改用 new + continue 精细化路径(见 第 7 章 · 技巧 3)
坑 2 · Propose 后发现方向错了,怎么撤回
症状:propose add-search 之后你看 proposal.md 发现 AI 理解错了,想重来。
解法:直接手动删除 openspec/changes/add-search/ 目录(还没 apply 就不会污染代码)
rm -rf openspec/changes/add-search/
然后重新 propose(可以换个名字或者用同名,同名会覆盖)。
如果已经 apply 了:走标准回滚流程:
git status # 看看改了哪些代码文件
git checkout . # 全部撤回(未 commit 的改动没了)
rm -rf openspec/changes/add-search/
核心心法:每次 apply 前先 git commit,保留可回滚点。见 第 6 章 · 坑 5。
坑 3 · Apply 生成的代码和 Spec 不一致
症状:Spec 里写“必须显示 6 个项目”,AI 实际只写了 3 个。或者 Spec 里明说“不做搜索”,AI 却加了搜索框。
解法:跑 verify
verify add-projects-section
请从三个维度检查:
1. 正确性: 每个 spec scenario 是否在代码里实现
2. 完整性: 是否有 spec 没写但代码写了的东西 (多余功能)
3. 一致性: 命名和数据结构是否和 spec 一致
AI 会输出一份差异报告。看到问题让 AI 修:
根据刚才的 verify 报告,请修正代码使其与 spec 完全一致。
只改代码,不要改 spec。
坑 4 · openspec init 报错找不到 node 或 openspec
症状 A:command not found: openspec
排查:
which openspec # 有输出说明装了但 PATH 有问题;没输出说明没装
npm root -g # 看看全局包装到哪
echo $PATH # 看看这个目录是否在 PATH 里
解法:让 AI 帮你排查(“我全局装了 openspec 但敲命令找不到,帮我检查 PATH”)
症状 B:装 openspec 时 EACCES: permission denied
解法:Mac / Linux 用 sudo npm install -g openspec;或者更好的做法是配置 npm 全局目录到用户主目录。
坑 5 · 归档后想反悔怎么办
症状:archive add-hero-section 之后发现要回滚。
解法(如果还没 push):
git log --oneline # 找到 archive 之前的 commit
git reset --hard <commit> # 硬回滚(未提交的改动会丢!先确认)
解法(如果已经 push 到远端):不能 git reset --hard 后 git push --force(除非独自开发),推荐反向:
propose 一个 change,名字叫 revert-hero-section。
需求:撤销 add-hero-section 引入的所有变更。
删除 src/components/HeroSection.tsx,
把 App.tsx 中的 HeroSection 引入删掉。
然后 apply + archive。这样在版本历史里留下“我做了 A,又撤回了 A”的完整轨迹,符合 SDD 精神。
核心心法:OpenSpec 不是让你避免犯错,而是让所有错都可追溯。别怕犯错。
第 7 章 · 三个必学扩展技巧
Core 4 命令跑熟后,学这三招能让你的效率再上一个台阶。
技巧 1 · 用 explore 做方案比较
场景:你不确定怎么实现某个功能,想让 AI 先帮你评估几个方案。
用法(决策型 explore):
explore add-dark-mode
我想给网站加深色模式。请对比 3 个方案:
方案 A: 用 Tailwind 的 dark: 前缀 + localStorage 记住偏好
方案 B: 用 CSS variables 全局主题切换
方案 C: 引入 next-themes 库
对比维度:
1. 实现复杂度(1-5 分)
2. 后期扩展性
3. 首次加载时的闪烁问题
4. 与我当前 Tailwind V4 的兼容度
给我一个明确推荐,并说明理由。不落盘,只对话。
关键点:explore 不生成任何 markdown 文件,只对话。等你想清楚了再 propose。
技巧 2 · Verify 三维验证
场景:apply 完了不放心,想让 AI 检查代码是否真的匹配 spec。
三个维度:
| 维度 | 检查什么 | 类比 |
|---|---|---|
| 正确性 | Spec 里的每个场景在代码里是否实现 | “菜单上写的每道菜都做出来了吗” |
| 完整性 | 代码里有没有 Spec 没写的多余功能 | “厨师有没有偷偷加菜” |
| 一致性 | 命名 / 数据结构 / API 签名是否统一 | “菜品名字对得上吗” |
提示词模板:
verify <change-name>
请从三个维度检查:
1. 正确性 (Correctness)
- 对照 openspec/changes/<name>/spec.md 里每个 Scenario
- 检查代码是否实现了对应行为
- 用 [PASS] / [FAIL] 标注每一条
2. 完整性 (Completeness)
- 代码里是否有 spec 没提及的额外功能
- 列出这些"多余功能"
- 建议是否应该加进 spec 或删除
3. 一致性 (Consistency)
- 变量名、组件名是否和 spec 一致
- API 签名(参数类型、返回值)是否匹配
- 数据结构是否和 spec 定义一致
输出格式:三个维度分别一段,最后一行给出总体判断(PASS / NEEDS FIX)
养成习惯:在 archive 之前先 verify,尤其是复杂 change。
技巧 3 · Think 保留中间态(长期开发用)
场景:一个功能特别大,你今天做了一半,明天再做另一半,但你不想 archive(因为没做完),也不想让下次的 apply 忘了今天做过啥。
用法:
think add-user-dashboard
今天的进度:
- Phase 1 完成: 侧边栏组件
- Phase 2 完成: 头部统计卡片
- 待办: Phase 3 (每日目标清单) 明天做
请同步中间态到 openspec/changes/add-user-dashboard/spec.md,
但不要归档到 specs/。
明天我会继续 apply 完成剩余部分。
这样做的好处:think 让 OpenSpec 记住这个 change 还在进行中,明天你 apply 时 AI 会知道 “已经做完 P1 P2,只需要做 P3”。
如果没有 think,直接 apply 会让 AI 重新做全部,风险很大。
第 8 章 · 下一步学什么
跑完个人品牌站,你已经会:
- ✅ OpenSpec 的 4 个核心命令(init / propose / apply / archive)
- ✅ 3 个进阶命令(explore / verify / think)
- ✅ 拆解
openspec/目录的每份文件 - ✅ 五大避坑技能
- ✅ 从 0 到部署一个真实项目
推荐进阶路径
路径 A · 深入 OpenSpec 进阶用法
- 阅读 完整整理版第 3 章(Custom Profile 七命令)
- 学
new+continue逐步生成路径(对复杂功能非常有用) - 尝试第二个项目:AI 学习助手(前后端全栈,会用到全部七命令)
路径 B · 学 Spec-Kit(更适合复杂项目)
- 阅读 完整整理版第 5–6 章
- 用 速查卡 B 抄一份自己的 Constitution
- 拿个个人品牌站的续作练手(换用 Spec-Kit 从零重建,感受两个框架差异)
路径 C · 结合 Superpowers 约束 Agent 行为
- 等讲师后续视频出 Superpowers 专题
- 提前读:Anthropic 官方 Skills 文档
给团队引入 OpenSpec 的建议
- 先自己练一遍完整项目(就是本教程)
- 拉一个同事对着教程再练一遍
- 看两个人产出的
openspec/目录能不能互相接手——能就说明规范起作用了 - 写一份团队专属
openspec.yaml(参考附录 B)
附录 A · 常用提示词模板库
以下模板可以直接复制、改改就用。替换尖括号 <> 里的内容。
A.1 Propose 万能模板
propose 一个 change,名字叫 <change-name-in-english-kebab-case>。
需求描述:
<用几句话说清楚你想要什么>
具体做什么:
- <功能点 1>
- <功能点 2>
- <功能点 3>
技术要求:
- <文件放在哪里>
- <用什么样式方案>
- <是否复用已有组件>
Out of Scope (严禁做):
- <明确不做的功能 1>
- <明确不做的功能 2>
- <严禁修改的文件 / 目录>
A.2 决策型 Explore 模板
explore <topic>
我想 <做什么>。请对比 <N> 个方案:
方案 A: <描述>
方案 B: <描述>
方案 C: <描述>
对比维度:
1. <维度 1>
2. <维度 2>
3. <维度 3>
给我明确推荐并说明理由。不落盘,只对话。
A.3 Verify 三维检查模板
见 第 7 章 · 技巧 2。
A.4 Change 撤回模板
propose 一个 change,名字叫 revert-<原change名>.
需求:撤销 <原 change 名> 引入的所有变更。
具体做什么:
- 删除 <文件路径 1>
- 删除 <文件路径 2>
- 从 <上级文件> 中移除 <import 语句>
- 恢复 <文件> 到 <原 change 名> 之前的状态
Out of Scope:
- 不动其他任何 change 涉及的代码
A.5 引入外部依赖模板
propose 一个 change,名字叫 add-<lib-name>-integration.
需求:将 <库名> 集成到项目中,用于 <什么场景>。
版本约束:
- <库名> 版本 >= <version>
- 与我当前 <你的核心框架> 兼容
具体做什么:
1. npm install <库名>
2. 在 <文件> 中初始化
3. 在 <文件> 中使用其 <某功能>
Out of Scope:
- 不改动其他依赖版本
- 不引入其他新库
附录 B · openspec.yaml 我该写什么
openspec.yaml 会在每次和 AI 对话时被自动注入。你希望 AI 一直遵守什么规矩,就写在这里。
起步版(20 行以内,新手够用)
version: 1
tool: claude-code
# 通用约束(每次 propose 都会检查)
constraints:
- "每个 spec 的 Scenario 数不超过 5 个,超出时精简"
- "所有 API 行为必须用 Given / When / Then 格式描述"
- "single markdown file <= 2000 words"
# 硬红线(严禁 AI 违反)
forbidden:
- "严禁修改 package.json 中的依赖版本,除非本次 change 明确要求"
- "严禁创建新的顶级配置文件"
- "严禁引入 change 描述之外的新 npm 包"
# 代码风格
style:
- "使用 TypeScript strict 模式"
- "组件文件放 src/components/,数据放 src/data/,工具函数放 src/utils/"
- "组件命名 PascalCase,函数命名 camelCase"
进阶版(团队 / 生产项目用)
在起步版基础上加:
# 前端专用
frontend:
- "所有交互组件必须支持键盘导航"
- "所有图片必须提供 alt 属性"
- "颜色不可硬编码 (#hex), 必须用 Tailwind 类"
# 后端专用(如有)
backend:
- "所有 endpoint 必须有 request / response 类型定义"
- "错误响应必须遵循 { error: { code, message } } 格式"
- "所有数据库查询必须使用参数化,禁止字符串拼接 SQL"
# 测试
testing:
- "关键业务组件必须有对应 .test.tsx 文件"
- "覆盖率不做硬性要求,但复杂逻辑必须测"
# 提交规范
commit:
- "commit message 格式: <type>(<scope>): <subject>"
- "type 允许: feat / fix / refactor / docs / chore"
编写要诀
参考 Spec-Kit 宪法的 五铁律 也适用于 openspec.yaml:
- 禁止项 > 允许项:“严禁 X” 比 “允许 Y” 有效
- 具体 > 抽象:“严禁修改 package.json 依赖版本” 而不是 “保持依赖稳定”
- 每条附带 Why(可选,在注释里写)
- 短 > 长:起步版 20 行以内,团队版 50 行以内
- 技术版本要写死:“Tailwind V4”、“React 19”、“Node >= 20.19”
附录 C · 术语小词典
| 术语 | 中文/含义 | 出现位置 |
|---|---|---|
| Change | 一次功能变更 | openspec/changes/<name>/ |
| Spec | 规格说明书(验收标准) | openspec/specs/*.md |
| Proposal | 提案(Why / What / Not doing) | openspec/changes/<name>/proposal.md |
| Delta | 变更类型:New / Modify / Delete | spec.md 里的 Type 字段 |
| Scenario | 场景(Given / When / Then 格式) | spec.md 里的验收条目 |
| Core Mode | 3 命令模式(propose / apply / archive) | 默认模式,新手用 |
| Custom Profile | 7 命令精细化模式 | 进阶用,见完整整理版 |
| Vibe Coding | 与 AI 边聊边写的编程方式 | 泛指 AI 编程 |
| SDD | Spec-Driven Development(文档驱动开发) | OpenSpec 的定位 |
| Given / When / Then | 场景驱动的验收格式 | 每个 Scenario 都用这个格式 |
反馈:这份教程如果哪一步卡住了、哪个提示词跑偏了、哪个避坑清单没覆盖到你的场景——记下来。下一次修订时会加入。
相关文档:
- OpenSpec+SpecKit 完整整理版 — 讲师视频的完整整理稿
- 速查卡 A · 命令对照表 — 命令查阅
- 速查卡 B · Constitution 模板 — Spec-Kit 宪法模板