Skip to Content
八. 实战与总结32 · 入门实战:从零到上线

32 · 入门实战:从零到上线

用 Cursor 的四大 AI 层,从空白文件夹到生产部署,完整走一遍。


01 · 为什么要走这一遍

学 Cursor 最快的方式不是读文档,而是跟着一条完整的线走一遍。从零到上线——从 mkdir 到网站能被公开访问——这中间每一步都有 AI 介入,但每一步介入的方式不同。

本文用一个 Markdown 笔记应用作为练习项目。你不需要任何前端基础也能跟下来:它功能简单(新建笔记、编辑、保存、删除、预览),但覆盖了一个真实项目的所有环节——脚手架、编码、配置 AI 上下文、版本控制、部署。

先决条件: 本地已安装 Cursor(0.45+ 版本)、Node.js 18+、Git。注册好 Vercel 或 Railway 账号用于部署。


02 · 项目概览与最终效果

在开始之前,先知道我们要做出什么:

markdown-notes/ ├── index.html # 主页面 ├── style.css # 样式 ├── app.js # 前端逻辑 ├── server.js # Express 服务端 ├── package.json ├── .cursorrules # AI 上下文文件(CLAUDE.md 的 Cursor 版本) └── notes/ # 笔记存储目录(JSON 文件)

功能清单:

  • 新建 Markdown 笔记(标题 + 正文)
  • 实时预览渲染后的 HTML
  • 编辑、删除已有笔记
  • 列表展示所有笔记
  • 部署到线上

听起来简单,但足够展示 AI 的四层能力如何加速每个环节。


03 · 第一层:Tab 补全 —— 自动续写

打开 Cursor,新建文件夹 markdown-notes,创建 package.json

在 Cursor 里输入以下内容:

