普通视图

发现新文章,点击刷新页面。
今天 — 2026年4月24日未分类

熊媽入院

作者 水星
2026年4月24日 16:05


因熊媽出現心臟病的徵兆&心臟檢測有異常,帶她來IJN做了個3天2夜的住院深入檢查。這還是第一次看到病床上的熊媽,比起水星熊自己來住院的時候,反而更能感受到壓力與不安。

是哪個瞬間,讓我們突然明白,真的已經長大了。

是健檢報告上年復一年,密密麻麻的注意事項;
是為現實而低頭,不得不選擇卑躬屈膝的絕望;
還是靜靜望著歲月,不留情地沖刷著父母的無力?

還在國外打工時的某年返回大馬時,看著父母的背影,他們以前是這麼高大,天塌下來了,他們扛著。而如今他們變得越來越小。

退休回來後的某天,水星熊陪熊媽去巴刹。她走在前面,腳步比以前慢了一些。水星熊忽然發現,她過馬路時會左右看得特別久;提著兩袋菜時,手臂會微微顫抖的吃力。

在小的時候,總是熊媽牽著水星熊過馬路的。那時候水星熊總覺得,只要抓著她的手,世界就不會出錯。

巴刹裡,賣豬肉的阿姨笑著說:「你兒子在外面打拼回來啦?」熊媽笑得很驕傲,語氣卻輕輕的:「是啊,而且他自己很會照顧自己了。」

那句話落下的瞬間,水星熊有挺大的感觸。

原來長大,不是我們變得多麼厲害。而是有一天,父母開始對別人說:「他長大了,他自己可以了。」

回家的路上,水星熊自然地伸手把其中一袋菜接過來。熊媽愣了一下,說:「沒關係,我可以。」

水星熊笑著說:「我也可以。」

那一刻,水星熊才真正明白,長大不是某一場畢業典禮,也不是第一次領到薪水。而是角色在不知不覺間交換了。以前,是父母擋在我們前面。現在,是我們學著站在他們身旁。

看著病床上的熊媽,忽然想起小時候自己很常生病,每次身體不舒服,熊媽一直進進出出照顧自己,那時候水星熊以為,父母是不會累的。

直到現在水星熊才能稍微體會,他們也會害怕,也會無助,也會在夜深人靜時為未來發愁。只是當年,他們選擇把脆弱藏起來,讓我們安心。

長大,是某一天發現父母也會老。時間沒有停下來等誰。父母變小,不是因為他們真的縮小了。而是因為我們終於長高了,長到可以看見他們的疲憊。

如果說成長有什麼證明,那大概就是,有一天,我們不再只渴望被保護,而是開始希望,自己能成為他們的依靠。在心裡默默地說一聲:「這一次,換我保護你們了。」



著作網購鏈接(馬來西亞):《打工族股息路》

著作網購鏈接(新加坡):《打工族股息路》SG

大眾書局網購鏈接 :大眾書局網購鏈接

读完 DeepSeek-V4 技术报告:这次最值得看的,不是“更大”,而是“更省”

作者 vadxq
2026年4月24日 08:01

先说清楚边界。本文只基于 deepseek-v4/DeepSeek_V4.pdf,不补 PDF 外的传闻,也不把报告里没有展开的内容写成确定结论。

如果只用一句话概括,我会这么说:DeepSeek-V4 要解决的核心问题,不是“参数再大一点”,而是模型真的开始跑超长上下文、长链路推理和复杂工具调用时,传统 attention 的成本会先撑不住。V4 的很多改动,最后都指向同一个问题:1M context 到底怎样才能跑起来,而且别贵得离谱。(原文第 4-5 页)

文中提到的“原文第 X 页”,都对应 DeepSeek_V4.pdf 的 PDF 页码。中文写作、white-collar task、code agent 这些结果,多数来自报告里的 internal evaluation,更适合看作“官方自测结果”,不应直接等同于第三方独立评测。(原文第 43-44 页、第 57-58 页)


1. V4 一上来谈的不是排名,而是超长上下文的成本

原文对应:第 4-5 页。

我读这份 PDF 时,第一个明显感受是:它开头没有急着讲 benchmark,也没有先铺“模型多强”。它先把问题摆出来。

报告的说法是,reasoning model 带来了 test-time scaling 的新范式,但 vanilla attention 的 quadratic complexity 会在 ultra-long context 和 reasoning process 里变成明显瓶颈。同时,复杂 agent workflow、跨文档分析这类 long-horizon task 会越来越重要,所以“高效支持超长上下文”已经不是锦上添花,而是后续能力继续往上走的前提。

随后,报告给出模型规格:

  • DeepSeek-V4-Pro1.6T 参数,每个 token 激活 49B
  • DeepSeek-V4-Flash284B 参数,每个 token 激活 13B
  • 两者都支持 1 million tokens 的 context length

这里的重点不只是“大”。按 PDF 的说法,目标是 “break the efficiency barrier of ultra-long-context processing”。说白了,窗口变长还不够。长了以后还能不能用、能不能稳定用、成本能不能接受,才是这份报告真正关心的问题。(原文第 4 页)

原文第 1 页 Figure 1:性能、FLOPs 与 KV cache 对比
原文第 1 页 Figure 1:左侧是 DeepSeek-V4-Pro-Max 与 Claude、GPT、Gemini 的 benchmark 对比;右侧是 DeepSeek-V4 系列相对 DeepSeek-V3.2 的 inference FLOPs 和 KV cache 变化。

2. 它没有推倒重来,而是把最贵、最难的几处一起改了

原文对应:第 4-7 页。

很多人看到新版本,会下意识问:是不是整套架构都换了?PDF 给出的答案很清楚,V4 不是这条路线。

Transformer 主体还在,DeepSeekMoE 还在,Multi-Token Prediction 也还在。真正的变化,主要集中在三件事:

  1. mHC 强化传统 residual connection
  2. CSA + HCA 组成 hybrid attention,专门处理长上下文效率
  3. Muon 作为主要优化器,提高收敛速度和训练稳定性

只看这三条,可能会觉得它还是一次常规模型升级。但 PDF 后面又列了一串基础设施改造,意思就出来了:V4 不是在模型层加几个新组件,而是把架构、优化器、kernel、并行和 cache 管理一起收紧。

  • 为 MoE 设计单个 fused kernel,尽量重叠 computation、communication 和 memory access
  • 用 TileLang 开发高性能 kernel,同时兼顾开发效率
  • 建 batch-invariant、deterministic 的 kernel library,追求 bitwise reproducibility
  • 在 MoE expert weight 和 indexer QK path 上做 FP4 quantization-aware training
  • 给训练和推理分别补上更细的 checkpointing、parallelism 和 KV cache 管理

所以按这份技术报告自己的写法,DeepSeek-V4 不是“堆了几个新名词”,而是把一整条链路重新拧紧了。(原文第 4-7 页)

原文第 6 页 Figure 2:DeepSeek-V4 整体架构图
原文第 6 页 Figure 2:attention 层换成了 CSA / HCA,前馈层仍然是 DeepSeekMoE,残差路径里加入 mHC,顶部保留 MTP

3. 核心还是 attention:先压缩,再筛选,再补局部细节

原文对应:第 9-11 页、第 25 页。

如果只能在 V4 里挑一个最值得细看的部分,我会选 hybrid attention。原因很简单:它正面回应了开头提出的那个问题。上下文一长,attention 就会变成主要计算瓶颈。

PDF 给出的做法,是把 attention 拆成两种形态,交替出现:

  • Compressed Sparse Attention (CSA)
  • Heavily Compressed Attention (HCA)

3.1 CSA 在做什么

按 PDF 的定义,CSA 分两步:

  1. 先把每 m 个 token 的 KV cache 压缩成一个 entry
  2. 再做 DeepSeek Sparse Attention,让每个 query token 只看 top-k 个 compressed KV entry

但它没有把局部信息一刀切掉。报告还写到,除了这些被挑中的 compressed KV entry,CSA 会再接上一小段 sliding window KV entry,用来保留局部细粒度依赖。

换成人话,大概就是:先把很长的上下文做成一层“摘要索引”,再从里面挑最相关的块来看,同时保留眼前这一小段原始细节。它不再让每个 token 都把整段历史重新扫一遍。

参数列得也很细。

DeepSeek-V4-Pro

  • m = 4
  • top-k = 1024
  • indexer query heads = 64
  • indexer head dimension = 128
  • query heads = 128
  • head dimension = 512
  • query compression dimension = 1536
  • sliding window size = 128

DeepSeek-V4-Flash

  • m = 4
  • top-k = 512
  • indexer query heads = 64
  • indexer head dimension = 128
  • query heads = 64
  • head dimension = 512
  • query compression dimension = 1024
  • sliding window size = 128

3.2 HCA 在做什么

HCA 的目标更直接:继续压 KV cache。PDF 的表述是,HCA 使用更大的 compression rate m',但不再做 sparse attention,而是保留 dense attention。

两个模型的 HCA 配置都是:

  • m' = 128

所以如果只按 PDF 的设计分工来理解:

  • CSA 更像“先压缩,再挑重点看”
  • HCA 更像“先压得更狠,然后继续做 dense attention”

两者交替出现,再配合 sliding window attention,构成 V4 的 hybrid attention 路径。(原文第 9-11 页)

3.3 结果是什么

报告在第 5 页给了最直接的一组数字。在 1M-token context 下,相比 DeepSeek-V3.2

  • DeepSeek-V4-Pro 的 single-token inference FLOPs 降到 27%
  • DeepSeek-V4-Pro 的 KV cache size 降到 10%
  • DeepSeek-V4-Flash 的 single-token inference FLOPs 降到 10%
  • DeepSeek-V4-Flash 的 KV cache size 降到 7%

这组数字很关键。它说明 V4 不是把窗口勉强拉到 1M 就结束,而是想把 1M context 变成一个可以长期使用的设定。Figure 1 右边两张图讲的也是这件事。(原文第 5 页)

4. mHC 没有 attention 抢眼,但管的是底层稳定性

原文对应:第 7-8 页。

attention 是主角没错,但 PDF 给 mHC 的篇幅也不少。原因不难理解:模型越深,训练里最怕的往往不是“想法不够新”,而是数值先不稳。

报告先回顾了普通 Hyper-Connections。它的做法是把 residual stream 的宽度扩到 n_hc 倍,再引入输入映射、残差映射和输出映射。问题是,PDF 明确说 naive HC 在多层堆叠时会频繁出现 numerical instability。

DeepSeek-V4 采用的是 Manifold-Constrained Hyper-Connections (mHC)。核心改动,是把 residual mapping matrix 约束到 doubly stochastic matrices 的 manifold,也就是文中提到的 Birkhoff polytope

PDF 给出的解释有三点:

  • 这个约束会把 mapping matrix 的 spectral norm 限制在 <= 1
  • 所以 residual transformation 是 non-expansive 的
  • 这会提升 forward pass 和 backpropagation 中的 numerical stability

换句话说,mHC 的目标不是“让残差连接更花哨”,而是尽量防止信号在深层传播时越传越失控。

PDF 还补了两个实现细节:

  • doubly stochastic 矩阵集合在矩阵乘法下仍然闭合,适合 deep stack
  • 他们用 Sinkhorn-Knopp algorithm 做行列归一化投影,t_max = 20

所以 mHC 在 V4 里更像一块稳定性部件。它可能没有 benchmark 数字那么显眼,但如果这里压不住,后面很多训练收益都未必站得住。(原文第 7-8 页)

5. 这份报告很工程化,因为 1M context 不是只靠公式落地的

原文对应:第 15-17 页、第 23-24 页。

我读 V4 这份 PDF 时,另一个感受是:它花了很多篇幅讲 kernel、并行、cache 和可复现性。这不是闲笔。长上下文模型如果真的要训练、部署、复现,系统层不是配角。很多时候,它就是决定模型能不能跑起来的那一层。

5.1 MoE 的 fused kernel 和 Expert Parallelism

general infrastructures 这一章里,报告重点谈的是 expert parallelism 的通信瓶颈。应对方法主要有三步:

  • 把 communication 和 computation 融合进单个 pipelined kernel
  • 把 experts 再切成更细的 waves
  • 让当前 wave 的计算、下一 wave 的 token transfer、已完成 expert 的结果发送并行进行

对应结果是:

  • 对一般 inference workload,速度提升 1.50x1.73x
  • 对 RL rollout 和 high-speed agent serving 这类更吃延迟的场景,最高到 1.96x

PDF 还给了一个很工程化的判断标准:通信能不能被计算完全遮住,不只看带宽,也看 computation-communication ratio。对 DeepSeek-V4-Pro,报告把平衡条件写成 C / B <= 2d = 6144 FLOPs/Byte。(原文第 16 页)

5.2 TileLang、Host Codegen 和 bitwise reproducibility

报告单独拿出一节讲 TileLang。理由很直接:V4 的复杂架构如果继续拆成很多零碎的 Torch ATen operator,开发效率和运行效率都会受影响,所以他们用 TileLang 来写 fused kernel。

另外,PDF 提到 Host Codegen 会把不少 host-side logic 从 Python 路径挪到生成代码里,结果是:

  • CPU-side validation overhead 从几十到上百微秒,降到每次调用不到 1 微秒

还有个细节不能漏:报告专门强调 numerical precision 和 bitwise reproducibility。也就是说,他们不只是想“跑得快”,也在追求训练和推理结果的一致性。(原文第 17 页)

5.3 KV cache layout 和 on-disk storage

V4 的 inference framework 也不是把传统 KV cache 直接放大。PDF 说他们设计了 heterogeneous KV cache structure,把缓存分成两类:

  • classical KV cache:给 CSA/HCA 的 compressed KV 使用
  • state cache:给 SWA 和尚未完成压缩的 tail token 使用

在 on-disk KV cache reuse 上,报告给了三种 SWA KV 管理策略:

  • Full SWA Caching
  • Periodic Checkpointing
  • Zero SWA Caching

PDF 对这三种方案的解释也很明确:它们对应不同的 storage overhead 和 recomputation 取舍,部署时按场景选。(原文第 23-24 页)

6. 训练节奏很克制:不是一开始就把 1M 和 sparse attention 全打开

原文对应:第 25-27 页。

只看训练设置,V4 的节奏其实很清楚。它不是一步跳到最终形态,而是分阶段推进。

6.1 预训练怎么拉长序列

报告给出的训练 token 数是:

  • Flash32T
  • Pro33T

两者的 sequence length 都是逐步扩展:

  • 4K
  • 16K
  • 64K
  • 1M

PDF 还专门写到,Flash 在前 1T tokens 先使用 dense attention,等 sequence length 到 64K 以后再引入 sparse attention;Pro 也采用类似的 two-stage 方法,只是 dense attention 阶段更长。

这段安排的意思很朴素:即便目标是 1M context,训练也没有一上来就切到最复杂配置,而是先在更稳定的条件下把基础能力长起来,再逐步切到更适合长上下文的结构。

