DeepDojo.AI发布 2026-11-13更新 2026-11-13English

Claude Code 跑在 CI 里,权限怎么设

Claude CodeAI 编程

平时在交互终端里和 Claude 对话,感觉很自由:下一步怎么走没想好,可以多问两句;缺什么文档随时补;改完代码还能当场扫一眼,再决定要不要继续。

换到“每天半夜跑定时巡检、自动分析几百行构建报错”这种固定场景,事情的性质就变了:输入是现成的日志文件,输出是给报警系统消费的摘要。这时候还得半夜手动开个窗口敲回车,你就成了人肉转接器。

边界和格式已经固定的重复工作,很适合交给脚本:

  • CI 跑完单元测试后自动提炼失败堆栈;
  • 本地脚本批量扫描代码,提出测试补丁建议;
  • 定时任务拉取慢查询日志,输出格式化的 JSON 告警。

难点在于,把键盘交给脚本的那一刻,就没人替你看权限提示了。交互里随手点的“允许”,在无人值守时要么卡住整个流程,要么被一刀切地跳过。办法是先从只读分析起步,再按脚本的实际动作逐项设权限:模型能拿到哪些工具、哪些调用不用确认、哪些动作要单独拦住,最后给轮次、预算和并发加上上限。

01 一次 CLI 调用经过哪些环节

在终端输入 claude 时,你用的就是 CLI,也就是命令行接口。一个 CLI 调用可以拆成这条链路:

命令行输入
  |
  v
claude [options] [query]
  |
  v
选择模式:交互 / print
  |
  v
加载上下文、模型、权限、MCP、agents
  |
  v
生成输出:text / json / stream-json
  |
  v
终端显示、脚本处理、CI 消费或管道传给下一个命令

下面的命令会启动交互式会话,也可以带一个初始问题启动:

claude
claude "解释这个认证流程"

如果任务要把一次请求的结果交给脚本,就用打印模式,输出后退出:

claude -p "这个函数做什么?"

你可以把文件内容通过管道传进去,也可以把输出继续交给其他工具:

cat error.log | claude -p "解释这些错误并给出修复建议"
claude -p "列出待办事项" | grep "URGENT"

开始只需分清:要接着讨论,用 claude;要让脚本接结果,用 claude -p。恢复会话、登录、管理 MCP、后台会话或插件,遇到时再查对应入口。

02 交互模式和打印模式怎么选

交互模式适合需要人持续判断的任务,例如探索架构、逐步重构、比较方案,或让 Claude Code 先读代码再提计划。打印模式适合一次性、可脚本化的任务,例如解释日志、总结测试失败、输出 JSON、生成固定格式报告或批量分析文件。

模式启动方式特点适合场景
交互模式claude多轮对话、历史记录、Tab 补全、slash commands探索、讨论、重构、人工确认
打印模式claude -p单次查询、可管道化、可输出 JSON脚本、CI、批处理、机器消费

把两类任务放在一起想。支付模块偶发重复扣款,当前还不知道根因,要不断追证据、排除假设,交互会话便于接着谈。每晚总结构建日志,材料和用途早已确定,打印模式就能把结果交给脚本。

打印进程退出后,如果直接发起新请求继续追问,前面的结论未必还在。恢复会话或传入必要结论,才有条件接着做;否则可能重复读一遍代码。

无人值守先从只读分析、日志总结和格式化输出开始。文件修改、部署、推送、删除和数据迁移涉及实际状态,要把人工确认留在相应动作前。

03 -p 退出得快,内部仍然是多轮

-p(print)在打印结果后退出进程,一次调用内部仍可能包含多轮推理和工具交互。

比如你让它“审查这个函数并报告隐患”,它得先调用 Read 工具读文件,发现引用了外部工具类又得去 Grep 跨文件定位,必要时还要在终端里跑测试,最后才把综合分析结果打印出来。

所以给脚本设置轮次上限和预算时,要站在“完成整条业务链路”的视角来衡量。如果随手写一个 --max-turns 1,它可能刚用工具读完第一个文件就因为轮次耗尽被掐断,最终吐出一个半截报告。

拿到脚本输出后,也得回过头扫一眼工具调用日志,确认它在报告里声称“跑过测试”“翻过源码”的结论,是真的查过,还是凭空推断出来的。打印模式省下的是人机交互的等待时间,排查过程本身的步骤一步也没少。

04 按实际动作逐项设权限

无人值守任务缺少现场确认,权限边界因此更重要。CLI 提供了几类控制参数:

参数作用
--tools限制可用的内置工具,"" 表示全部关闭
--allowedTools指定无需提示即可执行的工具
--disallowedTools拒绝规则:写工具名会把它从可用工具里移除,写带范围的规则只拒绝匹配的调用
--permission-mode用指定权限模式启动
--permission-mode auto由自动权限机制判断调用风险
--dangerously-skip-permissions跳过权限提示,高风险

配置前先判断任务风险。只读分析只开放读取工具;修改文件或外部系统的任务,还要明确无需提示的允许项和禁止项。

假设无人值守任务是“每晚审查新增代码并生成报告”,可按实际动作确定权限:

  • 保留 Read、Grep、Glob,用于阅读代码。
  • 允许必要测试命令,例如 Bash(npm test *),避免无人处理确认。
  • 用 --disallowedTools "Edit,Write" 移除编辑工具。
  • 拒绝不属于报告任务的 push 和部署操作。

下面分别演示权限设置,它们不是一条可复制即用的完整安全策略:

# 只读审查
claude --permission-mode plan -p "审查这个代码库"

# 只允许读取和搜索
claude --tools "Read,Grep,Glob" --disallowedTools "mcp__*" -p "找出所有 TODO 注释"

# 允许特定 git 查询,无需提示
claude --allowedTools "Bash(git status *)" "Bash(git log *)"

# 阻止危险命令
claude --disallowedTools "Bash(rm -rf *)" "Bash(git push --force *)"

回到“每晚只出报告”的任务,先逐项问:模型还能拿到哪些工具,哪些调用不用确认,还有哪种能力需要另外限制?按 Claude Code 的 CLI 参考,--tools 只筛内置工具,MCP 工具要用 --disallowedTools "mcp__*" 单独拒绝;--allowedTools 只免去提示,没列出的工具并不会因此消失。这和斜杠命令里 allowed-tools 的原理相同,详见Claude Code 只读命令为什么还能改文件。

再看拒绝列表。只写 rm -rf 和强推两种写法,其他等效命令仍可能没覆盖。Plan 模式适合先分析,外部账号却仍需自己的只读权限。工具、命令和账号各管一段,只收紧其中一项,代替不了其余检查。

检查仍需确认的操作能否从任务中移除;无法收紧的部分,安排在有人值守的流程中。权限范围要覆盖脚本的实际效果,不能只看名称。若某步还要等待确认,就考虑把它移出无人值守流程,跳过提示并不等于获得授权。

--dangerously-skip-permissions 只适合在可随时销毁重建的沙盒或一次性容器里使用。在日常主机上给无人值守脚本这样的权限,会让文件、远端仓库、生产部署和核心数据库面临风险,先在权限层限制这些操作。

05 留意那些不经过工具也会运行的东西

权限参数管的是模型调用的工具,有些内容在调用开始时就会自己运行。官方的 Claude Code 程序化运行文档提醒:不加 --bare 时,claude -p 会像交互会话一样加载项目配置,运行 .claude/settings.json 里的 Hook、连接 .mcp.json 里的服务器,即使是在一个从未信任过的文件夹里,而且打印模式不会弹出信任对话框。

所以即使把模型的内置工具和 MCP 都关了,配置里的 Hook 仍可能执行。选择可信目录,把这部分副作用单独查过,再谈这次分析是不是只读。

