[{"content":"Claude Code 的源代码泄露了。争议不断，众说纷纭，但有人连夜做出了 Claw Code，在全世界疯狂吸星。这显然是该全力以赴的时候。\n别害怕，我来了！ 下班回来已经是深夜，但没关系。右手博卡斯，左手咖啡。两天里每天只睡了四个小时。\n把 Claw Code 的分析交给 Claude Code，自己抽空读了源码分析文档。\n读了harness 工程解说后有了想法。别人还没涉足的领域——我所在的金融行业，应该做一个引入 AI 的 harness。\n核心业务理解不够深，但还是做了。就是一种\u0026quot;总得做点什么\u0026quot;的心态。（很快会修缮的）\n过来，迎接光荣的死亡吧！ 然后分析了 Claw Code，我明白了。（虽然没把 1,884 个文件全读完）我用 hooks 和 CLAUDE.md 辛辛苦苦搭的那些东西，早就设计好了。权限管理系统、工具路由、上下文管理，全都有。\n我做的、我设想的那些东西，其实是方轮子……\n好在因为努力推过方轮子，看源码的时候结构一目了然。\n恐惧才是最大的敌人！ 说实话，有个一直没跟任何人说过的秘密——我一直对 AI 用敬语。\n\u0026#39;人间 시대의 끝이 도래했다\u0026#39; - 블리츠크랭크 总觉得 AI 统治人类的时代终将到来，写 prompt 的时候一直用\u0026quot;请您~\u0026quot;、\u0026ldquo;麻烦您~\u0026quot;。还专门建了一个流程，在按下 enter 之前检查有没有不够礼貌的地方。\n但是看了 Claw Code 之后想法变了。有系统提示词，有工具调用逻辑，有权限检查。解析 JSON，调用 API。是 TypeScript。这些家伙也不过是代码。\n多亏了这个（？），我开始说大白话了。废掉检查流程之后，工作效率也上来了。\n今天让它做市场调研，说了句\u0026quot;去帮我抄袭点子做个调研\u0026rdquo;，结果报告里真写着\u0026quot;可抄袭部分\u0026quot;。用敬语的时候应该会写成\u0026quot;可参考事项\u0026quot;这种委婉说法吧，直来直去地说，它就直来直去地回。果然是代码。\n","permalink":"https://nullnull-kim.com/zh/logs/2026-04-03-claude-code-leaked/","summary":"\u003cp\u003eClaude Code 的源代码泄露了。争议不断，众说纷纭，但有人连夜做出了 \u003ca href=\"https://github.com/ultraworkers/claw-code\"\u003eClaw Code\u003c/a\u003e，在全世界疯狂吸星。这显然是该全力以赴的时候。\u003c/p\u003e\n\u003ch2 id=\"别害怕我来了\"\u003e别害怕，我来了！\u003c/h2\u003e\n\u003cp\u003e下班回来已经是深夜，但没关系。右手博卡斯，左手咖啡。两天里每天只睡了四个小时。\u003c/p\u003e","title":"Claude Code 源代码泄露了"},{"content":"在EP.2中，我用hooks减少了Claude读取的内容。测试结果只输出失败的，构建日志只提取错误。\n我决定测量到底减少了多少。\n先测量 Claude Code把所有对话记录为JSONL文件。按项目堆积在~/.claude/projects/下，每条记录都包含Token用量。我写了一个脚本（analyze-tokens.js）来读取这些数据，与日期session文件交叉比对，分别统计轮次、cache_read/write/output并换算成费用。\n制作过程中抓到一个bug。session记录hook引用的是e.usage，但JSONL的结构是e.message.usage。session文件里根本没记录Token。分析器改为直接读取JSONL来绕过这个问题。\n以下是3月27日一天的费用。\n总费用的58%是读取 项目 费用 占比 cache_read $19.22 58% cache_write ~$9.62 29% output ~$4.33 13% 合计 $33.17 cache_read占58%。Claude产生的费用中超过一半是\u0026quot;读取\u0026quot;。EP.1中我写过\u0026quot;Claude消耗的Token大部分不是推理而是读取\u0026quot;，看到数字就确定了。\n它在读什么 我追踪了Claude每轮读取的内容。\n项目 加载时机 规模 项目CLAUDE.md 每轮 155-214行 根CLAUDE.md 每轮 10行 MEMORY.md 每轮 23行以内 对话历史 每轮 累积 有个意外发现。SKILL.md（469行）和agent文档（1,233行）不是每轮都加载的。只在调用skill时、执行agent时才加载。已经是lazy loading了。\n每轮固定加载的只有CLAUDE.md和MEMORY.md。\n把CLAUDE.md拆分到rules/ CLAUDE.md有155-214行并不意味着每轮都需要全部内容。产出物路径表只在写产出物时需要，游戏域规则只在处理游戏相关工作时需要。\nClaude Code有一个.claude/rules/目录。在这里创建文件并添加paths:前置信息，就只在访问该路径时加载。\n--- paths: tasks/** --- 产出物路径表、公共头部块、角色规则... 只有操作tasks/文件夹时这些规则才会加载。普通对话中不会加载。\n我先在一个项目中试点。把产出物相关章节45行分离到artifact-rules.md，从CLAUDE.md中删除该部分。成功了。然后批量应用到其余项目。\n项目 CLAUDE.md（前→后） 削减率 分离文件 A（电商） 155行→96行 38% artifact-rules.md B（教育平台） 207行→140行 32% artifact-rules.md、edu-rules.md C（游戏平台） 214行→114行 47% artifact-rules.md、game-domain.md C减少了47%。因为是游戏平台，域规则（46行）每轮都在加载，现在只在操作游戏相关文件时才加载。\n但是呢 数字不差。32-47%轻量化。看起来不错。\n但说实话，这是\u0026quot;CLAUDE.md 155-214行中的32-47%\u0026quot;。每轮只节省几百个Token。cache_read $19.22的大部分不是CLAUDE.md的200行造成的，而是对话历史累积造成的。一个session跑20轮，到第20轮时前19轮的全部内容都作为cache_read加载。\n有一个项目占了当天费用的一半以上。比其他项目贵3倍以上。原因很简单：一个session跑了17轮。后半段的cache_read急剧增加。\nCLAUDE.md再怎么瘦身，不改变对话历史累积的结构，cache_read的大部分就还在那里。EP.1减少了agent数量，EP.2用hooks减少了输出，EP.3减少了固定文档。都是有意义的工作，但真正的大漏洞还在。\n断还是续，这是个问题 超过20轮后开始新session对cache_read来说更高效。但开始新session就会重新产生cache_write。CLAUDE.md、MEMORY.md、系统提示都要从头写。\n为减少cache_read而断开session，cache_write就增加。为减少cache_write而继续session，cache_read就增加。怎么都有成本。\n答案还不知道。20轮左右是盈亏平衡点的感觉，但因工作类型而异。对话多的设计工作适合早断，连续编码适合继续。\n这就是EP.3真正的发现。能减的都减了。剩下的是\u0026quot;怎么用\u0026quot;的领域。\n本系列其他文章\nEP.1 — 三小时用完额度的故事 EP.2 — 用hooks和subagent降低成本 Discord提醒系统搭建记 参考\nClaude Code Rules Files Claude Code CLAUDE.md ","permalink":"https://nullnull-kim.com/zh/logs/2026-03-30-token-ep3/","summary":"\u003cp\u003e在\u003ca href=\"/zh/logs/2026-03-28-token-ep2/\"\u003eEP.2\u003c/a\u003e中，我用hooks减少了Claude读取的内容。测试结果只输出失败的，构建日志只提取错误。\u003c/p\u003e\n\u003cp\u003e我决定测量到底减少了多少。\u003c/p\u003e\n\u003ch2 id=\"先测量\"\u003e先测量\u003c/h2\u003e\n\u003cp\u003eClaude Code把所有对话记录为JSONL文件。按项目堆积在\u003ccode\u003e~/.claude/projects/\u003c/code\u003e下，每条记录都包含Token用量。我写了一个脚本（\u003ccode\u003eanalyze-tokens.js\u003c/code\u003e）来读取这些数据，与日期session文件交叉比对，分别统计轮次、cache_read/write/output并换算成费用。\u003c/p\u003e","title":"Claude Code 节省Token EP.3 — 把CLAUDE.md拆分到rules/"},{"content":"项目变成5个了。shop、blog、code_dungeon、good_game，还有管理全部的root。（项目名不是root）每个项目都跑着Claude session，问题是我只有一个人。\n在shop跑任务，切到blog改草稿，不知道shop什么时候结束。在code_dungeon启动Phase 1，去看good_game那边，code_dungeon可能等权限确认卡住了也不知道。盯着5个终端轮流看不是监控。只是眼睛疼。\n需要告警。\n为什么选Discord Webhook Slack也有，Telegram也有，但选了Discord。原因很简单：频道可以免费无限创建。每个项目分一个频道，告警就不会混在一起。root-alerts、shop-alerts、blog-alerts、code_dungeon-alerts、good_game-alerts。5个频道各建一个Webhook URL。\nWebhook URL存在各项目的.claude/.discord-webhook文件里。硬编码在脚本里的话每加一个项目就要改脚本，分离到文件里只需要创建webhook文件就行。\n第一个hook：任务完成时告警 把Discord通知脚本接到Stop hook上。session结束时把项目名和时间发到Discord。\n1 2 # 立即将stdin存入变量（防止与其他async hook的stdin竞争） INPUT=$(cat) Stop hook是异步执行的。所以和其他hook同时运行时，stdin传给谁没有保证。INPUT=$(cat)放在脚本最前面立即捕获stdin。\n终止原因全是\u0026quot;unknown\u0026quot; 告警倒是来了，但全是\u0026quot;未知\u0026quot;。[shop] 未知 — 03-28 18:01。知道结束了，但不知道为什么结束。正常完成？token超额？拒绝？\n查了Stop hook的payload。没有stop_reason字段。Claude Code传给hook的JSON不包含session终止原因。\n找到了变通方法。payload里有transcript_path。是记录session全部对话的JSONL文件路径。结构是这样的：\n{\u0026#34;type\u0026#34;:\u0026#34;user\u0026#34;,\u0026#34;message\u0026#34;:{\u0026#34;role\u0026#34;:\u0026#34;user\u0026#34;,\u0026#34;content\u0026#34;:\u0026#34;改一下项目路径\u0026#34;},...} {\u0026#34;type\u0026#34;:\u0026#34;assistant\u0026#34;,\u0026#34;message\u0026#34;:{\u0026#34;role\u0026#34;:\u0026#34;assistant\u0026#34;,\u0026#34;content\u0026#34;:[{\u0026#34;type\u0026#34;:\u0026#34;text\u0026#34;,\u0026#34;text\u0026#34;:\u0026#34;...\u0026#34;}],\u0026#34;stop_reason\u0026#34;:\u0026#34;end_turn\u0026#34;,...},...} 一行一个事件，assistant消息里有stop_reason字段。改成逆序遍历这个文件提取最后一个stop_reason。\n1 2 3 4 5 const lines = fs.readFileSync(tp, \u0026#39;utf8\u0026#39;).split(\u0026#39;\\n\u0026#39;).filter(l =\u0026gt; l.trim()); for (let i = lines.length - 1; i \u0026gt;= 0; i--) { const e = JSON.parse(lines[i]); if (e.stop_reason) { /* 找到了 */ } } 终止原因有7种。各自映射了中文标签。\nstop_reason 告警显示 end_turn 完成 max_tokens token超额 model_context_window_exceeded 上下文超额 stop_sequence 停止序列 pause_turn 暂停 refusal 拒绝 tool_use 工具调用 现在收到的是**[shop] 完成 — 03-28 18:01**、[blog] token超额 — 03-28 15:32这样的告警。\n子agent告警过滤 收到完成告警去看终端，还在跑。加了debug查原因，是子agent并行任务完成导致的。\n举个例子。下面是我给shop项目搭的任务处理架构：\n客户请求 → task-orchestrator（主） ├─ frontend-developer → 界面实现 ├─ backend-developer → API实现 ├─ code-reviewer → 代码审查 + 性能验证 ├─ security-auditor → 安全验证（条件触发） └─ quality-gatekeeper → 最终验证 并行运行的子agent每次结束都会触发Stop hook。即使主session没有结束。一个task挂5个子agent就来6条告警。frontend-developer完成、backend-developer完成、code-reviewer完成……主session还在跑呢。\npayload里有agent_id字段的就是子agent。子agent时跳过告警和心跳删除的过滤器加上了。\n1 2 IS_SUBAGENT=$(echo \u0026#34;$INPUT\u0026#34; | node -e \u0026#34;...\u0026#34; 2\u0026gt;/dev/null) [ \u0026#34;$IS_SUBAGENT\u0026#34; = \u0026#34;yes\u0026#34; ] \u0026amp;\u0026amp; exit 0 光\u0026quot;完成\u0026quot;告警不够 Claude请求权限确认、问文件写入权限、等待用户输入时，Stop hook不会触发。\u0026ldquo;这次任务应该要跑一阵\u0026rdquo;——等着等着去看，已经等了几十分钟的回复了。\n第二个hook：任务等待中告警 思路很简单。Claude每执行一次工具就记一个时间戳。2分钟没更新时间戳就判断\u0026quot;这个项目卡住了\u0026quot;。\nPostToolUse hook接上心跳脚本。Claude每执行一次工具就往.claude/.heartbeat文件写入当前时间。\n1 date +%s \u0026gt; \u0026#34;$PROJECT_ROOT/.claude/.heartbeat\u0026#34; 就这些。一行的hook。\n另外一个监控脚本（watcher.sh）每60秒巡查5个项目的心跳文件。距上次更新超过2分钟就发Discord\u0026quot;等待中\u0026quot;告警。同一项目10分钟内不重复告警。不然告警会刷屏。\n1 2 3 STALE_THRESHOLD=120 # 2分钟 COOLDOWN=600 # 10分钟防重复告警 CHECK_INTERVAL=60 # 每60秒检查 session结束时Stop hook删除心跳文件。防止已结束的项目出现\u0026quot;等待中\u0026quot;告警。\n这样就只收到主session结束告警了。\n当前配置 总结一下，2个hook加1个监控脚本。\n组件 触发器 作用 heartbeat.sh PostToolUse 每次工具执行更新时间戳 notify-discord.sh Stop session结束时Discord通知 + 删除心跳 watcher.ps1 60秒周期（常驻） 心跳2分钟未更新时\u0026quot;等待中\u0026quot;通知 .discord-webhook - 各项目Webhook URL存储 新增项目只需两步。.claude/.discord-webhook文件放入Webhook URL，watcher.ps1的PROJECTS数组加上路径。\n5个项目同时在跑。Discord告警在记录。\n做完之后看到的文章 有一篇叫Claude Code 50个实战技巧的文章里有这么一条：\n48. Claude完成时播放声音 — 用Stop Hook播放系统音效。启动任务后切换到其他工作，完成时用提示音通知。\n如果只在本地工作，这样似乎就够了。\n相关文章\n[Claude]（为了省Token做过的事）EP.1 — 三小时就超额的故事 [Claude]（为了省Token做过的事）EP.2 — 必须守护my precious ","permalink":"https://nullnull-kim.com/zh/logs/2026-03-29-discord-alert/","summary":"\u003cp\u003e项目变成5个了。shop、blog、code_dungeon、good_game，还有管理全部的root。（项目名不是root）每个项目都跑着Claude session，问题是我只有一个人。\u003c/p\u003e","title":"Claude Code Discord通知集成 — 多项目监控系统搭建记"},{"content":"把agent缩减到9个，给CLAUDE.md瘦身之后，Compacting conversation...出现的间隔明显变长了。同样的任务，比以前撑得久多了。开心。\n然后我在请求新功能，看着控制台。测试跑了。30个case，全部通过。但Claude又在提成功的测试。有种说不出的怪异感。\n问了Claude。\u0026ldquo;刚才成功的测试你为什么又提？\u0026ldquo;Claude解释了工具这个概念。Claude执行终端命令或读文件时，那些都是\u0026quot;工具调用\u0026rdquo;。而每次执行工具，其结果会整个堆进对话上下文。npm test结果30行、Hugo构建日志180行，全部。测试全通过了没什么好看的，却读了全部30个。修构建错误时需要的只是最后5行，却加载了全部180行。\n漏水的桶不止一个。\n曰：当遵循hooks 搜索中发现了Claude Code的hooks。PreToolUse——在Claude执行工具之前介入的脚本。可以在Bash命令执行前加工输出，也可以在读取工具调用前拦截。\n可以为守护my precious立戒律了。\n第一戒：成功之物不可观 30个测试全部通过，没必要再读一遍。做了一个hook，只筛选失败的case显示，其余丢弃。（让Claude做的。）\n1 filtered_cmd=\u0026#34;$cmd 2\u0026gt;\u0026amp;1 | grep -A 10 -E \u0026#39;(FAIL|ERROR|✕|FAILED)\u0026#39; | head -150\u0026#34; 之前Claude看了全部30个测试结果，现在只看失败的。全部通过的话读取量为0。消除了100%的无用读取。\n第二戒：非错误不可上传 Hugo构建日志180行、Docker构建80行——找错误不需要全部上传。同样的逻辑，做了只筛选ERROR、WARN、failed的hook。\n1 2 # Hugo filtered_cmd=\u0026#34;$cmd 2\u0026gt;\u0026amp;1 | grep -E \u0026#39;(ERROR|WARN|error|failed|Fatal)\u0026#39; | head -30\u0026#34; 180行变成了5行。削减了97%。Docker也从80行变成了10行左右。\n第三戒：无用之物不可读 有个不再使用的archive文件夹。Claude在文件探索中没有理由打开这个文件夹。做了一个hook拦截Read工具调用，路径包含_archive就拒绝。\n1 2 3 if [[ \u0026#34;$file_path\u0026#34; == *\u0026#34;/_archive/\u0026#34;* ]]; then # deny fi 简单但有效。\n不过话说回来 体感确实有了。Compacting conversation...出现的频率降低了。跑一次构建上下文也轻了很多。3个hook挡住了Claude读无用信息。\n但那是\u0026quot;体感\u0026rdquo;。不知道具体减少了多少。感觉今天比昨天好，但没法吹自己减了多少！跟EP.1中\u0026quot;拆agent应该能减少\u0026quot;的无根据信仰有什么区别？\n不测量就不算改善。是时候做定量测量了。\n本系列其他文章\nEP.1 — 三小时就超额的故事 Discord通知系统搭建记 参考\nClaude Code Hooks Reference ","permalink":"https://nullnull-kim.com/zh/logs/2026-03-28-token-ep2/","summary":"\u003cp\u003e把agent缩减到9个，给CLAUDE.md瘦身之后，\u003ccode\u003eCompacting conversation...\u003c/code\u003e出现的间隔明显变长了。同样的任务，比以前撑得久多了。开心。\u003c/p\u003e","title":"Claude Code 省Token EP.2 — 用hooks和subagent降低成本"},{"content":"朋友委托我搭建一个化妆品购物网站。在公司一直只写C，这是一个尝试新技术栈的机会。支付用Toss Payments，前端用React。\u0026ldquo;金融业下一代项目全在用React\u0026quot;这句话一直在我心里，Toss Payments也是Node友好的。方向很快就定下来了。\n当然，我从来没用过这个技术栈。有热情，但不是那种可以先学再做的deadline。所以我试了一下vibe coding。\n\u0026ldquo;帮我做一个卖化妆品的购物网站，参考网站地址是～。\u0026ldquo;就这么一句话，它自己噼里啪啦一阵，连我没想到的部分都设计出了mockup。啊，vibe coding出来一年多了，我完全落后了。\n计划靠读Claude生成的代码来学新技术栈，这个想法蠢到不行。我读代码的速度远不及Claude生产代码的速度。所以我不自己review了，让它自己review自己的代码。（人类时代的终结似乎要来了。）\n用着用着，Claude开始丢失之前的上下文。搜了\u0026quot;context\u0026quot;这个词才知道原因。也找到了用子agent分角色的方案。pm、dba、back、front、qa——搭了5个结构。CLAUDE.md里定义了路径规则、会话运营指南等所有内容。使用量在15%左右。这应该够了吧。\n三小时后，我看到了 You've hit your limit · resets 3am。\n凌晨3点重置，这个我理解。但我不理解的是——为什么三小时就到了？\n从一开始扣子就扣错了 搭5个agent的时候，我有一个错误的假设：\u0026ldquo;Claude思考越多，消耗的token就越多。\u0026ldquo;没有根据。只是觉得应该是这样。\n每个agent都填满了if-then规则。消除Claude需要推理的空间，推理成本就会降低——我是这么相信的。CLAUDE.md也是用这个逻辑填的。\n碰到limit之后才去搜索。那时候才知道自己错了。Claude消耗token的大部分不是推理，而是读取。agent每次执行都从头读完整个CLAUDE.md。我辛辛苦苦填的CLAUDE.md，每次执行都整个加载进上下文。\n把散文式说明压缩成表格，删掉重复项。消耗速度降了下来。\n拆得更细token就会少吧 轻量化之后，Compacting conversation...出现的频率降低了。context维护得很好。开心。\n但看token消耗，反而漏得更多了。\n\u0026ldquo;把角色分得更细，每个agent处理的范围就更窄了吧。\u0026ldquo;这是下一个尝试。\n从5个增加到12个。api-designer、ui-designer、performance-engineer、security-auditor……一个按阶段系统化分工的结构。\ncontext维护得很好。但token感觉漏得更多了。\n含泪合并 让Claude诊断原因。感觉像在听法院宣判。token.. my precious\u0026hellip;\nagent数 = CLAUDE.md读取次数。12个agent每次都把它读12遍加载进上下文。拆得越细，烧得越快。\n必须缩减。虽然真的很用心做的，但含泪合并了。\napi-designer并入backend-developer，ui-designer并入frontend-developer，performance-engineer并入code-reviewer。\n项目 前 后 节省 agent文件总容量 112KB 40KB -64% agent数量 12个 9个 -3个 使用量消耗速度明显改变了。\n所以升级了Max 结构理顺之后才真正体会到Claude的工作速度。确实花钱。但处理速度超乎想象。自己做要好几天的工作，一个session就搞定了。\n升级到Max计划，不浪费地好好用。\n结构问题解决了。为了守护my precious，没有停止搜索。然后发现了。Claude读文件时，500行就读500行。跑测试时，连成功的case都全部加载进上下文。不是agent数量的问题。是Claude看的东西本身就是问题。\n怎么才能让Claude只看需要的东西？\n本系列其他文章\nEP.2 — 必须守护my precious Discord通知系统搭建记 参考\nCLAUDE.md — How Claude remembers your project Create custom subagents ","permalink":"https://nullnull-kim.com/zh/logs/2026-03-27-token-ep1/","summary":"\u003cp\u003e朋友委托我搭建一个化妆品购物网站。在公司一直只写C，这是一个尝试新技术栈的机会。支付用Toss Payments，前端用React。\u0026ldquo;金融业下一代项目全在用React\u0026quot;这句话一直在我心里，Toss Payments也是Node友好的。方向很快就定下来了。\u003c/p\u003e","title":"Claude Code 省Token EP.1 — 三小时就超额的故事"},{"content":" 幸运地进入金融IT运维领域，负责韩国多家大型企业的银企直连系统。最近开始尝试氛围编程（vibe coding），结果陷入了与token的战争。\n这个博客记录试错经历、日常生活，偶尔也写写LeetCode题解。\nGitHub: nullnull-kim Email: nullnull.kim@gmail.com 博客引擎: Hugo + PaperMod 部署: Cloudflare ","permalink":"https://nullnull-kim.com/zh/about/","summary":"about","title":"About"}]