浅析Cursor Hooks实战指南:让 AI 编程更安全、更规范

  在使用 Cursor AI 编程助手的过程中,你是否担心 AI 会执行危险的命令?是否希望代码能自动遵循团队规范?本文将通过实战案例教你配置 Cursor Hooks,打造专属的 AI 编程护栏。

  官方文档:https://cursor.com/cn/docs/agent/hooks

一、什么是 Cursor Hooks?

  Cursor Hooks 是 Cursor 编辑器提供的一套拦截机制,允许你在特定时机介入 AI Agent 的行为。

用户提问 → AI 思考 → 执行操作 → 完成任务
                      ↑
                  Hook 拦截点

二、核心 Hook 类型

  Cursor Hooks 分为两大类:Agent Hooks(用于 Cmd+K/Agent Chat)和 Tab Hooks(用于行内补全)。

1、Agent Hooks(Cmd+K/Agent Chat)

Hook 类型

触发时机

典型用途

返回值

beforeShellExecution

执行 shell 命令前

安全拦截、权限控制

permission: allow/deny/ask

afterShellExecution

执行 shell 命令后

审计日志、收集指标

beforeMCPExecution

执行 MCP 工具前

控制 MCP 工具使用

permission: allow/deny/ask

afterMCPExecution

执行 MCP 工具后

审计 MCP 调用

beforeReadFile

读取文件前

访问控制、内容脱敏

permission: allow/deny

afterFileEdit

Agent 编辑文件后

代码格式化、记录日志

beforeSubmitPrompt

提交提示前

验证提示内容、阻止提交

continue: true/false

stop

Agent 循环结束时

质量报告、统计分析

followup_message

afterAgentResponse

Agent 完成回复后

跟踪响应内容

afterAgentThought

Agent 完成思考后

观察推理过程

2、Tab Hooks(行内补全)

Hook 类型

触发时机

典型用途

返回值

beforeTabFileRead

Tab 读取文件前

Tab 专用访问控制

permission: allow/deny

afterTabFileEdit

Tab 编辑文件后

Tab 专用格式化

3、为什么区分 Agent 和 Tab Hooks?

  Agent 是用户驱动的操作,Tab 是自动化的行内补全。两者使用场景不同,可以应用不同的策略。例如,Tab 补全可以更严格地控制文件访问,而 Agent 操作可以记录更详细的审计日志。

三、为什么需要 Hooks

  官网介绍的:

借助 hooks,你可以:

1. 在编辑后运行代码格式化工具

2. 为事件添加分析统计

3. 扫描敏感个人信息(PII)或机密数据

4. 为高风险操作加上门控(例如 SQL 写入)

  痛点 1:AI 可能执行危险操作

rm -rf /  # 💀 删除整个系统
git push --force  # 💀 覆盖远程仓库
chmod 777 *  # 💀 开放所有权限

  痛点 2:代码不符合团队规范

  - AI 生成的代码可能不遵循你的格式规范
  - 文件可能过长,难以维护
  - 缺少统一的代码审查机制

  痛点 3:缺少工作记录

  - 不知道 AI 修改了哪些文件
  - 无法追踪修改历史
  - 出问题时难以排查

  Cursor Hooks 就是解决这些问题的利器!

四、实战案例一:代码质量守护者

  需求背景:我们希望在每次对话结束后:
1. ✅ 自动格式化代码(使用项目的 Prettier 配置)
2. ✅ 检查文件行数,超过 500 行给出拆分建议
3. ✅ 结果直接显示在对话中,无需打开额外文件

  创建 hooks 的模板如下三步:

// 第一步:创建目录结构
.cursor/
├── hooks.json          # Hooks 配置文件
└── hooks/
    ├── on-stop.js      # 对话结束时执行
    └── hook.log        # 日志文件(自动生成)
// 第二步:配置 Hooks
创建 `.cursor/hooks.json`
{
  "version": 1,
  "hooks": {
"afterFileEdit": [
{
"comment": "记录编辑的文件",
"command": "node .cursor/hooks/after-file-edit.js"
}
],
"stop": [ { "comment": "对话结束后检查代码质量", "command": "node .cursor/hooks/on-stop.js" } ] } } // 第三步:编写检查脚本 // 脚本自己编写即可

  核心流程

AI 编辑文件
    ↓
afterFileEdit Hook → 记录到日志(轻量)
    ↓
用户结束对话
    ↓
stop Hook → 读取日志 → 格式化 → 检查行数 → 生成报告
    ↓
报告显示在对话中

  效果演示:当对话结束后,会在对话末尾自动显示

📊 代码质量检查报告

### src/views/article/articleGeneration.vue
- 文件行数:**689**- 格式化:✅
- 状态:⚠️ 超过限制 (189 行)

