Skip to content

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

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

什么是 Hooks

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

典型用途:

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

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

配置格式

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

json
{
  "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 配置字段

字段类型说明
typestring目前只支持 "command"
bashstring要执行的 bash 命令(Linux/macOS)
powershellstring要执行的 PowerShell 命令(Windows)
cwdstring命令的工作目录
envobject额外的环境变量
timeoutSecnumber超时时间(秒),防止 hook 卡死

典型使用场景

场景一:自动格式化

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

json
{
  "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

json
{
  "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 退出码时,该工具调用会被阻止

场景三:审计日志

记录所有工具调用:

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

场景四:会话统计

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

json
{
  "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/ 目录或用户级配置目录,具体路径参见当前版本文档。