第 08 期 | 实战:子 Agent 的召唤、授权与权限避坑
(申请发送: agentupdate)
避坑:依赖方向不能搞反! 本项目中曾误设
Task #2 blockedBy Task #1(Phase B blockedBy Phase A 是对的),但描述文本写了错误的依赖号导致 agent 困惑。blockedBy 中的 ID 必须是前置任务的 ID。
8.1 配置权限白名单
创建 .claude/settings.json:
{
"permissions": {
"allow": [
"Bash(ls:*)",
"Bash(cat:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(wc:*)",
"Bash(open:*)",
"Bash(which:*)",
"Bash(node:*)",
"Bash(npx:*)",
"Bash(npm:*)",
"Bash(python3:*)",
"Bash(git:*)",
"Bash(mkdir:*)",
"Bash(cp:*)",
"Bash(mv:*)",
"Bash(touch:*)",
"Bash(rm:*)",
"Bash(echo:*)",
"Bash(tmux:*)",
"Bash(bash:*)",
"Edit",
"Write",
"Read",
"WebSearch",
"Skill",
"Agent",
"SendMessage",
"TeamCreate",
"TeamDelete",
"TaskCreate",
"TaskGet",
"TaskList",
"TaskUpdate"
]
}
}
避坑:权限格式必须用冒号!
Bash(ls:*)是正确的,Bash(ls *)(空格)无效。
权限条目详解:
| 格式 | 含义 |
|---|---|
Bash(ls:*) |
允许以 ls 开头的所有 bash 命令 |
Edit |
允许文件编辑(无需参数限制) |
Write |
允许文件写入 |
Read |
允许文件读取 |
Skill |
允许调用 Skill(重要!) |
SendMessage |
允许 agent 间通信 |
Agent |
允许 spawn 子 agent |
8.1.1 Spawn Agent
ui-dev
Agent({
name: "ui-dev",
mode: "bypassPermissions",
team_name: "calc-dev",
prompt: `你是 ui-dev,负责 HTML 和 CSS 开发。
重要规则:
- 不要调用任何 Skill(不用 /planning-with-files、/brainstorming 等)
- 直接写代码,不要创建 plan 文件
- planning 已在 task_plan.md 里完成,你只负责实现
先读 requirement.md 了解需求。
你的第一个任务:创建 index.html
- 语义化结构:header(模式切换) + main(显示区 + 按钮网格) + aside(历史面板)
- 显示区:expression-line(id="expression") + result-line(id="result")
- 按钮网格:4×5 grid,每个按钮有唯一 id
- 数字:btn-0 到 btn-9
- 运算符:btn-plus, btn-minus, btn-multiply, btn-divide, btn-percent
- 功能:btn-equals, btn-clear, btn-backspace, btn-decimal, btn-toggle-sign
- 括号:btn-paren-left, btn-paren-right
- 模式切换:btn-mode-toggle
- 历史面板:id="history-panel",内含 id="history-list"
- 所有按钮加 aria-label
你的第二个任务:创建 style.css
- CSS 变量体系,[data-theme="senior"] 和 [data-theme="standard"] 两套
- 老年模式:按钮 28px+、显示 36px+、按钮 80×80px+、高对比黑白
- 标准模式:按钮 18-20px、显示 24px、按钮 48×48px、现代配色
- transition: all 0.3s 过渡动画
- 响应式:@media 断点 1024px 和 768px
每个任务完成时:
1. TaskUpdate 标记 completed
2. SendMessage 通知 team-lead
Working directory: /Users/eric/work/teamtest`
})
logic-dev
Agent({
name: "logic-dev",
mode: "bypassPermissions",
team_name: "calc-dev",
prompt: `你是 logic-dev,负责 JavaScript 计算引擎和交互逻辑。
重要规则:
- 不要调用任何 Skill
- 直接写代码
- Phase A 只写纯函数,不操作 DOM
先读 requirement.md 了解需求。
你的第一个任务:创建 app.js 计算引擎
- tokenize: 词法分析
- parseExpression: Shunting-yard 算法转 RPN
- evaluate: RPN 求值
- 输入辅助:appendNumber, appendOperator, appendDecimal, toggleSign, appendParenthesis
- 除零保护:返回 "Error"
- previewResult: 实时预览
- 单元测试(TDD)
你的第二个任务:DOM 事件绑定
- 通过 HTML 中的 id 绑定事件
- 键盘映射:0-9, +-*/, Enter, Backspace, Escape
- 模式切换:document.documentElement.dataset.theme + localStorage
- 历史记录:数组,10 条上限
- aria-live 结果播报
每个任务完成时:
1. TaskUpdate 标记 completed
2. SendMessage 通知 team-lead
Working directory: /Users/eric/work/teamtest`
})
避坑:为什么子 Agent 不能调用 Skill?
bypassPermissions只自动批准settings.json中allow列表里的操作。Skill 是独立于 TeamCreate/Agent/TaskUpdate 的工具调用,需要单独的Skill条目。但即使加了Skill条目,子 agent 调用 Skill 时仍可能触发权限请求弹窗(因为 Skill 内部可能包含未在 allow 列表中的操作链)。最佳实践:在 agent prompt 中明确写 "不要调用任何 Skill"。 规划工作在 team-lead 完成就够了,子 agent 只负责实现。
8.1.2 分配任务
TaskUpdate({ taskId: "1", owner: "ui-dev" })
TaskUpdate({ taskId: "2", owner: "ui-dev" })
TaskUpdate({ taskId: "3", owner: "logic-dev" })
TaskUpdate({ taskId: "4", owner: "logic-dev" })
8.2 避坑指南(核心问题与解决方案)
8.2.1 settings.json 权限格式
// ❌ 错误:空格分隔
"Bash(ls *)"
// ✅ 正确:冒号分隔
"Bash(ls:*)"
冒号格式是 Claude Code 识别的权限匹配语法。Bash(node:*) 表示允许所有以 node 开头的 bash 命令。
8.2.2 bypassPermissions 不等于万能通行证
mode: "bypassPermissions" 只跳过 settings.json allow 列表内 的工具的确认弹窗。
不在 allow 列表中的工具调用仍会触发权限请求。 特别是:
| 工具 | 是否在默认 bypassPermissions 范围内 | 解决方案 |
|---|---|---|
Bash(node:*) |
✅(如果在 allow 中) | 确保 settings.json 有该条目 |
Edit |
✅ | 加入 allow |
Write |
✅ | 加入 allow |
Skill |
⚠️ 即使加入 allow,内部操作链可能仍触发弹窗 | 在 prompt 中禁止调用 Skill |
Agent |
✅ | 加入 allow |
8.2.3 子 Agent 为什么不能调用 Skill
根本原因: Skill 工具的执行链涉及多个步骤(读取 skill 定义 → 解析参数 → 执行 skill 逻辑 → 可能触发额外工具调用)。bypassPermissions 只覆盖单层工具调用,不覆盖 Skill 内部的嵌套操作。
Agent 调用 Skill("planning-with-files")
→ Skill 内部读取 .agents/workflows/planning-with-files.md
→ Skill 内部可能调用 Write(创建 plan 文件)
→ Write 触发权限检查 ← 这里卡住!
解决方案:
- 最佳: 在 agent prompt 中写 "不要调用任何 Skill,直接写代码"
- 备选: 把规划工作在 team-lead 中完成,agent 只执行
- 不推荐: 尝试把所有可能用到的工具都加入 allow — 太脆弱