学习指南: Qwen Code 钩子示例

模块「Qwen Code 钩子示例」中第 2 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

主题:Qwen Code 钩子示例

难度级别:中级

预计学习时间:4-6 小时(理论 + 实践)

前置条件: Python 基础知识(语法、文件操作、JSON)

理解命令行和 Bash 的工作原理

有使用 Qwen Code 或类似 AI 编程助手的经验

了解软件系统中钩子(hooks)的概念

具备 Git 和版本控制系统的基本操作技能

学习目标: 根据文档示例配置并激活三种 Qwen Code 钩子(pre_tool_guard、log_tool_result、inject_sdd_context)

修改 pre_tool_guard.py 脚本,将自定义危险命令添加到阻止列表中

分析和扩展 log_tool_result.py 的工具日志系统,以满足特定项目需求

通过 inject_sdd_context.py 将项目 SDD 文件上下文集成到工作流程中

手动将 settings-workflow.example.json 中的设置与现有的 .qwen/settings.json 合并,且不丢失配置

概述:本学习指南致力于实践掌握 Qwen Code 中的钩子系统——一种扩展 AI 编程助手功能的机制。钩子允许在工具执行的各个阶段拦截和修改其行为:启动前(pre-)、执行后(post-),以及向工作流注入额外上下文。本材料基于教程第 17 部分中的三个生产级示例:pre_tool_guard.py 安全系统、log_tool_result.py 审计系统和 inject_sdd_context.py 上下文增强机制。学习这些示例将使您掌握创建自定义钩子以解决实际问题的技能:从防止意外删除数据到自动记录 AI 助手的操作。

关键概念: 钩子(hook):Qwen Code 架构中的扩展点,是一个可执行脚本(通常用 Python 编写),在工具生命周期的特定时刻被调用。钩子允许在不修改系统核心的情况下改变其行为,实现控制反转(Inversion of Control)原则。

Pre-tool 钩子:在工具启动前执行的钩子。用于验证、阻止危险操作、请求额外确认。在 pre_tool_guard.py 示例中,实现了对破坏性 Bash 命令的防护。

Post-tool 钩子:在工具执行完毕后运行的钩子。用于日志记录、结果分析、通知、数据后处理。log_tool_result.py 示例展示了以 JSON Lines 格式进行紧凑事件日志记录。

上下文钩子(context injection):向 AI 对话上下文中注入额外信息的钩子。inject_sdd_context.py 示例自动添加关于 SDD 文件结构(软件设计文档)的备忘,帮助模型遵循项目的架构决策。

Settings-workflow.example.json:示例配置文件,演示同时连接多个钩子的语法。包含 hooks 结构,指定路径、事件类型和执行优先级。

JSON Lines(jsonl):文本文件格式,每行是一个独立的有效 JSON 对象。在 log_tool_result.py 中用于紧凑且便于解析的日志记录:新事件只需追加到文件末尾,无需重写整个结构。

SDD(Software Design Document):软件架构描述文档。在 inject_sdd_context.py 钩子的上下文中,这是关于项目的元信息,AI 在生成代码时应加以考虑,以保持与已确定的项目决策的一致性。

可执行权限(chmod +x):类 Unix 操作系统中的文件系统属性,允许将脚本作为程序运行。对 Qwen Code 钩子至关重要,因为系统通过 exec 机制直接调用它们。

手动合并设置:将示例配置集成到现有 settings.json 中的过程,不使用自动合并工具。需要仔细操作以保留用户当前设置并正确遵守 JSON 语法。

实践练习: 标题:安装和激活基础安全钩子

问题:将示例中的 pre_tool_guard.py 文件复制到 .qwen/hooks/ 目录,使其可执行,并手动在 .qwen/settings.json 中添加相应部分。测试其工作:启动 Qwen Code 并要求执行命令 'rm -rf /tmp/test'。确认钩子阻止执行。然后将 'dd if=/dev/zero of=/dev/sda' 添加到禁止命令列表中,并测试该命令的阻止效果。

解决方案:1. 创建目录:mkdir -p ~/.qwen/hooks/

  1. 复制脚本:cp pre_tool_guard.py ~/.qwen/hooks/
  2. 赋予可执行权限:chmod +x ~/.qwen/hooks/pre_tool_guard.py
  3. 在编辑器中打开 ~/.qwen/settings.json
  4. 添加 hooks 部分(或扩展现有部分):

