AI 编程的边界:哪些任务适合 AI,哪些必须人工把关

AI2天前发布 beixibaobao
3 0 0

AI 编程的边界:哪些任务适合 AI,哪些必须人工把关

在这里插入图片描述

一、理解 AI 能力的"三区模型"

在使用 AI 编程工具近一年后,我逐渐形成了一个理解 AI 能力的心智模型——我称之为"三区模型"。

这个模型将 AI 能处理的任务分为三个区域:

📊 舒适区(Comfort Zone):AI 可以出色完成的、不需要人类过多干预的任务。在这个区域,AI 的效率和正确率都超过了人类。

📊 危险区(Danger Zone):AI 可以完成但看起来正确实际上有问题的任务。这个区域最危险——因为你可能被 AI 看似正确的输出误导,而忽略了潜藏的问题。

📊 禁区(No-Go Zone):绝不应该交给 AI 处理的任务。把这些任务交给 AI 可能导致安全漏洞、法律风险或严重的事故。

理解这三个区域不是一蹴而就的。我最初使用 AI 编程时,犯了不少错误——把危险区的任务当成了舒适区,或者在禁区踩了线。希望这篇文章能帮你少踩一些坑。

让我从最安全的"舒适区"开始说起。

二、舒适区详解——AI 的"拿手好戏"

舒适区的任务是 AI 在大量训练数据中反复见过、模式固定、变化少的任务。在这个区域,AI 的表现非常可靠。

2.1 样板代码(Boilerplate)生成

任何有经验的开发者都知道,项目中大量代码是"样板代码"——每次开新功能都要写的、结构几乎一样的代码。这些代码通常包括:

  • RESTful API 的 CRUD 路由和控制器
  • 数据库模型定义
  • 表单组件的模板结构
  • 项目配置文件(Webpack、Vite、ESLint等)
  • Redux/Vuex 的 Store 模板

示例:生成 CRUD 控制器

Prompt:
"帮我生成一个 Express.js 的 CRUD 控制器,
模型是 Product(字段:id, name, price, category, stock, createdAt),
使用 Prisma ORM,
包含输入验证和错误处理,
使用 async/await,
所有响应统一格式为 { code, data, message }"

AI 输出:

// controllers/productController.js
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
// 统一响应格式
const response = (code, data, message = 'success') => ({ code, data, message });
// 获取所有产品(支持分页和筛选)
const getAllProducts = async (req, res) => {
  try {
    const { page = 1, pageSize = 20, category, minPrice, maxPrice } = req.query;
    const where = {};
    if (category) where.category = category;
    if (minPrice || maxPrice) {
      where.price = {};
      if (minPrice) where.price.gte = Number(minPrice);
      if (maxPrice) where.price.lte = Number(maxPrice);
    }
    const [products, total] = await Promise.all([
      prisma.product.findMany({
        where,
        skip: (Number(page) - 1) * Number(pageSize),
        take: Number(pageSize),
        orderBy: { createdAt: 'desc' },
      }),
      prisma.product.count({ where }),
    ]);
    res.json(response(200, {
      list: products,
      pagination: {
        page: Number(page),
        pageSize: Number(pageSize),
        total,
        totalPages: Math.ceil(total / Number(pageSize)),
      },
    }));
  } catch (error) {
    res.status(500).json(response(500, null, error.message));
  }
};
// 获取单个产品
const getProductById = async (req, res) => {
  try {
    const { id } = req.params;
    const product = await prisma.product.findUnique({ where: { id } });
    if (!product) {
      return res.status(404).json(response(404, null, '产品不存在'));
    }
    res.json(response(200, product));
  } catch (error) {
    res.status(500).json(response(500, null, error.message));
  }
};
// 创建产品
const createProduct = async (req, res) => {
  try {
    const { name, price, category, stock } = req.body;
    // 输入验证
    const errors = [];
    if (!name?.trim()) errors.push('产品名称不能为空');
    if (!price || price <= 0) errors.push('价格必须大于0');
    if (!category?.trim()) errors.push('产品类别不能为空');
    if (errors.length > 0) {
      return res.status(400).json(response(400, null, errors.join('; ')));
    }
    const product = await prisma.product.create({
      data: {
        name: name.trim(),
        price: Number(price),
        category: category.trim(),
        stock: stock ? Number(stock) : 0,
      },
    });
    res.status(201).json(response(201, product, '创建成功'));
  } catch (error) {
    res.status(500).json(response(500, null, error.message));
  }
};
// 更新产品
const updateProduct = async (req, res) => {
  try {
    const { id } = req.params;
    const { name, price, category, stock } = req.body;
    const existing = await prisma.product.findUnique({ where: { id } });
    if (!existing) {
      return res.status(404).json(response(404, null, '产品不存在'));
    }
    const updateData = {};
    if (name?.trim()) updateData.name = name.trim();
    if (price !== undefined) {
      if (price <= 0) return res.status(400).json(response(400, null, '价格必须大于0'));
      updateData.price = Number(price);
    }
    if (category?.trim()) updateData.category = category.trim();
    if (stock !== undefined) updateData.stock = Number(stock);
    const product = await prisma.product.update({
      where: { id },
      data: updateData,
    });
    res.json(response(200, product, '更新成功'));
  } catch (error) {
    res.status(500).json(response(500, null, error.message));
  }
};
// 删除产品
const deleteProduct = async (req, res) => {
  try {
    const { id } = req.params;
    const existing = await prisma.product.findUnique({ where: { id } });
    if (!existing) {
      return res.status(404).json(response(404, null, '产品不存在'));
    }
    await prisma.product.delete({ where: { id } });
    res.json(response(200, null, '删除成功'));
  } catch (error) {
    res.status(500).json(response(500, null, error.message));
  }
};
module.exports = {
  getAllProducts,
  getProductById,
  createProduct,
  updateProduct,
  deleteProduct,
};

这个控制器包含了一个产品 CRUD 操作的所有核心要素:分页查询、条件筛选、输入验证、错误处理、统一响应格式。AI 只用了不到10秒就生成了——而手写至少需要30分钟。

💡 效率提升高达90%:样板代码是 AI 舒适区中最"舒适"的部分。直接让 AI 生成,然后根据业务需求微调即可。

2.2 配置文件编写

现代前端项目的配置文件让人头大——Webpack、Vite、ESLint、Prettier、TypeScript、Tailwind CSS、PostCSS……每个工具都有自己的配置语法。

AI 非常擅长写这些配置,因为它们有固定的格式和大量的示例。你只需要描述你的需求:

Prompt:
"帮我写一个 Vite 的配置文件,用于 React + TypeScript 项目:
- 使用 @vitejs/plugin-react 插件
- 路径别名 @ 指向 ./src
- 开发服务器端口 3000
- 构建目标 es2020
- 代码分割:react、react-dom 单独打包
- CSS Modules 支持"

2.3 格式转换

需要把 JSON 转成 TypeScript 接口?把 Markdown 转成 HTML?把 CSV 转成 SQL INSERT 语句?这些是 AI 信手拈来的任务。

// 输入(JSON)
{
  "user": {
    "id": 1,
    "name": "张三",
    "roles": ["admin", "editor"]
  }
}
// AI 输出(TypeScript Interface)
interface User {
  id: number;
  name: string;
  roles: string[];
}

2.4 正则表达式

正则表达式是"写一次就忘"的语言。但 AI 对正则非常擅长:

开发者:"帮我写一个正则表达式,匹配中国大陆手机号"
AI:/^1[3-9]d{9}$/
开发者:"再写一个提取 URL 中所有查询参数的正则"
AI:/[?&](w+)=([^&s]+)/g

2.5 单元测试

单元测试是典型的"结构固定、内容变化"的任务——最适合 AI 来做:

Prompt:
"为上面的 calculateOrderTotal 函数生成 Jest 单元测试,
覆盖正常订单、含折扣券、空订单、边界值等场景"

AI 会生成一整套测试用例,包括正常路径、异常路径和边界条件。

2.6 文档与注释生成

