agent-Specialization/.astrion/memory/agent_hooks_design.md

5.3 KiB
Raw Permalink Blame History

name description
agent_hooks_design 当需要继续讨论或实现本项目的 hooks / 生命周期钩子功能时,应该索引本记忆

Hooks / 生命周期钩子功能设计讨论(进行中)

调研结论

主流实现

  • Claude Code最完整20+ 事件、5 种 handlercommand/http/mcp_tool/prompt/agent、多层配置全局/项目/本地/组织/插件/SDK
  • OpenAI Codex11 个事件、command 回调为主、有信任审查机制和企业托管 hooks。
  • Cursor.cursor/hooks.jsonBetacommand 回调,项目/用户/企业三级。
  • GitHub Copilot.github/hooks/*.jsoncommand/http/prompt 三种回调Cloud Agent 也支持。
  • Windsurf/Cascade.windsurf/hooks.jsonexit 2 阻断12 个事件。
  • Aider / Continue.dev / Kimi Code / Devin:无原生 hooks 或资料有限。

共性模式

Agent 事件发生
    ↓
stdin 发送 JSON 事件载荷 → Hook 脚本 / HTTP 端点
    ↓
返回决策allow/deny/ask/modify/injectMessage
    ↓
Agent 根据决策继续执行

用户(项目 owner对 hooks 的理解

钩子 = 发生一件事件之前/中/后 → 自动触发另一个事件。用 JSON 格式写条件和行为,分为全局/项目级,放在数据存储目录下/工作区内。

用户认可的核心:事件驱动 + JSON 配置 + 全局/项目两级 + before/after 拦截

已达成的设计共识

1. 配置位置

  • 全局:~/.astrion/astrion/config/hooks.json
  • 项目级:<project>/.astrion/hooks.json
  • 未来可扩展:.astrion/hooks.local.json、企业策略级。
  • 多层配置合并执行,不是覆盖(更安全)。

2. 优先事件MVP 范围建议)

  • PreToolUse:工具执行前拦截/修改
  • PostToolUse:工具执行后触发后续动作
  • Stop:模型/turn 结束时注入反馈
  • PreCompact:上下文压缩前备份

3. 优先回调类型

  • MVP 只做 commandshell/python/任意可执行文件)。
  • 后续可扩展 httppromptagentmcp_tool

4. 通信协议(对齐 Claude Code/Codex

  • stdin 输入 JSON 事件载荷
  • stdout 返回 JSON 决策
  • exit code0=通过1=非阻断错误2=阻断

5. JSON 结构草案

{
  "version": 1,
  "disabled": false,
  "hooks": {
    "PreToolUse": [
      {
        "name": "block-dangerous-rm",
        "matcher": "run_command",
        "if": "command contains 'rm -rf /'",
        "enabled": true,
        "max_repeats": null,
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.astrion/astrion/hooks/block_dangerous.py",
            "timeout": 5,
            "statusMessage": "检查危险命令...",
            "fail_policy": "continue",
            "on_error": "log"
          }
        ]
      }
    ],
    "Stop": [
      {
        "name": "remind-check-completion",
        "max_repeats": 3,
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.astrion/astrion/hooks/remind_check.py",
            "timeout": 5
          }
        ]
      }
    ]
  }
}

已讨论的具体例子

例子 1拦截危险命令

  • 事件:PreToolUse
  • 条件:matcher=run_command + if=command contains 'rm -rf /'
  • 行为:调用脚本,返回 permissionDecision: deny

例子 2edit_file 单行全替换触发审核

  • 事件:PreToolUse
  • 条件:matcher=edit_file + old_string 只有一行 + replace_all=true
  • 行为:返回 permissionDecision: ask

例子 3Stop 时自动插入 user 消息,最多 3 次

  • 事件:Stop
  • 行为:返回 injectMessage: {role: "user", content: "请仔细检查是否真的完成了所有工作"}
  • "最多 3 次"可用 max_repeats 或由脚本自己维护状态文件。

尚未决定的决策点

  1. if 条件表达式语法

    • 选项 A简单规则 DSLcommand contains '...'
    • 选项 B结构化 JSON{"field": "...", "op": "contains", "value": "..."}
    • 选项 C交给 hook 脚本自己判断,if 只保留工具名匹配
  2. "最多 N 次"由谁负责

    • 框架负责 max_repeats(简单,但状态语义固定)
    • 脚本自己维护状态文件(灵活,框架更轻量)
  3. 注入消息语义

    • injectMessage.user:会触发模型再回复一轮
    • addContext.system:只是给下一轮加提示,不立刻触发回复
  4. hook 失败时的主流程策略

    • 默认 continue(用户配置错误不瘫痪智能体)
    • 或提供 fail_policy: block 让管理员强制策略
  5. 工具名匹配

    • 是否同时支持内部工具名(run_command/edit_file)和 Claude Code 风格别名(Bash/Edit|Write

推荐后续路线

  1. 先定 JSON schema 和 if 语法。
  2. MVP 实现 command 回调 + PreToolUse/PostToolUse/Stop
  3. 新增 modules/hook_manager.py
  4. core/main_terminal_parts/tools_execution.pycore/web_terminal.py 插入 hook 调用。
  5. 确保 API task 模式也走 hooks。
  6. 补文档 docs/hooks.md

参考资料位置

  • 调研报告:research/claudecode_hooks/claudecode_hooks.md
  • 调研报告:research/codex_hooks/codex_hooks.md
  • 调研报告:research/other_agents_hooks/other_agents_hooks.md