AI 生成的代码都是一坨屎?聊聊怎么给 Agent 制定工程约束
- 前端开发
- 14天前
- 13热度
- 0评论
如何为AI编写高效且规范的前端代码
高性能JavaScript在现代Web开发中扮演着重要的角色。随着人工智能技术的发展,越来越多地利用AI来生成代码以提高开发效率。然而,在实际应用中,如果不对AI进行适当的约束和指导,很可能会产生难以维护和扩展的“垃圾”代码。
AI生成代码的问题
有次前端架构评审会上,一位同事提到他们的团队在使用某款流行的国产AI编码工具后,虽然起初提高了工作效率,但后来发现生成的代码极其混乱。具体表现为:
- 一个复杂的用户界面模块被硬塞到了单一文件中,且代码量接近2000行。
- 文件中充斥着随意定义和使用的变量名、繁杂的正则表达式以及多层嵌套的回调函数。
团队尝试对这些代码进行迭代更新时发现几乎无法下手。这不禁让人怀疑:是否是AI工具本身的问题?还是说团队在使用过程中没有遵循合理的工程规范?
AI与初级开发者的相似性
AI本质上就像一个具备无限精力和快速输入能力,但缺乏实际项目经验的初级开发者。它可能精通各种开源代码库,却难以理解特定公司特有的技术栈、设计模式以及网络请求相关的安全措施。
例如,在为某业务需求生成防抖搜索框时,未受约束的AI可能会做出如下行为:
- 直接调用原生fetch函数而忽略项目中已封装好的Axios拦截器。
- 使用硬编码样式而非遵循设计系统中的标准变量和类名。
- 手写防抖逻辑而不是复用现有的可维护代码库。
如何制定有效的工程约束
为了确保AI生成的代码能够满足企业级应用的要求,需要从多个维度对它进行规范:
- API调用:强制使用项目中的HTTP客户端来处理请求与响应,并在其中加入Token验证逻辑。
- 样式管理:鼓励基于现有的CSS框架或变量库生成组件样式,以保持视觉一致性。
- 防抖/节流:复用现有实现的高阶函数而不是重新编写,减少冗余。
示例代码
下面是一个规范化的搜索框实现示例,展示了上述几条建议的应用:
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 键和回车键的开发者。