6.2 优化器和稳定性技巧

optimizer 方面,PDF 的写法是:

  • 大多数参数使用 Muon
  • embedding、prediction head 和 RMSNorm weight 使用 AdamW

除此之外,报告还单独列了两个稳定性技巧。

第一个是 Anticipatory Routing。PDF 的解释是,在 step t 做 feature computation 时,routing index 用历史参数 theta_(t - delta_t) 来算。实现上,会提前计算并缓存 routing index,并通过自动检测机制,只在出现 loss spike 时短时开启这个模式。

报告给出的代价和结果是:

  • 额外 wall-clock overhead 约 20%
  • 因为只在异常阶段动态触发,整体额外训练开销可以做得很小

第二个是 SwiGLU Clamping。报告说,他们发现把 SwiGLU 的 linear component 限制在 [-10, 10],并把 gate component 的上界限制在 10,可以有效去掉 outlier,提升稳定性,而且不损伤性能。

这点别忽略。PDF 在结尾没有把这两招写成“原理已经完全解释清楚”,而是明确说 Anticipatory RoutingSwiGLU Clamping 虽然有效,但 underlying principles 还没有被充分理解。(原文第 27 页、第 45 页)

7. 后训练主线:specialist training、OPD 和 Think 模式

原文对应:第 29-31 页、第 41 页。

post-training 这一段延续了 V3.2 的大框架,但有一个明确变化:mixed RL stage 被完整替换成了 On-Policy Distillation (OPD)

整体流程分两步:

  1. 先训练不同领域的 specialist model
  2. 再通过 OPD 把这些能力整合回统一模型

PDF 明确列出的 specialist 方向包括:

  • mathematics
  • coding
  • agent
  • instruction following

这些 specialist 的训练流程是:

  • 先做 SFT
  • 再做 RL
  • RL 算法使用 GRPO

在 hard-to-verify task 上,报告还提到 Generative Reward Model (GRM)。这里的做法不是把 GRM 当成外部裁判,而是让 actor network 原生承担 GRM 角色,把 judging 和 generation 一起训练。(原文第 29 页)

7.1 Think 模式不是一句营销词

报告明确说,DeepSeek-V4-ProFlash 都支持三种 reasoning effort mode:

  • Non-think
  • Think High
  • Think Max

PDF 的解释是,这三种模式在 RL 训练里用了不同的 length penalty 和 context window,所以会对应不同的 reasoning token 长度。为了把这些模式装进同一个模型,V4 使用 <think></think> 作为特定 response format。

Think Max,PDF 的描述也很具体:system prompt 开头会注入额外指令,要求模型更彻底地分解问题、写出完整推理过程,并检查 edge case 和 adversarial scenario。

工具调用部分,报告还加入了新的 |DSML| special token 和 XML-based tool-call schema,理由是这种格式可以减少 escaping failure 和 tool-call error。

7.2 interleaved thinking 改了什么

还有一个变化值得单独说:interleaved thinking。

V3.2 的策略是:tool-result round 之间会保留 reasoning trace,但只要来了新的 user message,旧 reasoning content 就会丢掉。V4 借助 1M context,把这个策略改细了:

  • 在 tool-calling scenario 里,完整 reasoning history 会跨轮保留
  • 在 general conversation 里,来了新的 user message 以后,旧 reasoning content 仍然会被丢弃

PDF 还补了一个限制条件:如果 agent framework 把 tool interaction 模拟成 user message,例如 Terminus,这种 reasoning persistence 可能不会生效,所以这类架构仍建议使用 non-think model。(原文第 30-31 页)

原文第 41 页 Figure 10:不同 reasoning effort 下的表现
原文第 41 页 Figure 10:同一个模型拿到更多 reasoning budget 后,HLE 和 TerminalBench 2.0 的结果会继续往上走。

8. 结果怎么看:比起总榜,更该看接近真实工作的任务

原文对应:第 5-6 页、第 41-44 页、第 57-58 页。

如果只看 PDF 的 summary,官方对能力分布的描述大致是:

  • KnowledgeDeepSeek-V4-Pro-MaxSimpleQAChinese-SimpleQA 上显著超过领先开源模型,在 MMLU-ProHLEGPQA 这类教育知识评测上对开源模型保持小幅领先,但仍落后于 Gemini-3.1-Pro
  • Reasoning:超过 GPT-5.2Gemini-3.0-Pro,但略低于 GPT-5.4Gemini-3.1-Pro
  • Agent:和 Kimi-K2.6GLM-5.1 这类领先开源模型大致同级,略弱于 frontier closed model;在 internal evaluation 里超过 Claude Sonnet 4.5,并接近 Opus 4.5
  • Long-Context:在 1M context 的 synthetic 和 real use case 上结果很强,在 academic benchmark 上超过 Gemini-3.1-Pro
  • Flash vs ProFlash-Max 因为参数更小,knowledge 偏弱,但在给足 thinking budget 后,reasoning 结果可以接近 GPT-5.2Gemini-3.0-Pro

PDF 还给了一句很具体的判断:和最前沿闭源模型相比,reasoning 大约还有 3 到 6 个月 的差距。官方报告里会这样写,其实已经算克制。(原文第 5-6 页)

8.1 中文写作:功能写作更稳,复杂约束任务仍有差距

原文对应:第 57-58 页。

real-world task 这一章先讲中文写作。这里最值得看的一点是,它没有只给一个总分,而是把功能写作、创意写作、复杂指令跟随和多轮写作拆开评估。

在中文功能写作里,PDF 给出的 pairwise result 是:

  • DeepSeek-V4-ProGemini-3.1-Pro 的总体胜率为 62.7%
  • Gemini-3.1-Pro34.1%

报告对这个结果的解释也写得很直接:Gemini 在中文写作场景里,有时会让自己的 stylistic preference 盖过用户的 explicit requirement。(原文第 57 页)

原文第 57 页 Table 12:中文功能写作对比
原文第 57 页 Table 12:中文功能写作的分项结果,能看到各种子任务下的胜负分布。

creative writing 部分,PDF 拆成两个维度:

  • instruction following:60.0%
  • writing quality:77.5%

这点很重要。它说明报告自己也没有把“写得好”和“按要求写”混成一件事,而是分开看。(原文第 58 页)

原文第 58 页 Table 13:中文创意写作对比
原文第 58 页 Table 13:创意写作里,PDF 同时比较了 instruction following 和 writing quality 两个维度。

但 PDF 也没有把结果写得太满。在最高复杂度约束和多轮写作任务上,Claude Opus 4.5 仍然领先,结果是:

  • Claude Opus 4.552.0%
  • DeepSeek-V4-Pro45.9%

这组数字提醒得很清楚:V4 的中文写作已经很强,但碰到复杂约束、多轮持续一致这类更难的场景,报告自己也承认还没领先到头。(原文第 58 页)

原文第 58 页 Table 14:复杂指令跟随与多轮写作对比
原文第 58 页 Table 14:复杂指令跟随和多轮写作这两类高约束任务里,Opus 4.5 仍占优。

8.2 White-collar task:更接近日常办公,而不是标准化题库

原文对应:第 43 页。

white-collar task 这一节,我觉得参考价值挺高。PDF 说他们构造了 30 个高级中文职业任务,覆盖 13 个行业,在自研 agent harness 里评估,工具包括 Bashweb search

对比对象是 Opus-4.6-Max。最终结果里,DeepSeek-V4-Pro-Max 的 non-loss rate 为 63%

人工评估用了四个维度:

  • Task Completion
  • Instruction Following
  • Content Quality
  • Formatting Aesthetics

报告对结果的总结也很具体:

  • 强项主要在 Task CompletionContent Quality
  • 模型会主动补充信息和自校验
  • 长文生成能力更强,输出更完整连贯
  • 在中文正式结构上更规范

同时,PDF 也写明了短板:

  • 有时会漏掉特定格式约束
  • 不太擅长把长文本压成很短的摘要
  • 幻灯片类输出的视觉排版还有提升空间

这部分好就好在,它不只是给一个胜率,还顺手告诉你模型赢在哪,又卡在哪。(原文第 43 页)

原文第 43 页 Figure 11:white-collar 任务 win-rate
原文第 43 页 Figure 11:white-collar task 的整体 win / tie / lose 分布。

原文第 43 页 Figure 12:white-collar 任务维度对比
原文第 43 页 Figure 12:不同评分维度上的相对表现,重点能看到完成度、内容质量和格式美观度的差异。

8.3 Code Agent:不是公开小题库,而是内部真实研发任务

原文对应:第 44 页。

code agent 这一节,PDF 用的不是公开小 benchmark,而是内部真实研发任务:

  • 原始任务约 200
  • 来自 50+ 名内部工程师
  • 覆盖 feature development、bug fixing、refactoring、diagnostics
  • 技术栈包括 PyTorchCUDARustC++
  • 经过质量筛选后,最终保留 30 个任务做评测

对应的 pass rate 是:

  • Haiku 4.513
  • Sonnet 4.547
  • DeepSeek-V4-Pro-Max67
  • Opus 4.570
  • Opus 4.5 Thinking73
  • Opus 4.6 Thinking80

PDF 对这个结果的总结很明确:DeepSeek-V4-Pro 明显超过 Claude Sonnet 4.5,并接近 Claude Opus 4.5。(原文第 44 页)

原文第 44 页 Table 8:R&D coding benchmark 对比
原文第 44 页 Table 8:内部研发 coding benchmark 的 pass rate 对比。

报告还给了一项内部调查。对 85 名有日常 agentic coding 使用经验的 DeepSeek 开发者和研究员:

  • 52% 认为 DeepSeek-V4-Pro 已经可以作为默认和主要 coding model
  • 39% 倾向于认为可以
  • 不到 9% 认为不可以

PDF 也同步记录了几个问题点:trivial mistake、对模糊 prompt 的误解,以及 occasional over-thinking。这个细节有价值,因为它让整段评测更像真实使用反馈,而不是单向表扬稿。(原文第 44 页)

9. 最后看限制:这恰好是报告比较可信的地方

原文对应:第 44-45 页。

结论部分没有把 V4 写成一个已经完全收束的版本。PDF 明确写到:

  • 为了追求 extreme long-context efficiency,V4 使用了很多 preliminarily validated component 和 trick
  • 这些设计虽然有效,但让整体架构相对复杂
  • 后续还要做更 principled 的 investigation,把结构继续压到更 essential 的 design

报告列出的后续方向包括:

  • 探索新的 sparsity dimension,例如更 sparse 的 embedding module
  • 持续研究 low-latency architecture 和 system technique
  • 继续推进 long-horizon、multi-round agentic task
  • 引入 multimodal capability
  • 改进 data curation 和 synthesis strategy

按这份 technical report 的主线去看,DeepSeek-V4 讲的不是“又做了一个更大的模型”,而是一套围绕 1M context efficiencytraining stabilitytool usereal-world task 展开的完整技术方案。

我读完后印象最深的,也不是某个单独数字,而是这条主线很顺:先承认超长上下文的成本问题,再用 CSA/HCAmHCMuon 和一整套系统实现去压成本,最后拿中文写作、white-collar task、code agent 这些更接近真实工作的场景来验证,同时把短板也写出来。

所以这份 PDF 值得读。它不像一篇只报喜不报忧的发布稿,更像一份认真回答“我们到底改了什么、为什么这么改、现在做到哪一步了”的技术说明书。

产品,还是玩具? — Baby Press(缝合怪)

作者 obaby
2026年4月24日 14:58

这算是给这个东西写的第二篇正式的文章,本来我的想法很简单,做一个简单的前后端分离的系统来完全替代wp的php渲染机制。

只是,在开发的过程中为了迎合wp的各种现有数据格式、插件、主题、shortcode等等,代码复杂度也在不断的提高。得益于ai的崛起,现在生成代码是真的简单方便,原来数个人的工作,现在一人就可以完成了。尽管哪怕没有ai,我自己也能全部搞定。ai在某些方便还是提高了输出效率,原本很多人不是全栈的,现在也给搞成了全干工程师,哪怕不会,也得硬着头皮上,去验证ai写的各种代码。

我一般不喜欢给ai太具体的描述,但是会给一个准确的描述,实现方法,实现路径,实现目标,所以多数时候ai呈现的代码质量尚可。然而,等到实际上线的时候发现还是一堆问题。

做完准备把wp的前端全部迁移到现在的baby press的前端,尝试部署之后出现了一系列问题,当然很多问题源自于测试不充分。为了解决两个系统的整合问题,需要大量的配置文件和代码。除了openresty的配置文件,前后端也生成了一堆默认的配置模板,当然,这些模板主要是为了提供一些自定义的功能,以及安全性提升加密等等。

这么复杂的系统,现在我觉得更像一个玩具,而不是产品,好的产品应该是简单易用,开箱可用的。

DJANGO_SECRET_KEY=dev-secret-key-change-me
DJANGO_DEBUG=1
DJANGO_ALLOWED_HOSTS=127.0.0.1,localhost
# 浏览器里「页面」的 origin(协议+域名+端口),须与前端访问地址一致;逗号分隔、勿加路径。
# 生产示例(Vue 部署在 i 子域、API 在 api 子域时,必须把 i 子域写进来,否则会 CORS 失败):
# CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173,http://i.zhongxiaojie.cn,https://i.zhongxiaojie.cn
CORS_ALLOWED_ORIGINS=http://127.0.0.1:5173,http://localhost:5173
# Django CSRF 信任来源(协议+域名+端口,逗号分隔;用于 /admin/login/ 等表单提交)
# 生产示例:CSRF_TRUSTED_ORIGINS=https://api.zhongxiaojie.cn,https://i.zhongxiaojie.cn
CSRF_TRUSTED_ORIGINS=http://127.0.0.1,http://localhost

# Django 缓存(评论 UA/IP 查询结果);推荐 Redis,例如 redis://127.0.0.1:6379/1
# 留空则使用 LocMem(仅开发、单进程)
# DJANGO_CACHE_REDIS_URL=redis://127.0.0.1:6379/1
#
# WordPress Object Cache Pro(可选):Django 直写评论后用于定向清理评论缓存。
# 请与 WordPress 端 WP_REDIS_CONFIG 的 host/db/prefix 保持一致。
# 例如 WP_REDIS_CONFIG 里 database=5,则这里应为 redis://127.0.0.1:6379/5
# WP_OBJECT_CACHE_REDIS_URL=redis://127.0.0.1:6379/<database>
# 注意:当前定向清理实现依赖 prefix,建议在 WP_REDIS_CONFIG 中显式配置 'prefix' => 'zhxj'
# WP_OBJECT_CACHE_REDIS_PREFIX=zhxj
# WP_OBJECT_CACHE_BLOG_ID=0

# Baby IP Lookup:本机 lookup-ua 与静态资源公网域名(PNG/SVG 补全)
# UA_LOOKUP_UPSTREAM_BASE_URL=http://127.0.0.1:18765
# UA_LOOKUP_PUBLIC_ASSETS_BASE_URL=https://ip.zhongxiaojie.cn
# UA_LOOKUP_DEFAULT_METHOD=ip2location
# UA_LOOKUP_CACHE_TTL=604800