{ "hooks": [ { "path": "~/.qwen/hooks/pre_tool_guard.py", "event": "pre_tool", "tool": "Bash", "priority": 100 } ] }

  1. 保存文件,检查 JSON 有效性
  2. 启动 Qwen Code,请求执行 'rm -rf /tmp/test'
  3. 通过钩子消息确认阻止
  4. 编辑 pre_tool_guard.py:将 'dd if=/dev/zero of=/dev/sda' 添加到 dangerous_commands 列表
  5. 重启 Qwen Code,测试新命令的阻止效果

难度:初级

标题:扩展带过滤功能的日志系统

问题:激活 log_tool_result.py 钩子。创建一个场景,在使用 Qwen Code 的 10 分钟内积累日志。然后修改钩子:添加过滤功能——仅记录 Bash 工具的事件,且仅当命令执行时间超过 1 秒时才记录。确认过滤后的日志仅包含所需记录。

解决方案:1. 按照第一个练习的方式安装 log_tool_result.py

  1. 在 settings.json 中添加 event 为 "post_tool" 的钩子
  2. 执行各种任务:读取文件、Bash 命令、搜索
  3. 检查积累的日志:cat ~/.qwen/hooks/logs/tool-events.jsonl | jq .
  4. 创建原始钩子的备份副本
  5. 修改脚本:在处理函数开头添加检查:

if tool_name != 'Bash': return if result.get('duration_ms', 0) < 1000: return

  1. 保存,重新赋予可执行权限
  2. 清空日志:> ~/.qwen/hooks/logs/tool-events.jsonl
  3. 重复工作场景
  4. 确认日志中只有耗时的 Bash 命令
  5. 比较过滤前后的日志体积

难度:中级

标题:为团队创建综合 SDD 上下文

问题:为您的项目设计三个 SDD 文件:架构.md、api-契约.md、代码风格.md。配置 inject_sdd_context.py 以根据用户请求类型自动注入相关上下文。如果请求包含 'API' 或 'endpoint' —— 注入 api-契约.md;如果包含 '重构' 或 '风格' —— 注入 代码风格.md;其他情况 —— 注入 架构.md。在测试请求上验证其工作效果。

解决方案:1. 创建项目目录:mkdir -p ~/my-project/sdd/

  1. 创建三个包含有意义内容的文件(每个 5-10 条要点)
  2. 将 inject_sdd_context.py 复制到 ~/.qwen/hooks/
  3. 修改文件选择逻辑:

import re def select_sdd(user_message): msg_lower = user_message.lower() if any(kw in msg_lower for kw in ['api', 'endpoint', 'rest']): return 'api-契约.md' elif any(kw in msg_lower for kw in ['重构', '风格', '格式化']): return '代码风格.md' else: return '架构.md'

  1. 更新钩子的主函数以使用 select_sdd
  2. 在 settings.json 中配置 event 为 "pre_tool" 或 "pre_message" 的钩子(取决于 Qwen Code 版本)
  3. 依次测试:
  • "为用户创建 API endpoint" → 应加载 api-契约.md
  • "按项目风格重构这个模块" → 代码风格.md
  • "如何组织数据库?" → 架构.md
  1. 通过调试输出或日志检查选择了哪个文件
  2. 在项目 README 中记录选择规则

难度:中级

标题:合并设置时的备份和恢复

问题:您已经配置了一个复杂的 .qwen/settings.json,包含自定义提示、模型偏好和一个遗留钩子。从教程中获取 settings-workflow.example.json,并正确集成所有三个新钩子,同时保留现有配置。创建一个验证脚本,检查最终 JSON 的完整性以及 hooks 数组中无重复项。

解决方案:1. 创建备份:cp ~/.qwen/settings.json ~/.qwen/settings.json.backup.$(date +%s)

  1. 研究当前结构:cat ~/.qwen/settings.json | jq 'keys'
  2. 研究 settings-workflow.example.json:cat settings-workflow.example.json | jq '.hooks'
  3. 创建中间文件 merge.json
  4. 手动合并:从两个文件中复制根级字段
  5. 对于 hooks 数组:提取现有的,添加新的,并设置正确的优先级
  6. 确保组合的唯一性(path + event + tool):

jq '.hooks | group_by(.path, .event, .tool) | map(select(length > 1)) | length' merge.json 结果应为 0

  1. 检查 JSON 有效性:python3 -c "import json; json.load(open('merge.json'))"
  2. 创建 validate-settings.py 脚本以自动化检查
  3. 应用:cp merge.json ~/.qwen/settings.json
  4. 启动 Qwen Code,验证所有钩子的工作
  5. 如有错误 —— 从备份回滚

