新增 scripts/http_utils.py 统一封装 HTTP 请求的限流重试(429/5xx 指数退避, 优先遵守服务端 Retry-After),search_arxiv/crossref/semantic_scholar.py 和 verify_citation.py 都已接入,不再各自裸调 urllib。 新增 scripts/search_openalex.py 作为第四个检索源:免费、无需 API key,覆盖面 比单独的 Crossref 更广,还能拿到开放获取PDF直链;已接入 literature_search.py 的主检索流程。verify_citation.py 的跨源标题核查同步改为同时查 Semantic Scholar 和 OpenAlex 两个独立源、任一命中相似度达标即通过,不再单点依赖 S2—— 这是针对"S2 被限流导致整批候选退化成 unverified"这个实际发生过的问题的直接 修复,已用真实网络请求验证:复测中 S2 确实当场返回了 429,靠 OpenAlex 兜底 最终判定仍然是 verified。 顺带修了 archive_references.py 的 slugify(),之前中文主题名会被正则全部 过滤掉、退化成通用的 "references",导致不同中文主题的归档目录互相冲突。 scripts/tests/ 下补了 37 个 unittest(全部 mock 网络请求,不发真实请求), 覆盖 verify_citation 的三档判定和双源核查合并逻辑、archive_references 的 bib 解析边界情况(嵌套花括号、中文主题名)、literature_search 的候选去重 合并与 BibTeX 生成、http_utils 的重试逻辑。用标准库 unittest 而不是 pytest, 和这些脚本本身不引入第三方依赖的原则保持一致。 CLAUDE.md 的下一步计划里,这一项已标记为完成。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
5.3 KiB
5.3 KiB
autoPaper — 科研辅助 Claude Skill 库
本仓库不是一篇具体论文的工作区,而是一套持续维护的 Claude Code skill 库,
服务于科研工作流(文献检索 → 核实 → 归档 → 写作)。references/ 下按主题
归档的文献是这套 skill 实际产出的样例/沉淀,不是本仓库的主体。
目录结构
.claude/skills/ 所有 skill 的定义,每个子目录一个 skill,只放代码/说明
literature-search-verify/ 检索 + 反幻觉引用核查
SKILL.md skill 说明(frontmatter name 必须与目录名一致)
scripts/ 纯标准库 Python 脚本,无第三方依赖(含 http_utils.py 统一限流重试)
tests/ unittest 单测,全部mock网络请求,不发真实请求
paper-writing-grounded/ 论文写作(强制数据溯源)
SKILL.md
git-commit/ 规范化 commit message 生成与提交
SKILL.md
output/<skill-name>/<topic-slug>/ 各 skill 运行时的草稿区,.gitignore 掉,不进版本库;
按 skill 分子目录、同一 skill 内再按主题分子目录
(topic-slug 规则和 references/ 下的目录名一致),
避免不同 skill、不同主题的草稿互相覆盖/混堆
references/<topic-slug>/ literature-search-verify 归档产出的稳定文献库
references.bib 已验证文献,写作阶段 \cite{} 直接复用这里的 key
README.md 人可读索引,含 suspect/unverified 条目说明
pdfs/ 开放获取的原文 PDF(如有)
核心设计原则(新增/修改 skill 时必须保持)
- 反幻觉是硬约束,不是建议:任何进入正文引用或数字的内容都必须能独立核实
或追溯到真实数据,验证不通过就必须显式标记(
suspect/unverified/[需要数据: ...]),绝不能为了让输出"看起来完整"而悄悄丢弃或蒙混过关。 - 脚本优先于临场编 API 调用:能写成
scripts/里可重复运行的脚本就不要 指望模型每次现场拼 HTTP 请求——后者不可复现、容易在细节上出错。脚本只用 标准库,不引入第三方依赖,保证任何环境下拿来就能跑。 - 草稿区与交付物分离:草稿(项目根目录下的
output/<skill-name>/<topic-slug>/) 只是运行痕迹,不是可信的最终产物,也不放在.claude/skills/里面(那里只放 skill 代码本身);确认稳定后要显式归档到references/<slug>/这类项目级 目录,才算数。同一 skill 下不同主题的草稿必须分子目录,不能用无区分度的 通用文件名(如t1.json)散落在同一层——这类命名冲突曾经真实发生过。 - skill 之间通过约定(如 bibtex key)解耦协作,而不是互相读对方内部状态; 每个 SKILL.md 末尾应有一节说明它和其他 skill 的配合方式。
- 目录名必须和 SKILL.md frontmatter 里的
name:完全一致——skill 发现/ 调用是按目录名走的,两者不一致会导致"文档里写的名字"和"实际能唤起的名字" 对不上(曾经出现过paper-wiriting-grounded目录名手滑打错、和 frontmatter 里正确拼写的paper-writing-grounded不一致的问题,已修正)。
已知薄弱环节 / 待办方向
- 目前只覆盖"检索/核实"与"写作/溯源"两段,引用一致性核查(定稿里的
\cite{}是否都对得上references.bib、有没有归档了却从未引用的条目) 还没有对应 skill。 search_openalex.py目前只用了 OpenAlex Works API 里比较基础的字段 (标题/作者/年份/venue/DOI/引用数/开放获取PDF),没有用它的 concept/topic 分类字段做更细的学科过滤——如果以后要精确限定学科方向,这是可以深挖的点。
下一步计划
给核心脚本补单测 + 给网络请求加限流重试已完成:新增scripts/http_utils.py统一封装限流重试(429/5xx指数退避,遵守Retry-After),search_arxiv/crossref/semantic_scholar/openalex.py和verify_citation.py都已接入;verify_citation.py的跨源标题核查改成 同时查 Semantic Scholar + OpenAlex 两个独立源(任一命中即通过),不再 单点依赖 S2;新增search_openalex.py作为第四个检索源;archive_references.py的slugify()修了中文主题名被折叠成通用"references"名的问题;scripts/tests/下补了 37 个 unittest 单测(全部mock,不发真实请求), 覆盖上述所有改动。- 新增"引用一致性核查" skill:检查定稿里所有
\cite{}的 key 是否都能在 对应主题的references/<slug>/references.bib里找到,以及有没有已归档 但从未被正文引用的"僵尸条目",在 literature-search-verify 和 paper-writing-grounded 之间补上这个校验环节。
新增 skill 时的约定
- SKILL.md 的 frontmatter
description要写清楚"什么场景下必须触发这个 skill",因为这是 skill 被自动选中的唯一依据。 - 正文按"为什么需要 / 工作流程 / 和其他 skill 的配合"组织,和现有两个 skill 保持同样的结构和颗粒度。
- 目录名 = frontmatter
name,不要有拼写差异。