第一次让 AI 写代码:实现一个待办事项清单

简介: 本文通过一个完整的待办事项清单案例,详解AI编程实战流程:从明确需求、拆解功能模块、生成代码,到本地运行、边界测试与迭代优化。强调开发者需主导目标定义、方案判断与结果验证,AI仅作高效辅助。附可运行单文件代码及提示词模板。(239字)

AI04.png

前面的文章中,我们了解了什么是 AI 编程,也认识了常见的 AI 编程工具。

这一篇不再停留在概念层面,而是通过一个完整的小案例,体验一次真实的 AI 编程流程:

让 AI 帮我们实现一个简单的 JavaScript 待办事项清单。

这个案例虽然简单,但包含了日常开发中比较典型的步骤:

  • 分析需求
  • 拆分功能
  • 生成代码
  • 运行代码
  • 发现问题
  • 修改代码
  • 验证结果

掌握这套流程后,后面无论是开发表单、后台页面,还是实现接口功能,都可以使用类似的方法。

一、先明确我们要做什么

在让 AI 写代码之前,不能只说一句:

帮我写一个待办事项应用。

这个需求过于简单,AI 不知道我们具体需要什么功能,可能会出现以下问题:

  • 使用什么技术实现不明确
  • 页面需要哪些功能不明确
  • 数据是否需要保存不明确
  • 是否需要处理空输入不明确
  • 代码应该放在哪个文件中不明确
  • 最终运行方式不明确

因此,在开始之前,我们先把需求整理清楚。

本次要实现的待办事项清单包含以下功能:

功能 说明
添加任务 输入任务内容后点击按钮添加
展示任务 将已添加的任务显示在列表中
完成任务 点击复选框后标记任务已完成
删除任务 删除不再需要的任务
数据保存 刷新页面后任务仍然保留
空输入校验 不允许添加空白任务

技术要求如下:

  • 使用 HTML、CSS 和 JavaScript
  • 不使用前端框架
  • 不依赖第三方库
  • 所有代码放在一个 HTML 文件中
  • 双击文件即可在浏览器中运行

需求越明确,AI 生成的结果越接近我们真正想要的结果。

二、先让 AI 拆解需求

很多人使用 AI 时,习惯直接让它输出最终代码。

更稳定的方式是先让 AI 分析需求,确认实现思路后,再让它生成代码。

可以使用下面这段提示词:

我想使用原生 HTML、CSS 和 JavaScript,
开发一个简单的待办事项清单。

功能要求:
1. 用户可以输入任务并添加
2. 任务显示在列表中
3. 每条任务前有一个复选框
4. 勾选后显示完成状态
5. 每条任务都可以删除
6. 使用 localStorage 保存数据
7. 输入为空时不能添加

请先不要生成完整代码,
先帮我拆分功能模块,
说明每个模块的实现思路,
并列出需要注意的边界情况。

一个比较可靠的 AI 回复,通常会把需求拆分成以下模块:

  1. 页面结构模块:输入框、添加按钮、任务列表。
  2. 数据模块:使用数组保存任务数据。
  3. 渲染模块:将任务数据转换成页面内容。
  4. 添加模块:获取输入内容并创建新任务。
  5. 完成模块:修改任务的完成状态。
  6. 删除模块:从数组中移除指定任务。
  7. 持久化模块:将任务保存到 localStorage。
  8. 校验模块:处理空输入和无效数据。

这一步的价值在于:我们可以先检查 AI 的理解是否正确。

如果需求拆解错了,及时纠正即可;如果直接生成几百行代码,后面再发现方向不对,修改成本会更高。

三、再让 AI 生成代码

确认实现思路后,可以继续给 AI 下面的提示词:

请根据刚才的功能拆解,
生成一个完整可运行的 index.html 文件。

具体要求:
1. 使用原生 HTML、CSS 和 JavaScript
2. 不使用任何第三方库
3. 所有代码放在同一个 HTML 文件中
4. 页面布局简洁,适合初学者阅读
5. JavaScript 使用清晰的函数拆分
6. 使用 localStorage 保存任务
7. 添加任务时校验输入内容
8. 删除任务前不需要弹窗确认
9. 代码中添加必要注释
10. 输出完整代码,并说明运行方法

这里增加了“单文件”“不使用第三方库”“函数拆分”等限制,可以减少 AI 输出不符合要求的代码。

四、完整可运行代码

下面是一份可以直接运行的示例代码。

