博客 • AI / Agent
Claude Code 为什么越来越像真正的 AI Agent?从 Tool Use、MCP、Session、Permission 到 JSON Workflow 全面解析
Claude Code 像 Agent,是因为一次会话把三份 JSON 绑在一起:可恢复的对话、每次 Tool Use 都要过的权限,以及启动时读入的 MCP。恢复用 --resume,权限写在 settings.json,工具来自 .mcp.json。缺任何一份,恢复出来的都不是同一次工作。
工具循环本身已经写在 Coding Agent 如何工作。各家 Harness 的差别写在 Harness 大战。本篇只拆 Claude Code:会话恢复什么、权限模式何时变、MCP 何时重新读,以及你该自己留下哪份工作流 JSON。
本文将介绍:
- 会话恢复带上什么、带不上什么
- 权限模式是会话状态,规则在 settings 里
- MCP 在会话启动时读入,命令行配置不会自动回来
- 一份你自己的工作流 JSON,用来下次按同样的参数恢复
- 一轮 Tool Use 按什么顺序改这三份文档
先记住这一点:恢复会话不等于恢复启动参数。对话和部分权限模式会回来,--mcp-config 不会。下面按「会话 → 权限 → MCP → 你的工作流 JSON」拆开。
会话恢复什么,不恢复什么
会话是绑在项目目录上的对话。官方说明见 管理会话。记录持续写到本机,所以退出之后还能回来。
| 入口 | 恢复什么 | 权限模式 |
|---|---|---|
claude --continue |
当前目录最近一次交互会话的完整对话,含工具调用和结果 | 终端里不带 -p 时,按官方表恢复;bypassPermissions 和 plan 不会原样回来 |
claude --resume <name> |
按名字直接恢复那一次会话 | 名字唯一时直接进入;重名则打开选择器,选择器不恢复当时的权限模式 |
claude -p --resume |
非交互恢复,适合脚本 | 按一次新的 claude -p 来决定模式。会话结束在 plan,且满足官方四个条件时,才回到 plan |
恢复时还会带上当时的模型,以及仍有效的目标和未过期的计划任务。后台 Bash 不会回来。
- 会回来:对话历史、当时的模型(模型已下线或被 availableModels 拦住时除外)、用 --agent 启动的 agent 定义。两边目录都找不到该 agent 时,退回默认工具并给出警告。
- 不会自动回来:
--mcp-config、--settings、--add-dir,以及会话中途用 /add-dir 加的目录。这些要在恢复命令里再传一次。 - 写在
settings.json和 settings.local.json 里的配置会在启动时重读,不用再传。
转录默认是 JSONL,路径在 ~/.claude/projects/ 下面、按工作目录转成的文件夹里。官方写明格式会变,不要把它当成你的稳定契约。你要稳定的字段,自己另写一份 JSON。
权限模式跟着会话走
模式不是写在提示词里的。会话中可以用 Shift+Tab 在 default、acceptEdits、plan 之间切。启动时用 --permission-mode,长期默认写在 权限模式 文档里的 permissions.defaultMode。聊天里要求模型换模式,不会改这次会话的闸门。
{
"permissions": {
"defaultMode": "default",
"allow": ["Bash(npm test *)"],
"ask": ["Bash(git push *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
规则顺序见 Claude Code 权限。更具体的 allow 盖不过已经命中的 deny。
| 怎么恢复 | 权限模式 |
|---|---|
| 终端 --continue 或按唯一名字 --resume,且不带 -p | 恢复会话结束时的模式,例外:bypassPermissions 和 plan 会回到新会话该用的模式。auto 只在账号仍满足条件时恢复。 |
| 启动时的选择器,或名字对上多个会话 | 不恢复存下来的模式,按这次启动新会话的模式开始。 |
/resume |
不恢复目标会话存的模式,沿用你当前这次会话的模式。 |
规则怎么落到审批队列和拒绝回写,见 权限控制怎么接。本篇只说明模式是会话状态,规则文件在恢复时重读。
MCP 在会话启动时读入
项目级服务器写在仓库根的 .mcp.json,会话启动时读取。改完文件要退出再开一次会话。说明见 连接 MCP。第一次看到项目级服务器会要求批准,克隆下来的仓库不能未经同意就在你机器上起进程。
{
"mcpServers": {
"docs": {
"type": "http",
"url": "https://code.claude.com/docs/mcp"
}
}
}
- 项目范围:
.mcp.json,克隆仓库的人共用。要先批准。 - 本机范围:
~/.claude.json。local 只对你、只对当前项目;user 只对你、所有项目。 - 命令行
--mcp-config只在这一次启动生效。恢复会话时不会自动带上,要再传。
工具全名以 mcp__docs__ 这类前缀出现。权限规则按这个全名匹配,不要只写服务器里的短名。
你自己的工作流 JSON
转录 JSONL 不稳定。下面这份是你的应用契约,用来记住下次恢复该传什么。它不是 Claude Code 的请求体,也不会被 CLI 自动读取。
{
"name": "auth-refactor",
"cwd": "/repo/app",
"permission_mode": "default",
"settings": ".claude/settings.json",
"mcp_config": ".mcp.json",
"resume": ["--resume", "auth-refactor"],
"last_tool": {
"name": "mcp__docs__search",
"decision": "allow"
}
}
name 用 claude -n 或 /rename 设过的名字,方便 --resume 按名字找。cwd 必须是当时的项目目录,会话存在按目录划分的存储里。
-
1
先对上会话
name用来 --resume,cwd用来决定去哪个项目目录找转录。目录不对,同名会话也找不到。 -
2
再对齐权限模式
把
permission_mode抄进恢复命令的--permission-mode。选择器和 /resume 不会帮你恢复旧模式。 -
3
最后补上 MCP
mcp_config指向仓库里的文件时,启动会重读。若当时靠的是命令行文件,把路径放进--mcp-config。
一轮 Tool Use 怎么改这三份文档
一轮不是再写一段提示词。顺序是固定的。
-
1
读入
会话载入已有对话,并重读 settings.json 与 .mcp.json。命令行 MCP 只有你这次传了才在。
-
2
提出调用
模型给出 tool_use:工具全名和 input。MCP 工具带服务器前缀。
-
3
过权限
按 deny、ask、allow 判定。deny 不执行。ask 停下来等人。allow 才调用工具。
-
4
写回
结果追加进会话转录。你的工作流 JSON 只更新
last_tool,不要把整段转录复制进去。
这样下次恢复时,你知道上次停在哪个工具、当时的模式,以及 MCP 配置从哪个文件读。转录本身仍由 Claude Code 保存。
和另外两篇怎么分工
| Coding Agent 如何工作 | Harness 大战 | 本篇 | |
|---|---|---|---|
| 回答的问题 | 工具循环一般怎么转 | 各家外壳差在哪 | Claude Code 一次会话恢复时,三份 JSON 各管什么 |
| 不要在这里找 | 又一篇工具调用综述 | 又一张产品对比表 | 把 JSONL 转录当成稳定 API 来解析 |
在 JSONNote 里检查工作流 JSON
-
1
格式化
用 JSON 格式化 打开 settings.json 和工作流记录。注释和尾逗号会让 Claude Code 在下次启动报 Settings Error。
-
2
校验工作流记录
把下面的 Schema 贴进 JSON Schema。缺 name、cwd 或 permission_mode 不在枚举里,都先改再拿去恢复。
-
3
对比权限规则
改 deny / allow 前后用 JSON Diff 看一条
deny有没有被挪进allow。这种变化比会话名字更值得人看。
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"additionalProperties": false,
"required": ["name", "cwd", "permission_mode", "settings", "mcp_config"],
"properties": {
"name": { "type": "string", "minLength": 1 },
"cwd": { "type": "string", "minLength": 1 },
"permission_mode": {
"enum": ["default", "acceptEdits", "plan", "auto", "dontAsk", "bypassPermissions"]
},
"settings": { "type": "string", "minLength": 1 },
"mcp_config": { "type": "string", "minLength": 1 },
"resume": { "type": "array", "items": { "type": "string" } },
"last_tool": {
"type": "object",
"required": ["name", "decision"],
"properties": {
"name": { "type": "string" },
"decision": { "enum": ["allow", "deny", "ask"] }
}
}
}
}
常见问题
resume 之后 MCP 服务器还在吗?
写在 .mcp.json 或 ~/.claude.json 里的会在启动时重读。只通过 --mcp-config 传入的不会自动回来,恢复时要再传。
权限模式会不会和对话一起恢复?
不一定。终端里不带 -p 的 --continue 或唯一名字的 --resume,会按官方表恢复,但 bypassPermissions 和 plan 不会原样回来。选择器和 /resume 用的是当前这次启动的模式。
能不能解析 ~/.claude/projects 里的 JSONL 来做工作流?
不要。官方把转录格式当成会变的内部文件。你要稳定的字段,另写本篇这份工作流 JSON,只记名字、目录、模式、配置路径和上一笔工具决定。
在对话里让模型切换权限模式有用吗?
没用。模式由 Shift+Tab、--permission-mode 或 settings 里的 defaultMode 决定,不由提示词决定。
这和审批队列是同一件事吗?
不是。本篇的 permission_mode 是这一次会话的闸门。队列、拒绝回写和 tool_use_id 见权限控制那篇。两边都要有:模式决定会不会问你,队列决定问了之后怎么落盘。
总结
Claude Code 像 Agent,是因为会话把对话、权限模式和 MCP 工具绑成一次可恢复的工作。恢复对话不等于恢复启动参数。转录 JSONL 留给 CLI,你自己留一份工作流 JSON。
直接结论:用名字和目录定位会话;权限模式在选择器和 /resume 里要显式再传;--mcp-config 每次恢复都要再带上。
下一步:先校验工作流记录,再按里面的 resume 参数打开会话。