[Feature] Agent 节点工具调用策略:按命令前缀/路径声明 allow·deny·ask 规则,高危操作拦截或转人工审批
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 15/100
Direção de pesquisa
This is design work spanning several subsystems, so read the referenced files first: internal/runtime/hooks.go (materializeAgentHooks), internal/domain/agent.go (AgentHook), internal/engine/node_outcome.go (waiting_approval), and the provider files for Claude Code, CodeBuddy and Codex. Agree on the policy model and the three-level merge order with a maintainer before coding. Done means the acceptance checklist in the issue passes, starting with the check endpoint and policy unit tests.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
背景与借鉴来源
无人值守的 Agent 节点在沙箱里执行 shell 和文件写入。沙箱能隔离宿主,但挡不住在工作区和已授权的远端上做的高危操作:git push --force、删分支、rm -rf 仓库目录、改 CI 配置或 migrations/、kubectl/terraform apply、curl … | sh 等。主流 Agent 都在「全放开」和「每步都问」之间加了一层声明式工具调用策略:
- openai/codex(https://github.com/openai/codex ,约 135k★,当天仍有提交):
codex-rs/execpolicy用prefix_rule(pattern=[...], decision=allow|prompt|forbidden, justification=...)按命令前缀判定;forbidden时把justification(如「请用 jj 代替 git」)回给模型;规则自带match/not_match样例,加载时当单测校验。 - google-gemini/gemini-cli(https://github.com/google-gemini/gemini-cli ,约 109k★,当天仍有提交):Policy Engine 用 TOML 规则(
toolName、commandPrefix/参数匹配、decision = allow|deny|ask_user、priority),用户级、管理员级多层合并,优先级高的规则生效。 - OpenHands/software-agent-sdk(https://github.com/OpenHands/software-agent-sdk ,OpenHands 约 93k★,SDK 当天仍有提交):
security/confirmation_policy.py提供AlwaysConfirm/NeverConfirm/ConfirmRisky(threshold),按动作风险等级决定是否要人工确认。 - anthropics/claude-code(约 155k★):
permissions.allow/deny/ask支持Bash(git push:*)、Edit(./migrations/**)这种细粒度规则,PreToolUse hook 可返回permissionDecision: deny。
LoopForge 现状与不足
- 所有执行器都强制全放开:
internal/runtime/provider_claude.go的Prepare固定改成--permission-mode bypassPermissions;internal/runtime/provider_codebuddy.go的isolateCodeBuddyFlagsWithSource固定加-y和bypassPermissions;internal/runtime/provider_codex.go在 docker/bwrap 下改成--sandbox danger-full-access。
这对无人值守是必要的,但结果是 SOP 节点里任何命令都不会被拦下,平台也没有统一的地方补拦截。
- 只能靠每个 Agent 自己写 hook 脚本:
domain.AgentHook(internal/domain/agent.go)+internal/runtime/hooks.go的materializeAgentHooks支持 PreToolUse 脚本,但要每个角色手写 shell/python、不同 CLI 的输入输出格式各不相同、没有平台/项目级统一配置、没法审计「拦了什么」。Main Bot 的 PreToolUse 拦截(internal/httpapi/assistant_provider.go、assistant_engine_cli.go)只用于助手会话,不覆盖 SOP 节点。 - 没有「需要人工确认」这条路:引擎已有
waiting_approval(internal/engine/node_outcome.go)和干预点HumanInterventionPoint,但干预点只能挂在before_execution/after_execution/before_publish阶段,不能「执行到某条高危命令时」暂停等人批。 - 现有相关 issue 都不覆盖这块:#226 管沙箱出网域名,#227 管推送前密钥扫描,#258 管停滞/打转,#223 管 Token 预算。
建议方案
- 策略模型(
internal/domain新增ToolPolicy,归CatalogRepo管理):规则字段
tool(shell/edit/write/mcp:<server>/<tool>)、commandPrefix(按 token 前缀,支持备选)、pathGlob(文件类工具)、decision(allow/deny/ask)、priority、justification、examples.match/notMatch。
作用域:平台默认 → 项目 → Agent 角色,按优先级合并;平台可标记某些deny规则为「不可被下层覆盖」。 - 内置默认规则集(可关):
git push --force*/git push * :branch、rm -rf /及工作区根、curl|wget … | sh、改.github/workflows/**、.gitlab-ci.yml、migrations/**等给出deny或ask建议值。 - 统一执行点:在
materializeAgentHooks阶段为每个节点自动注入一个平台 PreToolUse 守卫(复用 Main Bot 守卫的做法),守卫读物化后的策略 JSON 做判定,按 Claude Code / CodeBuddy / Codex 各自的 hook 协议返回结果;不支持 hook 的执行器(opencode、cursor 等)在节点详情里标「策略未生效」,项目可配置「要求策略生效,否则拒绝运行」。 - 三种结果的处理:
deny:拒绝该调用,把justification作为拒绝原因回给模型,让它换做法;ask:拒绝本次调用并结束当前轮,节点进入waiting_approval,审批卡片展示命令、工作目录、命中规则;批准后通过 resume 会话放行该命令(一次性 allow token),拒绝则把原因作为反馈继续;allow:放行。
- 审计:每次命中写
policy.decision事件(规则 ID、工具、命令摘要、结果),节点详情和运营分析里可查「被拦/被审批」的次数。 - 策略测试:保存策略时校验
examples;提供POST /api/tool-policies/check输入命令返回命中结果,便于配置前试跑。
验收标准
- 可以在平台、项目、Agent 三级配置策略,合并顺序和「不可覆盖」标记有单测覆盖;保存时
examples.match/notMatch不符会报错。 - Claude Code、CodeBuddy、Codex 三种执行器下,节点执行
git push --force origin main时被拦截,模型能收到justification,事件里有policy.decision=deny。 -
ask规则命中时节点进入waiting_approval,审批卡片能看到命令和命中的规则;批准后该命令得以执行、节点继续;拒绝后原因作为反馈回到 Agent。 - 不支持 hook 的执行器在节点详情显示「策略未生效」;开启「要求策略生效」时这类节点启动即失败并给出明确提示。
- 未配置任何策略、且关闭内置默认规则时,现有节点行为和测试结果不变。
-
check接口对给定命令返回命中的规则和最终结果。
- Linguagem predominante
- Go
- Estrelas
- 141
- Forks
- 28
- Merge médio
- 1d 15h
- PRs com merge (30d)
- 113
Preparar o ambiente
- Inclui um Dockerfile ou arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de Tencent/LoopForge
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
Mantenedores costumam responder em até 1 dia
-
[Bug]: 官方镜像未安装 wecom-cli,企业微信通知报「通知服务未安装 wecom-cli」Talvez já em andamento @newexploreor assumiu há 1 dia. Abertabug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
Tencent/LoopForge#156 · 1 comentário · 1 responsável ·
Mantenedores costumam responder em até 1 dia
-
【架构优化】合并 gitwork/workbranch.go 中 push/pull 重复的默认提交身份注入为 withFallbackIdentityTalvez já em andamento @fx-kurumi assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 40/100
Mantenedores costumam responder em até 1 dia
-
【架构优化】从 runtime.installNPMCLI 中拆出 npm 参数拼装 npmCLIInstallArgs 与安装结果启用 activateNPMStageTalvez já em andamento @fx-kurumi assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 30/100
Mantenedores costumam responder em até 1 dia
Todas as issues de Tencent/LoopForge
Issues semelhantes
-
type:bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
nightgauge/nightgauge#3266 ·
Mantenedores costumam responder em até 1 dia
-
area: ai-models priority: normal
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
Mantenedores costumam responder em até 1 dia
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 85/100
prime-radiant-inc/evener#6325 ·
Mantenedores costumam responder em até 1 dia
-
team:library-maintainers
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
padok-team/burrito#1208 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
bazel-contrib/rules_go#4784 · 1 comentário ·
Mantenedores costumam responder em até 1 dia