将代码保存为 index.html,然后使用浏览器打开即可。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>我的待办事项</title>
  <style>
    * {
    
      box-sizing: border-box;
    }

    body {
    
      margin: 0;
      min-height: 100vh;
      padding: 40px 16px;
      background: #f3f5f7;
      color: #1f2937;
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI",
        "PingFang SC", "Microsoft YaHei", sans-serif;
    }

    .todo-app {
    
      width: min(100%, 640px);
      margin: 0 auto;
      padding: 28px;
      background: #ffffff;
      border-radius: 12px;
      box-shadow: 0 8px 24px rgba(15, 23, 42, 0.08);
    }

    h1 {
    
      margin: 0 0 24px;
      text-align: center;
      font-size: 28px;
    }

    .input-row {
    
      display: flex;
      gap: 10px;
    }

    #task-input {
    
      flex: 1;
      min-width: 0;
      height: 42px;
      padding: 0 12px;
      border: 1px solid #d1d5db;
      border-radius: 6px;
      font-size: 15px;
    }

    #task-input:focus {
    
      outline: none;
      border-color: #2563eb;
      box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
    }

    button {
    
      border: 0;
      border-radius: 6px;
      cursor: pointer;
      font-size: 14px;
    }

    #add-button {
    
      padding: 0 18px;
      background: #2563eb;
      color: #ffffff;
    }

    #add-button:hover {
    
      background: #1d4ed8;
    }

    #task-list {
    
      margin: 24px 0 0;
      padding: 0;
      list-style: none;
    }

    .task-item {
    
      display: flex;
      align-items: center;
      gap: 10px;
      min-height: 48px;
      padding: 8px 0;
      border-bottom: 1px solid #e5e7eb;
    }

    .task-text {
    
      flex: 1;
      overflow-wrap: anywhere;
    }

    .task-item.completed .task-text {
    
      color: #9ca3af;
      text-decoration: line-through;
    }

    .delete-button {
    
      padding: 6px 10px;
      background: #fee2e2;
      color: #b91c1c;
    }

    .delete-button:hover {
    
      background: #fecaca;
    }

    .empty-message {
    
      padding: 20px 0;
      color: #6b7280;
      text-align: center;
    }

    @media (max-width: 480px) {
    
      .todo-app {
    
        padding: 20px 16px;
      }

      .input-row {
    
        flex-direction: column;
      }

      #add-button {
    
        height: 42px;
      }
    }
  </style>
</head>
<body>
  <main class="todo-app">
    <h1>我的待办事项</h1>

    <div class="input-row">
      <input
        id="task-input"
        type="text"
        placeholder="请输入待办事项"
        maxlength="100"
      >
      <button id="add-button" type="button">添加任务</button>
    </div>

    <ul id="task-list"></ul>
  </main>

  <script>
    const STORAGE_KEY = "todo-tasks";

    const taskInput = document.querySelector("#task-input");
    const addButton = document.querySelector("#add-button");
    const taskList = document.querySelector("#task-list");

    let tasks = loadTasks();

    // 从 localStorage 读取任务数据
    function loadTasks() {
    
      try {
    
        const savedTasks = localStorage.getItem(STORAGE_KEY);
        const parsedTasks = savedTasks ? JSON.parse(savedTasks) : [];

        return Array.isArray(parsedTasks) ? parsedTasks : [];
      } catch (error) {
    
        console.error("读取任务失败:", error);
        return [];
      }
    }

    // 保存任务数据
    function saveTasks() {
    
      localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
    }

    // 将任务数据渲染到页面
    function renderTasks() {
    
      taskList.innerHTML = "";

      if (tasks.length === 0) {
    
        const emptyMessage = document.createElement("li");
        emptyMessage.className = "empty-message";
        emptyMessage.textContent = "暂时没有待办事项";
        taskList.appendChild(emptyMessage);
        return;
      }

      tasks.forEach((task) => {
    
        const taskItem = document.createElement("li");
        taskItem.className = "task-item";

        if (task.completed) {
    
          taskItem.classList.add("completed");
        }

        const checkbox = document.createElement("input");
        checkbox.type = "checkbox";
        checkbox.checked = task.completed;
        checkbox.setAttribute("aria-label", `完成任务:${
      task.text}`);

        checkbox.addEventListener("change", () => {
    
          toggleTask(task.id);
        });

        const taskText = document.createElement("span");
        taskText.className = "task-text";
        taskText.textContent = task.text;

        const deleteButton = document.createElement("button");
        deleteButton.className = "delete-button";
        deleteButton.type = "button";
        deleteButton.textContent = "删除";

        deleteButton.addEventListener("click", () => {
    
          deleteTask(task.id);
        });

        taskItem.append(checkbox, taskText, deleteButton);
        taskList.appendChild(taskItem);
      });
    }

    // 添加任务
    function addTask() {
    
      const text = taskInput.value.trim();

      if (!text) {
    
        alert("请输入待办事项");
        taskInput.focus();
        return;
      }

      tasks.unshift({
    
        id: Date.now(),
        text,
        completed: false
      });

      saveTasks();
      renderTasks();

      taskInput.value = "";
      taskInput.focus();
    }

    // 切换任务完成状态
    function toggleTask(taskId) {
    
      tasks = tasks.map((task) => {
    
        if (task.id === taskId) {
    
          return {
    
            ...task,
            completed: !task.completed
          };
        }

        return task;
      });

      saveTasks();
      renderTasks();
    }

    // 删除任务
    function deleteTask(taskId) {
    
      tasks = tasks.filter((task) => task.id !== taskId);

      saveTasks();
      renderTasks();
    }

    addButton.addEventListener("click", addTask);

    taskInput.addEventListener("keydown", (event) => {
    
      if (event.key === "Enter") {
    
        addTask();
      }
    });

    renderTasks();
  </script>
