Session 5: 与 AI 结对编程 - 写好 Prompt 就是写好代码

前面都是准备,这节课开始写代码!但不是你写,是你教 AI 写。


🎬 开场故事

小李让 AI 写代码:

小李:"帮我写个登录功能"

AI:"好的,这里有 200 行代码,包含 JWT、OAuth、双因素认证..."

小李:"我只要简单的邮箱密码登录..."

AI:"这是完整的企业级解决方案"

小李看懵了,复制粘贴,报错,放弃。

meanwhile,小王这样写 Prompt:

角色:你是前端开发专家
任务:写一个登录表单
技术:HTML + 纯 JavaScript,不要用框架
要求:
  1. 只要邮箱和密码两个字段
  2. 前端验证:邮箱格式、密码至少6位
  3. 提交时显示"登录成功"(先不连后端)
  4. 代码要简洁,有注释
输出:完整 HTML 文件,可以直接打开运行

AI 给了 50 行代码,小王复制粘贴,运行成功。

区别在哪?

小李给的是"一句话需求",AI 自由发挥,结果太复杂。

小王给的是"结构化 Prompt",限定边界,结果刚刚好。


🧠 核心概念:Prompt 就是接口

系统设计师设计 API 时,会明确:

  • 输入什么
  • 输出什么
  • 有什么约束

和 AI 协作也一样!

好的 Prompt = 好的 API 设计

结构化 Prompt 框架

【角色】你是...
【任务】请帮我...
【背景】项目情况是...
【约束】需要注意...
【输出格式】请按...格式输出

🛠️ 实战工具:Prompt 模板库

模板 1:生成代码

【角色】你是一个资深[前端/后端/全栈]工程师
【任务】请帮我实现[模块名称]
【技术栈】
  - 前端:[技术]
  - 后端:[技术]
  - 数据库:[技术]
【功能需求】
  1. [具体功能1]
  2. [具体功能2]
  3. [具体功能3]
【输入】[描述输入数据]
【输出】[描述输出结果]
【约束】
  - [约束条件1]
  - [约束条件2]
【输出要求】
  1. 完整可运行的代码
  2. 关键部分有注释
  3. 提供一个使用示例

模板 2:代码审查

请审查以下代码:
```[粘贴代码]

【背景】这段代码用于[功能描述] 【检查点】

  1. 是否有明显 Bug?
  2. 是否有安全隐患?
  3. 代码风格是否规范?
  4. 性能是否有问题?
  5. 是否有更好的实现方式?

请按以上维度给出评价,并给出改进建议。


### 模板 3:生成测试

请为以下函数写测试用例:


【要求】
1. 覆盖正常情况
2. 覆盖边界情况(空值、最大值、最小值)
3. 覆盖异常情况(错误输入、网络中断等)
4. 使用 [Jest/Mocha/其他] 测试框架
5. 每个测试用例要有说明

模板 4:解释代码

请解释以下代码:
```[粘贴代码]

【要求】

  1. 这段代码整体做什么?
  2. 每一行/每一块的具体作用?
  3. 关键概念的解释(如我是新手,不懂...) ```

模板 5:调试报错

我的代码报错了:

【错误信息】
```[粘贴报错]

【相关代码】


【上下文】
- 这段代码想实现:[描述]
- 运行环境:[Node.js/浏览器/其他]
- 最近做了什么改动:[描述]

请帮我分析可能的原因,并给出修复建议。

📝 实战案例:小红的读书笔记模块

模块:添加书籍

小红写的 Prompt:

【角色】你是前端开发专家
【任务】写一个"添加书籍"的表单页面
【技术栈】
  - HTML5
  - Tailwind CSS(用 CDN)
  - 纯 JavaScript(不用框架)
【功能需求】
  1. 两个输入框:书名(必填)、作者(选填)
  2. 一个"添加"按钮
  3. 点击按钮后,在页面下方显示添加的书籍列表
  4. 数据暂时存在内存里(不连后端)
【约束】
  - 书名不能为空,否则提示错误
  - 界面要简洁美观
  - 要适配手机屏幕
【输出要求】
  1. 一个完整的 HTML 文件
  2. 可以直接在浏览器打开运行
  3. 代码有注释,解释关键部分

AI 生成的代码:

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>添加书籍</title>
  <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 p-4">
  <!-- 输入表单 -->
  <div class="max-w-md mx-auto bg-white rounded-lg shadow p-6">
    <h1 class="text-2xl font-bold mb-4">添加书籍</h1>

    <div class="mb-4">
      <label class="block text-gray-700 mb-2">书名 *</label>
      <input type="text" id="title" 
             class="w-full border rounded px-3 py-2" 
             placeholder="输入书名">
    </div>

    <div class="mb-4">
      <label class="block text-gray-700 mb-2">作者</label>
      <input type="text" id="author" 
             class="w-full border rounded px-3 py-2" 
             placeholder="输入作者(选填)">
    </div>

    <button onclick="addBook()" 
            class="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600">
      添加
    </button>

    <p id="error" class="text-red-500 mt-2 hidden"></p>
  </div>

  <!-- 书籍列表 -->
  <div id="bookList" class="max-w-md mx-auto mt-6"></div>

  <script>
    // 存储书籍的数组
    let books = [];

    // 添加书籍函数
    function addBook() {
      const title = document.getElementById('title').value.trim();
      const author = document.getElementById('author').value.trim();
      const errorEl = document.getElementById('error');

      // 验证
      if (!title) {
        errorEl.textContent = '书名不能为空';
        errorEl.classList.remove('hidden');
        return;
      }

      errorEl.classList.add('hidden');

      // 添加到数组
      books.push({ title, author, date: new Date() });

      // 清空输入
      document.getElementById('title').value = '';
      document.getElementById('author').value = '';

      // 更新显示
      displayBooks();
    }

    // 显示书籍列表
    function displayBooks() {
      const listEl = document.getElementById('bookList');

      if (books.length === 0) {
        listEl.innerHTML = '';
        return;
      }

      let html = '<h2 class="text-xl font-bold mb-4">已添加的书籍</h2>';

      books.forEach((book, index) => {
        html += `
          <div class="bg-white rounded shadow p-4 mb-2">
            <div class="font-bold">${book.title}</div>
            ${book.author ? `<div class="text-gray-600">${book.author}</div>` : ''}
          </div>
        `;
      });

      listEl.innerHTML = html;
    }
  </script>
