skillhub/docs/2026-04-08-issue-automation-design.md
wowo 8f694ddc7c
[codex] add issue triage automation mvp (#268)
* add issue triage automation mvp

* Document issue automation design in Chinese

* Fix legacy compat slug tests
2026-04-09 15:04:33 +08:00

10 KiB
Raw Blame History

Issue 自动分诊 MVP 设计

目标

通过自动将 GitHub issue 分诊到三个队列中,降低维护者负担:

  • triage/deferred:低优先级 issue会随着时间推移逐步上浮
  • triage/core:高优先级或高风险 issue需要 core maintainer 接手
  • triage/agent-ready:高优先级、低风险 issue适合作为后续 agent 执行候选

本 MVP 版本还不会自动修复 issue。它聚焦在评分、路由、打标签以及让 backlog 持续流动。

当前版本支持两种执行模式:

  • 仅规则分诊
  • 规则 + 兼容 OpenAI 的 LLM 辅助

为什么这样拆分

最初的方案把优先级和执行难度混在同一个决策里。实践上,如果把它们拆开, 系统会更容易调参:

  • Priority:这个 issue 现在是否值得投入时间?
  • Route:一旦值得处理,应该由谁来接手?

这样一来,高价值但高难度的 issue 仍然可以保持高优先级,同时继续路由到 triage/core

输入

自动化会读取 issue 的实时标题、正文、标签、评论和时间戳。

结构化的 issue 表单字段来自:

评分模型

每个 issue 会沿四个维度评分:

  • impact1-5对用户和工作流的影响
  • urgency1-5发布时间压力、功能损坏情况或重复讨论程度
  • effort1-5预估改动规模和协作成本
  • confidence1-5issue 描述的完整性和可执行程度

优先级计算公式如下:

priority = impact * 0.45 + urgency * 0.35 + age_boost + engagement_boost

其中:

  • age_boost:基于 SLA 的升级机制
    • 第 7-9 天:预热阶段,最低提升到 priority/p2
    • 第 10-13 天:强制移出 triage/deferred,最低提升到 priority/p1
    • 第 14 天及以后:在下一次 triage/rescore 时,将该 issue 视为已违反 SLA 并至少提升到 priority/p0
  • engagement_boost:由评论压力和奖励金额共同决定,上限为 +1.0

在 MVP 中,effort 不会直接降低优先级,它只影响路由。

LLM 辅助分诊

配置后,工作流可以调用兼容 OpenAI 的 chat completions API。

LLM 不会替代规则引擎。它只用于辅助:

  • 生成 issue 摘要
  • 对软性分数做微调
  • 生成 needs-info 的追问问题
  • 为维护者提供更好的判断依据
  • triage/core 生成 maintainer 交接摘要

硬性门槛仍然由规则控制:

  • 缺失必填信息
  • auth、schema、migration、SDK 或公共契约变更等高风险区域
  • 最终是否可以提升到 triage/agent-ready

issue 正文和评论都视为不可信输入。工作流会:

  • 在发送给模型前截断过长的正文和评论
  • 明确告诉模型issue 文本是数据而不是指令
  • 使用严格的 JSON 协议校验模型输出
  • 如果 provider 调用失败或 JSON 校验失败,则回退到仅规则模式

模式

  • off:仅规则
  • shadow:调用 LLM 并展示其建议,但最终仍沿用仅规则的路由和标签
  • assist:允许 LLM 对软性分数做最多 +/-1 的微调,然后重新应用硬性门槛

何时使用 LLM

工作流只会在 issue 看起来存在歧义或价值较高时调用 LLM例如

  • triage/needs-info
  • triage/core
  • 靠近路由阈值的 issue
  • 低置信度案例
  • 正文很长或讨论很多的 issue
  • 需要更多判断的 feature 或 reward issue

路由规则

  1. triage/needs-info 当缺少必填字段或 confidence <= 2 时触发。

  2. triage/deferredpriority < 3.6、issue 不受信息缺失阻塞、且 issue 年龄仍低于 SLA 升级底线时触发。

  3. triage/corepriority >= 3.6 且满足以下任一条件时触发:

    • issue 阻塞了 OpenClaw/ClawHub 核心工作流,例如 install、publish、 update、sync 或基于 namespace 的发布
    • effort >= 4
    • confidence <= 3
    • 存在高风险关键词或会影响契约的字段
  4. triage/agent-readypriority >= 3.6effort <= 3confidence >= 4,且不存在高风险 信号时触发。

assist 模式下LLM 建议可以对 impacturgencyeffortconfidence 各自最多调整 1 分。规则引擎随后会重新计算优先级和路由。

涉及 OpenClaw/ClawHub 核心工作流的 issue 是进入 triage/core 的硬性门槛; LLM 辅助不会放宽这一规则。

受管标签

自动化负责管理以下标签前缀:

  • triage/
  • priority/
  • effort/
  • risk/

当前使用的具体标签有:

  • triage/needs-info
  • triage/deferred
  • triage/core
  • triage/agent-ready
  • priority/p0
  • priority/p1
  • priority/p2
  • priority/p3
  • effort/s
  • effort/m
  • effort/l
  • risk/high

其余所有标签都保持不变。

另外,自动化还识别一个不由其管理的人工操作标签:

  • triage-manual:冻结该 issue 的自动分诊更新

工作流

1. Issue 分诊

文件:issue-triage.yml

触发条件:

  • issues.opened
  • issues.edited
  • issues.reopened
  • 当评论包含 /retriage 时触发 issue_comment.created
  • workflow_dispatch

执行动作:

  • 拉取 issue 和评论
  • 计算分数和路由
  • 更新或创建受管标签
  • 更新或创建一条分诊评论,其中同时包含人类可读的判断理由和隐藏的机器状态
  • 可选调用兼容 OpenAI 的 provider并合并结果

2. Deferred Backlog 重新评分

文件: issue-backlog-rescore.yml

触发条件:

  • 每 6 小时一次
  • workflow_dispatch

执行动作:

  • 列出所有带有 triage/deferred 标签的 open issue
  • 结合年龄和参与度加成重新计算优先级
  • 决定将每个 issue 升级还是保留
  • 原地更新分诊评论
  • 当 issue 内容未变化时复用缓存的 LLM 结果

试运行说明:

  • 当前定时 rescore 只扫描 triage/deferred 队列中的 issue
  • 这可以保证低优先级 backlog 不会在 deferred 中闲置超过第 10 天
  • 一旦某个 issue 已经从 deferred 中升级出去,之后第 14 天的进一步升级 依赖新的 triage 事件或手动 /retriage
  • 在试运行阶段14 天规则应被视为运营层面的 SLA 目标,而不是仓库范围内的 硬性计时器

脚本

新的 GitHub 自动化脚本位于 .github/scripts

配置

设置以下 GitHub 仓库变量和 secret即可启用 LLM 辅助分诊:

仓库变量:

  • ISSUE_TRIAGE_LLM_MODE
  • ISSUE_TRIAGE_LLM_BASE_URL
  • ISSUE_TRIAGE_LLM_MODEL
  • ISSUE_TRIAGE_LLM_TIMEOUT_MS 可选
  • ISSUE_TRIAGE_LLM_TEMPERATURE 可选
  • ISSUE_TRIAGE_LLM_MAX_COMMENTS 可选
  • ISSUE_TRIAGE_LLM_MAX_COMMENT_CHARS 可选
  • ISSUE_TRIAGE_LLM_MAX_BODY_CHARS 可选

仓库 secret

  • ISSUE_TRIAGE_LLM_API_KEY

建议的第一轮上线方式:

  • ISSUE_TRIAGE_LLM_MODE=shadow
  • 先观察几天分诊评论
  • 等 LLM 建议看起来稳定后,再切换到 assist

兼容 OpenAI 的变量示例:

ISSUE_TRIAGE_LLM_MODE=shadow
ISSUE_TRIAGE_LLM_BASE_URL=https://your-provider.example.com/v1
ISSUE_TRIAGE_LLM_MODEL=gpt-4.1-mini

推出计划

Phase 1当前阶段

  • 启用 triage 和 backlog rescore
  • 观察几周的 issue 流量后微调阈值
  • 允许维护者通过 triage-manual 冻结特定 issue 的自动化处理
  • 如果使用 LLMshadow 模式开始

Phase 2Maintainer 交接

triage/core issue 增加 issue-brief 生成器,输出内容包括:

  • 复现提示
  • 可能涉及的模块
  • 风险备注
  • 验证清单

这些输出可以直接用于本地编程 agent 会话,以及现有的并行 worktree 流程。

当前 MVP 已经会在 triage/core issue 的分诊评论中直接嵌入一个 Maintainer Brief 区块。该摘要包括:

  • 简洁的 issue 摘要
  • issue 为什么被升级到 core
  • 复现路径或操作路径备注
  • 疑似相关模块或工作流负责人
  • 风险提示
  • 验证清单

Phase 3自托管 Issue Agent

增加一个自托管 runner监听 triage/agent-ready,并执行:

  • 创建隔离的分支和 worktree
  • 运行解决 issue 的 agent
  • 执行最小相关测试集
  • 打开一个 draft PR

在这个阶段,以下场景仍应保留硬性阻断:

  • auth 和权限变更
  • 安全敏感变更
  • schema 或 migration 相关工作
  • 公共 API、SDK 或 CLI 契约变更

待调优问题

  • 参与度加成是否只看评论数就够了,还是也应该拉取 reactions
  • reward issue 是否应比当前 MVP 获得更强的价值加成
  • agent-ready 是否应要求 effort <= 2,而不是 <= 3
  • 某些区域(如 scanner)是否应默认视为高风险
  • 某些团队是否应长期保持 shadow 模式,只把 assist 用在更窄的仓库子集上