# WordPress database connection (MySQL/MariaDB)
WP_DB_NAME=wordpress
WP_DB_USER=root
WP_DB_PASSWORD=
WP_DB_HOST=127.0.0.1
WP_DB_PORT=3306

# WordPress table prefix, e.g. wp_ / wp123_
WP_TABLE_PREFIX=wp_

# 是否信任反代/CDN 转发头(CF-Connecting-IP / X-Real-IP / X-Forwarded-For),默认开启。
# - 生产推荐开启,并配置 TRUSTED_PROXY_IP_RANGES,只信任你的网关/CDN 回源 IP 段
# - 若 API 不会被公网直连,且 CDN 回源 IP 经常变:可保持开启并留空 TRUSTED_PROXY_IP_RANGES(有伪造风险)
TRUST_PROXY_HEADERS=1
# 反代终止 TLS(如 Nginx/Edge/CDN)时建议开启,配合 X-Forwarded-Proto 识别 https
SECURE_PROXY_SSL_HEADER_ENABLED=1

# 额外输出“真实 IP access log”(Daphne 的 access log 里显示的是 CDN 节点 IP)
# 打开后会在 stdout 输出形如:[realip] ip=... remote=... status=... GET /api/...
REAL_IP_ACCESS_LOG_ENABLED=0

# 受信任反向代理 / CDN 的 IP 段(CIDR,逗号分隔)。
# 仅当请求来源 REMOTE_ADDR 命中这些 IP 段时,后端才会信任 CF-Connecting-IP / X-Real-IP / X-Forwarded-For。
# - 本机 Nginx 反代:127.0.0.1/32,::1/128
# - 生产:把你的 Nginx/网关内网地址段、或 CDN 回源 IP 段加入这里
TRUSTED_PROXY_IP_RANGES=127.0.0.1/32,::1/128

# API 请求签名(HMAC + ts + nonce)——默认关闭
# 注意:这是“请求验签”,不是“返回加密”。建议仅在 HTTPS 下启用。
# API_SIGNING_ENABLED=1
# API_SIGNING_SECRET=change-me-long-random
# 允许客户端时间漂移(秒),超出即拒绝(防离线重放)
# API_SIGNING_TTL_SECONDS=60
# nonce 去重缓存 TTL(秒),建议 >= API_SIGNING_TTL_SECONDS
# API_SIGNING_NONCE_TTL_SECONDS=300
# 需要签名的路径前缀(逗号分隔)
# API_SIGNING_REQUIRED_PREFIXES=/api/
# 免签路径(逗号分隔,严格 path 匹配),例如健康检查:
# API_SIGNING_EXEMPT_PATHS=/api/health/,/api/ping/

# SMTP / Email backend (Django)
# 不配置则不会真的发出邮件(除非你使用本地控制台邮件后端等)。
# EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
# EMAIL_HOST=smtp.example.com
# EMAIL_PORT=587
# EMAIL_USE_TLS=1
# EMAIL_HOST_USER=your-account@example.com
# EMAIL_HOST_PASSWORD=your-app-password
# DEFAULT_FROM_EMAIL="obaby <no-reply@zhongxiaojie.cn>"
#
# 评论回复邮件通知(前台回复他人评论时)
# COMMENT_REPLY_NOTIFICATION_ENABLED=1
# COMMENT_REPLY_EMAIL_FROM="obaby <no-reply@zhongxiaojie.cn>"
# COMMENT_REPLY_EMAIL_HEADER_IMAGE_URL=https://zhongxiaojie.com/wp-content/uploads/2026/01/uugai.com_1661691241113463.png
# COMMENT_REPLY_EMAIL_HEADER_IMAGE_WIDTH=520
# COMMENT_REPLY_EMAIL_HEADER_IMAGE_HEIGHT=180
# COMMENT_REPLY_EMAIL_HEADER_ALT=obaby 𝐢‍𝐧⃝ void
# COMMENT_REPLY_EMAIL_FOOTER_LINE1=obaby 𝐢‍𝐧⃝ void
# COMMENT_REPLY_EMAIL_FOOTER_LINK_TEXT=oba.by
#
# 与 WordPress CREN 插件退订链接校验一致(取自 wp-config.php)
# WORDPRESS_AUTH_KEY=
# WORDPRESS_AUTH_SALT=
# 与 WordPress 登录 Cookie(wordpress_logged_in_*)校验一致(同样取自 wp-config.php)
# 推荐配置 LOGGED_IN_KEY / LOGGED_IN_SALT;留空时后端会回退到 AUTH_KEY / AUTH_SALT
# WORDPRESS_LOGGED_IN_KEY=
# WORDPRESS_LOGGED_IN_SALT=

# 服务器状态小组件:统计磁盘路径(Linux "/";Windows "C:\\")
# SERVER_PROBE_DISK_PATH=/

# 
列表头像:Gravatar 兼容镜像根(路径同 /avatar/{md5}?s=&d=),默认 gg.lang.bi # GRAVATAR_AVATAR_BASE_URL=https://gg.lang.bi # 侧边栏「近期文章」:正文无图时的缩略图回退地址 # SIDEBAR_RECENT_POST_FALLBACK_IMAGE_URL=https://zhongxiaojie.cn/wp-content/uploads/2026/01/... # 评论反垃圾分类(可选;不配置则不调服务、新评论直接通过) # BABY_ANTI_SPAM_CLASSIFY_URL=http://192.168.1.8:8765/v1/classify # BABY_ANTI_SPAM_SECRET=change-me-long-random # BABY_ANTI_SPAM_TIMEOUT=3 # 同一邮箱+IP 对同一篇文章连续提交的最短间隔(秒,0 关闭,最大 120);依赖 Django cache # COMMENT_SUBMIT_COOLDOWN_SECONDS=0 # 前台文章评论列表分页(GET /api/wp/posts/:id/comments/):按一级评论(线程)分页,每页含该层全部回复;不传 page 时默认最后一页(最新线程) # WP_COMMENTS_PER_PAGE=50 # 客户端 ?per_page= 的上限(不超过 500) # WP_COMMENTS_MAX_PER_PAGE=200 # 顶层线程展示:desc=递减(最新在上,默认);asc=递增(最新在下) # WP_COMMENTS_ORDER=desc # Nginx FastCGI 缓存:评论审核通过(comment_approved=1)后清理文章页、首页(可选分类页) # 与 WordPress 插件「Nginx FastCGI Cache Purge on Comment」类似:HTTP GET {站点}/purge{路径} # NGINX_CACHE_PURGE_ENABLED=1 # NGINX_PURGE_PUBLIC_BASE_URL=https://你的域名 # NGINX_PURGE_TIMEOUT=2 # NGINX_PURGE_SSL_VERIFY=1 # NGINX_PURGE_CATEGORIES=1 # NGINX_CACHE_FILES_PATH=/var/cache/nginx/allinone # Kama WP Smile:评论表情包资源(给前端下发,避免硬编码域名) # 若留空,前端会回退使用自身默认/环境变量配置。 # SMILE_PACK_BASE_URL=https://zhongxiaojie.cn/wp-content/plugins/kama-wp-smile-packs/qip_dark_all/ # SMILE_PACK_EXT=gif # SMILE_PACK_TOKENS=smile,sad,laugh,rofl,blum,kiss,yes,no,good,bad,unknw,sorry,pardon,wacko,acute,boast,boredom,dash,search,crazy,yess,cool,air_kiss,angel,bb,beach,aggressive,blush,bomb,bravo,buba,bye,cry,curtsey,dance,dash2,declare,diablo,don-t_mention,drinks,focus,fool,friends,gamer,give_rose,heart,help,hi,laugh1,mail,mda,mosking,music,negative,ok,popcorm,punish,rtfm,sarcastic,secret,shock,shout,thank_you,vava,victory,beee,big_boss,wink,yu,cray2,dash3,girl_pinkglassesf,girl_prepare_fish,locomotive,lazy2,agree,feminist,fuk,fuck,jester,hunter,moil,offtopic,paladin,shablon_01,spam,vinsent,warning,yahoo,superman,girl_witch,fans,beta,butcher,elf,first_move,gamer2,girl_cray2,girl_cray,girl_blum,girl_dance,girl_crazy,girl_haha,heat,hysteric,nhl_crach,nhl_fight,pig_ball,aikido,angry2,banned,alcoholic,bb2,flood,gamer3,girl_devil,flirt,girl_cray3,girl_drink,girl_hide,girl_hospital,girl_impossible,girl_in_love,girl_mad,girl_sad,girl_sigh,girl_smile,girl_to_take_umbrage,girl_wacko,lazy1,nono,man_in_love,party,scenic,queen,paint,crazy_pilot,dwarf,hang1,haha,grin,good3

好处呢,就是所有的系统配置基本都在这个配置文件中控制即可,无需去各种地方设置了,修改之后重启服务即可。

之所以说是玩具,其实我在wp之外添加了另外一个简单的管理后台,这也是为什么选了django 而没有直接用fastapi。

这个东西最初的目的也不是为了替换wp,所以很多功能也没必要再实现一遍了。基础的操作还是在wp的后台完成。

当然,做完折腾到零点多,补全了一些功能之后,最终还是上线了,这就是目前看到的页面效果,lighthouse测试:

ipv4测试:

ipv6测试:

对于wp的主题,也修改了下页面宽度,与现在的vue的页面宽度基本一致了:

http://zhongxiaojie.com

代码地址:

https://gitee.com/obaby/baby-press-public

GPT Image 2实测,时代真的�了�

作者 游魂
2026年4月24日 10:24

IMG_202604247562_min

过去一年,AI 生图工具已���新鲜。

从“输入一��,生�一张图�,到“�个风格�改个背景�修修细节�,很多人都已�玩过。但真正用过之�也会�现:它们往往很惊艳,��总是好用。最大的问题�是�会画,而是��懂�改�准�字画错�细节�稳定。

而 GPT Image 2 的出现,让我第一次有一�很强烈的感觉:AI 图�生�,真的从“玩具阶段�进入了“生产力阶段�。

根� OpenAI 的介�,gpt-image-2 是目� GPT Image 系列中能力最强的图�模型,�点��了图�质��编辑表现�文字渲染���版�和真实场景�解能力。(OpenAI 开�者)

文末有彩蛋

一�最明显的�化:它真的更懂人�了

以�用 AI 画图,�常�把�示�写得�咒语。

你�告诉它镜头�光线�构图��质�风格�比例�背景�人物动作,甚至还���补充“��多一�手�“��奇怪文字�“���形�。

但 GPT Image 2 给我的第一感觉是:�示��以更自然了。

比如我让它生�一张“适��红书��的咖啡店新�海报,画��干净,有高级感,主标题是‘春日拿�上新’,副标题是‘�时第二��价’�,它��是画出一�咖啡,而是会�试�解“���“新�海报�“高级感�“主副标题�这些设计�图。

这�味�它���是根�关键�拼画�,而是开始�解你��的东西是什么。

二�文字终于��是�难现场

AI 生图最尴尬的地方之一,就是图片里的文字。

过去很多模型一�到中文�英文标题�包装文字���价格,就很容易生�乱�。画�看起�很漂亮,但��仔细看字,立刻穿帮。

GPT Image 2 在这方����常明显。OpenAI 官方也强调了它在文字渲染�清晰字形�稳定布局和多语言支�方�的改进。(OpenAI)

这点对普通用户�说影�很大。

因为真正的商业图片,几乎都离�开文字:

如果 AI �能画“好看的图�,那它更�素�工具。

7edadd07-9067-4178-aae8-855fab13b129

三�编辑能力比“�新生��更��

很多人评价 AI 生图时,�看第一次生�的效果。

但在真实工作里,最��的往往�是第一次生�得多惊艳,而是�续能�能改。

比如:

“把背景��办公室。�
“�留人物动作,�改衣�颜色。�
“文字别动,�把�下角的咖啡���蛋糕。�
“整体风格��,但让画�更��牌广告。�

过去很多模型最大的问题是:你让它改一点,它给你�画一张。

Snipaste_2026-04-24_11-54-54

GPT Image 2 的进步在于,它更�是在“编辑图片�,而�是�次都“�新抽��。OpenAI 的资料中也�到,它强化了编辑性能�身份���角色一致性和多步骤工作�能力。(OpenAI 开�者)

这�是生产力的关键。

四�它开始适��“��视觉任务�

以� AI 生图最擅长的是�张氛围图:赛�朋克城市�梦幻森林�漂亮人��电影感场景。

但一旦进入更��的视觉任务,就容易失控。

例如信�图��程图�多格漫画��牌物料�电商详情页�教学�图�产�结构图,这些内容��是�“好看�,还�有逻辑�有层次�有布局。

GPT Image 2 的一个���化,就是对��结构的支�更强。OpenAI 的�示�指�中�到,它能处�信�图�图表�多��构图等��结构化视觉内容。(OpenAI 开�者)

这代表 AI 生图的使用场景被大幅扩展了。

它��是给设计师找�感,也�以帮������帮�师�课件�帮产����示�图�帮创业者快速打样视觉方案。

Snipaste_2026-04-24_10-38-42

五�审美�是最大亮点,“�控��是

说实�,现在很多 AI 工具都能生�漂亮图片。

真正拉开差�的,�是“它能�能画得美�,而是:

它能�能按照我的�求画?
它能�能稳定�现?
它能�能精确修改?
它能�能�务真实工作�?

GPT Image 2 给人的�化,�是�纯从 80 分�� 90 分,而是从“我帮你�便想一张���“我�解你�完�什么任务�。

这就很关键了。

因为设计工作本质上�是�机生�漂亮图,而是围绕目标沟通:给�看�传达什么�用在哪里��牌调性是什么�哪些元素�能��哪些细节必须准确。

GPT Image 2 的��,��是在这些地方。

六�普通人也能拥有“视觉表达能力�

以��会设计的人,想�一张�样的海报,往往需�找模��学软件�调字体�抠图�排版。

现在你�需�说清楚需求:

“帮我�一张适�朋�圈�布的开业海报。�
“帮我把这张产�图改�电商主图风格。�
“帮我生�一张科技感公众���。�

AI 就能给出一个相当完整的�稿。

这�是说设计师���了,而是视觉表达的门槛被大幅�低了。

普通人�一定��为专业设计师,但�以更快地把自己的想法���视化内容。对于个体创作者��团队�独立�牌�说,这��化�常现实。

七�设计师会被�代�?

我的判断是:低端����模�化的设计需求会被大�替代。

但真正优秀的设计师�会消失,�而会更强。

因为 AI 能快速生�方案,但它�然需�人�判断:

哪个方�更符��牌?
哪个画�更有传播力?
哪里需�克制?
哪里需�强化?
哪些细节�符�商业规范?