为已有代码生成 JSDoc、README、API 文档——这些任务 AI 做得非常好:

Prompt:
"读取这个 utils.js 文件,为其中每个函数生成 JSDoc 注释"

三、危险区详解——看似正确,暗藏风险

危险区是我在使用 AI 编程中踩坑最多的地方。这些任务的特点是:AI 完成它们,生成的代码看起来完全正确,甚至能通过编译和简单测试——但在特定条件下会暴露严重问题。

3.1 复杂业务逻辑

为什么危险

复杂业务逻辑的危险在于:AI 不了解你的业务规则全貌。它可能生成了逻辑正确的代码,但这个"正确"是基于通用情况,而不是你的特定业务场景。

具体案例:订单退款逻辑

开发者 Prompt:
"写一个电商订单退款的处理函数"
AI 可能生成的代码:
function processRefund(order) {
  // AI 只考虑了简单的全额退款逻辑
  return refundService.process(order.id, order.totalAmount);
}
实际业务需要考虑的复杂情况(AI 不知道的):
function processRefund(order, refundType, refundItems) {
  // ① 是否在可退款时间窗口内(不同商品类别不同政策)
  // ② 是否为部分退款(只退部分商品)
  // ③ 已使用的优惠券如何处理(按比例退还?全额作废?)
  // ④ 运费是否退还(包邮商品 vs 用户自付运费)
  // ⑤ 已使用的积分如何处理
  // ⑥ 退款方式限制(必须原路退回)
  // ⑦ 与第三方支付平台的交互逻辑
  // ⑧ 退款后是否需要触发其他流程(库存恢复、通知、对账)
}

💡 安全策略:面对复杂业务逻辑时:

  1. 不要让 AI 一次性生成全部代码——先和它讨论各种边界情况
  2. 先用自然语言和 AI 确认完整的业务规则,再让它写代码
  3. 关键业务逻辑必须写详细的单元测试

3.2 性能敏感的代码

为什么危险

AI 生成的代码在功能上可能是正确的,但它不了解你的性能上下文——数据量级、并发量、延迟要求。

具体案例:数据库查询优化

// AI 可能生成这样的代码(功能正确,但性能糟糕)
async function getUserReport(userId) {
  const user = await db.user.findUnique({ where: { id: userId } });
  // N+1 问题!
  const orders = await db.order.findMany({ where: { userId } });
  for (const order of orders) {
    // 每个 order 都单独查一次数据库
    order.items = await db.orderItem.findMany({ where: { orderId: order.id } });
    for (const item of order.items) {
      item.product = await db.product.findUnique({ where: { id: item.productId } });
    }
  }
  return { user, orders };
}
// 正确的做法(用 JOIN 或 include 一次性加载)
async function getUserReport(userId) {
  const user = await db.user.findUnique({
    where: { id: userId },
    include: {
      orders: {
        include: {
          items: {
            include: { product: true },
          },
        },
      },
    },
  });
  return user;
}

AI 的代码在数据量小的时候完全正常——测试数据库只有几十条数据,N+1 查询看不出任何问题。但上线后数据量增长到几十万条,1500次数据库查询直接把服务器拖垮。

⚠️ 安全策略

  • 对于涉及数据库查询的代码,始终检查是否有 N+1 问题
  • 使用数据库查询分析工具(如 Prisma 的日志、MySQL 慢查询日志)
  • 在代码审查时特别关注数据访问层的性能

3.3 安全相关代码

为什么危险

AI 的训练数据来自公开代码仓库,而公开代码仓库中有大量不安全的代码。AI 学到了"常见的写法",但"常见的写法"不一定安全。

具体案例:SQL 查询

// AI 可能生成的代码(SQL 注入风险)
router.get('/api/users', async (req, res) => {
  const { username } = req.query;
  // 直接拼接用户输入到 SQL 查询中!
  const users = await db.raw(`SELECT * FROM users WHERE username = '${username}'`);
  res.json(users);
});
// 安全的方式(使用参数化查询)
router.get('/api/users', async (req, res) => {
  const { username } = req.query;
  const users = await db.raw('SELECT * FROM users WHERE username = ?', [username]);
  // 或者使用 ORM 的安全方法
  const users = await db.user.findMany({ where: { username } });
  res.json(users);
});

