Gemini CLI 与 Claude Code 的权限与上下文模型
太长不看:Gemini CLI 把权限拆成「审批模式 + 策略引擎(TOML 规则 + 数值优先级)」两层;Claude Code 是一套 JSON 规则,按 deny → ask → allow 的固定顺序评估,规则具体程度不改变顺序。上下文文件两者都默认 GEMINI.md / CLAUDE.md 三段式,但 Claude 会一路向根目录拼接父级 CLAUDE.md,Gemini 走目录扫描加 JIT 加载。下面每条都标了出处与实测条件。
我实测的口径
版本号不是模糊的「最新版」,是我本机 npm 装完后用 --version 跑出来的真实输出,日期 2026-10-18:
- gemini: 0.64.0(
@google/gemini-cli@0.64.0,engines 要求node >=20) - claude: 2.1.302 (Claude Code)(
@anthropic-ai/claude-code@2.1.302)
环境是 Windows 11 + Node v24.15.0。两个包分别 94.0 MB(449 个文件)与 276.9 MB(约 2.9 亿字节,7 个文件);gemini --help 全文 3989 字符、29 个参数,claude --help 是 22102 字符、78 个参数,后者接近前者的 2.7 倍,这个量级差本身就说明了两家的取向。
需要先说清楚:我没有 Gemini 与 Anthropic 的可用 API Key,所以本文不涉及模型回答质量,只测命令能不能起、配置怎么被解析、报错长什么样。所有退出码都是本机跑出来的真实数字。
权限第一层:谁能改你的文件
Gemini CLI 的入口是审批模式,--approval-mode 只接受四个值(0.64.0 --help 原文):default(每个工具调用都要问)、auto_edit(编辑类自动放行,其余继续问)、yolo(全部放行)、plan(只读)。
这里有个容易踩的点:yolo 不能写进 settings.json。settings 表里给了 general.defaultApprovalMode,但校验报错的原文是 Invalid enum value. Expected 'default' | 'auto_edit' | 'plan', received 'yolo'(退出码 1)。想无脑放行只能在命令行给 --yolo 或 --approval-mode=yolo;反过来想彻底禁掉,写 "security": {"disableYoloMode": true},源码里它和 admin.secureModeEnabled 是或的关系。
Claude Code 的对应物是权限模式,六档:default、acceptEdits、plan、auto、dontAsk、bypassPermissions。官方文档对 default 的描述是「Prompts for permission on first use of each tool」,CLI 里显示为 Manual,manual 是它的别名。
一个版本相关的坑:文档明确写了 auto 与 bypassPermissions 从项目或 local 设置里不生效,必须写进 user 或 managed 设置,或者用 --permission-mode 临时给;并注明「Before v2.1.257, bypassPermissions took effect from any file」。也就是说 2.1.257 之前你写在项目 .claude/settings.json 里的 bypassPermissions 是能用的,升级之后静默失效。想从根上禁掉,设 permissions.disableBypassPermissionsMode 或 permissions.disableAutoMode 为 "disable"。
权限第二层:规则写在哪、谁赢
这层两家思路完全不同。
Gemini CLI 的规则是 TOML,放在 ~/.gemini/policies/*.toml:
[[rule]]
toolName = "run_shell_command"
commandPrefix = "git"
decision = "ask_user"
priority = 100
决胜靠优先级:final_priority = tier_base + (toml_priority / 1000),tier 从低到高是 Default(1) / Extension(2) / Workspace(3) / User(4) / Admin(5)。
⚠️ 官方文档在这段自相矛盾,我按原文照抄不作取舍:tier 表给 Admin 的 base 是 5、User 是 4,同页下面的例子却写「User 的 priority 100 变成 3.100」「Admin 的 priority 20 变成 4.020」,而 Admin 小节又把 Admin 称作 "Tier 4"。三处对不上,真要做企业级下发,建议自己写一条高 priority 规则实测一遍,别照文档推断。
更要紧的是这段原文警告:Workspace tier(.gemini/policies)当前是坏的,官方直接写了 "currently non-functional ... will not have any effect",并指向 issue #18186。想给某个仓库单独下发策略,目前只能落在 User 或 Admin 层。
Claude Code 的规则是 JSON,写在 settings.json 的 permissions 里:
{
"permissions": {
"allow": ["Bash(npm run test *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
评估顺序固定,官方文档原话:「Rules are evaluated in order: deny, then ask, then allow. The first match in that order determines the outcome, and rule specificity doesn't change the order.」翻成白话:一条宽 deny 会吃掉一条窄 allow,你没法用 Bash(aws s3 ls) 的 allow 去开 Bash(aws *) 的 deny 一个口子;ask 同理压过 allow。跨作用域也一样,用户级 deny 压过项目级 allow。
对比下来最实用的一句话:Gemini 是「谁的数值大谁说话」,Claude 是「deny 永远最大」。前者灵活但要自己算数,后者死板但不会算错。
另外三个细节值得记:
1. Gemini 的全局 deny(不带 argsPattern)有个副作用是好事:官方说这会把工具「从模型的记忆里完全移除」,模型连这个工具都看不到,省上下文。
2. Claude 的文件路径规则只认 Edit(path) 与 Read(path)。写 Write(docs/) 会被接受但永远不被查询,启动时给警告,官方要求改用 Edit(docs/)。
3. 通配符位置有讲究:Claude 的 Bash(git *) 放行所有 git 子命令,Bash(git log *) 只放行 git log。文档原话是 "Put the * after the subcommand"。
信任模型也不同。Claude 里项目 .claude/settings.json 的 allow 规则要等你在工作区信任对话框里确认后才生效,deny 与 ask 立刻生效;Gemini 的 folderTrust 则直接决定 headless 能不能起来,这条放到报错二讲。
上下文文件:同名不同命
两家都用一个 markdown 文件当项目记忆,默认名分别是 GEMINI.md 与 CLAUDE.md,都可以改(Gemini 是 context.fileName,可以填数组;Claude 另外认 AGENTS.md)。加载范围差别很大:
| Gemini CLI | Claude Code | |
|---|---|---|
| 全局 | ~/.gemini/GEMINI.md | ~/.claude/CLAUDE.md |
| 项目 | 工作区与父目录中的 GEMINI.md | ./CLAUDE.md 或 ./.claude/CLAUDE.md |
| 私有 | 私有记忆目录 | ./CLAUDE.local.md(建议进 .gitignore) |
| 规则目录 | 无 | .claude/rules/**.md、~/.claude/rules/ 递归发现 |
| 组织下发 | Admin 系统目录 | managed CLAUDE.md(Windows 在 C:\Program Files\ClaudeCode\CLAUDE.md) |
| 按需加载 | 工具访问某目录时扫该目录及祖先(JIT) | 子目录文件在读写该目录内文件后才加载 |
| 导入语法 | @file.md | @path,递归最多 4 跳 |
两个容易被忽略的差异:
- 父目录拼接:Claude 明确写了「从文件系统根一路向下拼到你的工作目录」,所以
~/work/CLAUDE.md里写的东西,进到~/work/proj也会带上;Gemini 的层级描述是「全局 → 工作区与父目录 → JIT」,实际行为要先在目标机器上验证。 - 大小上限:Claude 写了「loads a CLAUDE.md file of up to 4 MiB in full and skips a larger file」,超限整个文件跳过;Gemini 官方文档我没找到对应数字,不确定就不要自己加限制。
自动记忆这块也能看出取向。Claude 的 auto memory 每次会话自动带 MEMORY.md 的前 200 行或 25KB(先到先算);Gemini 的 Auto Memory 标注为 experimental 且默认关闭,要手动开 experimental.autoMemory,触发条件还挺苛刻:会话需空闲至少 3 小时且含至少 10 条用户消息,而且只把候选写进 inbox,不经批准不碰任何记忆文件。一个是默认帮你记,一个是默认不记、记了也要你点头。
顺手放三篇本站之前的上下文管理文章,配合着看更完整:Claude Code 上下文窗口管理 讲 200K/165K 的实际可用空间,65K token 余量怎么省 讲压缩策略,CLAUDE.md 与 Skills 该怎么分工 讨论了这个文件到底该写多长。
报错一:退出码 41,没配认证方式
现象(headless 下 -p):
Please set an Auth method in your /.gemini/settings.json or specify one of the following environment variables before running: GEMINI_API_KEY, GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_GENAI_USE_GCA
原因:GEMINI_API_KEY 为空且 settings 里没有 security.auth。处理:在用户 settings 里配 security.auth.selectedType,或显式 export GEMINI_API_KEY=...。注意别把它塞进项目 .gemini/settings.json,那样会被 folderTrust 拦在门外(见下一条)。
报错二:退出码 55,headless 里工作区不被信任
现象:
Gemini CLI is not running in a trusted directory. To proceed, either use `--skip-trust`, set the `GEMINI_CLI_TRUST_WORKSPACE=true` environment variable, or trust this directory in interactive mode.
这是 CI 里最容易卡住的一条。三种解法我都实测过:加 --skip-trust;设 GEMINI_CLI_TRUST_WORKSPACE=true;或在用户 settings 里显式写 "security": {"folderTrust": {"enabled": true}} 并预先登记目录。
⚠️ 顺带挖到一个官方文档的自相矛盾:trusted-folders 文档写「The Trusted Folders feature is disabled by default」,settings 表却给 security.folderTrust.enabled 默认值 true,而 0.64.0 的源码 isFolderTrustEnabled 是 settings.security?.folderTrust?.enabled ?? true。我用一个全新目录测试:不写任何设置直接 -p,拿到的就是这条 55;把 folderTrust 显式设成 false 后,命令行继续往下走到了认证阶段。实际默认是开启的,trusted-folders 那页文档滞后。 结论:CI 里别依赖默认值,显式给 --skip-trust 或环境变量,版本升级也不会翻车。
报错三:退出码 52,settings.json 语法错
现象:
Error in /.gemini/settings.json: Expected double-quoted property name in JSON at position 44 (line 1 column 45)
Please fix the configuration file(s) and try again.
比 Claude 那边更硬:整个 CLI 起不来。而且报错给的是字符位置不是行号,长文件里找起来很烦,建议先 python -m json.tool 过一遍。
报错四:想在 settings.json 里默认开 YOLO
现象(退出码 1,但仍会继续执行):
Invalid configuration in /.gemini/settings.json:
Error in: general.defaultApprovalMode
Invalid enum value. Expected 'default' | 'auto_edit' | 'plan', received 'yolo'
原因前面说过,yolo 只接受命令行形式。要长期生效就写 --approval-mode=yolo(或 --yolo),要永久禁止就 security.disableYoloMode: true。
报错五:CI 里工具静默被拒
这不是一条报错文本,是策略引擎的语义坑。官方文档原文:ask_user 决策「In non-interactive mode, this is treated as deny」。也就是说你在本地交互时习惯让模型问你一声,到了 -p 的 CI 里会直接被拒,而日志未必告诉你为什么。
处理:CI 里显式下发 allow 规则(User 或 Admin tier),或者对个别命令写 commandPrefix 规则覆盖默认的 ask_user。不要指望 --yolo 兜底,那条路在 security.disableYoloMode 打开时会被降级成 default。
报错六:Claude 的 permissions.allow 类型写错,整个文件失效
现象(退出码 1):
Not logged in · Please run /login
These settings files did not load, so nothing in them is in effect, including hooks and permission rules. Each loads again once the problem listed for it is fixed:
/claude/settings.json (permissions.allow): Expected array, but received string
我测试时把 permissions.allow 写成了字符串。注意这句的严重性:hooks 一起失效,不只是权限。修成数组即可。排查时优先看这段提示,它比任何日志都直接。
报错七:两个 CLI 的家目录会互相污染
同时测两个工具时,这次实测时我一开始只设了 GEMINI_CLI_HOME,结果 Claude 照旧往 ~/.claude 里写。正确做法是分别重定向:
$env:GEMINI_CLI_HOME = "D:\tmp\gcli\home"
$env:CLAUDE_CONFIG_DIR = "D:\tmp\gcli\home\claude"
实测首次运行的落盘差异:Gemini 只生成 .gemini/projects.json(72 字节)与 history/、tmp/ 下的 .project_root;Claude 会写 .claude.json(719 字节,含 machineID 与 userID)、backups/.claude.json.backup. 以及 projects/<路径>/ 会话记录(单条 80 KB 上下)。做沙箱或 CI 缓存时这个差异要算进去。
迁移对照表
从 Claude Code 切到 Gemini CLI,或者反过来,可以照这张表改:
| Claude Code | Gemini CLI |
|---|---|
permissions.allow: ["Bash(npm test *)"] | TOML toolName="run_shell_command" + commandPrefix="npm test" + decision="allow" |
permissions.deny: ["Read(./.env)"] | 同上 decision="deny"(全局 deny 还会把工具从模型视野移除) |
--dangerously-skip-permissions | --yolo 或 --approval-mode=yolo |
--permission-mode plan | --approval-mode plan |
permissions.defaultMode | general.defaultApprovalMode(不接受 yolo) |
| managed settings | Admin tier 策略 + 系统级 settings(Windows 在 C:\ProgramData\gemini-cli\policies) |
--add-dir | --include-directories |
项目 .claude/settings.json | 项目 .gemini/settings.json(folderTrust 未信任时被忽略) |
CLAUDE_CONFIG_DIR | GEMINI_CLI_HOME |
FAQ
Q: 两个能同时装在一台机器上吗?
A: 能,我这次就是同时装的。但家目录要分开(见报错七),否则排查配置时会互相干扰。
Q: 项目级的策略下发,哪家现在能用?
A: Claude 可以用 .claude/settings.json 提交进仓库(allow 需等工作区信任确认);Gemini 的 Workspace tier 官方标注为 non-functional(issue #18186),目前只能走 User 或 Admin 层。
Q: 想让某个工具彻底不出现在模型视野里,怎么做?
A: Gemini 写一条不带 argsPattern 的 deny,官方明确说这会把工具从模型记忆里移除;Claude 侧 Bash(*) 作为 deny 时「remove the tool from Claude's context」,效果类似。
Q: 上下文文件写多大合适?
A: Claude 给了硬指标:单个 CLAUDE.md 超过 4 MiB 整个跳过,官方还提示 "Shorter files produce better adherence"。Gemini 侧我没查到官方上限,建议自己保守一点。
Q: 版本信息以哪个为准?
A: 以 gemini --version / claude --version 的实际输出和 npm registry 为准。第三方教程的版本号经常滞后,本文所有数字都是 2026-10-18 在本机实测得到的。
写到最后
这两家的差异不在「谁更安全」,而在你把决策权放在哪:Gemini 把决定权交给一套可算优先级的规则文件,适合要集中下发、分级管控的团队;Claude 把决定权交给 deny-first 的固定顺序和逐条提示,适合想让规则行为可预测、宁可多问一句的人。
如果你的场景是 CI,先解决 folderTrust(报错二)和 ask_user 静默变 deny(报错五)这两条,其余都是配置习惯问题。
👉 立即参与小米 MiMo 开放平台:国内领先的 AI 大模型开放平台,高性价比推理服务
👉 立即参与阿里云 AI:汇集爆款 AI 产品,热门模型专属权益优惠券助力企业创新加速
📌 本文由 AI 辅助生成并经人工审核发布 | TechPassive — AI 驱动的内容测试站点,专注于效率工具与 SaaS 真实评测
🔗 精选推荐工具
使用以下链接支持我们持续产出高质量内容(点击可直接前往购买):