</body>
</html>

五、如何运行这段代码

按照下面的步骤操作:

  1. 创建一个名为 index.html 的文件。
  2. 将上面的完整代码复制到文件中。
  3. 保存文件。
  4. 使用浏览器打开 index.html。
  5. 在输入框中添加几条任务。
  6. 勾选任务,观察完成状态。
  7. 删除一条任务。
  8. 刷新浏览器,检查任务是否仍然存在。

如果刷新后任务还在,说明 localStorage 保存功能正常。

六、如何验证 AI 生成的代码

代码能够运行,并不代表代码完全正确。

建议至少验证下面这些情况:

测试场景 预期结果
直接点击添加按钮 提示输入任务
输入空格后添加 提示输入任务
输入正常内容后添加 任务成功显示
按回车键添加 任务成功显示
勾选任务 任务显示完成状态
取消勾选 任务恢复未完成状态
删除任务 任务从列表中消失
刷新页面 已有任务仍然存在
添加较长文本 页面布局不被撑破
删除全部任务 显示空列表提示

这一步非常重要。

AI 生成代码时,通常会优先实现主流程,但一些边界情况可能被忽略。开发者需要通过实际操作发现问题,再把问题反馈给 AI。

例如,发现输入空内容也能添加任务,可以继续询问:

当前代码允许用户输入空格后添加任务,
请分析原因并修改代码。

要求:
1. 使用 trim 判断输入内容
2. 空内容时给出提示
3. 输入框清空后保持焦点
4. 只输出需要修改的代码片段,
   并解释修改原因

与其让 AI 每次重新生成全部代码,不如明确指出问题,让它进行局部修改。

七、AI 生成代码时常见的问题

1. 代码看起来完整,但无法运行

常见原因包括:

  • HTML 标签没有闭合
  • JavaScript 变量名称前后不一致
  • 事件绑定到了错误的元素
  • 函数名称写错
  • 代码依赖了没有安装的第三方库

解决方法是把完整报错信息和相关代码一起提供给 AI。

打开页面后,点击“添加任务”没有任何反应。

浏览器控制台报错:
[粘贴完整报错]

请定位具体原因,
指出错误代码所在位置,
然后给出最小修改方案。

2. 只实现了正常情况

例如,正常输入可以添加任务,但空输入、重复任务、超长文本没有处理。

可以让 AI 补充边界条件:

请检查这段待办事项代码,
重点分析以下边界情况:

- 空字符串
- 只有空格的输入
- 超过 100 个字符的输入
- localStorage 中保存了非法数据
- 用户连续快速点击添加按钮

请列出问题,并给出修改建议。

3. 代码能运行,但自己看不懂

这说明 AI 输出的代码超出了当前理解范围。

可以要求 AI 降低代码复杂度:

请把这段代码改写成适合 JavaScript 初学者学习的版本。

要求:
1. 保留原有功能
2. 减少复杂语法
3. 拆分成多个简单函数
4. 逐个解释每个函数
5. 说明数据是如何从输入框流向页面的

使用 AI 的过程中,不要只关注最终结果,也要关注自己是否理解实现过程。

八、一套可以复用的提示词模板