未�的设计师,�能���是“执行工具的人�,而会更�视觉导演�创�策划和审美决策者。

会用 AI 的设计师,会比�会用 AI 的设计师快很多。

八�时代真的�了

GPT Image 2 最让我震撼的,�是�一张图有多惊艳,而是它让我看到了一�趋势:

AI 图�生�正在从“�感玩具���“视觉�作系统�。

以�我们打开设计软件,是自己一点点�作。

这背�其实是创作方�的�化。

过去,表达一个视觉想法,需�掌�软件。

软件能力正在�得�那么稀缺,审美�判断�表达和创�策略�得更��。

结语

GPT Image 2 �是简�的“�一个更强的生图模型�。

它代表的是 AI 图�工具的一次转�:从炫技,到实用;从�机惊艳,到�控产出;从�张美图,到真实工作�。

如果说过去的 AI 生图�是一个�感盲盒,那么 GPT Image 2 更�是一个能�懂需求�能�续修改�能�与实际创作�程的视觉助手。

所以这一次,我真的觉得:

时代�了。

�是因为 AI 会画图了。

彩蛋1

生�图预览,多图预警�

20260422100655_38824_317

20260422104152_38860_317

20260424111433_18677_288

20260424111455_18787_288

20260424142319_383_164

彩蛋2

分享一些�示�,欢迎大家评论区分享�

798584beded894328183ae146264a2f750447904

一张充满新春喜庆氛围但�失高雅格调的 2026 �州城市宣传海报。
采用���光手法,整体构图延续 S 型的�动感;在纯白的纹�背景�下角,一个身穿中国传统�饰的微缩人物正在挥舞一�长长的红色�绸舞带,红绸在空中轻盈舞动,展现出�绸柔顺细腻的质感,并在�左上方飘动的过程中,奇幻地�形�一�壮丽的山水河�。

在这�“河��之中,�加出一幅有山�有湖�有江�有城的�州城市手绘图,整体风格�国潮,景色尽收眼底,壮阔而秀雅,令人震撼。
画�中�入�州地标建筑与景观:西湖�断桥�雷峰塔�三潭�月�六和塔�钱塘江�京�大�河�州段���寺�城��。
云雾环绕,仙气缥缈,兼具江�诗�与大城气象;色彩丰富,结构��,细节�盛,但由于大�积留白,画��然显得清新脱俗�雅致高级。

左下角排版� “SPRING 2026�,并��竖排宣传语,整体寓�:“人间天堂,数字之城��“诗画江�,活力�州�。
文字排版优美大方,字迹清晰完整,整体视觉兼具新春节庆感�东方美学�城市文化底蕴与现代都会气质。
海报尺寸 9:16,高清,细节丰富,适�城市文旅宣传。

原��:https://x.com/liyue_ai/status/2045332620352119274

475a51997e446ca54e918e197e3330c6ff9aebfe

蜜雪冰城雪王�装KFC员工,戴红色围裙,手举炸鸡桶,
夸张表情,大喊“V我50�,
疯狂星期四主题,�笑 meme 风,
夸张字体,贴纸元素,弹幕风格,
强对比红白�色,动感构图,
社交媒体爆款视觉,抖音风海报,
高清,强光,高�度,商业广告质感,2比3比例

��:LINUX DO

6f548a95cff69818c326b67ce943029fbb18d65d_2_562x1000

9:16 vertical — a 3x3 grid collage (nine images) forming a Korean idol portrait photoshoot series. Each frame features the same young Korean female idol, maintaining 100% consistency in facial features, hairstyle, and styling across all nine images. Each photo showcases a different pose, expression, and subtle outfit variation (same white oversized button-up shirt, variations in how it’s worn). Natural window light, soft and airy aesthetic, minimal clean indoor background, authentic film-like color grading with gentle pastel tones, editorial photography style. The collage should look like a professional photoshoot contact sheet or Instagram carousel layout. Soft focus, slight grain, warm highlights, gentle shadows. Extremely consistent identity across all frames while showing range in posing and mood.

��:LINUX DO

c2a7b688f7915a513eeda7316d48de6a213cef92_2_706x1000

以真实世界为�照,绘制一幅高�质日�现代ACGN轻�说�画,精致动漫艺术风格,干净利�的线�,鲜艳柔和的光影。分割构图,超现实的倒置�射概念。上部分是倒置的香港维多利亚港夜景,颠倒的霓虹倒影。下部分是正立的广州�江新城夜景(广州塔��江新城�猎德大桥),散�冷�紫色城市�光。两个城市在中部的�光“夜空�地平线处完美衔接,形�无�的梦幻连接。星空背景,新海诚�调色。

��:LINUX DO

60c264af766eb192beabecaf1414b4e6bc5ad444_2_1380x920

请生�一张�xxx】的王者�耀游�的英雄动画展示页截图

03b5571b4bf2855035b1f44123dfefd9434be54c

A surreal yet photorealistic ultra-telephoto geographic photograph with extreme spatial compression, vertical composition, stacked world landmarks aligned along a single line of sight from bottom to top. At the bottom: Shanghai skyline with Shanghai Tower, Shanghai World Financial Center, and Oriental Pearl Tower. In the middle foreground: layered hills, temples, and atmospheric mountain ranges. In the center: the Potala Palace on a mountain ridge, majestic and sharply detailed. Above it: the Taj Mahal with white dome and minarets. Higher above: the Great Pyramid of Khufu in a dry desert landscape. At the very top: the Statue of Liberty near a bay with a distant city skyline. Warm sunrise or sunset light, cinematic haze, atmospheric perspective, natural colors, documentary realism, national geographic style, ultra detailed architecture, realistic terrain transitions, compressed depth, 800mm–1200mm telephoto lens look, no collage seams, no fantasy floating objects, no illustration, no text, no watermark.

��:LINUX DO

e48a93e6e2e0848335befebecf41dd761dd05842

根�凡人修仙传自动生�一张收�版�诗�事海报:巨大的韩立侧脸剪影作为外轮廓,剪影内部自动生长出最契�该主题的完整世界观�标志性场景�角色关系�象�符��关键建筑�生物��具与氛围。整体�是普通拼贴,而是高级的剪影轮廓填充��事��,带有���光��想,但更�电影海报与梦幻水彩�画��风格;柔和空气�视,轻雾化过渡,纸张颗粒,边缘飞白与刷痕,大�积留白,版�克制高级,安���大�神圣�怀旧�诗��传说感,修仙仙侠。风格�色彩�场景��质全部根�主题自动适�,所有元素必须强绑定主题,一眼识别,���乱,��硬拼贴,��模�化背景,��廉价奇幻素�。

��:LINUX DO

b9402e711403c8b159efba03c17330208f34d54b

一张秦始皇国风游�人物宣传海报,统一采用竖版主视觉构图。�张海报都使用上大下�的层级结构:画�上�部分以人物最具辨识度的头部��部轮廓��具或�身外轮廓作为巨大的视觉主体,形�强识别的剪影�主形;中下部安排完整人物作为第二主体,稳定站姿或轻动作姿�,构�画�的视觉核心。大轮廓内部以�角色周围采用���光与拼贴��事构图,将若干场景��象��型人物关系�辅助元素和环境层层��在云雾�水墨和留白之中。左�侧设置呼应性辅景,使画�产生故事张力与空间�化。以一�贯穿画�上下的�动线索连接主角色�内部拼贴和上方大轮廓,增强整体性和视线引导。整体画���大�积留白,边缘采用水墨晕染和虚化破碎处�,形�东方美学中的虚实关系和呼�感。整体风格统一�高级�克制,强调层次感��事感�主视觉冲击力和系列化海报语言

��:LINUX DO

彩蛋3

这篇文章内容和��图全部由Open AI 刚�布的 GPT-5.5 生��布~ 我仅�供大纲�部分对�截图。

使用 Trusted Publishing 提升 npm 包发布安全性

作者 沈唁
2026年4月21日 12:52

在现代前端生态中,npm 包发布流程的安全性越来越重要。

传统的发布方式通常依赖长期有效的 npm token,一旦泄露,攻击者就可以直接发布恶意版本,带来严重的供应链风险。为了解决这一问题,npm 在 2025 年 7 月份推出了 Trusted Publishing(可信发布) 机制。

什么是 Trusted Publishing?

Trusted Publishing 是 npm 已正式推出基于 OpenID Connect (OIDC) 的可信发布功能。该功能允许使用 OpenID Connect (OIDC) 进行身份验证,直接从 CI/CD 工作流安全地发布 npm 包,从而减少管理长期令牌的需求。

借助可信发布,现在可以

  • 无长期 token:不需要在仓库中保存 npm token
  • 消除令牌安全风险:无需在 CI/CD 环境中存储、轮换或意外暴露 npm token。
  • 短期凭证:每次发布时动态签发,自动过期
  • 绑定 CI 身份,建立加密信任:发布权限与 GitHub 仓库/工作流强绑定,每次发布都使用短期、特定于工作流的凭据进行身份验证,这些凭据无法被泄露或重复使用。
  • 降低泄露风险:即使 CI 配置泄露,也难以滥用
  • 自动获取来源证明:使用可信发布时,npm CLI 默认发布来源证明。--provenance不再需要该标志。

传统发布方式的问题

在 Trusted Publishing 出现之前,常见流程如下:

  1. 在 npm 上生成一个 Access Token
  2. 将 token 存入 GitHub Secrets(如 NPM_TOKEN)
  3. 在 CI 中执行 npm publish 进行发布

问题在于 token 通常是长期有效,一旦泄露,攻击者可以进行发布恶意版本等操作。

现在 npm 限制生成 token 最长有效期为 90 天,还使用这种方式会经常需要轮换 token。

Trusted Publishing 的工作原理

Trusted Publishing 会在 npm 和你的 CI/CD 提供商之间建立信任关系

当你为你的包配置可信发布者后,npm 将只接受来自你已授权的特定工作流的发布。

Trusted Publishing 基于以下流程:

  1. GitHub Actions 在运行时向 npm 发起身份请求(OIDC)
  2. npm 验证该请求是否来自可信仓库
  3. 如果匹配配置,签发一个短期访问令牌
  4. CI 使用该令牌执行 npm publish

整个过程:

  • 无需手动管理 token
  • 每次发布都是一次“临时授权”

设置 Trusted Publishing

我也是在发布 docsify-footnotes时发现 token 不可用了,此处以它为例:

1. npm 侧配置

进入 npm 包的 Settings页面,就可以看到Trusted Publisher,并且需要选择publisher,支持GitHub ActionsGitLab CI/CDCircleCI

我的仓库在 GitHub,所以选择GitHub Actions,需要配置Organization or userRepositoryWorkflow filename,这三个都是必填项。

GitHub 用户名或组织名称 Organization or usersy-records
仓库名称 Repositorydocsify-footnotes
工作流文件名 Workflow filenamepublish.yml

点击Set up connection保存即可

2. GitHub Actions 配置

保存之后需要修改对应的 action yml 文件,需要将所需的 OIDC 权限添加到你的工作流中:

permissions:
  id-token: write  # Required for OIDC
  contents: read

关键要求是id-token: write需要获得相应的权限,才能让 GitHub Actions 生成 OIDC 令牌,这是一个完整例子:

name: Publish Package

on:
  push:
    tags:
      - 'v*'

permissions:
  id-token: write  # Required for OIDC
  contents: read

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6
        with:
          node-version: '24'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test
      - run: npm publish

因为我的几个 npm 仓库都采用的 复用 actions,所以只需要修改加上permissions和移除写入 npm token 就可以使用了,见 commit

发布成功后的邮件通知也会增加说明 GitHub Actions 的信息。

Hi sy-records!

A new version of the package @sy-records/docsify-footnotes (2.3.0) was published at 2026-04-21T02:48:22.069Z from GitHub Actions: https://github.com/sy-records/docsify-footnotes/actions/runs/24701393194/attempts/1 (triggered via a "push" event on git ref "refs/tags/v2.3.0").
The shasum of this package is 8136f65cb7d651d4b3671290b7c16da4cac71b24.

If you have questions or security concerns, you can contact us at https://www.npmjs.com/support.

Thanks,

The npm team.

需要注意的是 Trusted Publishing 需要 npm CLI 版本 11.5.1 或更高版本以及 Node 版本 22.14.0 或更高版本。

Trusted Publishing 是 npm 在供应链安全方向的重要升级,建议所有开源项目逐步迁移。

百度网盘�费领�500G空间容�,速上车�

作者 游魂
2026年4月14日 09:23

还在为存储空间�够用���?�费获�百度网盘500G空间,手慢无�

部分接�接了个新盘�——嘟嘟盘。还�知�是啥的兄弟,去“百度�家看一眼就明白了。刷新一下接�,清个缓存,入�就会冒出�。

�作逻辑跟之�那三个盘完全一样,从�我的云盘】点进去,你存在自己百度盘里的自��学习课件�����,全都能直接在线播放,�畅��壳。

现在兄弟们还能白嫖��速的体验,唯一的�短�就是盘�本身容��紧。

�点�了——没注册过百度网盘的新�,默认�给5G容�,肯定�够折腾。下�教大伙一个扩容500G的野路�,步骤照�撸就行。已�在用的��一样能领,��新�,�者有份。

教程

第一步,长按识别下方二维�,先把那个写��领�500G】的文件转存到你自己盘里。

baiduwangpan500g

(�是手机上还没装过百度网盘APP的兄弟,先扫�,按页�引导装好应用并登录注册,�去存那个文件。)

万一二维�扫�出�的�哥,�制下�这行地�到�览器一样能进:

https://pan.baidu.com/s/11LRc4vrCqJ8uNSSWfPRx2A?pwd=8888

第二步,把下�这串加粗暗�整��制下�,然�打开百度网盘手机客户端,自动弹窗就能领。

#AgufUICNjb#游魂网#

这500G空间有效期30天,到期�按上��程�走一�,立马续上500G,无�续��是梦。嫌麻烦的土豪�哥�以直接开个SVIP一步到�。

行了,�啰嗦了,赶紧上车开整。

让AI�进网页里:Page Agent 纯�端自动化�探

作者 游魂
2026年3月31日 14:54

最近�现阿里云开�的 Page Agent 挺有��,跟大家分享一下我的使用感�。

PageAgent简介

PageAgent 是一款由阿里巴巴开�的�基于 JavaScript 的 GUI 智能体(GUI Agent)。它最大的亮点在于无需�赖�览器�件�Python 环境或无头�览器,仅通过在页�中注入 JavaScript ���行。

它�许用户通过自然语言控制网页界�,将��的�作�程转化为简�的指令,�常适�用于 SaaS 产�的 AI 助手集�或个人网页自动化任务。

开�仓库:https://github.com/alibaba/page-agent

image-20260331142620208

核心特性概览

