Eval Repo

API key required
Other

评估 GitHub 开源项目是否与用户研究方向相关,提供复现环境指南、风险提示,并存入知识库供后续参考。

Install

openclaw skills install eval-repo

Skill: eval_repo — paper-kb 开源项目评估与入库

用途

用户在飞书发来一个 GitHub 仓库链接并表达"评估/判断"意图(如"这个项目对我课题有用吗" "帮我评估下这个开源项目""这个 repo 能不能复现 / 环境怎么配")时,本 Skill:

  1. 抓取该仓库的 README、依赖文件、元信息(语言/stars/最近提交/许可证等);
  2. 结合该用户的研究方向其知识库里已有的相关资料,做一次结构化评估 (相关性、是否值得深入、环境复现清单、风险与坑);
  3. 把评估结果作为一篇「开源项目」资料存入用户的 Gitea 知识库 (生成 summary 页、更新概念页/资源页、同步飞书表格);
  4. 在飞书回复用户:结论 + 相关性 + 环境清单要点 + Gitea 链接。

与 ingest_paper 的区别:ingest_paper 是"把资料存进来";本 Skill 是"先评估值不值, 评估结果本身就是有价值的知识,顺带存档"。评估的核心是结合用户已有知识库的判断, 而不是孤立地复述 README。

触发条件

Activate when(同时满足):

  • 消息中含 GitHub 仓库链接(github.com/owner/repo 或 owner/repo 形式);
  • 且有评估/判断意图:包含"评估""值不值""有没有用""有没有帮助""能不能复现" "环境怎么配""分析下这个项目""要不要深入"等表述。

Do NOT activate when:

  • 用户只是说"把这个项目存进知识库 / 存下来 / 记录一下",没有评估意图 → 那是 ingest_paper 的 project 入库流程,交给 ingest_paper。
  • 发的是 arxiv / 普通网页 / PDF / 文件 → 交给 ingest_paper 或 query_papers。
  • 用户在查询知识库内容 → 交给 query_papers。
  • 用户未注册(init_user check 返回 registered=false)→ 先走 init_user。
  • 只发了 GitHub 链接、没说要干嘛 → 先问一句"需要我评估这个项目对你课题的价值 并存入知识库吗?",确认后再执行。

前置依赖

  • current_user_open_id:从消息上下文 sender 获取,传给所有脚本的 --open_id。 网页测试拿不到时用 webchat_test
  • 用户必须已注册(按 workspace AGENTS.md,任何 paper-kb 请求的第一步永远是 init_user --check)。用户记录里的 research_direction 在评估时必须用上。
  • 本 Skill 根目录需有 .env(GITEA_URL / GITEA_ADMIN_TOKEN / GITEA_BOT_USERNAME; 建议再配 GITHUB_TOKEN 提高抓取限额)。

临时文件路径约定

中间文件放 /tmp/paperkb/

  • fetch_github 抓取的合并文本:/tmp/paperkb/text_<owner>_<repo>.txt(脚本自动生成并返回 text_path)
  • 你生成的草稿:/tmp/paperkb/draft_eval.md/tmp/paperkb/draft_concept_*.md

完整执行流程

Step 1:抓取仓库材料

python3 scripts/fetch_github.py --url "<GitHub 链接或 owner/repo>"

返回 JSON:full_name / url / description / language / stars / forks / open_issues / created_at / pushed_at / license / archived / topics / default_branch / dep_files_found(找到的依赖文件列表)/ has_readme / text_path(合并文本,供你阅读分析)。

  • success:false → 按 message 转告用户(仓库不存在/私有、限流等),终止。
  • 记住 text_path(后面查重、落库都要用)和 url(GitHub 原始地址,要写进 summary)。

Step 2:读材料 + 取研究方向

读 text_path 全文(README + 依赖文件 + 元信息)。取用户记录里的 research_direction (评估的相关性必须围绕它)。

Step 3:评估分析(你自己完成,这是本 Skill 的核心)

按下面的五维判断逻辑评估这个项目,最后给一个三档结论。 你是基于 README/依赖文件/元信息做"初筛分诊",不是真把代码跑起来——结论是帮用户省时间的 判断信号,不是"保证能跑"的承诺,措辞要体现这一点。

