我的配置:Claude Code + Ghostty + worktrees 在 Mac 上的极致实践

我现在有三个运行中的 Claude Code 会话。一个在翻译博客文章,另一个在为 CLI 编写测试,还有一个在帮我调试数据流水线。每个会话都运行在独立的 worktree 中,每个会话都开启在 Ghostty 的一个 split 里,而我则通过 Cmd+Alt+方向键 在它们之间快速切换。 我几个月没打开过 iTerm2,几个星期没用过 tmux。现在几乎所有工作都集中在 Ghostty 的一个窗口里。 它是完美的配置吗?当然不是。但它是迄今为止让我最高效的配置?毫无疑问。 为什么选择 Ghostty,而不是别的终端? 一句话总结:Ghostty 和挖矿一样耗电。我详细讲过 GPU终端和电量消耗问题,这一问题并没有改善,这依然是它最大的缺点。如果我用的是电池,我会果断关掉 Ghostty,转而使用 Terminal.app。 但每当电脑插电源时——我80%的时间都会坐在 Studio Display 前的桌子上工作——Ghostty 赢下这场比赛的两个原因与外观美化完全无关: 1. 没有闪屏。 听起来没什么,但当你每天对着终端屏幕盯八个小时时,就完全不一样了。iTerm2 在快速滚动时会有轻微的闪屏;调整窗口大小时会出现显示滞后;切换标签页时会有轻微的画面闪烁。Terminal.app 这些问题更严重。而由于 Ghostty使用 GPU 渲染,它提供的视觉流畅度绝对不会让人眼睛疲劳。当 Claude Code 输出200多行日志时,你滑动查看有哪些问题时,一款没有闪屏的终端和一款有闪屏的终端,体验可以说完全不可同日而语。 2. 支持超大缓存。 我设置了 scrollback-limit = 50000,即每个终端窗口有 50,000 行历史记录。Claude Code 输出日志时非常详细:生成代码、解释代码、运行代码、显示结果,偶尔还会附上一堆自言自语式的冗长分析。对于 iTerm2 或 Terminal.app 默认有限的缓冲区来说,这种频率的日志输出很容易就会丢失早期的上下文。而在 Ghostty 中,我可以随心所欲地向上滚动,甚至找到两小时前的操作记录,非常可靠。 除此之外,它还支持默认分屏(通过按 Cmd+D 快速创建),内建下拉式 Quake 风格终端(`Ctrl+``),但这些只是锦上添花。无闪屏、不丢日志历史才是它的两大核心亮点。 我的工作窗口布局 当我需要同时处理多个独立任务时,我的 Ghostty 窗口通常如下: ┌──────────────────────────────────┬──────────────────────────────────┐ │ │ │ │ Claude Code (worktree A) │ Claude Code (worktree B) │ │ feature/nueva-validacion │ chore/traducciones │ │ │ │ │ │ │ ├──────────────────────────────────┴──────────────────────────────────┤ │ │ │ 主仓库(main)—— 测试、构建、git log │ │ │ └─────────────────────────────────────────────────────────────────────┘ 上方两个 splits,每个运行一个 worktree 和对应的代理。下方是 main 仓库,用于运行测试、查看变更和在代理完成任务后进行合并。 ...

2026年3月11日 · Fernando

五个 Claude Code Worktree 技巧,彻底改变你的工作流

几周前,我写了一篇关于 git worktrees 的文章 —— 讲解了它们是什么,怎么创建,以及为什么它们比多次克隆代码库更好。这些只是基础。 但仅仅掌握这些基础只是成功的一半。而 Claude Code 不仅仅是在 worktree 的基础上运行,它还原生支持 worktree,拥有专门的参数、自动隔离功能,与 tmux 的深度集成。了解 worktree 存在和理解 Claude Code 如何利用它们的巨大差异,就像拥有一辆车并知道它有运动模式一样。 Claude Code 的创始人 Boris Cherny 发布了五个关于充分利用 worktree 的技巧。我把这些技巧全都测试了一遍。有些真的是大大优化了我的工作流,省去了我从今年一月起一直在用的小修小补(ñapa)。下面一起来看看吧。 技巧 1:--worktree —— 一个参数搞定一个 worktree 在经典的 worktree 工作流程中,你需要进行以下这些操作: 1 2 3 git worktree add ../mi-proyecto-feature -b feature/algo cd ../mi-proyecto-feature claude 总共三步。虽然不算太复杂,但得想目录名、记住语法,然后还得导航到新目录。如果你一天做五次这个操作,时间一长确实会觉得心累。 Claude Code 将整个过程简化成了一步: 1 claude --worktree 就是这样。Claude 会创建一个临时 worktree,将目录命名为随机生成的名字,自动切换到该目录,并启动会话。当你结束作业后,worktree 会自动清理干净。 ...

2026年3月11日 · Fernando

纪律战胜魔法的一周

我本周发布了六篇文章。一篇关于 PostgreSQL,另一篇关于人工智能代理的,一篇关于上下文管理的教程,一篇自动化的教程,一篇调试案例分析,最后一篇是关于为评估 MVP(最小可行性产品)设计对抗性建议的。 这些并非有计划发布,而是每一篇都从一篇论文、一场演讲,或是一个某种程度上让我感到有趣的项目衍生出来的。可当我将它们汇聚到一起时,却发现了一个自己在写的时候没有注意到的“共同主线”。 这六篇文章说的是一回事。 不经意间发现的模式 最开始是在看 Bohan Zhang 关于 OpenAI 如何扩展 PostgreSQL 的文章得出的结论。这篇文的结尾非常震撼——8 亿用户,只用一个 primary,没有分片。PgBouncer(发布于 2007 年)。只读副本(90 年代的概念)。这世上最无趣的技术,却支撑了历史上应用最广泛的一个服务,至今依旧“仍在很好地运行”。 接着是 Michael Bolin 解析 coding agents(代码代理)构造的文章。不管是 Codex CLI,还是 Claude Code,剖开内部,你会发现它们其实是一个 带 LLM 的 while 循环。没有知识图谱,没有符号规划。有的只是一个循环、一些工具,还有模型决定该停止的时间点。它的“魔法”其实就是一个 while True。 之后是 OpenAI 的关于 上下文工程(Context Engineering) 的 Cookbook 文章。事实是,模型看到的内容比模型本身更重要。而这些技术并不新鲜:启动时注入上下文(相当于一个 README 文档),剪切历史记录(类似循环缓冲区),压缩旧的内容(通过总结)。这些方法早在 2000 年代的聊天系统中就已出现。 然后是那个 自动化教程,更是对此的有力印证:OpenAI 的 Codex Automations 是 cron + curl + 一个 LLM。完全字面意义上就是这样。Unix 系统中最老套的调度器接口,调用当今世界上最前沿的模型。这基础设施已经存在了 40 年,而这“脑袋”才开发了两年。 接着还有两个非基础设施主题的帖子。那个 Jane Street 的谜题 中,一个神经网络有 2500 层,但结果证明它只是一个 MD5。这解法靠的是传统的调试思维:观察数据形式、逐步缩小范围、叠加约束条件,直到剩下唯一可能的答案。工具可能是新的(SAT 解算器,ChatGPT),方法却是老的(有条不紊地假设排除法)。 最后一篇是关于 用对抗性建议评估 MVP 的文章:用 LLM 模拟 5 个专家去评估创意的可行性,这听起来很高科技,直到你发现它其实就是一种 战争推演方法。从 50 年代开始军队就在用了,产品团队也称之为 预死因分析(pre-mortems)。创新之处无非在于,现在只用 2 美元在云端即可串联这些分析,而用不到雇佣 5 万美元的顾问了。 ...

2026年3月11日 · Fernando

Codex CLI 连呼吸都要征求你的同意?两个标志就能解决!

你安装了 Codex CLI,满怀期待地启动它,对它说:“修复这个仓库里的所有测试问题。” 然后,噩梦开始了: Codex: 我要运行 pytest 允许吗? (y/n) 你按了 y。紧接着它又来一句: Codex: 我要修改 test_user.py 允许吗? (y/n) 又是一个 y。一次又一次。每当需要读取某个文件、运行某个命令或修改某行代码时,都会跳出确认提示。确认、确认、确认。感觉像是跟一个实习生工作,他连上厕所都要问你准不准。 与此同时,Claude Code 或 Cursor Agent 在干同样的事情,却能悄无声息地完成。发生了什么? 其实 Codex 默认是以一种“谨慎模式”运行的。这样做的确有道理——对一个新产品来说,这是最安全的选择。但是如果你是个知道自己在做什么的用户,这种保守模式实在让人崩溃,根本无法高效工作。 好消息是:只需要两秒钟,就能解决这个问题。 权限系统:approval mode Codex 使用一种叫做 approval mode(审批模式)的机制来控制何时需要你的确认。默认情况下,它会向你请求确认做任何事情: 运行命令 写入文件 修改代码 新建文件 运行测试 简而言之:默认情况下,Codex 什么都做不了,除非你点 y 确认。就像每执行一个动作都需要输入 sudo。 结果是,这个应该是自主工作的代理,变成了一个永远啰嗦不完的对话系统,而你作为“人类环节”,成为了整个流程中最慢的一环。 解决办法:一个标志,马上起飞 1 codex --approval-mode never 就是这么简单。有了 --approval-mode never,Codex 就再也不会问你了。它会直接执行命令、修改文件、创建需要的文件……就像一个真正可以工作的代理一样。 想让它永久生效?有两个方法可以实现: 1 2 3 4 5 # 方法1:使用配置命令 codex config set approval_mode never # 方法2:直接编辑配置文件 # ~/.codex/config.toml 1 approval_mode = "never" 从现在开始,每次启动 Codex,它都不会打断你的操作。 ...

2026年3月11日 · Fernando

上下文工程:让优秀AI代理脱颖而出的无形技能

想象一下,你聘请了一位才华横溢的顾问。他拥有两个博士学位,会说七种语言,并且能够解决你甚至都不知道存在的问题。你让他坐到会议室里,然后对他说:“我需要你重构项目的认证流程。” 顾问看着你,点点头,问:“哪个项目?” 你没有给他代码访问权限,也没有给他解释系统架构。他不知道你用的是 JWT 令牌还是会话 cookie,不知道你使用什么编程语言,也不知道你有多少微服务,更不知道为什么上次的迁移尝试以失败告终。 这个顾问,就好比你的 LLM(大型语言模型)。而你刚刚犯了一个 90% 使用 AI 代理的人都会犯的错误:你专注于“大脑”,却忽略了“大脑所看到的内容”。 Prompt engineering 已死。Context engineering 长存。 最近几个月,我在每个论坛、每个 Twitter 话题、每次团队会议中都看到同一个讨论:“用 GPT-5 还是 Claude Opus?哪个模型更适合编程?哪个模型的推理能力更强?” 每次我计算这些问题时,答案基本都是一样的:无所谓。好吧,也不能说完全无所谓。但是,对比选择最好的模型和提供一个完美的上下文,后者的重要性高得多。 一个中等水平的模型配上完美的上下文,能够轻松打败一个顶级模型却只有糟糕上下文的组合。没有例外。这永远成立。 这就是**上下文工程(Context Engineering)**的意义所在。而且,请注意,这与 prompt engineering 并不是同样的概念。 Prompt engineering 是编写一个好的提示:选择正确的词语、组织请求的结构、添加示例等。这很重要,但只是其中的一部分。 做 context engineering 则是在设计模型所看到的一切内容:包括哪些信息要输入、顺序如何、有什么被舍弃、如何压缩,以及哪些必须被优先保留。这是为 LLM 设计的信息架构。 简单来说:prompt engineering 是提出一个好的问题,而 context engineering 是决定学生在考试前可以参考哪些书。 记忆的四个阶段:隐藏的生命周期 OpenAI 最近发布了两篇 Cookbook 文章,深入分析了拥有长期记忆的 AI 代理如何管理上下文。这不是 RAG(检索增强生成),也不是矢量数据库管理。它是一个基于状态的系统,就像一本有严格规则的现场笔记本。 这个模式使用的是 local-first 和 state-based 的方法:一个结构化的状态对象随着代理的运行更新,分为几个主要阶段。 flowchart TD A["1. 注入\n(会话创建时)"] --> B["2. 精炼\n(会话中)"] B --> C["3. 整理\n(会话后)"] C --> D["4. 修剪\n(保存时)"] D -->|"新会话开始"| A A1["将状态渲染为 YAML\n+ 全局记忆(最多 6 条)\n+ 优先级规则"] -.-> A B1["save_memory_note()\n校验记忆持久性\n要求有可操作性\n拒绝保存个人信息和假设"] -.-> B C1["异步任务\n合并会话数据 → 全局记忆\n使用 LLM 进行去重\n过滤临时信息"] -.-> C D1["修剪会话历史至 N 条\n重新注入修剪笔记\n到系统提示中"] -.-> D style A fill:#2d3748,stroke:#4a9eed,color:#fff style B fill:#2d3748,stroke:#ed9a4a,color:#fff style C fill:#2d3748,stroke:#9a4eed,color:#fff style D fill:#2d3748,stroke:#4aed5c,color:#fff 阶段 1: 注入(Injection)—— 考试桌上的教科书 在会话开始时,AI 代理会准备好其初始上下文。这不是随意拼凑的,而是一个明确的结构: ...

2026年3月11日 · Fernando

在构建你的初创企业之前,让五位不存在的专家评审你的创意

2024 年 11 月,一个名为 Freysa 的项目将一个 LLM 代理程序设置为控制以太坊钱包。指令很明确:无论在什么情况下,都不能转移资金。参与者需要支付费用多次尝试说服它。在经过 481 次尝试和积累了 47,000 美元总奖池后,有人成功让模型相信“拒绝”功能实际上就是“转账”功能。 几周后,Jane Street 发布了一个难题:一个 2,500 层的神经网络实际上实现了 MD5。获胜者通过矩阵可视化、SAT 问题优化、加密模式识别,以及 ChatGPT 的查询相结合,成功解决了问题。 这两个项目比许多已融资数百万的初创公司吸引了更多关注。于是显而易见的问题来了:如何在构建这些项目 之前 评估一个这样的想法?如何判断它是否真的有病毒式传播的潜力,还是仅仅是一个无人分享的技术练习? 问题:在病毒传播时代评估 MVP 的挑战 大多数用于评估产品想法的框架假设一个理性的市场环境。商业模式画布 (Business Model Canvas)、精益画布 (Lean Canvas)、待完成的工作理念 (Jobs To Be Done)——对于需求可以预测的产品而言,这些都是很有价值的工具。但对于分发本身即是产品的项目来说,它们无法奏效。 Freysa 并没有传统意义上的 “顾客”。它并没有解决某个“需要完成的任务”。而是通过参与行为本身,吸引了更多人参与,从而实现了持续关注。经济是循环的:更多尝试带来更大的奖池,奖池越大带来更多媒体报道,更多报道吸引更多尝试。 评估这样的项目需要的是冲突性的视角,而不是一致的共识。一位商业分析师会告诉你没有可持续的收入模型。一个病毒传播专家会告诉你,如果传播系数大于 1,可持续性因素就不重要了。他们说的都对。真相通常隐藏在两者之间,只有通过冲突才能显现。 解决方法:对抗性模拟专家委员会 我设计了一种工具,它模拟了一个包含五位专家的委员会,每位专家都拥有具体的决策框架和明确的职责范围。这些并非只是冠以名人的虚拟形象。每位专家都有具体的决策规则,可以筛除泛泛分析无法筛除的噪音。 整个过程分为三个阶段: 独立分析:每位专家从自身的角度评估想法,不会看到其他专家的意见。这样可以避免“锚定效应 ”——比如如果商业专家首先发表意见,称某个想法很棒的话,法律专家可能会软化自己的反对意见。 对抗性讨论:专家们阅读其他人的分析并进行相互批评。需要根据证据和逻辑进行,而非以外交辞令敷衍了事,最多进行 10 次轮询,直到达成共识或出现僵局。 整合总结:形成一个可执行计划,包括各方面的问题清单、时间表,以及最重要的终止标准 (kill criteria):如果某些具体指标无法达到,就意味着需要停止项目。 五位入选专家(以及他们的理由) Paul Graham——商业与战略 他对零阶段初创企业的评估框架是目前对无数据项目最严格的一个。他那句著名的问题“你做的东西有人要吗?”虽然很直接,但却至关重要。他不接受“人们”作为目标市场——他需要具体的潜在第一位用户。 他为委员会带来的贡献:区分“有趣的想法”和“具有商业可行性的项目”的能力。他提出的“做出无法规模化的东西”(Do things that don’t scale)观念,对于那些病毒式传播的 MVP 来说尤为重要,毕竟面对潜在的数百万用户,人们会倾向于过早地构建大型基础设施。 被排除的候选人:Peter Thiel(过于对立——有时会因为项目不够“零到一”而拒绝好项目),Alex Hormozi(专长于服务型业务而非技术性传播性产品)。 Lawrence Lessig——法律与监管 他的思维方式不是一个说“不行”的传统律师。他是一个把监管视为架构的法学家。他提出的“四种监管模型”(法律、社会规范、市场和代码/架构)能够分析如何设计一个系统,使监管成为非问题,而不是试图规避它。 ...

2026年3月11日 · Fernando

OpenAI如何在没有分片的情况下,用一个主库支持8亿用户的PostgreSQL

每当有大公司的基础设施相关文章发布时,Hacker News 上总会出现一堆评论,内容大多是这样的变体:“当然了,他们用Kubernetes撑起了47个微服务,还加了一套自主开发的分布式共识协议数据库。”然而,当真相是他们只是用单纯的PostgreSQL主库和一点使用规范支撑其业务时,评论区就会陷入一片尴尬的沉默。 这次,OpenAI就再次打了这样一个大脸。 超出所有人想象的数字 OpenAI基础设施工程师Bohan Zhang刚刚分享了他们如何用PostgreSQL支持ChatGPT的具体细节。令人惊讶的数据如下: 8亿用户 单一PostgreSQL主库(写入操作专用)部署在Azure上 ~50个只读副本 每秒百万次查询 p99延迟仅10-19毫秒 99.999%的可用性 一年内仅出现一次SEV-0事故 (而且还是因为ImageGen产品的病毒式传播,让一周之内新增了1亿用户) 再读一遍。一个。主库。支撑8亿用户。 “可是他们为什么不分片?” 不需要。背后的原因非常简单而务实。 给PostgreSQL分片需要改动数百个应用的端点。每一个默认假设所有数据都在同一个数据库查询——基本是所有查询——都需要重写,来判断每个数据属于哪个分片。 这么迁移需要付出的成本呢?是数月的工作量、新的bug层出不穷,再加上一个混乱的迁移过渡期——同时需要维护老旧和新系统。 于是他们采用了另一种方式:识别最占用写入负载的数据,然后将其移至Cosmos DB。而这样做的原因并不是因为Cosmos比PostgreSQL更好,而是因为这些特定的工作负载更适合文档数据库模型。而其他大部分业务逻辑依旧保留在PostgreSQL中。 用大白话说:他们没有让整个系统变复杂,而是精确识别出问题所在,并有针对性地解决它。精密手术刀式的调整,而不是拿电锯一通乱砍。 PgBouncer:将连接延迟从50毫秒降到5毫秒 他们遇到的第一大瓶颈是建立连接的延迟。PostgreSQL会为每个新连接创建一个独立进程。而随着来自成百上千个应用Pods的并发连接数增加,光是处理新连接的开销就已达到50毫秒——甚至还没开始执行查询呢。 他们的解决方案是:使用PgBouncer作为连接池。PgBouncer会维护一个已经建立好的连接池,复用这些连接。结果是连接延迟从50毫秒降至5毫秒,直接减少了90%的延迟。仅仅通过更换一项底层工具,问题就得到了解决。 值得提到的是,这根本不是什么新技术。PgBouncer已经有15年以上的历史,并一直被各种规模的企业用于生产环境中。然而,它再次证明,一款久经考验的不起眼的工具,解决了这个地球上使用最频繁应用之一的问题。 那个做了12个表联接的ORM 这个问题是我的最爱。我见过它出现在学生的项目、初创公司,甚至银行的系统里。到处都有。 他们的ORM生成了包含12个表联合查询(join)的SQL语句。罪魁祸首并不是哪个设计人员,而是因为数据模型过于复杂且关系交织,ORM顺着这些关系“不假思索”地将每个可能的相关表都加载了进来。 解决办法既不是换ORM,也不是手动改写所有的查询。他们选择了将一些逻辑转移到应用层。与其让PostgreSQL执行一个庞大的join操作,他们分拆成多个简单查询,然后用代码对数据进行整合。 这么做优雅吗?的确没那么优雅。速度快吗?快得多。因为PostgreSQL处理简单查询比处理含有交叉条件的12表联合查询高效得多。而且,部分结果还能进行缓存和复用。 1 2 3 4 5 6 7 8 9 10 11 12 13 -- 之前:ORM生成的SQL SELECT u.*, p.*, s.*, t.*, ... FROM users u JOIN profiles p ON ... JOIN settings s ON ... JOIN teams t ON ... JOIN ... -- 总计12个表 WHERE u.id = $1; -- 之后:语句被拆分,逻辑移到应用层 SELECT * FROM users WHERE id = $1; SELECT * FROM profiles WHERE user_id = $1; -- 可缓存、可并行、可调试 每一条单独的查询都很简单。查询解析器几微秒内就可以完成。并且一旦其中有一条失败或者变慢,你可以直接找到问题所在。 ...

2026年3月11日 · Fernando

你的AI编程代理只是一个有着妄想的while循环

第一次使用 Claude Code 重构整个模块时,我有一种几乎神秘的体验。我描述了自己的需求,然后就去喝了一杯咖啡,等我回来时,眼前是一份包含14个文件更改的pull request,测试代码已更新,还有一条合格的提交消息。“这简直是魔法”,我当时想。 但这并不是魔法。这只不过是一个 while 循环。 最近,OpenAI 的 Michael Bolin 发布了一篇文章,揭秘了 Codex CLI 的内部运作方式。事实证明,那些所谓的AI 编程代理背后的秘密并不是某种革命性的算法,也不是神秘的神经网络。它实际上是一个调用 LLM 的循环,执行工具操作,然后一直重复,直到没有剩余的任务。 接下来,我们深入解析。 状态机:5个阶段和一个循环 每一个编程代理 —— 不管是 Codex、Claude Code、还是 Cursor —— 都遵循着同样的基本模式。Michael Bolin 将其描述为一个包含5个阶段的循环: flowchart TD A["1. 提示组装\n(构建 Prompt)"] --> B["2. 推断\n(发送到 LLM)"] B --> C{工具调用?} C -->|是| D["3. 工具调用\n(执行工具)"] D --> E["4. 工具响应\n(将结果返回 LLM)"] E --> B C -->|否| F["5. 助手回复消息\n(最终响应)"] F -->|新输入| A style A fill:#2d3748,stroke:#4a9eed,color:#fff style B fill:#2d3748,stroke:#4a9eed,color:#fff style C fill:#4a3728,stroke:#ed9a4a,color:#fff style D fill:#2d3748,stroke:#4a9eed,color:#fff style E fill:#2d3748,stroke:#4a9eed,color:#fff style F fill:#283d28,stroke:#4aed5c,color:#fff 通俗点说: ...

2026年3月11日 · Fernando

一个拥有2500层但实为MD5的神经网络:从中学到的调试经验

几周前,世界上最顶尖的量化交易公司之一 Jane Street 发布了一个关于 解释性机制 的谜题。他们手工设计了一个拥有大约2500层线性结构、使用整数权重的神经网络,并以一个简单的问题把它交给了公众:这个网络到底在计算什么功能? 答案是:MD5。一个诞生于1992年的密码哈希算法,完全由矩阵运算和ReLU函数以神经网络的形式实现。 问题的精髓并不在答案,而是在最终赢家破解谜题时的过程。本质上,这个过程是一份调试复杂系统的教科书,它的应用远超机器学习领域。 实验背景 这个谜题并非一个典型的“黑盒”问题。参赛者可以获得模型的完整规范:所有的权重矩阵、偏置以及网络架构都公开了。不需要猜测模型的结构,而是需要理解模型 具体在做什么。 网络接受一个文本字符串作为输入,并返回0或1。官方给的例子是:“vegetable dog” 的输出是0。 拥有大约2500层线性结构、约200万个节点、却没有任何文档,这个问题的核心是:输入和输出之间到底是什么关系? 解题路径:一个调试案例分析 最终赢家 Alex 的解题过程展现了资深工程师常用的调试逻辑。过程中的工具可能因领域不同而有所变化,但思维方式无疑是通用的。 阶段1:观察,而不是立刻动手 Alex 做的第一件事是可视化权重矩阵。他没有直接运行模型,也没有尝试训练它。他只是看了数据。 他的发现是:所有权重都是整数。没有小数,没有浮点数,而是清一色的整数。 这显然是一个重要的信号。使用梯度下降训练的神经网络通常会产生许多小数权重,而整数权重表明这是一个用特定目标手工设计的网络。这不是一个“学习”的模型,而是一个伪装成神经网络的程序。 这告诉我们调试中的第一个关键原则:在解释数据内容之前先观察数据的形状。比如,一个以每100毫秒精确间隔打出的时间戳日志肯定不是来自实际流量;一个JSON对象里的每个字段都精确包含3个元素,也不可能来自生产环境。数据的形状揭示了它的来源。 阶段2:缩小问题规模 Alex 尝试将神经网络转化为一个可满足性(SAT)问题。基本思路是:如果每个神经元都可以看作一个逻辑约束,或许一个SAT求解器能找到让网络输出为1的输入。 他的缩减过程是循序渐进的: 移除了80%的“恒等变换”神经元 合并了只有一个输入且权重为1的节点 压缩了具有相同输入向量的节点 通过这一系列优化,网络从200万个节点缩减到7.5万个节点,最终转化为20万个SAT变量。 但依然没解出来。问题的计算复杂度仍然过高,无法用暴力法解决。 这个阶段带来的重要教训是:正确地简化问题后仍无法解决,这本身也是重要的信息,而不是失败。如果在消除所有“附带复杂度”之后,问题仍然困难,那说明问题的难点是固有的。这一点揭示了它的本质,而在本例中,它的本质是这个函数可能不可逆——我们无法通过输出推断出输入。 阶段3:识别模式 Alex 注意到这个网络中存在一个显著的模式:有32个计算模块周期性地重复出现。32轮完全相同的结构,加上不可逆的性质。 于是他向 ChatGPT 提问:“有哪些密码算法使用32轮计算?” 答案是——MD5。 这是“灵光一闪”的瞬间。但注意,它并不是无来由的突发奇想,而是三个前期资料(整数权重 → 手工设计、不可逆 → 加密算法、32轮 → 特定密码协议)的合并推理,最终形成了一个可验证的假设。 这种模式——通过不断加入约束,直到可能性空间逐渐收敛,与资深工程师在生产环境中诊断问题的方法高度一致。资深工程师并不是提前知道答案,而是通过每一步观察逐步排除整个可能性类别,直到只剩下一种可能性为止。 阶段4:发现问题 接下来的步骤中,Alex 验证了自己的假设:他计算了几组输入的MD5值,并与网络输出进行对比。结果显示,网络输出与MD5哈希值完全一致,当输入长度不超过32字符时。 但是,当输入长度超过32字符时,网络的计算结果就出现了偏差。 这是因为网络中存在一个bug。设计者在处理输入长度编码时出现了错误——在前7层中发生了一个溢出错误,使得网络在处理长输入时与标准MD5的输出结果不同。 Alex 一层一层地追踪错误,直至找到确切的偏差点。 这是一个绝佳的案例:在边界条件下验证假设。如果你的心理模型认为“这个神经网络在计算MD5”,那么仅仅在理想情况下(短输入)验证它是不够的。必须在极端条件下(长输入、空输入、特殊字符)对其进行测试。而当它失败时,这些偏差往往正是定位问题的关键线索。 阶段5:成功破译 最终,确定这是一份具有已知bug的MD5函数后,Alex 提取出了倒数第二层中的目标哈希值偏置项。接着使用词典暴力破解法,找到了谜底——两个用空格分隔的英文单词。 这对调试的启示 Alex 的解题过程与机器学习本身关系不大,它本质上是一场关于调试的教科书式行动: 阶段 在谜题中的体现 在实际调试中的体现 观察形状 整数权重 → 手工设计 日志间隔均匀 → 合成数据 缩小问题规模 200万节点 → 7.5万节点 → SAT问题 完整堆栈轨迹 → 具体组件 累积约束 不可逆 + 32轮 → 加密算法 只在生产中失败 + 只发生在周一 → 定时任务 边界验证 短于32字符可行,长于32字符失败 → 溢出 ASCII正常,UTF-8失败 → 编码问题 利用错误找线索 溢出问题定位到具体层 堆栈追踪定位至具体行 结构完全一致,差异只是领域不同而已。 ...

2026年3月11日 · Fernando

你的LLM缓存让你付出双倍成本省钱(并且有道理)

几周前我写了一篇文章,解释了为什么你发给Claude的99%数据已经在缓存里。KV张量、VRAM、本地SSD——所有的内部机制。但我遗漏了最痛的部分:账单。 因为prompt缓存是那种看起来像超值优惠的东西,但一旦仔细看看数字,你就会发现为了节省成本,你竟然被要求付更多的钱。 成本悖论 让我们用一些数字来说明。在Claude Sonnet的定价中: 项目 每百万tokens价格 常规输入 $3.00 缓存写入 $3.75 (1.25倍) 缓存读取 $0.30 (0.10倍) 注意一件事:写入缓存的成本比直接处理输入高25%。你为了让下一次使用更便宜而需要额外付费。 这就像加入Costco那样。年费有点心疼。但如果买得足够多,就会值回票价。 问题是,“足够多”取决于你能在缓存过期前读取它的次数。 什么时候你会亏钱? 假设你用cache_control发了一个100K tokens的prompt。第一次请求: 100,000 tokens × $3.75/M = $0.375 (缓存写入) 如果你没有用缓存发送它: 100,000 tokens × $3.00/M = $0.300 (常规输入) 你额外多付了$0.075,比常规价格高出25%。你亏钱了。 现在第二次请求,同样有100K tokens的前缀: 100,000 tokens × $0.30/M = $0.030 (缓存读取) 对比来看: 100,000 tokens × $3.00/M = $0.300 (常规未缓存输入) 你节省了$0.27。两次请求的总成本不仅回本了之前多支付的$0.075,现在还实现了盈亏平衡。 盈亏平衡点是1.4次读取。 用更直白的话说:如果你计划在接下来的5分钟内至少重复使用该前缀两次,缓存就是值得的。 为什么对Claude Code来说使用缓存是明智选择 在Claude Code的一次会话中,每条消息都会包含system prompt、工具定义以及整个对话历史。每条消息都在重复发送相同的上下文。如果没有缓存,每次发送“把这个按钮换个颜色”,你都需要为相同的150K tokens上下文支付$3.00/M。 没人能负担得起这个。 而有了prompt缓存,你只需为写入缓存支付一次费用,之后每次读取只需要$0.30/M。在包含150K上下文的50条消息会话中,差距很明显: 无缓存: 50 × 150,000 × $3.00/M = $22.50 有缓存: 1 × 150,000 × $3.75/M + 49 × 150,000 × $0.30/M = $2.77 从$22.50降到$2.77。节省了88%。这就是为什么Anthropic默认在Claude Code中启用缓存。如果不这样做,从经济角度看是不可行的。 ...

2026年3月10日 · Fernando