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

323 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 表单字段来自:
- [bug_report.yml](../.github/ISSUE_TEMPLATE/bug_report.yml)
- [feature_request.yml](../.github/ISSUE_TEMPLATE/feature_request.yml)
- [reward-task.yml](../.github/ISSUE_TEMPLATE/reward-task.yml)
## 评分模型
每个 issue 会沿四个维度评分:
- `impact`1-5对用户和工作流的影响
- `urgency`1-5发布时间压力、功能损坏情况或重复讨论程度
- `effort`1-5预估改动规模和协作成本
- `confidence`1-5issue 描述的完整性和可执行程度
优先级计算公式如下:
```text
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/deferred`
`priority < 3.6`、issue 不受信息缺失阻塞、且 issue 年龄仍低于 SLA
升级底线时触发。
3. `triage/core`
`priority >= 3.6` 且满足以下任一条件时触发:
- issue 阻塞了 OpenClaw/ClawHub 核心工作流,例如 install、publish、
update、sync 或基于 namespace 的发布
- `effort >= 4`
- `confidence <= 3`
- 存在高风险关键词或会影响契约的字段
4. `triage/agent-ready`
`priority >= 3.6``effort <= 3``confidence >= 4`,且不存在高风险
信号时触发。
`assist` 模式下LLM 建议可以对 `impact``urgency``effort`
`confidence` 各自最多调整 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](../.github/workflows/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](../.github/workflows/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`](/Users/wowo/workspace/skillhub/.github/scripts)
- [github.ts](/Users/wowo/workspace/skillhub/.github/scripts/github.ts):精简版
GitHub REST 客户端
- [issue-triage-config.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-triage-config.ts)
标签、阈值和关键词规则
- [issue-llm-config.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-llm-config.ts)
LLM 模式、环境变量和调用启发式
- [issue-llm-provider.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-llm-provider.ts)
兼容 OpenAI 的 chat completions 客户端
- [issue-llm-evaluator.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-llm-evaluator.ts)
prompt 构造、JSON 校验和缓存 key 生成
- [issue-triage-lib.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-triage-lib.ts)
解析、评分、路由和评论渲染
- [issue-triage-merge.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-triage-merge.ts)
有界合并和硬性门槛重应用
- [issue-triage.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-triage.ts)
单 issue 入口
- [issue-backlog-rescore.ts](/Users/wowo/workspace/skillhub/.github/scripts/issue-backlog-rescore.ts)
deferred 队列重新评分入口
## 配置
设置以下 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 的变量示例:
```text
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 的自动化处理
- 如果使用 LLM`shadow` 模式开始
### 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` 用在更窄的仓库子集上