评估 GitHub 开源项目是否与用户研究方向相关,提供复现环境指南、风险提示,并存入知识库供后续参考。
# 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:抓取仓库材料
```bash
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):
```json
{
"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:查重
```bash
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:概念与资源规划
```bash
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` 后:
```bash
# 概念页
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 格式铁律**(所有字符串值加双引号;关键词用带引号的标准数组):
```markdown
---
标题: "<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`,然后:
```bash
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 = 脚本异常,告知用户并建议联系管理员。
- 评估结论务必给出三档之一并附理由,不要含糊其辞。
don't have the plugin yet? install it then click "run inline in claude" again.