Skip to content

AI 开源项目 README 离线分析需求规划

1. 背景

Hello-AI 已经积累了大量 AI 相关开源项目。当前 data/projects.json 按分类保存项目,项目数量约 20645 条,去重后的 GitHub URL 约 20569 个。现有项目元数据主要来自 GitHub 基础信息、topics、stars、更新时间、人工或 LLM 生成的中文简介与标签。

这些元数据足够支撑分类展示和基础搜索,但对“为什么推荐这个项目”“它适合什么场景”“和同类项目差异在哪里”“是否真的可用”这类推荐决策问题仍然不够。README 是更高信息密度的数据源,包含项目目标、功能边界、安装方式、示例、架构、依赖、许可证、维护状态和使用场景。后续需要把大量 README 读取出来,在本地进行离线分析挖掘,为更精准的项目推荐、项目对比和探索入口提供结构化信号。

2. 核心目标

  1. 批量提取项目 README 内容,用于本地离线分析。
  2. 原始 README 文件和大体积中间产物不进入当前仓库,不进入 docs/,不影响 VitePress 构建和发布。
  3. 产出可复用的轻量分析结果,未来可选择性回填到推荐、搜索、Explore 页面或 Meilisearch 索引。
  4. 建立可断点续跑、可限速、可重试、可审计的 README 提取脚本规划。
  5. 为后续内容分析定义统一的数据结构和质量指标,避免直接把长文本塞进项目主数据。

3. 非目标

  1. 不把所有 README 原文提交到仓库。
  2. 不把 README 原文输出到 docs/home/ 或公开站点产物。
  3. 第一阶段不要求接入向量数据库或在线推荐服务。
  4. 第一阶段不直接替换现有分类、项目筛选和发现逻辑。
  5. 不在脚本中默认调用高成本 LLM;README 提取和基础解析应先用确定性规则完成。

4. 数据边界

4.1 仓库内允许保存

  • 需求与实施规划,例如本文件。
  • 脚本源码,例如后续的 scripts/extract-readmes.js
  • 小体积、可审计的分析摘要或索引,例如 data/readme-analysis-summary.json,但是否回填需要单独评审。
  • 示例 fixtures,每个不超过少量样本,用于测试脚本解析逻辑。

4.2 仓库内禁止保存

  • 批量 README 原文。
  • 大体积 Markdown、HTML、压缩包、克隆仓库、临时抓取缓存。
  • 包含潜在敏感内容、外部项目完整文档镜像或未清洗 LLM 输出的大文件。

4.3 推荐本地存储位置

默认把离线工作目录放在仓库外,例如:

bash
../hello-ai-readme-lab/

建议目录结构:

text
hello-ai-readme-lab/
  manifest.jsonl
  readmes/
    github.com/{owner}/{repo}/README.md
  normalized/
    github.com/{owner}/{repo}.json
  analysis/
    github.com/{owner}/{repo}.json
  logs/
    extract-YYYY-MM-DD.jsonl

如果临时文件必须放在仓库内,只能放在 .cache/readme-analysis/。当前 .gitignore 已包含 **/.cache/,可以避免误提交。

5. README 提取脚本规划

5.1 脚本定位

建议新增脚本:

text
scripts/extract-readmes.js

建议新增 npm 命令:

json
{
  "ai:extract-readmes": "node scripts/extract-readmes.js"
}

脚本职责只做“项目列表读取、README 定位、内容下载、规范化、缓存、日志和断点续跑”。内容理解、LLM 总结、Embedding 生成、推荐特征计算应拆成后续独立脚本,避免单个脚本过重。

5.2 输入来源

默认输入:

text
data/projects.json

遍历方式:

  1. 读取 categories[].projects[]
  2. 使用 project.url 作为项目唯一来源。
  3. 解析 GitHub URL 得到 owner/repo
  4. 对同一个 GitHub URL 去重,避免 trending 与真实分类重复提取。
  5. 可通过参数筛选分类、子类、stars、更新时间和数量。

建议支持参数:

bash
pnpm ai:extract-readmes -- --limit 100
pnpm ai:extract-readmes -- --category agents --limit 500
pnpm ai:extract-readmes -- --min-stars 1000
pnpm ai:extract-readmes -- --since 2025-01-01
pnpm ai:extract-readmes -- --workdir ../hello-ai-readme-lab
pnpm ai:extract-readmes -- --resume
pnpm ai:extract-readmes -- --force
pnpm ai:extract-readmes -- --dry-run

5.3 README 获取策略

优先使用 GitHub API:

  1. GET /repos/{owner}/{repo}/readme
  2. 根据 API 返回的 download_url 获取原始 Markdown。
  3. 使用 ETag / Last-Modified 做缓存验证。
  4. 若默认 README 不存在,再尝试常见路径:
    • README.md
    • README.zh.md
    • README_zh.md
    • README.rst
    • docs/README.md

失败处理:

  • 404:记录为 not_found,不反复重试。
  • 403 rate limit:写入进度后停止,下一次从断点继续。
  • 5xx 或网络错误:指数退避重试,超过上限后记录失败。
  • 非 Markdown 格式:可以保存原始文本,但在 normalized 阶段标记 format

5.4 内容规范化

下载后生成轻量 JSON,建议字段:

json
{
  "source": {
    "url": "https://github.com/owner/repo",
    "owner": "owner",
    "repo": "repo",
    "defaultBranch": "main",
    "readmePath": "README.md",
    "downloadUrl": "https://raw.githubusercontent.com/owner/repo/main/README.md"
  },
  "fetch": {
    "status": "ok",
    "fetchedAt": "2026-07-06T00:00:00.000Z",
    "etag": "",
    "sha": "",
    "bytes": 12345
  },
  "content": {
    "format": "markdown",
    "languageHint": "en",
    "title": "Project Title",
    "plainTextLength": 9000,
    "headingCount": 18,
    "codeBlockCount": 6,
    "linkCount": 42
  }
}

规范化规则:

  1. 保留原始 README 到仓库外 readmes/
  2. 将 Markdown 转成可分析的纯文本和结构化 heading 树。
  3. 去除 badges、重复导航、空链接、过长 base64 图片、HTML 噪声。
  4. 保留代码块数量、语言、安装命令、示例命令等信号,但不把所有代码块写入仓库。
  5. 对超长 README 设置最大分析长度,原文仍在本地缓存,分析时分段处理。

5.5 Manifest 与断点续跑

manifest.jsonl 每行记录一个项目的提取状态:

json
{"url":"https://github.com/owner/repo","status":"ok","readmePath":"README.md","bytes":12345,"fetchedAt":"2026-07-06T00:00:00.000Z"}

状态枚举:

  • pending
  • ok
  • not_found
  • rate_limited
  • network_error
  • unsupported
  • skipped

断点策略:

  1. --resume 跳过 oknot_found
  2. --force 忽略缓存重新拉取。
  3. --dry-run 只输出待抓取数量、分类分布和预计 API 调用量。
  4. 每处理一个项目立即落 manifest,避免长批次中断后丢进度。

5.6 限速与稳定性

建议默认策略:

  • 未配置 GITHUB_TOKEN 时,低并发或串行,优先小批量验证。
  • 配置 GITHUB_TOKEN 后支持有限并发,例如 --concurrency 3
  • 每次请求记录剩余 rate limit。
  • 默认不超过 GitHub API 可承受范围。
  • 支持 --sleep-ms 在大批量抓取时主动降速。

6. 离线分析规划

README 提取完成后,建议拆分为三层分析。

6.1 规则分析层

不依赖 LLM,成本最低,优先实现:

  • README 完整度评分:标题、安装、快速开始、示例、配置、部署、贡献、许可证。
  • 可运行性信号:是否存在 install / quickstart / docker / npm / pip / uv / cargo / compose。
  • 项目成熟度信号:文档结构、release 链接、贡献指南、测试说明、API 文档。
  • 场景关键词:agent、rag、mcp、workflow、voice、vision、finetune、inference、observability。
  • 风险信号:archived、deprecated、experimental、WIP、unmaintained、no longer maintained。

6.2 语义摘要层

可以在小批量验证后接入 LLM,输出结构化摘要:

json
{
  "valueProposition": "这个项目解决什么问题",
  "primaryUseCases": ["用例1", "用例2"],
  "targetUsers": ["开发者", "团队", "研究者"],
  "coreCapabilities": ["能力1", "能力2"],
  "integrationComplexity": "low|medium|high",
  "productionReadiness": "learning|prototype|production_candidate|mature",
  "recommendationReason": "为什么值得推荐",
  "cautions": ["风险1", "风险2"],
  "alternativesSignal": ["可对比方向"]
}

