这周的技术圈有几件值得关注的事:有人把散落在各处的软件工程法则整理成了一个可检索的集合;有人做出了基于 CRDT 的 TypeScript 图数据库;还有人开始认真思考——让 LLM 生成带类型的代码,我们是不是一直在用错误的方式做这件事?

56条软件工程法则

Laws of Software Engineering 是一个新上线的项目,把软件工程领域那些耳熟能详的”定律”整理成了 56 张卡片。从 Conway’s Law 到 Hyrum’s Law,从 Brooks’s Law 到 Hofstadter’s Law,每条法则都有简洁的定义和分类标签。

这个项目的价值不在于发现了什么新东西,而在于系统化。它把这些散落在不同书籍、论文、博客里的经验法则,按照架构、团队、规划、质量、设计、决策、扩展性等维度做了归类。对于需要向团队解释”为什么这个功能不能下周上线”或者”为什么不能为了优化而优化”的工程师来说,这是一个挺好的引用工具。

几条我个人觉得值得反复看的:

  • Hofstadter’s Law:就算你把 Hofstadter’s Law 考虑进去,实际花费的时间还是比你预期的长
  • Gall’s Law:一个能跑的复杂系统,一定是从一个能跑的简单系统演化而来的
  • Price’s Law:参与人数的平方根,做了 50% 的工作

@codemix/graph:把图数据库塞进 CRDT

codemix/graph 是一个挺有意思的实验——一个类型安全、支持实时协作的图数据库,底层基于 Yjs 的 CRDT 实现。

它的核心设计很清晰:

  • 用 Zod/Valibot/ArkType 定义 schema,类型会贯穿所有查询和遍历
  • 支持 Gremlin 风格的图遍历 API
  • 支持类 Cypher 的查询语法(给 LLM 用)
  • 存储层可插拔,内置 Yjs 支持实现离线优先和实时同步

这个项目目前还是 alpha 状态,但已经能在浏览器里跑。演示页面甚至做了一个”把你自己加到关系图里”的功能,所有打开这个页面的用户都能看到彼此添加的节点和连线——这就是 CRDT 的能力。

对于需要在客户端维护复杂关系数据的场景(比如思维导图、流程编辑器、社交网络原型),这个方案比”自己手写状态同步”要靠谱得多。

类型系统与神经网络:我们生成代码的方式错了吗?

Bruno Gavranović 的一篇新文章 Types and Neural Networks 提出了一个尖锐的问题:现在的 LLM 生成代码,是先训练出 Token 序列,然后再用类型检查器去验证。这个过程是事后验证,而不是类型驱动生成

文章探讨了几个关键问题:

  1. 现在的做法(生成后编译,出错就重试)本质上是用类型检查器做过滤,而不是指导生成
  2. 有没有可能从底层重新设计 LLM,让它在训练阶段就学习类型约束,直接生成类型正确的代码?

这个问题在 Idris、Lean、Agda 这类依赖类型语言的代码生成场景下尤其重要——因为这些语言的类型约束本身就是程序逻辑的一部分,事后再修正的成本极高。

文章没有给出完整答案,但提出了一个值得关注的方向:如果神经网络的输出类型本身就是结构化的类型(而不是 Token 列表),我们能否训练出”天生就会类型检查”的模型?

小结

这周的热点某种程度上都在围绕同一个主题:如何管理复杂性。软件工程法则告诉我们复杂性的表现形式,CRDT 图数据库提供了一种协作状态下的数据一致性方案,而类型驱动的神经网络则在探索 AI 时代代码生成的正确打开方式。

文章发表于 gumi.ink