</body>
</html>

结果:

  • 代码可以直接运行
  • 界面简洁美观
  • 有注释,小红能看懂
  • 只需要 70 行!

🔄 迭代式开发流程

不要指望 AI 一次写出完美代码。用迭代:

第 1 轮:生成基础版本

请写一个[功能]的代码,要求:
- 能跑起来
- 核心功能实现
- 暂时不管样式

第 2 轮:添加样式

请给上面的代码加上样式:
- 使用 Tailwind CSS
- 简洁美观
- 适配手机

第 3 轮:添加验证

请给输入添加验证:
- 书名不能为空
- 显示错误提示

第 4 轮:代码审查

请审查这段代码:
- 有没有 Bug?
- 有没有改进空间?

每一轮都在上一轮基础上改进,而不是推倒重来。


⚠️ 常见陷阱

陷阱 1:Prompt 太模糊

❌ "帮我写个网站"

正确做法:说清楚是什么网站、什么功能、用什么技术

陷阱 2:一次要太多

❌ "写一个有登录、支付、聊天、直播的 App"

正确做法:一次一个模块,做完了再下一个

陷阱 3:不给约束

❌ 不说技术栈,AI 给 React,你不会用

正确做法:明确说"用 HTML+JS,不要用框架"

陷阱 4:不问为什么

❌ AI 给什么用什么,不理解代码

正确做法:让 AI 解释,确保你懂这段代码在做什么


🤖 高级技巧

技巧 1:先写伪代码

请先写伪代码,描述"添加书籍"的逻辑:

要求:
1. 不用真实代码语法
2. 用中文描述每一步
3. 确认逻辑后,再生成真实代码

好处:先确认思路,再写代码,返工少。

技巧 2:给 AI 看上下文

我在做读书笔记工具,已经实现了添加书籍功能。

【已实现的代码】
```[粘贴]

现在要实现"添加笔记"功能:

  • 选择已有书籍
  • 输入笔记内容
  • 关联到选中的书

请基于已有代码,实现这个功能,保持代码风格一致。


**好处**:AI 知道上下文,生成的代码更连贯。

### 技巧 3:用 AI 当 rubber duck

我在调试一个 Bug: [描述现象]

我已经尝试了:

  1. [方法1]
  2. [方法2]

但还是不行。你能帮我理清思路吗? 不需要给我答案,只需要问我一些问题,帮我排查。


**好处**:AI 问你问题,帮你理清思路。

---

## ✅ 本节课作业

### 作业 1:写第一个 Prompt
选 Session 4 拆分出的第一个模块,写完整的结构化 Prompt。

### 作业 2:迭代生成代码
- 第 1 轮:生成基础版本(能跑就行)
- 第 2 轮:加样式/验证
- 第 3 轮:让 AI 审查代码

### 作业 3:理解代码
让 AI 解释生成的代码,确保你每行都懂。

### 作业 4:生成测试
用测试模板,让 AI 给这个模块生成测试用例。

### 作业 5(进阶):处理报错
故意改错代码(比如删掉一个括号),把报错发给 AI,练习调试流程。

---

## 📎 模板下载

### Prompt 检查清单

写 Prompt 前检查:

□ 角色明确了吗?(前端专家?后端专家?) □ 任务具体吗?(一个模块,不是整个项目) □ 技术栈清楚吗?(用什么,不用什么) □ 输入输出定义了吗? □ 约束条件写了吗?(性能、安全、兼容性) □ 输出格式指定了吗?(完整文件?代码片段?带注释?)

写完后检查:

□ AI 能直接开始写吗?还是需要问我问题? □ 如果我是 AI,看了这个 Prompt 会怎么理解? □ 有没有可能产生歧义? ```


🎯 下节课预告

Session 6: 测试与迭代 - 让 AI 当你的 QA

我们会学习:

  • 测试的基本概念(不用写代码也能懂)
  • 用 AI 生成测试用例
  • 用 AI 测试 AI 写的代码
  • 建立反馈循环:测试 → 修复 → 再测试

记得带上你写的代码!


💬 常见问题

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

A: 正常!把报错信息和代码发给 AI,让它修复。或者你修,让 AI 解释怎么修的。

Q: 我不懂 AI 用的技术怎么办?

A: 在 Prompt 里明确指定你懂的技术。比如"只用 HTML/CSS/JS,不要用 React/Vue"。

Q: 怎么知道 AI 写的代码好不好?

A: 看三点:1) 能跑吗?2) 好懂吗?3) 容易改吗?如果都 OK,就是好代码。


完成这节课,你知道了怎么用结构化 Prompt 让 AI 写出能用的代码。

下节课,我们聊聊:怎么测试这些代码,确保它不会崩。

下节课见! 🚀

results matching ""

    No results matching ""