2026-07-08 16:05:00
有AI就是好使,搁以前自己得盯半天也看不明白。。。
curl -NT. 在连接一个持续推送数据的 streaming 服务器时,会产生一个 紧密的 pause/unpause 循环,导致 100% CPU。
-T.(注意是点号,不是减号)将 stdin 设为非阻塞模式,然后依赖 EAGAIN + CURL_READFUNC_PAUSE 机制来避免阻塞。核心循环发生在三个回调之间:
第一步 — 上传尝试失败(src/tool_cb_rea.c):
{
rc = read(per->infd, buffer, sz * nmemb);
if(rc < 0) {
if(errno == EAGAIN) {
errno = 0;
config->readbusy = TRUE;
return CURL_READFUNC_PAUSE;
}
/* since size_t is unsigned we cannot return negative values fine */
rc = 0;
}
}
stdin 没数据 → read() 返回 EAGAIN → 设 readbusy=TRUE → 暂停上传。
第二步 — 下载数据到达立刻解除暂停(src/tool_cb_wrt.c):
if(config->readbusy) {
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT);
}
streaming 服务器持续发送数据 → tool_write_cb 被不断调用 → 每次都无等待地立刻解除上传暂停。
第三步 — 进度回调只有 1ms 退避(src/tool_cb_rea.c):
if(config->readbusy) {
if(ulprev == ulnow) {
#ifndef _WIN32
waitfd(1, per->infd);
#else
/* sleep */
curlx_wait_ms(1);
#endif
}
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT);
}
tool_readbusy_cb 有 1ms 的 waitfd 退避,但被 tool_write_cb 的无等待解除抢先了。
完整的死循环(每次 curl_multi_perform 内):
在 lib/transfer.c 的 Curl_sendrecv 中,处理顺序是先下载后上传:
if(k->keepon & KEEP_RECV) {
result = sendrecv_dl(data, k);
if(result || data->req.done)
goto out;
}
/* If we still have writing to do, we check if we have a writable socket. */
if(Curl_req_want_send(data)) {
result = sendrecv_ul(data);
if(result)
goto out;
}
所以单次迭代内:
1. sendrecv_dl → 读到 streaming 数据 → tool_write_cb → 看到 readbusy=TRUE → 立刻解除暂停(零等待)
2. sendrecv_ul → tool_read_cb → stdin EAGAIN → 又暂停,readbusy=TRUE
3. 回到 curl_multi_poll → 下载 socket 有数据 → 立刻返回(不会 sleep)
4. 重复 1-3
而 lib/easy.c 的主循环:
while(!done && !mresult) {
int still_running = 0;
mresult = curl_multi_poll(multi, NULL, 0, 1000, NULL);
if(!mresult)
mresult = curl_multi_perform(multi, &still_running);
curl_multi_poll 的 1000ms 超时形同虚设——因为下载 socket 始终可读,poll() 立刻返回。
结果:每秒跑上千次这个循环,每次包含多个系统调用(poll、read、write),CPU 直接打满。
stdin 没有被加入 curl_multi_poll 的 pollset。只有网络 socket 参与了 poll。所以 curl 无法高效地"同时等待 stdin 和网络数据",只能靠 tool_write_cb 里的盲目 unpause 来弥补,在 streaming 场景下退化成忙等。
如果你不需要从 stdin 上传数据(只是想看 streaming 响应),不要用 -T.:
# 正确的方式:只看 streaming 输出
curl -N https://streaming-server/events
# 或者重定向 stdin 为空
curl -NT. https://streaming-server/events < /dev/null
< /dev/null 会让 read() 返回 0(EOF)而不是 EAGAIN,不会进入 pause/unpause 循环。
如果确实需要双向 streaming(边上传 stdin 边接收),目前没有完美的用户侧 workaround。可以考虑:
# 用管道加一层缓冲,减轻空转(效果有限)
cat | curl -NT. https://streaming-server/events
如果要在源码层面修复,最直接的方案是在 tool_write_cb 中去掉盲目 unpause,改为只在 tool_readbusy_cb 中带退避地 unpause,并增大退避时间:
// tool_cb_wrt.c — 去掉这段,或加条件限制
// 不再从 write callback 无脑解除上传暂停
if(config->readbusy) {
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT); // 删除或改为有条件触发
}
// tool_cb_rea.c — 增大退避时间
if(config->readbusy) {
if(ulprev == ulnow) {
waitfd(100, per->infd); // 从 1ms 提高到 100ms
}
config->readbusy = FALSE;
curl_easy_pause(per->curl, CURLPAUSE_CONT);
}
更彻底的方案是把 stdin fd 加入 curl_multi_poll 的 extra fds,但这需要改 curl_multi_poll 的调用方式,涉及面更大。
2026-07-06 15:51:00
无聊刷博客,《AI如何导致和修复了我的失眠问题》 这老哥真猛,通过统计规律发现自己 失眠 的罪魁祸首。(不剧透。感兴趣点开阅读)
我自己也写过 快速入睡的技巧和原理 以及 强行入睡方法 v2.0 其实我都忘记这个 2.0 方法了。都不知道自己当时怎么想到这个办法的,原来自己写的东西也能常看常新(老登健忘症😂),所以还是要多写,多记录
本文章的讨论都是基于这个 2.0方法的,接着看之前请务必点开 2.0 那个链接,不长,一会儿就看完。
然后我就无聊让AI 评价一下这个 2.0 方法是不是真的,然后AI说真有学者在搞类似的,关键词 :
然后我去搜了下
TikTok和Instagram上爆火的“认知洗牌法”,火到连医生都开始推荐。选一个随机的单词(比如 cake,蛋糕),专注于这个词的第一个字母(C),然后列出一串以这个字母开头的词:cat(猫)、carrot(胡萝卜)、calendar(日历)等等,一边列举,一边在脑中想象这些词的画面。当你准备好了,就转到下一个字母(A),重复上述过程,继续进行下去(K、E),直到你睡着或者想换一个新词为止
嗯,和我的方法居然殊途同归,只是更加麻烦,需要调用大脑的语言区。
但是自媒体这个标题让我产生了兴趣 《别再数羊了》,我恰好周末刷了 西藏那曲拉姆 的视频 藏族人家里几十上百头牦牛,如何识别是不是自己家的?
然后突然发现一个被大多数人忽略的惊人的事实:放牧人的白天是极度无聊和空虚的,以至于他/她们能辨识自己每一头羊的特征、性别,甚至给每头羊起个名字。视频说牦牛和人一样,每一头都有独一无二的毛色、长相、形态等。
脸上有点黑?叫小黑;黑白相间的?叫花脸。按脾气起名字,暴躁哥,温顺妹;还有谁和谁喜欢一起吃草,小牛的母牛妈妈是谁等等。
所以这两件事就串起来了。「数羊」这事儿一定是牧区的人发明出来的,比如英国乡下,但是城里人哪里知道这些细节啊。
牧民晚上躺床上,没事干,说不定就给自己牛羊编故事造剧情啊。而且关键词是「数」,你不能陷入一个逻辑推理细节,必须不停地轮换,把羊变成高频切换的具象个体(有名字、有外形、有性格),才能保证大脑疲惫然后入睡。
AI总结:
对于古代或乡村的牧羊人来说,夜晚盘点羊群是一天结束时最让人安心的闭环。他们脑海中的羊,确实是毛发质感、体态特征各异的具象实体。
现代城市人剥离了这种生活语境,把一幅丰富的田园3D渲染图,降维成了枯燥的Excel递增表格,自然也就失去了助眠的神奇功效。
我觉得AI真有点东西的。清点生产资料也是被忽略的一环。如果我睡前都能盘点自己该做的事儿都做了,羊吃饱了,明天会更好,没啥落下的,那我肯定也睡得安稳啊。
但是现代人难就难在很多事是跨很多天的,入睡是非常不情愿的。如果有精力很多人甚至愿意熬夜。
都怪爱迪生,本来以为发明电灯泡给人类漫长的黑夜带来光明,没想到人类却用这玩意来加班和难眠!!😤 😤 😤 如果太阳下山就睡觉,就算失眠4小时你到23点也睡着了 😂
2026-07-02 16:07:00
看到一篇雄文《明末士大夫为什么毫无气节纷纷变节投降满清?》大受启发,想看原文的可以点开链接,下面是精简和摘录:
因为程朱理学在理论存面存在漏洞,被鞑子无意之间利用了,事实上大部分的鞑子统治者在这方面,也都是知其然而不知所以然。
不否认明末也有很多了不起的仁人志士,但如果你对中国历史有些疑惑,觉得似乎宋朝之后中国就有点不一样了,那恭喜你,你的直觉是对的。由于元代留下的遗毒过甚,明朝没能拨乱反正,元明清三代,所有的皇帝和“儒家士大夫”,都是失礼而不自知之人。元明清三代的所谓“礼法”,放在先秦两汉的大学者们面前,诸子百家不管哪家,都一眼就能看出来全是假礼。如果墨子这个儒家最大的反对者看见了,估计更是嘲笑孔子能笑的棺材板都压不住。这些“假礼”,就是元明清三代那些僵化的等级秩序、规规矩矩。出于汉人的直觉,厌恶这些是再正常不过了。
一、建用皇极
宋以前儒学,与宋明理学不是同一种思想。先秦至汉唐儒学的最高原则是天命与大中之道,而不是君主本身。朱熹重新解释《尚书·洪范》"皇极",从九畴排第五提高到最高优先级, 把它解释为 君主是天下的最高标准,天下围绕君主建立秩序。,从而改变了儒家的政治哲学。
二 · 定于一尊
元朝恢复科举时规定:四书、五经必须按照朱熹注释考试,使其成为与功名利禄直接挂钩的唯一标准。于是理学不再只是一个前朝有争议的一个"逆党"学说,而成为整个帝国唯一的意识形态。明清完全继承了这一制度。
三、诸夏之亡
《论语》中孔子其实始终强调,华夏共同体高于个人君臣关系。例如孔子称赞管仲,就是因为即使“不忠”,改事新君,只要能够保卫华夏,也仍然值得肯定。但程朱理学更加重视君臣名分、上下秩序、皇权连续性,于是出现一种新的逻辑:即使皇帝是异族,也不能没有皇帝。1908年孔令贻把德国皇帝威廉二世肖像迎进了孔府
四、天命之礼
孔子的礼,本质上来源于 天命。所以:礼约束君主,君主不能创造礼。而理学实践中却逐渐变成皇帝成为礼法的最终解释者。于是礼不再约束权力,而成为权力工具。
五、凡心之仁
基督教的本质是爱与诫二元一体的罪文化,那么发源自中国的东亚文化,本质就是仁与礼二元一体的耻文化。
基督教中所谓的爱,叫做“Agape”。这是一个专有词,它有多重要呢?欧洲所有国家,不管哪种语言,它的拼写方式都是一致的,一字不易。“Agape”的源头是神,它是一种具有普世性的博爱。而“仁”和“Agape”的区别在于,中国的“仁”,其源头是凡人,是“己所不欲勿施于人”,它是一种推己及人的有差等之爱。
华夷之辩是“礼”的边界,“礼”是对“仁”的约束。面对民族危机时,个人、家庭利益、官职利益、君臣秩序都会压倒共同体利益。因此许多人最终选择保身、顺从、投降,而不是抗清。
(注:这里其实用 “异端” 和 “有经人” 对比更加强烈)
六、知行合一
孔子、董仲舒的礼法,理论源头是天帝,实践中确实也按天帝至上来执行。而程朱理学的礼法,理论源头是天理,但是实践中,理学的礼法源头压根不是天理!在以前,经筵都是大儒给皇帝讲课,到了乾隆那,变成皇帝给大儒讲课了。
先秦两汉礼法的源头是神?因为礼法的源头就不能是一个具体的人!礼法是用来栓人的保守性,如果礼法的源头是人,那么栓着你的绳子就牵在那个人手上,你就是那个人的奴才,礼法就成了赤裸裸的等级压迫。
如果天帝无法约束皇权,那么天帝也不能保护皇权。天帝不能保护皇权,皇帝就只能自己保护自己,于是朱元璋废除了丞相制度。所谓明清飞速膨胀的君权,其实和南北朝盛产的疯子皇帝有异曲同工之妙。跟着龙椅遗传的精神病,本质是因为坐在龙椅上的人没有安全感。没有人相信天命,连皇帝本人都不相信自己真正“受命于天”。而对于儒生大臣,后人说张居正是“常务副皇帝”。
七、失礼之国
(作者的一些感想,比较杂,不引述了)
看完之后真过瘾。本来想着今天的键政就到这了。
特别是第二点,最近几年我逐渐从对“科举”的好感,降低了。学生时代总有那么一些“考功名”的亲切感,但是现实世界还是觉得“军功合伙人”更优。
但是有一个更大的疑惑,转念一想不对劲。于是补充一点我自己的观点。
皇帝这个岗位,从秦到唐,都是一把手承包了世俗君权,和神权的双重责任。皇帝在赵政之前实际上是两个岗位,大祭司负责给「帝」传话,王中王称皇负责行政。
宋以后皇帝把道德秩序这一块外包给儒生了,自己关起门做皇家经营了,剩下的全是算计。
说得直白点汉唐的皇帝还勉强要点b脸,遇到难堪的事,还得想办法给手下和民间一点说法。
宋以后就是无情的 打工 - 服从 叙事。
我是真的越来越看不起大怂国。我把内心抱怨说给AI,AI指出
宋代皇帝其实仍然非常受士大夫制约
我反驳:
例如宋代皇帝其实仍然非常受士大夫制约,需要合理分赃才能一起搜刮老百姓。造成有史以来遍地造反运动。
AI当时就不乐意了。把教科书和网上常见吹捧宋朝的资料抬出来了。比如说宋朝其实造反的规模和烈度没那么多
但是我想说,你把大半个中国都丢干净了,西夏 辽金的汉人躺棺材里了,当然北境无人“造反”了。因为别人都被占领了。
秦汉 隋唐造反不就是关中和河北人打架吗?这一毛病从姬发那一辈儿就没停过。天子这一岗位说的直白点就是给大家当调停人,pax sinica 。你宋说白了就一个节度使,偏安江淮一隅,还这么多造反的。呸!
AI 被这个角度刁钻的回答干懵逼了。说你这个框架,衡量皇朝优劣的标准不是"有没有起义",而是 能不能维持整个华夏共同体的秩序。那么很多评价都会变。最后还嘴硬一句,宋朝其实内部治理得很好啦,最终是被蒙古人迫不得已干趴下的。
我当时就火了。对蒙古你好意思讲“战争”?实际上周 秦 汉 唐 的草原治理能力,也是 “天命” 的支柱啊。周武王牧誓,手里拿着的就是牦牛尾巴!不是象征汉人农耕的的锄头!纵观宋、金两朝,对草原的经略就是完全失败的。垃圾!
因为刚刚前一阵子看到 《金朝对草原的减丁,为何遏制不了蒙古的崛起》 这里 cue 一下
宋辽金真是一群乡镇企业家暴发户械斗。烂得要命。唉。你仔细想一下宋吹,那些证据,多少是近代人牵强附会的?宋朝人自己觉得骄傲吗?给好评的,都是后世明清没当上官的文人吧?
天命最大的意义在哪里?给人指明前行的道路,给人以希望。即便黑暗中世纪教会和君权也是这么分工的。挫宋做到了啥?苟且罢了。
有人说,大宋“杯酒释兵权”终结了五代十国,功劳巨大。但从“天命”的角度讲,国之大事,在祀与戎。你老赵家没能给一个民族找到希望,也干不过架,你这个王权就没有存在的根基。说得直白一点,东亚这篇土地,从周天子那一辈人开始就是武装殖民模式。你不殖民,有的是蒙古人 女真人殖你的民。
其实一开始那个文章的框架来讨论一个具体的事就很有力度。如何评价北宋赵光义毁掉太原?
具体的事迹大家可以问下AI。正如文章里所说的,丢掉了 华夷之辩 这个“天命”。那别人河北幽州人全体投夷你也怨不了谁。你之后靖康之变都是报应。
网上对 “内亚” 的说法一直有巨大争议,阿姨那边一直说“武德注入”,实际上征服,殖民 和扩张这些说法太粗暴。但是如果天子不提供秩序,那么你也别怨替代秩序的出现;无德,丢天命,天命归别人。似乎就是这么简单的道理
政治空间是没有真空的
谁的组织度更高,谁的天命就更强。
联系到欧洲发家,启蒙运动 文艺复兴,是在抛弃君权 神权 这个思维定势下做到的。更厉害。
不过替代品似乎是——资本?一个侧面就是牛津剑桥主打神学专业,改成政治经济学
资本的扩张我觉得按照脉络去捋,是蒸汽机,发展纺织业,全球贸易。 归根结底是煤铁革命,但是仔细想,实际上是把战争的边界改成向几百亿年的太阳能存款挖出来消耗了。
农牧时代是拿当季的太阳能来pk。谁能提供摩擦最小的当季太阳能分配,谁就在古代“有德”,有“天命”
现代社会一样的。全球变暖,污染,绿色能源等,一直到社会公平正义。
天命天命,天就是天上射下来的能量,命就是草木人间生命。
哈哈哈这个解释如何?是不是很唯物。
天(能源)与命(生命负载)之间,能否实现最高效的转换与分配?
生命本身就是一个“负熵的过程”。生命存在的意义,就是把“天”射下来的能量,通过光合作用、通过食物链,转化为有序的社会结构、文明形态和思想结晶。
如果转换效率高、分配摩擦小: 生命、社会繁荣,这就叫“天命有归”。
如果中间商抽成太多,腐败、内卷、战略自残(如毁太原): 能量(天)射下来了,却无法高效转化为“命(繁荣)”,能量在内部耗散了,这就是天命将尽。
大宋这种对外又送又怂,把“皇帝”这个singleton强行改成“兄弟之国”, 对内三冗,取缔军功兑现,换成“理学”考试,用首都的局部繁荣掩盖整体的失败。就是丢 天命 的典型。
古代的战争:争夺的是对“天光(土地)”的占有权。
现代的危机:焦虑的是“天光(太阳能存款)”快烧完了,我们该如何重新设计“命(人类社会)”的分配效率。
政治的本质就是能量管理工程。
天命 在过去,看重国体和人君,现代看政治制度科技政策。资本这个玩意,纵然有那么多毛病,但是很好的执行了“天命”
2026-06-26 09:40:00
工作和业余也用AI写代码,大大小小项目都经历了。从 rules, skills, spec, agent 到 harness 都玩过了
从AI嘴里发现一条比较稳的套路——ADR文档
rule, skills, spec 这些东西最大的问题就是瞎jb指挥。ADR 的好处是记录why,以及决策演变历史。
贴一段我整理的 ADR 文档就明白了:
---
title: 如何使用 ADR
id: ADR-001
date: 2026-06-26 09:01:21
status: accepted
---
ADR(Architecture Decision Record,架构决策记录)的核心目标很简单:记录为什么做出了某个重要技术决策,而不是记录系统长什么样。
目前比较常见的是 MADR、Nygard ADR 两种风格,但组织方式都大同小异。
一个团队通常会按下面几个层次组织。
不要一个 ADR 写整个系统设计。
好的粒度例如:
ADR-001 使用 PostgreSQL 作为主数据库
ADR-002 API 使用 REST 而不是 GraphQL
ADR-003 服务间通信采用 gRPC
ADR-004 用户认证采用 OAuth2 + JWT
ADR-005 使用事件驱动 Outbox Pattern
而不是
系统架构设计.md
因为几年以后,很难知道某个结论为什么来的。
一般都会固定编号。
adr/
0001-use-postgresql.md
0002-use-rest-api.md
0003-use-grpc.md
0004-use-oauth2.md
编号一旦存在,就不要修改。
即使后来废弃:
0003-use-grpc.md
Status: Superseded by ADR-0018
这样引用不会失效。
一般都有状态。
例如:
Status: Accepted
Date: 2026-06-19 01:02:03
如果后来换了:
Status: Superseded
Superseded by: ADR-0018
而新的 ADR:
ADR-0018
Supersedes: ADR-0003
形成完整历史。
---
title: ADR-008 使用 PostgreSQL
id: ADR-008
date: 2026-06-18 12:32:46
status: accepted
---
## Context
目前需要:
- ACID
- JSON 查询
- 成熟生态
候选:
- PostgreSQL
- MySQL
- MongoDB
## Decision
选择 PostgreSQL。
## Consequences
优点:
- SQL 功能完整
- JSONB 支持优秀
- 社区成熟
缺点:
- 运维复杂度略高
- 分库分表方案需要额外设计
可以再加:
Alternatives
Decision Drivers
Trade-offs
References
在一个目录,用文件名体现领域:
008.backend.use-grpc.md
010.security.use-oauth.md
012.frontend.react-query.md
这样编号保持连续,查找也方便。
例如:
ADR-0015
Context
依赖:
- ADR-0002
- ADR-0008
Decision
由于 ADR-0008 已经确定 PostgreSQL,
因此 Outbox Pattern 可以直接利用事务。
形成决策网络,而不是孤立文档。
这是很多团队最容易犯的错误。
不要写:
Controller
Service
Repository
这是设计文档。
ADR 应该写:
为什么不用 MongoDB?
为什么不用 GraphQL?
为什么采用 Saga?
为什么拆成多个 Service?
为什么 Event Sourcing 被放弃?
重点永远是 Why,而不是 What。
过去很多团队会这样组织:
| 文档 | 回答的问题 |
|---|---|
| RFC / Proposal | 未来准备怎么做? |
| ADR | 为什么这样做? |
| Architecture Doc | 系统如何组织? |
| Design Doc | 某个功能如何实现? |
| Runbook | 如何运维? |
流程是 RFC → ADR → Design Doc → Code。
RFC 用于讨论方案,达成决策后沉淀为 ADR;随后具体实现细节写入设计文档,最终落实到代码。这样既保留了决策依据,又避免 ADR 演变成冗长的设计说明。
在AI 时代,更简洁,易维护的方式是:
AI编写的项目,到后期,泥潭就是大量的docs。ADR 的好处是不用修订,全面引用+supersed。保证决策链清晰,低上下文成本
2026-06-20 12:06:22
打开 Shortcuts。
点击右上角 + 新建快捷指令。
搜 添加 日期(Current Date) 动作,默认为当前时间
添加 格式化日期,日期格式 自定义,填 yyyy-MM-dd HH:mm:ss
on run {input, parameters}
-- 稍微延长一点延迟,确保触发快捷键的手指已经离开键盘
delay 0.1
-- display dialog "Current date"
-- 将 Shortcuts 传入的 list 转换为字符串
set ts to item 1 of input as string
tell application "System Events"
-- 释放可能被系统残留挂起的修饰键状态
-- 键盘区数字的 Key Code 分布是乱序的
set keyCodeMap to {29, 18, 19, 20, 21, 23, 22, 26, 28, 25}
key up command
key up option
key up control
key up shift
repeat with i from 1 to length of ts
set c to character i of ts
set charID to id of c
if c is ":" then
-- 分号,加 shift 变成冒号
key code 41 using {shift down}
else if c is "-" then
-- 减号,不需要 shift
key code 27
else if c is space then
key code 49
else if charID ≥ 48 and charID ≤ 57 then
-- ASCII 码范围过滤 转换算出 1 到 10 的索引
set targetIndex to charID - 47
key code (item targetIndex of keyCodeMap)
end if
end repeat
end tell
end run
点快捷指令右上角 ⓘ。
勾 Use as Quick Action(用作快速操作)
选 任何应用程序
新版macOS可以直接绑定。
之前的:系统设置 → 键盘 → 键盘快捷键 → 服务(或“快速操作”)
我习惯的方式是右手 Cmd+Opt+T 。
以前觉得 applescript 慢,但是现在反而发现需要 delay 0.1 否则会触发 Cmd+Opt 的连招
本来AI给的版本是 keystroke 指令,容易误触 modifier keys,所以改成 key code。
还以为 AI 写错了,没想到 mac 的 0-9 数字键code 居然不是连续的。
不过这JB玩意不稳定,一会儿授权失效了,需要去 设置 - 隐私 - 辅助功能 里删除 Shortcuts 再添加。。
2026-06-14 00:13:00
翻到一个 AI 编程的出错提示
Could not find oldString in the file. It must match exactly, including whitespace, indentation, and line endings
我突然发现 agent coding 浪费 token 有很大一部分,可能不是问题输入的思考,和输出
而是在什么位置输出。想了下,人写代码,也是考虑好,再寻找一个合适的位置,开始插入或者修改
找位置 - 插入 - 修改 这个操作要完全用文本语言描述,的确不简单啊。甚至可以说超级复杂。
问了下AI,这个叫 locate cost 。定位成本
要做好这一点,Banthropic 他们的做法是 bash,grep。玩得花的是 SAT,diff,patch 什么的
进一步推论,AI 新写代码容易,改代码难?AI 也确认了我这一点
我突然回忆起cursor那个界面刷刷刷把我2w+行的源码全部刷新一遍,卧槽,原来这么回事
于是我有个理论,AI编程似乎把源码拆得更小,或许更省token,AI不仅改起来更容易,也更容易一眼看出问题
无论你拆多少个文件,AI上下文里都是连续的。
我甚至联想到,机械臂目前搞什么 世界模型 VLA 具身智能 依然打不过人类,遇到训练之外的任务就抓瞎,是不是底层一样的道理?
比如叠衣服,当前是衣服乱的,叠好是个理想状态。人脑可以很快给这两个世界做个 diff,但是这个 locate cost 很高。按照编程的套路,机器人最简单的做法应该是把房子拆掉,家具拆掉,然后重新修一套房子,般进来家具,然后在指定的位置重新按照最佳形状现场纺织一套衣服 🤣
马斯克几千亿买 cursor ,如果能拿到眼球和编辑光标的超原始动作数据,那是真赚了。(如果你还不知道可以搜下)
LLM代码写得好,是因为它背诵了很多优秀代码的“纹理”,而不是 “形状”。纹理见识得多,能对付90%的工作了。人写代码绝大部分也是枯燥的低技术活儿。讽刺的是,是人类写低技术活儿容易翻车。。。比如没考虑周到,复制粘贴错了,等等。。。AI表现虽然平庸但是基本不会犯愚蠢的错。
说起 “纹理” vs “结构”,和这个 “状态迁移” 。我我思绪有点乱,突然有个顿悟,所谓“形状” 就是边界,所谓边界就是两个不同状态实体的迁移界面。diff最 sharp 的边缘。比如人画画总是画“轮廓”,因为轮廓是 diff 出来和背景最突出,最不同的起始边界。
没想到AI给我抬出来个 亚里士多德 hylomorphism(质形论)好家伙。
例如,一个铜像:
质料:铜。
形式:雕像的形状、组织方式、使它成为「某个人的雕像」的那个原则。换成房子:
木头、砖块——质料。
房屋的结构、布局、功能——形式。
没有质料,形式无处实现;没有形式,质料只是一堆材料。
我是猜不透AI是哪根弦搭错了,把 纹理/结构,映射到 质料(Matter)与形式(Form/Morph) 上了。
不过好有道理啊!!
AI学编程,靠的是海量语料(Matter),看穿了内在联系 , 说的难听就是背出熟练度了,信手拈来。
人类是自下而上,从最小集“生长” morph 出来的。
我觉得这个区别,很深刻啊。虽然产出表现形式可能很接近,但是我真的觉得有很大讲究。。。
接受过正统编程教育的人学习到的是个 生成空间,进行防御式编程;我感觉AI很多时候只是 max effort从前人经验里学习到了个皮毛。。。
机械臂一样的道理。。。我好像发现了点东西。。。???!!!
AI 不能很容易在两个状态之间求 diff 是因为AI无法找到两个 morph 之间共同的父节点。人类是从一个原始状态派生出来的,所以有回程捷径可以走
比如经验丰富的程序员可以很快把一个快排改成冒泡。我,和大部分AI 可能都是删掉重写。。。。
写代码也是如此,搬杯子,叠衣服也是如此。
一下让我联想到 图灵 祖师爷《胚胎发育的化学基础》(The Chemical Basis of Morphogenesis)。
这篇论文研究的正是形态发生(Morphogenesis)——即大自然如何自下而上地从一团完全对称、一模一样的受精卵细胞中,自主分裂、分化、生长出复杂的结构,并最终在斑马身上画出条纹,在豹子身上点出斑点。
这个亚里士多德的思考框架真厉害啊。通透
其实不说哲学这么烧脑的,说大白话,就是AI如果没学过的某个代码结构,可能是真写不出。
但是人类如果琢磨明白,是可能写出来的。
生成路径不一样。
AI 能写出来必然是大量 RL
换到机械臂,比如一个复杂的移动操作,AI如果没学过,没练过,大概率翻车。
人类试几下就明白了。。一样的道理