简介
ClaudeCode是Anthropic推出的命令行AI编程工具。
第一眼看上去,像一个装在终端里的聊天窗口;但聊天窗口只会输出文字,Claude Code却会真的读文件、真的改代码、真的执行命令。
那么,一个只会生成文本的大模型,如何安全地作用于真实代码库的呢?
工具调用循环(agent loop):模型提出要做的动作,ClaudeCode代为执行,再把结果喂回模型。
而这个循环始又终受一个硬约束支配:模型一次能看到的内容是有限的。
即,ClaudeCode的本质是"大模型+工具调用循环+有限上下文窗口"。
官方文档:https://code.claude.com/docs
工具调用循环
工具调用
大模型的输入是文本,输出也是文本。大模型可以"说出"一段正确的补丁,但"说出"不等于"改掉"。
要让大模型作用于真实工程环境,必须有一个执行者,把模型的意图翻译成动作,再把动作的结果翻译回文本。
工具调用就是这层翻译的标准形式:大模型输出一个结构化请求(调用哪个工具、参数是什么),ClaudeCode执行该结构化请求,再把执行结果作为新的上下文交还给模型。
工具调用循环
但是单次工具调用不足以完成任务,真实的工程任务靠循环完成。
一次循环有三个阶段,如果跑不通就带着新信息再来一轮。
- 收集上下文
搜索、读文件、看报错,弄清现状。 - 执行操作
改文件、跑命令。 - 验证结果
跑测试、检查产物;不满意,回到第一阶段迭代。
注意,这里循环的每一步都可以被打断。
(我们在使用ClaudeCode时候,按下的ESC,打断的就是这个循环。)
工具的五大类
ClaudeCode的内置工具可以分为五大类:
| 类别 | 代表 | 用途 |
|---|---|---|
| 文件操作 | Read、Edit |
读取、修改文件 |
| 搜索 | Grep、Glob |
按内容、按文件名定位代码 |
| 执行 | Bash(Windows下为PowerShell) |
运行构建、测试等任意命令 |
| 网络 | WebFetch |
抓取网页与在线文档 |
| 代码智能 | IDE类工具 | 诊断、跳转等编辑器能力 |
工具集决定了循环的能力边界:能读到什么、能跑什么,循环就能做成什么。
有限的上下文窗口
概述
循环每转一圈,读过的文件、命令的输出、模型自身的推理,都会进入上下文窗口,而窗口是有限的。
后续我们的讨论,都是如何在有限的上下文中,让ClaudeCode完成既定的任务。
一些斜杠命令
我们可能见过ClaudeCode的如下三个命令,这三个都是和上下文管理有关的。
/context:可视化当前窗口的占用情况,用来判断还剩多少空间、什么占了大头。/compact:压缩上下文。
在窗口接近上限时,ClaudeCode也会自动压缩早期对话,把老的往来内容替换成摘要(保留原始请求与关键代码)/model:模型切换。
会话中途切换模型,全部对话历史要在新模型上重新处理,之前积累的prompt cache(提示词缓存,对已处理过的上下文前缀的复用机制)无法复用。所以,切换后的下一轮会明显更慢、更贵。
安装
有四种安装方式,主要差别在于是否自动更新。
| 方式 | 适用平台 | 自动更新 |
|---|---|---|
| 原生安装脚本(curl) | macOS、Linux、WSL | 是 |
| 原生安装脚本(PowerShell) | Windows | 是 |
| Homebrew | macOS | 否 |
| WinGet | Windows | 否 |
示例代码:
1 | macOS / Linux / WSL |
1 | # Windows PowerShell |
启动命令
| 命令 | 行为 |
|---|---|
claude |
启动交互式REPL |
claude "task" |
启动REPL并直接下发第一个任务 |
claude -c |
续接最近一次会话 |
claude -p "query" |
非交互执行、输出后退出,面向脚本与CI,见《7.Headless》 |
进入会话后,有三种基本输入:
- 自然语言
直接描述任务,这是主要的交互方式。 @file
用@引用文件,把它加入上下文。注意:@只是加载内容,不授予修改该文件的权限。!前缀
以!开头的输入直接作为bash命令执行,不经过模型。
常用斜杠命令
会话内以/开头的输入是斜杠命令,用来控制ClaudeCode本身而非下发任务。
| 命令 | 作用 |
|---|---|
/help |
列出可用命令 |
/model |
查看与切换模型 |
/clear |
清空上下文,开启新会话 |
/resume |
从历史会话列表中选择并恢复 |
/compact |
手动压缩对话以节省token |
/context |
可视化上下文占用 |
/cost |
查看成本统计 |
/doctor |
诊断安装问题,按f可自动修复 |
/permissions |
交互式管理权限规则 |
/config |
打开设置界面 |
/diff |
交互式查看文件改动 |
/plan |
进入只读计划模式,探索但不修改源文件 |
/init |
生成CLAUDE.md,见《2.Memory》 |
权限系统
权限系统对每一次工具调用只做一个判断:直接放行、先问我、还是拒绝。做这个判断的是两套机制——全局的权限模式与精确的权限规则。本节先分别看这两套机制,再看它们如何合并成最终结果。
机制一:权限模式
权限模式是全局的默认姿态,同一时刻只有一种,Shift+Tab可循环切换。
最基础的是default模式,它按风险把工具分三层对待:
- 只读操作
读文件、搜索等,不提示,直接执行。 Bash命令
执行类操作,需要批准。- 文件修改
Edit等写操作,需要批准,批准后本会话内不再重复提示。
其余五种模式,本质是在这条基线上整体调松或调紧放行的尺度:
| 模式 | 行为 |
|---|---|
default |
首次使用某工具时提示(即上面的三层) |
acceptEdits |
自动接受文件编辑,以及mkdir、touch、mv、cp等文件系统命令 |
plan |
只读探索,不修改源文件 |
auto |
后台安全检查通过即自动批准(研究预览阶段) |
dontAsk |
自动拒绝,除非已通过/permissions预先批准 |
bypassPermissions |
跳过全部权限提示 |
bypassPermissions会让Claude Code不经任何确认地修改文件、执行命令。
机制二:权限规则
模式是一刀切的,权限规则则能精确到具体命令或路径,为个别工具调用单独定规矩。规则写在Settings的permissions字段里,或用/permissions交互式管理,分为allow、ask、deny三类。规则的格式是Tool或Tool(specifier):只写工具名匹配该工具的全部调用,括号里的specifier进一步收窄匹配范围。
示例代码:
1 | { |
三条典型规则的含义:
Bash(npm *)
匹配所有以npm开头的命令。放进allow后,跑npm test、npm run build不再需要逐次批准。Read(/src/**)
匹配对/src/目录下所有文件的读取。WebFetch(domain:*.com)
匹配对.com域名的网页抓取。
三类规则之间的评估优先级固定为deny > ask > allow:deny最先检查,命中即拒绝。deny没有例外机制——即便存在一条更具体的allow,也豁免不了;并且deny跨作用域生效,写在任何一层配置里都拦得住。如果需要给某个deny"开口子",唯一的办法是收窄这条deny的specifier本身。
另外,Bash里的一批常用读类命令内置了免提示放行:ls、cat、pwd、head、tail、grep、find、wc、cd。这批命令对应的正是default模式里"只读操作不提示"那一层;如果想对其中某条强制确认,可以为它写一条ask规则。
两者如何合并
对每一次工具调用,Claude Code先按规则判定,规则没管到的再交给模式兜底:
- 规则优先,顺序deny > ask > allow,任一命中即定,其中deny绝对优先、没有例外。
- 模式兜底,规则都没命中时由当前模式给出默认处置:
default就是上面那三层,acceptEdits让编辑自动放行,plan挡下所有写操作,bypassPermissions则连提示都不出、一路放行。
一句话:模式定下基线的松紧,规则在具体的点上再收紧或放开,而deny永远压在最上面。
Settings配置
上一节的规则要落到文件里。ClaudeCode的配置体系围绕settings.json展开,同一个字段可以出现在多个作用域,高优先级覆盖低优先级:
| 优先级 | 作用域 | 位置 | 生效范围 | 是否共享 |
|---|---|---|---|---|
| 1 | Managed | 由组织统一下发 | 全组织或整台机器 | 是 |
| 2 | CLI临时参数 | 启动claude时的命令行参数 |
本次会话 | 否 |
| 3 | Local | .claude/settings.local.json |
当前用户在本仓库 | 否 |
| 4 | Project | .claude/settings.json |
仓库全部协作者 | 是 |
| 5 | User | ~/.claude/settings.json |
当前用户的全部项目 | 否 |
Managed层不可被覆盖,这是企业锁定安全策略的手段;Project层随仓库提交,用来沉淀团队共识;个人偏好放User层;只属于自己、不想提交的本仓库设置放Local层。
关键字段:
| 字段 | 类型 | 作用 |
|---|---|---|
model |
string | 默认模型 |
defaultMode |
string | 默认权限模式,六种取值见上一节 |
permissions.allow/permissions.deny/permissions.ask |
array | 权限规则列表 |
permissions.additionalDirectories |
array | 工作目录之外额外允许访问的目录 |
env |
object | 注入会话的环境变量 |
enabledPlugins |
object | 插件开关 |
示例代码,my-project的项目级配置.claude/settings.json,让团队所有人共享同一套边界:
1 | { |
注意:大部分设置改动自动生效,不需要重启Claude Code。