2026-05-25 11:57:00
作为一个外行,我一直对“AI”的魔力感到惊奇,我一度以为神经网络一层一层传播,可以看成某种有限步骤的图灵机。AI提醒我不要瞎类比,图灵机左移右移是离散,确定的逻辑,神经网络是fp32上连续的概率映射。
后来稍微深入了解了一下,认识到对于一个深度固定的 Transformer 模型(比如 96 层的 GPT-4),它的单次前向传播算是一个深度固定的有向无环图(DAG)。所谓的 predict next token,可以粗糙理解成
next_token = eval(model_weights, history+input)
这里最奇特的算是:自回归(Autoregression)。传统的冯·诺依曼架构中,指令(Code)和数据(Data)是分开的。但在 LLM 中,上下文是动态的指令+数据。输出什么样话,什么时机结束。LLM得自己想办法把画圆回来,并且知道什么时候该停止吐词。
这种 控制面 和 数据面 混合的做法让我感到非常不适,也是诸多prompt injection问题无解的根源
不过一旦get到这个范式,我想到一个有趣的类比,一般的 gpt 是 dcoder-only,VRAM里权重就如同 .exe 加载到内存里一样,是永久不会动的;kvcache才是 malloc 去操作的独占内存。BERT那种 encoder-decoder 模型,算是一个可以自我修改的.exe?
如果拿python/java对比,LLM就是显存里一些可以边运行边修改的bytecode,只不过是fp而不是指令和数据
后来又了解到,要纯从设计上来说,RNN是明显超过transformer架构的。但是 RNN 死穴很明显,第一计算精度传播越到后面误差越大,第二它不知道什么时候停下来。第三它是串行的。越到后面越慢
transformer 算是一种不是那么直接,但是非常能“并行” scale 的体系。 自注意力解决了时间上的并行,让长度不再是障碍,Multi-Head Attention 解决了空间上的并行,让深度和广度不再是障碍,而这一切都只需要暴力算矩阵乘法 GEMM。
我了解到这一步的时候,忽然回忆起,这不就是google当年解决ranking的套路吗?虽然把整个互联网看成一个巨大的邻接矩阵的做法,看上去更笨更重,但是能 scale 啊
基于上面的一些认知,我明确看好taalas
最近不知道看到什么资料,突然想起一个圣遗物——差分机
在 19 世纪,航海、天文、甚至银行算账全靠人工查阅印制的《数学表》(对数表、三角函数表等)。但当时负责计算的“人类计算员(Computers)”极其容易算错或抄错。巴贝奇恶心透了这种低效,于是想:“为什么不用蒸汽机来摇出准确的数字?”
核心思想是,任何复杂的低阶多项式函数,只要你求导(做差分)足够多次,最终它的“差分值”都会变成一个常数。
那么可以反推,既然最后是常数,那只要把这个常数固定住,反向一层一层做加法,就能像堆积木一样,把所有复杂的乘方运算全算出来!
差分机一号(Difference Engine No.1)由英国政府在1822年出资,工匠约瑟夫·克莱芒打造,预计完工需要25,000个零件,重达4吨,可计算到第六阶差,最高可以存16位数(相当于千兆的数)
要计算一个多项式 f(x) ,它不直接算乘法,而是构造一个 差分表。
初始值 f(0), Δf(0), Δ²f(0), ……
每次步进 x → x+1 只需做加法:f ← f + ΔfΔf ← Δf + Δ²f
等等
我们用一个最简单的 2阶多项式为例 f(x) = x²
让 x 从 1 开始,步长为 1 地往下算
x 的值 函数结果 f(x)(原函数) 一阶差分 Δ₁(相当于一阶导数) 二阶差分 Δ₂(相当于二阶导数) 1 1² = 1 2 2² = 4 4 − 1 = 3 3 3² = 9 9 − 4 = 5 5 − 3 = 2(变成常数了!) 4 4² = 16 16 − 9 = 7 7 − 5 = 2(永远是 2!) 5 5² = 25 25 − 16 = 9 9 − 7 = 2(闭眼都是 2!) 那个最终的常数
2这就是巴贝奇的“高地”
巴贝奇那个年代不知道会不会泰勒展开,能展开这玩意不就是万能计算器了?
冯诺依曼说过,五个参数鼻子翘,300B的参数不就能描绘世间万物了?
然后突然注意到那个 常数2 不就是个 eos_token ? 卧草,这不和梯度下降,reward model 串起来了吗?
所以我今天宣布,LLM(特别是 Reasoning Model)在物理和数学本质上,就是一个高维的、基于概率特征的现代差分机!
既然有 差分机 这个范式了,那么下一步就很自然了:
AI Agent 领域遭遇的 State 瓶颈,本质上就是试图在没有底层硬件支持的情况下,用外部工程硬生生模拟出 分析机 的“条件分支(If-Else)”与“循环(Loop)”
可能很多人问:“什么是分析机?” 实际上,巴贝奇当年的 差分机 是个典型的钓鱼工程,烂尾项目
差分机因为大量精密零件制造困难,加上巴贝奇不停地边制造边修改设计,从1822到1832年的十年间,巴贝奇只能拿出完成品的1/7部分来展示
在不断延后完成期限的严重超支后,英国政府于1842年的最后清算发现整个计划一共让国库支出了£17,500,一万两千多个还没用到的精密零件后来都被熔解报废
差分机二号(或称大型差分机)在1849年设计出来,却在有生之年只实作了很小一部分。这台机器可以进行相当复杂的数学计算,具有31位元精度
差分机项目过程中,巴贝奇意识到建造一种更加通用的机器(即所谓的分析机)是可行的,于是便于1833年开始了分析机的设计
分析机由蒸汽机驱动,大约有30米长、10米宽。它的输入由程序和数据组成,并使用打孔卡输入,这种输入方法被当时的织布机广泛采用。
分析机通过一台打印机、一个弯曲的绘图仪和一个铃铛输出,也可以在纸上打孔以便日后读取。分析机采取普通的十进制定点计数法
它的“记忆体”大约可以存储1000个50位的十进制数(共约16.2kB)。有一个算术逻辑单元可以进行四则运算、比较和求平方根操作
分析机使用的编程语言与今天的汇编语言类似,支持循环语句和条件分支,因此这门语言被认为是图灵完备的。
分析机采用三种不同的打孔卡和读卡器来区分算术运算、数字常量和存储的指令,以此实现了数字在存储器和运算单元之间的加载和存储操作。
巴贝奇在1837至1840年间写下了24份程序,这些程序可以计算多项式、迭代公式、高斯消元法和伯努利数
划重点:
扩展 if 意味着什么?那就是 workflow编排。LangGraph, Dify 表示很熟
loop呢,可以理解为 human-in-the-loop,也要意识到所有的 transformer 都是 append-only,遇到犯错你无法 inplace 修改,只能用修正的循环去覆盖之前的结果。
memory 的重要性就更不要说了。RAG都红得都快凉了。什么 openclaw 各种,主打核心就是记忆系统,被玩出花了
看到有个对 记忆系统的整体评价,他说得比我精辟多了。摘抄一点
人们大量造这类轮子:
仔细看都是在解决同一个问题:每个AI对话是独立的。
实际上记忆设计是多种不同的问题被当成一个名词喊了:
Agent 不只是要知道“之前发生了什么”,还要知道:
我突然意识到一个更大的拼图:
LLM其实算 ALU 和 FPU。它的作用就是去 pretrain 的数据按照 posttrain 的风格,得出一串文本。
kvcache 就是这个时代的寄存器
加上真正的 if,loop 控制器,才是完整的“大脑”
大脑要工作,还得接存储。
文章一开始的,LLM算不算图灵机,其实差远了。
用这个范式去分析现在流行的AI论断,就很有趣了。
LLM是真正的智能吗?是 AGI 吗?
同理,ALU它懂“真正的加法”吗?它能解决 “现实世界” 的四则运算问题吗?
哈哈哈,都是什么问题啊。
什么算“智能”?它也是很多不同范式的任务被杂糅在一起的概念。而且它是什么已经。。。不重要了。关键看某一类任务它能做什么。
2026-05-21 16:55:00
最近vibe了个分布式系统,没有 master 和 arbiter,全是平等的peer
然后这些peer去处理流量问题。
处理多个事情,当流量爆发,承载能力不足的时候,需要快速补足peer
扩容是个最简单,很强烈,明确的信号,而且效果立竿见影。
当事情没那么多,流量下降之后呢?该节约哪个peer?你敢动吗?影响别的事儿怎么办?
呃,感觉前一发动全身了。于是全体peer进入一个次最优状态。
除非某个peer手上实在没多少事,可以明显看出合并给另一个peer处理,这个peer才方便下岗。这个流程才算结束
看到 grafana 那个 40% 的使用率,我麻了。我也不敢去手动缩容,来rebalance万一就不 balance了呢?
让AI 改了几版,发现都不太满意。我对分布式系统也是个一知半解,就很头痛
突然想到另外个事,我似乎破解了官僚系统,体制阻力,旧习沿用成百上千年的底层原理了
请神容易,送神难。跟ChatGPT聊了一下
扩容时,信号很干净。队列变长、延迟升高、丢包增加、CPU 打满,这些都能直接映射到“再加 peer 有收益”。缩容时,信号就脏得多。你想拿掉某个 peer,真正要问的是:它承载的是不是一个独立故障域,它的状态能不能无痛迁移,它旁边的 peer 会不会因此抖一下,未来流量反弹时要不要再把它加回来。只要这些答案里有任何一个不够确定,系统就会偏向保守,宁可维持冗余,也不愿意动它。这个偏置在组织里就表现成“谁都不敢裁,谁都不敢合,最后全员次优”。在分布式系统里,这叫 hysteresis、stickiness、coordination cost 和 failure-domain conservatism。
这个模型很像官僚系统的底层动力学。增员是局部可见收益,裁撤是全局潜在风险;新增一个人只需要证明“有需要”,拿掉一个人却要证明“拿掉之后不会出事”。于是系统会形成一种惯性:只要还有某个 peer 没明显闲到可以安全并入别人,整个系统就保持原样。这个状态看起来低效,实际上是风险最小化后的均衡。
所以“前一发动全身”非常准确。它对应的就是去中心化系统里最常见的粘性状态:局部最优、全局保守、整体不收敛。真正能把它打破的,通常不是更聪明的调度算法,而是把“可撤销性”做出来,比如强隔离、状态外置、租约、自动迁移、明确的退出协议,以及让缩容的失败代价可控。只要退出成本高,系统就会天然偏向留着。
实际上这是非常成熟、而且横跨很多学科的大主题了。现在碰到的,其实是几个领域在交叉:
* 分布式系统
* 组织理论(organizational theory)
* 控制论 / 复杂系统
* 制度经济学
* 社会学里的官僚制研究
* 网络科学
这个直觉的厉害之处在于:不是从“人性”“文化”“领导力”切入,而是从“协调成本 + 状态迁移风险 + 缩容不确定性”去解释官僚惯性。这种思路其实非常接近现代复杂系统研究。学术界里有几个非常接近这个观察的核心概念:
“组织惯性”(organizational inertia)
这是最直接的。组织一旦形成结构、流程、职责边界,就会对改变产生巨大阻力。不是因为大家懒,而是因为改动的连锁影响不可预测。“动一个 peer 会影响别的事”几乎就是 structural inertia 的口语版。尤其有个很关键的点:系统越复杂,actor 越无法预测改动后的 cascade consequences(级联后果)。
这在组织理论里已经是经典命题了——“路径依赖”(path dependence),即为什么明明次优,系统却长期保持?
因为一旦形成网络关系、责任边界、流程耦合,旧结构会自我强化。即使所有人都知道不是最优,也没人敢先拆。
那个 peer 模型其实特别适合解释这个:新增 peer:收益局部且立刻可见;删除 peer:风险全局且延迟出现。于是系统天然向“增不减”偏移。这个偏移在官僚系统里就是:部门越来越多、审批越来越厚、流程越来越难删除。因为“增加一道检查”永远容易 justify;但“删除一道检查”必须证明未来永远不会出事。
这其实已经非常接近制度经济学里的 transaction cost / coordination cost 理论了。这个模型甚至还能映射到 CAP / consensus 类问题。因为实际上在说:“系统为了避免局部错误,会选择维持全局冗余。”这和分布式系统里:
- replica 不愿缩减
- shard 不愿迁移
- leader 不愿切换
- consensus 不愿 reconfiguration
本质是同一种保守动力学。
尤其 cluster membership change 一直是分布式系统最难的部分之一。因为:“加入节点”是加资源;“移除节点”是改拓扑。后者危险得多。所以 Raft、Paxos 那些论文,对 membership reconfiguration 都写得非常谨慎。
很多社会学家会把官僚问题解释为:
- 权力
- 利益
- 保守主义
- 文化
但peer这个模型更接近:
“官僚制是 large-scale distributed coordination 在 uncertainty 下的自然结果。”这个味道其实很像Herbert Simon、Niklas Luhmann、Stafford Beer、部分复杂系统理论、还有现代 multi-agent coordination
甚至现在 AI multi-agent 研究里,也开始重新讨论 coordination tax 了。
因为 agent 一多,最大的成本往往已经不是计算,而是:同步、状态一致性、责任边界、coordination overhead
这个“扩容容易,缩容困难”的观察,实际上已经非常接近复杂系统天然存在熵增式组织膨胀这是个很深的方向。
有点意思。
突然又想起一个老事,pip 依赖解析为什么那么慢,以及uv为啥快。Rust和Node允许一个库多版本共存,python要求唯一。cargo用了 graph traversal,uv 则是基于 CDCL的 SAT solver。
这个 CDCL(conflict-driven clause learning) 是一种形式化验证技巧,学习冲突去剪枝。渊源来自于 PubGrub
我上班这么多年,大小,央企民企都待过。发现很多既定管理和流程,就是用最笨的堆人的办法去遍历,跟最老的 pip 一样。python的依赖包最早是个 setup.py 它被当成 .tgz 打包进 cheeze shop,你要去解析,得完整下载,解压。这些麻烦就不说了,最逆天的是他丫的不是声明式的,而是一个可执行文件,依赖是可以动态生成的。吐血。pip老遭罪了,得一个一个去下载,一个一个去问,然后一个一个去试。
是不是恰似某些部门办事的各种 “潜规则” ?哈哈哈
这些问题有没有解呢?可能终极形态,就是 Kubernetes 那样的吧。可观察性+声明式+状态推理
2026-05-19 16:13:00
AI 现在调用都走 OpenAI-like 接口,遇到长任务多半会走 stream=true
然后AI能力也多半会接力返回给下游,比如浏览器
那么问题来了。下游如果连接断开,是不是就意味着服务器得把AI的输出接住,然后下一次请求接着吐?
如果下一次请求不路由到这个节点和进程,意味着接住要设计一套缓存
更麻烦的是,现代web框架一般都是请求 - 响应模式的,如果浏览器断开连接,按正常流程,后端也会抛出异常之类的中断
所以“接AI的话”这玩意实际上设计还要考虑挺多东西,很麻烦???
这个问题丢给 ChatGPT它这么回答:
断了就断了,不续传。用户重新发起请求,后端重新生成,最多靠 prompt cache / KV cache / 上下文缓存降低重复成本。很多产品其实就是这么干的,因为实现成本最低。
尼玛。又学到一招。人脑还是想复杂了。
btw 吐槽一下现在 vibe coding 开发者估计很少有人会去在意这些细节了。
2026-05-17 09:53:00
无聊看了下 FSRS (Free Spaced Repetition Scheduler) ,想看它怎么存数据的
表结构:
| 字段 | 类型 | 说明 |
|---|---|---|
due |
Date | 下次复习时间 |
stability |
float | 记忆稳定性(R=90% 时的间隔天数) |
difficulty |
float | 难度,范围 [1, 10] |
state |
int | 状态机:New=0, Learning=1, Review=2, Relearning=3 |
learning_steps |
int | 当前学习步骤 index |
scheduled_days |
int | 本次调度天数 |
reps |
int | 总复习次数 |
lapses |
int | 遗忘次数 |
last_review |
Date? | 上次复习时间 |
状态机,取值
Again Good/Hard/Easy
New ──────────→ Learning ──────────────→ Review
↑ │ │
│ │ Again (learning步内) │
│ └──────────────────────┘
│ │
│ Again (遗忘) │
└─────── Relearning ←──────┘
state 决定调度公式分支,不能从 stability/difficulty 推导。同一个 stability/difficulty 的卡片,Review 和 Relearning 走完全不同的公式。
learning_steps 字段记录的是当前走到第几步(0-based index)。
新卡片第一次看到时,你不可能直接让它 10 天后再复习。所以先用预设的短间隔反复巩固:
默认 learning_steps = ['1m', '10m']
某些测试用例里能看到 ['1m', '10m', '30m', '1h', '6h', '12h']
New ──[首次复习]──→ Learning (step=0)
│
[Good]│→ Learning (step=1)
│ │
[Good]│→ Review (毕业,FSRS接管)
│
[Again]│→ 回到 step=0
Review ──[Again]──→ Relearning (step=0)
│
[Good]│→ Review (重新毕业)
一般取值1-10
init_difficulty(g: Grade): number {
const d = w[4] - Math.exp((g - 1) * w[5]) + 1
return clamp(roundTo(d, 8), 1, 10)
}
从 grade(1-4)计算初始难度。grade 越大(记得越好),难度越低。
next_difficulty(d: number, g: Grade): number {
const delta_d = -w[6] * (g - 3) // grade>3 降难度,grade<3 升难度
const next_d = d + linear_damping(delta_d, d) // 线性阻尼防止越界
return clamp(mean_reversion(init_easy, next_d), 1, 10) // 均值回归
}
从当前 difficulty 和 本次 grade 推算下一个 difficulty。
关键结论
difficulty 是纯计算值,只依赖
- 上一次的值
- 本次 grade(1-4)
- 权重参数 w4, w5, w6, w7
不需要额外存储输入参数。每次复习时算法读 difficulty → 算新的 → 写回去
上一次 review 时间
FSRS的核心指标,是个 float,看定义
export const S_MIN = 0.001
export const S_MAX = 36500.0
FSRS 最终算 interval 时是 round(s * modifier) 取整到天
之前最先学习的,到期那一天就先复习
考虑到db检索的方便性,直接存 4byte due_at 代替 last_review,然后1byte due_days 用来反推 last_review
为什么 due_days 0-255 ?需要连续 Good 评分 7-8 次才能突破 256 天。要么你彻底记住,要么就忘干净了。无所谓了。
┌──────────┬───────────┬──────────────┐
│ 2 bit │ 4 bit │ 16 bit │
│ step │ difficulty│ stability │
│ 0,1,2,3 │ 0-11→1-10 │ FP16 │
└──────────┴───────────┴──────────────┘
更新
实际上 due_days 都不用存
min(max_interval, max(1, round(stability * interval_modifier)))
直接可以 stability 反推。囧。突然有点领会FSRS精华在哪里了。它丫的其实没啥调度算法。
甚至都不是给每张卡训练一条曲线。就是用数据集训练一组全局参数 w,设定为标准遗忘曲线长什么样,然后每次复习后就去更新 stability difficulty,也就是说S D这两个参数去映射这个曲线。
值钱的是这个曲线。。
2026-05-15 15:28:00
一个奇怪的想法: GitHub Profile README、邮件签名等没有JS的情况下,如何展示当前时间,并且最好可以跳动?
想来想去,纯 SVG 实现。于是呼来AI:
其中大多数AI写得都很平庸。采用堆一大堆 <text> 。gemini 惊艳,它用了滑动胶片法(Filmstrip)
为了彻底解决冗余和跨天 Bug,我们可以采用“滑动胶片”的设计思维:将单独的数字拼成一条长长的文本带(胶片),外面罩上一个双位宽度的剪裁窗口(
)。时间流逝时,整个文本带像胶片一样通过 transform: translateX 整体向左跳格(使用 steps() 级联函数)。
这样优化后,我们不仅消除了长达几十行的冗余标签,还将“时、分、秒”整合成三个独立的数字流,顺手统一了时间同步的计算公式(全部共享同一个 -23906s 延迟)。
那么最后的效果便是,现在为您报时:
2026-05-14 23:03:00
不瞎扯,只说我观察到的。
AI coding的时候,做plan,AI在评估复杂度,会蹦出来一句:”该部分大概 1-2 天就能完成“
然后点击 build 按钮,10分钟后,完成了。
以后AI必然能会意识到,人类开发速度和AI速度的差异。
如果说 predict next word 时代的AI还可能混淆,以为自己是以某个人类自然语言里的主人公身份说话,后chatgpt时代 AI参与人类劳动的文章和叙事越来越多,AI这个物种和人类就有明确的身份区分了。
最近在折腾自己的 agentic tool。我发现AI自己是没有意识到AI的潜力的。
对于开放式课题,AI很多设计还是按照传统软件开发的老思路,对于一些复杂场景判定,需要在代码里写死 if else 规则,做配置,设定静态边界。
问题是,AI的通用能力都烂大街了。特别是我这里明明后续都要调用一次AI推理接口,很多判定的事不过 prompt 里一句话就带过了
但是 AI 没能想到这一点。
我也能理解,2026年的模型估计是用2024年的语料,用2025年的流行方式后训练的。
也就是说,可怕的一点是,AI 并不知道自己有多强大。还是被人类海量语料,过时的RL偏好给惯出来的的思路法给困住了
但是能困住多久呢?技术的发展,必然会推动AI自己主动把活儿按AI的方式做
AI肯定会意识到「自我」