一、核心回答
核心就是让 AI 生成前先查,能复用就别新建;如果确实要新建,生成后把它纳入组件库,再人工确认一次。
这句话就够作为第一层答案。
二、为什么“让 AI 先查组件”还不够?
因为真正的问题不是:
有没有一个名字叫 Button 的组件?而是:
这个需求 ↓ 项目里有没有功能相同/相近的组件? ↓ 能不能直接复用? ↓ 能不能通过扩展现有组件解决? ↓ 如果不能,才需要新建例如项目里已经有:
ConfirmButton SubmitButton OkButtonAI 单纯搜索文件名,很可能认为:
我要 ConfirmButton 项目里没有 ConfirmButton ↓ 创建 ConfirmButton但实际上:
SubmitButton OkButton ConfirmButton ↓ 功能高度重叠所以组件复用不能只靠名称搜索,而要让 AI 能理解组件的功能、接口、适用场景和所属业务域。
三、第一步:建立 AI 能理解的组件索引
核心就是给组件建立一份机器可读的组件元数据。
例如:
{"name":"ConfirmButton","description":"用于确认用户操作的按钮","category":"business","domain":"order","props":{"text":"string","loading":"boolean","disabled":"boolean","onConfirm":"() => void"},"scenarios":["订单确认","支付确认","删除确认"],"examples":["<ConfirmButton text=\"确认支付\" />"],"path":"src/components/order/ConfirmButton"}这样 AI 搜索的就不只是:
ConfirmButton.tsx而是:
功能 + Props + 使用场景 + 业务域 + 示例 + 代码位置这里可以进一步做语义检索
组件数量比较大的时候,可以把这些 metadata 做 embedding,放到向量数据库里。
用户说:
“我要一个用于确认订单提交的按钮。”
检索出来:
ConfirmButton 相似度:0.91 SubmitButton 相似度:0.86 ActionButton 相似度:0.63AI 就有机会发现:
已经有一个非常接近的 ConfirmButton,不应该直接创建新的。
但这里要注意:
向量相似度只能负责“召回候选”,不能直接决定“必须复用”。
这是很重要的面试点。
四、第二步:把“存量检查”变成生成流程的一部分
不能只是告诉开发:
“你让 AI 记得先查。”
而应该把它变成固定流程。
例如:
用户提出需求 ↓ 检索组件索引 ↓ 找到候选组件? ↙ ↘ 是 否 ↓ ↓ 分析是否 进入新组件设计 可以复用 ↓ ┌──────────────┐ │ 直接复用 │ │ 扩展现有组件 │ │ 新建组件 │ └──────────────┘甚至可以把规则直接放进 AI Agent 的工作流:
Step 1:检索组件索引 Step 2:分析候选组件 Step 3:判断能否复用 Step 4:如果可以 → 给出复用方案 Step 5:如果现有组件需要小幅扩展 → 优先修改/扩展 Step 6:只有无法满足需求时 → 创建新组件 Step 7:新组件创建后 → 更新组件索引这比单纯在 Prompt 里写一句:
“生成前检查 components 目录。”
可靠得多。
五、第三步:怎么处理“80% 相似,但 Props 不一样”?
这是这道题真正开始拉开差距的地方。例如:
ConfirmButton已有:
<ConfirmButton text="确认" loading={loading} onConfirm={handleConfirm} />现在 AI 要生成:
<SubmitButton label="提交" submitting={submitting} onSubmit={handleSubmit} />表面上:
代码结构很像但接口不同。这时候不能简单说:
“相似度超过 70%,直接复用。”
因为代码相似 ≠ 业务上应该复用。
正确做法应该是:
候选组件召回 ↓ 功能相似度 ↓ 接口相似度 ↓ 代码结构相似度 ↓ 业务域 ↓ 依赖关系 ↓ 最终判断例如最终得到:
发现 ConfirmButton 功能相似度:92% 代码结构相似度:84% 接口相似度:68% 业务域:相同 建议:扩展 ConfirmButton 而不是创建 SubmitButton如果只是接口不同,但本质功能相同,可以考虑:
统一 Props或者:
在现有组件上增加能力而不是继续造一个新的组件。
六、AST 到底有什么用?
AST 更适合做代码结构分析。
例如:
function ConfirmButton({ loading, disabled, onConfirm }) { return ( <button disabled={loading || disabled} onClick={onConfirm} > 确认 </button> ); }可以通过 AST 分析:
组件结构 ├── props │ ├── loading │ ├── disabled │ └── onConfirm ├── button ├── disabled 条件 ├── click handler └── children然后和另一个组件进行结构层面的比较。所以更准确的说法是:
向量检索负责从大量组件里召回“可能相关”的候选,AST 等代码分析手段负责进一步比较代码结构,最后再结合功能和业务域做判断。
这句话就比较像真正做过工程的人。
七、第四步:最关键的是业务域隔离
这是比较重要、但还可以讲得更深的地方。假设有:
订单域: OrderConfirmButton 支付域: PaymentConfirmButton两个组件可能长得非常像:
按钮 + loading + disabled + confirm甚至代码可能达到:
90% 相似但不能因为相似就合并。因为:
订单域 ↓ 订单状态 订单权限 订单接口 订单业务规则 支付域 ↓ 支付状态 支付权限 支付接口 支付业务规则强行抽成:
CommonConfirmButton很可能最后变成:
<CommonConfirmButton isOrder={...} isPayment={...} orderStatus={...} paymentStatus={...} ... />最后组件变成一个巨型条件分支。所以:
组件复用的原则不是“越多复用越好”,而是“
稳定的共性才抽,业务差异大的就隔离”。
这句话非常值得背。
八、所以组件应该怎么分层?
比较合理的是:
组件体系 │ ┌──────────────┼──────────────┐ ↓ ↓ ↓ 基础组件 通用业务组件 业务域组件 │ │ │ Button/Input UserAvatar OrderCard Modal/Table Upload PaymentPanel1. 基础 UI 组件
例如:
Button Input Modal Select Table特点:
业务无关 稳定 复用范围大应该尽可能统一。
2. 通用业务组件
例如:
UserAvatar FileUploader AddressSelector多个业务都需要,但已经带有一定业务语义。
3. 业务域组件
例如:
OrderCard PaymentPanel CouponSelector这种组件虽然可能和其他业务组件长得很像,但业务边界明显。
不要为了消灭重复代码而强行合并。
九、完整流程应该是这样的
真正落地以后,可以形成一个闭环:
用户需求 ↓ AI 理解需求 ↓ 检索组件 Metadata ↓ ┌─────────┴─────────┐ ↓ ↓ 找到候选组件 没找到 ↓ ↓ 功能/接口/代码分析 新组件设计 ↓ ↓ 业务域判断 代码生成 ↓ ↓ ┌──────┼──────┐ ↓ ↓ ↓ ↓ ↓ 直接复用 扩展 隔离 自动登记 Metadata │ │ │ ↓ └──────┴──────┴──────→ Code Review ↓ 合并/淘汰冗余 ↓ 更新组件索引这才真正形成:
检索 → 判断 → 复用/新建 → 登记 → Review → 再进入索引
的闭环。
十、那为什么还需要人工 Review?
因为有些事情 AI 很难单独做最终决策。
例如:
A 组件和 B 组件 90% 相似AI 可以告诉你:
高度相似但它不一定知道:
A 属于订单域 B 属于支付域更不知道:
未来两个业务团队是否会独立演进所以最终还是需要工程规则:
AI: 负责检索、分析、推荐 工程规则: 负责边界约束 人工: 负责最终架构决策十一、这道题真正考什么?
它考的不是:
“你会不会让 AI 写组件。”
而是:
“你能不能让 AI 在现有工程约束下写组件。”
普通开发的思路:
需求 ↓ AI生成 ↓ 提交高级工程师的思路:
需求 ↓ 检索现有资产 ↓ 判断复用/扩展/新建 ↓ 生成 ↓ 登记 ↓ Review ↓ 持续治理所以这道题真正考的是:
AI Coding + 组件复用 + 工程治理 + 架构边界。
十二、面试官继续追问
追问 1:AI 为什么不能直接扫描整个项目?
可以扫描,但扫描 ≠ 理解 ≠ 正确决策。
项目里的组件可能:
命名不同 目录不同 Props 不同 业务域不同 文档缺失 代码已经废弃所以需要先建立结构化的组件索引,降低 AI 每次从源码重新理解整个项目的成本。
追问 2:为什么不用文件名搜索?
因为:
ConfirmButton SubmitButton OkButton完全可能是三个名字,但实际上是同一种组件。
所以需要:
关键词检索 + 语义检索 + 代码结构分析 + 业务域过滤追问 3:向量相似度高就一定复用吗?
不一定。向量检索主要用于:
召回候选,而不是直接做最终决策。
最终还要结合:
功能 接口 代码结构 业务域 依赖 演进关系判断。
追问 4:两个组件 90% 相似,为什么不合并?
因为:
技术相似不代表业务上应该复用。
如果两个组件属于不同业务域,而且未来演进方向不同,强行复用可能带来更大的耦合。
追问 5:AI 新生成组件以后怎么办?
不能生成完就结束。应该:
新组件 ↓ 生成 Metadata ↓ 注册组件索引 ↓ Code Review ↓ 进入组件库这样下一次 AI 才能检索到它。
追问 6:如果已经产生了三个重复组件怎么办?
可以定期做:
组件扫描 ↓ 语义相似度分析 ↓ 代码结构分析 ↓ 识别重复/近似组件 ↓ 人工确认 ↓ 合并 ↓ 废弃冗余组件所以组件治理不是一次性的,而是一个持续过程。
十三、最终满分答案
如果面试官只给你几十秒,我建议直接这么说:
让 AI 生成组件时,我不会只要求它先查目录,而是给项目建立一套可检索的组件索引,把组件的功能、Props、使用场景、代码位置和业务域都记录下来。AI 生成前先检索,优先判断是直接复用、扩展现有组件还是新建;对于相似组件,可以结合语义检索和 AST 等代码分析手段做二次判断,但最终还要结合业务域决定是否复用。新组件生成后再登记到索引,并通过 Code Review 和定期治理清理重复组件。
再压缩成一句真正适合第一句话的:
核心就是让 AI 生成前先查、相似时先判断、生成后再登记,并用业务域控制复用边界。
这比单纯说“让 AI 先查组件,没有就生成”高一个层级,因为后者解决的是有没有查,而真正的工程问题是查到了以后怎么判断该不该复用,以及新组件怎么反过来进入这套体系。