Claude Code 51万行源码泄露,我从里面扒出了这些Agent架构设计
上周Anthropic又翻车了。Claude Code v2.1.88的npm包里留了一个59.8MB的.map文件,1900个源文件、512000行TypeScript代码直接裸奔。13个月内第二次犯同样的错误——.npmignore没写对。
吃瓜归吃瓜,但51万行生产级Agent代码摆在眼前,不看白不看。我花了两天翻完核心模块,记录了几个值得借鉴的架构决策。
整体架构:比想象中复杂得多
先看目录结构:
claude-code/
├── coordinator/ # 多Agent协调(29000+行)
├── assistant/ # KAIROS自主模式
├── query-engine/ # 查询引擎(46000行,最大模块)
├── tools/ # 40个工具实现
├── plugins/ # 插件系统
├── skills/ # 技能按需加载
├── memory/ # 持久化记忆
├── security/ # 安全检查(2500行bash)
├── voice/ # 语音交互
├── ide-bridge/ # IDE桥接(VS Code, JetBrains)
└── system-prompt/ # 系统提示词
512000行代码分成了十几个模块。query-engine一个模块就46000行,tools目录29000行。这不是一个"套壳ChatGPT"——是一个完整的Agent平台。
技术栈也有意思:运行时用Bun(Anthropic 2025年底收购了Bun),终端UI用React + Ink做组件化渲染,数据校验全部用Zod v4。
第一个值得学的设计:用Prompt编排Agent,不用框架
coordinator/目录实现了多Agent协调,但没用LangChain、CrewAI这类框架。多个Agent各自有独立的上下文窗口和工具权限,在各自的沙箱里跑,通过Prompt来协调分工。
社区有个评论很到位:"这让LangChain看起来像是在寻找问题的解决方案。"
实际项目中我也碰过类似的选择。用框架写Agent,调试的时间比写业务的时间还长——框架的抽象层和你的业务逻辑经常打架。Anthropic的做法说明了一件事:对LLM来说,Prompt本身就是最好的编排语言。
如果你也在做Agent,先试试纯Prompt编排:
# 简化示例:Prompt驱动的Agent分工
coordinator_prompt = """
你是协调者。现在有三个任务需要并行处理:
1. 读取项目目录结构 → 交给 agent_file
2. 检查依赖版本 → 交给 agent_deps
3. 运行测试 → 交给 agent_test
每个agent完成后向你汇报,你汇总结果。
如果agent_test报告失败,让agent_file检查相关代码。
"""
核心思路:Prompt定义角色和规则,代码只负责消息传递和沙箱隔离。
第二个值得学的设计:技能按需加载
skills/目录实现了一套动态技能加载系统,工作流程是这样的:
用户输入 → 意图识别 → 技能匹配 → 按需加载领域知识 → 注入上下文 → 执行
这解决了一个实际问题:Agent的上下文窗口有限,不可能把所有领域知识都塞进去。技能系统的做法是——用到哪个加载哪个。
举个例子,你让Claude Code帮你调试Docker问题,它不会一开始就把Docker、Kubernetes、CI/CD的知识全部加载。它先识别"这是Docker相关",然后只加载Docker的技能包,把有限的上下文用在刀刃上。
这个思路可以直接搬到自己的项目里:
# 技能加载示例
skills_dir = "./skills/"
def load_skill(intent: str) -> str:
"""根据意图加载对应技能的提示词"""
skill_map = {
"docker": "docker/SKILL.md",
"git": "git/SKILL.md",
"database": "database/SKILL.md",
}
skill_file = skill_map.get(intent)
if skill_file:
with open(f"{skills_dir}/{skill_file}") as f:
return f.read()
return ""
# 使用时
user_input = "我的docker容器启动报错了"
intent = detect_intent(user_input) # → "docker"
skill_prompt = load_skill(intent)
# 把skill_prompt拼到系统提示词里,再调用LLM
第三个值得学的设计:44个功能标志管理未发布特性
泄露代码里有44个Feature Flag,控制着20多个未发布功能。KAIROS自主模式、语音交互、Undercover Mode——全部通过功能标志开关控制。
这在大型项目里很常见,但在Agent项目里用得好的不多。功能标志的好处是:代码已经在主分支上了,随时可以灰度发布,不需要维护一堆长期分支。
我在自己的Agent项目里也开始用类似的方式:
// 功能标志配置
const FEATURE_FLAGS = {
ENABLE_VOICE: false, // 语音交互
ENABLE_MULTI_AGENT: true, // 多Agent模式
ENABLE_MEMORY: true, // 持久记忆
ENABLE_AUTO_PLAN: false, // 自主规划
} as const;
// 运行时检查
if (FEATURE_FLAGS.ENABLE_MULTI_AGENT) {
await coordinator.dispatch(task);
} else {
await singleAgent.run(task);
}
好处很直接:新功能可以一边开发一边合并到主分支,不影响线上稳定性。想灰度测试?改个标志就行。
第四个值得学的设计:2500行bash做安全检查
security/目录里有2500行bash代码,专门做输入验证和命令注入防护。
为什么用bash不用TypeScript?因为Agent执行shell命令时,验证逻辑离执行层越近越安全。用bash写安全检查,直接在命令执行前拦截,少一层语言转换就少一个出错的环节。
Claude Code的安全模型分成几层:
用户输入
↓
权限检查(这个操作需要授权吗?)
↓
命令解析(提取要执行的命令)
↓
bash安全检查(命令注入检测、路径穿越检测)
↓
沙箱执行(隔离环境里跑)
↓
结果返回
如果你在做允许LLM执行命令的Agent,至少要做到两件事:
- 白名单机制:列出允许执行的命令,其他一律拒绝
- 参数检查:防止命令注入(比如用户输入里带分号、管道符)
#!/bin/bash
# 简单的命令安全检查
check_command() {
local cmd="$1"
# 检查危险字符
if echo "$cmd" | grep -qE '[;&|`$()]'; then
echo "BLOCKED: 检测到危险字符"
return 1
fi
# 白名单检查
local allowed="ls cat grep find head tail wc"
local first_word=$(echo "$cmd" | awk '{print $1}')
if ! echo "$allowed" | grep -qw "$first_word"; then
echo "BLOCKED: 命令不在白名单中"
return 1
fi
return 0
}
第五个值得学的设计:Source Map的教训
最后说说这次泄露本身的技术教训,因为这个错误太低级了。
Bun默认生成Source Map文件。Source Map的sourcesContent字段直接包含了所有原始源码——拿到.map文件就等于拿到了全部代码。
Anthropic的.npmignore里没排除*.map文件,package.json的files字段也没配对。一行配置就能防住的事情,两次都没做。
如果你在发布npm包,发布前跑一下这个检查:
# 发布前自查脚本
echo "=== 检查打包文件 ==="
npm pack --dry-run 2>&1 | head -30
echo ""
echo "=== 检查是否包含.map文件 ==="
npm pack 2>/dev/null | tar -tz | grep '\.map$'
if [ $? -eq 0 ]; then
echo "警告:包中包含.map文件!"
echo "修复:在.npmignore中添加 *.map"
else
echo "通过:没有.map文件"
fi
echo ""
echo "=== 检查包大小 ==="
npm pack 2>/dev/null | xargs ls -lh
# 如果包大小异常(比如超过10MB),大概率有问题
还有Bun用户注意一下构建配置:
# bunfig.toml
[build]
sourcemap = "none" # 生产环境禁用Source Map
总结
从Claude Code的51万行代码里,值得带走的几个实操经验:
- Agent编排用Prompt就够了,别急着上框架
- 技能按需加载,省上下文窗口
- 用功能标志管理未发布特性,别开长期分支
- Agent执行命令前必须做安全检查,白名单+参数过滤
- 发npm包之前,检查有没有.map文件混进去
Anthropic在安全上翻了车,但他们的Agent架构设计确实有东西。代码泄了不可怕,模型能力和工程迭代速度才是真正的护城河。
更多推荐

所有评论(0)