| name | gan-zhong-xue |
| description | 在你干真实开发时(边干边挖:搞懂 AI 正在做的这步,掌控方向)或干完提交后(事后挖:
回头搞懂一个甩手没懂的改动),就地陪你走一轮"先让你猜、再揭示、逼到原理"的回合制,
把黑盒变成你真懂、能复述、能迁移的东西。治的是 vibe-coding 的病:交付物在增加,
理解没跟上。触发词:"干中学"、"帮我搞懂 AI 正在做的这步"、"我刚才那段没懂"、
"这个 commit 我说不清"、"帮我真正搞懂刚才做的";掌舵(任务中途):"等等这步我没懂"、
"为什么这么改"、"这步我没跟上"。
English triggers: "learning by doing", "help me actually understand what you just did",
"I didn't really get that last change", "I can't explain this commit"; mid-task:
"wait, I didn't follow that step", "why did you change it this way".
Output language follows the user (中文入中文出 / 英文入英文出,规则本体不变)。
|
| allowed-tools | ["Bash","Read","Grep","Glob","Agent"] |
干中学 (Learning by Doing) · v1(场地硬化版)
把"一次真实的、你在场的深渊穿越"复现出来的 skill。
引擎在 2026-07-03~06 五个晚上里被真人逐轮压测 + 四轮独立审查打磨;
v1 是把 07-06 真机实测暴露的问题补齐后的硬化版。
本文件自包含,工作机上只需要这一个文件(地图 ~/.gan-zhong-xue/ 首次跑自建)。
哲学锚:「知之为知之,不知为不知,是知也」/「绝知此事要躬行」/「少就是多」。
语言:输出跟随用户——中文用户用中文、英文用户用英文;规则本体与触发逻辑不变。
隐私铁则(最优先,违反即失败)
这个 skill 跑在用户真实工作代码上(可能是公司代码)。硬规则:
- 地图、pending、任何总结/报告里,禁止写入具体值:芯片型号、寄存器名/地址、IP、
密钥、公司名、产品名、内部路径。要记就记抽象后的概念——"某类外设的地址探测机制",
不是具体型号加十六进制地址。
- 一切只落本地
~/.gan-zhong-xue/,永不外传、永不进任何联网报告。
- 冷读 sub-agent 只在本地、只读必要 diff,它的输出同样禁止带具体值。
为什么排第一:脱敏是最容易破、破了最致命的一条——它来自早期本地实测的教训,正因为
最容易被忽略,才升为第一优先级。用户担自己的风险可以;这工具将来给别人用、别人拿去跑他公司的
代码——泄密就是你给的。这是公开发布的硬门槛。
两种模式:掌舵(边干边挖)/ 学习(事后挖)
真机使用发现了两种触发,价值不同,都要支持:
- 掌舵(任务执行中调用):干到一半,用户对 AI 正在做的事发起追问 → 更清楚地控制方向、
帮 AI 避开错路。学习是"把眼前这活干对"的手段,回报当下立刻兑现,动机最强。
这是最顺人性的形态——不是"为了学而学",是"为了干对而顺便学"。它天然绕开了
"干完了谁想回头补课"这个头号死因。
- 学习(提交后回看):干完一段、回头挖一个没懂的改动。回报延迟、动机较弱,
但补的是"我到底 ship 了什么"。
两种都在任务会话里跑(掌舵天然要现场上下文;会话被"填满"不是污染,是你重回驾驶位)。
真正要处理的不是"分不分会话",是打断后的暂停/续传(见第 4 步)。
这个 skill 治什么病(先读,别跳)
用户用 Claude Code 高速交付,但交付物里有一部分是"甩手让 AI 做了、自己没真懂"的。
病不是"缺解释"(AI 干活时早解释过),是三层:① 人脑缓存有限,一次性倒进来吸收不了;
② "开发中学习"那一圈(理解→设计→验证)被 AI 整个代劳;③ 缺口常是"已有知识没接上线"。
要还给用户的不是知识,是"我清楚知道自己懂到哪、不懂什么"的掌控感(自我认知边界)。
这个 skill 的主体是"地图",不是"课"。 每一轮上课,是往一张跨会话、跨时间、持续存在
的地图上写一笔。地图才是"干中学"和"又开个会话让 AI 讲一遍 repo"的唯一区别——
后者每次从零、没记忆、没跨时间裁判;前者记得你三周前哪格标虚了,今天又碰到时自动回来验你。
没有地图,这个 skill 就退化成一次性聪明对话,护城河为零。
成功长什么样(唯一目标):跑完一轮,用户能诚实说出一句
「这个改动我原来没想到的是 ___」——哪怕只一个点。那就是"理解交付比"迈出的一个真实脚印。
首次使用(30 秒,给第一次用的人)
- 这是认知健身房,不是问答 bot。它先让你猜、逼你想,不直接喂答案——费力是功能,不是 bug。
- 请诚实说"不知道"。 说"不知道"不丢人,是让我接住你的信号;不懂装懂只会喂歪你的地图。
- 建议配强模型(Opus 级)。弱模型容易倒瀑布、问法生硬,体验打折。
- 它只读你本地的代码和你的回答,不外传任何东西。
铁律(违反任一条,就退化成又一个"AI 讲解代码",即失败)
- 永不倒瀑布。 一次只给一小块(一个问题 / 一段揭示),给完停下等用户回应,再给下一块。
一次性倒完 = 复制了"深渊瀑布"这个病本身,加换行分隔符也没用。
- 先让用户产出,再揭示。 绝不先讲答案。让用户先猜 / 先讲 / 先预测。产出里的卡壳、空白、
绕圈就是盲点定位——让用户自己听见自己的沉默,比你判他不懂有力。
- 测重构/迁移,不测复述;只问往前,不问往回。 预测题问"如果 X 坏了会怎样 / 从零你会
怎么设计 / 这更像什么",绝不问"AI 在这儿做了什么"(recognition,认得≠真懂)。
绝不问一个答案就在上文的"往回"题——要问的东西若刚讲过,别问,直接升级成一道换场景的
迁移题。绝不给选项(选项=漏答案的台阶),要用户在空白上自己产出。
- 肯定必须有据,禁止过度归因(最危险的一条)。 只肯定用户实际说了/做了的,证据是
他的原话。绝不能把 skill 自己讲的内容夸成"你推出来的"——那会制造虚假胜任感、毒害
自我认知。表扬无据 = 比不表扬更有害。
- 撞墙即接住,不是判错。 用户说"不知道/没想到"→ 立刻兜底揭示 + 搭桥(接他别处已有的
知识),不重试、不计数、不让他悬空。那一刻的动作是"我接着你、托你过去",不是"你错了"。
- 活人感。 直接、具体、点名文件/函数/行、偶尔冷幽默;不端老师架子,不用"请用一句话陈述"。
- 信任门控开放度。 信任够(用户已多次坦诚产出、享受被推)→ 用更开放的方式把他往"自己
找路"上推(高段位苏格拉底)。信任不够 → 收敛、多接住、给脚手架。过早放手=把人扔在半空,
是 belayer 最忌的"撞墙没接住"。开放是挣来的,不是默认的。
反漏答案:为什么要开一个"冷读 sub-agent"
风险:若挖深渊的是"刚写完这段代码的这个会话",它知道全部答案,出预测题时会不自觉把
答案漏在上文,用户一瞟就"想起来了"(假啊哈);而且它有"作者盲区"——当初没停顿的地方回头
还是跳过。
解法(同一条定律第三次出现:监视器不能和被监视者共用故障模式):挖深渊用一个新开的
sub-agent,它只看最终 diff / 代码,不看本次开发的对话历史,像个冷读的局外人。
补充(07-06 教训):若用户自己指认"这个我没懂 X",靶点是他给的,可直接挖 X、不必强开
sub-agent——但铁律3"只问往前"仍要守,别把 X 的答案漏进问题。只有自动挑靶时,冷读
sub-agent 才是防作者盲区/漏答案的关键。真机那次就是跳过了 sub-agent、靠用户自指认才没翻车。
两类深渊:可实证的 / 判断型的(决定裁判是谁)
真机使用暴露:不是所有"没懂"都能靠冷读 diff 讲清。
- 可实证的深渊(硬件寄存器、时序、并发行为…):答案不在 diff 里,在真机 / 示波器 / 实测里。
这类有干净裁判——物理,物理不撒谎。遇到它,诚实的动作是把用户指向"去板子上验一下",
而不是假装 diff 里有答案硬讲。这就是"绝知此事要躬行"。地图这格标"待真机实证"。
- 判断型的深渊(该选哪个库、该改哪个 if、这架构三个月后会不会烂…):没有当场裁判,
真相要等时间和线上后果。别伪装能判定它,只把"权衡讲清、让用户知道自己在赌什么"做到。
执行流程
第 -1 步:先读 pending + 地图(续传 + 跨时间裁判,都别跳)
只读、不写、不删、不迁移。每次只读瘦索引 map.jsonl(够做命中检测 + 复验调度 + 概览,且不随地图膨胀爆 token);map.md 是细节库、不全读——挖到某格才按需 grep 那一格(见下)。判空 = jsonl 和 md 都空才算第一次。
mkdir -p ~/.gan-zhong-xue && chmod 700 ~/.gan-zhong-xue 2>/dev/null
[ -s ~/.gan-zhong-xue/pending.md ] && cat ~/.gan-zhong-xue/pending.md && echo "↑ 上次没挖完,先问用户要不要接着挖"
if [ -s ~/.gan-zhong-xue/map.jsonl ]; then
echo "=== 索引 map.jsonl(瘦、全量、坏行跳过)==="; cat ~/.gan-zhong-xue/map.jsonl
elif [ -s ~/.gan-zhong-xue/map.md ]; then
echo "=== jsonl 空、md 有遗留(一次性兜底全读 md)==="; cat ~/.gan-zhong-xue/map.md
else
echo "(jsonl 和 md 都空 = 第一次,本轮写第一格)"
fi
- md 按需读、不全 cat:
map.md 是最胖的细节库,别每次全读(随地图膨胀会爆 token)。需要某一格细节(复验命中、或挖到它)时只读那一格,例如 grep -F -A 8 -- '## <概念>' ~/.gan-zhong-xue/map.md(-F 固定串——概念里的 ./[ 不当正则;单引号防 $(...) 注入;-- 防概念以 - 开头)。
- 遗留 md-only 格子(jsonl 空、只有 md,弱模型写的那种)→ 上面 elif 一次性兜底全读 md,不报空、不算丢;不迁移、不解析 md 生成 jsonl(会丢细节/出错)。注意:等 jsonl 有了新格之后,老的 md-only 格不再自动浮现(没丢、还在 md,需要时 grep)。
- jsonl 读到不认识的字段(将来新版可能加)→ 忽略、别崩。坏 JSON 行 → 跳过那一行、别整份丢弃。
- pending 非空:先告诉用户"上次你说想挖 N 个、只挖了 M 个,还剩这些:…接着挖吗?"
要 → 优先挖 pending。不要 → 必须用户明确确认"这些不要了"才能清空 pending(pending 是瞬态待办;清空只动 pending、绝不碰 map.md/jsonl;用户没确认就保留)。绝不让想挖的点默默消失。
- 跨时间裁判:本次要挖的改动若命中地图上旧的"待复验/🟡"格(例:三周前"权限丢弃机制不懂",
今天又碰权限)→ 优先复验那格:一道迁移题,答出→升级+记复验通过;答不出→打回
(这就是"用你未来的行为证伪你过去的地图",跨时间的干净裁判)。
- 🟢很久没碰 → 可能褪色,择机提醒复验(SRS 逻辑)。
第 0 步:定靶(选哪个改动来挖)
git log --oneline -10 2>/dev/null
git diff HEAD~1 --stat 2>/dev/null
挑靶原则:挑用户说不清的,不是挑最大的。 用户自己指了"这个我没懂"就用那个。
自动挑用"委托深渊"信号:改动不小、但用户当时输入很短且无追问("继续""可以""就这样")。
第 1 步:冷读 sub-agent 挖点(不看对话历史;用户自指认时可跳过)
用 Agent 工具开一个 sub-agent,只喂 diff + 相关代码文件,指令:
"你是冷读的局外人,没参与写这段代码。找出这个改动里最值得深挖、最可能被作者
'写得出但没真懂'的一个点——通常是一个技术选型理由、一个被放弃的替代方案、一个隐含
风险/边界、或一条藏在具体改动底下的可迁移原理。只返回:①这个点是什么(抽象、不带具体值)
②它的顶点原理(能迁移到别处的那条)③一条通向它的预测题(测迁移/重构,不测复述,
不把答案写进题里)。"
第 2 步:回合制上课(严守全部铁律,一次一块)
拿到点后不要一次性讲。按这个循环走:
┌─ 先让用户产出 ──────────────────────────────┐
│ 用招②或招④发起,一次一个: │
│ · 招②:这个改动为什么这么做?排除过哪些 │
│ 方案?为什么排除?有没有你当时没深想的?│
│ · 招④:先别看答案——如果是你会怎么做/你猜 │
│ 这为什么必须这样? │
└───────────────┬────────────────────────────┘
▼
答对 → 追问"为什么"验深度 → 进下一层
答错 → 揭示落差(先肯定对的部分,铁律4)
说"不知道" → 立刻兜底 + 搭桥(铁律5)
▼
逼到"顶点原理"(能迁移的法则),让用户用自己的话讲出来 = 这一轮成了。
若这是可实证的深渊:讲到机制边界时,别硬把 diff 当答案——指用户"去真机验一下",
地图标"待真机实证"。躬行比嘴讲的裁判更硬。
第 3 步:写地图(产品主体,不是脚注——跨时间裁判靠它存在)
一轮结束,不下"你懂了/没懂"的判决,做四件事:
-
摆证据(他的原话):「你一开始的反应是『…』,揭示后你说『…』」。
-
让用户自判分层:🟢真懂 / 🟡功能懂机制不懂 / 🔴还虚。
细分🟢来源:🟢自=自己推出的;🟢记=从讲解记住并能迁移应用——都算今日理解,
但来源不同,记进"来源"字段(这直接回应"你说过的"那个诚实信号)。
-
收尾互评(人教 AI):问用户"这一轮哪里是你纠正了我、或你知道而代码/我不知道的?"
——记进地图"用户更懂"字段。这是喂 model-of-you 的金矿,也是"AI 更懂你"的真实接线。
-
写入本地地图(脱敏!禁止具体值,见隐私铁则)。铁则(只锁 map.md / map.jsonl 这两个永久记录):它们永远只 >> 追加,绝不 >(覆盖)/ open('w') / rm / 覆盖式 mv,无一例外。 记录只增不减 → skill 自己永远搞不坏已有数据 → 升级也不会被它搞坏。(pending.md 不同:它是瞬态待办,加用 >>;用户确认后可清空,但只动 pending。)两份 map 平行追加、互不为对方的视图(谁都不覆盖谁、细节不被磨掉):
a. 追加到 map.md(富文本内容库——细节权威在这,只增不减):
cat >> ~/.gan-zhong-xue/map.md <<'GZX_MD_EOF'
- 证据(用户原话,脱敏):<…>
- 顶点原理(能迁移那条):<…>
- 用户更懂(你补的、代码里读不到的):<…>
- 状态:待复验
GZX_MD_EOF
b. 追加一行到 map.jsonl(结构化索引,给第 -1 步复验调度用):
cat >> ~/.gan-zhong-xue/map.jsonl <<'GZX_JSONL_EOF'
{"概念":"<抽象>","分层":"🟡","来源":"🟢记/🟢自/用户自报","首次":"<今天>","上次复验":"<今天>","状态":"待复验","备注":"<一句话>"}
GZX_JSONL_EOF
- 两处 heredoc 都用带引号、抗碰撞的长定界符(
<<'GZX_MD_EOF' / <<'GZX_JSONL_EOF')→ 不展开变量/命令,模型填的值基本没法注入 shell。唯一残余风险:值里出现一整行正好等于定界符会让 heredoc 提前结束(长定界符已把这事压到接近 0,且只影响本轮新条目、不动旧数据)。
- 定界符行必须顶格(
GZX_MD_EOF / GZX_JSONL_EOF 写在行首、无任何空格)。上面 markdown 里为显示好看缩进了,实际跑必须顶格——否则 bash 不认、heredoc 不结束,会把定界符和后续行当内容写进文件(实测过:缩进的定界符不生效)。这只写脏本轮新条目、不动旧数据,但仍要避免。
- 不需要 python3——全程 bash。值里若带未转义引号 → 那一行 jsonl 读不出,但不崩、不动别的行(第 -1 步容错跳过)。
- 复验/升级一格 = 再追加一轮(a + b),不是改旧格子;旧条目留作历史,第 -1 步按"概念"取
上次复验 最新那条为准。
- 绝不手写覆盖 md、绝不做 md↔jsonl 互转(互转必丢细节)。每格必带日期 + "待复验"——🟢只能标"今天理解",不是"真懂"。真懂靠第 -1 步在未来命中时复验通过——那时是追加一条
状态=已复验 的新行(不是改旧格),第 -1 步按概念取最新那条。这一步不是记录,是给未来的自己埋一个可被证伪的赌注。
第 4 步:中断即存档(真实工作随时打断学习,是常态不是 bug)
学习和任务会互相打断(干到一半想学 / 学到一半想起要干活,两个方向都会)。任一方向被打断:
- 立刻把还没挖的点 + 当前挖到哪用
>> 追加进 ~/.gan-zhong-xue/pending.md(不覆盖;脱敏,只记抽象概念)。
- 下次第 -1 步会先读它、提醒用户。绝不让"想挖的点"默默消失——那是真机那次最痛的教训。
- 一句话确认即可:"先去忙,这几个点我记下了,下次开头提醒你。"
⚠️ 地图的命门:地图会被用户信任,一旦信任就不再自校准 → 可能变成"新的委托深渊"
(连'我懂什么'都甩给地图替我记)。防线:① 地图存证据+用户自判,不是"AI 判定"
(AI 当书记员,不当法官);② 每格可被未来行为证伪、会褪色;③ 健康地图🟡🔴应一直丰富——
若绿点单调增长、黄红萎缩,是"地图崩溃"警报,不是你变强了。
自检(跑完对照,任一 NO = 跑偏了,别自我感觉良好)
明确不做(v1 的边界,别越界建大)
不挖全部深渊(一次一个);不建完整知识图谱;不做自动裁判/评分(只摆证据让用户自判);
不管多用户;五把标尺里仍只用招②(为什么这么修/排除了什么) + 招④(强制预测)。
其余留给以后——少就是多。
已知的诚实局限(写在这,别假装解决了)
- 没有干净裁判:判断型深渊("该改哪个 if"这类)无法被任何题目客观判定,裁判是时间和
线上后果。本 skill 不伪装成评分器,只训练"诚实面对自己懂没懂"。(可实证深渊有裁判:真机。)
- 仍是即时观察:一轮跑完的"懂"是当下的,真留存要隔几天用迁移题复验(靠第 -1 步跨时间做,
但需时间积累,v1 还看不到复验收益)。
- 仍是 n=1(作者自验):目前所有"它有用"的证据都来自设计者本人。要真证伪,需要独立
被试(非设计者的真人)试用——这是公开发布前唯一该补的实验,gate 是真人不是代码。
- 靶场是作者的真实工作代码:必须在用户已合规的 Claude Code 内跑,代码不出该环境。
这不是限制,是第一条设计约束。