难度:高级

案例研究: 标题:在金融科技初创公司中实施安全钩子

场景:一个 8 人开发团队的金融科技初创公司积极使用 Qwen Code 加速微服务开发。第一个月发生了两起事件:一次 AI 助手建议并差点执行了开发环境数据库中的 'DROP TABLE transactions CASCADE' 命令,另一次由于请求中的歧义上下文差点执行了 'kubectl delete namespace production'。管理层要求在不显著拖慢工作流程的情况下实施多层防护系统。

挑战:主要困难:(1)现有的 pre_tool_guard.py 示例仅覆盖明显的危险命令 rm -rf、mkfs、dd,但不了解金融科技基础设施的 specifics(kubectl、psql、liquibase)。(2)开发人员抵制额外确认,认为它们是"绊脚石"。(3)需要集中式审计系统来调查事件。(4)团队处理敏感数据,因此日志不能发送到外部系统。

解决方案:团队将教程中的三个钩子适配为综合系统:(1)扩展 pre_tool_guard.py:添加 SQL 命令模式(DROP、不带 WHERE 的 TRUNCATE)、kubectl 操作(delete、drain、taint)和特定工具(liquibase dropAll、flyway clean)的模式。实现了危险等级分级:对灾难性命令"阻止",对有风险命令"要求明确确认",对潜在问题命令"警告"。(2)配置 log_tool_result.py 在加密分区本地存储,添加敏感数据(PAN、CVV)的掩码处理,通过正则替换在写入前进行脱敏。(3)创建 inject_sdd_context.py 包含企业标准:处理数据库时 —— 关于禁止无迁移直接操作的备忘,处理 k8s 时 —— namespace 隔离规则。逐步实施:首先在无阻止的日志记录模式(观察一周),然后软警告,最终完全阻止。

结果:系统运行 6 个月期间:阻止了 23 次潜在危险操作(14 次 —— 无迁移的 SQL 命令,7 次 —— production 上下文中的 kubectl 操作,2 次 —— 数据清理尝试)。"灰色地带"命令的平均确认时间为 8 秒,团队认为可接受。审计线索允许在 15 分钟内恢复测试客户数据事件的完整时间线。开发人员注意到,SDD 上下文将向新团队成员解释架构决策的时间缩短了 30%。该系统成为控股公司中其他团队的标杆。

经验教训: 以仅审计模式开始实施安全钩子:记录而不阻止,以衡量真实危险场景的频率并避免误报

根据基础设施 specifics 调整危险命令列表:通用的 pre_tool_guard.py 只是起点

反应分级(阻止 / 确认 / 警告)对于平衡安全性和开发速度至关重要

带掩码的本地日志记录解决了审计需求与信息安全要求之间的冲突

上下文钩子(inject_sdd_context)作为"被动防护"运作:在错误发生前预防,减轻主动阻止的负担

相关概念: Pre-tool 钩子

Post-tool 钩子

上下文钩子(Context injection)

手动合并设置

JSON Lines(JSONL)

标题:优化分布式开发团队的日志记录

场景:一个分布在三个时区的 15 人开发团队,使用 Qwen Code 开发大型开源项目。协调员遇到问题:当 AI 生成的代码出现错误时,无法恢复究竟执行了哪些工具以及使用了哪些参数。Qwen Code 的标准日志不够详细,开发人员忘记手动记录复杂会话。

挑战:关键问题:(1)标准 log_tool_result.py 写入每个开发人员的本地机器,使聚合不可能。(2)日志量线性增长,一个月后 tool-events.jsonl 文件达到 500 MB,减慢读取速度。(3)日志不包含会话标识符,使事件关联困难。(4)某些工具(例如,多次代码搜索)产生"噪音"——数百条无用记录。(5)需要保护隐私:日志不应包含含密钥的文件内容。

解决方案:团队创建了标准钩子的进化版本:(1)在日志中添加会话标识符(UUID4,通过环境变量 QWEN_SESSION_ID 在 Qwen Code 启动时生成)。(2)实现日志轮转:每日创建新文件 tool-events-YYYY-MM-DD.jsonl,旧文件通过 gzip 归档。(3)添加按工具类型过滤:仅记录 Bash、Edit、Write——改变系统状态的工具。排除 Read、Search、Glob 作为非改变性工具。(4)实施清理:写入前检查内容是否符合密钥模式(AWS 密钥、令牌等正则表达式),匹配则替换为 [REDACTED]。(5)创建可选同步:当存在变量 QWEN_LOG_SYNC_URL 时,匿名化日志发送到中央 S3 兼容存储桶进行聚合。