五维判断逻辑(有先后的闸门,不是简单加权):

  1. 相关性(第一道闸门):项目做的事和 research_direction 有没有交集?同一类问题? 同一族方法?模态对得上吗?它对用户的角色是工具/库、baseline、数据集、还是只是沾边? → 映射为相关性评分 1-10。若判为基本不相关,无论项目多优秀,结论直接给"暂不建议"。
  2. 可复现性 / 工程成熟度:README 有没有安装步骤和用法示例;依赖是否明确 (有没有 requirements/environment/Dockerfile,版本有没有锁定——没锁=环境地狱预警); 有没有预训练权重;有没有示例数据/quickstart;代码是否模块化。
  3. 活跃度 / 可信度:stars、最近提交时间(看 pushed_at,很久没动是危险信号)、 未关闭 issue 数、是否 archived(已归档=停止维护)、许可证是否缺失、 出身是否可信(官方/知名实验室 vs 匿名复现)。
  4. 适配成本:即插即用的库,还是要从头搭的框架,还是一次性脚本? 硬件/环境是否匹配(GPU/CUDA、特定机器人硬件、ROS 版本、绑定某仿真器如 Isaac/MuJoCo/PyBullet)?有用的部分能不能单独抽出来?
  5. 独特价值:有没有更省事的替代?它是否提供别处难拿到的东西 (特定方法/数据集/硬件设计)?结合库内已有资料判断是补充还是重复。

三档结论(每档都必须绑定到"是哪个维度决定的"理由,不要只甩分数):

  • 值得深入:相关 + 能跑 + 适配成本低/中。
  • 选择性参考:相关但可复现性差(依赖不明/已废弃/无文档)→ 读思路别强求复现; 或适配/硬件成本高 → 看时间预算。
  • 暂不建议:相关性不过关,或综合判断投入产出明显不值。

结合知识库:先看 Step 5 读到的目录,判断库里有没有相关论文/项目, 在"与库内已有资料的关系"里说明它是补充、对比基线、还是重复。库为空时如实写 "知识库暂无可关联资料"。

输出结构化 JSON(你内部使用,用于后续生成 summary):

{
  "type_key": "project",
  "title": "<简洁中文项目名/标题>",
  "title_original": "<owner/repo 或原项目名>",
  "brief": "<一句话简介,50字内>",
  "keywords": ["5-8个"],
  "relevance": {"score": <1-10>, "reason": "<结合研究方向>"},
  "verdict": "<值得深入 | 选择性参考 | 暂不建议>",
  "verdict_reason": "<一句话,绑定到决定性维度>",
  "env": {
    "deps": "<检测到的依赖文件与关键依赖;没有则写'未声明依赖文件'>",
    "python_or_runtime": "<能推断的 Python/CUDA/框架版本,推断不出留空>",
    "risks": "<版本未锁/无依赖文件/特定硬件或仿真器/已归档 等复现风险>",
    "setup_steps": "<给用户的建议复现步骤,3-6 步>"
  },
  "concepts": ["<抽象概念,如 模仿学习>"],
  "resources": [{"name": "<项目名>", "type": "开源项目", "note": "<评价>"}]
}

Step 4:查重

python3 scripts/check_duplicate.py --open_id <open_id> \
    --title "<title>" --text_path "<Step1 的 text_path>"
  • duplicate:true / possible_duplicate:true → 告知已有《existing.title》,问是否覆盖更新; 确认后从 Step 5 继续,save 时加 --force;否则终止。
  • 否则继续。

Step 5:概念与资源规划

python3 scripts/kb_read.py --open_id <open_id> --list all

据 Step 3 的 concepts/resources 与已有目录,决定每项 create/update/skip:

  • 知识库文档 ≤ 3 篇时,每篇最多新建 2-3 个概念页,宁缺毋滥;同名/含义重叠的一律 update。
  • 本项目本身作为一条「开源项目」资源登记到 resources/(资源页已有则 update)。
  • 不为"项目本身的名字"再建概念页(概念页只给抽象方法/思想)。

Step 6:生成并保存概念页 / 资源页

create 项写草稿到 /tmp/paperkb/draft_concept_<名>.md / draft_resource_<名>.md 后:

# 概念页
python3 scripts/save_page.py --open_id <open_id> --kind concept \
    --name "<概念名>" --file "<草稿路径>" --brief "<一句话定义>"
# 资源页(本开源项目)
python3 scripts/save_page.py --open_id <open_id> --kind resource \
    --name "<项目名>" --file "<草稿路径>" --brief "<一句话简介>" --resource_type 开源项目

update 项先 kb_read.py --read "concepts/<名>" 读旧内容,把新信息融合改写进全文 (非追加)再同名保存。

【wikilink 格式铁律,所有页面通用】 所有 [[...]] 双链只写文件名本身,绝不带目录前缀

  • 对 → [[模仿学习]][[ManiSkill]]
  • 错 → [[concepts/模仿学习]][[resources/ManiSkill]](带前缀会让 Gitea 拼出重复路径 404)
  • 链接目标必须是确实存在的页面;标题尽量唯一。

