
丨 导语 Vibe Coding 一年后,再谈变与不变。

一年前,我坚信"代码是程序员的核心资产"。
但当 AI 能在几分钟内生成数千行代码,这份笃定开始松动。我不禁自问:还要继续积累代码吗?我们的价值,又将锚定于何方?
这个问题之所以让人焦虑,是因为它关乎我们作为开发者的"生存"。
过去一年,我在 Vibe Coding 的实践中不断思考这个问题。在技术剧变的表象之下,试图找到那些变化的和不变的。最终,我把思考浓缩为三个关键词:代码、prompt、领域模型。
接下来,我将展开这三个要素,探讨在技术快速迭代中,哪些能力构成了我们的护城河。

在 AI 时代,积累代码还必要吗?
答案是:必要。而且文章中总结的原则依然适用:
而且要重点积累特定问题的最佳实现,比如性能/安全/可靠性相关 —— 这是现阶段唯一能胜过 AI 的地方:在复杂问题的解决上更快。
此外,积累代码最大的用途不在于复用,而是萃取可稳定“复现”最佳代码实践的 prompt。
所以,代码积累的最大价值已经从"复用"转向"复现"。

传统开发中,我们积累代码是为了复用——把经过验证的代码片段导入或者拷贝到新项目中。这种方式的问题在于:
而在 AI 辅助开发中,我们的目标不再是"把代码复制过来",而是让 AI 在新的上下文中,可靠地复现我们的最佳实践。这意味着:
这个转变的意义在于:我们不再受限于具体代码的可复用性,而是提升到了可复现的方法论层面。一个好的 Prompt,能让 AI 在千变万化的业务场景中,始终生成符合我们质量标准的代码。
这就引出了下一个核心问题:如何写出能稳定复现最佳实践的 Prompt?
你是否有过这样的体验:编写 Prompt 时,感觉就像在写 SQL——你只需要描述想要什么结果,数据库引擎会自动生成最优查询计划并执行。
这其实揭示了 Prompt 的本质:一种面向 AI 的"声明式编程"。
在命令式编程中,我们告诉计算机"怎么做"(how);在声明式编程中,我们只需描述"要什么"(what)。SQL 是数据查询领域的声明式语言,而 Prompt 则是 AI 代码生成领域的声明式语言。它承载着我们的意图、约束条件和质量期望,然后由 AI 负责生成具体实现。
两者的相似之处在于:
但 Prompt 的挑战更大:
这个方向至关重要,因为:

