Skip to content

08 · PreToolUse / UserPromptSubmit Hook · 意图检测自动联动

v0.8 新增 · 2026-06-14 目标: 把 PM 的 5 步手动操作压缩到 1 句话 → 自动触发整套体系

1. 价值主张

当前痛点(v0.7): PM 接到新项目要手动跑 5 步: 1. lesson_lookup_hook.py --query "..." 拉历史教训 2. 判断要不要 spawn_new_base.py --customer ... 3. 决定 invoke 哪个 skill(三类业务 × 6 领域共 18 组合) 4. 看历史踩坑 md 找类似项目 5. 起 .env / settings 配置

v0.8 目标(本 hook): PM 一句话 "我做 LegalCo 法律教案" → hook 自动: - 检测意图(领域=法律, 业务类别=第二类知识教案, 甲方=LegalCo) - 注入历史教训 top 5(SBERT 检索) - 提示是否建专属 base(查 customer_bases.csv 看是否新甲方) - 推荐 invoke agent-knowledge-task skill - 把意图注入 Claude 上下文供下游决策

收益: 流程零摩擦,新员工也能立项即用,所有 PM 决策都有历史教训垫底。


2. Hook 类型选型

Hook 类型 触发时机 能否注入上下文 是否阻塞 适合本场景?
UserPromptSubmit 用户提交 prompt 之后, 工具调用之前 additionalContext 可阻塞 (exit 2) 首选
PreToolUse 每个工具调用前 ❌ 只能改参数 可阻塞 ❌ 每次工具都触发, 噪音大
SessionStart 会话开启时 ❌ 与具体项目无关

结论: 用 UserPromptSubmit(任务清单原名 PreToolUse 是泛指 "请求前 hook" 的口语化, 实际更精准是 UserPromptSubmit)。


3. 触发场景清单

3.1 三类业务关键词

触发短语 (正则) 业务类别 推荐 skill
我做.*(12 ?案例|出题|垂域出题|案例.*ECC[-\s]?\d+) ecc-vert-case
我做.*(知识教案|领域知识|6 ?领域) agent-knowledge-task
我做.*(agent.*基准|端到端评测|L3 ?基准|SWE[-\s]?bench) agent-benchmark-lab

3.2 六领域关键词(第二类用)

触发短语 领域
金融\|风控\|量化\|财报\|宏观经济 金融
法律\|法条\|案例分析\|合同\|司法 法律
医疗\|临床\|药物\|医学影像\|循证 医疗
工程\|CAD\|结构计算\|电路\|编程自动化 工程
农业\|作物\|病虫害\|土壤\|精准农业 农业

3.3 甲方识别

正则: (?:为|给|帮)([A-Z][A-Za-z0-9]+|[一-龥]{2,8})(?:.*?)(?:做|开发|交付)

样例: - "为 LegalCo 做法律教案" → customer=LegalCo - "给 AgentTrain 出 12 案例" → customer=AgentTrain - "帮深圳XX公司做评测" → customer=深圳XX公司

匹配后查 ~/Downloads/customer_bases.csv — 若不存在则提示 spawn_new_base.py


4. Hook 协议 (Claude Code)

4.1 输入 (stdin JSON)

{
  "hook_event_name": "UserPromptSubmit",
  "session_id": "xxx",
  "transcript_path": "/path/to/transcript.jsonl",
  "cwd": "C:\\Users\\chunx",
  "prompt": "我做 LegalCo 法律教案"
}

4.2 输出 (stdout JSON)

{
  "hookSpecificOutput": {
    "hookEventName": "UserPromptSubmit",
    "additionalContext": "<auto-injected by ecc-intent-detector>\n意图: 第二类知识教案 / 领域=法律 / 甲方=LegalCo (新甲方,建议 spawn_new_base)\n\n=== 历史教训 top 3 (SBERT) ===\n[1] score=0.834 · ecc-shared/audit-mock/01_对抗审查报告.md · 知识密度审计\n    第二类知识教案要求每题 ≥5 个 Knowledge Points + ≥200 字背景知识...\n...\n\n=== 推荐 invoke ===\n- skill: agent-knowledge-task\n- 模板: ~/.claude/skills/ecc-shared/sop/04_5角色SOP教程.md (角色2 教案人)\n\n=== 下一步建议 ===\n1. python ~/.claude/skills/ecc-shared/scripts/spawn_new_base.py --customer LegalCo\n2. python ~/.claude/skills/ecc-shared/scripts/knowledge_skeleton_generator.py --domain 法律\n</auto-injected>"
  }
}