6.3 推荐特征层

将 README 分析结果转成可排序、可检索、可解释的推荐特征:

  • readmeQualityScore
  • quickstartScore
  • productionReadinessScore
  • integrationComplexity
  • scenarioTags
  • capabilityTags
  • riskTags
  • audienceTags
  • recommendationSnippets

这些特征可以后续用于:

  • Explore 项目详情页的“适合场景 / 风险提示 / 下一步建议”。
  • 相似项目推荐的加权特征。
  • Meilisearch 索引字段增强。
  • 未来 Embedding 语义推荐的输入文本。

7. 与现有项目的集成边界

第一阶段只新增脚本和本地缓存,不改动现有展示数据。

第二阶段可以新增一个小体积产物,例如:

text
data/readme-insights.json

该文件只保存轻量摘要和评分,不保存 README 原文。是否提交该文件取决于体积、隐私和推荐收益,需要单独评审。

第三阶段再考虑把轻量特征合并进:

  • public/explore/data/project-details.json
  • Meilisearch 文档
  • 相关推荐计算逻辑
  • 项目详情页决策文案

8. 验收标准

8.1 提取脚本验收

  1. 能从 data/projects.json 正确遍历并去重 GitHub 项目。
  2. --dry-run 能输出待处理数量、去重数量、分类分布和预计请求量。
  3. 能成功抓取至少 100 个项目 README,并写入仓库外工作目录。
  4. 支持断点续跑,中断后不会重复下载已成功项目。
  5. 遇到 404、限流、网络错误时能记录明确状态,不导致全批次失败。
  6. 不向 docs/home/data/projects.json 写入 README 原文。
  7. 默认输出目录不在当前仓库内,或明确使用被 .gitignore 忽略的 .cache/readme-analysis/

8.2 分析结果验收

  1. 每个成功项目至少生成 README 完整度、快速开始、风险提示、场景标签等基础指标。
  2. 分析结果体积可控,不包含大段 README 原文。
  3. 对 README 缺失、非英文、超长、非 Markdown 的项目有明确降级策略。
  4. 抽样检查 30 个项目,推荐理由和风险标签与 README 内容一致。
  5. 分析产物可以独立重建,不依赖手工编辑。

9. 实施阶段

阶段一:提取闭环

  • 新增 scripts/extract-readmes.js
  • 支持读取项目库、去重、dry-run、limit、workdir、resume。
  • 完成 GitHub README 下载、缓存和 manifest。
  • 小批量验证 100 到 500 个项目。

阶段二:规则分析

  • 新增 README 规范化与规则评分。
  • 输出 normalized/analysis/ 本地 JSON。
  • 对不同分类抽样验证评分合理性。

阶段三:推荐特征设计

  • 从本地分析结果中提取轻量推荐特征。
  • 评估是否生成 data/readme-insights.json
  • 在 Explore 或相似推荐中做小范围实验。

阶段四:语义增强

  • 对高价值项目或高流量分类接入 LLM 摘要。
  • 控制成本,优先处理 stars 高、更新活跃、README 完整的项目。
  • 评估 Embedding 或 Meilisearch 向量检索的收益。

10. 风险与缓解

风险影响缓解
README 数量过多下载耗时、磁盘占用大默认仓库外缓存,支持 limit、category、resume、增量更新
GitHub API 限流批处理失败支持 token、限速、断点、rate limit 检测
README 格式差异大解析质量不稳定先做结构化统计和规则评分,再逐步补充格式兼容
原文误提交仓库膨胀、发布污染默认 workdir 在仓库外,禁止写入 docs,必要时使用 .cache/
LLM 成本不可控批量分析费用高第一阶段不默认调用 LLM,只对筛选后的项目做语义增强
推荐特征污染主数据数据回滚困难先独立生成 insights 文件,验证后再决定是否回填

11. 推荐的第一步

先实现一个只做提取的 MVP:

bash
pnpm ai:extract-readmes -- --dry-run
pnpm ai:extract-readmes -- --limit 100 --workdir ../hello-ai-readme-lab
pnpm ai:extract-readmes -- --resume --limit 500 --workdir ../hello-ai-readme-lab

MVP 完成后,再基于真实 README 样本设计规则分析器。这样可以先验证数据规模、失败率、限流情况、磁盘占用和 README 质量分布,再决定后续是否接入 LLM 摘要或向量化推荐。