LobeHub 模型元数据维护指南:knowledgeCutoff、family 与 generation 三个结构化字段的填写规则与全仓扫描工作流
本文基于 LobeHub 仓库中内置的模型元数据维护技能文档(SKILL.md),系统讲解 packages/model-bank/src/aiModels/*.ts 模型卡片上三个可选结构化字段——knowledgeCutoff(世界知识截止时间)、family(模型家族)与 generation(世代)的语义、数据来源规则、按厂商划分的易错点,以及从单模型 PR 到覆盖约 80 个 provider 文件、约 1900 条模型条目的全仓扫描(sweep)工作流。读完本文,你将掌握如何为新增模型正确填写元数据、如何甄别可采信的知识截止时间来源、如何使用仓库自带的四个脚本(提取 ID、派生 family、批量写入 cutoff、批量写入 family)完成幂等的 codemod 更新,以及如何用测试与 git grep 校验防止元数据在合并冲突中丢失。
三个字段的位置与类型定义
三个字段都定义在模型卡片的公共类型上,且全部为可选。在 AIChatModelCard 类型定义 中可以确认这一点:
// packages/model-bank/src/types/aiModel.ts(节选)
/** 'claude-mythos', 'gpt', 'o-series', 'qwen'. Families contain generations; */
family?: string;
/** model generation within the family (e.g. 'claude-4.6', 'gpt-5.2', 'qwen3.5'). */
generation?: string;
knowledgeCutoff?: string;
同文件下游的多个模型卡片类型(约 L716-L803)也复用了这三个可选字段,说明它们是跨 provider 模型卡片的统一元数据契约。一个真实示例来自 Anthropic 模型数据文件:
{
displayName: 'Claude Opus 5',
enabled: true,
family: 'claude-opus',
generation: 'claude-5',
id: 'claude-opus-5',
knowledgeCutoff: '2026-05',
// ...abilities / contextWindowTokens / pricing / releasedAt / settings
type: 'chat',
}
这三个字段都是读取时从 model-bank 合并到内置模型的:服务端仓储层(repositories/aiInfra/index.ts)会把整张模型卡片展开(spread)后下发,因此给卡片新增字段永远不需要数据库迁移——字段会自动流到客户端。
字段语义详解
原始技能文档给出的字段语义表是填写规则的核心依据:
| 字段 | 格式 | 含义 |
|---|---|---|
knowledgeCutoff |
'YYYY-MM'(厂商只公布年份时可用 'YYYY') |
世界知识截止时间。当厂商区分 "reliable knowledge cutoff"(可靠截止时间) 与更宽泛的训练数据截止时间时(Anthropic 会这样区分),一律取 reliable 那个值 |
family |
小写 slug,如 claude、gpt、o-series、qwen、deepseek、llama、glm 等 |
模型谱系,粒度细于 organization。用于 UI 对模型分组,以及在同一模型经由不同聚合商(aggregator)提供时做跨 provider 匹配 |
generation |
family slug + 版本号,如 claude-4.6、gpt-5.2、qwen3.5、llama-3.1 |
家族内的世代。仅在能从该模型线的命名规则有把握地推导时才填写。滚动别名(qwen-max、deepseek-chat、gemini-flash-latest)只填 family,不填 generation |
文档给出了最高原则(cardinal rule):只填写权威来源明确声明、或可从命名规则推导出的内容,绝不猜测。对不公布这些信息的厂商,字段留空是正确的结果——"留空优于猜一个"。这一原则在仓库的 knowledgeCutoff 常量模块注释 中得到了呼应:不公布知识截止时间的 provider(DeepSeek、Qwen、GLM、Kimi、MiniMax、Mistral 等)被刻意排除,注释明确写着 "leaving the field empty beats guessing"。
knowledgeCutoff 的采信来源规则
这是整套规则中最严格的部分。原始文档明确区分了"可采信"与"必须拒绝"两类来源:
可采信来源
- 厂商官方文档(platform.openai.com / developers.openai.com、docs.x.ai、ai.google.dev、docs.anthropic.com / platform.claude.com)
- 官方 Hugging Face 组织的模型卡(如 huggingface.co/meta-llama/... 之类)
- 官方技术报告 / system card / 发布博客
必须拒绝的来源
- 第三方聚合站(aiknowledgecutoff.com 及类似站点)。文档给出的实证案例:一次针对 Cohere 的扫描曾把
2024-06抄给了四个不同的基础模型,而所引用的 Cohere 页面没有任何一处这么写;Cohere 实际公布过的唯一截止时间是 08-2024 Command R/R+ 刷新版的 2023 年 2 月。聚合站的典型错误模式是把一个模型的值复制到整个家族。 - AWS Bedrock 模型卡作为唯一来源。实证案例:DeepSeek R1 的 Bedrock 卡片把发布日期和知识截止时间都写成 "Jan 2025",二者被混为一谈。规则是:如果一个值只出现在 Bedrock,字段就留空。
- 从
releasedAt推断——发布日期不是知识截止时间。
变体继承规则
以下几类模型变体共享基础模型的截止时间:
- 带日期的快照(
-2024-08-06) - 同一 checkpoint 的速度/价格档位
- 量化版本(
-fp8、-awq) - 上下文长度变体(
-32k) - ollama 的
:NNb标签 - 云前缀 id(Bedrock 的
anthropic./us./global.前缀)
但有两个重要的"不继承/不统一"例外:
- 蒸馏模型(distill)不继承教师模型或基础模型的截止时间——使用蒸馏模型自己公布过的值,否则留空;
- 同一世代内不同尺寸模型的截止时间可能真实不同:例如 Llama 3 8B 是 2023 年 3 月,而 70B 是 2023 年 12 月(按 Meta 自己的模型卡)。不要为了"看起来整齐"把它们统一成同一个家族级数值。
对于完全不公布截止时间的厂商,文档列出了"不追、留空"清单:Qwen、DeepSeek、GLM/智谱、ERNIE、Doubao、Hunyuan、SenseNova、Spark、MiniMax、StepFun、Yi(大部分)、Moonshot。
各厂商已知易错点(footguns)
- Anthropic:Opus 4.6 的 reliable 截止时间是
2025-05,Sonnet 4.6 是2025-08——两者极易填反。Claude 3.7 是2024-10(system card 写明训练数据到 2024 年 11 月,知识截止为 2024 年 10 月底)。引用时用 system card 或 models overview 页,而不要用 Help Center 文章——后者是活页,退役模型会被移除,产生引用腐化(citation rot)。仓库中 anthropic.ts 的 12 条knowledgeCutoff条目(如2025-05、2025-08、2024-10附近的历史值)就是这套规则应用后的实际数据。 - xAI:docs.x.ai 只有一句话笼统覆盖 grok-3/grok-4,mini 变体并未被点名;Grok 4.20/4.3 在任何官方渠道都没有截止时间,应留空。
- OpenAI:按模型的文档页(developers.openai.com/api/docs/models/<id>)会显式给出截止时间,且区分快照差异——例如
gpt-4-1106-preview是2023-04,而gpt-4-0125-preview是2023-12。
family / generation 的派生规则
与 knowledgeCutoff 不同,family 和 generation 是纯规则派生,不需要外部调研。规则集中存放在 derive-family.ts 中,按厂商分块实现了逐族的正则规则。该脚本先剥掉云/Bedrock 前缀再做匹配:
// 先剥掉 us./global./eu./apac. 地域前缀与 anthropic./meta./cohere./azure- 厂商前缀
const m = id.replace(/^(us\.|global\.|eu\.|apac\.)?(anthropic\.|meta\.|cohere\.|azure-)/, '');
文档特别强调:扩展规则时必须保留已经编码进去的"陷阱处理"。这些陷阱在源码中一一对应:
- 日期后缀不是版本号:
claude-sonnet-4-20250514的世代是claude-4而不是claude-4.2。源码用(?!\d)负向前瞻保证claude-opus-4-8匹配到claude-4.8类格式、而四位日期不会被误吞(derive-family.ts L24-L31)。 - 尺寸后缀不是版本号:
llama-3-8b派生为llama-3(不是llama-3.8);gemma-7b-it是 gemma-1(不是 gemma-7),源码中gemma-?\db的分支专门处理这一代无显式版本号只有尺寸命名的情况(L60-L63)。 - 厂商拼写变体:
qwen2p5= qwen2.5、llama-v3p1= llama-3.1、ollama 的:NNb标签、Bedrock 的us./global./anthropic.前缀,各有对应的正则分支。 claude-X.0归一化为claude-X:源码中g[2] === '0'时直接返回claude-${g[1]}(L28-L29)。- Fable/Mythos 类 id 不匹配 opus/sonnet/haiku 的正则——它们属于 Mythos 类,需手动填
family: 'claude-mythos'、generation: 'mythos-5'(发布页称 Fable 5 为 "the generally available Mythos-class model")。仓库数据中可以看到手工填写的实际结果(anthropic.ts L52-L56):
displayName: 'Claude Fable 5',
family: 'claude-mythos',
generation: 'mythos-5',
id: 'claude-fable-5',
脚本还支持两种运行模式:不带参数时打印去重后的 {family :: generation} 配对供人工审查;带 --emit 时把结果写出为 /tmp/family-map.json 供后续 codemod 消费(L234-L236)。
全仓扫描(sweep)工作流
当需要对全部约 80 个 provider 数据文件、约 1900 条模型条目做一次元数据补全时,原始文档定义了五步工作流。以下每步都标注了仓库中的实际脚本位置。
第 1 步:提取模型 ID
bun .agents/skills/model-bank-metadata/scripts/extract-model-ids.ts [out.json]
extract-model-ids.ts 动态导入 packages/model-bank/src/aiModels/ 下每个 .ts 数据文件的默认导出,只保留 type: 'chat' 的条目(图像/视频/embedding/TTS 模型没有知识截止时间,直接跳过),归一化规则是"取 id 最后一段路径并小写"(例如带 Bedrock 前缀的 id 只保留尾部真实模型名),去重后排序写出 JSON(默认 /tmp/model-ids.json),并打印 N unique normalized chat ids。注意:这个归一化规则与两个 apply codemod 完全一致,是三个脚本能互相配合的前提。
第 2 步:多 Agent 调研 + 对抗性核验
把第 1 步产出的 id 按家族分块(每块 ≤50 个),为每块扇出一个调研 Agent(用 Workflow 工具),要求每块返回 {id, cutoff, source},且把上文的来源采信规则原样注入 prompt。同时每块配一个对抗性核验(adversarial verify)Agent,重新抓取被引用的来源页面、专门反驳没有依据的断言。
文档特别指出:核验环节是承重墙(load-bearing)——正是它抓出了 Cohere 聚合站的复制粘贴错误和 AWS Bedrock 把发布日期当截止时间这两类错误。省略这一步,错误数据会被第 4 步的 codemod 放大到全仓。
第 3 步:来源策略过滤
在应用之前,先丢弃"唯一来源属于被拒类别"的条目(检查返回的 sources 映射,例如所有 source 指向 aws.amazon.com 的条目整批剔除)。这一步防止第 2 步中"确实有来源、但来源不合格"的条目混入。
第 4 步:幂等 codemod 批量写入
# 从仓库根目录运行
bun .agents/skills/model-bank-metadata/scripts/apply-cutoffs.ts <cutoff-map.json>
bun .agents/skills/model-bank-metadata/scripts/apply-family.ts <family-map.json>
两个写入脚本都是以归一化 id 为键的幂等 codemod:
- apply-cutoffs.ts 把
{normalizedModelId: 'YYYY-MM'}映射插入到每个匹配的 chat 条目中id:行之后的knowledgeCutoff字段(L49-L58)。它只处理"是 chat 类型、且尚无该字段"的条目,对 cutoff 值本身做/^\d{4}(?:-\d{2})?$/格式校验;运行结束打印inserted N ... across M files、映射键命中比例,并列出未命中的映射键(前 20 个)供排查。 - apply-family.ts 把
family(以及可选的generation)插入到id:行之前,同样是跳过已有family:字段的条目。
两个脚本都依赖这些数据文件统一的 prettier 排版:每个模型条目以 {(2 空格缩进)开始、以 }, 结束,字段位于 4 空格缩进处( id: '...')。这也是为什么 codemod 能按纯文本块解析而不需要完整 AST 解析。由于 codemod 按归一化 id 匹配,聚合商 provider(openrouter 等)引用的同一模型会自动获得相同值。
第 5 步:验证
cd packages/model-bank && bunx vitest run src/aiModels/__tests__/index.test.ts && bunx tsc --noEmit
用 aiModels 索引测试 加 tsc --noEmit 双重把关,确认 codemod 没有破坏数据文件的语法与类型。
日常维护规则
文档最后给出三条面向日常协作的维护规则,全部有实战教训支撑:
-
新模型 PR 应三个字段一次性填全,并在 PR 描述中引用官方来源。可参照 anthropic.ts 中的条目作为参考值与填写格式。
-
解决 model-bank 数据文件的合并冲突后,必须做元数据丢失自检:在冲突解决前后分别运行
git grep -c knowledgeCutoff -- 'packages/model-bank/src/aiModels/*.ts'对比计数。文档给出的教训:一次三个模型 PR 的三方堆叠合并曾在冲突解决过程中静默丢掉全部 10 条 Anthropic 的 cutoff——因为丢失的字段不会导致测试失败,
vitest+tsc都发现不了,只有计数对比能兜住。 -
聚合商数据中存在脏 id:曾有某个 sambanova 的 id 携带了一个不可见的尾部制表符。codemod 是按 id 逐字匹配的——如果某个映射键应用不上,先检查不可见字符,再下结论说该模型不存在。这与 apply 脚本结尾打印 "unused map keys" 的设计相配套。
小结
这套元数据维护流程的核心取舍可以概括为三句话:knowledgeCutoff 只信官方来源,宁空勿猜;family/generation 走规则派生,陷阱编码进正则;全仓更新用幂等 codemod,验证靠测试加计数对比。 仓库内的技能脚本(extract-model-ids.ts、derive-family.ts、apply-cutoffs.ts、apply-family.ts)与 types/aiModel.ts 中的字段定义、repositories/aiInfra/index.ts 的读取时合并机制共同构成了这条链路的完整证据:新卡片字段无需迁移即可到达客户端,而数据质量完全由"来源规则 + 幂等写入 + 计数自检"三道关卡保证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00