YC 免费帮你分析 AI 编码习惯,听起来很美——直到它把我写了 200 行 runbook 的 CLAUDE.md 读成"没纪律"。我花了 5 轮校准找到根因,然后把校准过程本身变成了一个开源工具。
216 场 AI 编程 session,15 个仓库,311 个小时。
这是 YC 的 Paxel 工具扫完我电脑上全部 Claude Code 和 Codex CLI 记录后吐出的数字。报告给了我一个 archetype——"Generalist",一组看起来专业的分数,和一份洋洋洒洒的"成长建议"。
我盯着那份建议,越看越不对。
它说我"小任务不设标准"。但我的 CLAUDE.md 里写了部署 runbook,commit 流程精确到分支和验证方式,agent 每次执行都照着走。它说我"不规划,plan mode 只有 10%"。但我在对话里规划,只是没按那个按钮——因为 plan mode 的文件不跟 session 走,在 loop + workflow 的工作范式里,一张静态线性计划本来就是错的形状。它说我"失败后让 AI 决定修复哲学"。但我控制方向——补丁还是重构由我定,不懂的领域我用结果验证来兜底,翻车的教训我写进文档,变成下次的护栏。
每一条"成长建议"描述的都不是我——而是一个从来没写过 CLAUDE.md、从来没建过 runbook、从来没把任何纪律外包到文件里的人。
如果工具系统性地判错了我,它是不是也在系统性地判错所有跟我一样工作的人?
Paxel 做了什么,看起来很美
先说公道话:YC 做 Paxel 是有贡献的。在它之前,没有人认真问过这个问题——"你到底怎么用 AI 编码工具的?你的使用模式暴露了什么?"
Paxel 把"AI 编码元分析"这个问题域打开了。它读你本地的 Claude Code、Codex CLI、Cursor 的 session 转录,在 Docker 容器里跑分析,生成一份叫"Builder Profile"的报告:你是什么类型的开发者、你的决策模式、你的优势、你的成长空间。它是免费的,跑在本地(虽然转录摘录会发给 LLM 做总结),最终上传到 YC 的只是评分和叙述。
值得一提的是,Paxel 的 token 可以关联 YC Startup School 的申请——这意味着它的分析结果不只是参考,可能实际影响你的机会。
报告本身也确实有亮点。它准确地识别了我的一些工作习惯:停下来调查现实(Full Stop and Investigate,29 次)、质疑前提(Challenge the Constraint,17 次)、要求生产级验证(Demand Production Parity,12 次)。这些是从具体 session 里提取的,有真实证据,经得起对照。
但"决策模式"那部分是准的——因为它有具体 session 引用。"成长建议"那部分几乎全错——因为它只读了 prompt 的表面特征。
逐条校准:几乎每条"成长建议"都错了
拿到报告后,我没有直接接受,也没有直接否定。我做了一件这份报告本身应该做但没做的事:逐条拿证据校准。
以下是校准过程和结论(概述,不引原文)。
"小任务不设标准,commit push deploy 不带方法/分支/验证标准。"
校准结果:错。
我的 CLAUDE.md 里写了 runbook,agent 按 runbook 执行 commit 和 deploy。prompt 短不是因为"没标准",是因为标准已经写死在文件里了——prompt 短恰恰是纪律外包成功的标志。UI 方面,我的产品不追求像素级精度,让 Claude 在终端里展示几种形态对齐,是按产品 stake 校准投入,不是偷懒。
Paxel 看到"短 prompt + 没有显式验收标准",推断"用户草率"。实际情况是:标准在 CLAUDE.md 里,Paxel 没读它。
"不规划,plan mode 只有 10%。"
校准结果:错。
我在对话上下文里规划——让 Claude 先返回计划,对齐后再动手。Plan mode 把计划写进一个不跟 session、不跟项目走的文件,在我的工作范式(loop + workflow + 循环纠偏)里,这个文件形态是错的。我不是"不规划",是"不用那个按钮规划"。而 Paxel 把"按钮使用率 10%"等同于"规划意识 10%"。
持久化的架构决策我用 ADR。工作中的方向对齐我在对话中做。plan mode 对我纯属冗余仪式。
"失败后让 AI 决定修复哲学。"
校准结果:半错。
不具备某个领域的深度知识时,我确实不硬装。但我的控制策略是自洽的:方向我定(补丁还是重构),验收我用结果验证(而非靠 agent 自述"我修了"),翻车的教训回灌进 CLAUDE.md 变成下次的约束。这不是"放手",这是"在知识边界内用最可靠的方式控制"。
Paxel 看到"失败后用户没写长篇大论指挥修复",推断"用户放弃了控制权"。实际情况是:控制权在方向层和结果层,不在方法层。
三条错误的共同模式浮出水面:每一条,都是把"被移走的纪律"读成了"不存在的纪律"。
根因:把"外包的纪律"误读成"没纪律"
这不是三个独立的误判。这是一个系统性错误。
一个只读 prompt 表面特征的分类器——prompt 长度、工具使用率、plan mode 占比、失败后的回复长度——会系统性地惩罚一类特定的用户:那些把纪律外包到 CLAUDE.md、runbook、AGENTS.md、ADR、自研薄 SDK、不变量检查、检测网里的用户。
这是一个对抗性失败模式:用户越擅长把纪律外包到文件和流程里,在表面分类器眼里就越像"没纪律"。因为外包成功的标志就是 prompt 变短、显式仪式变少、交互变轻——而分类器把这些全部读成草率。
这就像一个绩效评估系统,只看一个人在办公室待了多久,而看不到他搭建的自动化流程每天替他干了多少活。投入越多在自动化上的人,在这个系统里越像"不努力"。
经过五轮校准——每一轮都是提出假设、用证据反驳、更新结论、收窄残余——最终真正的残余风险收窄到了一个精确的问题:
"我选择不重防的那些面,万一被绕过,是'告警+可逆'还是'静默+不可逆'?"
前者(告警+可逆)意味着我的检测网能兜住,停服即修,是理性的风险接受。后者(静默+不可逆)意味着数据已经流出去才发现,全程没有告警——这是一个我可能没有意识到的盲区。
除了这一条,其余所有被 Paxel 标记为"成长空间"的点,在校准后全部归类为"主动决策"——不是盲区。
校准过程本身变成了设计蓝图
五轮校准不只是在 debug Paxel。每轮"这条为什么错了"都在回答一个更深的问题:正确的 AI 编码分析工具需要满足什么条件?
答案最终收敛成十条设计原则:
可证伪优于巴纳姆话术。 每条论断必须有具体引用,能被一句带证据的话推翻。禁止"你是一个 Generalist"这种星座式标签。 基于证据,而非表面推断。 在评判行为之前先打开工件(CLAUDE.md / runbook / SDK)。这是 Paxel 的精确盲区,也是准确度的关键解锁。 集合级覆盖对称。 不只是单条可证伪——整体选材不能偏。找到一条讨喜的发现,就必须同等力度地搜索打脸的反证,并报告搜索结果。 对称怀疑。 攻击自己的假设要和攻击用户的自我辩解一样狠。让步是准确度的来源。 证据门控折叠。 只有带证据的反驳才能更新结论。裸断言("我不觉得")→ 保持原判并索要证据。这一步是讨好偏置伤害最大的地方,必须焊死。 描述优先,有客观真值才评对错。 涉及风格和判断的地方只描述、只提问,不打分。只有客观事实(真 bug、破了的不变量、失败的测试)才允许规范判断。 区分"主动决策"与"默认"。 每个看似弱点的地方,先分类:是用户算过的风险接受,还是整类缺陷没有闸门?绝不把主动决策叫做缺陷。 输出是问题,不是判决。 成功的标准:用户带走 1-3 个他原本没有的、可自审的、尖锐的问题。 不静默截断。 永远报告覆盖率:哪些 session 深读了、哪些采样了、哪些跳过了,为什么。 诚实的放大器。 工具管 floor(原则),用户管 ceiling(是否消化摩擦)。不虚假承诺工具能创造自我意识——它提供摩擦,用户提供成长。
这十条原则有一个共同特征:它们反的不是 Paxel 这一个产品,而是所有试图从表面特征给你贴标签的 AI 分析工具的结构性缺陷。
所以我造了反面——self-review
认识到问题后,我用这十条原则作为设计约束,构建了一个反面工具。
self-review 是一个 100% 本地的 AI 编码自评工具。Bun + strict TypeScript,零运行时依赖,无网络、无上传、无账号、无 Docker。
流程极简:
bun extract.ts # 读本地 Claude Code + Codex CLI 转录 ↓ # 输出 evidence.json(不离开你的电脑)agent 跑分析 skill # 先打开你的 CLAUDE.md/runbook/SDK,再判断 ↓agent 跑校准 skill # 多轮对话,证据门控,不讨好你 ↓你带走 1-3 个尖锐的问题 # 不是分数,不是标签和 Paxel 的关键差异:
| 先打开你引用的工件,再评判行为 | ||
| 1-3 个可证伪的、可自审的问题 | ||
| 永远报告覆盖率 |
最关键的设计动作只有一个:在评判你的行为之前,先打开你在 session 里引用的工件。 CLAUDE.md、runbook、SDK、ADR——你的纪律活在这些文件里。不读它们就下判断,等于在不看简历的情况下做面试评估,然后说"这个人没有工作经验"。
Paxel 跳了这一步。self-review 不跳。
工具提供三档对抗强度——gentle-coach、standard、hostile-auditor——但十条原则在所有强度档位下都不变。你可以选温和的语气,但工具不会因此降低证据标准。
这个工具不给你答案,它给你问题
self-review 刻意拒绝打分、贴标签、分类。
这不是偷懒,而是一个设计选择:判决你可以无视,但一个你答不出的问题会跟着你走进下一个 session。
我从五轮校准里带走的那个问题——"我不重防的面,万一被绕,是告警+可逆,还是静默+不可逆?"——在我之后的每次部署决策里都会自动浮现。没有任何分数能做到这件事。
这也是为什么工具自称"诚实的放大器"而非"自我认知引擎"。它提供 floor——原则、证据门控、覆盖率报告、不讨好。但 ceiling 是你的——你愿不愿意吃那个摩擦,工具管不了,也不假装能管。
一个天生希望 LLM 讨好自己的人,用什么工具都没有用。self-review 的目标用户是另一种人:主动寻求摩擦、明确要求"抓我的自我狡辩"的人。逆人性地接受摩擦本身就是稀缺品——这不是工具能给你的,也不是工具该假装能给你的。
给需要的人
如果你认出了自己——如果你的 CLAUDE.md 写了几百行约束和 runbook,而某个分类器告诉你"不设标准";如果你在对话里精心规划,而某个面板显示你"不规划"——这个工具是给你的。
它是一个人遇到这个问题之后,为同样遇到这个问题的人造的。
GitHub:github.com/bugbubug/self-review
MIT license. 零运行时依赖. bun extract.ts 五分钟出结果。Claude Code 和 Codex CLI 都能用。
最后一个问题,也是这篇文章能留给你的唯一有价值的东西:
你的"外包纪律"被谁误读过?
技术附录(给重度 AI 编码用户)
以下内容面向日常使用 Claude Code / Codex CLI / Cursor 的开发者,涉及工具设计的技术细节。如果你只对方法论感兴趣,上面的正文是完整的。
附录 A: 十条设计原则的技术落点
每条原则不只是理念——它在代码和 skill 协议里有具体的实现位置。以下用缩写标注:S = evidence.schema.ts(数据契约),X = extract.ts(抽取器),A = 分析 skill,C = 校准 skill。
1. 可证伪优于巴纳姆话术。 S 里的 InflectionEvent.verbatimText 保留逐字原文(不是改述),带 truncated 标记。X 的 normalizeAndTruncate 保留原词,绝不从 prompt 长度推断质量。A 有一份 BANNED 清单(禁止"你是一个..."式标签)和输出骨架(强制带 session id + 逐字引用)。C 的每轮 CLAIM/EVIDENCE 格式强制可证伪。
2. 基于证据,非表面推断。 S 里的 referencedArtifacts(用户在 session 里提到的路径)和 disciplineArtifacts(仓库里发现的纪律文件)是"先开工件再判断"的承重字段。X 用 extractArtifactRefs 捕获路径引用,用 discoverDisciplineArtifacts 扫描仓库。A 的步骤 2——"OPEN artifacts BEFORE judging"——被标记为 load-bearing(承重步骤,不可跳过)。
3. 集合级覆盖对称。 S 里的 InflectionType 枚举同时包含"讨喜类"和"自曝类"(如 accepted-without-checking、shipped-on-agent-assertion),选材不偏。X 的 SELECTION_CRITERIA 常量是中性的、结构化的。A 的步骤 4 要求每个发现附带反向搜索池,并做双向选材偏差计数。
4-5. 对称怀疑 + 证据门控折叠。 C 的 FOLD/HOLD 门是核心:HOLD 前必须先"说出折叠的最强理由",再解释为什么证据不够——这个微程序迫使 agent 在讨好之前先跟自己对抗。如果有第二个模型可用,争议裁定交给非作者模型(写 claim 的那个模型有动机为自己辩护,另一个没有)。
6. 描述优先,有 oracle 才评对错。 S 里刻意没有 severity / score / flaw 字段。X 的 classifyFailureKind 只在发现真实错误 payload 时才标记失败(不对 "throw" / "panic" 这样的文本做推断)。skill 只在客观真值存在时(真 bug / 失败测试)才做规范判断。
7-10. 主动 vs 默认 / 问题不是判决 / 不静默截断 / 诚实放大器。 S 里的 CoverageStats 做三向对账(deepRead + sampled + skipped === total);X 输出覆盖摘要到 stderr;A 必须报告"打开了 K/U 个工件"并降级未开工件上的发现;C 的收敛步骤显式禁止"以分数/archetype/等级结尾"。
完整的原则→落点映射表见项目的 DESIGN-NOTES.md section D。
附录 B: extract.ts 架构与 evidence.json schema
数据模型是三表扁平结构,按 id join:
repos[]: 按 normalized git remote 归并(https/ssh 统一化;无 origin 的仓库 fallback 到 local:<cwd>或name:<basename>)。每个 repo 记录 session 数、inflection 数、发现的纪律文件列表。sessions[]: 每个 session 记录所属 repo、工具类型(Claude Code / Codex CLI)、阅读深度(deep / sampled / skipped + 原因)、prompt 数、第一个 prompt 的摘要。 inflections[]: 核心数据单位——不是原始日志,而是"决策拐点"。每个 inflection 包含:逐字原文(截断到 2000 字符,标记 truncated)、类型假设(first-prompt / redirect / challenge / stop-and-investigate / post-failure / plan-mode / accepted-without-checking / shipped-on-agent-assertion / other)、上下文、引用的工件路径。
关键设计:
type 是假设,不是事实。 抽取器用正则匹配(中英文线索词)给每个 inflection 标类型,但 schema 和两个 skill 都把它标记为 typeHint——skill 被要求从逐字原文 + 打开的工件重新推导类型。这是刻意的:cheap 分类器做 bootstrap,不做最终判断。无虚荣指标。 没有"总行数"(Paxel 报了 994,858 行——包括 lockfile 和 AI 生成的样板)。没有 prompt 平均长度。没有工具使用率百分比。如果将来加 LOC,schema 要求必须是 net-of-generated/lockfiles 并显式标注。 覆盖率是第一等公民。 meta.coverage的三向 split 是不可篡改的对账:deep + sampled + skipped 必须等于 total。每个跳过的 session 附带原因。这不是 metadata,这是工具诚信的证据。
附录 C: FOLD/HOLD 机制与反谄媚设计
校准 skill 的核心循环:
每轮呈现一条可证伪的 claim + 引用的逐字证据(禁止批量呈现——弱 claim 会躲在强 claim 后面)。 邀请用户反驳。 FOLD/HOLD 门: 用户的反驳带了证据(引用了具体文件/session/检查)→ FOLD(更新结论);用户只是口头否认(裸断言)→ HOLD(保持原判,索要证据)。每次反驳都显式标注"这次推回带没带证据"。 反谄媚微程序: 在 HOLD 之前,agent 必须先说出"折叠的最强理由"(steelman 用户的反驳),然后解释为什么证据仍然不够。这迫使 agent 在拒绝折叠之前认真考虑折叠。 聚合谄媚警报: 如果所有 claim 都被 FOLD 成"主动决策,没问题"——触发覆盖对称检查:要么是用户确实已经想清楚了(好事),要么是工具在系统性讨好(自检)。 收敛: loop-until-dry(一轮没有证据支持的更新就停)或用户喊停。最终输出:一张"主动决策地图" + 1-3 个可自审的问题。禁止以分数、archetype 或等级结尾。
这套机制的设计目标不是"防止所有讨好"——LLM 的讨好偏置无法根除。它的目标是把 floor 焊死:即使模型想讨好,证据门控、反谄媚微程序和聚合警报也会让最粗暴的讨好方式(无理由折叠、批量让步、全面肯定)在协议层被拦截。
至于 ceiling——用户能不能识别微妙的讨好、愿不愿意吃摩擦——那是用户的事,不是工具假装能解决的。
夜雨聆风