执行摘要
- 一句话:文档导航统一为纯标签分组、Overview 落地页、链接色收窄
- 推荐动作:值得快速浏览:本 PR 是文档工程化的不错样板 —— 把导航语义写成『生成器 + 钩子 + 约定文档 + 单测』四件套,并用页面数与 broken links 守恒作为自证回归证据。不需要精读源码;值得关注的决策点包括:用
sidebarTitle 分离 h1/SEO 标题与侧边栏短标签、以纯标签分组消灭『可点击与不可点击标题』的不一致、以及 pygrep 钩子一行代码锁死配置契约。后续维护者需留意 SECTION_DIRS 硬编码与生成器/手写双轨配置的扩展点。
功能与动机
PR body 给出的核心动机是让侧边栏行为遵循一条可读的规则:"Makes the docs sidebar behave by one legible rule: section headers are labels, rows are pages, and the only collapsible items are the Models family catalogs." 具体要解决三个问题:未加作用域的 a 链接颜色规则压过 Mintlify 的 layered Tailwind 颜色,把侧边栏/标签栏/页内 TOC 全刷成橙色并掩盖当前页高亮;带 root 的分组标题会跳转、无 root 的只折叠,点击前无法区分;导航结构层级不统一(单分组 tab 也套了一层 groups)。无关联 Issue,设计说明全部由 PR body 承担。
实现拆解
- 链接颜色作用域收窄(docs/style.css):三条规则
a、a:hover、a[href^="http"]::after 分别改为 .mdx-content a、.mdx-content a:hover、.mdx-content a[href^="http"]。原因是未作用域的 a 规则属于 unlayered 层,会压过 Mintlify 的 layered Tailwind 颜色,把侧边栏、tabs、页内 TOC 全部刷成品牌橙 #d55816;收窄后自定义颜色与站外链接 ↗ 标记只作用于正文容器。
- 导航配置重构(docs/docs.json,+97/-143):移除所有导航分组
root 键,模型家族各组(DeepSeek、Thinking Machines、Qwen、GLM、Kimi、Nemotron、Gemma)的 index 页降为各组 pages 首项,gpt-oss 等单页直接挂到 Models 根组之下;Welcome、Resources、FAQ 三个单分组 tab 从 groups 包装扁平化为顶层 pages;User Guide 的 Launch Script 两页分组被扁平化(页面标题从 "Structure and Usage" 改回 "Launch Script");Advanced Features 与 Developer Guide 内的 Performance、Scale & Reliability、MoE & Routing、CI 等子组全部静态展开,仅 Models 家族保留 expanded: false 折叠。附带变更:navbar 新增 "Contact" 主按钮(mailto:miles@radixark.ai)。
- 同步脚本语义升级(scripts/tools/sync_example_docs.py):新增
SECTION_DIRS = ("infra_features",) 常量标记纯标签分组目录;render_page 通过 landing = rel_dir == "" or rel_dir in SECTION_DIRS 判定 landing 页,命中则注入 sidebarTitle: "Overview",title 保留完整值供 h1/SEO;build_navigation 从返回带 root/expanded 的 group 字典改为返回 entries 列表(examples/index 恒为首项,随后是不带 root 的 "Recipes"、"Infra Features" 分组,且 infra landing 页作为分组第一行);main() 相应改为 tab.pop("groups", None) 后写 tab["pages"]。
- Landing 页批量打标(各 index.md):
docs/index.md(title 从 "Miles Documentation" 改为 "Welcome" 并新增 sidebarTitle)、docs/models/{deepseek,gemma,glm,kimi,nemotron,qwen,thinkingmachines}/index.md、docs/advanced/index.md、docs/developer/index.md、docs/examples/index.md 等 frontmatter 统一追加 sidebarTitle: Overview。
- 回归防护三件套:
docs/README.md 新增两段约定(landing 页 title 面向 h1/浏览器/搜索、sidebarTitle 是恒定字段名;禁止分组 root,正确做法是 landing 页作为 pages 首项);.pre-commit-config.yaml 新增 pygrep 钩子 ban-docs-nav-group-root(entry "root":,files 限定 ^docs/docs\.json$);tests/fast/doc/test_sync_example_docs.py 更新 test_navigation_follows_bullet_order 断言并新增 test_section_directory_becomes_rootless_group_with_landing_first,既有漂移门禁 test_docs_examples_matches_the_readmes(--check)保持不变,保证生成结果与提交内容一致。
关键文件:
scripts/tools/sync_example_docs.py(模块 同步脚本;类别 source;类型 core-logic;符号 SECTION_DIRS, render_page, build_navigation, main): Examples tab 导航生成器,随本次约定同步升级:build_navigation 改为输出无 root 的 pages 列表(index 首项 + 纯标签分组),render_page 对 landing 页注入 sidebarTitle: Overview,main() 从写 groups 改为写 pages。
docs/docs.json(模块 导航配置;类别 config;类型 configuration): 导航契约本体,改动量最大(+97/-143):移除全部导航分组 root、扁平化单分组 tab、各 landing 页提升为 pages 首项,仅 Models 家族保留可折叠嵌套分组,并附带 navbar 新增 Contact 按钮。
tests/fast/doc/test_sync_example_docs.py(模块 同步测试;类别 test;类型 test-coverage;符号 test_section_directory_becomes_rootless_group_with_landing_first, test_navigation_follows_bullet_order): 更新 build_navigation 断言以适配新的 entries 结构(index 首项 + 无 root 分组),并新增 test_section_directory_becomes_rootless_group_with_landing_first 验证 section 目录 landing 页作为分组第一行出现。
.pre-commit-config.yaml(模块 提交钩子;类别 config;类型 configuration): 新增 ban-docs-nav-group-root pygrep 钩子,从提交层面禁止 docs.json 中任何导航分组 root 键回归,是约定能否长期执行的保障。
docs/style.css(模块 站点样式;类别 other;类型 core-logic): 修复全局 a 规则把侧边栏、tabs、页内 TOC 刷成橙色并掩盖活动页高亮的问题:链接颜色与站外链接 ↗ 标记限定在 .mdx-content 正文容器内。
docs/README.md(模块 文档约定;类别 docs;类型 documentation): 固化导航约定的规范源:landing 页命名与 sidebarTitle 约定、禁止 root 的说明,是同步脚本与 pre-commit 钩子背后的设计依据。
docs/index.md(模块 站点首页;类别 docs;类型 documentation): 站点首页作为 landing 页约定的示范:title 从 Miles Documentation 改为 Welcome,并新增 sidebarTitle: Overview。
关键符号:build_navigation, render_page, main, parse_index, test_section_directory_becomes_rootless_group_with_landing_first, test_navigation_follows_bullet_order
关键源码片段
scripts/tools/sync_example_docs.py
Examples tab 导航生成器,随本次约定同步升级:build_navigation 改为输出无 root 的 pages 列表(index 首项 + 纯标签分组),render_page 对 landing 页注入 sidebarTitle: Overview,main() 从写 groups 改为写 pages。
# 需要渲染为纯标签侧边栏分组的目录:目录自己的 README 作为分组第一行
# (侧边栏显示 Overview),而不是作为 group `root` —— root 会使分组标题
# 变成可点击链接,与纯折叠分组外观无法区分(已被 pre-commit 禁止)。
SECTION_DIRS = ("infra_features",)
def render_page(title, description, rel_dir, body):
source = f"{repo_dir_of(rel_dir)}/README.md"
# 只有 tab 首页(rel_dir == "")与 section 目录首页写入 sidebarTitle:
# 页面保留完整 title(供 h1 / SEO),侧边栏统一显示短标签 Overview。
landing = rel_dir == "" or rel_dir in SECTION_DIRS
sidebar = 'sidebarTitle: "Overview"\n' if landing else ""
return (
"---\n"
f"title: {json.dumps(title, ensure_ascii=False)}\n"
f"{sidebar}"
f"description: {json.dumps(description, ensure_ascii=False)}\n"
f"# Generated from {source} by scripts/tools/sync_example_docs.py. Edit that README, not this file.\n"
"---\n"
f"{body}\n"
)
def build_navigation(pages, bullet_order):
"""生成 Examples tab 的 pages 列表:index 最前,随后是纯标签分组。
侧边栏顺序遵循 examples/README.md 的 bullet 顺序(README 拥有排序、
标题与描述);没有 bullet 的目录排最后、按字母序。返回的 entries
不含任何 group `root` —— Examples tab 在 main() 里直接写入
tab["pages"],而不再包一层 groups。
"""
rank = {rel_dir: i for i, rel_dir in enumerate(bullet_order)}
recipes, infra = [], []
for rel_dir in sorted(pages, key=lambda d: (rank.get(d, len(rank)), d)):
if not rel_dir:
continue
page = f"examples/{slug_for(rel_dir)}"
# infra_features 目录归入 Infra Features 分组,其余全部归入 Recipes
(infra if rel_dir.startswith("infra_features") else recipes).append(page)
entries = ["examples/index"]
entries.append({"group": "Recipes", "pages": recipes})
if infra:
infra_root = "examples/infra-features"
children = [p for p in infra if p != infra_root]
# landing 页作为分组第一行出现,分组自身不设 root、不设 expanded
entries.append({"group": "Infra Features", "pages": [infra_root] + children})
return entries
docs/style.css
修复全局 a 规则把侧边栏、tabs、页内 TOC 刷成橙色并掩盖活动页高亮的问题:链接颜色与站外链接 ↗ 标记限定在 .mdx-content 正文容器内。
/*
* 链接颜色只作用于正文容器 .mdx-content:未加作用域的 a 规则属于
* unlayered 层,会压过 Mintlify 的 layered Tailwind 颜色,把侧边栏、
* tab 栏、页内 TOC 全部刷成橙色,并掩盖当前页高亮。收窄后自定义
* 颜色只出现在正文内容区。
*/
.mdx-content a {
color: #d55816;
text-decoration-thickness: 1px;
text-underline-offset: 3px;
}
.mdx-content a:hover {
text-decoration-thickness: 2px;
}
/* 站外链接自动追加 ↗ 符号,同样限定在正文容器内 */
.mdx-content a[href^="http"]:not([href*="radixark.com"])::after {
content: "↗";
margin-left: 0.15em;
font-size: 0.7em;
}
评论区精华
该 PR 全程零讨论:无 issue 评论、无 PR 评论、无行内 review 评论,reviewer Zhichenzzz 直接给予空 body 的 APPROVED。设计决策由作者在 PR body 中完整自述,并以四重机制(同步脚本 + pre-commit 钩子 + docs/README.md 约定 + 单元测试)固化,弥补了缺乏评审交锋的审查盲区。回归证据同样由 PR body 自我声明:页面总数 96 不变,mint broken-links 与 main 持平(25 个存量)。
风险与影响
- 风险:
- pre-commit 规则一刀切(.pre-commit-config.yaml):
ban-docs-nav-group-root 以 pygrep 精确匹配 "root": 键,当前不会误伤其他键;但若未来 Mintlify 导航 schema 或文档站自身需要合法 root 用途,该钩子会直接拦截,需要调整匹配范围。
- 生成器与手写配置双轨(scripts/tools/sync_example_docs.py vs docs/docs.json):Examples tab 完全由生成器接管,
main() 现在显式 tab.pop("groups", None) 并写入 pages,手改 Examples 段会被 --check 漂移门禁拦截;而 User Guide/Advanced 等 tab 仍为手写,两套来源并存,语义必须保持一致。
- SECTION_DIRS 硬编码:
("infra_features",) 写死,未来新增 section 类目录(如把某组升级为纯标签分组)必须同步改代码,否则该目录会被静默归入 Recipes 分组,产生与期望不符的导航。
- CSS 依赖 Mintlify DOM(docs/style.css):
.mdx-content 是 Mintlify 生成的容器类名,若平台改版导致类名变化,正文链接颜色与 ↗ 标记会静默失效(不破坏布局但丢失定制样式)。
- 导航语义变化对读者的影响:所有分组标题不再可点击、落地页变成显式 "Overview" 行,习惯点击分组标题跳转的读者需要适应;URL 全部不变,无书签/外链破坏。
- 影响:影响范围限定在 docs 站点与文档维护工具链,不涉及训练、rollout、session 等任何运行时模块。对读者:侧边栏语义统一(标签不跳转、行才是页面)、活动页高亮恢复、站外链接 ↗ 与橙色仅出现在正文,导航可预期性明显提升。对团队:docs 贡献者必须遵守新约定(禁止 root、landing 页
sidebarTitle: Overview、Examples tab 由生成器独占),否则提交被 pre-commit 拦截或漂移测试失败;导航结构的增删改成本被工具化。页面数与 broken links 均无变化,说明这是一次无页面增删的纯结构重构。
- 风险标记:零 review 讨论, pre-commit 规则一刀切, SECTION_DIRS 硬编码, 生成器与手写配置双轨
关联脉络
- PR #2491 docs: nest Environments under User Guide, rename to Agentic Environments: 与本 PR 直接衔接:前者把环境文档迁入 User Guide 并更名 Agentic Environments,本 PR 将该组变为 User Guide 下的静态纯标签分组并保留其 landing 页语义。
- PR #2477 fix(docs): correct agentic rollout guidance: 同样大范围修改 docs/docs.json 与 user-guide 页面,本 PR 延续了同一导航文件的结构演进。
- PR #2484 docs: add disaggregated RL rollout guide: 新增 advanced 页面并同步 docs.json/advanced 索引,本 PR 将 advanced 下的子组扁平化,两者同处一个导航体系。
- PR #2383 [readme]: rewrite the README: 仓库近期文档体系整体整理(README 重写、examples 迁移、CI 文档化)脉络中的一环,本 PR 把导航语义变成可执行的工具化约定。
参与讨论