具体案例:认证逻辑

// AI 可能生成的代码(认证绕过风险)
function isAuthenticated(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];
  if (!token) {
    return res.status(401).json({ message: '未提供认证令牌' });
  }
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    // ⚠️ 问题:捕获所有异常并将它们都视为"令牌过期"
    // 实际上可能是"密钥不匹配"、"算法不同"等安全问题
    res.status(401).json({ message: '令牌已过期,请重新登录' });
  }
}
// 更安全的做法(区分不同类型的JWT错误)
function isAuthenticated(req, res, next) {
  // ... 省略前面的代码
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET, {
      algorithms: ['HS256'], // 指定算法,防止算法混淆攻击
    });
    req.user = decoded;
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ message: '令牌已过期' });
    }
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({ message: '无效的认证令牌' });
    }
    return res.status(500).json({ message: '认证服务异常' });
  }
}

⚠️ 安全策略

  • 对 AI 生成的安全相关代码(认证、授权、加密、输入验证)进行额外的安全审查
  • 使用安全扫描工具(如 npm audit, Snyk, SonarQube)做二次验证
  • 参考 OWASP Top 10 检查 AI 生成的 Web 代码
  • 敏感操作(密码处理、Token 生成、密钥管理)最好由安全专家编写或审查

四、禁区详解——绝对不能交给 AI 的任务

有些任务,无论 AI 看起来多么"懂",都不应该交给它。

4.1 涉密数据与密钥管理

⚠️ 红线:绝对不要把生产环境的密钥、密码、证书或任何敏感数据透露给公有 AI 服务。

❌ 绝对不要做的事:
Prompt: "这是我的数据库连接字符串,帮我写个连接池配置:
mongodb+srv://admin:MyP@ssw0rd123@prod-cluster.xxxxx.mongodb.net/myapp"
Prompt: "这是我的 AWS Access Key,帮我写 S3 上传代码:
AKIAIOSFODNN7EXAMPLE / wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
Prompt: "我们公司的内部 API 文档如下:[粘贴完整的内部文档]"

为什么这是禁区?你的对话内容可能会被用于模型训练。虽然 OpenAI 和 Anthropic 都有 API 数据使用政策(API 调用的数据不会用于训练),但 ChatGPT 网页版的对话可能会。而且,即使服务商承诺不使用数据,你的 Prompt 也经过了他们的服务器——这是在增加不要的攻击面。