Step 7:生成最终版 summary 并保存(作为「开源项目」入库)

白名单 = 本次 create/update 的页面 + kb_read 列出的已有页面。[[wikilink]] 只能指向白名单内页面。

summary 页结构(frontmatter 统一 + 正文为评估内容):

YAML frontmatter 格式铁律(所有字符串值加双引号;关键词用带引号的标准数组):

---
标题: "<title>"
原文标题: "<title_original>"
类型: "开源项目"
来源: "GitHub"
项目地址: "<fetch_github 返回的 url>"
关键词: ["关键词1", "关键词2", "关键词3"]
相关性评分: "<relevance.score,1-10>"
存入时间: "<今天 yyyy-MM-dd>"
---

# <title>

## 一句话总结
<brief> | 🔗 项目地址:<url>

## 结论:<verdict>
<verdict_reason>(说明:此结论基于 README/依赖/元信息的初筛分诊,非实际运行验证)

## 项目用途
<...>

## 技术栈与活跃度
主语言 <language>|Stars <stars>|最近提交 <pushed_at>|许可证 <license>|
是否已归档 <archived>。<对活跃度/可信度的一句判断>

## 核心方法与功能
<...>

## 与我研究方向的相关性
评分 <score>/10。<reason,结合 research_direction>

## 与库内已有资料的关系
<它是补充/对比基线/重复;库为空则写"知识库暂无可关联资料">

## 环境复现清单
- 依赖:<env.deps>
- 运行环境:<env.python_or_runtime>
- 复现风险:<env.risks>
- 建议步骤:<env.setup_steps>

## 风险与坑
<...>

## 关键概念
[[概念名]](只写文件名、仅白名单内;无则省略本节)

## 科研资源
[[项目名]](只写文件名、仅白名单内;无则省略本节)

写入 /tmp/paperkb/draft_eval.md,然后:

python3 scripts/save_paper.py --open_id <open_id> \
    --type_key project \
    --title "<title>" \
    --summary_file /tmp/paperkb/draft_eval.md \
    --keywords "<逗号分隔>" \
    --score <relevance.score,1-10> \
    --brief "<brief>" \
    --text_path "<Step1 的 text_path>" \
    [--force]

(开源项目无 PDF、无 arxiv_id,故不传 --pdf_path / --arxiv_id。) 输出含 summary_url / repo_url。

Step 8:同步飞书多维表格(可选,失败不阻塞)

用户记录里 feishu_app_token 和 feishu_table_id 非空时,调 feishu_bitable_app_table_record(action: create)。字段格式严格遵守(之前踩过坑):

  • 文本字段(标题/类型/关键词/arxiv_id)→ 字符串。arxiv_id 传空串 ""。
  • 数字字段(相关性评分)→ 纯数字不加引号,如 7
  • 日期字段(存入时间)→ 毫秒时间戳(纯数字)int(time.mktime(time.strptime("今天日期","%Y-%m-%d")))*1000
  • 超链接字段(Gitea链接)→ "显示文本|URL" 竖线分隔字符串,不是对象。 例:"<title>|<summary_url>"
fields: {
  "标题": "<title>", "类型": "开源项目", "关键词": "<逗号分隔>",
  "相关性评分": <纯数字 1-10>, "存入时间": <今天毫秒时间戳>,
  "Gitea链接": "<title>|<summary_url>", "arxiv_id": ""
}

失败最多重试 1 次,仍失败则跳过,回复中注明"飞书表格同步失败,不影响知识库"。

Step 9:回复用户

✅ 已评估并存入知识库!

📦 <title>(<language>|⭐<stars>|最近提交 <pushed_at>)
🔗 项目地址:<url>
🎯 结论:<verdict> — <verdict_reason 精简一句>
⭐ 与你研究方向的相关性:<score>/10 — <reason 精简一句>
🛠 环境提示:<env.risks 或"依赖清晰,可按 README 复现",一句>
🧠 概念页:<新建X/更新Y,列名字;无则省略>
🛠 资源页:<同上;无则省略>
📄 查看完整评估:<summary_url>

覆盖模式开头改"✅ 已重新评估并覆盖更新!"。飞书跳过/失败时追加一句说明。

错误处理总则

  • 脚本输出单行 JSON;success:false 时按 message 转告用户,不堆原始报错。
  • fetch_github 限流(rate limit)→ 提示在 .env 配置 GITHUB_TOKEN 后重试。
  • 仓库不存在 / 私有 → 如实告知,本版本只支持公开仓库。
  • stdout 非 JSON = 脚本异常,告知用户并建议联系管理员。
  • 评估结论务必给出三档之一并附理由,不要含糊其辞。