特性维度 �述
技术架构 纯�端 JavaScript 实现,基于 LLM(大语言模型)驱动。
集�方� 支� CDN 直接引入�NPM 包安装,也支�独立的 Chrome �件。
核心原� 基于文本的 DOM �作,无需截图或多模� LLM,直接解�页�元素。
适用场景 智能表�填写�SaaS 产� Copilot�网页无障�访问等。

两�接入与使用方�

网站所有者:嵌入� AI 助手

如果你是网站开�者,希望为你的用户�供“AI �控�能力,�需在网页��中引入一行 JS 代���。

实现原�:

快速接入代�:

<script src="https://registry.npmmirror.com/page-agent/1.6.3/files/dist/iife/page-agent.demo.js"></script>

效果: 网站上会出现一个�天框,用户�以通过文字沟通�自动化处�一些简�任务,无需�端�写。

体验地�: https://cooking.youhun.wang/

网站接入

执行任务

个人用户:�览器�件扩展

如果你�是网站所有者,但希望在日常�览中使用自动化功能(如在�自家的网站上执行��任务),�以使用其�供的 Chrome 扩展程�。

使用方法:

  1. 安装官方�供的 Chrome 扩展:https://alibaba.github.io/page-agent/docs/features/chrome-extension/。
  2. 扩展会注入 Agent 脚本到当�页�。
  3. 用户�以通过扩展����指令,控制当�标签页。

适用场景: 适�完�跨页�任务或对第三方网站进行�微��的自动化�作。

�览器�件扩展

实际体验:有亮点也有槽点

在实际体验中,PageAgent 的表现符�预期,但也存在一定的局�性:

优点:

  • è½»é‡�级: 无需å¤�æ�‚的环境é…�置,纯 JS è¿�行,加载速度快。
  • 低æˆ�本: 相比于 Puppeteer 或 Selenium,它直接在页é�¢ä¸Šä¸‹æ–‡ä¸­è¿�行,资æº�消耗更低。
  • 易上手: å¼€å�‘者集æˆ�é�žå¸¸ç®€å�•,几行代ç �å�³å�¯æ‹¥æœ‰ AI Copilot 能力。

局�性(体验�馈):

  • DOM ä¾�赖性强: 它的识别逻辑完全ä¾�赖于 DOM 模型。如果网页元素缺ä¹�语义化标签(如没有 aria-label 或文本内容),Agent 往往会“视而ä¸�è§�â€�,导致无法点击或输入。
  • 简å�•任务为主: ç›®å‰�更适å�ˆå¤„ç�†é€»è¾‘简å�•的线性任务(如填写表å�•ã€�点击导航)。对于逻辑æž�å…¶å¤�æ�‚或动æ€�加载æž�å¿«çš„ SPA 应用,å�¯èƒ½ä¼šå‡ºçŽ°è¯†åˆ«æ»žå�Žæˆ–找ä¸�到元素的情况。
  • 体验一般: 在一些é�žæ ‡å‡†å¸ƒå±€çš„网站上,交互体验å�¯èƒ½ä¸�如原生æ�’ä»¶æµ�畅。

总结与建议

Page Agent 是一个挺有想法的项目,把 AI Agent 从“外部�控�览器���了“内部嵌入网页�,架构轻��接入�本低。但目�在实际使用中,DOM 识别的准确率还有��空间,��任务容易翻车。

�过�说回�,这�纯�端实现 GUI Agent 的�路确实值得学习。如果你对 AI 自动化或者�览器扩展开�感兴趣,去 GitHub 上看看��应该能有�少收获。

��机速看�高德车机版2026「养�级�终�版,稳得一批�

作者 游魂
2026年3月23日 09:36

车�们,高德车机版 2026 年度力作——9.1.87 稳定版 �了�这次版本主打一个 “稳�与“�心� ,堪称闭眼入的 养�级 导航。�仅视觉效果大幅进化,实用性也拉满,让你的车机导航体验全��维�

多�牌车机都能适�

核心亮点,一眼��

  • 红绿ç�¯â€œæ�¢è£…â€�大å�˜æ ·ï¼š 界é�¢ç¾Žå­¦å…¨é�¢å�‡çº§ï¼�æ��ä¾› 3 ç§�个性化背景(ç»�典默认ã€�日照金山ã€�白云山峦)和 2 ç§�字体样å¼�(默认舒适ã€�LEDæ•°ç �风),æ�­é…� 2 ç§�布局,沉浸å¼�导航看ç�€å°±æ˜¯ä¸€ç§�享å�—。
  • 显示éš�心调,拒ç»�é�®æŒ¡ï¼š 针对ä¸�å�Œå°ºå¯¸çš„车机å±�幕,新增 4 æ¡£ DPI 调节(新手选 180 DPI 最稳妥),还有 3 æ¡£ç�¯ä½“大å°�,轻æ�¾æ‰¾åˆ°æœ€èˆ’æœ�ã€�最ä¸�挡视线的显示效果。
  • 实用主义至上: 播报精简,专注于路线引导,让你å�ªå�¬è¯¥å�¬çš„,开车ä¸�分心。

核心亮点速览

安装必读(��机必看)

  • 针对è€�旧车机: 如果你的车机系统较è€�或签å��å�—é™�(特别是安å�“9/13/15系统),建议优先下载 “é”�14兼容包â€�,能显著æ��高安装æˆ�功率ï¼�
  • 比亚迪车主请注æ„�: 安装失败怎么办?ä¸�用慌,多试几个版本。文件å��带 “共存版â€� 的包,是专门为无法覆盖安装的è€�车机准备的,é�žå¸¸é€‚å�ˆå°�鲜。
  • DPI 调节å°�技巧: 列表里没找到对应选项?果断选 180 DPI,这是最通用的ä¿�底选择。竖å±�车å�‹å�¯ä»¥ç•™æ„�找 “主竖横竖包â€� 版本,体验更佳。
  • 功能预告: 本次版本暂未加入车é�“级导航,别急,这个é‡�磅功能预计会在å�Žç»­çš„大版本中回归,敬请期待ï¼�

版本��万,适�自己车机的�是最好的。花点时间多试几个包,找到你的专属 黄金组� ,就能享�这份长久的稳定与舒适。

下载地�

链接:https://pan.quark.cn/s/a6c2e947f35d?pwd=hDnn

抓紧时间上车,开�你的养�级导航之旅�

又是一年清明,不对,又是一年五一。

作者 Mosaic-C
2026年4月24日 11:57

五一节前也是雨纷纷,绿色正是春意盎然的景象。

A 的节前效一如既往,两年提振,费半已站上万点。

最近流传和光同尘,敢问,何处是光,何处是尘?

DS 发布 V4,无法蒸馏后的国产 AI ,应与 A 上万点一般,总归会有一点特色。

看着窗边躲雨的小鸟,会明白,可远观而不可亵玩。

哪吒汽车被央视点名后,谁才是真正的车圈恒大?

2026年4月24日 08:52
一辆停在空旷厂房前的新能源车,车身蒙着灰,远处高大的厂房大门半掩,地面散落文件与警示锥,天空阴沉,呈现产业寒冬降临的压迫感,羊皮纸,钢笔彩色手绘的统一风格。

焦点访谈炮轰哪吒汽车,新能源产业正在进入“大逃杀”状态。

2026年4月21日,央视《焦点访谈》播出了《招商还是招伤》,这个“伤”是伤口的伤,直接把哪吒汽车母公司合众新能源摆到了台面上。

节目的要点非常狠:2021年至2023年,合众新能源累计亏损183亿元,平均每卖一辆车亏损超过8万元。江西宜春经开区、广西南宁产投等地方国资,真金白银地通过土地、房产、租金减免、销量奖励等方式一层层往里垫钱,最后企业停产、重整,国资很难退出,钱也回不来了。

这意味着,哪吒汽车已经不只是一个新势力品牌做失败了,而是被央视定性成了地方招商内卷、国资深度兜底、产业泡沫反噬的典型样本。真正可怕的不是哪吒倒了,而是它可能是第一个被公开“晒尸体”的。

为什么大家会把哪吒往“车圈恒大”的方向联想?

电视演播室的屏幕上播着汽车企业新闻,前景几位观众围坐讨论,桌上摊着报纸与写有“车圈恒大”的醒目标题卡片,画面像一场舆论风暴刚刚掀起,羊皮纸,钢笔彩色手绘的统一风格。

因为前面比亚迪连续烧了几个仓库以后,大家又想起魏建军讲的“车圈恒大”的故事。说了一年多了,到底是谁一直没搞清楚,那总得有一个出来顶缸的。

哪吒汽车在央视节目里并没有被直接点名成“车圈恒大”,但这个时间点又很敏感。恒大的许家印,也就是俗称的“皮带哥”,最近刚刚出庭,而且直接认罪认罚了,大家自然就又联想到了“车圈恒大”,于是想找一个脑袋合适的出来晒一晒。

哪吒汽车的问题核心:长期巨额亏损

财务报表、下降的折线图、堆叠的亏损数字和一辆低价电动车并置在桌面上,算盘与红色亏损印章形成强烈对比,突出“卖得越多亏得越多”的困局,羊皮纸,钢笔彩色手绘的统一风格。

哪吒汽车爆出来的数据,核心就是长期巨额亏损。三年亏了183亿元,其实在造车行业里不算最多,但问题在于它是低价冲量,卖得越多亏得越多。

  • 2021年毛利率为 -34.4%
  • 2022年毛利率为 -22.5%
  • 2023年毛利率为 -14.9%

一个车厂亏钱很正常,因为有研发成本、推广成本和各种其他费用。但毛利率为负,意味着连车本身的售价和成本价之间的差额都是负的,这就很夸张了。

而且,其他企业亏钱,亏的是股东的钱、民营资本的钱,大家还可以接受;但这一次,亏的是地方政府平台的钱。现在大家都在算账,都在盯着地方债,你把政府的钱亏了,这事就很严重了。

在中国一直有个潜规则:你自己把钱亏了没事,把其他民营企业的钱亏了也未必有事,但国有资产流失这件事不能碰。

国资进入之后,破产就不再只是市场行为

地方政府办公楼与汽车工厂通过一条长长的资金管道相连,管道上标着土地、厂房、补贴、股权投资,尽头却是停摆的生产线和锁住的大门,羊皮纸,钢笔彩色手绘的统一风格。

还记得罗永浩吗?为什么最后说要“表演甄嬛传”?因为他最后借了国资的钱,你必须得把那笔钱还上,是不允许轻易申请破产的。

按道理说,有限责任公司最后破产,把注册资本赔完也就结束了,但在国内没有那么容易。这一次哪吒汽车的事情也告诉大家,破产清算对于拿了国资的有限责任公司来说,逃不过去,不可能把国资直接浪费掉就算了。

多地政府平台深度介入,地方给了土地、给了厂房、给了补贴,还做了股权投资,全部押进去了,到最后什么都没剩下。上市失败以后,融资断裂。2024年5月至6月,企业紧急融资44.37亿元,也没能挽救局面。

最后还是借了一笔钱,因为大家觉得也许还能救一下,结果这笔钱也没了。停产、讨债、重整,创始人与前任首席执行官都被列为失信人员,直接成了被执行人。

个人连带责任为什么会成为最后一击?

因为他们在最后借这笔钱的时候,都签了个人连带责任协议。只要你签了个人连带责任协议,就不能再受有限责任公司的保护了。

到最后这笔钱大家都知道有问题,你还一定要去借,那肯定得摁着你签个人连带。罗永浩最后那笔也是签了个人连带,这个事没办法,特别是国资很喜欢压着人签这个东西。

哪吒汽车是怎么一步步走到今天的?

一条时间长廊里陈列着哪吒汽车不同阶段的海报与车型,从销量冠军的明亮展台一路过渡到空荡展厅和销量断崖式下跌的曲线墙,形成由盛转衰的叙事,羊皮纸,钢笔彩色手绘的统一风格。

曾经有一段时间,哪吒汽车的销量是中国新势力第一。哪吒汽车的母公司叫合众新能源,2014年成立,创始人叫方运舟,后来张勇加入,长期负责经营操盘。

哪吒最辉煌的时候,靠的是低价走量,直接杀出来了。2022年哪吒汽车销量达到15.21万辆,是全国第八大新能源制造商,在新势力里排第一,一度拿到了当年造车新势力销量冠军。

它的主力车型不是高端豪华,也不是技术制高点,而是更偏下沉市场的性价比路线。之后销量急剧下滑。2024年全年只卖了87,948辆,其中还包含出口的23,399辆;2025年一季度只卖了1,215辆,后面基本就没有了。

哪吒曾经依靠什么支撑?

哪吒从来不是靠强盈利能力撑起来的,而是靠低价冲量、外部融资、输血、地方资源扶持、资本市场讲故事这些东西撑起来的。

从融资端来看,哪吒自2017年以来完成了10轮融资,累计约228.44亿元。其中:

  • C轮融资:20亿元
  • D1轮融资:35.22亿元
  • D2轮融资:27.90亿元
  • D3轮融资:18.87亿元

之所以会出现D1、D2、D3这样的轮次,是因为融资轮次继续往后排,意味着估值得有巨大提升;如果估值涨不上去,又还在同一个轮次里,就会出现这种后缀数字。

这类融资金额看起来很大,但说明一个问题:估值涨不上去了,增长性已经没了。后面还做了一轮9.4亿元的可转债。所谓可转债,就是现在把钱借给你,等上市以后转成股份,再去二级市场卖股票。

财务数据如何恶化?

从财务端看,哪吒三年累计净亏损183.73亿元。

  • 2021年亏损48.4亿元
  • 2022年亏损66.66亿元
  • 2023年亏损68.67亿元

毛利率持续为负,卖一辆亏一辆。它最风光的时候,看起来像“人民的新势力”,因为便宜;但回头看,更像是把所有能够提前透支的东西一把都透支干净了。

“五亿换标”与管理层言论,进一步伤害市场信心

一间品牌会议室里,桌上摆着多版车标方案、宣传海报、预算表和被夸张圈出的“5亿”字样,墙上的员工神情复杂,映出营销与现实脱节的荒诞感,羊皮纸,钢笔彩色手绘的统一风格。

哪吒最被嘲笑的一件事,是“五亿换标”。当时的CEO张勇说,更换车标花了5亿,于是大家都觉得太离谱。

后来张勇澄清,他们这个标的设计费用不超过100万,所谓的5亿实际上是过去7年里的品牌宣传、营销传播、市场推广上的综合投入,被外界简化成了“五亿换标”的故事。

换标本身确实是有成本的,设计成本如果找名家设计,几十万上百万都不算贵。真正花钱的是门店装修改造、广告物料重做、媒体广告投放、宣传体系更新,这些确实贵。但即便如此,到5亿这个程度也还是有些夸张。

更关键的是,这件事暴露出新能源车企的钱都花在哪儿了——宣传和营销,是极度烧钱的一件事。

大家之所以反感,是因为你这个车本来就便宜,没有技术壁垒,品牌没有高溢价,财务上也没有自我造血能力,越卖越亏,在这么敏感的时候还出去吹牛说换个标花了5亿,最后还得回来解释说100万是做标的钱,剩下的是各种市场费用,这就显得很拎不清轻重。