💡 安全做法

  • 使用环境变量而非在代码中硬编码密钥
  • 在粘贴给 AI 的代码中用占位符替换敏感信息(如 REDACTED_API_KEY
  • 敏感配置使用专门的密钥管理服务(如 AWS Secrets Manager、HashiCorp Vault)
  • 企业环境使用私有部署的 AI 服务

4.2 合规关键代码

如果你的项目需要满足特定的合规要求(如 HIPAA(医疗)、PCI-DSS(支付)、SOC2(安全审计)),让 AI 生成合规关键代码是有法律风险的。合规不仅是"代码做什么",还包括"谁写的代码"、“谁审查了代码”、“代码变更的完整记录”。

💡 建议做法

  • 合规关键代码由有资质的开发者编写和审查
  • AI 生成的代码可以作为参考,但必须有完整的人工审查记录
  • 确保代码审查流程满足合规要求

4.3 关键基础设施配置

不要把生产环境的 Kubernetes 配置、数据库迁移脚本、防火墙规则交给 AI 直接部署。这类配置的一个小错误可能影响整个系统的可用性。

⚠️ 安全做法:AI 可以帮你生成草案,但这个草案必须经过:

  • 人工逐行审查
  • 在 Staging 环境验证
  • 至少两名工程师的 Code Review
  • 回滚方案的确认

五、判断框架:六大评估问题

基于我的实践经验,在决定是否把一个任务交给 AI 之前,可以问自己六个问题:

问题一:这个任务的"正确输出"是否明确可验证?

  • ✅ 明确可验证:生成正则表达式、格式化代码、写单元测试
  • ❌ 难以验证:复杂的架构决策、安全策略设计

问题二:任务失败(AI 出错)的后果是什么?

  • ✅ 低风险:代码风格不完美、注释有误、需要小幅修改
  • ❌ 高风险:数据丢失、安全漏洞、合规违规

问题三:这个任务需要多少"上下文"?

  • ✅ 局部上下文:单个函数、单个文件
  • ❌ 全局上下文:跨多个子系统、需要理解业务全貌

问题四:AI 在这个领域有多少训练数据?

  • ✅ 训练数据丰富:流行框架(React、Express.js)的常见用法
  • ❌ 训练数据稀少:小众框架、企业内部库、最新的 API

问题五:这个任务是否涉及"判断"和"权衡"?

  • ✅ 纯执行性:将已知的要求翻译为代码
  • ❌ 需要权衡:在多个可行方案中做选择

问题六:我是否有能力验证 AI 的输出?

  • ✅ 能独立验证:我熟悉这个领域,能判断 AI 输出的质量
  • ❌ 无力验证:我完全不懂这个领域,只能"信任" AI

📊 快速评估矩阵

场景 Q1 Q2 Q3 Q4 Q5 Q6 评估
写 CRUD 接口 安全,放心用
写 SQL 查询 可以用,但要审查
设计数据库 Schema 需要深度参与
写认证中间件 参考 AI 输出,自己做决策
配置 CI/CD 先学习基础,再使用 AI

六、人机协作的质量保障体系

既然有些区域是危险的,我们需要一套系统来安全地使用 AI。

6.1 “Trust but Verify” 原则

对于 AI 生成的每一段代码,默认态度应该是:信任但验证。就像你审查一个初级开发者的代码一样——你不会直接拒绝,但你会仔细检查。

6.2 分层审查策略

第一层(AI 生成后,立即):
  快速扫描——检查明显的错误、不安全的 API、敏感信息泄露
第二层(提交前,自己审查):
  逻辑审查——理解代码逻辑,确认符合业务需求
  安全审查——检查 OWASP Top 10 相关漏洞
  性能审查——检查明显的性能问题(N+1 查询等)
第三层(PR 阶段,同事审查):
  团队 Code Review——另一个开发者审查代码
  自动化检查——Lint、Test、Security Scan、覆盖率
第四层(部署前):
  Staging 环境验证——在类生产环境测试
  性能测试——压力测试和负载测试
  安全扫描——自动化安全扫描工具

6.3 团队规范建议

如果你们团队在使用 AI 编程工具,建议建立以下规范:

1. 代码注释标记
   // @ai-generated: 此函数由 AI 生成,已通过人工审查
   // 方便后续代码审查者了解代码来源
2. AI 使用日志
   记录哪些代码使用 AI 生成,以及审查结果
3. 安全红线清单
   列出绝对不能交给 AI 的任务类型
4. 审查清单
   AI 生成代码的特定审查项

七、总结

理解 AI 编程的边界不是要限制你的使用,而是让你用得更安全、更高效。当你清楚地知道什么可以交给 AI、什么必须自己把关时,你就真正掌握了 AI 辅助编程的精髓。

核心要点回顾:

  • ✅ 舒适区放心用:样板代码、配置文件、格式转换、正则、测试、文档
  • ⚠️ 危险区谨慎用:复杂业务逻辑、性能敏感代码、安全相关代码
  • ❌ 禁区绝不碰:涉密数据、合规代码、生产基础设施直部署
  • 💡 用好"六大评估问题"做快速判断
  • 💡 建立分层审查体系,将 AI 视为需要 Code Review 的"初级开发者"

下一篇文章,我们将探讨 Token 与上下文窗口——理解 AI 的"记忆力"和"视野",这是写好 Prompt 的基础。


下一篇:Token 与上下文窗口:理解 AI 模型的「记忆」与限制

© 版权声明

相关文章