Harness Engineering
今年以来这个Harness Engineering这个词的热度很高,最近公司一直在推AI辅助编程,所以就花了几天时间学习了下这个东西。harness这个词不是一个软件框架(比如orm的mybatis),它是一种开发的新范式,可以理解是一种指导思想、一种开发规范,本质是用来提升大模型的使用效果。 https://openai.com/index/harness-engineering/ 这篇文章提出了Humans steer. Agents execute的观点。 开发人员主要关注以下: systems(通过prompt进行系统功能、任务描述) scaffolding(脚手架设计,像架构分层及层级单向调度) leverage(好多地方翻译为杠杆,我认为的是影响力,对agent自动执行流程施加影响,按prompt交互运行)。 Harness Engineering这种工程范式体现在以下几个方面: 1、提高程序的可读性(Increasing application legibility):采取了各种辅助手段(application UI, logs, and app met...
25-架构模式总结
第 25 篇:架构模式总结 — 可迁移到你自己项目的设计模式在过去 24 篇文章中,我们逐一拆解了 Claude Code 的每个子系统——从启动链路到对话循环,从工具系统到权限防线,从 Prompt Cache 到 MCP 协议。每篇都聚焦于”这个模块是怎么设计的“。 但工程师阅读源码的终极目的不是理解别人的代码,而是把好的设计用到自己的项目里。 本篇将切换视角:不再关注 Claude Code 特有的业务逻辑,而是提取那些跨项目可复用的架构模式。这 7 个模式覆盖了从编译期优化到运行时状态管理、从工具注册到安全防线的全栈设计决策。 模式 1:编译期 DCE — 同一份代码构建多版本问题你的产品需要从同一份代码库构建出多个版本——内部版/外部版、免费版/付费版、或者面向不同客户的定制版。传统做法是维护多个分支或在运行时用 if/else 判断,前者导致合并噩梦,后者让所有版本都包含所有代码。 Claude Code 的解法利用 Bun bundler 的 feature() 函数实现编译期 Dead Code Elimination(DCE)。关键技巧是将...
24-Skill-Plugin开发实战
第 24 篇:Skill/Plugin 开发实战 — 基于源码理解扩展点为什么需要理解扩展点?Claude Code 的核心是一个 AI Agent 运行时。但不同团队、不同项目的需求千差万别 —— 有人需要自动化代码审查流程,有人需要集成内部工具链,有人需要约束 Agent 只做特定任务。 Claude Code 提供了四个层级的扩展机制,从轻量到重量依次为: 1Hook 脚本 → Skill 文件 → Agent 定义 → Plugin 包 Hook:在特定事件(工具调用前后、会话开始结束)触发 Shell 命令 Skill:一个 Markdown 文件,定义一段 prompt + 行为约束,模型可以自主调用 Agent:一个 Markdown 文件,定义一个独立的 AI 角色(有自己的 prompt、工具集、模型) Plugin:一个完整的目录包,可以同时提供 Skill、Agent、Hook、MCP 服务器 本篇将逐一解析这四个扩展点的编写方式,并指出它们在源码中是如何被发现、解析和执行的。 一、自定义 Skill 编写1.1 目录结构与发现机制Skil...
23-Memory系统
第 23 篇:Memory 系统 — AI 记忆的多层架构为什么 AI Agent 需要记忆?LLM 天生是”金鱼记忆” —— 每次对话都是从零开始。用户上次告诉 Claude “我喜欢用 bun 而不是 npm”,下次对话它就忘了。用户在项目里纠正了 Claude 三次”不要 mock 数据库”,第四次它可能又 mock 了。 这不仅仅是用户体验问题 —— 它直接影响 AI Agent 的工作效率。没有记忆的 Agent 永远是新手:每次都要重新了解用户偏好、重新踩同样的坑、重新探索同样的代码库。 Claude Code 的解决方案是一个五层记忆架构: 层级 名称 生命周期 存储位置 核心职责 1 CLAUDE.md 指令文件 永久 项目目录 / 用户目录 静态指令与规则 2 Auto Memory(memdir) 跨会话 ~/.claude/projects/<slug>/memory/ 自动提取的持久化知识 3 Session Memory 单次会话 ~/.claude/projects/<slug>/<sessi...
22-设计系统
第 22 篇:设计系统 — 终端 UI 的组件化实践为什么终端应用需要设计系统?当你用 console.log 输出几行文字时,不需要设计系统。但当你的终端应用有流式输出、多工具并行进度条、权限确认对话框、Tab 切换面板、模糊搜索选择器、dark/light 主题切换时,情况就完全不同了。 Claude Code 面对的正是这样的复杂度。它的 UI 不是静态的信息打印,而是一个高度动态的交互界面。在第 21 篇中我们看到了 forked Ink 框架如何在终端中运行 React;本篇则关注在这个框架之上,团队如何构建了一套可复用的组件化设计系统。 这套设计系统回答三个核心问题: 颜色从哪来? — 6 套主题 × 80+ 语义化颜色 token 的主题系统 组件怎么组合? — 15 个设计系统组件 + 1 个颜色工具函数的职责划分 工具 UI 怎么统一? — Tool 接口中 10 个 render/查询方法构成的 UI 协议 一、主题系统:80+ 语义化颜色 token1.1 Theme 类型:颜色的语义化契约终端应用的颜色管理比 Web 更复杂。We...
21-Ink框架深度定制
第 21 篇:Ink 框架深度定制 — 在终端中运行 React 本篇深入 Claude Code 的 forked Ink 框架(ink/ 目录,约 90 个文件),揭示如何在终端中构建一个完整的 React 渲染引擎:从自定义 Reconciler、Yoga 布局、双缓冲渲染管线,到虚拟滚动、鼠标事件、文本选择等深度定制。 为什么要 Fork Ink?Ink 是一个开源框架,让你在终端中使用 React 组件编写 UI。官方 Ink 适合简单的 CLI 工具 —— 但 Claude Code 不是简单的 CLI。它需要: 全屏模式:Alt Screen 下的完整 UI,不是”追加式”输出 虚拟滚动:对话历史可能有上千行,不能全部渲染 鼠标交互:点击、拖拽选择文本、滚轮滚动 60fps 渲染:流式输出时每 16ms 刷新一帧,不能闪烁 IME 支持:CJK 输入法需要物理光标精确定位 官方 Ink 不支持这些。Claude Code 团队 fork 了 Ink 并进行了大量深度定制,最终形成了一个功能完备的终端 React 渲染引擎。 一、架构全景:从 React 到终...
20-API调用与错误恢复
第 20 篇:API 调用与错误恢复 — 面向不可靠网络的鲁棒设计 本篇是《深入 Claude Code 源码》系列第 20 篇。我们将深入 API 调用层的错误恢复机制,看看一个生产级 AI CLI 如何在不可靠的网络环境下保持稳定运行。 为什么需要如此复杂的错误恢复?当你在本地调用一个 REST API 时,最简单的做法是失败就报错。但 Claude Code 面对的是一个远比这复杂的现实: 网络不可靠 — 用户可能在咖啡馆 WiFi、企业代理、VPN 隧道后面使用 API 容量波动 — 529 过载和 429 限流是 LLM API 的常态,不是异常 认证令牌过期 — OAuth token、AWS credential、GCP credential 都有 TTL 流式连接脆弱 — SSE 流可能在中途断开、超时、或被代理截断 多 Provider 差异 — 同一份代码要兼容 Anthropic 直连、AWS Bedrock、GCP Vertex、Azure Foundry 四种后端 如果每种错误都让用户手动重试,用户体验将是灾难性的 —— 想象你在一个需要 10 分...
19-Feature-Flag与编译期优化
第 19 篇:Feature Flag 与编译期优化 — 同一份代码构建两个产品 本篇揭示 Claude Code 如何用一套代码库同时维护内部版和外部版两个产品。你将看到 Bun 的 feature() 编译期常量折叠、process.env.USER_TYPE 构建时 --define 常量、MACRO.* 构建时值注入、以及 GrowthBook A/B 测试平台如何在不同的时间维度上协同工作。 为什么需要多层 Feature Flag?假设你是一家 AI 公司的工程师,你的产品既有面向公众的开源版本,也有内部员工使用的增强版本。内部版有更多实验性功能(语音模式、多 Agent 协调器、后台任务引擎),但你不想维护两个独立的代码仓库。 Claude Code 面临的正是这个问题。它的解决方案是三层 Feature Flag 体系,每层解决不同的问题: 层级 机制 决策时机 目的 编译期 feature() from bun:bundle 构建时 从产物中物理删除内部代码分支 编译期 process.env.USER_TYPE (--define)...
18-Hooks系统
第 18 篇:Hooks 系统 — 用 Shell 命令扩展 AI 行为 本篇是《深入 Claude Code 源码》系列第 18 篇。我们将深入 Hooks 系统的完整实现,揭示 Claude Code 如何让用户在 AI 生命周期的关键节点注入自定义逻辑,以及这套系统在安全性、可扩展性和性能上的精巧设计。 为什么需要 Hooks?想象一个场景:你希望 Claude Code 在每次执行 Write 工具后自动运行 prettier 格式化代码,或者在 Session 启动时自动加载项目特定的环境变量,又或者在模型即将结束回答时用一个验证脚本检查代码质量。 这些需求有一个共同特征:它们不是 AI 本身的能力,而是用户希望在 AI 工作流的特定节点注入的自定义行为。 Hooks 系统正是为此而生。它是 Claude Code 的”生命周期钩子”框架 —— 类似于 Git Hooks、Webpack Plugins 或 React 的 useEffect,但面向的是 AI Agent 的执行周期。用户通过 settings.json 声明:在哪个事件(event)、匹配什么条件(...
17-Settings-系统
第 17 篇:Settings 系统 — 多层配置的合并之道 本篇是《深入 Claude Code 源码》系列第 17 篇。我们将剖析 Settings 系统如何从 5 个正式配置源(加 1 个 Plugin 基底层)中读取、验证、合并配置,以及如何在运行时监听变更并热更新 —— 一个面向企业级部署的多层配置合并架构。 为什么需要多层配置?一个 CLI 工具的配置需求看似简单 —— 用户写一个 JSON 文件就行了。但 Claude Code 面对的现实远比这复杂: 个人偏好 —— 用户想全局设置自己偏好的模型、权限规则 团队共享 —— 项目组要把 MCP 服务器、Hook 脚本提交到 Git 仓库共享 本地覆盖 —— 个人本地调试需要覆盖项目设置,但不能提交到 Git 企业管控 —— 安全团队需要强制启用沙箱、禁用危险权限,且用户不能覆盖 远程策略 —— 企业管理员通过 API 远程下发配置,无需触碰每台机器 平台差异 —— macOS 用 plist + MDM、Windows 用注册表、Linux 用文件 这些需求层层叠加,任何单一配置文件都无法满足。Claude C...