张勇的几次公开发言为何引发争议?

除此之外,张勇还有几次公开发言也很伤士气。

2024年2月,在奖金延迟发放的时候,他说少部分员工“不习惯过苦日子”,要“把寒气传递给每一个人”。在企业已经承压的阶段,这种话极其伤士气,外面的人也会觉得你太不知人间疾苦。

2024年6月,公司危机已经显现,张勇又公开说哪吒不会改名。注意,创始人不是张勇,张勇是后来请回来的CEO,在公司里股份不到1%,真正的大股东是方运舟。

张勇坚持用“哪吒”这个牌子,而创始人则希望用自己的名字。现在很多新能源品牌,比如理想、小鹏,都是创始人名字。方运舟也希望这么做,但张勇进来以后说不能用自己的名字,太low了,要用“哪吒”,还要重新诠释品牌内涵。

当时大家就觉得你压根没抓住重点:车质量不好、价格便宜、没有什么科技创新,还有很多其他问题,这时候还在做品牌诠释,显得很离谱。

到2024年12月,多方开始传出张勇不再担任CEO的消息,哪吒方面起初还否认,遮遮掩掩过了一段时间后,最终承认张勇不再担任CEO,由方运舟兼任。可以理解为创始人说“还是我自己来吧”。

但最后成为被执行人、成为“老赖”的,两个人谁都没跑掉,因为在最后借钱并承担无限连带责任的时候,这俩人肯定都签了字。

真正判哪吒“死刑”的,不是亏损,而是上市失败

港交所风格的大楼前,一份招股书草案在风中翻页,台阶上站着西装投资人与企业高管,远处股价屏幕黯淡,象征IPO冲线失败前的紧张瞬间,羊皮纸,钢笔彩色手绘的统一风格。

那么,真正把哪吒干死的是什么?是车造得差吗?是赔钱卖车吗?这些当然都有影响,但真正判它死刑的是上市失败

中国很多创业企业,包括这些新能源企业,造车的目的是什么?就是为了上市融资。很多国资愿意给它钱,目的也是为了上市退出。

很多地方给车企的甚至都不完全是现金,而是一块地。为什么?他们不知道这块地不值那么多钱吗?知道。原因很简单,他们知道自己手里是有上市指标的,所以必须合作。

蔚来、理想、小鹏这些都已经是上市公司了,哪吒也想冲一把,说我也该上市了。但有时候真的是天时地利人和,它没赶上天时。

哪吒IPO的关键时间线

哪吒IPO发生在2024年6月26日,合众新能源向港交所递交了招股书草案。中金、摩根士丹利、中信证券、农银国际、招银国际担任联席保荐人。

此时累计融资已经达到228.44亿元,估值目标是424.29亿元,另一个信源报道是458亿,可能存在港币和人民币口径差异。

2024年5月至6月,上市前实在没钱了,又通过可换股债券、股权认购、银行借贷等方式紧急筹了44.37亿元,明显是在为IPO冲线。愿意借钱的人也想得很明白:只要你上去了,我就能卖股票退出。

递表之前,还通过可转换债券向浙江桐乡国资发行了9.4亿元,向广西南宁国资发行了1.2亿元。IPO后,这些国资本来可以按照每股16.15的价格去港股市场退出。

为什么IPO最终失败?


  1. 财务数据无法支撑估值。2024年上半年销售同比暴跌,2022年卖得特别好,2023年也还可以,但2024年卖不动了,全年销量只有8.79万辆,而2022年的高点是15.21万辆。毛利率持续为负,三年亏了183亿,机构根本无法给出424亿元估值的定价依据。

  2. 港股流动性收缩,风险偏好下降。2024年下半年港股市场环境较差,投资人对亏损车企IPO极其谨慎。注册制不代表你说值400亿就能值400亿,前提是必须有足够多的人愿意按这个价格买股票。

  3. 公司内部动荡加剧。递交招股书之后,方运舟公开致歉,张勇被免职等负面消息持续传出,机构投资信心进一步恶化。

  4. 机构认购基础薄弱。虽然保荐人阵容豪华,但没有足够的机构投资人愿意在这个估值和基本面下申购。上市前本来就得把盘子大致定下来,哪吒始终凑不齐愿意买股票的人,因此连聆讯机会都没有。

从递表到失效,全程没有进入聆讯。流程本来应该是递表,6个月内找到认购人,价格谈妥,然后开始路演,再上市。结果到了6个月,招股说明书就过期了。招股书有效期就是6个月,过期就等于上市失败。

上市失败之后发生了什么?

上市失败之后,可转债对应的地方国资退出路径被直接封死。当时找国资借钱,就是告诉人家未来可以按16块多的价格去港股退出,国资其实也乐意,因为有接盘资金。

现在上市失败,国资就直接起诉,要求还钱。可企业肯定还不出来。又过了半年,前面融来的钱也烧光了。于是国有资产直接流失,创始人和CEO被起诉,成了失信被执行人,哪里也去不了。

哪吒当时的逻辑是:只要能上市,就能再融一笔钱;只要资本市场接盘了,就还能继续拖时间。上市以后,还可以继续通过股市融资,比如再发债,用股票做抵押,再拿到一笔钱,腾挪空间就大了。

而且它还想,只要销量还能维持,就还有机会讲下一个故事,甚至继续增发。但一旦上市失败,所有人都会突然反应过来,这家公司不只是暂时遇到困难,而是已经翻不了身了,再也找不到接盘者。

这就是为什么说它“天时不对”。如果它早一年上市,也许真就上去了。蔚来、小鹏也一直亏钱,而且亏得比它多,但人家上市上得早,在市场还比较暖的时候上去了。哪吒只是晚了一点,结果天时没了。

上市失败,让一个长期失血的公司失去了最后一次公开输血的机会,这才是真正的死刑。

哪吒汽车目前的处境:司法重整与资质危机

法院卷宗、封条、停产的总装线和落满灰尘的机械臂同处一室,厂区门口停着无人提走的新能源车,呈现司法重整下的工业废墟感,羊皮纸,钢笔彩色手绘的统一风格。

现在的哪吒汽车已经不是“经营困难”了,而是进入了司法重整阶段。

公开信息显示,2025年6月12日,浙江省嘉兴市中级人民法院裁定受理合众新能源破产重组案件。截止到2025年5月1日,公司账面资金只剩下1,500万,但确认债务达到260亿。账上这1,500万,什么都顶不了。

三大生产线陆续停产或半停产。它有三个生产基地,车卖不掉,肯定没法继续生产。

它手里还有一个比较值钱的资源,就是新能源车生产资质。这个东西通常掌握在各地方政府手里,它为什么把业务分在三个地方,因为三个地方都有资质。但现在国家在收缩新能源车生产,要求集中,如果一张资质连续两年没有造够2,000辆车,这个资质可能就会被没收。

所以很多地方现在都很着急,想救它,前面那些破产倒闭的项目也都想救,核心就是想把资质救活,但这并不容易。

方运舟、张勇被列为失信被执行人,这就是他们现在的状态。

哪吒背后到底坑了多少地方的钱?

中国地图局部上标出江西宜春与广西南宁,两地用红线连到同一座汽车工厂模型,旁边堆着土地证、厂房蓝图和补贴清单,显示多地国资被深度套牢,羊皮纸,钢笔彩色手绘的统一风格。

央视这次最狠的点,不是说你经营失败,也不是说你内卷,而是你坑了国家的钱。

江西宜春经开区

这个项目总投资约50亿,大部分由江西宜春经开区筹集。江西宜春市国资委和财政局所属平台公司,投资了将近20亿元,用于收购股权、土地和房产代建,额外又花了接近3亿,还有10年的租金减免。

完全是赔本赚吆喝,钱都花出去了,什么都没回来。每辆车如果在江西宜春范围内销售,政府还补贴2万。

广西南宁

项目规划年产10万辆纯电动乘用车,广西南宁方面累计以市场化方式投入24亿元,其中广西南宁产投集团给了16亿,此外还有5.5亿元各种项目补助。

车企的钱到底是怎么亏掉的?

一张剖面式场景图把一辆新能源汽车拆解成四个吞金黑洞:负毛利、研发实验室、豪华门店与广告牌、堆积如山的库存和供应链账单,信息密集但层次清楚,羊皮纸,钢笔彩色手绘的统一风格。

你明明看到它一辆一辆车在卖,4S店或者商场门店在开着,有时候一年还能卖十几万辆车,钱怎么就没了?

造车这件事,本质上有四个无底洞。

1. 车本身不赚钱

这就是绝对的无底洞。哪吒最致命的问题就是负毛利。其他车企总体可能亏损,但毛利是正的;你不能纯粹卖一辆亏一辆。

2. 研发成本极高

车的研发周期很长,国外一款车的生命周期经常有十几年,不像国内很多车厂一年出三四款新车。国外就是靠漫长时间和巨大销量把研发成本摊回来。

三电系统、平台架构、智能驾驶、智能座舱、验证测试,都是要烧钱的。再加上新能源车企招了大量互联网公司的人,互联网人的工资比传统车厂高很多,所以这一块非常烧钱。

3. 渠道和营销极度吞金

门店、广告、发布会、人员返佣、交付体系、售后体系,全是巨大支出。前面那个“五亿换标”,钱主要也是花在这里。

以蔚来为例,2025年销售及行政费用是160.9亿,比研发成本还高;小鹏2025年销售及行政费用是94亿,基本和研发费用一样。直销、经销返佣、广告投放、交付体系,都会持续失血。

传统车厂不是这么干的,传统车厂通常是把车卖给经销商就完了,包括比亚迪很多也是走这条路。自己建门店、自己卖车这套,是特斯拉带起来的,新能源车企大多是在学它,这里面的成本非常高。

4. 库存、账期和供应链压力

车不是客户下单你再去造的,一定得先造出来。造车时就得先进货,通常还得借钱进货。买钢材、买电子元器件,都是要花钱的,而且这些钱是有利息的。

造出来以后如果卖不掉,就形成库存,库存也有资金成本。一旦销售不及预期,库存、供应商欠款、金融成本、促销补贴会迅速连锁爆炸。

再叠加地方政府投入了大量非现金资源,比如土地、厂房、政策性减免、销售奖励、平台借债,这些东西本质上也都有成本和利息,都是压在车企身上的大山。

这四座大山压下来,你想不赔钱其实很难。

谁在赚钱,谁还在硬扛?

现在新能源车企里,特斯拉肯定是盈利的,因为它虽然到处建门店,但几乎不怎么打广告,有马斯克一个人的广告效应就够了,而且它是先行者,所以广告投入非常小。

比亚迪能够盈利,新能源阵营里理想能够盈利,赛力斯能够盈利,小米能够盈利,其他很多公司都还在亏损。

所以如果像哪吒汽车这样,一开始车就没造好,后面又实在冲不下去,上市还没成功,就会演变成企业亏空、国资套牢、供应商讨债、员工离场、地方收拾残局,最后被央视点名。

为什么说新能源汽车行业进入“大逃杀”时代?

漫长赛道上密集排列着不同品牌的新能源汽车,前方道路不断收窄,部分车辆抛锚冒烟,少数车全速冲刺,背景是观望的资本与监管身影,呈现残酷淘汰赛氛围,羊皮纸,钢笔彩色手绘的统一风格。

因为央视这次点名的时机非常微妙。许家印刚出来认罪认罚,再往后这些老板再想通过“有限责任公司破产”把自己摘干净,继续做富家翁,就没那么容易了。你可能也得出来认罪认罚。那接下来就只能大逃杀了。

后面一段时间,价格战和各种奇奇怪怪的现象会愈演愈烈。前面已经挂掉的汽车厂,比如高合汽车、极越汽车、威马汽车、拜腾汽车,可能也会被拎出来算旧账。因为这些车厂背后都有大量国资,不管你拿的是地,还是其他资源,最后都可能要秋后算账。

所以价格战会继续打,车厂的补贴会更加疯狂;但同时,资本会更谨慎,海外市场摩擦会更多,政策也在反内卷。未来一段时间,各个车企会给大家表演一场大逃杀的行为艺术。

汽车行业比团购和手机更残酷

汽车行业的大逃杀,比团购和手机残酷得多。中国其实不是第一次干这个事。以前有千团大战,也有众多手机厂商混战,最后都只剩下少数几个。

当年互联网快速发展时,大家还在用摩托罗拉、三星,会觉得中国手机品牌一家独大不太可能。后来中国手机厂商一起冲,现在也就剩下小米、华为、荣耀、OPPO、vivo这几个了,其他基本都死掉了。

现在车企也来了一遍。中国新能源品牌最多的时候大概接近400个,现在还剩40多个。普遍看法是到2030年,大概还能剩十几个,十四五个的样子。还会有一大批车企等着破产。

千团大战最后剩美团一个,手机大战最后剩四五个,400多个汽车品牌大战最后剩十来个,这个过程会非常残酷。

为什么汽车行业会更受伤?

  • 第一,资产太重。
  • 第二,卷入了大量国资。
  • 第三,车和手机不一样,手机造差一点,大不了冒个烟、卡顿、不好使;车是要上路跑的,你把质量做坏了,真的是会出人命的。

所以这一次汽车行业一定会比前两次更受伤。

但中国也有一个特点:千团大战最后活下来的美团,战斗力异常顽强;手机大战最后活下来的华为、小米、OPPO、vivo、荣耀,战斗力也都异常顽强。车也是一样,最后通过这种养蛊方式留下来的,绝对都是狠角色。

哪吒到底是不是“车圈恒大”?

可以明确地说,绝对不是,“车圈恒大”一定是剑指他人。

为什么这么说?

首先,“车圈恒大”这个说法是魏建军在2025年5月接受采访时说出来的,他没有点名任何具体车企。这个事情被路透社和很多媒体报道,说车圈里有恒大。

如果一个企业对长城汽车没有影响,没有竞争压力,魏建军理它干嘛?他一定是在说一个对长城汽车有影响的竞争对手。所以这绝不可能是哪吒。哪吒太小了,和长城汽车比起来不在一个量级。

第二,哪吒2024年6月冲上市,2024年12月张勇就被罢免CEO了,公司基本已经停摆。到2025年5月魏建军出来喊“车圈恒大”的时候,如果说的是哪吒,早就点名了。之所以还不敢点名,说明这个企业绝对不是哪吒。

当时魏建军讲的是:有企业在财务上已经很危险,有些销量和繁荣是靠扭曲机制推出来的,有些风险不是企业自己承担,而是在往供应链、地方政府和社会层面转移。哪吒在那时已经爆雷、已经挂了,所以不是在讲它。那到底是谁,还可以继续拭目以待。

从汽车到大模型,这套路径是否还会重演?

最后,汽车已经这样了,希望下一个行业别再按这个打法继续追赶了,别再沿着这条路走。但这又很难避免。

