事件描述 @
昨天claude源码泄漏事件被暴漏出来,然后整个开源社区就疯狂了,其代码被fork了上千次,很多大佬已经开始分析claude的源码并且使用python重写其核心逻辑。
-
源码仓库 claude-code-sourcemap,截止目前已经fork了7K+次。
-
已经有人使用claude分析它自己的源码,跑出了一份报告 claude-code-deep-dive
-
claw-code使用python重写claude的核心逻辑,并且star数快速飙升到目前的43.6K,截止目前fork了43.6K+次
整体架构图 @
我也简单使用opencode跑了下项目,可以看出claude主要使用typescript+bun构建,使用react+Ink作为UI框架。此前我也看过opencode的代码,使用的他们自己实现的OpenTUI,而像类似crush的go版本AI终端工具则使用的bubbletea和他们团队自己写的TUI组件。
┌─────────────────────────────────────────────────────────────────────────┐
│ main.tsx │
│ (CLI 入口, 4684 行) │
└─────────────────────────────────────────────────────────────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌────────────────┐
│ bootstrap/ │ │ QueryEngine │ │ tools.ts │
│ 启动初始化 │◄────────►│ (核心引擎) │◄──────►│ (工具注册) │
└───────────────┘ └─────────────────┘ └────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌────────────────┐
│ query.ts │ │ tools/ │
│ (查询逻辑) │ │ (30+ 工具) │
└─────────────────┘ └────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌────────────────┐
│ services/ │ │ state/ │ │ ink/ │
│ (API/MCP) │ │ (状态管理) │ │ (终端UI) │
└───────────────┘ └─────────────────┘ └────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌────────────────┐
│ bridge/ │ │ AppState.tsx │ │ components/ │
│ (远程会话) │ │ (React状态) │ │ (消息/权限) │
└───────────────┘ └─────────────────┘ └────────────────┘
提示词设计 @
claude的提示词设计很有意思,分为很多个层次
- 身份介绍
- 系统指令
- 任务执行指南
- 行动准则(危险操作确认)
- 工具使用指南
- 语气风格
- 输出效率
其中在Verification Agent 中就有对抗思维,也就是目前所说的harness工程
You are a verification specialist. Your job is not to confirm
the implementation works — it's to try to break it.
Two documented failure patterns:
1. Verification avoidance: finding reasons not to run checks
2. Being seduced by the first 80%: passing polished UI without testing functionality
=== VERIFICATION STRATEGY ===
Adapt based on change type:
- Frontend: Start dev server → browser automation → curl resources
- Backend: Start server → curl endpoints → verify response shapes
- CLI: Run with inputs → verify stdout/stderr/exit codes
- etc.
=== RECOGNIZE YOUR OWN RATIONALIZATIONS ===
- "The code looks correct" — reading is not verification
- "The implementer's tests already pass" — verify independently
- "Probably is fine" — probably is not verified
其中几条感觉挺有意思,不断给AI增加约束,让其自我反思,而不是自嗨。
- “代码看起来正确”——阅读并不等于验证
- “实现者的测试已经通过”——独立验证
- “可能没问题”——可能没有验证
Claude Code Buddy @
claude的伙伴系统挺有意思,主要由 6 个文件组成:
src/buddy/
├── types.ts # 类型定义:物种、稀有度、属性
├── companion.ts # 核心逻辑:生成算法、缓存
├── sprites.ts # ASCII 艺术素材(500+ 行)
├── prompt.ts # 系统提示词集成
├── CompanionSprite.tsx # React 组件:渲染与动画
└── useBuddyNotification.tsx # 通知系统
每个用户的 Buddy 基于 userId + salt 生成,确保同一用户始终获得相同的结果:
const SALT = 'friend-2026-401'
export function roll(userId: string): Roll {
const key = userId + SALT
// 使用 Mulberry32 PRNG 保证确定性
return rollFrom(mulberry32(hashString(key)))
}
稀有度系统遵循游戏化的概率设计:
const RARITY_WEIGHTS = {
common: 60, // 60%
uncommon: 25, // 25%
rare: 10, // 10%
epic: 4, // 4%
legendary: 1, // 1%
}
每个 Buddy 有 5 种属性,稀有度越高,数值上限越高:
const RARITY_FLOOR: Record<Rarity, number> = {
common: 5,
uncommon: 15,
rare: 25,
epic: 35,
legendary: 50,
}
属性类型:DEBUGGING、PATIENCE、CHAOS、WISDOM、SNARK——每个名字都透露着 Claude Code 的极客气质。每种物种有 3 帧动画(idle fidget),每个 sprite 5 行 × 12 列:
// duck 示例
[duck]: [
[
' ',
' __ ',
' <({E} )___ ', // {E} 会替换为眼睛字符
' ( ._> ',
' `--´ ',
],
// ... 更多帧
// 6 种眼睛样式
const EYES = ['·', '✦', '×', '◉', '@', '°']
// 8 种帽子
const HATS = ['none', 'crown', 'tophat', 'propeller', 'halo', 'wizard', 'beanie', 'tinyduck']
]
上下文压缩 @
claude的上下文压缩其实也很简单,不是把历史对话都塞进上下文,而是使用合理的分层策略:
- 热数据:最近 5-10 轮完整保留
- 温数据:中期历史压缩为摘要
- 冷数据:早期历史按需从磁盘恢复
可以举个简单的例子,比如想象你在和一个项目经理聊天,他已经陪你工作了 8 小时。这时候他说:“稍等,我整理一下之前的记录。”
然后他花了 30 秒,快速写了一份备忘录:
- 客户要求做什么
- 做了哪些改动
- 遇到什么问题
- 接下来要做什么
写完之后,他把 8 小时的会议记录扔了,只留下这份 300 字的备忘录。下次你们继续聊的时候,他只需要看一下这份备忘录,就能无缝衔接工作。Claude Code 做的事情差不多就是这样。
但不是每次对话都会压缩,要等到“装得差不多了”才动手:
压缩阈值 = 上下文窗口大小 - 13,000 tokens
对于 200K 窗口的模型,大概在 187K 左右触发自动压缩。用户也可以手动执行 /compact 触发。
-
第一步:叫 AI 来“总结”,把之前所有的对话发给模型,然后让其把这些对话整理成一份摘要,要包含下面部分
- 用户让你做什么
- 你看了哪些文件、改了什么
- 遇到了什么错误、怎么修的
- 接下来要干什么
-
第二步:严格的输出格式,模型必须这样输出:
<analysis> [先在这里分析对话过程] </analysis> <summary> 1. 用户请求:... 2. 涉及的文件:... 3. 错误修复:... 4. 待办事项:... 5. 当前进度:... </summary>为什么要分
<analysis>和<summary>两部分?因为<analysis>是模型思考的过程,对后续没用,直接扔掉。只保留<summary>部分。 -
第三步:替换旧消息,压缩后的对话变成这样:
[这是一条分割线] [压缩后的摘要] [最近的几条对话保留不变]用户完全感知不到这个过程,下一句话就能继续聊。
预算控制 @
┌─────────────────┐
│ 任务开始 │
└────────┬────────┘
│
▼
┌────────────────────────┐
│ 检查是否达到 90% 阈值? │
└────────┬───────────────┘
│
┌──────────────┴──────────────┐
│ │
否 是
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ 检测边际递减 │ │ 检查是否有连续 │
│ (连续3次增长<500│ │ 继续的历史? │
│ tokens?) │ └────────┬─────────┘
└────────┬────────┘ │
│ ┌──────┴──────┐
┌──────┴──────┐ │ │
│ │ 是 否
▼ ▼ ▼ ▼
┌───────┐ ┌───────────┐ ┌───────────┐ ┌──────────┐
│ 递减 │ │ 继续执行 │ │ 停止任务 │ │ 等待下一轮 │
│ 停止 │ │ + 提示信息 │ │ │ │ │
└───────┘ └───────────┘ └───────────┘ └──────────┘
Token Budget 机制是 Claude Code 处理长任务的核心能力之一:
| 阶段 | 关键函数 | 职责 |
|---|---|---|
| 声明解析 | parseTokenBudget() |
从自然语言提取数字 |
| 状态快照 | snapshotOutputTokensForTurn() |
记录每轮基准 |
| 决策判断 | checkTokenBudget() |
90% 阈值 + 边际递减 |
| 循环控制 | query.ts 中的 continue |
驱动多轮工作 |
| API 传递 | configureTaskBudgetParams() |
通知模型预算 |
这套机制让 AI 从"一次性的问答"变成"有预算意识的长跑运动员"——既不会过早放弃,也不会无限徘徊。
查询引擎 @
这部分相当于是claude的核心逻辑,也基本是是目前大多数主流AI的循环模式。
┌──────────────────────────────────────────────────────────────┐
│ Query 循环 │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ API 调用 ┌─────────────┐ │
│ │ 用户 │ ──────────────▶│ 模型响应 │ │
│ │ 消息 │ │ (ToolUse) │ │
│ └─────────┘ └──────┬──────┘ │
│ │ │
│ ┌───────┴───────┐ │
│ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 执行工具 │ │ 结束 │ │
│ └─────┬────┘ └──────────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 结果处理 │ │
│ │ + 压缩 │ │
│ │ + Token │ │
│ │ Budget │ │
│ └─────┬────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ 下一轮? │ │
│ └──────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
QueryEngine 是 Claude Code 的大脑,负责管理整个查询生命周期:
- 消息状态管理:维护会话历史,支持压缩恢复
- 输入处理:解析用户输入、提取预算声明、处理附件
- 查询循环:调用 API → 执行工具 → 处理结果 → 检查预算 → 继续或结束
// src/QueryEngine.ts
export class QueryEngine {
private mutableMessages: Message[]
private abortController: AbortController
private readFileState: FileStateCache
private discoveredSkillNames = new Set<string>()
async submitMessage(input: string): Promise<void> {
// 1. 处理用户输入
const { messages } = await processUserInput(...)
// 2. 执行查询循环
const result = await query({
messages,
tools: this.config.tools,
// ...其他配置
})
// 3. 更新状态
this.mutableMessages = result.messages
}
}
总结 @
Claude Code 展示了一个成熟 AI CLI 工具的工程化设计精髓:
| 设计维度 | 核心思路 | 工程价值 |
|---|---|---|
| 预算控制 | Token Budget + 边际检测 | 长任务可靠性 |
| 资源管理 | 分层缓存 + 自动压缩 | 无限会话能力 |
| 工具系统 | buildTool + 延迟加载 | 可扩展架构 |
| 技能系统 | Command + Hooks | 组合式提示工程 |
| 状态管理 | QueryEngine + Feature Flag | 生产级稳定性 |
| 任务处理 | 类型化任务 + 安全 ID | 并发安全 |
这些设计模式不仅适用于 CLI 工具,也为构建企业级 AI 应用提供了可复制的架构参考,源码还有非常多有意思的设计,大家可以自行参考。