你有没有遇到过这种事:AI 把代码写到了错误的文件夹里
上周我帮一个朋友 Review 他的项目。他用 Cursor 做了一个电商网站,功能倒是做出来了,但项目结构是这样的:
src/
├── components/
│ ├── Header.tsx
│ ├── ProductCard.tsx
│ ├── Cart.tsx
│ ├── LoginForm.tsx
│ ├── api.ts
│ ├── helpers.ts
│ ├── types.ts
│ ├── useCart.ts
│ ├── useAuth.ts
│ └── ... 另外 47 个文件
所有东西都塞在一个 components/ 文件夹里。组件、API 调用、类型定义、自定义 Hook,全在一起。52 个文件平铺在同一层。
他跟我说:"我让 Cursor 加一个收藏功能,它把收藏逻辑写到了 Cart.tsx 里面。我让它加一个用户设置页面,它修改了 LoginForm.tsx。AI 是不是太笨了?"
我说:不是 AI 笨,是你的项目结构在"误导"它。

AI 怎么理解你的项目?
这里有个很多人不知道的事实:AI 在写代码之前,首先要做的是"理解项目结构"。它会读你的目录树,通过文件名和文件夹名来推断每个文件的职责。
这意味着:
- 如果你的文件夹叫
components/,AI 会认为里面都是 UI 组件 - 如果你的文件叫
helpers.ts,AI 不知道里面是什么——日期工具?字符串处理?API 封装?全都有可能 - 如果 52 个文件平铺在一起,AI 要逐个读取才能搞清楚每个文件是干什么的——但上下文窗口有限,它不可能全读
AI 友好 vs AI 不友好的项目结构
来看一个对比:
| AI 不友好 | AI 友好 |
|---|---|
src/components/ 放所有东西 | src/components/ 只放 UI 组件 |
helpers.ts(啥都有) | utils/date.ts、utils/format.ts(按功能拆) |
api.ts(所有 API) | services/product.service.ts、services/user.service.ts |
types.ts(所有类型) | types/product.types.ts、types/user.types.ts |
文件名:comp1.tsx、comp2.tsx | 文件名:ProductCard.tsx、CartSummary.tsx |
第一,按职责分目录。 组件归组件、服务归服务、类型归类型、工具归工具。AI 看到 services/product.service.ts 就知道"这是产品相关的 API 调用",不需要打开文件就能猜到八九不离十。
第二,文件名要"自解释"。 ProductCard.tsx 比 Card2.tsx 好一百倍。AI 看到文件名就知道这个组件是干什么的,要加收藏功能时它不会跑去改购物车组件。
第三,单一职责。 一个文件做一件事。不要把产品类型、用户类型、订单类型全塞在一个 types.ts 里。拆开之后,AI 在需要产品类型时只需要读 product.types.ts,不用把不相关的 500 行用户类型和订单类型也加载进上下文窗口。

一个实用的目录模板
我自己做项目,不管是 Next.js 还是 React,基本都用这个结构:
src/
├── app/ # 路由/页面(Next.js App Router)
├── components/
│ ├── ui/ # 通用 UI 组件(Button, Modal, Input)
│ ├── layout/ # 布局组件(Header, Footer, Sidebar)
│ └── features/ # 业务组件(ProductCard, CartItem)
├── services/ # API 调用,按实体分文件
├── hooks/ # 自定义 Hook
├── types/ # TypeScript 类型定义
├── utils/ # 工具函数,按功能分文件
├── constants/ # 常量
├── styles/ # 全局样式
└── config/ # 配置文件
这个结构好在哪?AI 看到这个目录树,不需要打开任何文件就能知道:"要加一个新 API,去 services/;要加一个新组件,看需求去 ui/ 还是 features/;要加一个新类型,去 types/。"
话说回来,这不是唯一正确的结构。有些团队喜欢按功能模块分目录(feature-based),比如 src/product/、src/cart/、src/user/,每个模块里面有自己的 components、services、types。这种结构也可以——关键不是用哪种,而是要统一、清晰、让 AI 看文件名就能猜到内容。

一个容易忽略的坑:index.ts 地狱
你见过这种结构吗?
src/
├── components/
│ ├── index.ts
│ ├── Product/
│ │ ├── index.ts
│ │ └── ProductCard/
│ │ ├── index.ts
│ │ └── ...
每个文件夹都有一个 index.ts 做 re-export。人类觉得 import 路径更短了很方便,但对 AI 来说这是噩梦——它看到一堆 index.ts,不知道哪个是哪个。当你让 AI 修改 ProductCard 组件时,它可能改错了 index.ts。
我的建议是:组件文件直接用组件名命名,少用 index.ts 做中间层。或者如果你一定要用 barrel exports,在 CLAUDE.md 里说清楚。
为什么 AI 在你的项目里总是"迷路"?
项目结构设计如何决定 AI 写代码的准确率