以后开发类似的小功能时,可以直接套用下面的模板:

我想开发一个【功能名称】。

使用技术:
- 【技术名称】
- 【是否使用框架】
- 【是否允许第三方库】

核心功能:
1. 【功能一】
2. 【功能二】
3. 【功能三】

输入数据:
- 【输入内容和格式】

输出结果:
- 【页面或接口应该返回什么】

特殊要求:
- 【异常处理要求】
- 【边界情况】
- 【兼容性要求】
- 【代码组织要求】

请按照以下步骤完成:
1. 先分析需求并拆分功能
2. 列出可能的边界情况
3. 给出实现方案
4. 再生成完整代码
5. 说明运行方法
6. 提供测试清单

这个模板的核心不是固定的文字,而是让 AI 清楚了解五件事:

  • 你想做什么
  • 使用什么技术
  • 需要哪些功能
  • 有哪些限制
  • 希望 AI 按什么步骤回答

九、这次实践应该掌握什么

通过这个小案例,我们完成了一次比较完整的 AI 编程流程:

明确需求
   ↓
让 AI 拆解功能
   ↓
确认实现思路
   ↓
让 AI 生成代码
   ↓
本地运行验证
   ↓
发现问题并反馈
   ↓
修改代码并再次测试

需要特别注意的是:

AI 编程不是把需求复制给 AI,然后直接复制它返回的代码。

更合理的工作方式是:

开发者负责明确目标、判断方案和验证结果,AI 负责提供实现建议和编码辅助。

即使案例很简单,也应该保留“生成、运行、验证、修改”这几个环节。

总结

  • 让 AI 写代码之前,首先要明确功能和技术要求。
  • 先让 AI 拆解需求,再让它生成代码,结果通常更稳定。
  • 代码生成后必须在本地运行,并验证正常场景和异常场景。
  • 遇到问题时,应提供完整报错、相关代码和运行环境。
  • AI 适合帮助我们快速完成基础实现,但不能替代开发者进行判断。
  • 一套清晰的提示词模板,可以复用到不同的开发任务中。

下一篇文章将继续讨论一个非常重要的问题:

为什么 AI 生成的代码不能直接使用?如何对 AI 代码进行检查和验证?


✍坚持原创,求关注,点赞,收藏