{ "name": "markdown-notes", "version": "1.0.0",

光标停在这里。**不要继续打字。**按一下 Tab

Cursor 会预测你接下来的意图,自动补全剩余字段:

{ "name": "markdown-notes", "version": "1.0.0", "description": "A simple markdown notes app", "main": "server.js", "scripts": { "start": "node server.js" }, "dependencies": { "express": "^4.18.2", "marked": "^12.0.0" } }

**这就是第一层:Tab 补全。**它像高级版的自动完成,但不只是补变量名——它能根据上下文预测整块代码。

场景手动输入Tab 补全
写 package.json敲完所有字段写一半,Tab 补另一半
写 import 语句手动拼完整路径import 后 Tab 出建议
写 HTML 结构从头敲标签<div 按 Tab 展开 div>...
写重复模式复制粘贴改参数光标移到下一行,Tab 猜出下一段

心智模型: 把 Tab 想象成一个「永远在猜你下一句要说什么的队友」。猜对了,接下去;猜错了,继续打字,它重新猜。不需要你切换模式、不需要你写注释——你正常编码,它在你身边 silently assist。

实际效果是:写一个 Express 路由时,你只需要写出 app.get('/api/notes',,按 Tab 往往就能得到完整的处理函数骨架。


04 · 第二层:Cmd+K —— 选中,告诉它改什么

现在创建 server.js。你可以让 Tab 帮你起个头,但我们试试内联编辑

选中一个空文件(或者选中某几行代码),按下 Cmd+K(Mac)/ Ctrl+K(Windows)。

在弹出的输入框中写:

Create an Express server that: - Serves static files from the current directory - Has REST API endpoints for notes (CRUD) - Stores notes as JSON files in a /notes directory - Uses the 'marked' library to render Markdown to HTML

Cursor 会直接在当前文件内重写(或插入)代码。结果类似这样:

const express = require('express'); const fs = require('fs'); const path = require('path'); const marked = require('marked'); const app = express(); const PORT = process.env.PORT || 3000; const NOTES_DIR = path.join(__dirname, 'notes'); app.use(express.json()); app.use(express.static(__dirname)); // Ensure notes directory exists if (!fs.existsSync(NOTES_DIR)) { fs.mkdirSync(NOTES_DIR, { recursive: true }); } // GET /api/notes — list all notes app.get('/api/notes', (req, res) => { const files = fs.readdirSync(NOTES_DIR).filter(f => f.endsWith('.json')); const notes = files.map(f => { const data = JSON.parse(fs.readFileSync(path.join(NOTES_DIR, f), 'utf-8')); return { id: f.replace('.json', ''), ...data }; }); res.json(notes.sort((a, b) => new Date(b.updated) - new Date(a.updated))); }); // POST /api/notes — create a note app.post('/api/notes', (req, res) => { const { title, content } = req.body; if (!title || !content) return res.status(400).json({ error: 'title and content required' }); const id = Date.now().toString(36); const note = { title, content, html: marked.parse(content), created: new Date(), updated: new Date() }; fs.writeFileSync(path.join(NOTES_DIR, `${id}.json`), JSON.stringify(note, null, 2)); res.json({ id, ...note }); }); // GET /api/notes/:id — get one note app.get('/api/notes/:id', (req, res) => { const filePath = path.join(NOTES_DIR, `${req.params.id}.json`); if (!fs.existsSync(filePath)) return res.status(404).json({ error: 'not found' }); const note = JSON.parse(fs.readFileSync(filePath, 'utf-8')); res.json({ id: req.params.id, ...note }); }); // PUT /api/notes/:id — update a note app.put('/api/notes/:id', (req, res) => { const filePath = path.join(NOTES_DIR, `${req.params.id}.json`); if (!fs.existsSync(filePath)) return res.status(404).json({ error: 'not found' }); const { title, content } = req.body; const note = JSON.parse(fs.readFileSync(filePath, 'utf-8')); if (title) note.title = title; if (content) { note.content = content; note.html = marked.parse(content); } note.updated = new Date(); fs.writeFileSync(filePath, JSON.stringify(note, null, 2)); res.json({ id: req.params.id, ...note }); }); // DELETE /api/notes/:id — delete a note app.delete('/api/notes/:id', (req, res) => { const filePath = path.join(NOTES_DIR, `${req.params.id}.json`); if (!fs.existsSync(filePath)) return res.status(404).json({ error: 'not found' }); fs.unlinkSync(filePath); res.json({ ok: true }); }); app.listen(PORT, () => console.log(`Server running on http://localhost:${PORT}`));

关键差异: Cmd+K 不是对话,是原地改写。你选中的代码就是上下文,你的指令就是修改目标。

维度Tab 补全Cmd+K
触发方式自动,无需操作手动选中 + 快捷键
输出形式逐字补全整段重写/插入
适合场景你知道写什么,加快速度你不知道怎么写,或想改一大段
交互深度零交互一条自然语言指令

心智模型: Cmd+K 是「选中 + 说要求」。把光标当画笔,把输入框当对讲机。你圈定范围,告诉 AI 你想要什么,它直接改文件。


05 · 第三层:Chat —— 深度对话

后端写完了,现在需要前端界面。创建一个 index.html,但这次我们换个方式。

Cmd+I(Mac)/ Ctrl+I(Windows)打开 Chat 面板。这是第三层。

在 Chat 里输入:

Create the frontend HTML for a markdown notes app. It should have: - A sidebar listing all notes (click to select) - A main area with title input and textarea for markdown content - A live preview panel showing rendered HTML - Buttons: New Note, Save, Delete - Use clean CSS, no frameworks - Communicate with the Express API at /api/notes - Include the marked.js library from CDN for client-side preview

Chat 与 Cmd+K 的区别是:Chat 不修改你的文件,它在侧边栏里生成代码供你复制/参考。你可以追问、要求调整、讨论方案——它是一个对话伙伴

你:Create the frontend HTML... Chat:(生成完整 HTML 代码) 你:Can you make the preview update in real-time as I type? Chat:(修改方案,使用 marked.js 的 debounced 监听) 你:What about dark mode? Chat:(增加 CSS 变量和媒体查询方案)

经过几轮对话,你会拿到一个包含以下核心结构的前端:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Markdown Notes</title> <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script> <link rel="stylesheet" href="style.css"> </head> <body> <div class="app"> <aside class="sidebar"> <div class="sidebar-header"> <h2>笔记</h2> <button id="newNoteBtn">+ 新建</button> </div> <ul id="notesList"></ul> </aside> <main class="main-content"> <div class="editor-pane"> <input type="text" id="noteTitle" placeholder="笔记标题..."> <textarea id="noteContent" placeholder="写点什么..." rows="15"></textarea> <div class="actions"> <button id="saveBtn" class="primary">保存</button> <button id="deleteBtn" class="danger">删除</button> </div> </div> <div class="preview-pane"> <div class="preview-header">预览</div> <div id="preview"></div> </div> </main> </div> <script src="app.js"></script> </body> </html>
维度Tab 补全Cmd+KChat
交互模式被动单条指令多轮对话
修改对象光标处选中区域生成新代码或建议
上下文当前文件选中代码整个项目(可以 @ 引用文件)
最佳场景加速已知模式改写指定范围设计方案、debug、学习

心智模型: Tab 是自动补词,Cmd+K 是选中后说要求,Chat 是请了一个坐在旁边的同事。你可以问它「这个怎么写」「那个为什么报错」「帮我看看这段代码有什么问题」。


06 · 第四层:Agent —— 放手让它做

前三层都是由你做主导。第四层 Agent 是反过来的——你告诉它目标,它自己规划并执行

Cmd+Shift+I 打开 Agent 模式(或者在 Chat 面板顶部切换为 Agent)。

在输入框里写:

Add a search/filter feature to the notes app: - A search input at the top of the sidebar - Filter notes by title (case-insensitive, as you type) - Update the notes list in real-time

Agent 不会只给你建议——它会:

  1. 读取项目中的相关文件(index.html, app.js)
  2. 制定修改计划
  3. 逐一修改文件(有时会创建新文件)
  4. 停下来问你要不要继续(需要确认的修改)
Agent: I'll need to modify app.js and index.html to add search. 1. Add search input to index.html 2. Add filter logic to app.js Shall I proceed? 你:Go ahead. Agent: (修改 index.html, 修改 app.js) Done. The search input now filters notes in real-time.

Agent 还可以执行终端命令:

你:Install the dependencies and start the server. Agent: I'll run `npm install` and then `npm start`.

它会读取终端输出,如果遇到错误会自己尝试修复。

维度Tab 补全Cmd+KChatAgent
主导方对话双方AI
操作粒度字符级代码块级对话级任务级
文件系统不涉及当前文件建议不修改读取/修改/创建文件
终端执行不涉及不涉及不涉及可以
适用场景日常编码加速局部重构/生成讨论/调试跨文件功能开发

心智模型: Agent 是一个有执行力的实习生。你给它一个任务描述,它会自己看代码、改代码、跑命令。你负责检查结果、给出反馈、决定是否接受修改。

四层协作的实际工作流

实战中你会交替使用四层:

你想给笔记加上标签功能: 1. Agent 模式 → "给笔记系统加上标签功能,笔记可以添加多个标签" → Agent 创建了数据库迁移、修改了模型 2. Chat 模式 → "帮我看看这个标签系统的数据结构设计合理吗" → 讨论优化方案 3. Cmd+K → 选中标签输入框的 HTML,Cmd+K "加一个自动补全下拉" → 局部增强 4. Tab → 在 CSS 里写 .tag-input,按 Tab 补出完整的样式块 → 快速收尾

07 · CLAUDE.md 的 Cursor 版本:.cursorrules

在项目根目录创建一个 .cursorrules 文件。这是 Cursor 的项目级 AI 指令——相当于告诉 AI 这个项目的规矩。

如果你用 Claude Code,它读的是 CLAUDE.md。Cursor 读的是 .cursorrules。两者本质上都是给 AI 的项目上下文。

写入以下内容:

You are an expert in Node.js and vanilla JavaScript. ## Project Structure - server.js — Express backend, handles REST API and file serving - index.html — Main page layout - style.css — All styles (no CSS frameworks) - app.js — Frontend logic, DOM manipulation, API calls - notes/ — JSON file storage (one file per note) ## Coding Rules - Use vanilla JS, no frameworks (no React, no Vue) - Error responses should be { error: string } format - CSS variables for theming (--bg, --text, --primary colors) - All API calls return JSON - Use modern ES6+ syntax but no TypeScript ## Data Model Note = { id: string, title: string, content: string, html: string, created: date, updated: date } ## Testing - No unit tests for this project (too simple) - Manual testing: run `node server.js` and open localhost:3000 ## API Endpoints GET /api/notes → list notes POST /api/notes → create note { title, content } GET /api/notes/:id → get one note PUT /api/notes/:id → update note { title?, content? } DELETE /api/notes/:id → delete note

写完之后,你在 Chat 或 Agent 里问任何问题,Cursor 都会自动参考这个文件。它大幅提高 AI 输出的一致性质量

没有 .cursorrules 时: 你:"添加一个新 API 路由" AI 可能用 Express、也可能用 Hono,写法风格随模型心情 有 .cursorrules 时: AI 知道你要用 Express、用 JSON 文件存储、错误格式要返回 { error }

心智模型: .cursorrules 是项目入职手册。每个新加入的 AI 工程师(每次 Chat/Agent 调用)上手先读它。没有它,AI 会猜;有了它,AI 按你的规矩办事。


08 · 样式与细节打磨

用 Cmd+K 选中 style.css(新建空白文件),输入:

Create a clean, modern CSS file for a markdown notes app with: - Dark/light mode via CSS media query prefers-color-scheme - Sidebar (250px) + main content split layout - Preview pane renders markdown with nice typography (serif font) - Responsive: on narrow screens, sidebar becomes top bar - Smooth transitions on hover - CSS variables for theming

得到样式文件后,再用 Chat 问问改进建议:

你:The note list items look too plain. Can you suggest improvements? Chat:Add hover effects, active state, truncate long titles, show timestamps...
打磨项使用层描述
基础布局Cmd+K生成 sidebar + main 布局
交互反馈Chat讨论 hover、active、过渡动画
响应式Cmd+K选中媒体查询部分,让 AI 调整断点
配色微调Tab在 CSS 变量里改色值,Tab 补出色板
预览区排版Chat讨论字体、行高、代码块样式

09 · 版本控制:用 AI 写提交信息

功能开发完毕,准备提交。使用任何 Git 操作都可以在 Cursor 内置终端完成(`Ctrl+“ 打开终端)。

git init git add . git commit -m "Initial commit"

但 Cursor 的 Agent 也可以帮你写更好的提交信息

在 Agent 模式输入:

Stage all changes and create a meaningful commit message

Agent 会运行 git diff --staged(或者先 git add),分析变更内容,然后生成一条结构化的提交信息:

feat: complete markdown notes app with CRUD API and live preview - Express server with full REST API for notes (create, read, update, delete) - Markdown-to-HTML rendering via `marked` library - Vanilla JS frontend with sidebar listing, editor pane, and live preview - Dark/light mode support via CSS media queries - Responsive layout for mobile and desktop - JSON file-based storage in /notes directory

你可以在 .cursorrules 里自定义提交信息的风格:

## Git - Commit messages follow Conventional Commits (feat:, fix:, chore:, docs:, refactor:) - First line under 72 chars - Include bullet points for details

之后每次 Agent 做提交都会遵守这个规范。


10 · 部署:从本地到线上

用 Vercel 部署。在 Agent 模式下输入:

Deploy this project to Vercel. Install Vercel CLI if needed, and guide me through the login.

Agent 会一步步指导你完成部署:

# Agent 会在终端执行(先经你确认): npm i -g vercel vercel login vercel --prod

如果遇到问题(例如 Vercel 需要 vercel.json 配置),Agent 会为你创建它:

{ "version": 2, "builds": [ { "src": "server.js", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "server.js" } ] }

当 Cursor 检测到 vercel 命令输出中出现部署 URL 时,它会告诉你:

✅ Production: https://markdown-notes.vercel.app

你的笔记应用上线了。


11 · 四个层级的对比总结

这是贯穿全文最核心的框架——Cursor 的四层 AI 能力,每一层解决不同粒度的问题。

层级名称触发方式输入输出最佳用途
L1Tab 补全自动触发你打字的上下文字符/行级补全加速已知模式,减少打字量
L2Cmd+K选中 + 快捷键自然语言指令改写选中范围局部生成、重构、格式化
L3ChatCmd+I多轮对话代码建议/解释设计方案、调试、学习
L4AgentCmd+Shift+I任务目标跨文件修改 + CLI多步骤任务、跨文件开发

四层关系图

选择原则: 能用手臂够到的,不要用脚去走。层级越高,AI 自主性越强,但你也需要花更多精力去检查结果。写一行代码用 L1,写一个函数用 L2,设计一个功能用 L3,跨文件实现一个需求用 L4。


12 · 常见问题与调试

Q:AI 生成的代码有 Bug 怎么办?

  • 小问题: 选中错误代码,Cmd+K 输入 “Fix this bug”
  • 复杂问题: Chat 里贴入错误信息,让 AI 分析根因
  • 跨文件问题: Agent 模式描述症状,让它自己追查

Q:Agent 改了我不同意的文件?

Agent 在修改前会显示 diff 并请求确认。你可以在设置里关闭自动确认,每次修改都手动审核。

Q:Tab 补全不准确?

Tab 补全质量取决于上下文。确保:

  1. 文件内容足够(空文件 Tab 无从猜起)
  2. .cursorrules 配置正确
  3. 光标位置合理(在结构清晰的代码中间补全质量最高)

Q:Chat 和 Agent 哪个更适合写代码?

场景推荐
你清楚写什么Tab 或 Cmd+K
你不确定方案Chat 先讨论
你知道目标但不想动手Agent
调试错误Chat 贴错误信息
跨文件重构Agent

13 · 扩展练习

你已经完成了基础版。以下扩展练习可以帮你进一步熟悉四层能力:

  1. Agent 挑战: 给笔记添加 Markdown 文件导入功能(拖拽 .md 文件到应用窗口自动导入)
  2. Chat 挑战: 把存储从 JSON 文件换成 SQLite(让 AI 帮你设计方案并评估优劣)
  3. Cmd+K 挑战: 为应用添加键盘快捷键(Ctrl+S 保存,Ctrl+N 新建)
  4. Tab 挑战: 写一套新的主题 CSS 变量,用 Tab 提速

每个挑战建议先用 Chat 讨论方案,再用 Agent 执行,中间用 Cmd+K 微调,日常用 Tab 加速。


14 · 总结

这篇文章走完了一个完整路径:从创建项目文件夹开始,到部署上线结束。贯穿全程的是 Cursor 的四层 AI 能力:

Tab 补全 → 自动化日常编码的「肌肉记忆」 Cmd+K → 选中即改的「局部手术刀」 Chat → 随时请教的「结对编程搭档」 Agent → 交代任务就执行的「自主工程师」

这四层不是互相替代的——它们是互补的。高手会在一分钟内切换使用全部四层:

用 Agent 创建新功能 → 用 Chat 讨论某段实现 → 用 Cmd+K 微调界面 → 用 Tab 加速收尾

.cursorrules 是你给所有 AI 能力的统一指挥手册。花 10 分钟写一份好的项目规则,之后每一次 AI 调用都会受益。


下一篇

33 · Cursor 与 Claude Code 双修指南:何时用 Cursor,何时用 Claude Code,两者如何配合


本教程使用的完整项目代码可以在 GitHub 上找到:github.com/bytesurging/cursor-guide-examples