# AI 时代的软件项目复杂度

过去，我们分析一个软件项目的复杂度，通常会从代码量、文件数、模块数量、圈复杂度、耦合度开始。

这些指标并没有失效。

但在 AI Agent 参与软件工程之后，它们已经不够了。

因为代码不再只是人类写给机器执行的文本，也不再只是人类之间交接知识的文档。它正在变成一种新的协作媒介：人类描述意图，AI 探索项目，工具执行反馈，人类再判断结果是否可信。

于是，软件复杂度的核心问题发生了变化：

```text
不是这个项目有多大，
而是它能否被 AI 理解、探索、修改、验证，
以及人类能否低成本信任这个过程。
```

AI 时代的软件复杂度，本质上是 **人类与智能体共同驾驭一个系统的成本**。

---

## 1. 体量：从代码量到上下文压力

文件量、代码量、模块数量，仍然是复杂度的第一层。

但它们描述的不是复杂度本身，而是复杂度的载体。

一百万行结构清晰、模式重复的 CRUD 代码，未必比五千行高度压缩的算法、交易、风控或编译逻辑更难理解。

在 AI 时代，代码量首先意味着：

```text
这个项目会消耗多少上下文？
```

真正重要的不是项目总共有多少代码，而是为了理解一个具体任务，AI 需要读多少文件、跨多少模块、加载多少配置、追踪多少调用链。

因此，体量复杂度可以被重新理解为 **上下文压力**。

代码越多，不一定越复杂；
但如果一个小需求必须牵引出巨大的上下文包，它就已经复杂了。

---

## 2. 语义：从功能数量到可提示性

一个项目承载多少功能，也不是复杂度的全部。

更关键的是：这些功能能不能被清楚地说出来。

简单的功能可以被自然语言稳定描述：

```text
用户提交订单，系统创建订单，扣减库存，支付成功后发送通知。
```

复杂的功能往往只能这样描述：

```text
大体是下单逻辑，但不同渠道、客户、历史版本、活动规则、异常状态和人工干预会走不同分支。
```

这时，复杂度来自语言与代码之间的翻译损耗。

如果一个功能无法被人类清楚描述，它也很难被 AI 稳定实现。AI 可以生成代码，但它无法凭空补全那些没有被表达出来的业务边界、历史原因和异常约束。

所以，AI 时代的功能复杂度，可以叫做：

```text
可提示性复杂度。
```

一个功能越难被 Prompt 清楚描述，它就越难被 AI 理解、修改、测试和复刻。

---

## 3. 上下文：从能否探索到能否收敛

现在的 AI Agent 已经具备很强的自主探索能力。

它可以自己找入口，阅读 README，分析依赖，搜索调用链，运行命令，观察错误，再根据反馈继续修正。

所以问题已经不再只是：

```text
AI 能不能探索这个项目？
```

而是：

```text
它的探索能不能收敛？
```

如果一个项目有清晰的入口、稳定的构建方式、明确的错误反馈、可运行的测试和一致的目录结构，AI 即使一开始不了解，也能逐步建立项目地图。

但如果逻辑分散在代码、配置、数据库、脚本、队列、定时任务和历史补丁中，探索就会变成无边界漫游。

AI 会不断发现新上下文，却很难判断哪些是核心，哪些是噪音，哪些是必须遵守的约束。

因此，一个项目的复杂度不在于 AI 是否能探索，而在于：

```text
AI 的探索是否有路径、有反馈、有终点。
```

---

## 4. 边界：从模块耦合到状态纠缠

传统软件工程谈耦合度。

AI 时代更需要谈状态纠缠。

一个系统如果边界清楚，每个模块都有明确的输入、输出、依赖、副作用和验证方式，那么它就可以被拆成一个个相对独立的任务单元。

这样的模块适合交给 AI 处理。

因为 AI 可以围绕一个有限边界完成闭环：

```text
理解需求
定位代码
修改实现
运行测试
根据反馈修正
```

但如果一个功能依赖全局状态、隐式配置、历史数据、外部服务、特殊客户分支和没人敢删的 hack，它就不再是一个清晰模块，而是一团纠缠的状态。

这种系统中，AI 一动就可能牵一发动全身。

所以，复杂度不只是模块之间有没有依赖，而是：

```text
一个局部改动会不会唤醒整个系统。
```

状态越纠缠，系统越难被 AI 局部处理，也越难被人类安全审查。

---

## 5. 暗知识：从代码可见性到隐性上下文

AI 能读代码，能读文档，能读测试，能读日志。

但它读不到没有被写下来的东西。

