AI 生成的代码都是一坨屎?聊聊怎么给 Agent 制定工程约束

如何为AI编写高效且规范的前端代码

高性能JavaScript在现代Web开发中扮演着重要的角色。随着人工智能技术的发展,越来越多地利用AI来生成代码以提高开发效率。然而,在实际应用中,如果不对AI进行适当的约束和指导,很可能会产生难以维护和扩展的“垃圾”代码。

AI生成代码的问题

有次前端架构评审会上,一位同事提到他们的团队在使用某款流行的国产AI编码工具后,虽然起初提高了工作效率,但后来发现生成的代码极其混乱。具体表现为:

  • 一个复杂的用户界面模块被硬塞到了单一文件中,且代码量接近2000行。
  • 文件中充斥着随意定义和使用的变量名、繁杂的正则表达式以及多层嵌套的回调函数。

团队尝试对这些代码进行迭代更新时发现几乎无法下手。这不禁让人怀疑:是否是AI工具本身的问题?还是说团队在使用过程中没有遵循合理的工程规范?

AI与初级开发者的相似性

AI本质上就像一个具备无限精力和快速输入能力,但缺乏实际项目经验的初级开发者。它可能精通各种开源代码库,却难以理解特定公司特有的技术栈、设计模式以及网络请求相关的安全措施。

例如,在为某业务需求生成防抖搜索框时,未受约束的AI可能会做出如下行为:

  1. 直接调用原生fetch函数而忽略项目中已封装好的Axios拦截器。
  2. 使用硬编码样式而非遵循设计系统中的标准变量和类名。
  3. 手写防抖逻辑而不是复用现有的可维护代码库。

如何制定有效的工程约束

为了确保AI生成的代码能够满足企业级应用的要求,需要从多个维度对它进行规范:

  1. API调用:强制使用项目中的HTTP客户端来处理请求与响应,并在其中加入Token验证逻辑。
  2. 样式管理:鼓励基于现有的CSS框架或变量库生成组件样式,以保持视觉一致性。
  3. 防抖/节流:复用现有实现的高阶函数而不是重新编写,减少冗余。

示例代码

下面是一个规范化的搜索框实现示例,展示了上述几条建议的应用:

import React, { useState } from 'react';
import axios from 'axios'; // 使用项目中的HTTP客户端
import useDebounce from './hooks/useDebounce'; // 重用防抖逻辑
import styles from './styles.module.css';

const SearchLocation = () => {
    const [query, setQuery] = useState('');

    useDebounce(() => {
        axios.get(`https://api.company.com/locations?q=${query}`, {
            headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
        })
            .then(res => res.json())
            .then(locations => console.log(locations));
    }, [query], 500);

    return (
        <div className={styles.searchContainer}>
            <input 
                type="text"
                value={query}
                onChange={e => setQuery(e.target.value)}
                placeholder='Search location'
            />
        </div>
    );
};

export default SearchLocation;

总结

通过设定严格的工程约束,可以有效引导AI生成符合公司标准的高质量代码。这不仅提升了开发效率,还保障了项目的长期可维护性和扩展性。希望本文能够帮助大家更好地理解和应用这些最佳实践。


请继续阅读后续部分以获得完整指南和更多实用建议。

把规范写进 AI 的基因里

现在主流的 AI 工具(无论是云服务还是本地运行的代理程序),都已经支持了全局规则配置,也就是常说的 .aiconfig 或者 System Prompt。

通过给 AI 设定严格的规则,你可以确保它生成的代码遵循高标准和最佳实践。以下是我在实际项目中为 AI 设置的一些关键约束:

规则一:严禁私自造轮子,强制依赖倒置

AI 必须使用项目中已有的工具库来处理异步请求或防抖机制,而不是重新实现这些功能。例如,我会明确要求 AI 使用项目中的 @/utils/request 模块进行所有异步操作,并通过 ahooks 库的 useDebounce 函数处理防抖逻辑。

规则二:状态与 UI 强制分离

当组件代码超过 100 行时,AI 必须将复杂的逻辑抽取成独立的自定义 Hook。这不仅提高了代码可读性,还避免了在组件中直接嵌入复杂的业务逻辑。这样的设计使得组件更加专注于渲染任务。

规则三:锁死样式系统

禁止使用内联样式或传统的 CSS 文件,所有样式必须通过 Tailwind CSS 进行管理。此外,特定颜色值应从 tailwind.config.js 中定义的主题变量中获取,以确保一致性和可维护性。

规则四:安全底线

AI 必须遵守严格的鉴权机制,不允许直接访问本地存储来读取 Token。所有需要权限验证的操作必须通过全局 Store 或特定的 Hook 来处理,确保数据的安全和一致性。


约束后代码的质量提升

当你在 AI 的配置中设置了上述约束,并要求它生成一个搜索框组件时,你会看到它的代码质量显著提高:

// 经过严格约束后的 AI 生成代码
import React, { useState } from 'react';
import { useDebounce } from 'ahooks';
import { fetchLocations } from '@/api/location'; // 使用统一的 API 接口封装
import { useAuth } from '@/hooks/useAuth'; // 强制使用鉴权 Hook

// UI 和逻辑彻底分离
const useLocationSearch = () => {
  const [query, setQuery] = useState('');
  const [locations, setLocations] = useState<Location[]>([]);
  const [loading, setLoading] = useState(false);
  const { getToken } = useAuth(); // 遵循安全规范

  const debouncedQuery = useDebounce(query, { wait: 500 });

  React.useEffect(() => {
    if (!debouncedQuery) return;

    const loadData = async () => {
      setLoading(true);
      try {
        const data = await fetchLocations(debouncedQuery, getToken());
        setLocations(data);
      } catch (err) {
        console.error(err);
      } finally {
        setLoading(false);
      }
    };
    loadData();
  }, [debouncedQuery, getToken]);

  return { query, setQuery, locations, loading };
};

export const SearchLocation = () => {
  const { query, setQuery, locations, loading } = useLocationSearch();

  // 使用 Tailwind CSS 设计系统
  return (
    <div className="p-4 bg-white rounded-lg shadow-sm">
      <input
        type="text"
        className="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-primary-500 focus:border-primary-500"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="search locations..."
      />
    </div>
  );
};

通过这些规则,AI 的代码输出变得更加模块化和规范。无论是网络请求、样式设计还是安全验证,都严格按照你的架构标准来执行。


你在驾驭,还是在旁观?

很多人认为编写 Prompt 是一件神秘的事情,但真正的 AI 辅助开发本质上是一次高强度的自动化 Code Review。如果你不能有效地管理项目依赖关系或提供清晰的类型定义,那么生成的代码可能会偏离预期的质量和标准。

AI 不会产生低质量代码;如果它产生了这样的结果,则说明你没有正确地设置架构边界或者提供了不明确的需求描述。因此,在严肃商业开发环境中,确保 AI 生成高质量代码的关键在于:

  • 清理和管理项目依赖关系
  • 提供精准的 TypeScript 类型定义
  • 设定严格的系统边界限制

否则,最终导致低质量代码出现的人,实际上是那个没有明确架构边界,只是机械地使用 Tab 键和回车键的开发者。