Claude Code 的核心并不是一条更长的提示词,而是一套围绕模型运行的 Agent 基础设施。模型负责判断下一步做什么;工具执行、权限确认、上下文管理、会话恢复和失败回退,则决定这个判断能否安全地落到真实代码库。
曾有源码分析用“5% 是模型调用,95% 是 harness”概括这套系统。这个比例来自特定版本和统计口径,不应当作精确结论,但方向成立:生产级编码 Agent 的工作量主要不在调用模型,而在控制模型与环境之间的交互。本文沿一条真实请求的生命周期,拆解这层基础设施。
一、先建立完整运行链路
Claude Code 与普通聊天产品的区别,是模型回复可以包含工具调用。工具结果会重新进入上下文,模型再根据新状态决定下一步,直到给出没有工具调用的最终回复。
这张图里,模型只占中间一个节点。真正让循环可用的是外围几层:上下文决定模型看见什么,权限决定工具能否运行,持久化决定中断后能否恢复,检查点决定出错后能否回退。
把 Claude Code 理解为“模型 + 工具”还不够。更准确的划分是六个控制面:
| 控制面 | 解决的问题 | 用户可观察入口 |
|---|---|---|
| 上下文 | 模型当前知道什么 | /context、/compact、/clear |
| 工具 | 模型如何读取和改变环境 | 内置工具、MCP、Skills |
| 权限 | 哪些动作可以执行 | /permissions、settings、沙箱 |
| 生命周期 | 在固定节点自动执行什么 | Hooks |
| 连续性 | 会话如何恢复,代码如何回退 | /resume、/rewind、checkpointing |
| 推理预算 | 每一步投入多少推理成本 | /model、/effort、thinking |
后面的机制都可以放回这六个控制面理解,不必记住内部文件和类名。
二、会话不是模型记忆,而是可恢复的事件记录
Claude Code 会把本地会话 transcript 存为 JSONL,默认路径是 ~/.claude/projects/<project>/<session-id>.jsonl。其中包含消息、工具调用、工具结果和元数据。/resume 与 --continue 依赖这些记录恢复工作,/export 则把它们渲染为便于阅读的文本。
这里要区分三个概念:
- Transcript 保存发生过什么,用于恢复和审计。
- 上下文窗口 保存模型这一刻能直接看到什么,会随着压缩而改变。
- 持久记忆 保存跨会话仍值得加载的项目规则和经验。
三者可以指向同一段信息,但生命周期不同。压缩会把旧对话变成摘要,却不会因此删除本地 transcript;恢复会话会重建当前消息链,也不等于模型重新逐字读入整个历史。
检查点同时管理代码和对话
Checkpointing 会在每条用户提示前建立检查点,并追踪 Claude 通过文件编辑工具做出的修改。按两次 Esc 或运行 /rewind,可以选择恢复代码、恢复对话、同时恢复二者,或只总结某一段历史。
这个能力有两个重要边界:
- 检查点追踪
Write、Edit和NotebookEdit等文件工具产生的修改,通过 Bash、外部进程或手工操作产生的变化不一定受它保护。 /rewind是会话内的快速恢复工具,不替代 Git。跨分支协作、长期历史和可审计提交仍应交给版本控制。
因此,大范围重构前仍应检查工作区并创建明确的 Git 边界。检查点适合撤回最近一次 Agent 操作,Git 负责项目级历史。
三、CLAUDE.md、规则和自动记忆各管一层
每个 Claude Code 会话都从新的上下文窗口开始。跨会话连续性主要来自两类文件:人维护的 CLAUDE.md,以及 Claude 维护的自动记忆。
| 机制 | 谁写 | 适合内容 | 是否强制执行 |
|---|---|---|---|
CLAUDE.md / AGENTS.md | 团队或个人 | 构建命令、架构约定、编码规范 | 否,属于模型指令 |
.claude/rules/*.md | 团队 | 按文件类型或目录生效的局部规则 | 否,属于模型指令 |
CLAUDE.local.md | 个人 | 本机地址、个人偏好、私有测试数据 | 否,属于模型指令 |
.claude/skills/、.claude/commands/、.claude/agents/ | 团队或个人 | 可调用的工作流、子 Agent 和专门提示 | 按需进入上下文 |
.mcp.json | 团队 | 项目级 MCP server 配置 | 作为工具配置生效 |
| 自动记忆 | Claude | 从纠正中提取的项目事实和经验 | 否,属于模型上下文 |
| settings 权限与 Hooks | 团队或管理员 | 必须允许、询问或阻止的行为 | 是,进入执行链路 |
这张表最重要的分界在最后一列。CLAUDE.md 告诉模型“应该怎样做”,权限和 Hook 决定系统“允许怎样做”。不能被违反的规则不能只写成提示词。
加载范围决定上下文成本
“Claude Code 会读取哪些文件”要按加载时机回答,而不是把整个仓库都当成启动提示词。下面按真实路径拆成多棵树;业务源码、README、package.json 等文件只有在模型调用工具、运行 /init,或某个 Skill 明确引用时才会读取。
组织托管目录
项目根目录
parent-directory
subdirectory
nested-subdirectory
项目 .claude/ 目录
rules
skills
skill-name
commands
agents
agent-memory
agent-name
agent-memory-local
agent-namelocal 范围的 subagent 记忆;不应提交到版本库
output-styles
workflows
hooks不是自动扫描入口;只有 settings.json 或 Agent frontmatter 引用的脚本才会执行
用户 ~/.claude/ 目录
.claude
rules
skills
commands
agents
output-styles
workflows
agent-memory
agent-name
projects/project-name/memory
用户插件目录
plugin-sourcecommand 源、—plugin-dir 或本地市场也可能从源目录就地加载
会话与运行数据目录
这些树中的“加载”不是一个单一动作:当前工作目录及其祖先、用户级和组织级的指令,无条件规则和主会话 MEMORY.md 通常在启动时进入上下文;嵌套的 CLAUDE.md、路径规则、主题记忆和 Skill 支持文件在需要时读取;settings、MCP、插件和 Hooks 则主要改变可用工具或生命周期。CLAUDE.md 还可以用 @path/to/file 导入其他 Markdown,导入最多递归四跳,导入文件会随引用它的指令一起进入启动上下文。主会话自动记忆默认不注入普通 subagent;启用 subagent 自己的 memory 后,则从其专属目录加载独立的 MEMORY.md。
默认项目说明设置是 claude-md-or-agents-md:若工作目录或其祖先存在 CLAUDE.md、.claude/CLAUDE.md 或 CLAUDE.local.md,默认不会再读取同层的 AGENTS.md;切换为 claude-md-and-agents-md 才会同时读取。直接发现 AGENTS.md 需要 Claude Code v2.1.277 或更高版本,且部分运行环境仍可能只支持 CLAUDE.md。Claude Code 不会把 AGENTS.local.md、AGENTS.override.md 或 .agents/ 目录当作默认说明入口,也不会把 ~/.claude/.mcp.json 当作全局 MCP 配置。
下面的规则只在处理 TypeScript 源码和测试时加载。这个例子用于说明按路径缩小规则范围,而不是提供一份完整的团队规范:
---paths: - "src/**/*.ts" - "tests/**/*.ts"---
修改公共类型后,运行类型检查和相关单元测试。这样组织后,前端规则不会占用后端任务的上下文,局部约定也不必塞进越来越长的根目录文件。
自动记忆同样是普通 Markdown。会话启动时只加载 MEMORY.md 的前 200 行或 25KB,以先到者为准;更详细的主题文件按需读取。这个限制说明 MEMORY.md 应该像索引和高频事实表,而不是无限增长的工作日志。
四、Hooks 把建议变成确定的生命周期动作
Hook 在会话启动、用户提交、工具调用、权限请求、上下文压缩和会话结束等节点运行。它适合执行格式化、验证、审计和通知等需要固定触发的动作。
最常用的事件可以按生命周期归纳,而不必背完整事件枚举:
| 阶段 | 代表事件 | 常见用途 |
|---|---|---|
| 会话 | SessionStart、SessionEnd | 加载动态环境信息、清理临时资源 |
| 输入 | UserPromptSubmit | 校验或补充用户输入 |
| 工具 | PreToolUse、PostToolUse、PostToolUseFailure | 权限判断、格式化、记录执行结果 |
| 权限 | PermissionRequest、PermissionDenied | 外部策略审批与拒绝记录 |
| 压缩 | PreCompact、PostCompact | 保存状态、归档摘要 |
| 子 Agent | SubagentStart、SubagentStop | 跟踪委派任务 |
Hooks 支持命令、HTTP、MCP 工具、单轮 prompt 和 Agent 验证等执行方式,具体可用类型取决于事件。Agent Hook 仍属于实验能力,配置时应查当前文档,而不是依赖历史版本的默认超时或最大轮数。
Hook 与权限不是覆盖关系
PreToolUse Hook 可以拒绝调用、要求询问或允许继续,但返回 allow 不会覆盖 settings 中匹配的 deny 或 ask 规则。官方权限文档明确保留了 deny 优先级:Hook 能收紧边界,不能悄悄绕过更严格的策略。
下面这条决策链比记忆内部函数名更重要:
这条链支持一个通用设计原则:把组织级禁止项放在 managed settings,把项目级安全约束放在可提交的 permissions 或 Hook,把偏好和操作建议留给 CLAUDE.md。
五、工具管线的核心是验证、授权和反馈
一次工具调用至少跨过三道边界:输入是否合法、当前主体是否有权执行、执行结果如何反馈给模型。内部实现会随版本变化,但公开能力呈现出的稳定管线可以概括为:
- 模型根据工具描述生成结构化输入。
- Claude Code 校验输入,并运行匹配的
PreToolUseHook。 - 权限系统根据工具、参数和当前模式决定允许、询问或拒绝。
- 工具在宿主环境或沙箱中执行。
- 成功结果进入
PostToolUse,失败结果进入PostToolUseFailure。 - 结果回到上下文,模型决定继续调用工具还是结束。
权限判断不能只看工具名。同一个 Bash 工具既可以运行只读的 git status,也可以执行破坏性命令;规则应尽可能约束到命令模式和资源范围。文件读取、网络访问和目录写入也应按最小权限配置。
多个独立工具调用可以并行执行,但是否并行由工具的安全属性和依赖关系决定。对自建 Agent 而言,不能只用 Promise.all 追求吞吐:写同一文件、共享工作目录或有先后依赖的命令必须串行,否则上下文里看到的结果可能与真实执行顺序不一致。
六、effort 和 thinking 控制的是推理预算
Effort 控制模型在每一步投入多少自适应推理。较低档位通常更快、更便宜,适合检索、格式化和机械修改;较高档位适合架构取舍、复杂故障定位和跨模块重构。
可用档位取决于当前模型。/effort、/model、--effort、CLAUDE_CODE_EFFORT_LEVEL 和 settings 都能设置 effort,但环境变量优先级最高;设置模型不支持的档位时,Claude Code 会选用不高于请求值的最高可用档位。具体模型、默认值和支持范围会变化,应以当前模型配置文档和界面显示为准。
Thinking 是推理过程的生成与展示方式,effort 是推理深度的主要控制。二者不能简单等同于“回答质量开关”:高 effort 会增加时间和 token 消耗,也不能替代清楚的目标、充分的代码上下文和可靠的测试反馈。
ultrathink 只是 Claude Code 识别的上下文关键词。它会为当前请求加入更深思考的指令,但不会直接改写发送给 API 的 effort 参数。与其在提示词里堆叠“think harder”,更稳定的做法是显式选择受支持的 effort 档位,并说明需要权衡的约束。
七、安全边界来自多层约束
编码 Agent 面对的输入不只来自用户,还来自仓库文件、网页、MCP 服务和命令输出。这些内容都可能包含错误指令或恶意数据。单一提示词无法覆盖这些风险,Claude Code 因而采用分层边界:
- 工作区信任决定是否加载项目配置和运行相关自动化。
- 权限规则决定工具调用是否允许、询问或拒绝。
- 沙箱限制 Bash 命令的文件系统和网络访问范围,并减少反复授权。
- Hooks在生命周期节点执行确定性检查。
- 组织策略可以通过 managed settings 设置用户无法覆盖的规则。
- 检查点和 Git提供出错后的恢复路径。
沙箱不是完整虚拟机,也不等于所有命令都安全。官方文档明确提醒:沙箱主要约束 Bash 及其子进程;未被沙箱覆盖的工具仍受常规权限系统控制,而且允许写入的目录会扩大潜在影响范围。安全审查应同时检查权限、沙箱配置、允许目录和网络域名。
bypassPermissions 则会绕过权限检查。它只适合外部已经完成隔离的容器或虚拟机,不应当作日常减少弹窗的快捷方式。需要减少确认时,应优先收窄并持久化明确的 allow 规则,而不是关闭整层授权。
八、从 Claude Code 提炼 Agent 产品设计
Claude Code 最值得借鉴的不是某个内部类名,而是几条可迁移的工程判断。
1. 把状态分成三类
对话 transcript、模型当前上下文和跨会话记忆不是同一种状态。分别存储,才能独立处理恢复、压缩和知识更新。
2. 指令与约束必须分层
模型指令适合表达偏好和工作方法;权限、沙箱和 Hook 承担强制边界。要求越不能被违反,越不应只依赖自然语言。
3. 所有副作用都要有恢复路径
文件修改需要检查点和 Git,外部 API 需要幂等键和补偿动作,长流程需要可恢复的任务状态。只记录对话不足以恢复真实世界的副作用。
4. 上下文是运行资源
工具定义、日志和中间搜索结果都会消耗上下文。应像管理内存一样管理它:观测占用、按需加载、隔离支线、在阶段边界压缩,而不是等到超限再处理。
5. 可观测性要覆盖决策链
只记录模型输入输出无法解释“为什么这个命令被执行”。生产系统至少要串起用户目标、模型决策、权限结果、工具输入输出、状态变更和最终验证。
九、一套可落地的配置顺序
面对一个新项目,可以按风险从低到高逐层增加能力:
- 先写一份短
CLAUDE.md,只放构建命令、架构边界和高频约定。 - 用
.claude/rules/拆出按路径加载的语言和模块规则。 - 在 settings 中明确 allow、ask、deny,先处理密钥、生产配置和发布命令。
- 用
PostToolUseHook 自动运行格式化或轻量检查,用PreToolUse阻止确定危险的动作。 - 打开沙箱并收紧可写目录和网络范围。
- 用
/context、/permissions、/hooks和/memory检查最终生效状态。 - 为长任务建立 Git 边界和验收清单,再考虑提高 effort 或增加子 Agent。
这套顺序先解决“知道什么”和“允许做什么”,再解决自动化和推理深度。模型能力越强,外围约束越需要清楚,因为更强的执行能力也会放大错误动作的影响。
结语
Claude Code 的工程价值不在某个固定的“5% 对 95%”比例,而在它把不稳定的模型判断放进了可检查、可授权、可恢复的运行链路。Agent 产品是否成熟,最终看的是三件事:能否解释一次动作为什么发生,能否在动作前阻止越界,能否在动作后恢复状态。
参考资料
- How Claude Code works - Agent 循环与上下文管理
- Agent loop - 消息、工具和结果的生命周期
- Manage sessions - 会话恢复、导出与 transcript 路径
- Checkpointing - 文件和对话回退
- How Claude remembers your project -
CLAUDE.md、规则和自动记忆 - Explore the
.claudedirectory - 项目、用户级、插件和运行数据文件全景 - Settings files - settings 作用域与优先级
- Skills - Skill 的发现、加载和支持文件
- Subagents - subagent 定义、作用域和持久记忆
- Plugins - 插件目录及其 Skills、Agents、Hooks 和 MCP 文件
- Hooks reference - Hook 事件、输入和决策能力
- Configure permissions - 权限规则与 Hook 优先级
- Sandboxing - 文件系统和网络隔离边界
- Model configuration - effort、thinking 与模型支持范围
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时








