Skip to content

[feat] 统计每个对话的人工干预次数(Human Intervention 指标) #34

Description

@jeff-r2026

Problem / 背景动机

teamai 的 dashboard 已经能实时展示每个 AI 会话(session)的运行状态,但缺少一个关键的质量 / 自主性指标:在一次对话里,用户到底人工干预了多少次?

「人工干预」是衡量 coding agent 自主完成度的核心信号。干预越少,说明 agent 一次把事做对的能力越强;干预多的会话往往对应:

  • 任务描述不清,反复纠偏
  • agent 走错方向,被用户打断(ESC / interrupt)
  • agent 想执行危险/越权操作,被用户拒绝(permission deny)

如果能按 每个对话 统计干预次数,并在 dashboard / digest 里聚合,团队就能回答:

  • 哪些类型的任务 agent 自主性差、需要人盯着?
  • 哪些 skill / rule 上线后干预率下降了(效果验证)?
  • 团队整体的「人均干预率」趋势如何?

什么算「人工干预」(信号定义)

一次对话内,下列事件各计为一次干预(MVP 范围,可迭代):

干预类型 含义 数据来源
interrupt 用户在 agent 执行中途打断(ESC) transcript 中被中断的 assistant turn
tool_reject 用户拒绝某个工具调用(permission deny) transcript 中 tool_result 标记拒绝 / PreToolUse deny
correction agent stop 后用户立即追加 prompt 纠偏(非新任务) stop 事件后紧跟的 prompt_submit

注:纯多轮对话(用户主动推进下一步)不应计为干预。区分「纠偏」与「正常推进」是本方案需要讨论的核心难点,见下方「待讨论」。

Proposed Solution

复用现有 dashboard 事件管线(src/dashboard-collector.ts + events.jsonl),不新增独立采集通道

1. 采集层

  • Stop / SessionEnd hook 触发时,解析 transcript(已有 readLastAssistantOutput 的 tail-read 基础设施,可扩展为统计扫描),提取本轮 turn 内的 interrupt / tool_reject 计数。
  • correction 信号无需读 transcript,直接在 rebuildSessions 折叠事件时识别「stop 后短时间内出现 prompt_submit」的模式。

2. 数据模型

  • 扩展 DashboardEvent,新增 interventions?: { interrupt: number; toolReject: number; correction: number }(或新增 type: 'intervention' 事件,二选一,见 Alternatives)。
  • DashboardSession 增加聚合字段 interventionCount,在 rebuildSessions 中累加。

3. 展示层

  • Dashboard 卡片src/dashboard-html.ts):每个会话卡显示干预次数 / 干预率徽标。
  • Digestsrc/digest.ts):新增「会话自主性」榜单——按干预次数排序,给出团队均值。

4. 隐私

  • 只统计次数,不落地 prompt / transcript 原文,符合现有 dashboard 仅存摘要的约定。

实现阶段

  1. 定义信号 + 扩展数据模型(types.ts / DashboardEvent)→ 验证:单测覆盖三类信号的 fold 逻辑
  2. transcript 解析增强(interrupt / tool_reject)→ 验证:用真实 transcript 样本断言计数
  3. correction 模式识别(stop→prompt 时间窗)→ 验证:构造事件序列断言
  4. dashboard + digest 展示 → 验证:HTML 快照 / digest 输出
  5. 文档(docs/usage-guide.md

Alternatives Considered

  • 新增独立 intervention 事件 vs. 复用 stop 事件携带计数:前者管线更清晰但写入次数翻倍;后者复用现有 hook、零新增 hook 配置。倾向后者。
  • 实时逐次采集(PreToolUse hook 记录每次 deny):能拿到更精确的拒绝信号,但要新增 hook 注入点、增加每次工具调用的开销。MVP 先用 transcript 事后解析,必要时再加。
  • 跨工具一致性:Claude Code / CodeBuddy 的 transcript 格式与中断/拒绝标记不同,Cursor 可能拿不到。方案需对「无 transcript 的工具」优雅降级(只统计 correction)。

待讨论 / 待定

  1. correction 的判定阈值(stop→prompt 的时间窗口多长算「纠偏」而非「新任务」)?是否结合 prompt 语义(如出现「不对 / 重来 / 错了」等)?
  2. 干预率的分母用什么——turn 数、tool_use 数、还是会话时长?
  3. 是否需要按「用户」「skill」「项目」三个维度做下钻聚合?

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions