<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>认知债务 on 止语Lab</title>
        <link>https://www.wujiachen.com.cn/tags/%E8%AE%A4%E7%9F%A5%E5%80%BA%E5%8A%A1/</link>
        <description>Recent content in 认知债务 on 止语Lab</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Mon, 10 Aug 2026 20:57:48 +0800</lastBuildDate><atom:link href="https://www.wujiachen.com.cn/tags/%E8%AE%A4%E7%9F%A5%E5%80%BA%E5%8A%A1/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>技术债有账本，认知债没有：AI 编程最贵的代价</title>
            <link>https://www.wujiachen.com.cn/posts/ai-coding-cognitive-debt/</link>
            <pubDate>Mon, 10 Aug 2026 20:52:23 +0800</pubDate>
            <guid>https://www.wujiachen.com.cn/posts/ai-coding-cognitive-debt/</guid>
            <description>&lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/cover.png&#34; alt=&#34;Featured image of post 技术债有账本，认知债没有：AI 编程最贵的代价&#34; /&gt;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/cover.png&#34; alt=&#34;封面：明账 vs 暗账&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;技术债是可以还的。&lt;/p&gt;&#xA;&lt;p&gt;欠了技术债，至少你知道自己欠了。代码在那里，issue 在那里，lint 报告在那里，SonarQube 的坏味道列表在那里。它可感知、可量化、可排期。本质上是一本明账，你随时可以翻出来看，然后安排时间去还。&lt;/p&gt;&#xA;&lt;p&gt;认知债不一样。它的可怕之处不在于&amp;quot;还不起&amp;quot;，而在于&lt;strong&gt;你根本不知道自己欠了&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;你让 AI 写了一段代码，它编译通过，测试通过，跑起来一切正常。三个月后这段代码出问题，你打开文件，发现自己讲不清它为什么这么写。那一刻你才意识到，这段代码在写出来的时候，就没有人真正理解过它。它从来就不难，它只是从未被理解。&lt;/p&gt;&#xA;&lt;p&gt;这不是&amp;quot;代码难懂&amp;quot;，这是&amp;quot;理解从未存在&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;技术债是明账，认知债是暗账。明账可以还，暗账你连借条都找不到。&lt;/p&gt;&#xA;&lt;p&gt;这篇文章就干一件事：把两种债放在同一盏灯下面，让你看清楚它们差在哪。差的那一点，恰好是 AI 编程时代最贵的那一点。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第一章技术债的账本&#34;&gt;&lt;a href=&#34;#%e7%ac%ac%e4%b8%80%e7%ab%a0%e6%8a%80%e6%9c%af%e5%80%ba%e7%9a%84%e8%b4%a6%e6%9c%ac&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;第一章：技术债的账本&#xA;&lt;/h2&gt;&lt;p&gt;先看技术债为什么&amp;quot;可还&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;技术债这个词被滥用得很厉害，但它能成为一个产业概念，就因为它有一个完整的基础设施在支撑。这个基础设施就是它的账本。&lt;/p&gt;&#xA;&lt;p&gt;先拆开看，技术债的账本到底记了什么。&lt;/p&gt;&#xA;&lt;p&gt;第一层，&lt;strong&gt;代码本身是账本&lt;/strong&gt;。坏味道、重复代码、死代码、过长的函数，它们就在那里，任何一个人打开代码库都能看到。你可以给&amp;quot;圈复杂度 45&amp;quot;打分、给&amp;quot;重复代码占比 12%&amp;ldquo;排名，这些数字是客观的，工具算得出来，团队每个人看到的是同一份数据。&lt;/p&gt;&#xA;&lt;p&gt;第二层，&lt;strong&gt;工具链是记账的&lt;/strong&gt;。lint 在 CI 里跑，SonarQube 在流水线上扫描，依赖扫描工具告诉你哪个库有 CVE。这些工具不休息、不遗忘、不挑人。它们把&amp;quot;技术债&amp;quot;翻译成了机器可读的报告，挂在每个人都能看到的地方。&lt;/p&gt;&#xA;&lt;p&gt;第三层，&lt;strong&gt;团队流程是账本的分录&lt;/strong&gt;。评审意见、技术债清单、重构排期、迭代承诺，这些是人为的记账动作，把&amp;quot;代码有问题&amp;quot;转化为&amp;quot;我们有计划还&amp;rdquo;。它可能不完美，但它让技术债第一次有了&amp;quot;责任人&amp;quot;和&amp;quot;到期日&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;这三层合在一起，技术债就成了一种&lt;strong&gt;可治理的对象&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch1-three-layer-ledger.png&#34; alt=&#34;技术债的三层账本&#34; loading=&#34;lazy&#34;&gt;&#xA;管理层可以决策&amp;quot;这季度还三个债&amp;quot;，工程师可以反驳&amp;quot;这个债不该现在还&amp;quot;，新人可以查历史记录理解&amp;quot;为什么当时这么写&amp;quot;。技术债的账本让它拥有了普通缺陷没有的东西：&lt;strong&gt;可谈判性&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;你想想一个典型的还款流程长什么样。&lt;/p&gt;&#xA;&lt;p&gt;代码评审的时候，reviewer 指出来：&amp;ldquo;这个函数 300 行，拆一下。&amp;ldquo;这是第一笔记录，写在 review 评论里：有上下文、有理由、有责任人。&lt;/p&gt;&#xA;&lt;p&gt;过了几天，SonarQube 扫描报告出来了：&amp;ldquo;这个模块的圈复杂度 45，超过阈值，标红。&amp;ldquo;这是第二笔记录，挂在 CI 流水线上，谁都能看。&lt;/p&gt;&#xA;&lt;p&gt;再往后，你们开了个技术债评审会，把这些问题排了优先级，写进迭代计划：&amp;ldquo;下个迭代还三个债，每个估了工时。&amp;ldquo;这是第三笔记录，变成了团队的一个承诺。&lt;/p&gt;&#xA;&lt;p&gt;发现没有？技术债从产生到偿还，每一步都有&lt;strong&gt;记录&lt;/strong&gt;。有记录就能追踪，能追踪就能度量，能度量就能排期，能排期就能还清。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch1-ledger-chain.png&#34; alt=&#34;技术债的还款仪式&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;我把这个过程叫技术债的&amp;quot;还款仪式&amp;rdquo;。它粗糙、繁琐、经常被人吐槽官僚主义。但它的存在本身就是一个巨大的优势：&lt;strong&gt;系统对技术债的感知是全自动的。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;工具和 issue 会替你把账记好，不需要你记得。技术债的可还性，不依赖任何人的自觉性，它依赖的是账本。&lt;/p&gt;&#xA;&lt;p&gt;账本这个东西的价值，你在它存在的时候感受不到，直到它消失。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第二章认知债没有账本&#34;&gt;&lt;a href=&#34;#%e7%ac%ac%e4%ba%8c%e7%ab%a0%e8%ae%a4%e7%9f%a5%e5%80%ba%e6%b2%a1%e6%9c%89%e8%b4%a6%e6%9c%ac&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;第二章：认知债没有账本&#xA;&lt;/h2&gt;&lt;p&gt;现在看认知债。&lt;/p&gt;&#xA;&lt;h3 id=&#34;六个月的保质期&#34;&gt;&lt;a href=&#34;#%e5%85%ad%e4%b8%aa%e6%9c%88%e7%9a%84%e4%bf%9d%e8%b4%a8%e6%9c%9f&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;六个月的保质期&#xA;&lt;/h3&gt;&lt;p&gt;先讲一个场景。两个工程师，同一家公司，同一个月入职，能力相当。&lt;/p&gt;&#xA;&lt;p&gt;A 工程师接了一个需求：给系统加一个带状态机的限流器。他花了两天，手写代码，画了状态迁移图，写了注释，给同事讲了讲设计取舍：为什么用固定窗口而不是滑动窗口，边界突刺怎么办。Review 的时候同事问了几个问题，他一一解释，同事点头。&lt;/p&gt;&#xA;&lt;p&gt;B 工程师接了一模一样的需求。他打开 AI 工具，描述了需求，两分钟后代码出来了。他扫了一眼，编译通过，测试通过，功能符合描述。他把代码提交了，感觉良好。同样的需求，A 花了两天，他只花了两个小时，效率是 A 的八倍。&lt;/p&gt;&#xA;&lt;p&gt;六个月后，需求变更：限流规则要调整，状态机要加一个状态。&lt;/p&gt;&#xA;&lt;p&gt;A 打开自己的代码，回忆了五分钟，开始改。他知道每个状态为什么存在，知道迁移规则背后的业务含义，知道改哪里会牵连哪里。两天后改完，加了两组测试，上线顺利。&lt;/p&gt;&#xA;&lt;p&gt;B 打开代码，开始读。他读懂了每一行代码在做什么，毕竟语法是清楚的，但他不知道为什么这么设计。为什么用固定窗口？为什么 SOFT_LIMIT 下面放行规则和 NORMAL 一样？为什么这个状态从这里迁移到那里而不是直接回 NORMAL？&lt;/p&gt;&#xA;&lt;h3 id=&#34;你从不知道而不是忘了&#34;&gt;&lt;a href=&#34;#%e4%bd%a0%e4%bb%8e%e4%b8%8d%e7%9f%a5%e9%81%93%e8%80%8c%e4%b8%8d%e6%98%af%e5%bf%98%e4%ba%86&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;你从不知道，而不是忘了&#xA;&lt;/h3&gt;&lt;p&gt;这些问题的答案，在六个月前那个&amp;quot;感觉良好&amp;quot;的两分钟里，从来没有存在过。不是被忘记了，是&lt;strong&gt;从未被生成&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;B 花了整整一周才改完，改了三个 bug，其中一个还是线上才发现的。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch2-ab-engineers.png&#34; alt=&#34;A/B 工程师半年后重构对比&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;同样是还债，A 还的是自己欠的债，他知道债在哪。B 还的是别人（或者说是机器）欠的债，他甚至不知道债长什么样。&lt;/p&gt;&#xA;&lt;p&gt;我特意用了&amp;quot;别人欠的债&amp;quot;这个说法，因为 B 的处境比&amp;quot;忘事&amp;quot;更糟糕。忘事的前提是&amp;quot;曾经知道&amp;rdquo;。你忘了一件事，至少说明它曾经在你的认知里存在过。而 B 面对的是从未进入过他认知的东西。&lt;/p&gt;&#xA;&lt;p&gt;他的问题比记忆问题更深一层，是&lt;strong&gt;存在性问题&lt;/strong&gt;：他从来没有理解过这段代码，无论他怎么努力回忆，都回忆不出不存在的东西。&lt;/p&gt;&#xA;&lt;p&gt;这是认知债最残忍的地方：你从来不知道，而不是忘了。而人的认知系统对&amp;quot;自己不知道&amp;quot;这件事，在代码正常运行时是毫无感知的。你不可能主动去补一个自己不知道缺什么的东西。心理学管这叫&amp;quot;元无知&amp;rdquo;：你不知道自己不知道。&lt;/p&gt;&#xA;&lt;p&gt;这也是为什么&amp;quot;多读书多学习&amp;quot;这种建议，对认知债完全无效。你可以主动学习任何你&amp;quot;知道自己不懂&amp;quot;的东西。但认知债恰恰是你&amp;quot;不知道自己不懂&amp;quot;的部分。你不可能给一个你看不见的坑填土。&lt;/p&gt;&#xA;&lt;p&gt;必须说清楚一点，免得被误解：认知债并不是&amp;quot;不可检测&amp;rdquo;。它是&amp;quot;没有自动检测&amp;rdquo;。B 打开代码读不懂的时候，他其实能感知到&amp;quot;读不懂&amp;rdquo;，但只有在&lt;strong&gt;需要改代码&lt;/strong&gt;这个场景触发时，他才会去读。代码正常运行的那几个月里，没有任何信号会提醒他&amp;quot;这里有债&amp;quot;。认知系统的默认是节能的，检测不会自己启动，它需要一个外部事件来触发。&lt;/p&gt;&#xA;&lt;p&gt;这就是认知债和技术的本质差异：&lt;strong&gt;技术债的债务人是代码，认知债的债务人是人。&lt;/strong&gt; 技术债的账本记在工具链里，认知债的账本不存在，因为认知债本身就没有&amp;quot;记录&amp;quot;这个环节。它只存在于人的脑子里，而脑子不会自动记账。&lt;/p&gt;&#xA;&lt;p&gt;你无法给一个&amp;quot;从未被记录的东西&amp;quot;记账。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第三章为什么工具链检测不到&#34;&gt;&lt;a href=&#34;#%e7%ac%ac%e4%b8%89%e7%ab%a0%e4%b8%ba%e4%bb%80%e4%b9%88%e5%b7%a5%e5%85%b7%e9%93%be%e6%a3%80%e6%b5%8b%e4%b8%8d%e5%88%b0&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;第三章：为什么工具链检测不到&#xA;&lt;/h2&gt;&lt;p&gt;到这里，一个更尖锐的问题自然浮现：为什么所有质量工具都在检测代码，却没有一个工具在检测理解？&lt;/p&gt;&#xA;&lt;p&gt;答案很残酷：&lt;strong&gt;因为理解不在代码里，而工具只能检测代码里有的东西。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;编译器校验什么？语法、类型、可编译性。它不校验&amp;quot;你为什么这么写&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;Lint 管格式、管命名、管常见反模式，但&amp;quot;这个设计决策有没有人验证过&amp;quot;不在它的职责表上。&lt;/p&gt;&#xA;&lt;p&gt;测试管行为是否符合预期，&amp;ldquo;写这段代码的人是否理解它&amp;quot;不在它的检查清单里。&lt;/p&gt;&#xA;&lt;h3 id=&#34;编译器lint测试都假设了一件事&#34;&gt;&lt;a href=&#34;#%e7%bc%96%e8%af%91%e5%99%a8lint%e6%b5%8b%e8%af%95%e9%83%bd%e5%81%87%e8%ae%be%e4%ba%86%e4%b8%80%e4%bb%b6%e4%ba%8b&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;编译器、Lint、测试，都假设了一件事&#xA;&lt;/h3&gt;&lt;p&gt;整个工程基础设施，从编译器到 CI 到代码评审，全部建立在同一个假设上：&lt;strong&gt;代码是被理解的&lt;/strong&gt;。这个假设在 AI 出现之前基本成立。人能写出编译通过的代码，通常意味着他至少理解自己写了什么。即使不理解，他也会因为痛苦（debug 的痛苦）而被迫理解。&lt;/p&gt;&#xA;&lt;p&gt;AI 出现之后，这个假设第一次失效了。&lt;/p&gt;&#xA;&lt;p&gt;我做了个实验。我用 AI 生成一个带状态机的 HTTP 限流器，需求写得很清楚：每秒最多 100 个请求，四个状态，迁移规则逐条列出。AI 两分钟生成了 140 行代码，我编译，通过。&lt;/p&gt;&#xA;&lt;p&gt;然后我逐行检查，问了一个问题：这些设计决策，有没有任何一个在代码里留下&amp;quot;为什么&amp;rdquo;？&lt;/p&gt;&#xA;&lt;h3 id=&#34;一行代码的顺序错误&#34;&gt;&lt;a href=&#34;#%e4%b8%80%e8%a1%8c%e4%bb%a3%e7%a0%81%e7%9a%84%e9%a1%ba%e5%ba%8f%e9%94%99%e8%af%af&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;一行代码的顺序错误&#xA;&lt;/h3&gt;&lt;p&gt;结果很具体：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;固定窗口计数&lt;/strong&gt;：AI 自己选的方案，代码里没有任何注释说明为什么不用滑动窗口或令牌桶。固定窗口在窗口边界会有两倍突刺——对 A 工程师来说这是取舍（他知道并接受），对 B 的代码来说它是无主的选择（没人知道这是取舍还是疏忽）。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;SOFT_LIMIT 回落规则&lt;/strong&gt;：需求里根本没写&amp;quot;count 降到 80 以下回 NORMAL&amp;quot;，AI 自己补的。这个规则是谁定的？没人知道。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;放行语义偏差&lt;/strong&gt;：代码是先 &lt;code&gt;count++&lt;/code&gt; 再检查状态，窗口内计数实际会记到 101（100 个放行 + 1 个被拒也入账），而阈值用 &lt;code&gt;&amp;gt;100&lt;/code&gt; 判断——需求写的是&amp;quot;每秒最多 100 个&amp;quot;，代码的对齐方式是&amp;quot;记 101 次再锁&amp;quot;。这个差 1 的错位，没有&lt;strong&gt;已存在的&lt;/strong&gt;测试能抓到。它通过了你写的全部测试，因为没有人写过针对它的测试——而&amp;quot;没人想到写这个测试&amp;quot;本身，就是认知债的表现。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;硬限流期间计数继续累加&lt;/strong&gt;：HARD_LIMIT 状态下 count 仍在递增，恢复后可能瞬间又触发限流。没有注释解释这个行为是有意还是无意。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;SOFT_LIMIT 状态没有行为差异&lt;/strong&gt;：进入 SOFT_LIMIT 后放行规则和 NORMAL 完全一样。它可能有个合理解读（响应头把状态暴露给调用方，供监控告警用），但代码里没有任何文字确认这是设计意图——这种&amp;quot;可能是这样，也可能不是&amp;quot;的不确定性，正是认知债的本质。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch3-compiler-gate.png&#34; alt=&#34;编译器只校验语法，不校验理解&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;五处设计决策，无一处有理由；一处对齐错位，没有现成的工具会检测它。你注意到没有，B 工程师六个月前遇到的&amp;quot;SOFT_LIMIT 为什么和 NORMAL 行为一样&amp;quot;，正是这段代码里的第 5 处意图缺失——他当时感觉良好的两分钟，就是在为今天的一周还债。&lt;/p&gt;&#xA;&lt;p&gt;我盯着这份代码看了很久，脑海里冒出一句话：&amp;ldquo;这代码能编译，能过测试，但它在默认的抄写员用法下，从来没有被理解过——它只是被生成过。&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;这句话就是这篇文章的题眼。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch3-intent-gap.png&#34; alt=&#34;五处设计决策没有为什么&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;技术债的检测工具检测的是&amp;quot;代码里有的东西&amp;quot;。但 AI 制造的债务，缺失的部分恰恰不在代码里。它在生成那一刻就没有进入代码。&lt;strong&gt;工具链检测不到认知债，因为债务本身就不在工具能检测的维度上——工具不是不够聪明，是检测的维度根本不同。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;就像你无法用体重秤测量一个人的负债率。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第四章ai-是怎么让债滚雪球的&#34;&gt;&lt;a href=&#34;#%e7%ac%ac%e5%9b%9b%e7%ab%a0ai-%e6%98%af%e6%80%8e%e4%b9%88%e8%ae%a9%e5%80%ba%e6%bb%9a%e9%9b%aa%e7%90%83%e7%9a%84&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;第四章：AI 是怎么让债滚雪球的&#xA;&lt;/h2&gt;&lt;p&gt;有人会说：认知债又不是 AI 发明的。学生抄答案，工程师复制粘贴 Stack Overflow，一样是跳过理解。&lt;/p&gt;&#xA;&lt;p&gt;对，这个说法没错。认知债这个概念，是 Margaret-Anne Storey 在 2026 年初正式提出的：AI 生成代码的速度超过团队吸收的速度，导致的共同理解侵蚀。这个概念随后在 Hacker News 上引发了大规模讨论，Simon Willison 专门写了博客推荐，Martin Fowler 也撰文讨论过。它确实不是 AI 的发明。早在 AI 编码工具出现之前，复制粘贴别人的代码、囫囵吞枣地改两行就提交，一直是新手工程师的常态。你甚至可以追溯到更远：查手册翻文档的时候，跳过&amp;quot;为什么&amp;quot;直接抄&amp;quot;怎么做&amp;quot;，是每个程序员都干过的事。&lt;/p&gt;&#xA;&lt;p&gt;我提这个概念，不是想加入术语争论。术语本身不重要，重要的是它指向的那个真问题。Storey 的定义是团队层面的：整个团队对系统的共同理解在消失。而我想讨论的是它在个人层面怎么起作用：一个人、一段代码、一个&amp;quot;从未被理解&amp;quot;的模块。团队层面的债是无数个个人层面的债叠出来的，先从个人看起，看得更清楚。&lt;/p&gt;&#xA;&lt;p&gt;但 AI 改变了两个变量，把认知债从&amp;quot;偶发事件&amp;quot;变成了&amp;quot;默认状态&amp;quot;。&lt;/p&gt;&#xA;&lt;h3 id=&#34;两个变量速度与默认化&#34;&gt;&lt;a href=&#34;#%e4%b8%a4%e4%b8%aa%e5%8f%98%e9%87%8f%e9%80%9f%e5%ba%a6%e4%b8%8e%e9%bb%98%e8%ae%a4%e5%8c%96&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;两个变量：速度与默认化&#xA;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;第一个变量是速度。&lt;/strong&gt; 抄答案和复制粘贴，都是有成本的。你要找到答案，要判断答案对不对，要把它适配到你的场景。这个过程本身就是一种过滤：完全不懂的人，连&amp;quot;找到对的东西&amp;quot;都做不到。而 AI 把&amp;quot;生成&amp;quot;的成本压到了接近零。B 工程师那&amp;quot;感觉良好的两分钟&amp;quot;，在过去根本不存在。过去你必须至少理解一点，才能把代码拼起来。现在你什么都不用理解，两分钟就能得到一份编译通过的代码。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第二个变量是默认化。&lt;/strong&gt; 过去，跳过理解是一个主动选择，你要&amp;quot;去抄&amp;quot;才抄。现在，跳过理解是默认路径，你不主动要求理解，理解就不会发生。人的认知系统是节能的，默认路径就是最省力的路径。当&amp;quot;让 AI 写然后直接提交&amp;quot;成为默认，认知债的积累就变成了自动驾驶。&lt;/p&gt;&#xA;&lt;h3 id=&#34;平滑性幻觉&#34;&gt;&lt;a href=&#34;#%e5%b9%b3%e6%bb%91%e6%80%a7%e5%b9%bb%e8%a7%89&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;平滑性幻觉&#xA;&lt;/h3&gt;&lt;p&gt;还有一个更隐蔽的机制，我把它叫&amp;quot;平滑性幻觉&amp;quot;。技术债会以报错、卡顿、烂代码的形式不断骚扰你，它是痛的，痛让人无法忽视。而认知债是产生时无痛的：代码在跑，测试在绿，一切信号都在说&amp;quot;一切正常&amp;quot;。偿还时却剧痛，那种痛在半年后等你。痛苦是债务的天然报警器，认知债把报警器拆了，只留下一个不断增长的隐藏余额。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch4-smoothness-illusion.png&#34; alt=&#34;平滑性幻觉：报警器被拆了&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;我把这个过程叫&amp;quot;滚雪球&amp;quot;。雪球越滚越大固然可怕，更可怕的是它&lt;strong&gt;根本停不下来&lt;/strong&gt;——技术债有账本、有排期、有还款仪式，再大也有个盘子兜着；认知债的雪球，没有任何刹车。你每个月让 AI 写五百行代码，五个月后，在你以抄写员模式使用的前提下，你积累了 2500 行&amp;quot;从未被理解&amp;quot;的代码，而你浑然不觉，你的认知债在增长，但没有一个仪表盘会显示这个数字。&lt;/p&gt;&#xA;&lt;p&gt;我自己的体验也是这样。我们维护一套自己的写作工程系统，里面有不少代码是 AI 辅助写的。系统跑得很稳，稳定得让人安心。直到有一次要做架构调整，需要动一个核心模块，我们的内容发布脚本，正好是 AI 写的。我打开文件，能读懂每一行，但读不懂&amp;quot;为什么&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;那是一种很奇怪的体验：语法全懂，逻辑全对，但你不敢改。因为你不知道改了这一处，会破坏什么你没有意识到的约定。你面对的是一段&lt;strong&gt;从未被理解过的代码&lt;/strong&gt;，它的难懂和普通难懂代码完全不同。&lt;/p&gt;&#xA;&lt;p&gt;最后我花了整整两个下午，用最笨的办法：把状态机每一步跑一遍，把所有分支画出来，才敢动手。而这段代码，只有四百行。&lt;/p&gt;&#xA;&lt;p&gt;回头想，这两个下午是可管理的成本——但前提是我主动去还了。如果我不主动，这笔债会一直躺在那里，直到下一次架构调整，或者下一个接手的人。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch4-tutor-vs-scribe.png&#34; alt=&#34;导师 vs 抄写员&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;这里有一个重要的区分，也是我想为 AI 工具说句公道话的地方：&lt;strong&gt;问题不在 AI，在输入模式。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;同一个工具，两种用法，产生完全不同的结果。&lt;/p&gt;&#xA;&lt;p&gt;用法一，AI 是导师：你让它生成代码，然后逐行追问：为什么用这个方案？这个边界条件怎么处理？如果并发量翻十倍会怎样？每一次追问，都是一次理解。这种用法下，AI 的效率和人的理解同步增长，工具越好，人越强。&lt;/p&gt;&#xA;&lt;p&gt;用法二，AI 是抄写员：你让它生成代码，扫一眼，提交。代码是你&amp;quot;拥有&amp;quot;的，理解是别人（机器）的。这种用法下，效率的每一分增长，都在透支理解。&lt;/p&gt;&#xA;&lt;p&gt;业界数据也支持这个区分。Stack Overflow 与 OpenAI 合作的开发者调查显示，用 AI 学习的人数占比从 2024 年的 37% 涨到了 2026 年的 64%，几乎翻倍，而且在逐年增长（2025 年是 44%）。也就是说，越来越多的开发者正在主动把 AI 当作学习工具。认知债是&amp;quot;抄写员模式&amp;quot;的必然产物，跟 AI 本身无关。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch4-learning-trend.png&#34; alt=&#34;用 AI 学习的开发者 37%→64%&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;同样的工具，导师模式让人变强，抄写员模式让人欠债。这就像健身器材：拿来练是增肌，拿来当椅子坐是伤腰。不是器材的错，是用法。&lt;/p&gt;&#xA;&lt;p&gt;AI 没有让人变笨。它只是把&amp;quot;理解&amp;quot;从工作流里静默地移除了，移除得如此顺畅，以至于没有人发现它在消失。如果你用的是抄写员模式，那移除的过程，你根本感觉不到，因为它本来就是默认的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;结尾怎么给自己建认知账本&#34;&gt;&lt;a href=&#34;#%e7%bb%93%e5%b0%be%e6%80%8e%e4%b9%88%e7%bb%99%e8%87%aa%e5%b7%b1%e5%bb%ba%e8%ae%a4%e7%9f%a5%e8%b4%a6%e6%9c%ac&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;结尾：怎么给自己建认知账本&#xA;&lt;/h2&gt;&lt;p&gt;讲到这里，你大概已经猜到我要说什么了。既然认知债没有账本，那解决办法就是：&lt;strong&gt;自己给自己建一本。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;不需要复杂的工具，不需要新的流程，三件事就够。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第一笔：给 AI 写的东西写注释，但写的是&amp;quot;为什么&amp;quot;，不是&amp;quot;是什么&amp;quot;。&lt;/strong&gt; 代码是 AI 写的，&amp;ldquo;是什么&amp;quot;它已经替你说清楚了。你唯一能补充的，是它永远不会写的东西：为什么这么设计，这个方案放弃了什么。一句话就够：&amp;ldquo;这里用固定窗口，因为请求分布均匀，滑动窗口的复杂度不值得。&amp;rdquo; 这句话的价值不在于给别人看，在于写这句话的那一刻，你被迫理解了一次。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch5-build-ledger.png&#34; alt=&#34;给自己建认知账本&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第二笔：用&amp;quot;解释测试&amp;quot;代替&amp;quot;运行测试&amp;rdquo;。&lt;/strong&gt; 每次让 AI 生成代码，提交之前，把 AI 给你的解释文字关掉，自己看着代码，把它讲一遍，不是讲给 AI，是讲给空气，或者讲给你自己。讲不出来的地方，就是你的认知债所在。讲不出来，就回去问 AI，直到你讲得出来。这个测试不花时间，五分钟，但它是唯一能检测认知债的工具。&lt;/p&gt;&#xA;&lt;p&gt;这个测试有个前提得说清楚：它只能测出&amp;quot;你讲不出&amp;quot;，测不出&amp;quot;你讲得对&amp;quot;。一个人可能把错误的理解讲得头头是道——那是另一种债，叫错误自信，比&amp;quot;讲不出&amp;quot;更隐蔽。解释测试不是万能药，它只是把&amp;quot;理解&amp;quot;从默认路径上拉回来一次，让你有机会发现问题。发现了，才算开始还债。&lt;/p&gt;&#xA;&lt;p&gt;我把它叫&amp;quot;解释测试&amp;quot;，因为它本质上是在给你自己上一道和编译器对等的门禁。编译器检查代码能不能被机器执行，解释测试检查代码能不能被人类理解。两道门禁都过了，这段代码才真正属于你。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第三笔：定期&amp;quot;对账&amp;quot;。&lt;/strong&gt; 每两周，挑一段 AI 写的、你从没细看过的代码，花半小时读懂它，然后删掉一句你认为没用的代码，跑测试——对账，就是查账本上有没有没记的债。如果测试挂了，你就知道那句话为什么在那里。这是你能给自己的、最接近真实还款仪式的体验。&lt;/p&gt;&#xA;&lt;p&gt;这件事有个反直觉的好处：删掉一句没用的代码、测试却过了，意味着你找到了一处&amp;quot;AI 写得比你需要的多&amp;quot;的地方。这通常意味着那个模块可以精简，也意味着你的理解又多了一块。如果测试挂了，你就找到了那行代码存在的理由。这也是理解。无论哪种结果，你都在还债。&lt;/p&gt;&#xA;&lt;p&gt;这三笔账，本质上是同一件事：&lt;strong&gt;把&amp;quot;理解&amp;quot;重新放回工作流。&lt;/strong&gt; AI 不欠你什么，是你默认接受了不验证。改掉默认，债务就不会滚雪球。&lt;/p&gt;&#xA;&lt;p&gt;最后说一句可能让你不舒服的话。&lt;/p&gt;&#xA;&lt;p&gt;这篇文章真正想讲的，是我们自己的问题，而非 AI 工具的问题。AI 只是把&amp;quot;跳过理解&amp;quot;从成本极高的主动选择，变成了零成本的默认路径，它放大了我们本来就有的偷懒倾向，仅此而已。责怪 AI 不会让你变强，承认这一点然后改掉默认，才会。&lt;/p&gt;&#xA;&lt;p&gt;给代码建账本的工具很多，给认知建账本的工具只有一个：你在点击&amp;quot;提交&amp;quot;之前，多问自己一句：&lt;strong&gt;这段代码，我真的懂吗？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/ai-coding-cognitive-debt/ch5-final-question.png&#34; alt=&#34;提交前多问一句&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;如果答案是否定的，那你欠的债，就从这一秒开始计息了。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;附录实验代码和原始数据&#34;&gt;&lt;a href=&#34;#%e9%99%84%e5%bd%95%e5%ae%9e%e9%aa%8c%e4%bb%a3%e7%a0%81%e5%92%8c%e5%8e%9f%e5%a7%8b%e6%95%b0%e6%8d%ae&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;附录：实验代码和原始数据&#xA;&lt;/h2&gt;&lt;p&gt;本文的 E4 实测（AI 生成限流器的意图缺失分析）代码已开源：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;GitHub：&lt;a class=&#34;link&#34; href=&#34;https://github.com/wujiachen0727/zhiyulab-evidence/tree/main/ai-coding-cognitive-debt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;zhiyulab-evidence/ai-coding-cognitive-debt&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;code&gt;code/e4-intent-gap/&lt;/code&gt; — 限流器源码（AI 生成，保持原样）+ 生成 Prompt + 意图缺失分析 README&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;output/e4-intent-gap/&lt;/code&gt; — 运行输出与结论&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;每个子目录都有独立 README，说明如何复现。二进制编译产物不入库，跑实验前自己 &lt;code&gt;go build&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;原文发布于 &lt;a class=&#34;link&#34; href=&#34;https://www.wujiachen.com.cn/posts/ai-coding-cognitive-debt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;止语Lab&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;</description>
        </item></channel>
</rss>
