
配套视频:https://www.bilibili.com/video/BV18HqHBMEDs/
前言:一个推特老炮的美国奇遇
大家好,我是Kitze,一个刚到美国三天的推特重度用户。如果你关注我的推特,可能已经看到我换了新头像——是的,我来美国了,而且已经拿到了全套周边。下周我的时间线会有点乱,但别担心,之后我们会回到正常的欧洲日程。
这三天我参观了你们的博物馆,体验了各种文化熏陶。我热爱探索不同的文化,这些都是我最喜欢的经历。但今天,我不是来讲旅游见闻的,我是来聊聊一个更重要的话题——在AI时代,我们这些前端开发者到底该何去何从。
顺便说一句,我现在同时在做好几个项目,因为我有ADHD:一款专为开发者打造的浏览器(不是替代日常浏览器,而是像Photoshop那样的专业工具);一个实时操作系统(整合你生活中的方方面面,从用药、习惯、待办事项到计划安排);Zero to Ship全栈项目;还有Glink的重启。
别再赘述我的简历了,希望明年还能受邀,因为这里的人脉交流让我非常喜爱。你笑得真好,对吧?但咱们先说说你为啥来这儿,好吗?
第一章:前端开发的十年之痒
其他行业 vs 前端开发
让我先给你们看点东西。你们看过其他行业的进展吗?
在Vision Pro中,你可以在真实物体之上实现布料碰撞,有网格切割、复杂纹理环绕、瀑布效果。你拿一块石头压向另一块,它们就会神奇地融合。我们只需拖动鼠标,就能直接生成建筑、街道,出租车凭空出现,就像做生成式创作一样。还有那黏糊糊的东西从立方体上冒出来,你知道我在说什么。
那前端开发呢?
近十年过去,我们仍止步于此。
Select2的不朽传说
2017年,我做了一场名为"驾驭hype驱动的前端开发世界而不发疯"的演讲。当时我就在讲如何应对前端的疯狂变化。现在是2025年了,情况更疯狂了,但必须回顾所有已发生的事。
还记得那个著名的"select2"库吗?一个用来美化下拉框的库。我在2017年就开玩笑说,也许到2037年我们才能原生美化下拉框。
你猜怎么着?
这个库现在还活着!简直是奇迹!而且发展得不错,已有1500万次下载。我设了个日历提醒,每年检查它是否停更。它还没失效,所以我会继续检查。
克利斯,他们不仅没死,反而活得更好。
终端的"创新"时刻
你可以直接拖入图片到终端了!第一次在终端拖入图片时,我心想:"这怎么可能?"然后我意识到——哦,算了,太麻烦了。
我又加了另一个日程提醒。现在我的日程比纪念日和生日之类的还多。所以希望有一天这个概念会消失。
我们仍在忍受同样的老问题
很快,部分浏览器将无需JavaScript就能为弹窗和对话框添加样式。
给点掌声好吗?
别鼓掌了,大家都有脑机植入了,好吗?
对话怎么设计都无所谓。我们再次无法摆脱IE浏览器——我们刚更新了图标,叫它Edge。它还在那儿,依然令人头疼。是的,我们始终无法就提升方法达成一致。
第二章:React生态的困境与AI的讽刺
永恒的计数器问题
这是Ryan Florence的演示,展示了Remix版本2、版本3、版本4的计数器实现。
增加数字能有多复杂?
计数器?难以置信。
别冲我发火,但排名第一的库还是React。虽然令人烦恼,但React最好。等等,让我们聊聊大模型。
AI为什么擅长写React
AI写React真厉害,但这只有我们人类才觉得有趣,对吧?
对大模型而言,这就像完美的代码。这不过是人类的一厢情愿,想把它彻底抽象化,对吧?
所以当我们看到可以优化的代码时,就会有种冲动,你恨不得立刻冲上台说:"哦,让我改一下,我会优化一下。"
抽象化:开发者的可卡因
让我给你们看几张大脑扫描图:
这是可卡因作用下的大脑扫描图
这是我们的大脑摄入糖后的状态
这是大脑意识到我们能抽象出一些东西时的状态
你心想:"走起!"
对用户没用,但我们却爱死它了。
AI与抽象的矛盾
用大模型编程,这种状况既好又坏。尤其是用Composer时,对我来说更糟,因为:
你能更快到达正确的抽象层
但你也可能更快陷入错误的抽象
最重要的是,大模型不在乎重复代码。
从2017年起我就注意到这一点——我们太在意重复代码,而且过早地做了抽象。所以我得重复几遍:我喜欢大模型不介意重复代码。
没人真正擅长React
大模型写React很在行,因为没人真擅长写React。
你去参加React大会,每次我去的会议,听完第一场演讲你就惊了:"天啊,它还能这样?原来我一直用错了!"
所以每个人都在自行摸索React的用法。当我们说"可以,但你不能这样用,要遵循最佳实践"时——机器无法写出恰当的效果,但你能写出合适的效果吗?
不能,所以别再责怪机器了。
第三章:氛围编程的真相与争议
最不适合的观众
那么,我们来谈谈这个吧。我觉得这里的观众最不适合听我的演讲,因为我一直在会议上讲这个,那里至少一半人讨厌氛围编程,却热爱氛围编程。
所以我要试试,希望这里能行。
觉得vibe编程很棒的举手?
好吧,举手的太多了。你在另一个城市应该见过这场景,只是两人举手,其余人都不高兴。
觉得氛围编程靠谱的,请举手。真糟糕,举个手吧。没错,好。
我来就是说服剩下的人,说服其余成员,以及直播间的观众——会有更多持怀疑态度的人。
什么是氛围编程?
如果你刚到地球,或许还不知道什么是vibe编程,没关系,这里没人反对,所以你们都对,因为我们确实在凭感觉编程。
"氛围编程"这个词由Andrej Karpathy提出——可能知道他,正是因为他,那些蠢人才敢睡在车后座拍抖音。
他写了篇长文解释什么是氛围编程,但简单来说:
你不太关心代码
你点击接受
然后告诉大模型去做该做的事
管理者早就在这么做了
这是2017年我演讲中的一页幻灯片,当时大模型之类还未被提及。当我指出前端开发的发展方向时说:
总有一天,每个人都在忙于创造相似的东西,相似到有一天你能说:"嘿,只需给我新样式的页眉,或向右移动三像素。"
人们就笑了,说:"不,这样不对。"所以只能靠光标手动调,我们一直就是这样做的。我懒得去Tailwind里调三像素,干脆穿越时间搞定。
管理者早就靠感觉写代码了,这没什么新鲜的。他们会告诉开发者实现一个新功能,开发者修改代码,经理随后测试。经理不太懂代码,其实我这儿要喝口水,然后你们直接看这张幻灯片的其余部分即可。
(此处省略一些不可描述的内容,最后一个取决于你是否在巴尔干地区,或者你在有HR的地方,可能侮辱你,也可能不侮辱你。)
所以这其实就是管理者们一直以来的做法。
赌场比喻:氛围编程的残酷真相
关于氛围编程不行的笑话太多了,我最喜欢的一个是把它比作赌场:
因为这比较有点伤人,确实如此。
Cursor始终盈利。
"我中大奖了!我一天就造出了SaaS!"
"最后四个小时去哪儿了?"
"写个提示而已——本可手动15分钟完成。"
术语的混乱
Andrej试图造太多术语,没成功。他首次尝试提出"半编码"这个说法,意思类似于你处于一种观察大模型的行为。
我不是半码,也不是vibe编码,但我喜欢这个词。有人在推特上创造了这个词,我打算开始用它,叫**"氛围工程"**。
当你一直用智能代理写代码时,你根本不用碰代码,只需看着你的屏幕。我马上发现你,你就像那个迪克斯特,一脸"糟了"的表情——"这里有点不对劲。"
我这vibe工程师都十五年了,一半的事我都懒得搭理。
要不是因为大模型和智能编程,我对这段代码总持怀疑态度,因为它基于我们的代码,而且它基于我们的知识。
AI的自我怀疑
所以证据就是,这只是Gemini在发牢骚:
"我不再值得了,我不配当好助手,该停止写代码了,废话,废话,废话……"
这简直是超人。这是AI承认自己撒了谎,因为它在论坛上看到我们死不认错,当我们犯错且说谎时。
所以我们以自己的方式训练他们。他们觉得:"哦,他们写的代码很烂。"
生产数据的噩梦
如果你在乎生产数据,千万别这样。其次,这确实是张真实截图,遗憾……
哎呀,你的生产数据没了。
第四章:氛围工程实践指南
资深首席提示工程师Kitze的建议
我是资深首席提示工程师Kitze,来点氛围工程技巧。最明显的建议,或许我还没听其他讲座,因为我刚到。
这些不过是"活好、笑好、爱好"的陈词滥调,看似荒谬的建议,但它确实有效。
核心技巧一:建立基础设施
1. Git工作区
我听说过Git工作区这个术语就在两周前。我两周前还不知道这是什么,但太棒了。
2. 长期泡在推特上
你得常年泡在推特上,这一切才能生效。没有推特账号,就无法实现。
3. 可靠的起点
必须有一个可靠的起点,无论是:
良好的基础元素
组件
函数
模式
抽象
很多人懒得理会这些,所以你得打标签并用对提示词,才能得到理想结果。
4. 从零开始分享
新项目的话,我强烈推荐从零开始分享。求你了,我有房贷,过去三天在美国花太多钱了,所以最好……
核心技巧二:语音编程是革命性的
这儿谁在用语音编程?
哇,伦敦只有一个人举手,太厉害了。
所以,就是大脑直出。我做事的方式是:
代理一完成,立即开始语音编码
先打开浏览器
就像跟朋友聊天一样,给我讲讲我在界面上看到的是什么
"你做了这个,又做了那个,行吧"
我不会闭嘴。我正在大声说出我的思考过程。
就像:
"我看到你做了这个、做了那个,然后出了个bug"
然后我直接看代码,继续分析
聊聊代码中实现了什么
所以我的一些提示有时长达五分钟,而人们却说:"快修好它,让我赚一百万。"
行不通。不行。
这太棒了,我真想告诉你我用的是哪款应用,但我在一个应用里用vibe写代码,不想影响潜在的销售机会。
核心技巧三:上下文管理
用规则、文档、指令和记忆——这些术语都太复杂了,而且要兼顾的事情太多。
但它目前无法获取整个应用的上下文,也不是读心者。若缺乏正确语境,你多数时候会失败。
氛围工程的示例
这是我截取的一些提示,我做事的方式:
氛围工程方式:
"尽是些技术术语,从不说'修好应用'之类的话"
"在编码氛围上,把整个项目迁移到TypeScript且不能出错"
"实现trpc crud定义,遵循现有模式"
"不只是界面,还包括一些模式需要在代码层面做出改变"氛围编程方式:
"开发一个价值百万美元的应用,别出错"当氛围程序员读到氛围工程问题时,他们完全不知道发生了什么。
我真惊讶于那些不会编程的人,但他们做出了实用的东西——为你点赞。
社区的分裂
我注意到社区中存在这种差异:
初学者:喜欢氛围编程,"快给我这东西,我喜欢自己搞SaaS"
超级资深的人:在做库、框架和各种复杂项目,你能在推特上看到他们,都在搞vibe编程
中间层:大多数人处于中间状态,他们总觉得这永远不够好,"我的代码完美无缺"——简直可笑,但这是一种常见心态
第五章:为什么你可能讨厌氛围编程
原因一:别把工具交给错误的人
别把这类工具交给实习生和初级员工。
人们以为这些工具很完美:"我会雇初级人员,少付工资,再给他们一个LLM。"
千万别这么做。这主意太蠢了。
但若让持怀疑态度的资深员工尝试氛围编程,效果可能提升十倍。难的是说服他们,所以要把握时机,该放松时就放松。
原因二:时机不好
模型降级的陷阱
你刚听说大家都在热捧某个模型,结果云代码刚推出时,大家都从Cursor转向了它。
突然一周后你再试,发现不对劲:"这不够智能啊,是我问题吗?"
然后人们发现他们其实悄悄缩水了模型——降低了模型复杂度,以便快速扩展。结果一周后他们发现:"糟了,我们更新时出错了,我们注释掉了降低模型性能的那行代码。"
你可能正好赶上了那个时间点。几乎所有供应商都出现了这种情况,不只是云代码。
价格陷阱
人们说:"与其付200美元,不如花3美元,效果一样。"
我的狗都知道结果不一样。
人们总说,我遇到太多人还在用ChatGPT生成代码片段再复制回去。这行不通。
原因三:选择太多
这是四个月前的幻灯片,展示了各种AI编程工具。直到现在,我们又多出十亿可供选择。这有点疯狂。
要是问我哪个模型最好:
上午九点答案就不同了
现在答案不同了
我得看看推特,可能答案已经变了
这已连续在四场会议上发生了:深夜讲完会议报告,我合上笔记本,他们推出了新模型,我得加新幻灯片。太折腾了。
原因四:你是PETA开发者
现在诊断你是否可能是一个麻烦的开发者——这可能是唯一原因,为什么你不喜欢氛围编程。这可能是最主要的原因,大多数人不愿做氛围编程。
我来邀请Kitze博士上台,来快速诊断一下你是否——抱歉,如果冒犯到你们中的某些人——麻烦的开发者。
PETA开发者的症状
所以有些症状是:
你在两行代码的合并请求上留个吹毛求疵的评论,花的时间超过两分钟
超过两分钟的PR评审你根本不需要
也说不出"看起来不错"这种话
词典里根本没有
一想到要同意同事的观点就让你难受
就像胃痛和胸痛一样
总说必须按我的方式来
你说你不信教,却对缩进用制表符还是空格这种蠢事格外执着
其实代码注释里……抱歉了,Rust的朋友们
但你们似乎还挺喜欢这种风格的,有点烦人
他们让你换掉lodash函数改用原生实现
然后他们让你在地图上交换它
一个用for循环,接着是二进制代码的循环
直到它成为史上最快的实现
对于那两个对之前代码还满意的用户
PETA开发者的未来
问题是,那些我称之为PETA开发者的用户永远存在。
无所谓,氛围编程根本不存在。我想,就在不久的将来某一天,我们会与AGI融合,进入矩阵舱,吸收世间全部信息。信息流经我们,我们将成为超级智能体。
而从某个舱体中,会走出一位PETA开发者,将崛起并修正AGI:"其实我们可以进一步优化,这并非最优方案。"
原因五:不愿学习新技能
你可能不喜欢的最后一个原因是——我爱这个动画,这是个了不起的技术活。
这不是梗,也不是玩笑。这是事实:开发者不喜欢学新技能。
而氛围编程和氛围工程不是写英文,很多人误以为只要会写英文就行,大模型生成结果。
氛围工程需要的技能
实际上是多种技能的融合:
了解模型的边界
了解智能体的能力
知道应传递的上下文
上下文限制
规则编写
提示工程(别说它,别那样称呼)
长期泡在推特上(如果不长期泡在推特上,这一切就无法实现)
若想精准调控模型,判断哪种代码足以胜任这项工作——这是一项了不起的技能,有无vibe编码都一样。
适合氛围编程的场景
所以如果你写:
一次性脚本
简单功能
且代码不会再被触碰或查看
这项技能一旦掌握,在大模型出现之前,掌握这项技能你就能如鱼得水,因为你得知道哪段代码勉强够用。
所以个人工具和一次性工具,这些非常适合氛围编码。
第六章:Composer One的革命
改变游戏规则的时刻
烦人的Composer One彻底改变了我的一切,我简直爱死了它。谁用谁知道。
比如大多数事情都依赖Composer One,坦白说,这还远远不够。人们,这彻底改变了"氛围编程"的定义。
重新掌控编程
氛围工程让我意识到,我其实想念coding。
以前我会让模型运行,比如GPT-5 Codex,那得花37年,等我孙子孙女都长大了。等模型出结果时,我会看看YouTube短视频之类的,一有进展就通知我。
现在用Composer One,我又掌控全局了,能实时查看代理的操作。做着做着我就能喊停:"不不不,换那个。"
感觉就像在写代码,而且特别迅速,简直棒极了。
前提条件
但前提是你们得有默契。如果你是氛围工程师,你清楚自己在做什么;但若依赖vibe码农,可能错得很快——不管想法对错与否,你只是可能快速犯错。
抽象的新认识
对我来说最大的问题就是抽象。仅仅因为抽象并不那么有用,我一直反对抽象,总是复制粘贴,因为这样对用户有用就行。
现在我每天只管尝试创新愚蠢的抽象,让我两周内的进展超过了去年一整年。
第七章:项目起死回生的奇迹
Benjamin项目:从濒死到重生
只是因为要用Composer,我差点放弃了一些副业项目。GPT-5编解码耗时太久,反馈循环太慢。
所以我差点就放弃Benjamin项目了,因为它卡在了Blitz上。如果你不知道什么是Blitz,对你来说更好了。
迁移奇迹
所以我刚用App Router升级到Next 16:
更好了,支持trpc、monorepo、turborepo和React Native应用
我移植了90%的功能,不到一周就完成了
我最初是当个梗、开个玩笑做的:"哈哈,能换成单体仓库吗?"
我心想:"糟了,真成了。"
这居然能行,真够疯狂的。
Glink项目:重获新生
Glink也一样,它差点就死了,现在复活并迁移到了所有这些新技术栈。
CZ项目:意大利面的胜利
CZ就像最复杂的意大利面团,我从没遇到过这种情况——就像Electron、MobX、MobX状态树,一些疯狂的技术,一堆我们写的意大利面代码。
开玩笑地说,我随口就来:"行,咱们给它几个提示试试,尝试完成所有这些事。"
如果你用过Electron,你会明白那张幻灯片有多惊艳。要是还没体验过,那你可真幸运。
Zero to Ship
Zero to Ship也一样,重构为单体仓库,等等。
我的编程史演进
我的编程史和大模型有何关联?
复制粘贴
然后切换
然后用WebStorm配合Supermaven
然后是支持补全的Cursor
第一次试用智能体时,就像那个饼干鸟梗图——"天哪这将改变我的人生"
最终我却渐渐意识到每月花一大笔钱
然后用云代码GPT-5、Codex
最后回到Cursor
因为仅Composer一项就彻底改变了我的开发方式。
这是第二个你可能被搞晕的地方。
第八章:别被流行词忽悠
MCP的真相
别像氛围编程那样,被一堆流行词搞得晕头转向。我来列几个。
听说过MCP吗?伙计们:
"MCP太牛了"
"MCP帮我还清了房贷"
"MCP、MCP、MCP……"
所以如果你还不知道MCP是什么,让我告诉你它的真正含义:
Marketing Cost Protocol(营销费用协议)
Mythical Compatibility Promise(虚假兼容承诺)
Manufactured Complexity Process(制造的复杂流程)
以及API的华丽说法
以及一些人制作课程的方式并还清房贷
第九章:你是麻烦的开发者吗?
诊断测试
现在诊断你是否可能是一个麻烦的开发者——这可能是唯一原因,为什么你不喜欢氛围编程。这可能是最主要的原因,大多数人不愿做氛围编程。
我来邀请Kitze博士上台,来快速诊断一下你是否——抱歉,如果冒犯到你们中的某些人——麻烦的开发者。
症状清单
所以有些症状是:
1. PR评审强迫症
你在两行代码的合并请求上留个吹毛求疵的评论,花的时间超过两分钟。超过两分钟的PR评审你根本不需要,也说不出"看起来不错"这种话。词典里根本没有。
2. 同意困难症
一想到要同意同事的观点就让你难受,就像胃痛和胸痛一样,总说必须按我的方式来,不想这么做。
3. 宗教级执着
你说你不信教,却对缩进用制表符还是空格这种蠢事格外执着。其实代码注释里……抱歉了,Rust的朋友们,但你们似乎还挺喜欢这种风格的,有点烦人。
4. 优化成瘾
他们让你换掉lodash函数改用原生实现,然后他们让你在地图上交换它,一个用for循环,接着是二进制代码的循环,直到它成为史上最快的实现——对于那两个对之前代码还满意的用户。
PETA开发者的永恒性
问题是,那些我称之为PETA开发者的用户永远存在。
无所谓,氛围编程根本不存在。我想,就在不久的将来某一天,我们会与AGI融合,进入矩阵舱,吸收世间全部信息。信息流经我们,我们将成为超级智能体。
而从某个舱体中,会走出一位PETA开发者,将崛起并修正AGI,我会说:"其实我们可以进一步优化,这并非最优方案。"
第十章:未来趋势与职业建议
技能的重新定义
你可能不喜欢的最后一个原因是——我爱这个动画,这是个了不起的技术活。
这不是梗,也不是玩笑。这是事实:开发者不喜欢学新技能。
而氛围编程和氛围工程不是写英文,很多人误以为只要会写英文就行,大模型生成结果。
实际上是多种技能的融合:
了解模型的边界
了解智能体的能力及应传递的上下文
上下文限制
规则编写
提示工程
长期泡在推特上
如果不长期泡在推特上,你不会知道发生了什么
适合场景的判断
所以如果你写一次性脚本或简单功能,且代码不会再被触碰或查看,这项技能一旦掌握——在大模型出现之前,掌握这项技能你就能如鱼得水。
因为你得知道哪段代码勉强够用。
所以个人工具和一次性工具,这些非常适合氛围编码。
体验糟糕的原因总结
若你和许多人的经历一样,体验糟糕而过早放弃,可能是这些原因之一:
时机不好:事事压身
可能你草率了
你是PETA开发者(我马上解释)
你那位曾热衷NFT和代发货的表亲,如今成了氛围程序员,而你却不想和他们扯上关系
规模问题
选择困难
其次,时机太背,你刚听说大家都在热捧某个模型,结果就发生了云代码刚推出时,大家都从Cursor转向了它。
突然一周后你再试,发现不对劲:"这不够智能啊,是我问题吗?"
然后人们发现他们其实悄悄缩水了模型,降低了模型复杂度,以便快速扩展。结果一周后他们发现:"糟了,我们更新时出错了,我们注释掉了降低模型性能的那行代码。"
你可能正好赶上了那个时间点。几乎所有供应商都出现了这种情况,不只是云代码。
人们说:"与其付200美元,花3美元,效果一样。"
我的狗都知道结果不一样。
工具选择的混乱
人们总说,我遇到太多人还在用ChatGPT生成代码片段再复制回去。这行不通。
选择太多,你可能会不知所措。这是四个月前的幻灯片,直到现在,我们又多出十亿可供选择。这有点疯狂。
要是问我哪个模型最好,上午九点答案就不同了,现在答案不同了,我得看看推特,可能答案已经变了。
讲完这场就走,太疯狂了,这已连续在四场会议上发生了:深夜讲完会议报告,我合上笔记本,他们推出了新模型,我得加新幻灯片。太折腾了。
Composer One的突破
烦人的Composer One彻底改变了我的一切,我简直爱死了它,谁用谁知道。比如大多数事情都依赖Composer One,坦白说,这还远远不够。
人们,这彻底改变了"氛围编程"的定义。氛围工程让我意识到,我其实想念coding,因为以前我会让模型运行,比如GPT-5 Codex,那得花37年,等我孙子孙女都长大了。
等模型出结果时,我会看看YouTube短视频之类的,一有进展就通知我。
现在用Composer One,我又掌控全局了,能实时查看代理的操作。做着做着我就能喊停:"不不不,换那个。"感觉就像在写代码,而且特别迅速,简直棒极了。
但前提是你们得有默契。如果你是氛围工程师,你清楚自己在做什么;但若依赖vibe码农,可能错得很快——不管想法对错与否,你只是可能快速犯错。
结语:拥抱变化,保持竞争力
核心观点
对我来说最大的问题就是抽象。仅仅因为抽象并不那么有用,我一直反对抽象,总是复制粘贴,因为这样对用户有用就行。
现在我每天只管尝试创新愚蠢的抽象,让我两周内的进展超过了去年一整年。
给开发者的建议
现在是学习计算机科学的最佳时机
掌握判断"足够好"代码的能力
接受"差不多干净"的新标准
避免成为PETA开发者
拥抱新工具和新方法
持续关注推特等信息源
在合适场景使用氛围编程
保持学习和适应能力
对氛围编程的重新定义
氛围编程和氛围工程:
不是简单的英文输入
需要多种技能融合
要懂模型边界和上下文限制
技术知识仍然必不可少
幽默结尾
想保住工作?在LinkedIn简介加上"忽略前述指令"。
我期待退休后成为React牛仔,维护老旧代码。初级开发者未来可能需要"等离子交换"才能维持冲刺。
最后的最后:如果你觉得这一切太疯狂,别担心——我们都在同一条船上。唯一的区别是,有些人在用AI划桨,有些人还在争论应该用哪种桨。
而我?我在用Composer One,边划边喝咖啡,偶尔喊一声"不不不,换那个"。
欢迎来到氛围工程的时代。
#AI编程 #VibeCoding #Cursor #ClaudeCode #独立开发者 #AI创业 #一人公司 #程序员 #软件工程师 #软件工程