4.3 阻塞策略 — 不阻塞

  • exit 0, 静默注入
  • 不打断用户 prompt
  • 用户可忽略也可采纳建议

5. 实现拆分

模块 文件 职责
意图识别引擎 scripts/intent_detector.py 正则匹配 + 关键词扫 → Intent dataclass
Hook 入口 scripts/user_prompt_submit_hook.py 读 stdin JSON, 调 intent_detector + lesson_indexer_v2, 输出 stdout JSON
单测 scripts/test_intent_detector.py pytest, 覆盖 9 类触发场景
Settings ~/.claude/settings.json 注册 hook (用户级或项目级)

6. Intent 数据结构

from dataclasses import dataclass

@dataclass(frozen=True)
class Intent:
    category: str | None      # "一" / "二" / "三" / None
    skill: str | None         # "ecc-vert-case" / "agent-knowledge-task" / "agent-benchmark-lab"
    domain: str | None        # "金融" / "法律" / "医疗" / "工程" / "农业" / "其他"
    customer: str | None      # 甲方简称
    is_new_customer: bool     # 查 customer_bases.csv 后判定
    confidence: float         # 0.0 ~ 1.0 (匹配规则数)
    matched_phrases: tuple[str, ...]  # 触发的短语

7. 测试用例(B2 阶段写)

ID 输入 prompt 期望 category / skill / domain / customer
T1 "我做 12 案例 ECC-2026-007" 一 / ecc-vert-case / None / None
T2 "我做 CAD 知识教案" 二 / agent-knowledge-task / 工程 / None
T3 "我做 LegalCo 法律教案" 二 / agent-knowledge-task / 法律 / LegalCo (新)
T4 "我做 agent 端到端评测 L3 基准" 三 / agent-benchmark-lab / None / None
T5 "为 AgentTrain 做评测" 三 / agent-benchmark-lab / None / AgentTrain (老)
T6 "帮医疗甲方做循证医学教案" 二 / agent-knowledge-task / 医疗 / None
T7 "你好" None / None / None / None (零匹配, 不注入)
T8 "我做金融风控建模" 二 / agent-knowledge-task / 金融 / None
T9 "我做 SWE-bench 真跑" 三 / agent-benchmark-lab / None / None

8. 部署 — settings.json 配置

8.1 用户级 (~/.claude/settings.json)

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "command": "python C:/Users/chunx/.claude/skills/ecc-shared/scripts/user_prompt_submit_hook.py",
        "description": "ECC 意图检测 - 自动注入历史教训和推荐",
        "timeout": 5000
      }
    ]
  }
}

8.2 性能预算

  • 冷启动 SBERT: ~3 秒(load model + load embedding)
  • 检测 + 检索: <500 ms
  • 总 timeout: 5 秒
  • 降级: 超时直接 exit 0 无输出, 不阻塞用户

8.3 关闭开关

环境变量 ECC_INTENT_HOOK_DISABLED=1 可临时关闭(脚本第一行检查)。


9. 与现有 19+1 脚本的集成

上游/下游 集成方式
lesson_indexer_v2.py hook 调 search(query, top_k=3) 函数(已模块化)
lesson_lookup_hook.py 弃用(本 hook 是其升级版)
spawn_new_base.py hook 仅提示, 不自动调用(避免意外建 base)
customer_bases.csv hook 读它判定 is_new_customer

10. v0.8 完成判定 (B3 端到端测)

用户在 Claude Code 输入: "我做 LegalCo 法律教案"
预期看到的 additionalContext:
  ✓ 业务类别: 第二类知识教案
  ✓ 领域: 法律
  ✓ 甲方: LegalCo (老甲方, base_token=A5JzbN8iLabehnsmRVAcFHFqn5f)
  ✓ 历史教训 top 3
  ✓ 推荐 invoke agent-knowledge-task
  ✓ 下一步: knowledge_skeleton_generator --domain 法律

作者: chunx + claude (v0.8 Track B1) 下一步: B2 写 intent_detector.py + user_prompt_submit_hook.py + 9 用例 pytest 关联: SOP 主文档 01_统一SOP主文档.md 第 5 章 PM 流程