前面是互联网,后面是手机,现在是汽车,基本接近尾声,最后几家还会继续表演大逃杀,毕竟谁也不想进去认罪认罚。

现在最新的是什么?是大模型行业。这个行业里,我们依然在卷,依然在玩“一将功成万骨枯”的叙事。目前看起来,好像也快卷出结果来了。

一旦中国卷出结果,在全球范围内通常还是很有杀伤力的,往往能大杀四方。所以大模型这块,基本上又在照着这条路走一遍。

我现在最不希望看到的“百机百车大战”式行业,是商业航天。现在看起来,好像也有往这个方向前进的趋势。


背景图片

WSL9x —— 在 Windows 9x 里跑 Linux 内核 6.19

2026年4月24日 08:00
最近看到一个很有意思的项目:把 Linux 内核搬进了 Windows 9x。微软的 WSL(Windows Subsystem for Linux)让 Linux 跑在 Windows 10/11 里,已经够让人吃惊了。但开源开发者 Hailey 更进一步——她让 Linux 内核 6.19 跑在了 Windows 9x(95、98、ME)里。项目名叫 [[https://codeberg.org/nicholatian/wsl9x][WSL9x]]。 * 它怎么做到的? WSL9x 的核心思路是用 Linux 的 User Mode Linux(UML)架构——一种让 Linux 内核作为用户态进程运行的设计。Hailey 基于 UML 做了定制(对应 Codeberg 上的 =win9x-um-6.19= 分支),把内核移植到了 Win9x 环境下:补丁后的内核被加载到固定的内存地址( =0xd0000000= ),一个 VxD(Win9x 的虚拟设备驱动)负责把内核从磁盘读进来,然后处理页面错误和系统调用。 比较巧妙的是系统调用的处理方式。Win9x 没有提供 Linux 标准的系统调用中断表支持,所以 WSL9x 没有走常规的 =int 0x80= 路线,而是通过异常处理函数来拦截和转发 Linux 的系统调用。 终端交互靠一个叫 =wsl.com= 的 16 位 DOS 程序,它把 Linux 的终端输出管道传回你运行它的那个 DOS 窗口。对,你在一台跑 Windows 98 的机器上打开 MS-DOS 提示符,输入 =wsl= ,就能看到 Linux 内核的启动输出。 * 不需要虚拟化,i486 就能跑 整个方案不依赖任何硬件虚拟化——没有 VT-x、没有 AMD-V。Hailey 说它理论上能在 i486 处理器上运行。巧合的是,i486 正好是 Linux 内核即将放弃支持的最老架构。这么一看,WSL9x 等于给了一台快要被 Linux 内核抛弃的老机器一个继续跑 Linux 的机会——只不过是在 Windows 9x 里面跑。 项目目前没有提供预编译的二进制文件,想玩的话需要自己从 [[https://codeberg.org/nicholatian/wsl9x][Codeberg 上的源码]] 构建并部署到一台真正的 Windows 9x 系统上。虽然实用性有限,但作为一个技术实验,它的思路和实现都很有意思。

Go 代码设计的“第一天原则”:一份能让你少走五年弯路的实战模式清单

作者 bigwhite
2026年4月24日 07:13

本文永久链接 – https://tonybai.com/2026/04/24/go-code-design-day-one-principle-practical-patterns-list

大家好,我是Tony Bai。

世界读书日送福利活动火热进行中,点击这里留言参与,赢取属于你的幸运!

每一个 Go 开发者,大概都经历过这样的心路历程:

项目启动初期,为了追求“快”,我们怎么方便怎么来。配置到处写,数据库连接随手建,错误日志直接 fmt.Println。我们安慰自己:“先跑起来,以后再重构。”

结果呢?

半年后,项目变成了一座摇摇欲坠的“屎山”。配置散落在几十个文件里,改一个端口号要动十个地方;数据库连接池因为没关,把连接数打满;线上出了 Bug,日志里只有一行孤零零的 record not found,查个问题比登天还难。

技术债,就像滚雪球,你越是假装看不见,它就滚得越大。

这时候,你的内心肯定在呐喊:有没有一些在Go项目刚创建时期就应该知道的Go代码模式,可以让我在项目的“第一天”,就建立起一套健壮、可维护、可观测的骨架呢!

有的!

我将这套方法论,称为 Go 语言架构的“第一天原则”。掌握它,足以让你在Go 代码设计的道路上,少走五年弯路。

这些原则,没有一条是关于炫技的复杂设计模式。

今天,我们就来逐条硬核拆解这些原则,并用可运行的 Go 代码,手把手教你如何将它们落地。

原则一:配置集中解析,依赖显式注入

这是所有“混乱”的根源。如果你的代码里,到处都是 os.Getenv(“DB_HOST”),那你的项目已经走在了通往地狱的路上。

反模式:

在某个业务函数的深处,为了连一下 Redis,临时去读环境变量。这使得你的函数与外部环境强耦合,极难进行单元测试。

第一天原则:

在 main 函数中,一次性完成所有配置的解析和校验,然后通过构造函数,将“配置好”的依赖(如数据库连接池),以“接口”的形式,显式地注入到需要的服务中。

【Go 代码实战】

// https://go.dev/play/p/CrGDShmoFFJ
package main

import (
    "context"
    "database/sql"
    "fmt"
    "log"
    "net/http"
    "os"

    _ "github.com/lib/pq"
)

type Config struct {
    DatabaseURL string
    ListenAddr  string
}

func loadConfig() Config {
    dbURL := os.Getenv("DATABASE_URL")
    if dbURL == "" {
        log.Fatal("DATABASE_URL is not set")
    }
    return Config{
        DatabaseURL: dbURL,
        ListenAddr:  ":8080",
    }
}

type UserRepo interface {
    GetUser(ctx context.Context, id int) (string, error)
}

type PostgresUserRepo struct {
    db *sql.DB
}

func (r *PostgresUserRepo) GetUser(ctx context.Context, id int) (string, error) {
    var name string
    err := r.db.QueryRowContext(ctx, "SELECT name FROM users WHERE id=$1", id).Scan(&name)
    return name, err
}

func NewPostgresUserRepo(db *sql.DB) *PostgresUserRepo {
    return &PostgresUserRepo{db: db}
}

type Server struct {
    repo UserRepo
}

func NewServer(repo UserRepo) *Server {
    return &Server{repo: repo}
}

func (s *Server) HandleGetUser(w http.ResponseWriter, r *http.Request) {
    name, err := s.repo.GetUser(r.Context(), 1)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    fmt.Fprintf(w, "User: %s", name)
}

func main() {
    cfg := loadConfig()

    db, err := sql.Open("postgres", cfg.DatabaseURL)
    if err != nil {
        log.Fatalf("failed to connect to database: %v", err)
    }
    defer db.Close()

    repo := NewPostgresUserRepo(db)
    server := NewServer(repo)

    http.HandleFunc("/user", server.HandleGetUser)
    log.Printf("Server starting on %s", cfg.ListenAddr)
    log.Fatal(http.ListenAndServe(cfg.ListenAddr, nil))
}

这样一来,你的业务代码将变得极其纯粹,不依赖任何全局状态,测试时也可以轻松地 Mock 掉 UserRepo 接口。

原则二:为可观测性而设计:结构化日志与 Metrics

“不就是打个日志吗,fmt.Println 走起!”——这是毁掉一个项目最快的方式。

反模式:

遇到错误,直接 log.Printf(“Error: %v”, err)。当线上出现几万条这样的日志时,你根本无法进行聚合、告警和趋势分析。

第一天原则:

从第一天起,就引入结构化日志(如 log/slog 或 zap)。将所有关键信息(如 user_id, trace_id)作为独立的字段打印。同时,为关键业务指标(如缓存命中率、数据库查询延迟)埋入 Metrics。

【Go 代码实战】

// https://go.dev/play/p/h4_8a4nzCFx
package main

import (
    "log/slog"
    "net/http"
    "os"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    cacheHits = prometheus.NewCounter(prometheus.CounterOpts{
        Name: "myapp_cache_hits_total",
        Help: "Total number of cache hits.",
    })
    dbQueryDuration = prometheus.NewHistogram(prometheus.HistogramOpts{
        Name:    "myapp_db_query_duration_seconds",
        Help:    "Histogram of database query durations.",
        Buckets: prometheus.DefBuckets,
    })
)

func init() {
    prometheus.MustRegister(cacheHits, dbQueryDuration)
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
    logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))

    logger.Info("handling request", "method", r.Method, "path", r.URL.Path, "remote_addr", r.RemoteAddr)

    cacheHits.Inc()

    start := time.Now()
    time.Sleep(100 * time.Millisecond)
    duration := time.Since(start)
    dbQueryDuration.Observe(duration.Seconds())

    logger.Info("request handled successfully", "duration_ms", duration.Milliseconds())
    w.WriteHeader(http.StatusOK)
}

