AI SDK 官方文档站(ai-sdk.dev)技术架构与实践:基于 Geistdocs 的多版本文档应用构建指南
2026/9/11 19:59:42 网站建设 项目流程

AI SDK 官方文档站(ai-sdk.dev)技术架构与实践:基于 Geistdocs 的多版本文档应用构建指南

【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai

本文面向希望了解或复刻 AI SDK 官方文档站点实现方式的开发者。AI SDK(The AI Toolkit for TypeScript)的官方文档站是一个基于 Vercel Geistdocs 框架构建的包级应用,托管于仓库的apps/docs目录,负责ai-sdk.dev的文档、Providers、Cookbook 等全部内容面。读完本文,你将掌握该文档应用的本地开发流程、三版本(v5/v6/v7)内容同步管线的完整原理、Geistdocs 多版本路由配置、Vercel 部署要点,以及 llms.txt、站点地图与社交卡片等面向搜索引擎与 LLM 的 SEO 基建实现。

一、应用定位:一个由包驱动的文档站

apps/docs是仓库中的一个独立包(package name 为ai-sdk-docs),其核心定位在 apps/docs/README.md 中写得很清楚:

This is the package-backed Geistdocs application forai-sdk.dev.

所谓"package-backed",意味着文档站的依赖、脚本和构建配置全部收拢在这个包内,与仓库中content/目录的原始文档源相互独立。文档站本身并不直接消费content/下的 MDX 文件,而是先通过内容同步脚本把源文件变换并拷贝apps/docs/content/生成目录,再由 Geistdocs/Fumadocs 消费。

从 apps/docs/package.json 可以看到其技术栈:

  • 框架:Next.js 16.2.12 + React 19.2.3,使用@vercel/geistdocs1.20.4 作为文档框架;
  • 文档管线fumadocs-core/fumadocs-mdx/fumadocs-ui负责 MDX 编译与 UI;
  • 代码高亮shiki3.23.0 配合@shikijs/langs@shikijs/transformers
  • 其他zod(配置与 Frontmatter 校验)、lucide-react(图标)、@vercel/analytics(站点分析)。

二、本地开发:三步起一个文档站

README 明确要求使用Node.js 22 或更新版本,并在仓库根目录执行命令:

pnpm install pnpm --filter ai-sdk-docs dev:site

其中dev:site脚本(见 apps/docs/package.json)实际上是三件事的串联:

"dev:site": "pnpm sync-content && fumadocs-mdx && next dev"
  1. pnpm sync-content:执行内容同步脚本,把多版本文档源变换到apps/docs/content/
  2. fumadocs-mdx:生成 Fumadocs 的 MDX 集合配置;
  3. next dev:启动 Next.js 开发服务器。

因此,如果你直接运行next dev而跳过前两步,站点会因为缺少content/目录而无法渲染页面——这也是 README 强调"内容同步生成apps/docs/content/"的原因。

完整本地校验

运行完整的本地校验命令:

pnpm --filter ai-sdk-docs validate:site

它等价于先跑单测再跑生产构建:

"test:site": "node --test scripts/*.test.mjs", "build:site": "pnpm sync-content && fumadocs-mdx && next build", "validate:site": "pnpm test:site && pnpm build:site"