很多软件项目真正的复杂度，不在仓库里，而在仓库之外：

```text
为什么这里要 sleep 50ms？
为什么这个字段不能删？
为什么这个接口不能并发调用？
为什么这个丑陋的 if 分支一直保留？
为什么这个看似多余的校验绝不能移除？
```

这些答案可能存在于老员工的记忆、事故复盘、聊天记录、客户合同、线上故障、历史迁移和一次又一次现实妥协里。

这就是暗知识。

暗知识越多，AI 越容易自信地犯错。

它可能会把一个历史补丁看成冗余代码，把一个特殊分支看成坏味道，把一个丑陋实现重构成更优雅但错误的版本。

因此，AI 时代的软件复杂度，很大程度上取决于：

```text
系统正确运行所需的知识，有多少没有被显性化。
```

不在代码、文档、测试和约束里的知识，对 AI 来说几乎等于不存在。

---

## 6. 验证：从生成成本到信任成本

AI 让生成代码的成本急剧下降。

过去，写一段复杂逻辑可能需要几天。现在，AI 可能几分钟甚至几十秒就能给出一个看似完整的实现。

但生成变便宜之后，真正昂贵的东西变成了验证。

```text
它写得对吗？
它漏掉了什么？
它破坏了什么？
它的解释可信吗？
人类是否还需要重新读一遍源码？
```

这就是验证不对称。

AI 生成一个方案很快，但人类确认这个方案在真实系统中不会出问题，可能仍然很慢。

如果一个项目缺少测试、缺少可观测性、缺少稳定环境、缺少清晰边界，那么 AI 的产出越多，人类的验证压力反而越大。

此时，复杂度已经不再是“代码写不写得出来”，而是：

```text
写出来之后，能不能证明它是对的。
```

所以，在 AI 时代，验证成本就是复杂度的核心标尺之一。

一个系统是否适合 AI 协作，最终取决于它能否让 AI 的修改被快速、可靠、低成本地验证。

---

## 一个简化公式

如果用一个公式来描述 AI 时代的软件项目复杂度，可以写成：

```text
Project Complexity ≈
Semantic Density
× Context Span
× State Entanglement
× Implicit Knowledge
× Verification Cost
÷ Capsuleability
```

也就是：

```text
语义越密，越复杂；
上下文越长，越复杂；
状态越纠缠，越复杂；
暗知识越多，越复杂；
验证越贵，越复杂；
越能被胶囊化，越不复杂。
```

这个公式不追求数学精确，而是表达一种判断方式：

```text
复杂度不是代码的物理大小，
而是系统能否被描述、装入上下文、拆开处理、探索收敛、修改验证。
```

---

## 重构与复刻：复杂度的终局指标

判断一个项目复杂不复杂，最后可以看两个问题：

```text
能不能重构？
能不能复刻？
```

重构要求我们在保持行为不变的前提下改善结构。

它考验的是：

```text
行为边界是否清楚？
测试是否可信？
暗知识是否显性？
局部修改是否安全？
```

复刻要求我们提取核心功能，并重新实现一个等价或近似等价的新系统。

它考验的是：

```text
主要功能是否说得清？
业务规则是否完整？
数据模型是否可理解？
异常边界是否可枚举？
```

有些项目代码很烂，但功能简单，所以难重构，却容易复刻。

有些项目代码看似规整，但业务规则、历史数据、异常状态和外部依赖极其复杂，所以局部重构不难，完整复刻却非常困难。

因此，重构和复刻不是普通指标，而是复杂度的最终显影。

它们会把体量、语义、上下文、状态、暗知识和验证问题全部暴露出来。

---

## 总结

AI 时代，软件项目复杂度可以被压缩成六个问题：

```text
1. 它有多大的上下文压力？
2. 它的语义密度有多高？
3. 它能否被清楚 Prompt？
4. 它的探索能否收敛？
5. 它的状态是否可以被拆开？
6. 它的修改能否被低成本验证？
```

更简洁地说：

```text
复杂项目不是 AI 写不出代码，
而是 AI 写完之后，人类难以确认它是否真的理解、真的改对、真的没有破坏系统。
```

这也引出了 Harness Engineering 关心的问题。

重点不只是让 AI 生成代码，而是如何设计一个工程环境，让 AI 能够理解上下文、遵守约束、探索系统、接收反馈、修正错误，并让人类能够低成本建立信任。

AI 时代的软件工程，正在从“写代码”转向“设计可被智能体驾驭的系统”。

而复杂度分析，就是理解这一转变的第一步。