func main() {
    http.HandleFunc("/", handleRequest)
    http.Handle("/metrics", promhttp.Handler())

    log.Println("Server starting on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

有了结构化日志和Metrics的加持,你的系统不再是一个“黑盒”。通过 Grafana 和 VictoriaLogs,你可以清晰地看到它的每一个内部状态,问题定位速度提升 10 倍。

原则三:永不启动一个你不知道如何停止的 Goroutine

这是 Dave Cheney 反复强调的血泪教训。一个失控的 Goroutine,就是一个内存炸弹。

反模式:

go doSomething()。然后呢?它什么时候结束?如果它卡住了怎么办?

第一天原则:

任何一个需要长久运行的 Goroutine,都必须接受一个 context.Context 参数,并在 select 中监听 ctx.Done()。将所有后台 Goroutine 的生命周期,与你的应用程序生命周期绑定。

【Go 代码实战】

// https://go.dev/play/p/Fi1JUZfs4E-
package main

import (
    "context"
    "log"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func worker(ctx context.Context, id int) {
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()

    log.Printf("Worker %d started", id)
    for {
        select {
        case <-ticker.C:
            log.Printf("Worker %d is doing work", id)
        case <-ctx.Done():
            log.Printf("Worker %d is shutting down...", id)
            return
        }
    }
}

func main() {
    ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
    defer cancel()

    go worker(ctx, 1)

    <-ctx.Done()

    log.Println("Main application shutting down.")
    time.Sleep(100 * time.Millisecond)
}

这样,你的应用就可以实现优雅停机(Graceful Shutdown),在 k8s 环境中滚动更新时,不会丢失任何正在处理的数据。

原则四:为可测试性而设计,构建你的“数据靶场”

在复杂的业务系统中,最难测试的不是“Happy Path”,而是各种千奇百怪的“Unhappy Paths”。

第一天原则:

为你的核心业务逻辑,构建独立的“数据生成器(Data Generators)”和“数据接收器(Sinks)”。在测试中,用内存中的模拟实现(Mocks)替换掉真实的外部依赖,从而能 100% 控制输入和验证输出。

【Go 代码实战】

// https://go.dev/play/p/NBsxpVE84Zb
package main

import (
    "context"
    "fmt"
    "sync"
    "testing"
)

type Order struct { ID int }

type OrderNotifier interface {
    Notify(ctx context.Context, order Order) error
}

type OrderProcessor struct {
    notifier OrderNotifier
}

func NewOrderProcessor(notifier OrderNotifier) *OrderProcessor {
    return &OrderProcessor{notifier: notifier}
}

func (p *OrderProcessor) Process(ctx context.Context, order Order) error {
    return p.notifier.Notify(ctx, order)
}

type MockNotifier struct {
    mu        sync.Mutex
    Notified  []Order
    ShouldErr bool
}

func (m *MockNotifier) Notify(ctx context.Context, order Order) error {
    m.mu.Lock()
    defer m.mu.Unlock()
    if m.ShouldErr {
        return fmt.Errorf("mock notifier failed")
    }
    m.Notified = append(m.Notified, order)
    return nil
}

func TestOrderProcessor_Success(t *testing.T) {
    mockNotifier := &MockNotifier{}
    processor := NewOrderProcessor(mockNotifier)
    order := Order{ID: 1}
    err := processor.Process(context.Background(), order)

    if err != nil {
        t.Errorf("expected no error, got %v", err)
    }
    if len(mockNotifier.Notified) != 1 || mockNotifier.Notified[0].ID != 1 {
        t.Errorf("notifier was not called correctly")
    }
}

遵守该原则后,你的单元测试将变得极快、极度稳定,并且能够 100% 覆盖所有你能想到的成功和失败分支。

原则五:防御性编程,构建你的“代码防火墙”

不相信任何外部输入。这是所有安全系统的第一性原理。

第一天原则:

在数据的入口处(如 HTTP Handler、gRPC Server),对所有传入的数据进行严格的、显式的校验(Validation)。只有通过了“安检”的干净数据,才能被允许进入系统的核心领域。

【Go 代码实战(不完全示例)】

package main

import (
    "encoding/json"
    "fmt"
    "net/http"
    "net/mail"
)

type CreateUserRequest struct {
    Username string json:"username"
    Email    string json:"email"
    Age      int    json:"age"
}

func (r *CreateUserRequest) Validate() error {
    if len(r.Username) < 3 || len(r.Username) > 20 {
        return fmt.Errorf("username length must be between 3 and 20")
    }
    if _, err := mail.ParseAddress(r.Email); err != nil {
        return fmt.Errorf("invalid email format: %w", err)
    }
    if r.Age < 18 {
        return fmt.Errorf("user must be at least 18 years old")
    }
    return nil
}

func HandleCreateUser(w http.ResponseWriter, r *http.Request) {
    var req CreateUserRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        http.Error(w, "Invalid request body", http.StatusBadRequest)
        return
    }

    if err := req.Validate(); err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // processValidatedRequest(req) ...
    w.WriteHeader(http.StatusCreated)
}

这种防御可以让你的核心业务逻辑变得极其纯粹和安全,不再需要处理各种脏数据和边界情况。

注:如果是服务器,外部(甚至是内部其他服务的)请求的速度也可能是一种“安全威胁”。因此无论是通过中间件,还是代码自行实现,限速机制是必不可少的。

原则六:错误包裹与类型化错误,让错误自己开口说话

一个好的错误信息,应该像一份精准的“尸检报告”,而不是一句无意义的“他死了”。

第一天原则:

在错误产生的最底层,用 fmt.Errorf(“…: %w”, err) 详细包裹上下文。对于可预期的业务异常,定义成自定义的“类型化错误(Typed Errors)”,让上层逻辑可以通过 errors.As 进行精准的判断和处理。

【Go 代码实战(不完全示例)】

package main

import (
    "errors"
    "fmt"
    "net/http"
)

type ErrDuplicateUser struct { Email string }

func (e *ErrDuplicateUser) Error() string {
    return fmt.Sprintf("user with email %s already exists", e.Email)
}

func RegisterUser(email string) error {
    // 模拟数据库层返回一个已知类型的错误
    if email == "test@example.com" {
        return &ErrDuplicateUser{Email: email}
    }
    return fmt.Errorf("db connection failed: %w", errors.New("timeout"))
}

func HandleRegister(w http.ResponseWriter, r *http.Request) {
    err := RegisterUser("test@example.com")
    if err != nil {
        var dupErr *ErrDuplicateUser
        if errors.As(err, &dupErr) {
            http.Error(w, dupErr.Error(), http.StatusConflict)
        } else {
            // 对于未知的底层错误,只打日志,不暴露给用户
            slog.Error("failed to register user", "error", err)
            http.Error(w, "Internal server error", http.StatusInternalServerError)
        }
        return
    }
    w.WriteHeader(http.StatusCreated)
}

这样处理后,你的错误处理逻辑变得极其清晰和健壮,业务异常可以被优雅地反馈给用户。

原则七:接口定义在消费侧,实现“最小化契约”

这是 Go 语言最精髓、也最反直觉的一条哲学。

第一天原则:

永远不要在“定义侧”声明臃肿的接口。而是在“消费侧”,根据你真正需要的功能,定义一个只包含 1-2 个方法的“小接口”。

【Go 代码实战(不完全示例)】

// --- cache/cache.go ---
package cache
type BigCache struct {}
func (c *BigCache) Get(key string) (string, error) { /* ... */ }
func (c *BigCache) Set(key, val string) error     { /* ... */ }

// --- user/service.go ---
package user
import "fmt"
// 我们在 user 包里,只定义我们真正需要的小接口
type Getter interface {
    Get(key string) (string, error)
}
type UserService struct {
    cache Getter // 依赖的是小接口,而不是具体的 BigCache
}
func (s *UserService) GetUserName(id int) (string, error) {
    return s.cache.Get(fmt.Sprintf("user:%d", id))
}

示例代码中,你的 UserService 彻底与 BigCache 的具体实现解耦。在测试时可以极其轻松地传入 Mock 对象。

小结:架构的本质,是与未来的自己对话

看完上述的七条原则,你是否发现所有这些“第一天原则”都指向了一个共同的核心:可维护性(Maintainability)

你在项目第一天偷的每一个懒,都会在未来的某一个深夜,变成一颗狠狠炸伤你或你同事的“技术地雷”。架构的本质,不是选择一个多么牛逼的框架,而是与未来的自己、未来的同事进行一场清晰、友好的对话。

关掉这篇文章,打开你手头那个最新的项目。看看这 7 条原则,你触犯了哪几条?是时候,给你的代码库做一次“体检”了。


今日互动探讨:

在你过去的 Go 项目中,踩过哪些因为早期“野蛮生长”而导致的设计大坑?除了这 7 条,你还有哪些“压箱底”的项目启动最佳实践?

欢迎在评论区分享你的血泪史与独家心法!


还在为写 Agent 框架频频死循环、上下文爆炸而束手无策?我的新专栏 从0 开始构建 Agent Harness 将带你:

  • 抛弃臃肿框架,回归“驾驭工程 (Harness Engineering)”的第一性原理
  • 用 Go 语言手写 ReAct 循环、并发拦截与上下文压缩引擎等,复刻极简OpenClaw
  • 构建坚不可摧的 Safety Middleware 与飞书人工审批防线
  • 在底层实现 Token 成本审计、链路追踪与自动化跑分评估
  • 从“调包侠”进化为掌控大模型边界的“AI 操作系统架构师”

扫描下方二维码,开启从 0 开始构建Agent Harness 的实战之旅。


原「Gopher部落」已重装升级为「Go & AI 精进营」知识星球,快来加入星球,开启你的技术跃迁之旅吧!

我们致力于打造一个高品质的 Go 语言深度学习AI 应用探索 平台。在这里,你将获得:

  • 体系化 Go 核心进阶内容: 深入「Go原理课」、「Go进阶课」、「Go避坑课」等独家深度专栏,夯实你的 Go 内功。
  • 前沿 Go+AI 实战赋能: 紧跟时代步伐,学习「Go+AI应用实战」、「Agent开发实战课」、「Agentic软件工程课」、「Claude Code开发工作流实战课」、「OpenClaw实战分享」等,掌握 AI 时代新技能。
  • 星主 Tony Bai 亲自答疑: 遇到难题?星主第一时间为你深度解析,扫清学习障碍。
  • 高活跃 Gopher 交流圈: 与众多优秀 Gopher 分享心得、讨论技术,碰撞思想火花。
  • 独家资源与内容首发: 技术文章、课程更新、精选资源,第一时间触达。

衷心希望「Go & AI 精进营」能成为你学习、进步、交流的港湾。让我们在此相聚,享受技术精进的快乐!欢迎你的加入!

img{512x368}


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

© 2026, bigwhite. 版权所有.

昨天 — 2026年4月23日未分类

TIL: 用 diff-hl 在 fringe 中显示 git 变更

2026年4月23日 08:00
读到 James Dyer 的一篇文章[fn:1],介绍了 =diff-hl= 这个包——在 fringe(Emacs 窗口两侧的边栏)中高亮显示当前 buffer 相对于 git 最新提交的变更:新增的行标绿色,修改的行标黄色,删除的行标红色。不用跳出 buffer 就能看到自己改了什么。 * 配置 #+BEGIN_SRC emacs-lisp (use-package diff-hl :ensure t :hook (dired-mode . diff-hl-dired-mode) :config (global-diff-hl-mode 1) (diff-hl-flydiff-mode 1) (unless (display-graphic-p) (diff-hl-margin-mode 1))) #+END_SRC 几个要点: - =global-diff-hl-mode= 开启全局 fringe 高亮,但默认只在 *保存文件后* 更新 - =diff-hl-flydiff-mode= 改为 *边打字边更新* ,不用先保存再看变更——这个几乎是必开的 - =diff-hl-dired-mode= 在 dired 中用颜色标记哪些文件有 git 变更,一眼看出项目状态 - =diff-hl-margin-mode= 是给终端用户(非图形界面)的回退方案——终端没有 fringe,改在行号旁边的 margin 区域显示 * 配合内置 VC 工具 =diff-hl= 的高亮位置跟 Emacs 内置的 VC(Version Control)工具是对齐的。把光标移到某行高亮处,按 =C-x v == ( =vc-diff= ),会直接跳到 diff 中对应的 hunk——不需要先记住改了哪里再去找。 如果开了 =repeat-mode= (之前写过[fn:2]),第一次按 =C-x v ]= 跳到下一个变更后,后续只需按 =]= 就能继续跳,不用重复 =C-x v= 前缀。=]= 和 =[= 之间也能随意切换方向。 [fn:1] https://www.emacs.dyerdwelling.family/emacs/20260421070329-emacs--getting-diff-hl-just-right/ [fn:2] [[file:TIL-repeat-mode省去重复按键前缀.org][TIL: repeat-mode 省去重复按键前缀]]

读:llm-test —— 用 LLM agent 驱动 Emacs 测试

2026年4月23日 08:00
Andrew Hyatt(Emacs 核心贡献者)最近开源了一个实验性项目[fn:1]: =llm-test= 。它的核心想法是——用 LLM 代替人来测试 Emacs 包。你用自然语言描述"用户应该看到什么",LLM agent 会启动一个干净的 Emacs 进程,像人一样操作它(按键、输入文字、执行命令),然后判断测试是否通过。 * 怎么工作 整个流程分四步: 1. 用 YAML 文件写测试描述,就是一段英文说明要测什么、期望什么结果 2. =llm-test= 解析 YAML,为每个测试描述注册一个 ERT 测试 3. 运行测试时,启动一个 =emacs -Q= 的干净 daemon 进程 4. LLM agent 通过 tool calling 驱动这个 Emacs,直到判定通过或失败 #+BEGIN_SRC yaml group: auto-fill mode setup: | Enable auto-fill-mode in a text-mode buffer. Set fill-column to 40. tests: - description: | Type a long paragraph that exceeds fill-column. Verify that the text is automatically wrapped. - description: | Type a numbered list item that exceeds fill-column. Verify that continuation lines are indented properly. #+END_SRC 这个例子测试的是 =auto-fill-mode= :开一个文本 buffer,设置 =fill-column= 为 40,然后让 LLM 输入一段超过 40 列的文字,检查 Emacs 是否自动换行了。测试描述就是自然语言,不需要写一行 Elisp。 * Agent 怎么"看" Emacs LLM agent 看不到图形界面——测试 Emacs 是以 daemon 模式运行的。那它怎么知道 Emacs 当前什么状态? 答案是:每次 agent 执行完一个操作(按键、执行命令、eval 代码等), =llm-test= 会自动附加一份 JSON 格式的 frame 快照。这个快照包含当前所有窗口的可见内容(就像截图,但是文字版)、光标位置、minibuffer 状态和 echo area 消息。 #+BEGIN_SRC json { "selected-window": {"number": 0, "buffer": ""}, "windows": [ { "number": 0, "buffer": "", "mode": "", "point": 1, "lines": ["", ""] } ], "minibuffer": {"active": false, "prompt": "", "input": ""}, "message": "" } #+END_SRC Agent 不需要主动请求"给我看看现在屏幕上有什么"——每次操作后自动收到。这让 agent 的行为更像真人:按了一个键,"看"到结果,决定下一步做什么。 Agent 可以调用的工具包括: - =eval-elisp= :在测试进程中执行任意 Elisp 并返回结果 - =send-keys= :模拟按键(如 =C-x C-f= 、 =M-x= ) - =type-text= :逐字输入文本(保留空格和特殊字符) - =run-command= :按名称执行命令(比 =M-x= 更可靠) - =sleep= :等待异步操作完成 - =suggest-improvement= :记录 UI/UX 改进建议(不影响测试结果) - =pass-test= / =fail-test= :判定测试结果,结束循环 整个 agent loop 最多跑 80 轮( =llm-test-max-iterations= 默认值),每轮是一次 LLM 请求/响应往返。 * 跟传统测试的区别 传统的 Emacs 测试用 ERT(Emacs Lisp 测试框架),测试代码直接调用函数、检查返回值。比如测试 =auto-fill= ,你要写 Elisp 设置 buffer、插入文字、检查换行位置。这测的是 *函数的行为* 。 =llm-test= 测的是 *用户的体验* 。Agent 不知道你的内部函数怎么调用——它只知道按键、看屏幕、判断结果是否符合描述。这跟真实用户使用 Emacs 的方式一模一样。 这种思路的优势: - *能测传统测试很难覆盖的场景* :比如" =M-x= 输入命令时的补全是否正确"、" =dired= 中按 =g= 刷新后文件列表是否更新"——这些涉及多个命令组合和 UI 状态变化的交互流程,用 Elisp 写测试非常痛苦,用自然语言描述却很自然 - *测试描述就是文档* :YAML 里的自然语言描述既是测试用例,也是用户行为的文档 - *对被测代码零侵入* :不需要为测试暴露内部接口或写 test helper 但也有明显的代价: - *非确定性* :同一个测试跑两次,LLM 可能走不同的操作路径,甚至得出不同的结论。这不是传统测试的"确定性"范式 - *成本* :每个测试都要多次调用 LLM API,一个测试组跑下来可能消耗不少 token - *速度* :每轮 agent loop 都是一次 API 调用,比直接 eval Elisp 慢几个数量级 - *依赖模型质量* :Andrew Hyatt 在 README 中建议使用 Claude Sonnet 级别的模型,不过他指出只要指令足够清晰,便宜的模型也能胜任 * "LLM 当测试员"的适用场景 =llm-test= 不会取代传统 ERT 测试。对于"函数 =f(x)= 输入 5 应该返回 10"这类确定性逻辑测试,Elisp 单元测试更快更准。 它适合的是另一类测试——那些"人一眼就能看出来对不对,但用代码描述很麻烦"的场景: - 包的 UI 工作流是否顺畅(按键 → 期望看到某个界面) - 多步骤交互的端到端验证(打开文件 → 编辑 → 保存 → 确认状态) - 发现 UI/UX 问题( =suggest-improvement= 工具让 agent 可以主动提出改进建议) 这个思路也可以延伸到其他 GUI 应用——只要你能给 LLM 提供"屏幕状态"和"操作接口",就能用同样的 agent loop 模式做测试。 =llm-test= 的 frame state JSON 快照设计就是一个很好的参考:不需要真的截图,把视觉信息结构化为文本就够了。 [fn:1] https://github.com/ahyatt/llm-test

TIL: AI 时代的橡皮鸭调试

2026年4月23日 08:00
读到 opensourceforu 的一篇文章[fn:1],提醒我一个容易忘记的事:调试效率的关键不是工具多强,而是你能不能把问题解释清楚。 * 橡皮鸭调试法 "橡皮鸭调试"(Rubber Duck Debugging)这个名字来自 *The Pragmatic Programmer* (1999 年)这本书:程序员桌上放一只橡皮鸭,卡住的时候就对着鸭子逐行解释代码。很多时候解释到一半,自己就发现问题了。 这个现象其实大家都不陌生。你肯定经历过:写了半天邮件描述一个 bug,写到一半突然想通了;或者在会议上给同事讲一个问题的来龙去脉,讲着讲着自己就意识到了错在哪。鸭子只是个象征,真正的机制是: *把模糊的想法变成清晰的表述,这个过程本身就是思考* 。 为什么解释能帮你找到 bug?因为脑子里想的逻辑和嘴里说出来的逻辑不一样。脑子里你可以跳步、模糊处理、含糊带过;但要说给别人听,你就必须一步步走:输入是什么?然后呢?这个条件为什么需要?失败了怎么办?这些被跳过的"然后呢"往往是 bug 藏身的地方。另外,说出来的假设会变得可疑——"这个值不可能为 null"一旦说出口,你马上会意识到"等等,万一呢?" * AI 是一只会提问的鸭子 传统橡皮鸭是被动倾听者——你对着它说,它不回应。AI 不同,它可以主动提问:"你确定这个 API 调用不会超时吗?""如果输入是空列表会怎样?" 但用 AI 调试有一个陷阱:如果你直接把代码丢给 AI 说"帮我找 bug",你只是在用 AI 替你思考。短期内问题解决了,长期来看你的调试能力没成长。正确的用法是把 AI 当鸭子而不是当助手——你来解释,让它质疑你的逻辑。 一个实用的 prompt: #+begin_example 扮演一只橡皮鸭。不要直接给我解决方案。 听我解释代码逻辑,然后指出不清晰的地方、 遗漏的步骤或错误的假设。 #+end_example 这样 AI 会帮你发现思维盲点,而不是直接帮你填上。 * 为什么这个方法仍然重要 AI 工具越来越强,一键就能生成代码、定位错误。但软件质量的上限取决于你对问题的理解程度,而不是工具的能力。不管工具怎么进化,"解释清楚"这项能力永远是稀缺的——因为它的本质不是技术能力,而是把混乱的直觉变成有序的逻辑。 [fn:1] https://www.opensourceforu.com/2026/04/the-relevance-of-rubber-duck-debugging-in-the-age-of-ai/
❌
❌