其中test:site使用 Node 内置的node --test运行scripts/*.test.mjs(当前为 sync-content-utils.test.mjs),对内容变换工具函数做单元测试。

另外需要注意:生成后的内容(apps/docs/content/)、Fumadocs 源文件和 Next.js 构建输出均被 Git 忽略,不会提交进仓库,每次构建都从源重新生成。

三、内容同步管线:三版本文档的单一事实来源

这是整个文档应用最核心的机制。同步脚本 apps/docs/scripts/sync-content.mjs 从三个经过评审的来源拉取内容:

版本来源说明
v7当前工作区的content/docs/即仓库main分支的实时内容
v6固定 commit31e168b16f71a2abc03a1fae69176886577337f4在脚本中显式 pin 的 SHA
v5固定 commit1319452c1f1a75045950817242ef3207dac1e540同上

脚本头部注释明确解释了 pin 版本的目的:"Pinning keeps builds reproducible and content changes reviewable"(固定 commit 保证构建可复现、内容变更可评审)。这意味着 v6/v5 的稳定文档不会跟随 v7 主线的每次修改而漂移,只有在明确更新 SHA 时才会发布新的维护版文档。

同步的内容家族

脚本遍历families = ["docs", "providers", "cookbook"]三个内容家族,对应仓库根目录的content/docscontent/providerscontent/cookbook。对每个版本 × 家族组合,输出到:

apps/docs/content/{v5|v6|v7}/{docs|providers|cookbook}

例如 v7 文档最终位于apps/docs/content/v7/docs,这正是 apps/docs/geistdocs.tsx 中content配置所指向的目录。

拉取策略:git 优先,tarball 兜底

fetchRef函数为固定 commit 提供了三层回退策略(sync-content.mjs第 60-86 行):

  1. origin 远程git fetch --depth=1 origin <ref>后用git archive FETCH_HEAD content | tar -x解出content/
  2. 本地 git 对象:直接git archive <ref> content(适合仓库已包含该对象的情况);
  3. GitHub tarballcurl -sfL https://codeload.github.com/vercel/ai/tar.gz/<ref>下载并解压(为无 git 访问权限的环境兜底)。

拉取结果缓存于apps/docs/node_modules/.cache/ai-sdk-docs,第二次运行直接使用缓存;需要强制刷新缓存时传--force参数:node scripts/sync-content.mjs --force

四、内容变换规则:从NN-前缀到 Fumadocs 的完整映射

原始内容(仓库content/目录)使用NN-数字前缀组织目录与文件名(例如02-foundations),而 Fumadocs 需要干净的 slug。变换逻辑集中在 apps/docs/scripts/sync-content-utils.mjs,共 4 步:

1. 剥离NN-数字前缀并生成 meta.json

parseSegment用正则/^(\d+)-(.+)$/解析路径段,transformDir递归遍历并按数字前缀排序,为每个目录生成meta.jsonpages数组即排序后的干净文件名列表)。同时处理两个特殊场景:

  • collapsed: true:目录index.mdx的 Frontmatter 若标记collapsed: true,则在 meta.json 中写入"defaultOpen": false,使侧边栏默认折叠;
  • 前缀冲突检测:如果两个文件剥离前缀后撞名(如01-foo.mdx02-foo.mdx),脚本会直接抛错,防止生成不可预测的路由。

2. 丢弃 index.mdx,避免重复的 Overview 页面

如果目录内同时存在index.mdxoverview.mdx,则丢弃index(它曾是旧站点的卡片网格落地页)。原因是 Geistdocs 会把文件夹索引页渲染为侧边栏中合成的 "Overview" 项,从而与真实的 Overview 页面重复。被丢弃 index 的 Frontmatter 信号(如collapsed)仍会保留到目录的 meta.json。纯 Frontmatter 的 index 页(Cookbook 各章节)同理被丢弃,因为旧应用从未渲染它们。

3. 剥离正文首个# H1

Geistdocs 用 Frontmatter 的title作为页面 H1,因此stripLeadingH1会把 MDX 正文开头(Frontmatter 之后)的第一个# 标题行删除,避免重复标题。

4. 代码围栏 meta 重写与遗留链接修复

rewriteLines处理代码块的展示约定:

原始写法变换后说明
```ts filename="x"```ts title="x"filename/file→ Fumadocs 的title
highlight="1,3-5"{1,3-5}高亮行 →transformerMetaHighlight语法
```typescript"```typescript清理围栏语言后的多余引号
```prompt/```env/```regotxt/dotenv/txt重映射 Shiki 未内置的语言

同时,rewriteLegacyLinks会把旧版锚点批量重定向到新锚点,例如#ui-message-stream-protocol#data-stream-protocol#multi-modal-messages#file-parts#attachments-experimental#attachments等共 10 组映射,保证存量外链不失效。addLegacyAnchors还为streamTextOutputTelemetry等特殊页面插入<span id="..."/>形式的兼容锚点。

变换后的渲染配置

变换产出的{1,3-5}高亮 meta 由 apps/docs/source.config.ts 中的transformerMetaHighlight()消费;文档集合通过defineDocs注册,并启用includeProcessedMarkdown: true以输出处理后的 Markdown(供 llms.txt 等场景使用)。

五、多版本路由:Geistdocs 版本化配置

版本切换与路由挂载完全由 apps/docs/geistdocs.tsx 声明:

  • 站点身份title = 'AI SDK'siteId = 'ai-sdk'用于向 Geistdocs 平台上报反馈问题(feedback)与 markdown 请求追踪;
  • 导航:Docs、Resources(Recipes / Tools Registry / Templates / Showcase)、Providers 三大导航入口;
  • 内容集合:共 9 个集合(v5/v6/v7 × docs/providers/cookbook),v7 挂载在无前缀路由(/docs/providers/cookbook),v6/v5 分别挂载在/v6/v5前缀下;
  • 版本列表current: 'v7',v6 描述为 "v6 maintenance documentation",v5 为 "v5 maintenance documentation",版本切换 UI 由此驱动。

路由重定向矩阵

apps/docs/next.config.ts 中配置了大量重定向,核心规则包括:

  • v4 归档/v4/v4/:path*永久重定向到独立的 v4 归档站(v4 不纳入本应用构建,以控制内存占用);
  • v7 无前缀化/v7//v7/:path*/:path*
  • 章节落地页折叠/docs/:section(基础章节)/重定向到对应的overview页(与内容同步丢弃 index.mdx 的行为呼应,见 sync-content-utils.mjs);
  • 遗留资源 URL/tools-registry/resources/tools/showcase/resources/showcase/elements→ 独立站点、/model-library→ Vercel AI Gateway 文档;
  • Cookbook 双表面/cookbook/resources/recipes均可用,章节落地页(如/cookbook/node)重定向到该章节第一篇菜谱generate-text
  • 内容迁移/docs/ai-sdk-core/prompts/docs/foundations/promptsvalidate-json-rpc-messagecreate-mcp-client