--bare 能排除这些干扰,先看看它会一起拿掉什么:Hooks、Skills、插件、MCP、自动记忆和 CLAUDE.md 都会跳过,订阅登录凭据和系统钥匙串也不会读取,使用 Anthropic API 时需要另给 ANTHROPIC_API_KEY。配置少了,测试条件也变了;先确认规则与认证来源,再决定用不用它。

--no-session-persistence 只决定是否留下可恢复的会话记录。CI 只要当前结果时可以用它,但不能因此推断磁盘或外部状态也被隔开了。

06 目录、MCP 和模型参数只给当前任务需要的

工作目录和外部工具同样会扩大范围。规范做法是先 cd 进项目目录再启动,跨仓库任务再按需追加:

参数作用
--add-dir追加可见目录
--mcp-config从文件加载 MCP 配置
--strict-mcp-config仅使用 --mcp-config 提供的 MCP 配置
# 在后端目录工作,同时读取前端目录
(cd ./backend && claude --add-dir ../frontend)

# 严格只启用指定 MCP
claude --strict-mcp-config --mcp-config ./configs/strict-mcp.json

括号让 cd 只影响这次调用;相对路径按进入后的目录解释。严格 MCP 示例要求配置文件里只包含本次需要的服务。多目录和 MCP 会同时扩大上下文与权限范围,自动化脚本只加载当前任务必需的部分。

模型参数同样按需调整。--model 指定模型,--fallback-model 在主模型不可用或负载过高时换用后备模型,--effort 设置推理强度。普通批处理沿用默认值即可;复杂架构、排错或审查任务再调整。只指定一个高负载模型可能提高失败率,配置后备模型能增加可用性,但后备模型也要足以完成任务。

如果某次 CLI 会话需要临时使用一个只读的审查角色,可以用 --agents 传入 JSON 定义,再用 --agent 指定。定义里用 tools 只给 Read、Grep、Glob,用 description 和 prompt 写清调用时机与方法;临时定义只作用于本次会话。

07 批处理先定三个上限

当文件数量成百上千时,稍不留神就会碰上 API 限流或预算失控。在脚本全量放开跑之前,先定三个上限:

控制项限制什么
轮次单项工作量
预算费用
并发同时运行的数量
# 处理多个文件,每个文件限制轮次和预算
find src -name "*.ts" -print0 | xargs -0 -I{} claude -p --max-turns 5 --max-budget-usd 1 "review {}"

这里的数值只是示例,不能当成所有任务的推荐值。官方说明 --max-budget-usd 按客户端估算的花费判断,实际花费可能越过上限,要留出余量。

先用一小批文件试跑,看清失败项和成本,再定上限;直接扩大批次,可能会让尚未查清的问题更难处理。失败项仍由人决定缩小输入还是重试。

环境变量适合统一脚本环境,比如 ANTHROPIC_MODEL 设默认模型、CLAUDE_CODE_EFFORT_LEVEL 设推理强度。准备在另一台机器运行时,沿脚本确认三件事:在哪里执行、输出交给谁、使用哪份 MCP 配置,分别用 cd、--output-format 和 --mcp-config 明确写出。真实密钥由安全的环境配置注入,不写进教程、仓库和命令模板。

出故障时,先按失败位置选择检查:

现象先查什么
找不到 claude安装、PATH,再重开终端
登录或 API key 失败认证状态、有效期与 API 网络
找不到会话名称、ID、账号,以及是否用了 --no-session-persistence
权限拒绝--permission-mode、--allowedTools、--disallowedTools,按任务补最小权限
MCP 不可用配置路径、server 名和本次是否启用

权限设好之后,脚本拿到的结果还要校验:JSON 能解析、调用没报错,结论是否有依据仍是另一回事。这一步接着看 校验 Claude Code 输出的 JSON。

半夜那次巡检能放心交给脚本,靠的是权限覆盖了它真正会做的每一个动作;仍要等人确认的那一步,就留在白天有人值守的流程里。