VS Code Copilot Chat 中的 Hooks 定制创建.github/hooks/钩子以强制执行策略与自动化 Agent 生命周期【免费下载链接】vscode-copilot-chatCopilot Chat extension for VS Code项目地址: https://gitcode.com/gh_mirrors/vs/vscode-copilot-chat本篇技术指南聚焦 VS Code Copilot Chat 的Hooks钩子定制能力它如何通过.json配置文件在 Agent 会话的生命周期节点上挂载确定性命令用于强制执行团队策略、自动化校验和注入运行时上下文。文章以仓库中的 create-hook.prompt.md 提示词为工作流骨架结合 hooks.md 参考文档的完整配置契约并佐证以 hookExecutor.ts 等源码实现。读完本文你将掌握从对话中提炼策略需求、设计 hook JSON、编写配套脚本、理解 stdin/stdout 与退出码契约以及测试与迭代钩子的完整实战能力。一、Hook 是什么Agent 生命周期上的确定性自动化Hooks 是 VS Code Copilot Chat Agent 定制体系中的一种原语用于对 Agent 会话进行确定性的生命周期自动化。与 Instructions、Prompts、Skills、Agents 等指导性非确定性原语不同Hook 通过执行外部 shell 命令在特定生命周期事件点强制行为——例如阻止危险命令、强制运行校验、自动注入上下文。从仓库源码看hook 的职责被严格定义为运行时强制与确定性自动化hookExecutor.ts 中定义了IHookExecutor服务接口其职责是执行单个 hook 命令向 stdin 写入 JSON 输入并捕获 stdout/stderr。而 SKILL.md 的决策流程表中对 Hook 的定位是在 Agent 生命周期节点上执行的确定性 shell 命令阻止工具调用、自动格式化、注入上下文。选择 Hook 而非普通指令的判据在于当行为必须被保证例如阻止危险命令、强制校验、自动注入上下文时使用 Hook仅靠提示文本建议Agent 去做某件事并不够时就需要用 Hook 强制执行。二、Hook 文件的存放位置与生效范围参考 hooks.mdHook 配置存放于以下位置路径作用域.github/hooks/*.json工作区团队共享.claude/settings.local.json工作区本地不提交.claude/settings.json工作区~/.claude/settings.json用户级配置关键行为来自所有配置位置的 Hook 会被收集并全部执行工作区与用户级 Hook 之间不存在互相覆盖的关系。这意味着一方面 Hook 具备叠加效应——团队策略工作区与个人自动化用户级可以同时生效另一方面也要求你设计 Hook 时考虑叠加执行后的可预期性。在 create-hook.prompt.md 中创建向导明确将钩子引导到.github/hooks/目录下创建——这是团队共享策略的首选位置。如果需要个人化的跨工作区自动化则应使用用户配置文件。三、Hook 事件可以挂在哪些生命周期节点Hook 支持在以下生命周期事件上触发来源hooks.md事件触发时机SessionStart新 Agent 会话的第一个提示词UserPromptSubmit用户提交提示词PreToolUse工具调用之前PostToolUse工具成功调用之后PreCompact上下文压缩之前SubagentStart子 Agent 启动SubagentStop子 Agent 结束StopAgent 会话结束这八个事件覆盖了会话从开始到结束、从主 Agent 到子 Agent、从工具调用前到调用后的完整生命周期。设计 Hook 时的第一件事就是确定你的策略/自动化需求应该挂在哪个事件上。四、create-hook 工作流第一步从对话中提取策略需求create-hook.prompt.md 给出的创建流程第一步是回顾对话历史。如果用户反复表达对 Agent 行为的关切例如不要运行这个命令做 X 之前总是先检查注入这个上下文就应该把这些关切**泛化generalize**为一条 Hook 策略。需要提取的内容有三类应被阻止或设闸gated的操作Actions that should be blocked or gated——例如不允许 Agent 直接执行git push或rm -rf这类高风险命令应映射到PreToolUse事件上做权限决策应在特定节点注入的上下文Context that should be injected at certain points——例如每次会话开始或每次工具调用时注入当前分支、环境变量、构建状态等运行时信息应映射到SessionStart、UserPromptSubmit或PreToolUse等节点通过输出的additionalContext字段实现会话开始/结束或工具使用时的自动化需求Automation needs at session start/end or tool use——例如会话结束时自动运行清理脚本或工具调用后自动格式化产物应映射到SessionStart、Stop、PostToolUse等事件。五、create-hook 工作流第二步澄清关键决策点如果从对话中无法明确浮现出清晰的策略需求创建向导会向用户澄清以下三个核心问题对应 create-hook.prompt.md 的 Clarify if Needed 章节什么事件应触发这条 Hook例如PreToolUse、SessionStart、Stop——事件决定挂载点直接对应上一节的生命周期事件表它应该阻止block、警告warn还是注入上下文inject context——行为模式决定输出契约阻止对应permissionDecision: deny警告对应permissionDecision: ask或非阻塞退出码注入对应additionalContext字段它是否需要配套脚本companion script——复杂校验逻辑通常无法内联在 JSON 里需要独立的 shell 脚本JSON 中的command字段指向该脚本。这三个问题的答案共同决定 Hook 的形态一个 JSON 条目 可能的一个或多个脚本文件。六、create-hook 工作流第三步迭代起草与完善起草与完善是一个迭代过程create-hook.prompt.md 给出了三步循环起草 Hook JSON以及任何需要的脚本并保存到.github/hooks/下识别最模糊或最薄弱的部分就这些点提问——不要一次问完所有问题而是针对草稿中真正不确定的地方例如退出码策略、权限决策的默认值、跨平台命令差异进行聚焦澄清定稿后总结概括这条 Hook 强制了什么行为建议如何测试并提议接下来还可以创建哪些相关的定制例如配套的 Instructions、Prompt 或 Agent。6.1 配置格式详解Hook 配置文件的核心结构如下完整示例来自 hooks.md{ hooks: { PreToolUse: [ { type: command, command: ./scripts/validate-tool.sh, timeout: 15 } ] } }每个 hook 命令支持以下字段type必须是commandcommand默认要执行的命令windows、linux、osx平台覆盖命令可在不同操作系统上指定不同实现cwd命令工作目录从 NodeHookExecutor 源码 可见未指定时默认使用用户主目录homedir()env传递给命令的附加环境变量源码中通过{ ...process.env, ...hook.env }与当前进程环境合并timeout超时秒数。注意源码中的默认值DEFAULT_TIMEOUT_SEC 3030 秒超时后子进程会被终止SIGKILL_DELAY_MS 5000表示发送终止信号后额外等待 5 秒再强制 kill。6.2 输入 / 输出契约JSON 进出Hook 命令通过stdin 接收 JSON 输入通过 stdout 返回 JSON 输出。这是 Agent 与外部脚本之间的标准化协议。仓库 hookCommandTypes.ts 给出了类型层面的精确契约PreToolUse 的 stdin 输入包含{ tool_name: 要调用的工具名, tool_input: 工具的输入参数, tool_use_id: 本次工具调用的唯一 ID }PostToolUse 的 stdin 输入比 PreToolUse 多一个tool_response字段工具执行后的响应内容即四个字段tool_name、tool_input、tool_response、tool_use_id。公共输出字段所有 Hook 通用continue是否继续stopReason停止原因——从 hookResultProcessor.ts 可见当结果包含stopReason时会抛出HookAbortErrorHook ${hookType} aborted: ${stopReason}终止当前处理systemMessage系统消息。PreToolUse 权限决策从hookSpecificOutput.permissionDecision读取取值为allow|ask|deny{ hookSpecificOutput: { hookEventName: PreToolUse, permissionDecision: ask, permissionDecisionReason: Needs user confirmation } }类型定义 IPreToolUseHookSpecificCommandOutput 还包含updatedInput修改后的工具输入和additionalContext附加注入的上下文两个可选字段。PostToolUse的输出可以通过decision: block阻止后续处理其类型定义同样支持additionalContext用于在工具执行后注入上下文。6.3 退出码语义成功、阻塞错误与非阻塞警告Hook 命令的退出码决定了执行结果如何被处理来源hooks.md 与 hookExecutor.ts 源码退出码0成功stdout 若为合法 JSON 则按对象解析否则按字符串处理退出码2阻塞错误blocking error错误信息会展示给模型终止当前流程其他非零退出码非阻塞警告仅展示给用户不阻塞流程。源码中的HookCommandResultKind枚举Success/Error/NonBlockingError正是对这三类结果的建模。此外有一个重要的边界细节进程被信号终止等没有数值退出码的情况会被归一化为退出码1即非阻塞警告而命令本身无法启动如命令不存在时NodeHookExecutor 会将其捕获为非阻塞警告而非硬错误。另一个值得一提的源码细节对于SessionStart/SubagentStart这类开始型事件hookResultProcessor.ts 提供了ignoreErrors选项当为true时错误和stopReason会被完全忽略不抛错、不警告、不显示进度——因为会话开始时的阻塞错误没有意义应当静默吞掉而对Stop/SubagentStop这类结束型事件错误会通过onError回调被收集为阻塞原因。这意味着同一套退出码语义在不同事件上的处理策略是不同的设计 Hook 时需要了解目标事件的错误处理行为。七、测试你的 Hook验证策略真的被强制执行create-hook.prompt.md 要求定稿后建议测试方式。测试 Hook 可以从以下维度展开单测脚本本身直接用固定 JSON 输入管道测试脚本例如echo {tool_name:Git,tool_input:{command:push},tool_use_id:t1} | ./scripts/validate-tool.sh检查 stdout 输出的 JSON 是否符合契约、退出码是否符合预期0/2/ 其他在真实会话中触发在 VS Code Copilot Chat 中发起会触发该事件的操作如让 Agent 执行被 Hook 拦截的命令观察是否出现预期的权限决策提示、阻塞消息或注入的上下文验证输出契约的三种行为分别测试allow/ask/deny三种permissionDecision确认 UI 行为符合预期测试非阻塞警告退出码非 0 非 2与阻塞错误退出码 2的区别检查超时与平台差异如果脚本可能执行较久验证timeout生效如果配置了windows/linux/osx平台覆盖分别在目标平台上验证错误处理验证故意让命令启动失败例如指向不存在的脚本确认它被按非阻塞警告处理而非中断整个会话。八、设计原则与反模式hooks.md 给出了四条核心原则保持 Hook 小而可审计Keep hooks small and auditable——Hook 是确定性强制机制代码越简单越容易审查其行为校验并净化 Hook 输入Validate and sanitize hook inputs——stdin 输入来自不可信的模型上下文脚本必须做输入校验避免在脚本中硬编码密钥Avoid hardcoded secrets in scripts——Hook 脚本与配置文件通常提交到仓库硬编码密钥会直接泄露团队策略优先用工作区 Hook个人自动化用用户级 Hook——对应配置文件的位置选择。同时要避免以下反模式运行长时间阻塞的 Hook——这会阻塞正常流程默认超时 30 秒、超时强制 kill 正是为了兜底此类问题在纯指令Instructions足够的情况下使用 Hook——过度使用确定性强制会增加复杂性和维护成本让 Agent 在没有审批控制的情况下编辑 Hook 脚本——Hook 是策略强制点让被约束的对象随意修改约束本身就是安全漏洞。九、Hook 与其他定制原语的协同在 Agent 定制体系中Hook 与其余原语各司其职决策流程详见 SKILL.md原语行为Instructions / Prompts / Skills / Agents指导性非确定性——引导 Agent 行为Hooks运行时强制与确定性自动化——保证行为必然发生选型判断可以参考Instructions vs HooksInstructions引导Agent 行为非确定性Hooks强制行为——需要阻塞操作、要求审批或确定性运行格式化器时用 HookHooks vs MCPMCP 用于集成外部系统、API 或数据Hook 用于生命周期节点上的确定性命令执行Hooks vs SkillsSkills 是按需执行的打包工作流含脚本/模板Hooks 是自动挂载在生命周期事件上的强制点。在 create-hook.prompt.md 的收尾步骤中向导还会提议接下来创建哪些相关定制——一条新 Hook 落地后往往需要配套的 Instructions说明策略意图、Prompt触发特定任务或 Agent隔离上下文才能形成完整的定制闭环这正是 Hook 在定制体系中的协同价值所在。十、总结创建 Hook 的本质是一个从需求到强制策略的转化过程从对话中提炼出应被阻止的操作、应注入的上下文、应自动化的环节 → 澄清事件挂载点、行为模式与配套脚本 → 起草 JSON 并迭代完善 → 依据 stdin/stdout JSON 契约与退出码语义测试验证。整个过程由 create-hook.prompt.md 作为 Agent 侧的工作流模板由 hooks.md 提供完整的配置契约并由 hookExecutor.ts、hookCommandTypes.ts、hookResultProcessor.ts 等源码落实执行语义。掌握了这套流程你就可以为团队工作区构建可审计、可叠加、确定性的 Agent 行为约束层。【免费下载链接】vscode-copilot-chatCopilot Chat extension for VS Code项目地址: https://gitcode.com/gh_mirrors/vs/vscode-copilot-chat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考