当前Pull Request已关闭, 关闭人@rui
Thanks for your pull-request.
The full list of commands accepted by me can be found at here。
You can get sig-info at here
PR Approval Progress
⚠️ This PR does not yet meet the following requirements:lgtm (requires ≥ 2 person(s) per module)、approve (requires ≥ 1 person(s) per module)
Module Approval Details
| module | lgtm status | approve status |
|---|---|---|
| docs | ❌ (0/2)(You can also ask: Reyn52166, 张子菁, 卢煜坤, 侯延保, 王涛) | ❌ (0/1)(You can also ask: 卢煜坤, 侯延保, 王涛, 张子菁) |
| repo-cann/runtime | ❌ (0/2)(You can also ask: 卢煜坤, 侯延保, 张子菁, zhangpengpeng8, yanmingxiang) | ❌ (0/1)(You can also ask: 张子菁, zhangpengpeng8, yanmingxiang, 侯延保, 卢煜坤) |
💡 Tip:
- Committer can comment
/approveor/lgtm- Commenting
/approveimplies both code review (lgtm) and intent to merge (approve)
CLA Signature Pass
good_luck_to_me, thanks for your pull request. All authors of the commits have signed the CLA. 👍


变更摘要
本次 PR 新增 issue-response-eval 评测 skill,用于对 issue-response skill 进行系统性基准评测和迭代驱动。核心交付包括:20 条分层抽样的基准数据集(benchmark.jsonl)、4 个自动化脚本(run_benchmark.sh、regress.sh、triage_open.sh、score.py)、以及打分摘要与执行日志数据结构。评分体系由 R1-R6 六项规则检查(分类一致性、链接可达性、错误码正确性、检查点覆盖、不重复回复、源码验证结论)与 LLM 三维裁判(技术准确性、可执行性、采纳适宜度)组成,综合分按规则分 60% + LLM 分 40% 计算,通过线 0.85。
主要改动
-
基准数据集
benchmark.jsonl:新增 20 条分层抽样基准记录,涵盖 L0/doc-faq(6 条)、L1/error-code-log(4 条)、L1/hw-concept(2 条)、L1/build-sample(4 条)、L2/framework-integration(1 条)、L2/code-audit(2 条)、L2/complex-analysis(1 条),每条包含expected_level、expected_subtype、ground_truth_reply_summary、expected_checkpoints等字段用于对比评测。 -
基准运行脚本
run_benchmark.sh:遍历全部 20 条基准数据,为每条 issue 调用 subagent 执行issue-response全流程生成草稿,支持超时控制(600 秒)与版本化管理(benchmark_v{N}.json),并提取执行日志中的分类结果写入run_log.json。 -
打分器
score.py:实现 R1-R6 六项规则检查函数,其中 R2 通过git show origin/master:path验证草稿中引用的文档链接是否可达,R4 通过关键词匹配检查期望检查点的覆盖度,R5 检测是否简单复制维护者回复。LLM 裁判生成结构化 prompt 后由外部 LLM 执行。最终输出scores.jsonl和score_summary.json,当前初始状态所有条目均为 0 分。 -
实时分流脚本
triage_open.sh:通过 GitCode API 拉取assignee=null且标题含[Question或[Documentation的 open issue,调用 subagent 生成草稿后人工交互录入 adopt/revise/reject 决策,决策记录写入live_decisions.jsonl,并统计采纳率。 -
回归验证脚本
regress.sh:支持按逗号分隔的 issue 编号列表重跑指定条目的草稿生成,从benchmark.jsonl查找期望分类,执行完毕后提示运行score.py查看结果,形成「失败用例 → 修改 skill → regress.sh 重跑 → 全量回归」的迭代闭环。


代码审查
审查总结
已完成对所有 22 个变更文件的逐一审查。结果如下:
| 优先级 | 数量 | 说明 |
|---|---|---|
| P2 | 2 | 评分逻辑缺陷(R3 子类型遗漏、LLM 公式缺 ÷3) |
| P3 | 4 | 可移植性、安全、代码整洁问题 |
| 总计 | 6 |
各文件审查结果
.claude/skills/issue-response-eval/DEV_PROCESS.md— 无问题.claude/skills/issue-response-eval/SKILL.md— 无问题.claude/skills/issue-response-eval/evals/.gitkeep— 无问题.claude/skills/issue-response-eval/evals/benchmark.jsonl— 无问题(20 条有效 JSONL).claude/skills/issue-response-eval/evals/live_decisions.jsonl— 无问题.claude/skills/issue-response-eval/references/.gitkeep— 无问题.claude/skills/issue-response-eval/references/benchmark-sampling.md— 无问题.claude/skills/issue-response-eval/references/scoring-rubric.md— 无问题.claude/skills/issue-response-eval/reports/drafts/.gitkeep— 无问题.claude/skills/issue-response-eval/reports/run_log.json— 无问题.claude/skills/issue-response-eval/reports/score_summary.json— 无问题(空跑占位数据).claude/skills/issue-response-eval/reports/scores.jsonl— 无问题(空跑占位数据).claude/skills/issue-response-eval/scripts/.gitkeep— 无问题.claude/skills/issue-response-eval/scripts/regress.sh— 无问题.claude/skills/issue-response-eval/scripts/run_benchmark.sh— 1 个 P3 发现(GNU 专有grep -oP).claude/skills/issue-response-eval/scripts/score.py— 3 个发现(P2×2: R3 子类型遗漏 + LLM 公式缺 ÷3;P3×1: 未使用 import).claude/skills/issue-response-eval/scripts/triage_open.sh— 2 个 P3 发现(API token URL 暴露 + grep 计数重复输出).superpowers/sdd/progress.md— 无问题docs/superpowers/plans/2026-07-06-issue-response-eval.md— 无问题docs/superpowers/specs/2026-07-06-issue-response-eval-design.md— 无问题issue-classification-review.md— 无问题issue-review-with-bodies.md— 无问题
整体风险评估:低到中等
核心逻辑路径(score.py 的 R3 和 LLM 公式)存在两个需要修复的 P2 缺陷,但当前它们处于休眠状态——R3 的影响需要实际草稿数据才能触发,LLM 公式的 bug 需要接入 LLM 裁判(当前为 TODO)才会显现。其余 P3 问题不影响核心评测逻辑的正确运行。建议在接入 subagent 和 LLM 裁判之前优先修复 score.py 中的两个 P2 问题。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 0 |
| 🟡 建议 | 8 |
💬 仅评论


🟡 Medium Priority
regress.sh 第33-39行将用户传入的 $num(来自 $1 参数,仅经过 tr -d ' ' 去空格)直接内插到 bash -c "..." 双引号字符串中。由于 $num 未做任何 shell 元字符转义,攻击者可以传入包含单引号的内容(如 1';id;#)提前闭合内层 echo 的单引号字符串,执行任意命令。
触发条件:开发者或调用方传入含 shell 元字符的 issue 编号,如 bash regress.sh "1';malicious_cmd;#" 。tr -d ' ' 只删除空格,';&|$() 等均保留。
虽然该脚本是开发者工具、攻击面有限,但按 Shell 审查规则,外部输入拼接进命令属于应报告的命令注入。
建议:先对 $num 做严格校验,仅允许纯数字;或将 $num 通过环境变量传入内层 bash,避免直接拼接。推荐方案:在 for 循环开头增加 [[ "$num" =~ ^[0-9]+$ ]] || { echo "ERROR: 无效issue编号: $num"; exit 1; } 校验,确保 $num 仅含数字后再使用。


🟡 Medium Priority
计划文档 Task 3 (run_benchmark.sh) 的第 351 行使用正则表达式从 subagent 输出中提取 exec_log JSON:
match = re.search(r'{[^{}]"classified_level"[^{}]}', content, re.DOTALL)
受影响行为:字符类 [^{}] 排除了花括号,因此该正则无法匹配含嵌套对象的 JSON。而 exec_log 的设计格式本身包含嵌套对象(source_verification 是一个含 claim/result 的子对象,links_checked 是含 url/valid 的对象数组),正则会在遇到第一个内层 { 或 } 时停止匹配,导致 JSON 提取失败。
失败模式:subagent 正确输出完整 exec_log 后,score.py 因正则匹配失败,fallback 到 classified_level=UNKNOWN 的默认值,造成 R1(分类一致性)规则全部误判为 FAIL。
触发条件:subagent 实际接入并输出符合设计格式(含嵌套 source_verification 和 links_checked)的 exec_log 时必然触发。
证据:当前 score_summary.json 中 20 条记录全部显示 classified=UNKNOWN,与正则无法提取嵌套 JSON 一致。
建议:改用能匹配嵌套 JSON 的提取策略。方案一:先定位 "classified_level" 的位置,然后手动配对花括号来提取完整 JSON 块。方案二:要求 subagent 输出时用特殊标记(如 <<<EXEC_LOG_START>>> / <<<EXEC_LOG_END>>>)包裹 JSON,脚本按标记行截取后再用 json.loads() 解析。方案二更可靠。


🟡 Medium Priority
计划文档 Task 4 score.py 的 main() 函数第 789 行调用 llm_judge 时,第一个参数 issue_text 硬编码为空字符串 "":
llm_prompt = llm_judge("", draft or "", item.get("ground_truth_reply_summary", ""))
受影响行为:llm_judge 函数用该参数生成 LLM 裁判 prompt 的 ## Issue 原文 段落(第 712 行 {issue_text[:1000]}),空字符串导致 prompt 中 issue 原文完全缺失。LLM 裁判无法看到原始 issue 内容,只能基于草稿和 ground truth 摘要打分,失去了"对比 issue 原文评估草稿是否准确回应"的核心评判能力。
失败模式:LLM 裁判的 accuracy(技术准确性)和 actionability(可执行性)维度评分失去关键上下文,裁判质量严重下降。
证据:score_summary.json 中所有 20 条记录的 llm_prompt 字段均显示 ## Issue 原文\n\n\n## AI 生成草稿——issue 原文段落为空,直接跳到了下一个章节。
注意:benchmark.jsonl 中每条记录不包含 issue 正文(只有摘要),因此需要从 GitCode API 或本地缓存获取 issue 正文,或至少在 benchmark 记录中增加 issue_text 字段。
建议:需要在 benchmark.jsonl 中增加 issue_text 字段(存储 issue 正文),或从 GitCode API 拉取 issue 正文后传入 llm_judge。对应的 main() 调用改为类似 llm_judge(item.get("issue_text", ""), draft or "", ...) 的形式。


🟡 Medium Priority
第19行 curl -s "https://api.gitcode.com/api/v5/repos/cann/runtime/issues?state=open&per_page=50&access_[REDACTED] 将 $GITCODE_API_TOKEN` 直接拼接在 URL query string 中。
风险:
- token 可能被中间代理/网关日志记录(URL 通常被记录)
- token 出现在进程命令行参数中,
ps aux可被同机其他用户看到 - shell history 会记录完整 URL 含 token
虽然这是开发者工具而非生产服务,但 token 泄露风险真实存在。应使用 HTTP Header(如 Authorization: Bearer 或 PRIVATE-TOKEN)传递,避免 token 进入 URL。
建议:改用 HTTP Header 传递 token:curl -s -H "Authorization: Bearer $GITCODE_API_TOKEN" "https://api.gitcode.com/..." 。如果 GitCode API v5 不支持 [REDACTED],至少应使用 `curl -s -H "PRIVATE-[REDACTED] 等 header 方式,避免 token 出现在 URL 中。


🟡 Medium Priority
calculate_score() 函数(第 178 行)计算 LLM 均分时:
这里 sum(s.values()) 对每个 run 的 3 个维度(accuracy/actionability/adoptability,各 0-2 分)求和得到 0-6 的值,然后除以 run 次数。但设计规范(scoring-rubric.md 第 42 行)要求的是 "LLM 三维均分/2"——即先对每个 run 求三维均值(÷3),再跨 run 求平均,最后 ÷2 归一化。
以满分(两个 run 均为 {2,2,2})为例:
差距达 3 倍。一旦 LLM 裁判自动化(DEV_PROCESS.md 第 147 行的 TODO)接入,总分将被严重扭曲——规则分最高贡献 0.6,LLM 分最高贡献 1.2,LLM 分将主导评分。当前因 main() 中传 llm_scores=None 未触发此路径。
建议:修改为:先对每个 run 的三维度求均值再跨 run 平均,即 avg_llm = sum(sum(s.values()) / 3 for s in llm_scores) / len(llm_scores)
|
179 | + avg_llm = sum(sum(s.values()) / 3 for s in llm_scores) / len(llm_scores) |
| 179
180 | llm_score = (avg_llm / 2) |


🟡 Medium Priority
计划文档 Task 7 (triage_open.sh) 的第 1036 行将 $GITCODE_API_TOKEN 拼接在 curl 的 URL query string 中:
ISSUES_JSON=$(curl -s "https://api.gitcode.com/api/v5/repos/cann/runtime/issues?state=open&per_page=50&access_[REDACTED] 2>/dev/null)
受影响行为:API token 出现在 URL 中,会被以下途径泄漏:
- 中间代理/网关的访问日志会记录完整 URL
ps aux进程列表中可看到完整命令行(含 token)- 若服务端发生 301/302 重定向,token 可能出现在 Referer 头中
触发条件:用户按文档执行 export GITCODE_API_[REDACTED] bash scripts/triage_open.sh 时必然触发。
建议:将 API token 从 URL query string 移至 HTTP Authorization header,避免 token 在代理日志和进程列表中泄漏。


🟡 Medium Priority
check_r3_error_code() 函数(第 86 行)仅通过检查 expected_checkpoints 中是否出现 "错误码"、"error"、"107002"、"507" 关键词来判断该 issue 是否涉及错误码。但 4 条 expected_subtype == "error-code-log" 的基准项(bm-007~bm-010)的 checkpoints 中均不含这些关键词:
因此这 4 条全部被判定为 error_related=False,R3 直接返回 PASS 而不检查草稿中是否引用了错误码。这导致 R3 规则对其核心目标子类型完全失效。
触发条件:任何 benchmark item 的 expected_subtype 为 "error-code-log" 但 expected_checkpoints 中不含关键词 "错误码"/"error"/"107002"/"507" 时触发。
修复方向:在 error_related 判断中增加对 benchmark_item.get("expected_subtype") == "error-code-log" 的检查。
建议:在 error_related 判断中增加 subtype 检查:error_related = benchmark_item.get("expected_subtype") == "error-code-log" or any(...)
| 86
| - error_related = any("错误码" in cp or "error" in cp.lower() or "107002" in cp or "507" in cp for cp in checkpoints) |
|
86 | + error_related = benchmark_item.get("expected_subtype") == "error-code-log" or any("错误码" in cp or "error" in cp.lower() or "107002" in cp or "507" in cp for cp in checkpoints) |


🟡 Medium Priority
calculate_score() 第177-179行计算 LLM 裁判分时:
该公式将所有维度的原始分直接求和再除以运行次数(而非总维度数),导致分子缺少对每轮 3 个维度的平均。
设计公式:「LLM 三维均分 = 每轮 (accuracy+actionability+adoptability)/3,两轮取均值,再 /2 归一化」。
设 2 轮 × 3 维 = 6 个值,正确计算应为 sum(6个值) / 6 / 2 = sum / 12,当前代码计算为 sum(6个值) / 2 / 2 = sum / 4。
高估倍数:12/4 = 3 倍(LLM 维度);反映到综合分上 LLM 贡献被高估 50%(因为还有 ×0.4 系数)。
例如规则分 0.6 + LLM 全满分时,正确综合分 = 0.36 + 0.4 = 0.76,当前代码 = 0.36 + 0.6 = 0.96,导致未达标用例错误通过 0.85 阈值。
当前 main() 中传入 llm_scores=None 所以尚未触发,但 LLM 自动打分启用后将立即出错。
建议:将分母从 len(llm_scores)(运行次数)改为 sum(len(s) for s in llm_scores)(总维度数),使 avg_llm 正确表示所有维度分的均值。
|
179 | + if llm_scores and len(llm_scores) > 0: |
|
180 | + total_dims = sum(len(s) for s in llm_scores) |
|
181 | + avg_llm = sum(sum(s.values()) for s in llm_scores) / total_dims |
| 179
182 | llm_score = (avg_llm / 2) |


描述
新增
issue-response-evalskill,对 PR #2551 的issue-responseskill 进行系统性评测和迭代驱动。核心能力
交付物
.claude/skills/issue-response-eval/完整 skill(SKILL.md + 4 脚本 + 2 参考文档 + 20 条基准数据集)docs/superpowers/specs/设计 spec(9 章节)docs/superpowers/plans/实现计划(8 个 Task)DEV_PROCESS.md完整开发过程记录issue-classification-review.md全量 631 条 issue 分类审阅表issue-review-with-bodies.md85 条待确认 issue 含正文摘要 + 用户标注基准数据集
从仓库 631 条 issue 中筛选 53 条外部社区 issue,分层抽样 20 条:
打分器
变更类型
关联的Issue
关联 PR #2551(issue-response skill)
如何测试
cd .claude/skills/issue-response-evalecho '{"version":1,"timestamp":"test","results":[]}' > reports/run_log.jsonpython3 scripts/score.py— 验证空跑 20 条不崩溃bash scripts/run_benchmark.sh— 跑基准(需接入 subagent)bash -n scripts/*.sh— 脚本语法检查python3 -m py_compile scripts/score.py— Python 语法检查核对清单
其他信息