AI 项目分类与标签方案评审及 V2 实施计划
评审日期:2026-07-17
评审对象:plans/AI_PROJECT_TAXONOMY_AND_TAGGING_PLAN.md
评审结论:REVISE(方向正确,但不建议按原稿直接实施)
0. 执行摘要
原方案最重要的判断是正确的:Hello-AI 仍需要一个稳定的分类目录,但不能再用单一分类承载项目的全部语义;跨分类属性应由受控标签表达。原方案也正确地区分了 subcategoryId、受控标签和原始 tags/topics 三层信号(原方案 71-79 行)。
但原方案仍然偏重“把分类拆得更细”,标签部分还不足以直接实施:
- 顶层分类同时混用了项目形态、能力、平台和行业,二级分类又存在多组重叠,单靠 1-12 的优先级不能稳定处理跨类项目。
- 首批标签候选约 114 个,已经接近原稿设定的 80-120 上限;其中
task、audience、maturity有较强推断性或与已有字段重复。 categoryId、subcategory、subcategoryId和分面对象同时写入项目会制造多个事实源。- 自动打标缺少
evidence、置信度门槛、金标集、人工一致性和回滚机制。 - Explore 当前只有单标签状态和单值精确匹配,原方案没有定义多分面筛选的 AND/OR 语义。
V2 推荐采用三层模型:
一级分类 + 一个主子类 负责稳定导航和文档分组
+
2-6 个受控分面标签 负责跨类表达、筛选、推荐和任务入口
+
原始 tags/topics 负责全文召回、别名发现和 taxonomy 演进核心决策:
- 保留 12 个业务顶层分类;
trending继续作为派生榜单。 - 分类只是
primary shelf(主陈列位置),不再宣称它是项目唯一的语义归属。 - 二级分类数量按分类规模自适应,不再强制每个大类都是 4-7 个。
- V1 只启用 4 个标签分面、56 个标签,活跃标签硬上限为 60。
- 每项目总标签 1-6 个,目标 2-5 个;不为满足数量强制补标签。
task改成标签查询预设,maturity从已有状态派生,audience暂缓。- taxonomy 是唯一结构事实源;项目只保存稳定 ID,不复制标签分面归属和分类展示名。
1. 评审依据与数据快照
1.1 代码链路
| 事实 | 证据 | 对方案的影响 |
|---|---|---|
| 评估 Prompt 只把分类 ID、名称和自由文本子类列表拼接给 LLM | scripts/evaluation-prompt.js:7-11、30-35 | 当前不能保证子类和标签来自受控枚举 |
| 入库只校验顶层分类,子类由 LLM 自由写入 | scripts/discover-and-evaluate.js:649-664 | 必须增加 taxonomy 校验层,且分类失败不能等同于内容拒绝 |
文档按 project.subcategory 展示文本分组 | scripts/generate-docs.js:28-34、71-83 | V2 需要由 subcategoryId 查 taxonomy label,同时保留一期兼容 |
Explore 从父分类派生 categoryId | scripts/generate-explore-data.js:490-513 | 嵌套结构下不应在项目内重复保存 categoryId |
| 相关项目混合使用子类、raw tags 和 topics | scripts/generate-explore-data.js:292-338 | canonical tag 可提高稳定性,但 raw 信号仍应保留召回价值 |
Explore 当前只有单个 tag 状态 | public/explore/assets/app.js:21-29 | 要支持真正的多维标签,需要把状态改成按 facet 分组的多选集合 |
| Explore 只展示全局前 28 个标签 | public/explore/assets/app.js:600-607 | 不能把 50-100 个标签平铺成一组 chip |
| 搜索 Worker 只做一个标签的精确匹配 | public/explore/assets/search-worker.js:22-40 | 必须定义同分面 OR、跨分面 AND 的组合规则 |
| Meilisearch 当前只搜索 raw tags/topics/subcategory | scripts/meilisearch-index.js:84-98 | canonical tagIds 和 subcategoryId 需要进入索引配置 |
categories.json 当前从 projects.json 生成 | scripts/extract-categories.js:8-31 | 引入 taxonomy 后必须重新明确唯一事实源和派生方向 |
1.2 数据观察
本次只读分析以 2026-07-17 当前工作区为快照。data/projects.json 正在发生未提交变化,因此下列数字用于判断数量级,不作为发布基线:
- 约 2.1 万条业务分类记录,去重 URL 略少于分类记录,数据中存在重复项目。
trending的项目在业务分类中也存在,说明它本质上应是派生视图,而不是重复存储的分类。- 当前 raw
tags有超过 1.2 万种原始拼写,简单归一化后仍超过 1 万种。 llm/LLM、mcp/MCP、PyTorch/pytorch、空格与短横线等同义变体大量存在。- 当前每项目 raw tags 中位数约为 4,说明“标签数量”不是主要问题,“语义归一和质量”才是主要问题。
- 现有大桶仍明显失衡,例如
agents/Agent Frameworks、devtools/SDKs & APIs、applications/Productivity Tools、robotics_iot/Robotics均超过所属活跃项目的一半。
data/stats.json:2-4 与当前源数据数量存在时点差异,V2 应给所有派生物写入统一的 taxonomyVersion 和 sourceDigest,避免用不同快照做验收。
2. 多维评审
2.1 评审评分
| 维度 | 评分 | 结论 |
|---|---|---|
| 战略方向 | 8/10 | “稳定分类 + 横向标签 + raw 信号”是正确方向 |
| 信息架构 | 6/10 | 顶层分类兼容性强,但多种分类轴混杂 |
| 二级分类边界 | 5/10 | 提案覆盖面完整,但多组子类直接重叠 |
| 标签收敛度 | 4/10 | 六个分面约 114 个候选,首版过大 |
| 数据模型 | 5/10 | 有稳定 ID 思路,但存在重复字段和多事实源 |
| 自动标注可靠性 | 3/10 | 缺证据、置信度、金标集和错误隔离 |
| 搜索与筛选体验 | 5/10 | 指明了改造对象,但未定义多选交互语义 |
| 迁移与回滚 | 4/10 | 有 dry-run,没有 inverse patch、原子替换和索引切换 |
| 验收可测性 | 4/10 | 覆盖率指标较多,正确性指标不足 |
| 向后兼容 | 8/10 | 保留顶层 ID 和 raw tags/topics 的策略合理 |
2.2 值得保留的设计
- 顶层分类 ID 保持稳定。 当前导航、README、文档路径和 Explore 都依赖这些 ID,原方案
38-60行的兼容性判断成立。 - 稳定 ID 与展示 label 分离。
subcategoryId和中文 label 分离有利于重命名和多语言展示。 - canonical 与 raw 信号分层。 GitHub topics 不应直接成为目录或过滤器,原方案
75-79行的三层思路应保留。 - 先 dry-run 再批量迁移。 原方案
446-462行已经具备正确的迁移顺序雏形。 - 同时改造评估、文档、Explore 和搜索。 这避免 taxonomy 只存在于数据文件而没有产品消费端。
2.3 必须修订的问题
A. 分类不是同一条轴
applications 是项目形态,multimodal 是能力/模态,desktop_tools 是平台,finance_business 是行业。一个桌面端金融 Coding Agent 可以同时命中多个顶层分类。原方案 407-420 行的线性优先表只能给出一个结果,却不能解释为什么该结果对用户最有用。
修订原则:承认分类只是主陈列位置,用可停止的决策树确定一个位置;所有未被主分类表达的属性进入标签。
B. 二级分类存在直接重叠
| 重叠主题 | 原方案中的位置 | V2 边界 |
|---|---|---|
| Embedding/Reranking | llms 与 rag_data | 模型权重归 llms;检索管线与工具归 rag_data;两者都可打 capability tag |
| OCR | rag_data 与 multimodal | 通用 OCR/视觉引擎归 multimodal;面向知识库摄取的文档管线归 rag_data |
| MCP | agents 与 devtools | MCP server/client/integration 归 devtools;Agent runtime 仅因支持 MCP 不迁类,只打 mcp |
| Local AI | infrastructure 与 desktop_tools | 无头运行时/Serving 归 infrastructure;GUI 工作台归 desktop_tools |
| Coding Agent | agents 与 devtools | 自主修改仓库/执行任务归 agents;IDE 补全、代码查询和插件归 devtools |
C. 标签首版过大且分面职责重叠
原方案 297-337 行约有 114 个候选标签。主要问题不是 114 这个绝对数字,而是其中有三类不应直接入库:
task是用户查询意图,可以由标签组合生成,不应再复制一套标签。maturity中的maintained/inactive与现有health和更新时间重复;tutorial/awesome-list实际是项目形态。audience很难从当前 name/description/topics 稳定判断,容易让 LLM 猜测。
原方案要求每项目 3-8 个、最多 10 个(424-432 行),会诱导系统为了达标填充弱标签。V2 改为上限控制,不设置强制平均数。
D. 数据模型存在漂移风险
原方案示例在项目中新增 categoryId、展示文本 subcategory、subcategoryId 和按分面展开的 canonicalTags(377-394 行)。但当前项目已经嵌套在父 category 下,Explore 和 Meilisearch 都从父级派生 categoryId。重复写入会导致父分类和项目字段不一致。
V2 项目只写 subcategoryId、扁平 tagIds 和 taxonomyVersion;category 来自父级,标签所属 facet 来自 taxonomy,展示 label 也来自 taxonomy。
E. 自动标注没有质量闭环
当前 Prompt 输入只有 name、description、topics(scripts/evaluation-prompt.js:14-20)。这些证据不足以可靠判断 audience、成熟度和复杂任务。原方案虽然提到低置信度 review,但没有定义置信度、证据格式、人工样本或最低正确率。
此外,taxonomy 输出非法不等于项目内容不合格。原方案 490-494 行把失败结果降级到 rejected reason 的做法会混淆“内容拒绝”和“分类待审”。两者必须使用不同队列。
F. 迁移和索引缺少回滚
原方案有 dry-run 和 patch,但没有:
- 输入文件摘要和 taxonomy 版本;
before/after/reason/confidence记录;- inverse patch;
- 幂等和原子替换;
- Meilisearch 新索引构建、验证、swap 和旧索引保留;
trending从业务数据重新派生的顺序。
G. 验收指标偏覆盖率,缺少正确率
“98% 有 ID”“未分类低于 2%”“平均 3-8 个标签”都可以通过强制赋值达成,却不能证明标签正确。原方案对子类成立阈值也同时使用了 50 个(64-69 行)和 30 个(534-540 行),口径不一致。
3. V2 目标与非目标
3.1 目标
- 用户能通过稳定目录浏览项目,也能通过多维标签找到跨分类项目。
- 新增项目只能写入合法分类、子类和标签 ID。
- 标签集合规模受控、语义明确、可合并、可废弃、可审计。
- 自动打标有证据、有置信度、有人工质量基线。
- 迁移可 dry-run、可回滚、可重复执行。
- 文档、Explore、相关项目和 Meilisearch 消费同一 taxonomy。
3.2 非目标
- V1 不追求表达 GitHub 项目的每个技术细节。
- V1 不把编程语言、厂商名、模型名、许可证和所有 GitHub topics canonical 化。
- V1 不引入多主分类;多维语义由标签解决。
- V1 不一次性创建 80-120 个标签,也不根据一次 LLM 输出自动扩充 taxonomy。
4. 信息架构决策
4.1 三层语义模型
| 层级 | 每项目数量 | 职责 | 是否受控 |
|---|---|---|---|
categoryId | 1 | 顶层导航、稳定 URL、统计 | 是 |
subcategoryId | 1 | 当前分类内的主陈列位置 | 是 |
tagIds | 1-6 | 跨类能力、平台、形态和领域 | 是 |
tags/topics | 0-N | 搜索召回、别名学习、趋势发现 | 否,保留原值 |
这里的“每项目一个分类”不代表项目只属于这个语义类别,只代表项目在目录里有一个稳定落点。一个金融 Coding Agent 可以主陈列在 finance_business,同时具有 agent-runtime、code-generation、cli、application、finance 标签。
4.2 顶层分类
保留原有 12 个业务分类和 trending 派生入口,不在本轮改变 URL 和导航认知。trending 不参加 LLM 分类、不持久化业务副本,应由业务项目集合生成。
4.3 二级分类规模
不再对所有顶层分类统一要求 4-7 个二级分类,改为按活跃项目规模设置:
| 顶层分类活跃规模 | 建议子类数 | 子类成立门槛 |
|---|---|---|
| 少于 300 | 2-4 | 至少 30 个且占所属分类 8%,或战略例外 |
| 300-1000 | 3-5 | 至少 40 个且占所属分类 5%,或战略例外 |
| 大于 1000 | 4-7 | 至少 50 个且占所属分类 5%,或战略例外 |
先对原方案提出的子类执行全量 dry-run,再决定启用、合并或保留为标签。不能为了达到子类数量目标而拆出没有稳定用户入口的小桶。
4.4 主分类停止式决策树
按下面顺序命中后停止;实现时每条规则都必须有 include/exclude 样例:
- 纯教程、课程、论文清单、Notebook、资源导航 ->
learning。 - 核心交付物是模型权重或模型架构 -> 文本/通用模型归
llms,视觉/音视频模型归multimodal。 - 核心价值依赖机器人、传感器、嵌入式设备或自动驾驶环境 ->
robotics_iot。 - 核心价值离不开金融、交易、市场或企业业务数据 ->
finance_business。 - 核心交付物是推理运行时、部署、网关、监控或硬件加速 ->
infrastructure。 - 核心交付物是训练、微调、数据集生产或模型评测 ->
finetuning。 - 核心交付物是检索、索引、文档摄取或知识图谱管线 ->
rag_data。 - 核心行为是自主规划、调用工具并持续执行任务 ->
agents。 - 核心交互依赖桌面、操作系统或浏览器扩展 ->
desktop_tools。 - 面向最终用户的可直接使用产品 ->
applications。 - SDK、IDE 插件、代码分析、API client 和开发脚手架 ->
devtools。 - 仍无法裁决 -> 保留原归属并进入
taxonomy-review.jsonl,不得靠随机优先级写入。
4.5 典型冲突裁决
| 项目 | 主分类/子类 | canonical tags |
|---|---|---|
| 通用 MCP server | devtools/mcp-integrations | mcp, library-sdk,按接口补平台 |
| 支持 MCP 的多智能体框架 | agents/multi-agent-systems | multi-agent, mcp, framework |
| Embedding 模型权重 | llms/embedding-rerank-models | embedding, model |
| Embedding 检索管线 | rag_data/search-retrieval-engines | embedding, vector-search, framework |
| 通用 OCR 引擎 | multimodal/vision-understanding-ocr | ocr, vision-understanding, library-sdk |
| 面向 RAG 的 PDF 摄取工具 | rag_data/document-parsing-ocr | document-parsing, ocr, library-sdk |
| 本地模型无头运行时 | infrastructure/local-runtime-model-management | local-model-runtime, model-serving, self-hosted |
| 本地模型 GUI 客户端 | desktop_tools/local-ai-workbench | local-model-runtime, desktop-app, application |
| 自主修复仓库的 CLI Agent | agents/coding-agents | agent-runtime, code-generation, cli, application |
| IDE 内代码补全插件 | devtools/ai-ides-code-assistants | code-generation, ide-extension, application |
| 文生图 SaaS 的开源前端 | applications/creative-content-apps | image-generation, web-app, application |
5. 收敛标签体系
5.1 标签设计原则
一个 canonical tag 必须同时满足:
- 能回答一个明确、可重复的筛选问题。
- 语义预计至少稳定 6 个月,不是短期产品名或热词。
- 与已有标签有清晰边界,不把上下位概念当 alias。
- 能从 README、topics、仓库元数据或人工判断中找到证据。
- 默认覆盖至少 50 个活跃项目;战略能力可例外,但必须记录批准原因。
- 活跃标签总数不超过 60;超过上限时执行 one-in-one-out 合并或废弃。
明确不收录为 canonical tag 的内容:
- 过宽:
ai、machine-learning、open-source、developer。 - 具体厂商/产品:
openai、claude、gemini、ollama;保留为 raw topics 或 alias 证据。 - 编程语言:
python、rust、typescript;继续用于搜索,不进入首版 facet。 - 推断性强:
end-user、product-builder、production-ready。 - 与现有字段重复:
maintained、inactive、deprecated。
5.2 V1 标签总表
首版共 56 个:capability 31 个、platform 9 个、project_type 9 个、domain 7 个。
Capability(31)
| 标签组 | tagIds | 边界说明 |
|---|---|---|
| 本地与模型工具 | local-model-runtime, embedding, reranking | 不使用过宽的 llm;只标明确的运行、向量化或重排能力 |
| Agent 与协议 | agent-runtime, multi-agent, mcp, tool-calling | multi-agent 是更具体能力;mcp 只表示协议兼容,不决定分类 |
| 检索与知识 | rag, graphrag, vector-search, knowledge-graph, document-parsing, ocr | OCR 可跨 rag_data 与 multimodal,由主交付物决定分类 |
| 训练与运行 | fine-tuning, model-training, model-evaluation, model-serving, model-quantization, llm-observability | 避免泛化为 mlops、training、evaluation |
| 多模态 | image-generation, vision-understanding, video-generation, video-understanding, speech-to-text, text-to-speech | 音乐/通用音频生成暂保留 raw topic,达到门槛后再评估 |
| 编程与自动化 | code-generation, code-search, browser-automation, workflow-automation | automation 太宽,不进入 canonical |
| 机器人与端侧 | robotics-control, edge-inference | edge-device 属于 platform,不与能力混写 |
Platform(9)
cli, web-app, desktop-app, browser-extension, ide-extension, mobile-app, self-hosted, kubernetes, edge-device
平台标签只在存在明确运行或交互证据时写入。仅提供 Dockerfile 不自动产生平台标签;self-hosted 需要文档明确支持自行部署。
Project Type(9)
model, framework, library-sdk, application, database-engine, dataset, benchmark, learning-resource, curated-list
每个项目必须且只能有一个 project_type。curated-list 与 learning-resource 互斥:资源目录使用前者,课程/教程/Notebook 使用后者。
Domain(7)
finance, healthcare, legal, education, cybersecurity, autonomous-driving, iot
领域标签默认最多一个。只有项目核心价值无法脱离该领域数据、规则或工作流时才添加;README 中出现一个行业示例不构成领域证据。
5.3 每项目标签数量
| Facet | 数量约束 | 规则 |
|---|---|---|
project_type | 恰好 1 | 无法确定则进入 review |
capability | 0-3 | 只写有直接证据的能力;资源清单和通用数据集可为 0 |
platform | 0-2 | 只写真实支持的平台,不从技术栈猜测 |
domain | 0-1 | 只写核心领域 |
| 总数 | 1-6 | 目标 2-5,不为凑数补标签 |
5.4 最具体标签优先
taxonomy 应支持 broader 关系,但项目不重复保存父子标签:
multi-agent的 broader 是agent-runtime;项目只存multi-agent,筛选agent-runtime时通过查询展开命中。graphrag的 broader 是rag;项目只存graphrag。browser-extension与browser-automation不是父子关系,一个是平台,一个是能力,可以共存。speech-to-text与text-to-speech是不同能力,可以共存。
5.5 不入库的任务预设
任务入口由稳定标签表达式生成,避免再维护一套 task 标签:
| 任务入口 | 查询表达式示例 |
|---|---|
| 构建 RAG | capability in (rag, graphrag) AND project_type in (framework, library-sdk) |
| 本地运行模型 | capability = local-model-runtime AND platform in (self-hosted, desktop-app, edge-device) |
| 构建 Coding Agent | capability = agent-runtime AND capability in (code-generation, code-search) |
| 文档问答 | capability in (rag, graphrag) AND capability in (document-parsing, ocr) |
| 部署模型服务 | capability = model-serving |
| 浏览器自动化 | capability = browser-automation |
这些表达式可维护在 data/task-presets.json,当前 scripts/generate-explore-data.js:344-362 已有任务匹配概念,可改为读取 canonical 表达式而不是字符串包含判断。
6. Taxonomy 与项目数据结构
6.1 唯一事实源
新增 data/taxonomy.json,它是下列信息的唯一事实源:
- category/subcategory 的 ID、label、顺序、别名和边界;
- tag 的 ID、facet、label、别名、include/exclude、broader 和生命周期;
- taxonomy 版本和变更记录。
data/categories.json 改为从 taxonomy 生成的轻量导航产物。Prompt、文档、Explore 和 Meilisearch 均通过同一个 scripts/lib/taxonomy.js 读取和校验 taxonomy。
6.2 Taxonomy 示例
{
"version": "2.0.0",
"facets": ["capability", "platform", "project_type", "domain"],
"tags": [
{
"id": "graphrag",
"facet": "capability",
"label": "GraphRAG",
"description": "Retrieval augmented generation whose retrieval structure is a graph.",
"aliases": ["graph-rag"],
"include": ["Graph-based retrieval is a core project capability."],
"exclude": ["A generic knowledge graph without a RAG pipeline."],
"broader": "rag",
"status": "active",
"replacedBy": null
}
]
}alias 只能表示同义拼写,不能把 agent、multi-agent 这样的上下位概念互相归一。
6.3 项目记录
项目继续嵌套在 category 下时,不重复存 categoryId:
{
"name": "Example",
"url": "https://github.com/org/example",
"subcategoryId": "coding-agents",
"tagIds": ["agent-runtime", "code-generation", "cli", "application"],
"taxonomyVersion": "2.0.0",
"tags": ["AI Agent", "Claude Code"],
"topics": ["coding-agent", "cli"]
}一期兼容期间可以继续输出 subcategory 展示文本,但它必须由 subcategoryId 和 taxonomy 生成,不再由 LLM 直接写入。兼容期结束后删除持久化展示文本。
6.4 标注审计记录
data/taxonomy-assignments.jsonl 保存自动标注证据,不把大段 evidence 复制进项目主库:
{
"url": "https://github.com/org/example",
"sourceDigest": "sha256:...",
"taxonomyVersion": "2.0.0",
"subcategoryId": {
"value": "coding-agents",
"confidence": 0.94,
"evidence": ["README: autonomous repository task execution"],
"source": "rules+llm"
},
"tagIds": [
{
"value": "code-generation",
"confidence": 0.96,
"evidence": ["topic:coding-agent", "README: edits repository files"],
"source": "rules"
}
],
"reviewRequired": false
}7. 自动分类与打标管线
7.1 证据优先级
- 当前合法分类和人工锁定结果。
- 精确 URL/owner/name 规则。
- taxonomy alias 与 GitHub topics 的精确匹配。
- README 中明确的功能、安装和使用场景证据。
- description、项目名和仓库元数据。
- LLM 在白名单内的结构化判断。
scripts/extract-readmes.js 已经能维护 README 抓取结果和 manifest,可复用该离线证据链,不应只依赖当前 Prompt 的 name/description/topics。
7.2 自动决策门槛
- 每个自动分类或标签必须返回
value/confidence/evidence/source。 - 经金标集校准后,
confidence >= 0.90且无规则冲突才自动写入。 0.70 <= confidence < 0.90进入taxonomy-review.jsonl,保留旧归属。confidence < 0.70不写该标签;项目类型或子类不确定时进入 review。- 违反数量、facet、互斥或 broader 规则的输出一律不入库。
- taxonomy 判断失败写入分类 review,不写入内容
rejected-projects。
7.3 金标集
首版建立至少 600 个项目的分层金标集:
- 12 个业务分类各抽 30 个,共 360 个;覆盖每个候选子类。
- 典型跨类冲突 120 个:MCP、OCR、Embedding、Local AI、Coding Agent、金融 Agent 等。
- 空子类、重复 URL、低频标签和历史异常 120 个。
至少 200 个样本由两人独立标注,用于计算 Cohen's kappa;其余样本用于离线 precision/recall 和 macro-F1。12 个分类的抽样还要按候选子类分层,不能只按分类总量均匀抽样。
7.4 Taxonomy 校验器
新增 scripts/validate-taxonomy.js,至少校验:
- category/subcategory/tag ID 全局唯一;
- alias 归一化后不冲突;
- tag facet 合法,
broader不成环; status=deprecated必须有replacedBy或明确删除原因;- 每项目子类属于父 category;
- 每项目恰好一个 project type,总标签不超过 6;
- 不保存父子冗余标签;
- URL 唯一,
trending不作为业务源数据重复参与; - 所有项目和派生物的 taxonomy version/source digest 一致。
8. 产品筛选与搜索规则
8.1 筛选语义
- 同一 facet 多选使用 OR:
cli OR desktop-app。 - 不同 facet 之间使用 AND:
agent-runtime AND (cli OR desktop-app) AND finance。 - category/subcategory 与标签之间使用 AND。
- raw tags/topics 只参与全文召回,不进入 canonical facet 计数。
- broader 查询由搜索层展开,例如选择
agent-runtime时同时命中multi-agent。
8.2 Explore 交互
- 标签按
capability/platform/project_type/domain分组,不平铺 56 个标签。 - 每组默认显示动态计数最高的 6-10 个,其余通过组内搜索或展开查看。
- 计数基于当前筛选结果联动更新;零结果标签禁用。
- 已选条件可单独删除,并写入 URL,刷新或分享后可恢复。
- 任务入口只应用预设筛选条件,不生成另一种项目属性。
8.3 相关项目
相关项目权重建议:
- 相同最具体 capability tag;
- 相同 subcategory;
- 相同 project type/platform/domain;
- raw tags/topics 仅作为较低权重补充;
- 高频标签需要 IDF 或上限,避免
application、framework主导相似度。
9. 实施计划
阶段 0:冻结可复现基线
涉及文件:data/projects.json、data/stats.json、public/explore/data/*
- 记录源文件 SHA-256、项目行数、唯一 URL、重复 URL、空/非法子类和生成物时间。
- 先按 URL 去重业务数据;保留冲突报告,不静默丢弃不同分类记录。
- 将
trending改为派生输出,确保它不污染业务唯一性和分类统计。 - 所有 dry-run 报告带
sourceDigest,源文件变化后旧报告不得应用。
阶段 1:定义 taxonomy 和共享 loader
涉及文件:新增 data/taxonomy.json、scripts/lib/taxonomy.js、scripts/validate-taxonomy.js
- 写入顶层分类、经 dry-run 验证的子类、56 个 V1 标签和边界规则。
- 实现 ID/alias/facet/broader/status 校验。
- 修改
scripts/extract-categories.js,由 taxonomy 生成data/categories.json。 - 为 loader 和 validator 增加单元测试,包括 alias 冲突和 broader 环路。
阶段 2:建立金标集并验证子类
涉及文件:新增 data/taxonomy-gold.jsonl、scripts/audit-taxonomy.js
- 按第 7.3 节建立 600 个样本。
- 对原方案候选子类跑全量分布,输出 active/raw 数量、最大桶占比、冲突率和低置信率。
- 不满足第 4.3 节门槛的候选子类合并或降级为标签。
- 固化分类冲突样例作为回归测试。
阶段 3:现有项目 dry-run 打标
涉及文件:新增 scripts/classify-existing-projects.js、data/taxonomy-assignments.jsonl
- 先应用确定性 alias/include/exclude 规则。
- 再读取 README 信号;证据不足时才调用 LLM。
- 输出版本化 patch:
url/before/after/reason/confidence/evidence。 - 同时生成 inverse patch、review 队列和分布报告。
- dry-run 默认写新文件,禁止直接覆盖
data/projects.json。
阶段 4:改造新增项目评估
涉及文件:scripts/evaluation-prompt.js、scripts/discover-and-evaluate.js
- Prompt 只允许返回 taxonomy 中的 category/subcategory/tag ID。
- 输入增加可用 README 摘要或结构化信号。
- 输出增加逐项 confidence/evidence,不再返回自由文本子类。
- 入库前通过共享 validator;分类不确定进入 review,内容不合格才进入 rejected。
- 新增 Prompt 与入库校验测试,覆盖非法 ID、跨 facet、超量标签和低置信结果。
阶段 5:改造消费端
涉及文件:
scripts/generate-docs.jsscripts/generate-explore-data.jspublic/explore/assets/app.jspublic/explore/assets/search-worker.jsscripts/meilisearch-index.jsscripts/meilisearch-tui.js
工作内容:
- 文档从 taxonomy 解析子类顺序和 label。
- Explore 输出按 facet 分组的标签、broader 展开和动态计数所需数据。
- Worker 支持同 facet OR、跨 facet AND。
- 相关项目优先使用 canonical capability,raw 信号降权。
- Meilisearch 增加
subcategoryId、tagIds和按 facet 派生的 filter 字段。 - 任务路径改读
data/task-presets.json。
阶段 6:分批迁移与发布
- 先迁移金标集和 500 个非金标样本,人工检查错误类型和分布。
- 达到第 10 节质量门槛后,再生成全量 patch。
- 原子替换项目前重新校验
sourceDigest,替换后立即运行 validator。 - 重建文档、Explore 数据和站点构建。
- Meilisearch 使用新索引名构建;验证计数和查询后执行 index swap。
- 旧项目文件、inverse patch 和旧索引至少保留一个发布周期。
阶段 7:持续治理
- 每月输出 taxonomy drift:高频 raw topic、未映射信号、标签增长和低置信队列。
- 每季度审查低使用标签、近义标签和 project type/domain 误标。
- 新增 tag 必须提交覆盖数据、include/exclude、与现有标签重合率和迁移影响。
- active 标签达到 60 后执行 one-in-one-out,不直接扩容。
10. 验收标准
10.1 数据完整性
- 非
trendingURL 重复数为 0。 - 非法 category/subcategory/tag ID 为 0。
- 子类与父分类不一致为 0。
- project type 缺失或多于一个为 0。
- 每项目
tagIds为 1-6 个,父子冗余标签为 0。 trending完全由业务项目派生,不作为 LLM 可选分类。- taxonomy、项目、Explore 数据和搜索索引版本一致。
10.2 分类与标签正确性
- 金标集主分类准确率不低于 90%。
- 子分类 macro-F1 不低于 0.85。
- canonical tag micro precision 不低于 0.90、micro recall 不低于 0.80。
- 双人标注样本 Cohen's kappa 不低于 0.80。
- 自动写入的每个分类和标签都有 evidence,低置信结果不会覆盖旧归属。
- 新增项目不能生成 taxonomy 外 ID。
10.3 Taxonomy 收敛度
- V1 active tag 数不超过 60。
- 新增普通标签需覆盖至少 50 个活跃项目;战略例外必须在 taxonomy changelog 中记录。
- alias 冲突为 0,deprecated tag 均有替代或删除说明。
- 低于 30 个活跃项目且连续两个季度没有增长的非战略标签必须合并、降级为 raw 或废弃。
10.4 产品体验
- Explore 可同时选择多个 facet,同组 OR、跨组 AND 的结果与测试夹具一致。
- 动态计数、零结果禁用和 URL 状态恢复通过端到端测试。
- raw topics 仍能被全文搜索,但不出现在 canonical facet 中。
- 至少 6 个任务预设能稳定生成可解释的标签表达式和结果。
- 相比发布前基线,主要查询的零结果率不升高,筛选响应耗时不退化超过 20%。
10.5 工程与回滚
npm run ai:generate-docs成功。npm run explore:generate-data成功。npm run docs:build成功。- taxonomy loader/validator、Prompt 校验、迁移幂等和筛选逻辑测试通过。
- 同一 patch 重复执行不会产生额外变化。
- inverse patch 回滚演练成功。
- Meilisearch 新索引验证和 swap 演练成功,失败时可切回旧索引。
11. 风险与缓解
| 风险 | 影响 | 缓解 |
|---|---|---|
| 为了覆盖率强制打标签 | precision 下降、筛选失真 | 不设最低 capability 数;以 precision 和 evidence 为门槛 |
| 主分类边界仍有争议 | 用户对目录落点困惑 | 分类只作 primary shelf;保存争议样本并迭代停止式规则 |
| 标签过快膨胀 | UI 噪声和维护成本上升 | V1 上限 60、晋升门槛、one-in-one-out |
| LLM 置信度未校准 | 高分错误自动入库 | 以金标集校准;低置信 review;规则校验兜底 |
| taxonomy 多源漂移 | Prompt、页面、索引不一致 | 单一 loader、版本和 source digest 校验 |
| 迁移覆盖用户正在更新的数据 | 数据丢失或 patch 错位 | 输入摘要、默认写新文件、应用前 digest 校验和原子替换 |
| 多选筛选造成零结果 | 用户认为标签无用 | 动态计数、零结果禁用、任务预设和筛选可撤销 |
| 长尾能力被收敛掉 | 新兴方向不可发现 | raw topics 保留召回;月度 drift 报告;战略例外机制 |
12. ADR:选择“主分类 + 收敛分面标签”
Decision
采用一个稳定主分类、一个主子类、1-6 个受控分面标签和原始搜索信号并行的混合模型。
Drivers
- 保持现有 URL、导航和文档生成兼容。
- 表达项目跨能力、平台、形态和行业的真实多维属性。
- 控制标签规模、自动标注误差和长期治理成本。
Alternatives considered
- 纯分类树:实现简单,但跨类项目只能被迫选择一个语义归属,继续制造重叠子类。
- 纯标签目录:表达灵活,但会破坏现有导航认知,且 2 万项目的首屏探索成本过高。
- 多主分类 + 标签:表达力最强,但统计、去重、文档生成和 URL 规则复杂,当前收益不足以覆盖迁移成本。
- 主分类 + 收敛分面标签:既保留导航,又能表达多维语义,且可渐进迁移。
Why chosen
第四种方案在兼容性、表达力、实现复杂度和治理成本之间最均衡。它也允许未来在不改变项目数据的前提下,增加任务入口和新的浏览视图。
Consequences
- 分类不再被解释为项目完整本体,只是稳定陈列位置。
- 产品需要真正支持分面多选,而不是只增加一个标签字段。
- taxonomy 变成核心业务数据,需要版本、测试和变更治理。
- 自动标注必须接受“少打但准确”,不能以标签数量作为成功指标。
Follow-ups
- 先实施阶段 0-2,验证子类和 56 个标签的真实分布。
- 分布与金标结果通过后,再决定是否进入全量迁移。
- V1 上线一个季度后,根据 drift 报告评估是否晋升
audio-generation、privacy、3d-spatial等候选标签。
13. 最终建议
原方案不应废弃,而应作为“候选分类和标签素材库”。实际实施以本 V2 的约束为准:
- 先把分类定义降级为主陈列位置,解决“一个项目并非只属于一个语义类别”的根本矛盾。
- 首版只启用 56 个受控标签和 4 个 facet,不实施 task/audience/maturity 三套持久化标签。
- 先做分布 dry-run 和金标集,不直接回填 2 万项目。
- 用 evidence、precision、recall 和回滚演练决定是否发布,而不是用覆盖率和平均标签数决定。
满足以上条件后,“分类时顺便打标签”是合理且应当同步完成的,可以避免未来再次扫描全库;但同步打标必须产出可审计证据和版本化 patch,不能只扩展现有 LLM Prompt 后直接写回主库。