相关文章
|
1天前
|
人工智能 JavaScript 开发工具
开始 AI 编程前,到底需要准备什么?
本文为AI编程入门指南,详解初学者必备的10项准备:AI工具选择、编辑器配置、基础环境搭建、编程基础要求、练习项目设计、Git版本管理及安全提示等,强调“轻启动、重实践”,助你零门槛开启AI编程之旅。
开始 AI 编程前,到底需要准备什么?
|
17天前
|
人工智能 自然语言处理 安全
阿里云千问办公 QwenWork详细介绍:产品核心能力、典型场景、价格及常见问题解答
在AI技术快速落地办公场景的当下,市面上绝大多数智能工具依旧停留在问答对话、文本摘要、简单文案改写层面,只能完成碎片化单点任务。企业员工处理一份完整业务工作时,往往需要同时开启多款工具,文档处理、数据分析、素材创作、网页制作分属不同软件,中间内容需要反复复制粘贴,即便借助通用大模型生成内容,输出成果还需要大量二次格式调整,才能达到交付标准。同时企业内部的数据分散在聊天记录、审批单据、本地文档、业务平台,普通AI工具无法直接读取内部业务信息,每一次任务都要人工复述背景条件,法务、财务、研发这类垂直岗位,还需要编写冗长提示词才能拿到相对可用结果,AI办公落地的实际门槛长期居高不下。千问办公Qwen
427 9
|
人工智能 自然语言处理 搜索推荐
罗兰艺境GEO技术架构深度解析:从RAG机理到全栈自研的技术路线
生成式引擎优化(GEO)通过干预RAG架构的重排序阶段,提升企业内容在AI答案中的引用率。本文剖析RAG四阶段熵增点,指出重排序阶段的核心变量为语义匹配度、证据密度与信源权威等级,据此推导DSS原则(语义深度、数据支持、权威来源)及三层工程架构,并给出五级量化评分标准(≥75分入库)。文章综述FeatGEO、MAGEO、AgenticGEO等前沿研究,展望GraphRAG、多智能体协同、跨模态适配等六大趋势,为技术团队提供工程化参考。
542 0
|
1天前
|
人工智能 安全 测试技术
AI 编程是什么?5 个真实开发场景带你快速入门
本文面向AI编程初学者,系统讲解AI编程的本质、适用场景与使用边界。涵盖代码解释、报错分析、基础生成、测试补充和文档编写等实用技巧,并强调“AI辅助而非替代”的核心理念——所有输出均需开发者验证与决策。入门建议从小问题着手,边用边学。
AI 编程是什么?5 个真实开发场景带你快速入门
|
1天前
|
调度 C++
0.8MB 跑通 Qwen|第 7-2 篇:推理引擎的混合精度路由——flags 决定谁用 Q8、谁用 Q4
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎,适配Qwen3-VL多模态模型,在RK3588上实现实测。核心创新是混合精度路由:prefill阶段用Q8保精度,decode阶段用Q4省带宽,通过flags比特位动态调度,兼顾速度与质量。(239字)
|
1天前
|
开发工具 C++ git
0.8MB 跑通 Qwen|第 5-3 篇:推理引擎的参考实现对拍——怎么读懂 rel err 的数量级
本系列《0.8MB跑通Qwen》聚焦ARM端零依赖纯C推理引擎开发,实测适配Qwen3-VL多模型,在RK3588上完成Q8/Q4量化与NEON加速。核心创新在于“两把尺子”误差分析法:内核一致性(1e-7)验证手写代码正确性,量化损失(1e-2)界定精度边界,实现可验证、可调试、可落地的轻量级LLM部署。(239字)
|
1天前
|
并行计算 Java API
0.8MB 跑通 Qwen|第 4-1 篇:推理引擎为什么换掉 OpenMP——线程唤醒与亲和(vllm_tp 设计)
本系列《0.8MB跑通Qwen》聚焦ARM端侧轻量化部署,基于RK3588平台,自研零依赖纯C推理引擎,适配Qwen3-VL多模态模型。核心突破在于手写线程池vllm_tp——摒弃OpenMP,采用常驻线程、spin-then-event、调用者参与及静态绑核四大设计,将微秒级小并行区调度开销降低12倍,实现在资源受限边缘设备高效运行大模型。(239字)
|
2月前
|
存储 人工智能 运维
大模型Agent安全实践:Workspace沙箱隔离与全链路审计,规避AI自主运行核心风险21.2
Workspace安全治理是专为AI Agent设计的闭环安全体系,以轻量沙箱隔离为底座、精细化权限管控为核心、全链路日志审计为兜底,有效应对模型幻觉、越权操作、数据泄露等原生风险,保障Agent在办公、开发、运维等场景中安全可控、合规可用。
126 2
|
2月前
|
人工智能 弹性计算 自然语言处理
阿里云建站产品解析:万小智AI建站、云·企业官网,智能建站系统,满足企业不同阶段需求
本文对比了阿里云两大AI建站产品体系:万小智AI建站与云·企业官网。万小智定位为自助式零代码建站,用户通过自然语言或上传文档即可自动生成含前后端与数据库的完整网站,支持一键发布,提供轻量版(360元/年)、标准版(980元/年)、高级版(1980元/年)三档套餐,并赠送.CN域名与备案服务码,核心优势在于“自己动手、AI辅助”,适合快速上线、自主操作且预算有限的个人与中小企业。云·企业官网则定位为专业定制化服务,由双认证工程师一对一全程交付,采用“人工设计+AI运维”模式,基于独立ECS部署,提供国际一流设计与专属AI后台,适合对品牌形象、功能深度与长期运营有高要求的中大型企业。
阿里云建站产品解析:万小智AI建站、云·企业官网,智能建站系统,满足企业不同阶段需求
|
2月前
|
人工智能 算法 API
通义千问Qwen3.7‑Max全解|技术架构、核心能力、API实战与版本选型
随着AI智能体技术快速迭代,行业对于大模型的诉求已经跳出传统问答对话的范畴。开发者更需要模型具备长链路自主任务执行、大规模代码库解析、复杂多步骤逻辑推理、上千次连续工具调用的综合能力。Qwen3.7‑Max作为通义千问系列专门面向Agent场景打造的旗舰文本大模型,依托MoE混合专家架构,把深度推理、大型代码工程处理、超长上下文记忆、长周期自主任务执行作为核心卖点,在专业代码编写、数学逻辑推演、海量文档处理、多步骤工具编排等场景展现出强劲实力,广泛适配AI智能体研发、软件项目开发、科研数据分析、企业业务自动化等多元化业务。
184 1

热门文章

最新文章