🔹 拆分 Vue 组件:
  - 提取子组件:将复杂的模板部分提取为独立组件
  - 分离逻辑:将复杂的 methods 提取到 composables (如 useXxx.js)
  - 独立样式:考虑将样式移到单独的 .scss 文件

💡 遵循原则:
  - 单一职责:每个文件只做一件事
  - 高内聚低耦合:相关功能放一起,减少依赖
  - 可测试性:拆分后更容易编写单元测试

五、实战案例二:安全防护系统

  需求背景:在使用 AI 的过程中,我们发现它可能会执行一些危险的命令(如:😱 `rm -rf` 删除重要文件、`git push --force` 覆盖远程仓库、 `chmod 777` 开放所有权限)。我们需要一个安全防护系统来拦截这些操作!

  具体脚本就不贴了,因为也是根据你的需求来的,什么需求怎么写脚本即可,只简单说下思路。

1、实现思路:使用 `beforeShellExecution` Hook 在命令执行前进行拦截

2、核心机制:在执行任何 shell 命令之前,检查命令是否危险

3、实现要点:

  - 使用正则表达式匹配危险命令模式

  - 返回三种权限决策:`allow`(允许)、`deny`(拒绝)、`ask`(需要确认)

  - 提供友好的用户提示信息

// 输入数据:
{
  "command": "rm -rf node_modules",
  "cwd": "/path/to/project"
}
// 输出数据:
{
  "permission": "deny" | "allow" | "ask",
  "user_message": "🚫 命令已被安全策略拦截",
  "agent_message": "命令已被安全 hook 拦截"
}

4、命令分类策略

(1)直接拒绝的命令(`deny`)

  - `rm -rf`:删除文件/目录

  - `git push --force`:强制推送,可能覆盖远程仓库

  - `format`、`dd`、`mkfs`:磁盘操作,可能损坏系统

  - `chmod 777`:开放所有权限,安全风险

(2)需要确认的命令(`ask`)

  - `git reset --hard`:硬重置,会丢失未提交的更改

  - `npm uninstall`:卸载包,可能影响项目依赖

(3)允许执行的命令(`allow`)- 其他所有命令默认允许

5、核心流程

AI尝试执行命令
    ↓
beforeShellExecution Hook → 检查命令模式
    ↓
匹配危险模式?
    ├─ 是 → 返回 deny/ask
    └─ 否 → 返回 allow
    ↓
根据权限决策执行或拦截

6、实际效果:当 AI 尝试执行危险命令时,完美拦截!AI 无法执行危险操作,但不影响你手动操作。

图片

六、使用技巧

1、个人配置 `.gitignore`:Hooks 通常是个人配置,不需要提交到 Git

  团队共享配置:如果想与团队共享部分 Hooks(但不共享个人配置)

.cursor/
├── hooks.json          # 个人配置(不提交)
├── hooks.team.json     # 团队配置(提交到 Git)
└── hooks/
    ├── shared/         # 团队共享脚本(提交)
    │   └── security.js
    └── personal/       # 个人脚本(不提交)
        └── my-check.js
// gitignore
.cursor/hooks.json
.cursor/hooks/personal/
.cursor/hooks/*.log

2、性能优化:`afterFileEdit` hook 会频繁触发,保持轻量

// ✅ 好的做法:只记录日志
async function main() {
  const payload = JSON.parse(input);
  log(payload.file_path);
  process.exit(0);
}
// ❌ 不好的做法:执行耗时操作
async function main() {
  const payload = JSON.parse(input);
  runPrettier(payload.file_path);  // 每次编辑都格式化,太慢了!
  process.exit(0);
}

  建议:轻量操作用 `afterFileEdit`,重量操作用 `stop`。

3、错误处理:Hook 脚本出错会影响 Cursor 正常使用,务必做好异常处理

process.stdin.on('end', () => {
  try {
    // 你的逻辑
    const payload = JSON.parse(input);
    // ...
  } catch (error) {
    // 记录错误但不影响主流程
    logToFile({ error: error.message });
    console.log(JSON.stringify({ permission: 'allow' }));
    process.exit(0);  // 即使出错也正常退出
  }
});

4、Hook 会影响性能吗?

  - `afterFileEdit`: 每次编辑都触发,务必保持轻量(< 100ms)

  - `stop`: 对话结束触发,可以执行较重操作(< 5s)

  - `beforeShellExecution`: 命令执行前触发,建议 < 500ms

  优化建议:使用异步操作、避免同步的文件 I/O、大文件用流式处理、缓存计算结果

  总结:通过 Cursor Hooks,我们可以:

1、提升代码质量:自动格式化、行数检查、拆分建议  

2、保障安全性:拦截危险命令、权限控制  

3、增强可追踪性:记录所有操作日志  

4、自定义工作流:完全符合你的开发习惯

posted @ 2026-01-09 18:38  古兰精  阅读(48)  评论(0)    收藏  举报