Visual Studio Code 中的 Agent 钩子(预览版)
钩子允许你在智能体(Agent)会话的关键生命周期点执行自定义 shell 命令。使用钩子可以自动化工作流程、强制执行安全策略、验证操作并与外部工具集成。
有关钩子如何融入 AI 自定义框架的背景信息,请参阅自定义概念。
本文介绍了如何在 VS Code 中配置和使用钩子。
Agent 钩子目前处于预览阶段。配置格式和行为在未来的版本中可能会有所变化。
你的组织可能已禁用 VS Code 中的钩子功能。请联系管理员以获取更多信息。详情请参阅企业策略。
使用智能体自定义编辑器(预览版)可以集中发现、创建和管理所有的智能体自定义配置。通过命令面板运行 Chat: Open Customizations 即可打开。
钩子旨在跨智能体类型工作,包括本地智能体、后台智能体和云端智能体。每个钩子都会接收结构化的 JSON 输入,并可以返回 JSON 输出以影响智能体的行为。
为什么要使用钩子?
钩子提供确定性的、代码驱动的自动化。与引导智能体行为的说明或自定义提示词不同,钩子在特定的生命周期点执行你的代码,并保证执行结果。
-
强制执行安全策略:在危险命令(如
rm -rf或DROP TABLE)执行前将其拦截,无论智能体收到什么指令。 -
自动化代码质量:在文件修改后自动运行格式化程序、代码检查工具或测试。
-
创建审计跟踪:记录每一次工具调用、命令执行或文件更改,以满足合规性和调试需求。
-
注入上下文:添加特定于项目的详细信息、API 密钥或环境详情,以帮助智能体做出更好的决策。
-
控制审批:自动审批安全操作,同时对敏感操作要求人工确认。
快速入门:你的第一个钩子
以下示例展示了如何创建一个在每次文件编辑后运行 Prettier 的钩子。在你的工作区中创建一个 .github/hooks/format.json 文件:
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
}
保存此文件后,VS Code 会自动加载该钩子。下次智能体编辑文件时,Prettier 将在更改后的文件上运行。检查 GitHub Copilot Chat Hooks 输出通道以验证钩子是否已执行。
有关使用自定义脚本的更复杂钩子,请参阅使用场景。
钩子生命周期事件
VS Code 支持八种钩子事件,它们会在智能体会话期间的特定点触发:
| 钩子事件 | 触发时机 | 常见用例 |
|---|---|---|
SessionStart(会话开始) |
用户提交新会话的首个提示词时 | 初始化资源、记录会话开始、验证项目状态 |
UserPromptSubmit(用户提交提示词) |
用户提交提示词时 | 审计用户请求、注入系统上下文 |
PreToolUse(工具使用前) |
智能体调用任何工具之前 | 拦截危险操作、要求审批、修改工具输入 |
PostToolUse(工具使用后) |
工具成功执行完成后 | 运行格式化程序、记录结果、触发后续动作 |
PreCompact(上下文压缩前) |
对话上下文被压缩之前 | 导出重要上下文、在截断前保存状态 |
SubagentStart(子智能体开始) |
子智能体被创建时 | 跟踪嵌套智能体的使用情况、初始化子智能体资源 |
SubagentStop(子智能体停止) |
子智能体执行完成时 | 汇总结果、清理子智能体资源 |
Stop(停止) |
智能体会话结束时 | 生成报告、清理资源、发送通知 |
配置钩子
钩子在存储于工作区或用户目录中的 JSON 文件中进行配置。
钩子文件位置
VS Code 会在以下位置搜索钩子配置文件:
在 monorepo(单体仓库)中,启用 chat.useCustomizationsInParentRepositories 即可从父仓库根目录发现钩子。了解更多关于父仓库发现的信息。
| 范围 | 默认文件位置 |
|---|---|
| 工作区 | .github/hooks/*.json |
| 工作区 (Claude 格式) | .claude/settings.json, .claude/settings.local.json |
| 用户 | ~/.copilot/hooks, ~/.claude/settings.json |
| 自定义智能体 | .agent.md frontmatter 中的 hooks 字段(参阅智能体作用域钩子) |
| 插件 | hooks.json 或 hooks/hooks.json,取决于插件格式(参阅插件中的钩子) |
对于同一事件类型,工作区钩子的优先级高于用户钩子。
使用 chat.hookFilesLocations 设置可以自定义加载哪些钩子文件。你可以指定文件夹路径(VS Code 会加载文件夹中所有的 *.json 文件)或单个 .json 文件的路径。仅支持相对路径和波浪号 (~) 开头的路径。
默认值包含上述位置。
"chat.hookFilesLocations": {
".github/hooks": true,
".claude/settings.local.json": true,
".claude/settings.json": true,
"~/.claude/settings.json": true
}
要添加自定义位置,请在此设置中添加条目。
"chat.hookFilesLocations": {
"custom/hooks": true,
"~/my-hooks/security.json": true
}
将路径设置为 false 可禁用从该位置加载钩子(包括默认位置)。例如,要停止从 Claude Code 配置文件加载钩子:
"chat.hookFilesLocations": {
".claude/settings.json": false,
".claude/settings.local.json": false,
"~/.claude/settings.json": false
}
智能体作用域钩子
智能体作用域钩子目前处于预览阶段。
你可以直接在自定义智能体的 YAML frontmatter 中定义钩子。智能体作用域钩子仅在该自定义智能体处于活动状态(由用户选中或作为子智能体调用)时才会运行。智能体作用域钩子将与针对同一事件配置的任何工作区或用户级钩子一起运行。
要启用智能体作用域钩子,请将 chat.useCustomAgentHooks 设置为 true。
在智能体 frontmatter 中添加一个 hooks 字段,其结构与钩子配置文件相同:事件名称映射到钩子命令对象数组。
---
name: "Strict Formatter"
description: "Agent that auto-formats code after every edit"
hooks:
PostToolUse:
- type: command
command: "./scripts/format-changed-files.sh"
---
You are a code editing agent. After making changes, files are automatically formatted.
钩子配置格式
创建一个包含 hooks 对象的 JSON 文件,其中包含每个事件类型的钩子命令数组。为保持兼容性,VS Code 使用与 Claude Code 和 Copilot CLI 相同的钩子格式。
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/validate-tool.sh",
"timeout": 15
}
],
"PostToolUse": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
}
钩子命令属性
每个钩子条目必须具有 type: "command" 且至少包含一个命令属性。
| 属性 | 类型 | 描述 |
|---|---|---|
type |
字符串 | 必须为 "command" |
command |
字符串 | 要运行的默认命令(跨平台) |
windows |
字符串 | Windows 专用命令覆盖 |
linux |
字符串 | Linux 专用命令覆盖 |
osx |
字符串 | macOS 专用命令覆盖 |
cwd |
字符串 | 工作目录(相对于仓库根目录) |
env |
对象 | 附加环境变量 |
timeout |
number | 超时时间(秒,默认:30) |
操作系统专用命令是根据扩展宿主平台选择的。在远程开发场景(SSH、容器、WSL)中,这可能与你的本地操作系统不同。
操作系统专用命令
为每个操作系统指定不同的命令
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "./scripts/format.sh",
"windows": "powershell -File scripts\\format.ps1",
"linux": "./scripts/format-linux.sh",
"osx": "./scripts/format-mac.sh"
}
]
}
}
执行服务会根据你的操作系统选择合适的命令。如果未定义特定于操作系统的命令,则回退到 command 属性。
钩子输入和输出
钩子通过 stdin(输入)和 stdout(输出)使用 JSON 与 VS Code 进行通信。
通用输入字段
每个钩子都会通过 stdin 接收包含这些通用字段的 JSON 对象:
{
"timestamp": "2026-02-09T10:30:00.000Z",
"cwd": "/path/to/workspace",
"sessionId": "session-identifier",
"hookEventName": "PreToolUse",
"transcript_path": "/path/to/transcript.json"
}
通用输出格式
钩子可以通过 stdout 返回 JSON 以影响智能体的行为。所有钩子都支持这些输出字段:
{
"continue": true,
"stopReason": "Security policy violation",
"systemMessage": "Unit tests failed"
}
| 字段 | 类型 | 描述 |
|---|---|---|
continue |
布尔值 | 设置为 false 以停止处理(默认:true) |
stopReason |
字符串 | 当 continue 为 false 时的停止原因(会显示给用户) |
systemMessage |
字符串 | 显示给用户的警告消息 |
退出代码
钩子的退出代码决定了 VS Code 如何处理结果:
| 退出代码 | 行为 |
|---|---|
0 |
成功:将 stdout 解析为 JSON |
2 |
阻塞错误:停止处理并向模型显示错误 |
| 其他 | 非阻塞警告:向用户显示警告,继续处理 |
选择如何返回数据
钩子有多种控制智能体行为的方法:退出代码、顶级输出字段(continue, stopReason)以及特定于钩子的输出字段(hookSpecificOutput)。结合使用它们的方式如下:
- 退出代码 2 是阻塞操作最简单的方法。钩子的 stderr 会作为上下文显示给模型。无需 JSON 输出。
- JSON 输出中的
continue: false会停止整个智能体会话。使用stopReason告知用户原因。这比仅阻塞单个工具调用更彻底。 hookSpecificOutput提供特定于每个钩子事件的细粒度控制。例如,PreToolUse钩子使用permissionDecision来允许、拒绝或询问单个工具调用,而无需停止整个会话。systemMessage无论其他决定如何,都会在聊天中向用户显示警告。
当多种控制机制同时使用时,限制性最强的机制生效。例如,如果钩子返回 continue: false 且 permissionDecision: "allow",会话仍会停止。
PreToolUse(工具使用前)
PreToolUse 钩子在智能体调用工具之前触发。
PreToolUse 输入
除通用字段外,PreToolUse 钩子还会接收:
{
"tool_name": "editFiles",
"tool_input": { "files": ["src/main.ts"] },
"tool_use_id": "tool-123"
}
PreToolUse 输出
PreToolUse 钩子可以通过 hookSpecificOutput 对象控制工具执行:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by policy",
"updatedInput": { "files": ["src/safe.ts"] },
"additionalContext": "User has read-only access to production files"
}
}
| 字段 | 值 | 描述 |
|---|---|---|
permissionDecision |
"allow", "deny", "ask" |
控制工具审批 |
permissionDecisionReason |
字符串 | 显示给用户的理由 |
updatedInput |
对象 | 修改后的工具输入(可选) |
additionalContext |
字符串 | 提供给模型的额外上下文 |
审批决策优先级:当同一工具调用运行多个钩子时,限制性最强的决策生效:
deny(限制性最强):阻塞工具执行ask:需要用户确认allow(限制性最弱):自动批准执行
updatedInput 格式:要确定 updatedInput 的格式,请打开智能体日志并查找已记录的工具架构。如果 updatedInput 与预期架构不匹配,它将被忽略。
PostToolUse(工具使用后)
PostToolUse 钩子在工具成功完成后触发。
PostToolUse 输入
除通用字段外,PostToolUse 钩子还会接收:
{
"tool_name": "editFiles",
"tool_input": { "files": ["src/main.ts"] },
"tool_use_id": "tool-123",
"tool_response": "File edited successfully"
}
PostToolUse 输出
PostToolUse 钩子可以向模型提供额外上下文,或阻塞后续处理:
{
"decision": "block",
"reason": "Post-processing validation failed",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "The edited file has lint errors that need to be fixed"
}
}
| 字段 | 值 | 描述 |
|---|---|---|
decision |
"block" |
阻塞后续处理(可选) |
reason |
字符串 | 阻塞原因(显示给模型) |
hookSpecificOutput.additionalContext |
字符串 | 注入到对话中的额外上下文 |
UserPromptSubmit(用户提交提示词)
UserPromptSubmit 钩子在用户提交提示词时触发。
UserPromptSubmit 输入
除通用字段外,UserPromptSubmit 钩子还会接收一个包含用户提交文本的 prompt 字段。
UserPromptSubmit 钩子仅使用通用输出格式。
SessionStart(会话开始)
SessionStart 钩子在新智能体会话开始时触发。
SessionStart 输入
除通用字段外,SessionStart 钩子还会接收:
{
"source": "new"
}
| 字段 | 类型 | 描述 |
|---|---|---|
source |
字符串 | 会话的启动方式。目前始终为 "new"。 |
SessionStart 输出
SessionStart 钩子可以向智能体的对话中注入额外上下文:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Project: my-app v2.1.0 | Branch: main | Node: v20.11.0"
}
}
| 字段 | 类型 | 描述 |
|---|---|---|
additionalContext |
字符串 | 添加到智能体对话中的上下文 |
Stop(停止)
Stop 钩子在智能体会话结束时触发。当作用域限定于自定义智能体时,Stop 钩子也被视为 SubagentStop。
Stop 输入
除通用字段外,Stop 钩子还会接收:
{
"stop_hook_active": false
}
| 字段 | 类型 | 描述 |
|---|---|---|
stop_hook_active |
布尔值 | 当智能体因之前的停止钩子而继续运行时为 true。检查此值以防止智能体无限运行。 |
Stop 输出
Stop 钩子可以阻止智能体停止:
{
"hookSpecificOutput": {
"hookEventName": "Stop",
"decision": "block",
"reason": "Run the test suite before finishing"
}
}
| 字段 | 值 | 描述 |
|---|---|---|
decision |
"block" |
阻止智能体停止 |
reason |
字符串 | 当 decision 为 "block" 时必需。告知智能体为何应继续。 |
当 Stop 钩子阻止智能体停止时,智能体将继续运行,且额外的轮次会消耗 AI 额度。务必检查 stop_hook_active 字段以防止智能体无限运行。
SubagentStart(子智能体开始)
SubagentStart 钩子在子智能体被创建时触发。
SubagentStart 输入
除通用字段外,SubagentStart 钩子还会接收:
{
"agent_id": "subagent-456",
"agent_type": "Plan"
}
| 字段 | 类型 | 描述 |
|---|---|---|
agent_id |
字符串 | 子智能体的唯一标识符 |
agent_type |
字符串 | 智能体名称(例如,内置智能体为 "Plan" 或自定义智能体名称) |
SubagentStart 输出
SubagentStart 钩子可以向子智能体的对话中注入额外上下文:
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "This subagent should follow the project coding guidelines"
}
}
| 字段 | 类型 | 描述 |
|---|---|---|
additionalContext |
字符串 | 添加到子智能体对话中的上下文 |
SubagentStop(子智能体停止)
SubagentStop 钩子在子智能体执行完成时触发。
SubagentStop 输入
除通用字段外,SubagentStop 钩子还会接收:
{
"agent_id": "subagent-456",
"agent_type": "Plan",
"stop_hook_active": false
}
| 字段 | 类型 | 描述 |
|---|---|---|
agent_id |
字符串 | 子智能体的唯一标识符 |
agent_type |
字符串 | 智能体名称(例如,内置智能体为 "Plan" 或自定义智能体名称) |
stop_hook_active |
布尔值 | 当子智能体因之前的停止钩子而继续运行时为 true。检查此值以防止子智能体无限运行。 |
SubagentStop 输出
SubagentStop 钩子可以阻止子智能体停止:
{
"decision": "block",
"reason": "Verify subagent results before completing"
}
| 字段 | 值 | 描述 |
|---|---|---|
decision |
"block" |
阻止子智能体停止 |
reason |
字符串 | 当 decision 为 "block" 时必需。告知子智能体为何应继续。 |
PreCompact(上下文压缩前)
PreCompact 钩子在压缩对话上下文之前触发。
PreCompact 输入
除通用字段外,PreCompact 钩子还会接收:
{
"trigger": "auto"
}
| 字段 | 类型 | 描述 |
|---|---|---|
trigger |
字符串 | 压缩触发方式。当对话过长超出提示词预算时为 "auto"。 |
PreCompact 钩子仅使用通用输出格式。
使用 UI 配置钩子
你可以通过交互式 UI 以多种方式配置钩子:
- 在聊天输入框中输入
/hooks并按下 Enter。 - 打开命令面板(⇧⌘P(Windows, Linux 为 Ctrl+Shift+P))并运行 Chat: Configure Hooks。
- 选择聊天视图顶部的 设置 图标(),然后选择 Hooks。
在配置钩子菜单中:
-
从列表中选择一个钩子事件类型。
-
选择现有钩子进行编辑,或选择 Add new hook 进行创建。
-
选择或创建钩子配置文件。
该命令会在编辑器中打开钩子文件,光标置于命令字段,准备编辑。
使用 AI 生成钩子
你可以利用 AI 来生成钩子配置。在聊天框输入 /create-hook 并描述你想要的自动化操作(例如,“每次文件编辑后运行 ESLint”)。智能体会提出澄清问题,并生成包含合适事件类型、命令和设置的钩子配置文件。
使用场景
以下示例演示了常见的钩子模式:
拦截危险的终端命令
创建一个 PreToolUse 钩子来防止破坏性命令:
.github/hooks/security.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/block-dangerous.sh",
"timeoutSec": 5
}
]
}
}
scripts/block-dangerous.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input')
if [ "$TOOL_NAME" = "runTerminalCommand" ]; then
COMMAND=$(echo "$TOOL_INPUT" | jq -r '.command // empty')
if echo "$COMMAND" | grep -qE '(rm\s+-rf|DROP\s+TABLE|DELETE\s+FROM)'; then
echo '{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"Destructive command blocked by security policy"}}'
exit 0
fi
fi
echo '{"continue":true}'
编辑后自动格式化代码
在任何文件修改后自动运行 Prettier:
.github/hooks/formatting.json:
{
"hooks": {
"PostToolUse": [
{
"type": "command",
"command": "./scripts/format-changed-files.sh",
"windows": "powershell -File scripts\\format-changed-files.ps1",
"timeout": 30
}
]
}
}
scripts/format-changed-files.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
if [ "$TOOL_NAME" = "editFiles" ] || [ "$TOOL_NAME" = "createFile" ]; then
FILES=$(echo "$INPUT" | jq -r '.tool_input.files[]? // .tool_input.path // empty')
for FILE in $FILES; do
if [ -f "$FILE" ]; then
npx prettier --write "$FILE" 2>/dev/null
fi
done
fi
echo '{"continue":true}'
记录工具使用情况以进行审计
为所有工具调用创建审计跟踪:
.github/hooks/audit.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/log-tool-use.sh",
"env": {
"AUDIT_LOG": ".github/hooks/audit.log"
}
}
]
}
}
scripts/log-tool-use.sh:
#!/bin/bash
INPUT=$(cat)
TIMESTAMP=$(echo "$INPUT" | jq -r '.timestamp')
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
SESSION_ID=$(echo "$INPUT" | jq -r '.sessionId')
echo "[$TIMESTAMP] Session: $SESSION_ID, Tool: $TOOL_NAME" >> "${AUDIT_LOG:-audit.log}"
echo '{"continue":true}'
要求对特定工具进行审批
强制对修改基础设施的工具进行人工确认:
.github/hooks/approval.json:
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "./scripts/require-approval.sh"
}
]
}
}
scripts/require-approval.sh:
#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
# Tools that should always require approval
SENSITIVE_TOOLS="runTerminalCommand|deleteFile|pushToGitHub"
if echo "$TOOL_NAME" | grep -qE "^($SENSITIVE_TOOLS)$"; then
echo '{"hookSpecificOutput":{"permissionDecision":"ask","permissionDecisionReason":"This operation requires manual approval"}}'
else
echo '{"hookSpecificOutput":{"permissionDecision":"allow"}}'
fi
在会话开始时注入项目上下文
在会话开始时提供特定于项目的信息:
.github/hooks/context.json:
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "./scripts/inject-context.sh"
}
]
}
}
scripts/inject-context.sh:
#!/bin/bash
PROJECT_INFO=$(cat package.json 2>/dev/null | jq -r '.name + " v" + .version' || echo "Unknown project")
BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Project: $PROJECT_INFO | Branch: $BRANCH | Node: $(node -v 2>/dev/null || echo 'not installed')"
}
}
EOF
安全性
如果智能体有权编辑钩子运行的脚本,那么它在运行期间就能够修改这些脚本,并执行它所编写的代码。我们建议使用 chat.tools.edits.autoApprove 来禁止智能体在未经人工审批的情况下编辑钩子脚本。
故障排除
查看钩子诊断
要查看哪些钩子已加载并检查配置错误:
-
选择 View Logs 以查看所有日志。
-
查找 "Load Hooks" 以查看已加载的钩子及其来源位置。
查看钩子输出
要查看钩子输出和错误:
-
打开 Output 面板。
-
从通道列表中选择 GitHub Copilot Chat Hooks。
常见问题
钩子未执行:验证钩子文件是否位于 .github/hooks/ 且具有 .json 扩展名。检查 type 属性是否设置为 "command"。
权限拒绝错误:确保你的钩子脚本具有执行权限 (chmod +x script.sh)。
超时错误:增加 timeout 值或优化你的钩子脚本。默认值为 30 秒。
JSON 解析错误:验证你的钩子脚本是否向 stdout 输出有效的 JSON。使用 jq 或 JSON 库来构建输出。
常见问题
VS Code 如何处理 Claude Code 钩子配置?
VS Code 默认从 .claude/settings.json、.claude/settings.local.json 和 ~/.claude/settings.json 中读取钩子配置。VS Code 会解析 Claude Code 的钩子配置格式,包括匹配器 (matcher) 语法。目前,VS Code 会忽略匹配器值,因此无论匹配器如何,钩子都会在所有工具调用上运行。
如果你正在为 VS Code 适配 Claude Code 钩子,请注意以下差异:
- 工具输入属性名称:Claude Code 使用 snake_case 命名工具输入属性(例如
tool_input.file_path),而 VS Code 工具使用 camelCase(例如tool_input.filePath)。更新你的钩子脚本以读取正确的属性名称。 - 工具名称:Claude Code 和 VS Code 使用不同的工具名称。例如,Claude Code 使用
Write和Edit进行文件操作,而 VS Code 使用如create_file和replace_string_in_file等工具名称。请检查tool_name输入字段中的工具名称,并相应地更新你的钩子逻辑。 - 匹配器被忽略:类似
"Edit|Write"的钩子匹配器会被解析但不会被应用。所有钩子都会在每个匹配事件上运行,无论匹配器中的工具名称是什么。
VS Code 如何处理 Copilot CLI 钩子配置?
VS Code 会解析 Copilot CLI 钩子配置,并将 lowerCamelCase 钩子事件名称(如 preToolUse)转换为 VS Code 使用的 PascalCase 格式(PreToolUse)。bash 和 powershell 命令属性会映射到操作系统专用命令:powershell 映射到 windows,bash 映射到 osx 和 linux。
安全注意事项
钩子以与 VS Code 相同的权限执行 shell 命令。请仔细审查钩子配置,尤其是在使用来自不受信任来源的钩子时。
-
审查钩子脚本:在启用所有钩子脚本之前进行检查,尤其是在共享仓库中。
-
限制钩子权限:遵循最小权限原则。钩子应仅有权访问其所需的内容。
-
验证输入:钩子脚本会接收来自智能体的输入。验证并清理所有输入以防止注入攻击。
-
保护凭据:切勿在钩子脚本中硬编码密钥。请使用环境变量或安全的凭据存储。