这些重定向的目标是完全镜像生产站 ai-sdk.dev 的 URL 行为,保证搜索引擎收录的旧链接全部可达。

六、Vercel 部署:外部源码目录与构建命令

README 的 "Vercel project" 一节明确了三个关键配置:

配置项原因
Root Directoryapps/docs以文档包为部署根
Include source files outside the Root Directoryenabled内容同步需要读取仓库根目录的content/docs/与 Git 元数据
Node.js仓库支持的版本README 要求本地 Node.js 22+,部署环境同样需要满足

第二个设置至关重要:由于构建脚本会从仓库根目录的content/同步内容,并执行git fetch/git archive操作,Vercel 必须在构建镜像中包含根目录源码与.git元数据。

apps/docs/vercel.json 补充了部署策略:

{ "buildCommand": "pnpm build:site", "git": { "deploymentEnabled": { "release-v*": false, "changeset-release/release-v*": false, "changesets-ghcommit-temp/**": false, "backport-pr-*": false } } }

即发布分支(release-v*等)不触发自动部署,避免中间态发布到生产。

七、面向搜索引擎与 LLM 的基建

README 提到"镜像生产环境",这背后是一整套可被搜索引擎与 LLM 消费的产物:

llms.txt 与 Markdown 代理

apps/docs/proxy.ts 使用 Geistdocs 的createProxy将文档 URL 映射到llms.mdx渲染路由。每个 URL 面(/docs/*/v6/docs/*/providers/*/cookbook/*/resources/recipes/*)都对应一个[lang]/...-llms.mdx路由,为 Agent/LLM 提供纯 Markdown 版本的页面内容。目录中同时存在app/[lang]/llms.txt/route.tsapp/[lang]/sitemap.md/route.ts,即标准化的llms.txt索引与可读站点地图。

双 URL 表面与 canonical

每条 Cookbook 菜谱同时服务在/cookbook/.../resources/recipes/...两个 URL 面,而sitemap、llms.txt 与搜索 canonical 统一指向/cookbook,避免重复内容影响 SEO 权重。

社交卡片(Open Graph 图片)

社交卡片由app/[lang]/og/[...slug]/route.tsx渲染(对应 README 中的路径),同时支持两种 URL 形态:

  • Geistdocs 形态:/og/<slugs>/image.png
  • 遗留生产形态:/og/docs?title=…&description=…(查询参数形态)。

该路由(见 apps/docs/app/[lang]/og/[...slug]/route.tsx)只对**当前版本(v7)**的三个源(docs/providers/cookbook)生成卡片,维护版本(v5/v6)是 noindex 且无卡片。实现上使用 Next.jsImageResponse,对标题(140 字符)与描述(320 字符)做截断以控制渲染成本,并通过两种缓存策略优化 CDN 命中:查询参数形态(URL 随内容变化)使用immutable缓存一年,slug 形态(URL 稳定)让浏览器每次 revalidate、CDN 缓存一年。

八、第三方 Logo 的版权边界

README 最后说明public/images/中的第三方资源:

  • public/images/icons/:Providers 索引页上的第三方提供商 Logo(提名性使用);
  • public/images/showcase/:Showcase 页面的产品截图与 Logo;
  • components/docs/upsell.tsx:内联的客户 Logo。

这些标识属于各自所有者,不涵盖在本仓库的开源许可范围内。若你复刻此文档站,需要注意保留该版权声明并遵守各 Logo 的使用条款。

九、实践要点总结

  • 本地开发三步pnpm installpnpm --filter ai-sdk-docs dev:site,Node.js 需 22+;
  • 内容同步是三段式:拉取(git archive / tarball 兜底)→ 变换(剥前缀、去 H1、改围栏 meta、修链接)→ 输出到apps/docs/content/{v5,v6,v7}/,产物不入 Git,缓存可--force刷新;
  • 多版本靠 Geistdocs 声明式配置geistdocs.tsxcontentversions是唯一事实来源,重定向矩阵在next.config.ts中镜像生产行为;
  • 部署关键在"外部源码":Vercel 必须开启 "Include source files outside the Root Directory",否则同步脚本无法读取根目录content/
  • SEO/LLM 基建分层llms.txt+ Markdown 代理 + 双 URL canonical 归一到/cookbook+ v7-only 社交卡片。

若想深入源码,建议依次阅读 apps/docs/scripts/sync-content.mjs(同步主流程)、apps/docs/scripts/sync-content-utils.mjs(变换规则与测试对象)、apps/docs/geistdocs.tsx(站点配置)以及 apps/docs/next.config.ts(重定向矩阵),它们共同构成了 ai-sdk.dev 这套"内容源与文档应用解耦、多版本可复现构建"的完整工程方案。

【免费下载链接】aiThe AI Toolkit for TypeScript. From the creators of Next.js, the AI SDK is a free open-source library for building AI-powered applications and agents项目地址: https://gitcode.com/GitHub_Trending/ai/ai

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询