Copilot Hooks 让你在 AI 代理运行的关键时刻自动执行自定义 shell 命令——会话开始时初始化环境、工具调用前进行安全检查、工具调用后触发格式化或日志记录、会话结束时清理资源。相比手动监控每个操作,Hooks 把守卫逻辑写入一次,永远自动执行。

GitHub Copilot Cloud Agent Hooks:会话生命周期自动化配置指南

什么是 Hooks

Hooks 允许你定义在 Copilot 代理运行的特定时刻自动执行的 shell 命令,类似于 Git hooks,但作用于 AI 代理的工作流程。

典型用途:

  • 每次文件修改后自动运行代码格式化
  • 工具调用前验证安全策略(阻止危险操作)
  • 会话开始时初始化必要的环境
  • 记录所有工具调用到审计日志

注意:Hooks 是同步执行的,会阻塞代理执行。保持每个 hook 的执行时间短,重操作应异步化或放到 sessionEnd 中执行。

配置格式

Hooks 使用 JSON 配置,必须包含 "version": 1

{
  "version": 1,
  "hooks": {
    "sessionStart": [
      {
        "type": "command",
        "bash": "echo \"Session started: $(date)\" >> logs/session.log",
        "timeoutSec": 10
      }
    ],
    "preToolUse": [
      {
        "type": "command",
        "bash": "./scripts/check-tool-policy.sh \"$TOOL_NAME\" \"$TOOL_INPUT\"",
        "timeoutSec": 5,
        "env": {
          "POLICY_FILE": "./.github/copilot-policy.json"
        }
      }
    ],
    "postToolUse": [
      {
        "type": "command",
        "bash": "if echo \"$TOOL_NAME\" | grep -q 'write'; then prettier --write \"$TOOL_OUTPUT_FILE\" 2>/dev/null || true; fi",
        "timeoutSec": 30
      }
    ]
  }
}

支持的钩子事件

事件 触发时机 典型用途
sessionStart 会话开始时 初始化日志、设置环境变量
sessionEnd 会话正常结束时 清理临时文件、生成报告
userPromptSubmitted 用户提交提示词后 记录交互、注入额外上下文
preToolUse 工具调用前 安全策略检查、阻止危险操作
postToolUse 工具调用后 代码格式化、自动测试
errorOccurred 发生错误时 错误日志记录、告警通知
agentStop 主代理停止时 最终清理和报告
subagentStop 子代理停止时 子任务结果处理

hook 配置字段

字段 类型 说明
type string 目前只支持 "command"
bash string 要执行的 bash 命令(Linux/macOS)
powershell string 要执行的 PowerShell 命令(Windows)
cwd string 命令的工作目录
env object 额外的环境变量
timeoutSec number 超时时间(秒),防止 hook 卡死

典型使用场景

场景一:自动格式化

每次文件写入后自动运行 Prettier:

{
  "version": 1,
  "hooks": {
    "postToolUse": [
      {
        "type": "command",
        "bash": "[ \"$TOOL_NAME\" = 'write' ] && prettier --write \"$TOOL_FILE_PATH\" 2>/dev/null || true",
        "timeoutSec": 30
      }
    ]
  }
}

场景二:阻止 git push

preToolUse 中拦截 git push

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "if echo \"$TOOL_INPUT\" | grep -q 'git push'; then echo '错误:禁止 AI 直接 push,请人工确认后执行' >&2; exit 1; fi",
        "timeoutSec": 3
      }
    ]
  }
}

preToolUse hook 返回非 0 退出码时,该工具调用会被阻止

场景三:审计日志

记录所有工具调用:

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      {
        "type": "command",
        "bash": "echo \"$(date -Iseconds) TOOL_CALL: $TOOL_NAME\" >> ~/.copilot/audit.log",
        "timeoutSec": 3
      }
    ]
  }
}

场景四:会话统计

会话结束时记录统计信息:

{
  "version": 1,
  "hooks": {
    "sessionEnd": [
      {
        "type": "command",
        "bash": "./scripts/report-session-stats.sh",
        "timeoutSec": 60
      }
    ]
  }
}

安全注意事项

  • 验证输入:不要盲目使用 hook 中的环境变量(可能包含恶意代码),做好转义
  • 不要记录敏感数据:日志中避免记录 Token、密码等
  • 限制权限:hook 脚本本身的文件权限应限制为只有你可以修改
  • 设置超时:每个 hook 都设置合理的 timeoutSec,防止 hook 卡死整个代理
  • 最小权限:hook 脚本只请求完成任务所需的最低权限

与 Claude Code Hooks 的对比

Claude Code 也有类似的 Hooks 机制(在 ~/.claude/settings.json 中配置),支持 PreToolUsePostToolUseStop 等事件,配置风格类似但格式不同。如果你同时使用两个工具,建议维护独立的 hook 配置,逻辑上保持一致。

常见问题

Q: hook 执行失败(非 0 退出码)会影响后续操作吗?

A: preToolUse 的非 0 退出码会阻止工具调用;其他钩子的失败通常会被记录但不阻断流程(具体行为取决于版本)。建议 hook 脚本除了 preToolUse 保护用途外,都用 || true 防止意外阻断。

Q: hook 能访问哪些环境变量?

A: 可以访问 TOOL_NAME(当前工具名)、TOOL_INPUT(工具输入)、TOOL_FILE_PATH(涉及文件路径)等,以及你在 env 字段额外配置的变量。具体变量因 hook 事件类型而异。

Q: hooks 配置文件放在哪里?

A: 与 Copilot CLI 的 Custom Instructions 类似,可以放在项目的 .github/ 目录或用户级配置目录,具体路径参见当前版本文档。