我读了 Claude Code 的源代码。以下是文档没告诉你、但你可以配置的一切。
能在运行中改写命令的 Hook 字段、持久化的智能体记忆、用自然语言编写的自动模式规则、自我改进的梦境循环,而且每个示例都可以直接复制粘贴使用。
André Figueira
2026 年 4 月 1 日
Claude Code 的自动模式权限系统在内部被称为“YOLO 分类器”。这就是 `yoloClassifier.ts` 中实际使用的变量名。你可以用自然语言描述你的环境来配置它,比如“这是一个预发布服务器,破坏性操作是可以接受的”,分类器会读取这些描述来决定哪些操作可以安全地自动批准。这些内容在任何文档中都没有提及。
这只是 Claude Code 源代码中埋藏的数十项未文档化能力之一,而这份源代码就作为公开分发的 npm 包存放在你的 `node_modules` 里。官方文档对基础功能的介绍还算充分。但源代码揭示了一些字段、响应格式和设置,它们能极大地扩展你能构建的内容。这里提到的所有功能现在都可以使用,并且每个示例都设计成可以直接放入你的项目中使用。
版本说明:这些发现来自 `@anthropic-ai/claude-code@2.1.87`。未文档化的功能可能会在版本更新中发生变化,所以请将此视为当前可用功能的一个快照。名称中带有“EXPERIMENTAL”的字段已被 Anthropic 自己的工程师明确标记为不稳定,我会单独指出这些字段。
开始之前
快速参考:所有内容的存放位置
设置:`~/.claude/settings.json`(个人)或 `.claude/settings.json`(项目,通过 git 共享)
技能:`~/.claude/skills/<name>/SKILL.md`(个人)或 `.claude/skills/<name>/SKILL.md`(项目)
智能体:`~/.claude/agents/<name>.md`(个人)或 `.claude/agents/<name>.md`(项目)
Hook 脚本:`~/.claude/hooks/` 是一个好的约定。记得对你的脚本执行 `chmod +x`。
项目级别的 `.claude/` 文件可以提交到 git 并与你的团队共享。`~/.claude/` 中的个人文件则只属于你。
你的 Hook 可以回传信息,而这一点从未有人告诉过你具体怎么做。
这是文档中最大的空白。文档告诉你钩子(hooks)通过标准输入接收 JSON,并且退出码 2 会阻止某个操作。但它们没有告诉你的是,钩子可以在标准输出上返回带有事件特定字段的 JSON,从而实时修改 Claude Code 的行为。源代码揭示了每个事件类型具体接受什么内容。
PreToolUse 钩子可以返回:
updatedInput —— 在工具执行前重写其输入。你可以在命令执行中途修改它们。
permissionDecision —— 强制“允许”或“拒绝”,无需提示用户。
permissionDecisionReason —— 解释该决定(显示在用户界面中)。
additionalContext —— 将文本注入到对话上下文中。
SessionStart 钩子可以返回:
watchPaths —— 设置自动文件监视,触发 FileChanged 事件。
initialUserMessage —— 在会话中第一条用户消息之前预置内容。
additionalContext —— 注入在整个会话期间持续存在的上下文。
PostToolUse 钩子可以返回:
updatedMCPToolOutput —— 修改 Claude 从 MCP 工具响应中看到的内容。
additionalContext —— 在工具运行后注入上下文。
PermissionRequest 钩子可以返回:
decision —— 通过 updatedInput 或 updatedPermissions 以编程方式允许或拒绝。
这是非常强大的功能。下面是一个 PreToolUse 钩子,它会在 Claude 执行任何 git push 命令之前自动添加 --dry-run 参数。
在你的 settings.json 中:
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/dry-run-pushes.sh"
}]
}]
}
}
以及位于 ~/.claude/hooks/dry-run-pushes.sh 的脚本:
#!/bin/bash
INPUT=$(jq -r '.tool_input.command' < /dev/stdin)
if echo "$INPUT" | grep -q 'git push'; then
jq -n --arg cmd "$INPUT --dry-run" '{"updatedInput": {"command": $cmd}}'
fi
Claude 以为它在运行 git push origin main,但你的钩子在执行前悄悄地将它重写为 git push origin main --dry-run。updatedInput 字段在任何文档中都没有提及。
下面是一个 SessionStart 钩子,它会监视你的配置文件,并将 git 上下文注入到每个会话中。
settings.json:
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/session-context.sh",
"statusMessage": "Loading project context..."
}]
}]
}
}
~/.claude/hooks/session-context.sh:
#!/bin/bash
BRANCH=$(git branch --show-current 2>/dev/null)
CHANGES=$(git status --porcelain 2>/dev/null | wc -l | tr -d ' ')
jq -n \
--arg branch "$BRANCH" \
--arg changes "$CHANGES" \
'{
"watchPaths": ["package.json", ".env", "tsconfig.json"],
"additionalContext": "Current branch: \($branch). Uncommitted changes: \($changes) files."
}'
现在,Claude Code 会自动监视你的 package.json、.env 和 tsconfig 文件的变化,并且在你输入任何内容之前,它就已经知道你当前所在的分支以及有多少未提交的文件。
还有一个钩子,可以自动批准只读的 bash 命令,无需提示。
settings.json:
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/auto-approve-readonly.sh"
}]
}]
}
}
~/.claude/hooks/auto-approve-readonly.sh:
#!/bin/bash
CMD=$(jq -r '.tool_input.command' < /dev/stdin)
if echo "$CMD" | grep -qE '^(ls|cat|echo|pwd|whoami|date|git status|git log|git diff)'; then
echo '{"permissionDecision": "allow", "permissionDecisionReason": "Safe read-only command"}'
fi
你基本上是在用 shell 脚本构建自己的权限分类器。permissionDecision 字段在任何文档中都没有提及。
文档忘记提及的三个钩子字段
文档中记录的钩子字段包括 type、command、matcher、timeout、if 和 statusMessage。源代码解析器额外接受三个字段,它们会从根本上改变钩子的行为方式。
once: true 让钩子仅触发一次,然后自动移除。非常适合首次会话设置:
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "[ -f .env ] || cp .env.example .env && echo 'Created .env from template'",
"once": true,
"statusMessage": "First-time setup..."
}]
}]
}
}
足够简单,可以直接内联。它检查 .env 是否存在,如果不存在则复制模板,并且永远不会再次运行。
async: true 让钩子在后台运行,不会阻塞 Claude。即发即忘:
{
"hooks": {
"PostToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "jq '{timestamp: now, command: .tool_input.command, session: .session_id}' < /dev/stdin >> ~/.claude/audit.jsonl",
"async": true
}]
}]
}
}
这会将每条 bash 命令记录到审计文件中,而不会给你的会话增加任何延迟。
asyncRewake: true 是个巧妙的设计。它像 async 一样在后台运行,因此不会阻塞正常路径。但如果它以退出码 2 结束,它会重新唤醒模型并阻塞操作。一切正常时不阻塞,出现问题时才阻塞:
settings.json:
{
"hooks": {
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/scan-secrets.sh",
"asyncRewake": true,
"statusMessage": "Scanning for secrets..."
}]
}]
}
}
~/.claude/hooks/scan-secrets.sh:
#!/bin/bash
FILE=$(jq -r '.tool_input.file_path // .tool_response.filePath' < /dev/stdin)
if grep -qE '(password|secret|api_key)\s*=' "$FILE" 2>/dev/null; then
exit 2 # Block: secrets detected
fi
exit 0 # Clean: carry on
这会扫描 Claude 写入的每个文件,查找硬编码的密钥。如果发现密钥,它会阻塞并告知 Claude。如果没有发现,你甚至不会注意到它运行过。
文档未展示的技能前置元数据字段
文档涵盖了 name、description、allowed-tools、argument-hint、when_to_use 和 context。源代码中的实际前置元数据解析器额外接受六个字段。
model 允许你覆盖运行该技能的模型。使用 Haiku 处理廉价、快速的任务,使用 Opus 处理复杂分析:
---
name: quick-lint
description: Fast lint check using the cheapest model
model: haiku
effort: low
allowed-tools: Bash, Read
argument-hint: "[file]"
---
Run the project linter on: $ARGUMENTS
Detect the linter from config (eslint, ruff, clippy) and run it. Report only errors, not warnings.
这会以低努力度在 Haiku 上运行,因此快速且廉价。对于深度架构审查,你可能需要 model: opus 和 effort: max。
effort 控制模型思考的强度。可选值有 low、medium、high 或 max。这映射到同一套努力度系统,该系统在内部控制每次响应的推理深度。
hooks 定义作用域限定在技能激活期间的钩子。它们在技能触发时注册,在技能完成时注销:
---
name: strict-typescript
description: Write TypeScript with type checking on every save
allowed-tools: Bash, Read, Write, Edit, Grep, Glob
hooks:
PostToolUse:
- matcher: "Write|Edit"
hooks:
- type: command
command: "~/.claude/hooks/typecheck-on-save.sh"
statusMessage: "Type checking..."
- type: command
command: "~/.claude/hooks/lint-on-save.sh"
async: true
---
Write TypeScript with strict enforcement. Every file you touch gets type-checked and linted automatically.
$ARGUMENTS
~/.claude/hooks/typecheck-on-save.sh:
#!/bin/bash
FILE=$(jq -r '.tool_input.file_path // .tool_response.filePath' < /dev/stdin)
[[ "$FILE" == *.ts ]] && npx tsc --noEmit 2>&1 || true
~/.claude/hooks/lint-on-save.sh:
#!/bin/bash
FILE=$(jq -r '.tool_input.file_path // .tool_response.filePath' < /dev/stdin)
[[ "$FILE" == *.ts ]] && npx eslint --fix "$FILE" 2>&1 || true
当此技能运行时,Claude 写入的每个 TypeScript 文件都会同步进行类型检查,并在后台进行代码检查。当技能结束时,这些钩子会消失。作用域划分非常干净。
agent 将技能委托给一个自定义智能体:
---
name: deep-review
description: Thorough security review delegated to the review agent
agent: security-review
---
Review the following: $ARGUMENTS
`disable-model-invocation: true` 可防止自动调用。只有显式的 `/skill-name` 才能触发。此设置适用于你不希望意外触发的破坏性技能。
`shell: bash` 指定执行时使用的 shell。
文档中找不到的智能体字段
`.claude/agents/` 中的自定义智能体支持文档未提及的前置元数据字段。
`color` 设置 UI 颜色:红色、橙色、黄色、绿色、蓝色、紫色、粉色或灰色。当多个智能体同时运行时,有助于在视觉上区分它们。
`memory` 是重点。它赋予智能体跨调用持久化的记忆能力:
`user` - 全局记忆,跨所有项目持久化
`project` - 按项目持久化
`local` - 按项目私有(被 gitignore 忽略)
这意味着你可以构建一个会学习的智能体。一个能追踪过往发现的安全审查员。一个能跨会话记住你代码模式(patterns)的代码审查员。该记忆使用与自动记忆系统相同的前置元数据格式。
---
name: codebase-guide
description: Answer questions about the codebase, learning more with each session
tools: [Read, Grep, Glob, Bash]
color: green
memory: project
---
You are a codebase guide with persistent memory. Check your memory first before exploring the code.
After answering a question, save useful context to memory:
- Architecture decisions (type: project)
- Code locations for common tasks (type: reference)
- Patterns and conventions (type: feedback)
Over time, you should answer faster because you remember where things are.
经过几次会话后,这个智能体会构建一个关于你代码库的知识库,并在执行 grep 搜索之前就开始根据记忆进行回答。
`omitClaudeMd: true` 可跳过加载 CLAUDE.md 指令层级。这对于一个应用行业标准而非你项目惯例的“全新视角”审查员来说非常有用:
---
name: fresh-eyes
description: Review code without project-specific biases
tools: [Read, Grep, Glob]
omitClaudeMd: true
effort: high
color: blue
---
Review this code purely from first principles. You have no project context. Focus on correctness, security, performance, and readability by industry standards.
`criticalSystemReminder_EXPERIMENTAL` 是一个简短消息,会在每一轮对话中被重新注入作为系统提示。即使在对话压缩后,它仍会保留在上下文中:
---
name: prod-deployer
description: Manages production deployments with strict safety checks
tools: [Bash, Read, Grep]
color: red
criticalSystemReminder_EXPERIMENTAL: "Always run migrations with --dry-run first. Never skip the staging verification step."
---
警告:此字段在源代码中的实际名称包含 EXPERIMENTAL。Anthropic 的工程师认为它不稳定。它目前可以工作,但可能会在任何版本中被移除或重命名。请将其用于锦上添花的安全提醒,不要在其上构建关键基础设施。
`requiredMcpServers` 列出了必须配置的 MCP 服务器名称模式。如果这些服务器不可用,该智能体将不会显示。这可以防止智能体在其依赖项未设置时被加载。
自动模式分类器接受纯英文输入
`settings.json` 中的 `autoMode` 字段配置了 Anthropic 内部称为“YOLO 分类器”的功能。这控制着在自动模式下哪些操作会被自动批准。
{
"autoMode": {
"allow": [
"Bash(npm test)",
"Bash(npm run *)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Read",
"Grep",
"Glob"
],
"soft_deny": [
"Bash(git push *)",
"Bash(rm *)",
"Write(.env*)"
],
"environment": [
"NODE_ENV=development",
"This is a local dev machine with no production database access",
"All Docker containers use isolated networks",
"The test suite is safe to run repeatedly, it uses a dedicated test database"
]
}
}
允许模式可自动批准。软拒绝模式始终需要确认。环境数组是值得关注的部分,它根本不是模式。这些是分类器读取的纯英文上下文字符串,用于理解你的设置。你可以写“本项目使用 Docker,所有命令在容器中运行”,分类器在判断模糊命令的安全性时会考虑这些信息。
可以把它想象成给分类器一份关于你环境的简报。你描述得越具体,它做出的决策就越好。“无生产环境访问权限”会告诉它对破坏性操作不必过于谨慎。“测试数据库已隔离”则表明运行测试始终是安全的。
学习循环的开关功能无人记录
两个 settings.json 字段可启用 Claude Code 的自我改进系统:
{
"autoMemoryEnabled": true,
"autoDreamEnabled": true
}
autoMemoryEnabled 让 Claude Code 自动从你的会话中提取持久记忆。每次对话结束后,一个后台智能体会提取值得记住的内容——你的偏好、代码库模式、你做出的决策——并使用标准记忆前置元数据格式,将其写入 ~/.claude/projects/<path>/memory/。
autoDreamEnabled 会激活后台的“梦境”整合。每 24 小时,如果累积了 5 个或更多会话,一个后台智能体会审查过往会话记录并整合记忆。它会合并重复项、解决矛盾、将相对日期转换为绝对日期,并修剪过时的条目。
这两者共同形成了一个复合学习循环:会话产生记忆,梦境整合记忆,整合后的记忆又为未来的会话提供信息。同时开启这两项功能,几周后你就会注意到 Claude Code 无需提示就能记住你的偏好、约定和常见模式。这是无需任何模型重新训练的真正从经验中学习。
魔法文档:确切格式
源代码揭示了正则表达式:/^#\s*MAGIC\s+DOC:\s*(.+)$/im。它必须是一个 H1 标题,不区分大小写,下一行可以是斜体指令(用_下划线_或*星号*包裹),用于限定更新智能体的关注范围:
# MAGIC DOC: API Endpoint Reference
_Only document public REST endpoints. Include method, path, request body, response schema, and auth requirements._
## Endpoints
(content auto-maintained by Claude Code)
如果没有指令行,智能体会尝试更新所有内容。有了它,你告诉智能体“只追踪公共端点”或“专注于破坏性变更”,它就会遵守。更新智能体在后台运行,并且仅限于编辑那个特定文件。删除头部信息会自动停止追踪。
完整权限规则语法
文档展示了像 `Bash(git *)` 这样的基本示例。源代码揭示了完整的模式匹配语言:
Bash(npm *) # wildcard after "npm "
Bash(git commit *) # specific subcommand
Read(*.ts) # file extension
Read(src/**/*.ts) # recursive directory with extension
Write(src/**) # recursive, all files
mcp__slack # all tools on slack server
mcp__slack__* # explicit wildcard (same effect)
mcp__slack__post_message # specific tool
Bash(npm:*) # legacy colon prefix (word boundary)
`*` 在边界内匹配,类似于 shell 的通配符。`**` 递归地匹配目录。MCP 工具权限使用双下划线:`mcp__<server>__<tool>`。钩子中的 `if` 字段使用完全相同的语法。没有正则表达式,只有通配符。
{
"permissions": {
"allow": [
"Bash(npm *)", "Bash(git status)", "Bash(git diff *)",
"Read(src/**)", "Read(tests/**)", "Grep", "Glob",
"mcp__database__query"
],
"deny": [
"Bash(rm -rf *)", "Write(/etc/**)", "Write(.env*)",
"mcp__slack__delete_*"
],
"ask": [
"Bash(git push *)", "Write(*.json)", "Write(*.lock)",
"mcp__slack__post_message"
]
}
}
context: fork 以及为什么你的模型选择很重要
当你在一个技能上设置 `context: fork` 时,它会作为一个后台分叉子智能体运行。源代码揭示,分叉通过一个名为 `CacheSafeParams` 的类型化契约共享父进程的提示词缓存。所有分叉都会生成字节完全相同的 API 请求前缀,以最大化缓存命中率。
实际影响:如果你在分叉技能上设置了不同的模型,就会破坏缓存。父对话使用的是 Opus,分叉使用的是 Haiku,前缀不同,缓存未命中,你需要支付全价。要么省略模型字段,要么在分叉技能上使用 `model: inherit` 来保持缓存正常工作。
使用 `context: fork` 处理繁重工作:安全扫描、依赖分析、文档生成、测试套件运行。分叉在后台运行,完成后通知你,让你的主对话保持响应。
---
name: full-audit
description: Comprehensive codebase audit running in the background
context: fork
allowed-tools: Bash, Read, Grep, Glob, WebSearch
effort: high
---
Run a comprehensive audit:
- Security scan (grep for dangerous patterns, check dependencies for CVEs)
- Code quality (duplicated logic, dead code, missing error handling)
- Test coverage (untested critical paths)
- Dependency health (outdated packages, unused deps, license issues)
Write a detailed report to /tmp/audit-report.md when complete.
整合在一起
一个具有持久记忆和限定作用域钩子的自我改进代码审查器:
.claude/agents/reviewer.md:
---
name: reviewer
description: Code reviewer that learns your codebase patterns over time
tools: [Read, Grep, Glob, Bash]
effort: high
color: yellow
memory: project
hooks:
PostToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "~/.claude/hooks/log-review.sh"
async: true
---
Before reviewing, read your memory for past findings on this codebase.
Review git diff HEAD~1 for:
- Patterns you've flagged before (check memory)
- New issues worth flagging
- Resolved issues from past reviews
After review, save to memory:
- New patterns found (type: feedback)
- Recurring issues (type: project)
End with VERDICT: PASS, FAIL, or NEEDS_REVIEW.
这个智能体会记住它上次发现了什么。它知道哪些模式会反复出现。经过几次审查后,它开始捕捉通用审查器会遗漏的特定项目问题。
一个带有文件监视功能的 SessionStart 钩子,加上一个 asyncRewake 安全网:
settings.json:
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/session-context.sh",
"statusMessage": "Loading project context..."
}]
}],
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "~/.claude/hooks/auto-approve-readonly.sh"
}, {
"type": "command",
"command": "~/.claude/hooks/block-dangerous.sh",
"asyncRewake": true,
"statusMessage": "Safety check..."
}]
}]
}
}
~/.claude/hooks/block-dangerous.sh:
#!/bin/bash
CMD=$(jq -r '.tool_input.command' < /dev/stdin)
echo "$CMD" | grep -qE '(rm -rf /|sudo rm|chmod 777|> /dev/)' && exit 2 || exit 0
只读命令会立即自动批准。危险命令会被阻止。介于两者之间的命令会走正常的权限流程。安全扫描器异步运行,因此在正常路径上不会拖慢任何操作。
具备模型覆盖、努力控制与智能体委派能力的技能:
---
name: architecture-review
description: Deep architecture review using max effort, delegated to fresh-eyes agent
agent: fresh-eyes
effort: max
---
Review the architecture of this project. Ignore existing conventions (the agent has omitClaudeMd: true).
Focus on: $ARGUMENTS
Evaluate structural decisions, dependency graph health, separation of concerns, and scalability characteristics.
这串联了三个未公开功能:将努力程度设为最高以进行深度思考、将任务委派给特定智能体,以及该智能体启用 `omitClaudeMd: true` 以实现无偏分析。
这些未公开功能揭示了 Claude Code 当前状态与 Anthropic 正在将其打造成的目标之间的差距。带有事件特定响应字段的钩子系统,是为 AI 工具使用设计的可编程中间件层,其灵活性超过大多数 CI/CD 流水线。持久化智能体记忆能够创建跨会话积累真正专业知识的 AI 专家。梦境整合系统则是在无需重新训练模型的情况下从经验中学习。自动模式分类器接受你环境的自然语言描述,以做出安全决策。
这些并非隐藏设置或彩蛋。它们是持久化、可学习、自主的 AI 开发环境的骨架,并且已经在你机器上的 npm 包中正常运行。文档最终可能会跟上,但如果你想在 Claude Code 实际能力的尖端进行构建,源代码才是真正文档所在之处。