结果:日志系统变得透明且可扩展:活动日志文件的平均大小从 500 MB 降至 12 MB。由于每日分段,日志搜索时间从分钟缩短到秒。94% 的会话在问题升级时通过 session_id 成功关联。发现 3 个 AI 行为的系统性错误(单一工具的循环调用),并在上游修复。清理系统在 4 个月运行中通过安全审计,零泄露。钩子代码被提取到独立的开源仓库,获得 340 个星标。

经验教训: 日志轮转和分段对于长期运行是必需的:单体 JSONL 文件无法扩展

会话标识符将本地日志转变为可追踪的系统:一行代码的投资带来分析上的秩序

按"改变状态"工具过滤可将噪音降低 80-90%,且不丢失关键信息

清理应该是主动的,不是被动的:在首次事件前嵌入密钥模式检查

开源方法发展钩子创造网络效应:外部贡献在不直接投入的情况下改进您的系统

相关概念: Post-tool 钩子

JSON Lines(JSONL)

可执行权限(chmod +x)

学习技巧: 从单个钩子开始:安装 pre_tool_guard.py,确认其工作,然后再添加其他。并行安装所有三个会将配置错误的可能性增加 3-4 倍

维护"实验日志"——一个单独的文件,记录对 settings.json 的每次更改及其日期和验证结果。这在合并错误后回滚时会拯救您

使用 jq 验证和研究 JSON 结构:jq '.' settings.json 检查语法,jq '.hooks | length' 统计钩子数,jq '.hooks[] | select(.event=="pre_tool")' 按类型过滤

创建测试"沙盒"——一个隔离的项目,复制 .qwen/,可以在其中实验而无破坏工作配置的风险

为了理解数据流,临时在每个钩子中添加调试输出到 stderr:print(f"DEBUG: hook triggered for {tool_name}", file=sys.stderr)。调试后删除

逐行研究原始脚本,不要盲目复制。尝试在阅读注释前预测下一行的功能——这将加速对架构的理解

在简单示例上练习手动合并:取两个小的 JSON 文件,在记事本中合并,用验证器检查。这个技能在更新 Qwen Code 版本时会派上用场

为了听觉感知:大声朗读脚本,向想象中的对话者解释逻辑。这会激活其他记忆通道并揭示理解上的空白

创建钩子检查清单:可执行权限?正确的 shebang?settings 中的有效 JSON?正确的事件?hooks 数组中的唯一性?——在每次运行前执行

修改钩子时使用版本控制系统:在 ~/.qwen/hooks/ 中初始化 git,提交每个工作状态。回退到上一个提交比手动恢复更快

额外资源: Qwen Code 官方文档(第 17 部分):包含 settings-workflow.example.json 和三个钩子参考实现的原始教程——所有修改的起点

JSON Lines 规范:https://jsonlines.org/ —— log_tool_result.py 中使用格式的正式描述,包含不同语言的解析示例

Python subprocess 模块文档:https://docs.python.org/3/library/subprocess.html —— 深入理解钩子基础的进程启动和交互机制

Jq 手册:https://stedolan.github.io/jq/manual/ —— 命令行中处理 JSON 配置和日志的必备工具

《Secure by Design》(Manning Publications):关于设计安全系统原则的书籍,适用于钩子架构——特别是关于故障安全默认值和纵深防御的章节

Git 钩子文档:https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks —— 用于比较模式和最佳实践的并行钩子生态系统

Open-source 仓库 enhanced-qwen-hooks:标准钩子的假设性社区扩展,包含额外示例和测试(在 GitHub 上按关键词搜索)

总结:Qwen Code 钩子系统是一个强大的机制,通过三个关键注入点扩展 AI 编程助手:预验证(pre_tool_guard.py)、事后审计(log_tool_result.py)和上下文增强(inject_sdd_context.py)。掌握这些示例不仅需要理解 Python 和 JSON 语法,还需要理解架构原则:控制反转、事件反应分级、安全性与便利性的平衡。关键技能是手动合并配置——一项需要细心和系统方法的操作。成功应用钩子将 Qwen Code 从被动工具转变为具有企业安全策略、透明审计和一致架构纪律的主动管理系统。从简单开始,记录每一步,对脚本使用版本控制——您将获得可靠的基础设施,可从个人开发扩展到分布式团队。

我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

基于 Qwen Code CLI 的规范驱动开发
进度 0 / 135