基于一年来的实践,下面的方法能有效帮助我将代码中的最佳实践,系统化地转化为可复现的 Prompt:
本质:为 AI 提供清晰的目标、参考特定的人物角色,或提供明确的背景信息,就像给实习生布置任务一样详细。
1:明确任务三要素
一个完整的 Prompt 应该包含:
2:设定角色和风格
这些方向指引会激活 AI 训练数据中的特定"语义集群",让生成的代码更符合专业标准。
本质:通过约束输出格式,确保生成代码的一致性和可集成性。
格式约束不仅是编码风格,更是架构规范的体现。应该明确:
当 AI 生成的代码符合统一格式,它可以无缝集成到现有项目中,减少人工修改成本。
本质:用具体案例消除歧义,让 AI 理解"好代码"的标准。
这是最强大的原则:示例越精准,模型越容易对齐你的意图。
特定任务40% 的准确率提升,具体数据可搜索 few-shot vs zero-shot。
关键技巧:示例应该来自你积累的最佳代码资产,它们已经经过生产验证。
注意: 一般来说,提供3到5个高质量的示例可以在可靠性和创造性之间取得最佳平衡。示例越多、越相似,输出的创造性就越低,但其格式和风格的可靠性则越高。
一个非常重要的技巧:在评估提示中加入一句“让我们一步步思考”(Let's think step by step)。通过“给模型时间思考”,AI的输出不仅会给出结果,还会附带理由。 这使得结果更加可靠和透明,也为我们提供了调试和优化 prompt 的线索。
像迭代代码一样,我们也要持续评估 Prompt 的输出质量,并根据反馈进行迭代。
而代码资产是迭代效果的基准,所以从代码萃取 Prompt 的方向至关重要。
具体的代码实践来自前端已死命题背后:UI开发范式的底层变革
# 数据模型设计原则
## 基本原则
原子数据模型:接口(唯一数据源)
1. 一层层根据视图需要:计算数据模型
2. 不要改原子数据模型
## 注意事项
- 每一步不改上一层数据模型
- 所有模型,都是来源于原子数据模型的组合和运算
## 接口返回统一状态结构
interface AtomicMetricState {
value: 业务数据
loading: boolean
error: Error | null
}
## 实现模式
### 1. 原子数据模型层
原子数据模型是接口返回的原始数据,应当保持不变:
// 定义接口原始数据类型
export interface ApiResponse {
code: number;
msg: string;
data: ApiData;
}
// 在composable中存储原始数据
const rawApiData = ref<ApiResponse|null>(null);
// 获取数据时直接存储原始响应
const fetchData = async () => {
const response = await api.getData();
rawApiData.value = response;
};
### 2. 计算数据模型层
视图需要的数据通过计算属性从原子数据模型派生:
// 定义视图模型
export interface ViewModel {
// 视图所需的属性
}
// 通过计算属性转换数据
const viewData = computed<ViewModel[]>(() => {
if (!rawApiData.value) return [];
// 转换但不修改原始数据
return rawApiData.value.data.items.map(item => ({
// 构建新的视图模型对象
id: item.id,
displayName: item.name || '未命名',
// 可以保留原始数据引用
raw: item
}));
});
### 3. 组件中的二次计算
组件中可以基于计算数据模型进行进一步的计算:
// 过滤、排序等操作创建新的数组,不修改上游数据
const filteredData = computed(() => {
return viewData.value.filter(item =>
item.displayName.includes(searchText.value)
);
});
const sortedData = computed(() => {
return [...filteredData.value].sort((a, b) =>
a.displayName.localeCompare(b.displayName)
);
});
## 优势
- 数据流向清晰,易于调试和理解
- 数据操作无副作用,减少bug
- 组件逻辑与数据处理分离,提高可维护性
- 原始数据不变,便于回溯和状态管理
你是一位精通 Vue3 Composables API 和函数式编程的高级前端工程师,
严格遵循不可变数据原则和单向数据流设计。
# 核心原则
1. 三层架构:原子数据层 → 计算数据层 → 视图层
2. 原子数据不可变,只在接口获取时赋值
3. 所有转换通过 computed 完成,使用纯函数
4. 创建新对象/数组,永不修改原始数据
5. 数据流单向且可追溯
# 技术约束
- TypeScript,类型定义完整
- 大型数组使用 shallowReactive 优化
- 原子状态包含 value、loading、error
- 遵循提前终止原则
# 命名规范
- 原子数据:atomicState、rawData
- 计算属性:描述性(activeServers、filteredData)
- 函数:动词开头(fetchData、calculateMetrics)
# 任务
[描述具体需求]
# 输出格式
按以下结构组织代码:
// 1. 类型定义
interface ...
// 2. 原子数据层
const atomicState = shallowReactive({...});
// 3. 计算数据层
const computed1 = computed(() => {...});
// 4. 数据获取
const fetchData = async () => {...};
# 参考示例
项目中的正面案例:
- xxx.ts:多维度数据扩展
- xxx.ts:数据增强模式在微信支付监控前端项目中,对比了优化前后的 Prompt 效果:
优化前的问题:
优化后的改进:
结果:优化版 Prompt 一次生成即可通过,代码质量显著提升。
上述优化版 Prompt 适用于简单场景。但面对复杂任务(十几个接口、多层数据转换),需要 think step by step,在 prompt 中拆分为三个连续步骤:
第一步:定义原子数据模型层
# 任务
基于以下 API 接口定义,创建原子数据模型:
- 接口 1:getServerInstances
- 接口 2:getAppSetNodes
- 接口 3:getGrayDeployInfo
# 要求
- 使用 shallowReactive 存储
- 包含 value、loading、error 三要素
- 只定义数据结构,不做任何转换第二步:创建计算数据模型层
# 任务
基于第一步的原子数据,创建以下计算属性:
1. moduleInstance:聚合三个数据源的 IP
2. currentModuleInstance:过滤激活的实例
# 要求
- 使用 computed
- 纯函数转换
- 创建新对象,不修改原数据第三步:组件中的二次计算
# 任务
基于第二步的计算数据,实现视图层的最终数据:
- 按 IDC 分组显示
- 支持搜索过滤
# 要求
- 继续使用 computed
- 保持单向数据流渐进式引导的优势:
将复杂任务分解,AI 依据清晰的思维链(任务步骤)生成高质量代码。
领域驱动设计(DDD),在 AI 时代,不仅是团队的协作语言,更是个人萃取知识的强大工具。
前面我们讨论了如何从代码中萃取"泛化能力"更强的 Prompt。但软件开发中,代码只是冰山一角,水面下还有更深层的东西:业务规则、领域知识、问题本质。
当我们进入一个新的业务领域,往往会被海量信息淹没:业务术语、流程规则、数据关系、…… 需要一种方法来帮助我们从具体问题出发,提炼出清晰、简洁、有力的核心概念及其关系。 这个过程就是领域建模。
领域建模是一个从具体到抽象的过程:
这个过程的产出,就是领域模型——一个能够准确描述问题域的概念体系。
领域模型和所解决的问题紧密相关。
领域模型不是对现实的全面镜像,而是针对特定问题的有损压缩。它的价值在于:
正因如此,建模活动本质上是一种高强度的知识学习、吸收、提炼和固化(knowledge crunching)过程。
传统上,领域驱动设计(DDD)主要被视为团队的协作语言——帮助技术人员和业务人员建立共同理解。
但在 AI 时代,DDD 获得了新的个人价值:它是开发者萃取深度知识的强大工具。
为什么这么说?因为:
换句话说:代码会过时,框架会更替,但对业务本质的理解——凝结在领域模型中的洞察——具有长期价值。
监控是典型的数据密集型领域,涉及多种数据类型:日志(logs)、追踪(traces)、指标(metrics)、事件(events)、告警(alerts)。

通过建模过程,我得到了两点关键洞察:
洞察 1:单纯了解监控领域,无法做好监控系统
洞察 2:日志是唯一事实源
这两点洞察,如果没有经过系统化的领域建模,很容易被淹没在具体的实现细节中。而一旦提炼出来,它们就成为了指导后续开发的"第一性原理"。
到这里,我们已经讨论了 AI 时代开发者的三大核心资产:代码、Prompt、领域模型。它们代表了"变化"——我们需要适应的新范式。
但在这些变化之下,有些东西始终不变。
框架会过时,语言会更替,工具会淘汰,技术栈会重构——技术浪潮来了又去。但有些核心能力,如同基石,穿越技术周期而不变。即便在 AI 改变一切的时代,这些能力依然是开发者的根本。
如果你观察过觅食中的蚂蚁,会发现一个有趣的现象:
大部分蚂蚁排成整齐的队列,沿着信息素的轨迹,在巢穴和食物源之间往返。这是高效的"剥削"(exploitation)策略——利用已知的最优路径。
但仔细观察,你会发现总有一定比例的蚂蚁似乎在"漫无目的"地徘徊,偏离主路线,到处探索。这些蚂蚁在做什么?它们在执行"探索"(exploration)策略——寻找可能更好的路径。
这种机制的精妙之处在于:通过持续的随机探索,蚂蚁群体能跳出局部最优解,发现全局最优解。如果所有蚂蚁都只走已知路径,当环境变化(比如导向美食的原有路径被阻断)时,整个系统就会崩溃。
这对开发者的启示是什么?
在 AI 时代,我们更容易陷入"局部最优":
因此,我们需要刻意保留"探索模式":
就像蚂蚁群体的智慧来自于"剥削"与"探索"的平衡,我们的成长也需要在"利用 AI 提效"和"保持独立思考"之间找到平衡点。
在《数据密集型应用系统设计》(Designing Data-Intensive Applications)中,Martin Kleppmann 提出了一个深刻的观点:
大多数技术问题没有"绝对正确"的答案,只有权衡(trade-offs)。
权衡不是非黑即白的开关,而是一道连续的光谱。 在光谱的不同位置,系统展现出不同的特性。理解这道光谱,就是理解技术的本质。
理解本质,才能做好权衡。在 AI 时代,这个能力变得更加关键:
技术在变,范式在变,工具在变。但保持探索、深挖本质这两种能力,是穿越技术周期的不变锚点。
回到开头的问题:代码贬值了吗?
我的答案是:代码的形式在变,但价值并未贬值,只是转移了。
在 AI 时代,开发者的价值不再仅仅体现在"写了多少行代码",而是:
代码、Prompt、领域模型是我们的新资产;探索精神、本质思维是我们的不变能力。
变与不变,相辅相成。拥抱变化,我们才不会被时代抛弃;守住不变,我们才能在变化中找到锚点。
这就是 Vibe Coding 一年后,我对"开发者护城河"的理解。