跳转到内容

配置与权限覆盖(多层 merge)

权限与角色行为来自多层配置的合并结果,而不是单一文件。后加载的层覆盖先加载的层;显式 permission 覆盖由旧式 tools 布尔映射来的规则。单次 prompt 仍可再收窄工具集;最终在 resolveTools 与权限询问处收口。

大致从低到高:

flowchart TD
R[远程 / 全局配置目录] --> F[配置文件指定路径]
F --> P[项目 agentforge 配置]
P --> A[目录内 agent / command 扫描]
A --> C[配置内容环境变量]
C --> H[托管 / 账号配置]
H --> M[托管策略最高优先]

项目侧优先读写 .agentforge/ 与 agentforge.json(c);若磁盘上仅有历史目录布局,仍可读旧路径以免拆散已有配置。环境变量使用 AGENTFORGE_* 族(含配置路径与内容覆盖)。

机制含义
permissionallow / deny / ask,可带路径或命令 pattern
tools(旧)布尔开关,加载时折算进 permission

同一角色内:先把 tools 转成 permission,再与显式 permission 合并,显式项获胜。例如 tools.bash=true 且 permission.bash=ask 时,结果为 ask。全局 tools 同样折算进全局 permission。运行时还可用权限相关环境变量做强制覆盖。

全局 permission.bash=allow,项目 permission.bash=deny → 项目后加载 → deny。

规则值可以是单个动作,也可以是 pattern 到动作的映射。字符串等价于 pattern: "*";嵌套对象里的每个 pattern 各成一条规则,匹配用通配符,同一权限取最后命中的那条。

{
"permission": {
// 读一律放行
"read": "allow",
// 写入默认禁止,只放开本项目 reports 目录
"edit": { "reports/**": "allow", "*": "deny" },
// shell 只自动放行只读命令,其余每次询问
"bash": { "git status": "allow", "git diff *": "allow", "*": "ask" },
// 不派子任务
"task": "deny"
}
}

配置只给默认值。同一条会话里,某一轮可以在请求上带 tools: { bash: false },折算成 bash 的 deny("*"),这一轮模型看不到 shell;下一条请求不带该字段即恢复。

规则模型能否看到工具执行时行为
deny 且 pattern 为 *看不到,整工具从本轮工具表移除不会被调用
deny 且 pattern 具体(如只禁某目录)能看到命中被禁路径时执行被拒,并带原因回填
ask能看到执行前发出询问,决定后才继续

因此模型看不到某工具与该工具被拒绝是两段不同的现象:前者查 resolveTools 与整工具 deny,后者查执行期规则命中与询问流。

  • default_agent:未指定角色时的主角色
  • agent.{name}:模型、提示词、步数上限、permission、变体等
  • 历史 mode.* 会并入同名主角色;mode 文档扫描结果同样并入 agent 表

配置只提供默认规则。单次 prompt 的 tools 输入、会话级 permission,以及执行期 Permission.ask,在运行时继续收口。结构化输出不会因自然语言描述自动出现,需 API 显式传 format。见Processor 与 LLM 适配。

flowchart LR
Cfg[合并后的 permission] --> RT[resolveTools]
In[单次 input.tools] --> RT
RT --> LLM[模型可见工具]
LLM --> Exec[execute]
Exec --> Ask[ask / deny / allow]

复核:改完项目配置后确认实例已按目录重新加载;只改文件不触发重载时,进程内仍可能持有旧合并结果。见实例边界与并发调度。


相关阅读: