issue-ingest · diff
git:20260903.c0ca896 to git:20260910.b327dc1
2 added, 0 removed. Audit B to B.
---
name: issue-ingest
description: >
从外部 issue 源(GitHub 等)批量导入案例知识。编排上游 issue 拉取、硬过滤、价值评估、沉淀与状态标记:拉取精简元数据(fetch_issues.py,不含 body),硬过滤+启发式排序(issue_filter.py:label 池/评论数/标题规则/已处理排除),对候选按需评估(subagent 读 body 判断可否沉淀),通过的走 to-postmortem 沉淀为 case 草稿(进 inbox 待审),完成后标记已导入(幂等)。框架差异(repo、label 体系)参数化配置。前置环境:gh CLI 已安装并登录(未登录引导 gh auth login)。这是外部 issue 源 → case 的统一批量注入入口,与 to-postmortem(人工笔记等异构来源)互补。
---
# Issue Ingest
从上游仓库的 closed issue 批量沉淀 case。适合:团队想吸收某框架(vllm-ascend / vllm / mindspeed-llm…)的 issue 里的排障知识,而不想逐条手工翻 issue。
**自动化边界(拉取→沉淀全自动;升格分场景,2026-09 明确)**:本 skill 自动完成"拉取 → 过滤 → 评估 → 沉淀草稿 → 标记已导入",产出 `status: draft` 的 case 草稿进 `postmortems/inbox/`——**不进诊断上下文**。升格分两种:
- **默认(人工审后转正)**:维护者批量审 inbox(knowledge-groom 周批)后转正——知识生效点(draft → active)是人;
- **自动化升格(owner 预授权源)**:本 skill 即 owner 配置的持续管道,其产出的草稿 verification 链完整(upstream-fix-merged 等外部验证)+ pre-triage 判别完成——**可直接调 knowledge-groom 升格入库提 PR**,不等周批(同 2026-W36 round2 全自动轮 22 case 先例;groom SKILL「触发场景区分」)。逐条人审不是自动化源的必经环节。
## 前置环境(不满足先处理,不跳过)
1. **gh CLI**:`gh --version` 检查;未安装 → 提示用户安装(`curl -fsSL https://cli.github.com/ | sh` 或包管理),装完重查;
2. **gh 登录**:`gh auth status` 检查;未登录 → 引导用户 `gh auth login`(选 GitHub.com → HTTPS → **Login with a web browser**,用户浏览器完成授权)——不要替用户输入凭据,等 auth status 通过;
3. 其他源(GitCode 等):确认对应 CLI(如 `gitcode-cli`)已装已登录,本 skill 流程以 GitHub 为例,其他源换 CLI 命令即可(缓存格式保持一致:number/title/comments/closed_at/labels/state_reason)。
## 输入方式(按需交互:给得越全,问得越少)
```
/skill:issue-ingest --repo vllm-project/vllm-ascend --labels triaged [--since <ISO时间>] [--min-comments 3] [--limit 20] [--mode auto|confirm]
/skill:issue-ingest vllm-ascend # 半明确:调查后给建议
/skill:issue-ingest "我想导入些昇腾训练框架的 issue" # 不明确:引导问框架,再走半明确
```
| 用户给到什么 | agent 行为 |
|---|---|
| 完整参数(`--repo --labels ...`)| 直接执行(不打扰)|
| 半明确(框架名或仓库)| 查 `ingest-state.json` 该源有无 config → 有则复用(显示给用户,可改);无则**调查 + 建议 + 确认**(见步骤 0)|
| 不明确 | 引导问框架 → 走半明确路径 |
- `--repo`:上游仓库(必填;半明确时 agent 从框架名映射,映射不了就问)
- `--labels`:issue 池(可覆盖 config / 映射表;默认按下表)
- `--since`:增量游标(从 `ingest-state.json` 的 `last_fetch_oldest_closed` 续拉,或用户指定)
- `--min-comments`:最少评论数(默认 3,有排查过程的信号)
- `--limit`:候选上限(默认 20)
- `--mode`:`auto`(默认,批量自动评估沉淀)| `confirm`(候选列表给用户过目后再评估)
## 源配置固化(ingest-state.json 的 sources.<source>.config)
**交互中确认过的配置固化下来,同一仓库下次不再问同样的问题**——与 case/先验沉淀同一哲学。
- **生命周期**:首次导入某仓库 → 调查(label 体系/规模)→ 给建议 → 用户确认 → **写入 `config`**(labels / min_comments / limit / strategy 说明);再次导入同仓库 → 读 `config` 直接执行(显示配置,用户可改);用户改参数 → 覆盖 `config`
- **config 位置**:`ingest-state.json` → `sources.<source>.config`(与 processed/游标同处)
- **更新**:仓库 label 体系演进或策略变化 → 用户主动改参数时覆盖;无需显式清理
## 框架 label 映射(初始猜测;半明确路径先查 config,无 config 再调查确认)
| 框架 | 主池 | 说明 |
|---|---|---|
| vllm-ascend | `triaged` | 维护者确认过,信噪比最高;不够再扩 `bug` |
| vllm(上游)| `bug` | 无 triaged 体系时用 bug |
| 其他框架 | 调查后确认 | 先 `gh api repos/<repo>/labels` 看实际 label 体系再定,**不猜** |
## 流程
### 0. 配置(仅半明确/不明确路径;有 config 或无参数冲突时跳过)
```bash
# 查实际 label 体系(零 token)
gh api repos/<repo>/labels --jq '.[].name'
# 数候选池规模(可选,按 label 逐个数)
gh api "search/issues?q=repo:<repo>+is:issue+is:closed+label:<候选label>&per_page=1" --jq '.total_count'
```
给用户建议(主池 label、min_comments、limit、预计候选数),用户确认或调整 → **写入 `config`**;用户给了完整参数 → 跳过本步,直接执行(并把参数记入 config 供下次复用)。
```bash
python3 scripts/fetch_issues.py --repo <repo> --state closed --labels <labels> \
[--since <游标>] --output /tmp/issues-<repo>.json
```
只拉元数据(不含 body)。输出重定向文件,不进 context。
### 2. 硬过滤 + 启发式排序(0 token)
```bash
python3 scripts/issue_filter.py --cached /tmp/issues-<repo>.json \
--state ingest-state.json --source "github/<repo>" \
[--labels <labels>] [--min-comments 3] [--limit 20] [--report /tmp/candidates.json]
```
已处理编号排除(幂等)、label 池、评论数、标题规则;候选按 label 优先级(triaged>bug)/ 已解决 / 评论数排序。读候选列表。
**增量缓存同样走本步统一过滤**——`--since` 拉出的新缓存也过 `issue_filter.py`(标题规则/评论数/已处理排除都要应用),**勿直接读增量文件跳过过滤**(增量里的 `[Doc]`/`[Feature]` 等标题规则条目会被滤掉,直接读会混进评估)。
### 3. 评估(~1-2K token/条,只花在候选上)
对候选逐条:`gh api repos/<repo>/issues/<n>` 取 **body + 评论**(issue 的 body 多为环境信息+现象,**根因和 fix 通常沉淀在评论里**——至少读最后 2-3 条评论,结论常在尾部;body 只读现象段落),判断:
- **可否沉淀**:症状→根因→fix 是否闭环(根因有定论、fix 有方向即可,不必等社区验证)、是否昇腾相关、是否与现有 case 重复(对照 `knowledge/` 与 `postmortems/`);
- 评论数多的不等于可沉淀(可能多问题未定论)——以"根因是否定论 + fix 是否明确"为判据,不只看评论热度;
+ - **fix 指向 PR 时,核对那个 PR 是否真的动了所述代码位**(零 token:`gh pr view <n> --json title,files`;要对齐到行就 `gh api repos/<repo>/pulls/<n>/files` 看 patch)。关单评论里的"#NNNNN fix it"**不等于**该 PR 就是所述修复——先例:VLLM-ASC-12957 被记成"PR #14269 加了流同步",而该 PR 实为删除 `batch_matmul_transpose` 算子,照 case 给用户的"升级到含 #14269 的版本"是**空路**。核对不上就写成待确认(草案 `fix_type: pending-investigation` + 注明"上游自述 PR 与所述修复不符"),不要记成既定修复;
+ - **版本号认准维度**:issue 里的 `VLLM_VERSION` 是 **vLLM** 的版本,镜像 tag(如 `quay.io/ascend/vllm-ascend:glm5.2-a3`)也不是 vllm-ascend 的版本号。写 `compat.ranges` 必须用 vllm-ascend 自身版本(`pip show vllm-ascend` 级别的事实);取不到就留空或标注待补,**不要拿 vLLM 版本凑**——先例:VLLM-ASC-12461 的版本范围一度按现场的 `VLLM_VERSION=0.21.0` 误判;
- 不可沉淀(feature/讨论/无结论)→ 跳过,但记录到 `ingest-state.json` 的 `processed`(`--mark-imported` 一并标记,防反复评估)。
`--mode confirm`:先展示候选列表(编号/标题/评论数)给用户确认取舍,再评估。
### 4. 沉淀 + 同步 pre-triage(~3-5K token/条,产资产)
评估通过的 → 走 `/skill:to-postmortem` 逐条提炼(症状/根因/fix/命名空间建议),产出 case 草稿 + postmortem 进 `postmortems/inbox/`。批量时逐条执行,不合并多 issue 为一条 case。
**产出时同步 pre-triage**(省去提交时重复判断):用 `knowledge/_index.yaml` 按 symptoms/tags 定位现有 case 候选,全量读比对 root_cause 与 fix,给 `new_pattern` / `variant_of:<case-id>` / `covered_by:<case-id>` + 证据(简要),写入 draft 头注释(如 `# pre-triage: variant_of VLLM-ASC-XXXX(同算子×同网络,增量=维护者确认升级修复)`)。groom 复核该标签而非重判。
### 5. 标记已导入(幂等闭环)
```bash
python3 scripts/issue_filter.py --state ingest-state.json \
--source "github/<repo>" --mark-imported <n1,n2,...>
```
把本次处理过的编号(含评估跳过与已沉淀)追加 `processed`——下次拉取不重导。评估跳过的不反复评估。
### 6. 报告落点
```
拉取 N 条 → 候选 M 条 → 评估通过 K 条 → 沉淀 case 草稿 K 条 → postmortems/inbox/(待审)
已标记 J 条编号(含跳过)→ ingest-state.json(幂等)
转正:维护者批量审 inbox(/skill:knowledge-groom)
```
### 7. 收尾 evolve-check(伴随演进评估,默认执行)
**先落执行记录**(evolve-check 读它作现场,不靠 agent 记忆):
`python3 scripts/log_skill_exec.py --skill issue-ingest --products "<本轮产出 case id(submitted),...>" --reason "<一句话:拉取 N/评估 K/沉淀 M>" --source issue-ingest --tokens <估算>`
沉淀完成、出最终报告前,执行一次伴随演进评估(`read skills/evolve-check/SKILL.md`
遵循):本轮沉淀出 ≥3 条同根因/同族 case(T1 → 归纳 reference 候选)、发现新 issue
类型/新错误码无覆盖(T5)、或拉取/评估环节有重复手动动作或流程摩擦(T3/T4)时,
**agent 自动产 idea 卡并自行验证执行**(ev_proposal 产卡 → golden/S2 验证 → 进攒批);
无信号则报告加一行"evolve-check:无演进信号"。这是流程默认收尾,**不需要用户另说
"改进系统"**——演进由数据触发,像人学习。产出与流程报告一并给出。
## 与既有 skill 的关系
- **to-postmortem**:issue 提炼复用其沉淀逻辑(本 skill 只做"外部源的预过滤与编排",不重复提炼);
- **knowledge-groom**:inbox 批量审、转正、索引重建在 groom 轮;
- **诊断**(diagnose):沉淀的 case 转正后进入 Tier 2,下次诊断命中。
## 幂等与可重复
- `ingest-state.json`:`processed`(已处理编号,硬排除)+ `last_fetch_*_closed`(游标)+ `config`(用户确认过的源配置)——重复运行不重导、不重评估、不重问配置;
- 拉取无状态、过滤纯本地——管道可重复执行,结果稳定。
## 为什么需要专门入口
工程师不会为了"把 issue 翻一遍"写 postmortem;但上游 issue 里躺着大量已验证的排障知识(triaged = 维护者确认过)。专门的批量入口把门槛降到一条命令:拉取、过滤、评估、沉淀全自动,人只审转正。