我阅读了 Claude Code 的源代码。以下是文档中没有告诉你的所有可配置项。
能够中途重写命令的钩子字段、持久化的智能体记忆、用自然语言编写的自动模式规则、自我改进的梦境循环——每一个示例都可以直接复制粘贴使用。
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/<名称>/SKILL.md(个人)或 .claude/skills/<名称>/SKILL.md(项目)
智能体:~/.claude/agents/<名称>.md(个人)或 .claude/agents/<名称>.md(项目)
钩子脚本:建议放在 ~/.claude/hooks/。记得执行 chmod +x 你的脚本。
项目级文件放在 .claude/ 中可以提交到 git 并与团队共享。个人文件放在 ~/.claude/ 中仅供你自己使用。
你的钩子可以回传信息,而这一点从未有人告诉过你该怎么操作。
这是文档中最大的空白。文档告诉你,hook 通过 stdin 接收 JSON,且退出码 2 会阻止某项操作。但它们没有告诉你的是,hook 可以通过 stdout 返回带有事件特定字段的 JSON,从而实时修改 Claude Code 的行为。源代码揭示了每种事件类型具体接受哪些内容。
PreToolUse hook 可以返回:
updatedInput——在工具执行前重写其输入。你可以中途修改命令。
permissionDecision——强制“允许”或“拒绝”,无需用户提示。
permissionDecisionReason——解释该决定(在 UI 中显示)。
additionalContext——将文本注入对话上下文中。
SessionStart hook 可以返回:
watchPaths——设置自动文件监视,触发 FileChanged 事件。
initialUserMessage——在会话中第一条用户消息之前附加内容。
additionalContext——注入会持久存在于整个会话中的上下文。
PostToolUse hook 可以返回:
updatedMCPToolOutput——修改 Claude 从 MCP 工具响应中看到的内容。
additionalContext——在工具运行后注入上下文。
PermissionRequest hook 可以返回:
decision——通过 updatedInput 或 updatedPermissions 以编程方式允许或拒绝。
这是很强大的功能。下面是一个 PreToolUse hook,它会在 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,但你的 hook 在执行前悄悄将其重写为 git push origin main --dry-run。updatedInput 字段在任何文档中都没有提及。
下面是一个 SessionStart hook,它会监视你的配置文件,并将 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 命令的 hook。
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.
这会在低 effort 下运行在 Haiku 上,因此又快又便宜。对于深入的架构审查,你会想要 model: opus 和 effort: max。
effort 控制模型思考的深度。可选 low、medium、high 或 max。这映射到同一个 effort 系统,该系统在内部控制每次响应的推理深度。
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 文件都会同步进行类型检查,并在后台进行 lint 检查。技能结束后,这些钩子就会消失。作用域划分非常干净。
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/ 目录下自定义智能体支持文档未提及的 frontmatter 字段。
color 设置界面颜色:red、orange、yellow、green、blue、purple、pink 或 gray。当同时运行多个智能体时,有助于从视觉上区分它们。
memory 是关键字段。它让智能体在多次调用之间拥有持久化记忆:
user - 全局级别,跨所有项目持久化
project - 按项目持久化
local - 项目级私有(已加入 gitignore)
这意味着你可以构建一个能够学习的智能体。比如:一个能追踪历史发现的安全审查员,或者一个能跨会话记住你编码风格的习惯审阅者。记忆系统使用的 frontmatter 格式与自动记忆系统相同。
---
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.
经过几次会话后,这个智能体将建立起关于你代码库的知识库,并会在搜索之前直接从记忆中给出答案。
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/<路径>/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>`。hook 中的 `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.
综合运用
一个具有持久记忆和范围化 hook 的自我改进代码审查智能体:
`.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.
这个智能体会记住它上次发现了什么。它知道哪些模式反复出现。经过几次审查后,它就能捕捉到通用审查器难以发现的项目特定问题。
一个包含文件监听和 `asyncRewake` 安全网的 `SessionStart` hook:
`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 实际能做的事情的前沿进行构建,源代码才是真正文档所在之处。
