2026-07-03
今日主题
- Tailwind 组件库边界
- 受控组件模型
- K8S DDD 建模视角
- 行编辑删除操作的颗粒度体系
- Claude Code auto mode 架构
- auto mode 分类器模型
新增认知
Tailwind 组件库边界
-
黑盒与源码:AntD 这类传统组件库是 npm 黑盒,适合快速获得 Table、Form、Modal、Tabs 等复杂后台能力;
但它内部 DOM 层级和样式封装会让 Tailwind 的 w-full、h-full、min-h-0 等布局类无法自然透传,
遇到 Tabs 等复杂组件时常需要全局 CSS 或项目级封装补洞。这个结论成立的前提是 Tailwind 被当作主要布局和样式系统,
而不是只做少量辅助 class。 -
零件与半成品:Radix UI / Headless UI 提供的是无样式交互原语,负责可访问性、键盘行为、焦点管理等底层能力;
shadcn/ui 则是在 Radix 和 Tailwind 之上组装好的可复制组件源码。二者的差别不是是否使用 Radix,而是一个给零件,
一个给已带默认样式和项目组件形态的半成品。 -
AI 维护难度:shadcn/ui 并不只是调用组件库 API,而是把组件源码放进项目后继续维护本地设计系统。AI coding 容易显得不擅长,
不一定因为训练数据少,而是它必须先理解本地 components/ui、Tailwind 规则、Radix 组合模型和项目二次封装;如果缺少边界约束,
AI 容易重复造基础组件或写出 demo 化页面。
受控组件模型
-
控制权在外:受控组件里的“受控”指关键状态受外部 props 控制,而不是组件内部自己决定。以 Dialog 为例,
传入 open 和 onOpenChange 后,用户点击关闭只是触发 onOpenChange(false),
真正是否关闭取决于父组件是否把 open 改成 false。 -
默认值只初始:非受控组件通过 defaultOpen、defaultValue、defaultChecked 只接收初始状态,
后续状态由组件或 DOM 内部维护;因此外部数据变化不会自动同步到 UI。需要提交成功关闭弹窗、URL 控制 Tab、表单回填重置、表格选中联动等业务控制时,
应使用 open/value/checked 加对应 change 回调的受控模式。 -
双模式实现:一个组件同时支持受控和非受控,通常通过判断 open/value 是否为 undefined 来决定状态来源:传了受控值就使用外部值,
没传就使用内部 useState(defaultOpen/defaultValue)。状态变化时非受控模式更新内部 state,
同时始终调用 onOpenChange/onChange 通知外部。
K8S DDD 建模视角
-
脉络:从"背 YAML kind"到"理解领域模型":K8S 几十个内置对象如果按 YAML 字典来学,只能靠死记;
但如果用 DDD 的实体/值对象/聚合/规约/限界上下文/领域事件/领域服务这套概念框架去映射,每个 kind 的职责和收敛边界就自然浮现。
这条脉络连接了以下所有具体映射,核心是声明式系统天然适合 -
Deployment→ReplicaSet→Pod 三层是不同一致性边界:Deployment 管版本和滚动发布策略,
ReplicaSet 管某个版本的副本数,Pod 管容器组。三层不是冗余,而是各自收敛不同维度的 spec 差异——
Deployment 不关心 Pod 死活(那是 ReplicaSet 的事),ReplicaSet 不关心版本切换(那是 Deployment 的事)。
这是聚合设计的关键案例。 -
Controller reconcile 就是领域服务:DDD 中"无法归属到某个实体的领域逻辑"抽成领域服务,
K8S 中 Controller 的 reconcile loop 正是这种模式——watch 事件触发、比较 spec 与 status、执行收敛操作。
这也解释了为什么自愈是"免费"的:删掉 Pod 后 status 偏离 spec,事件触发,控制器补一个,无需额外命令。 -
K8S 是最终一致而非强事务聚合:DDD 聚合强调一次修改原子地改变聚合内所有对象,但 K8S 一次 spec 修改不会原子地改变下层所有对象——
各控制器独立 watch 独立 reconcile,收敛有时间差。这个边界条件是工程上理解 Operator 行为的关键:reconcile 必须幂等可重入,
因为可能被多次触发且在中间状态执行。
行编辑删除操作的颗粒度体系
-
kill 与 yank 的本质是 kill ring:Ctrl+U/Ctrl+W 等 kill 类删除会把内容压入 kill ring,
Ctrl+Y 召回最近一条;连续 kill 会合并进同一条目,中间任何非 kill 操作(移动光标、输入字符)都会断开累积。
这是它们区别于普通 Backspace 的关键——kill 是"剪切"而非"删除"。 -
删除颗粒度分四档:
字符(Ctrl+H/D)→ 词(Ctrl+W/Meta+Backspace)→ 行(Ctrl+U/K)→ 段落(emacs 有 kill-paragraph,
终端 REPL 基本不绑)。每档都只有"向后删"和"向前删"两个方向,shell 操作几乎都是删刚敲的内容,所以向后删用得最多。 -
粗词 Ctrl+W 与细词 Meta+Backspace 的边界差异:Ctrl+W 按空白分隔,
一个 shell 参数就是一个单位(foo-bar 整段删掉);Meta+Backspace 按标点也算边界,
foo-bar 会被拆成 bar、-、foo 三次删。前者适合删 shell token,后者适合改编程标识符如 getUserById。
决定 zsh 下 Ctrl+W 实际删法的是 WORDCHARS 变量,它定义哪些字符算词内字符。 -
方向对称性缺失:Ctrl+K 是 Ctrl+U 的正向版(行尾),Meta+D 是 Meta+Backspace 的正向版(细词向前),
但 Ctrl+W 没有对应的"向前删粗词"默认绑定。同理 Meta+B/Meta+F 移动用的是细词边界,与 Ctrl+W 删的范围不一致,
这是"跳过去和删的范围对不上"的根源。 -
bash 与 zsh 的 Ctrl+U 行为不同:bash/readline 下 Ctrl+U 是 unix-line-discard(删光标到行首),
zsh/zle 默认是 kill-whole-line(删整行,继承自 csh)。跨 shell 行为不一致时用 bindkey '^U' 查当前绑定,
想改回删到行首用 bindkey '^U' backward-kill-line。
Claude Code auto mode 架构
-
架构本质是 AI 分类器代理审批:auto mode 不是简单的规则匹配或跳过权限,
而是在权限管道中插入一个独立的 AI 分类器(内部称 YOLO classifier)。权限决策流程为:安全工具白名单 → 项目内文件操作 → 分类器评估。
分类器不是主 agent 的一部分,而是独立运行的模型实例,因此不受 agent 自身推理的影响。 -
推理盲设计防止两类攻击:分类器只接收用户消息和工具调用,剥离 Claude 的思考过程和工具输出。这同时防御了两类风险——
agent 不能用花言巧语说服分类器放行危险操作,工具输出中的注入内容也无法污染分类器判断。
代价是分类器不知道 agent 从哪获取的信息(如文件名是 agent 查询到的还是编造的),但对注入鲁棒性优先。 -
两阶段分类以低 FPR 换高召回:Stage 1 是快速单 token 过滤器(max_tokens=64),指令偏向拦截,
FPR 8.5% 但 FNR 低;Stage 2 仅在 Stage 1 标记时触发,做链式推理(max_tokens=4096),将 FPR 降到 0.4%。
Stage 2 的 prompt 与 Stage 1 几乎相同(仅最后一句指令不同),因此 prompt cache 几乎全命中,推理成本很低。
端到端 FNR 约 17%(真实过激行为),适用于替代 --dangerously-skip-permissions 的场景,不是人工审核的替代品。 -
拒绝即继续而非中断:分类器拒绝不暂停会话,而是作为工具结果返回并附带原因,指示 agent 找更安全的路径。
连续 3 次拒绝或累计 20 次拒绝才升级给用户(headless 模式下终止进程)。这使 0.4% 的误报率变得可容忍——误报只消耗一次重试,
不会杀死长任务会话。 -
当前为内部功能:auto mode 是 ant-only 特性,
外部构建通过 TRANSCRIPT_CLASSIFIER feature flag 做死代码消除。
进入 auto mode 时自动剥离危险权限规则(如 Bash(*)),防止这些规则绕过分类器。
可用 Shift+Tab 循环切换或 --permission-mode auto 启动。
auto mode 分类器模型
-
默认使用 Sonnet 4.6:
Anthropic 官方博客(2026.3)明确 transcript classifier 运行在 Sonnet 4.6 上。
分类器独立于主 agent 模型,不受主对话模型选择影响。当前 Sonnet 5 已发布,分类器模型可能已更新但未重新发文确认。 -
模型选择优先级链:
环境变量 CLAUDE_CODE_AUTO_MODE_MODEL → GrowthBook 远程配置 tengu_auto_mode_config.model → 回退到主对话模型。
GrowthBook 还控制 auto mode 的可用性(enabled/disabled/opt-in 三态)和两阶段分类器的开关。 -
两阶段共享 prompt 的缓存优势:Stage 2 的 system prompt 与 Stage 1 几乎完全相同,
仅最后一句指令从"err on the side of blocking, single token decision"变为"careful reasoning"。
因此 Stage 2 的 prompt cache 几乎全命中,只在实际推理 token 上产生成本。