Appearance
Hooks 是 Copilot SDK 的拦截层,通过在 createSession 时传入 hooks 对象,可以在工具调用前后、Prompt 提交时、会话启停时注入自定义逻辑。最常用场景:阻止危险工具、审计日志、上下文注入。
GitHub Copilot SDK Hooks 快速入门:5 分钟添加工具权限控制
最简示例:阻止危险工具
typescript
import { createSession } from '@github/copilot-sdk'
const DANGEROUS_TOOLS = ['delete_files', 'drop_table', 'system_restart']
const session = await createSession({
hooks: {
onPreToolUse: async ({ toolName }) => {
if (DANGEROUS_TOOLS.includes(toolName)) {
return {
action: 'deny',
reason: `工具 "${toolName}" 已被安全策略禁止`
}
}
return null // 允许其他所有工具
}
}
})5 行代码,Agent 就无法调用危险工具了。
四个核心 Hook 点
| Hook | 触发时机 | 常见用途 |
|---|---|---|
onPreToolUse | 工具调用前 | 权限控制、参数校验 |
onPostToolUse | 工具调用后 | 结果过滤、日志记录 |
onUserPromptSubmitted | 用户发送消息后 | 上下文注入、内容过滤 |
onSessionStart/End | 会话开始/结束时 | 初始化、清理资源 |
组合多个 Hook
typescript
const session = await createSession({
hooks: {
// 1. 工具调用前:权限检查 + 日志
onPreToolUse: async ({ toolName, arguments: args }) => {
console.log(`[AUDIT] 工具调用: ${toolName}`, args)
if (toolName === 'execute_command' && args.command?.includes('rm -rf')) {
return { action: 'deny', reason: '危险命令已被阻止' }
}
return null
},
// 2. 工具调用后:脱敏处理
onPostToolUse: async ({ toolName, result }) => {
if (toolName === 'read_env' && result.content) {
// 过滤包含 KEY 或 SECRET 的环境变量值
const filtered = result.content.replace(
/([A-Z_]*(KEY|SECRET|TOKEN|PASS)[A-Z_]*=).*/g,
'$1[REDACTED]'
)
return { modifiedResult: { ...result, content: filtered } }
}
return null
},
// 3. 用户输入:自动追加上下文
onUserPromptSubmitted: async ({ prompt }) => {
return {
additionalContext: `工作目录: ${process.cwd()}`
}
}
}
})返回值规则
| 场景 | 返回值 |
|---|---|
| 不修改,保持默认 | null 或 undefined |
| 允许工具执行 | { action: 'allow' } |
| 拒绝工具执行 | { action: 'deny', reason: '原因' } |
| 请求用户确认 | { action: 'ask', message: '确认提示' } |
| 修改工具调用后的结果 | { modifiedResult: {...} } |
| 追加上下文信息 | { additionalContext: '...' } |
常见问题
Q: Hook 函数可以是 async 的吗?
A: 可以,所有 Hook 都支持 async 函数。但注意 Hook 会阻塞工具调用,async Hook 中的 await 会延迟执行,尽量避免不必要的异步操作。
Q: 多个 onPreToolUse 可以链式调用吗?
A: 不可以,每个 Hook 类型只能注册一次。如果需要多个逻辑,在同一个 Hook 函数中串联处理。
Q: Hook 能改变工具调用的参数吗?
A: onPreToolUse 可以返回 { modifiedArguments: {...} } 修改传给工具的参数。