@rspress/plugin-llms

为 Rspress 站点生成 llms.txt 相关文件,使大模型可以更好地理解你的文档站。

安装

npm
yarn
pnpm
bun
npm add @rspress/plugin-llms -D

使用

1. 安装插件

在配置文件中写入以下的配置:

// rspress.config.ts
import { defineConfig } from '@rspress/core';
import { pluginLlms } from '@rspress/plugin-llms';

export default defineConfig({
  plugins: [pluginLlms()],
});

之后执行 rspress build 命令,在生成产物的同时,会在产物目录下根据导航栏、侧边栏生成 llms.txt llms-full.txt 和对应路由的 markdown 文件。

2. UI 展示

如果你希望阅读文档站的用户可以更多地调用大模型来阅读文档,可以通过 自定义主题 在页面顶部增加一个复制 Markdown 按钮,效果与本网站相同。

为所有页面增加顶部复制按钮,示例:

theme/index.tsx
import { getCustomMDXComponent as basicGetCustomMDXComponent } from '@rspress/core/theme';
import {
  LlmsContainer,
  LlmsCopyButton,
  LlmsViewOptions,
} from '@rspress/plugin-llms/runtime';

function getCustomMDXComponent() {
  const { h1: H1, ...mdxComponents } = basicGetCustomMDXComponent();

  const MyH1 = ({ ...props }) => {
    return (
      <>
        <H1 {...props} />
        <LlmsContainer>
          <LlmsCopyButton />
          {/* LlmsViewOptions 组件可根据需要添加  */}
          <LlmsViewOptions />
        </LlmsContainer>
      </>
    );
  };
  return {
    ...mdxComponents,
    h1: MyH1,
  };
}

export { getCustomMDXComponent };
export * from '@rspress/core/theme';

为指定页面增加复制按钮,示例:

docs/hello-world.mdx
# Hello world

<LlmsContainer>
  <LlmsCopyButton />
  <LlmsViewOptions /> {/* LlmsViewOptions 组件可根据需要添加  */}
</LlmsContainer>

这是一个示例文档。

选项

这个插件接受一个对象参数,类型如下:

  • 类型:
interface LlmsTxt {
  name: string;
  onTitleGenerate?: (context: {
    title: string | undefined;
    description: string | undefined;
  }) => string;
  onLineGenerate?: (page: PageIndexInfo) => string;
  onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}

interface MdFiles {
  mdxToMd?: boolean;
  remarkPlugins?: PluggableList;
}

interface LlmsFullTxt {
  name: string;
}
export interface Options {
  llmsTxt?: false | LlmsTxt;
  mdFiles?: false | MdFiles;;
  llmsFullTxt?: false | LlmsFullTxt;
  include?: (context: { page: PageIndexInfo }) => boolean;
  exclude?: (context: { page: PageIndexInfo }) => boolean;
}
  • 默认值:

当未开启 国际化 时,默认值为:

{
  llmsTxt: { name: 'llms.txt' },
  llmsFullTxt: { name: 'llms-full.txt' },
  mdFiles: true
}

当开启 国际化 时,会使用多组配置,默认值为:

[
  {
    llmsTxt: { name: 'llms.txt' },
    llmsFullTxt: { name: 'llms-full.txt' },
    mdFiles: true,
    include: ({ page }) => page.lang === config.lang,
  },
  // 根据 locales 配置自动生成其他语言
  {
    llmsTxt: { name: `${lang}/llms.txt` },
    llmsFullTxt: { name: `${lang}/llms-full.txt` },
    mdFiles: true,
    include: ({ page }) => page.lang === lang,
  },
  // ...
];

llmsTxt

  • 类型: false | LlmsTxt
import type { PageIndexInfo } from '@rspress/core';

export interface LlmsTxt {
  name: string;
  onTitleGenerate?: (context: {
    title: string | undefined;
    description: string | undefined;
  }) => string;
  onLineGenerate?: (page: PageIndexInfo) => string;
  onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}
  • 默认值: { name: 'llms.txt' }

是否生成 llms.txt 文件,或者通过 hooks 自定义生成 llms.txt 文件。

一个 llms.txt 文件的默认格式如下:

# {title}

> {description}

## {nav1.title}

- [{page.title}]({ page.routePath }): {page.frontmatter.description}

## {nav2.title}

- [{page.title}]({ page.routePath }): {page.frontmatter.description}

你可以通过 hook 对指定部分进行修改。

  • onTitleGenerate: 自定义生成 title 和 description 部分。
  • onLineGenerate: 自定义生成 md 文件的每一行。
  • onAfterLlmsTxtGenerate: 最后修改 llms.txt 文件的内容。

例如:

pluginLlms({
  llmsTxt: {
    onTitleGenerate: ({ title, description }) => {
      return `# ${title} - llms.txt

> ${description}

Rspress is a static site generator based on Rsbuild and it can generate llms.txt with @rspress/plugin-llms.
`;
    },
  },
});

对应的生成结果为:

# Rspress - llms.txt

> Rsbuild based static site generator

Rspress is a static site generator based on Rsbuild and it can generate llms.txt with @rspress/plugin-llms.

## guide

- [foo](/foo.md)

mdFiles

  • 类型: false | MdFiles
export interface MdFiles {
  mdxToMd?: boolean;
  remarkPlugins?: PluggableList;
}
  • 默认值: { mdxToMd: false, remarkPlugins: [] }

是否生成对应路由的 markdown 文件,当设置为 false 时,不会生成对应路由的 markdown 文件。

mdxToMd

  • 类型: boolean
  • 默认值: false

是否将 mdx 内容转换为 md 内容,如果启用,会将 mdx 文件通过一组默认策略转换为 md 文件,但可能会有一定的信息丢失。

remarkPlugins

  • 类型: PluggableList
  • 默认值: []

用户可以传入自定义的 remark plugins 来对 Markdown 的内容做一些修改。

llmsFullTxt

  • 类型: false | LlmsFullTxt
export interface LlmsFullTxt {
  name: string;
}
  • 默认值: { name: 'llms-full.txt' }

是否生成 llms-full.txt 文件,当设置为 false 时,不会生成 llms-full.txt 文件。

include

  • 类型: (context: { page: PageIndexInfo }) => boolean

是否生成时包含某些页面,一般用于精简 llms.txt。

  • 示例:

只为语言为英文的页面生成 llms.txt 等相关文件:

pluginLlms({
  llmsTxt: {
    name: 'llms.txt',
  },
  llmsFullTxt: {
    name: 'llms-full.txt',
  },
  include: ({ page }) => {
    return page.lang === 'en';
  },
});

exclude

  • 类型: (context: { page: PageIndexInfo }) => boolean

是否生成时排除某些页面,会在 include 之后执行。

  • 示例:

排除 /foo 路由下的单个页面:

pluginLlms({
  llmsTxt: {
    name: 'llms.txt',
  },
  llmsFullTxt: {
    name: 'llms-full.txt',
  },
  exclude: ({ page }) => {
    return page.routePath === '/foo';
  },
});

UI 组件选项

LlmsCopyButtonProps

  • 类型LlmsCopyButtonProps
interface LlmsCopyButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  textByLang?: Record<string, string>;
  text?: string;
}

textByLang

  • 类型Record<string, string>
  • 默认值{ en: 'Copy Markdown', zh: '复制 Markdown' }

根据对应语言替换按钮上的文本。

  • 示例
<LlmsCopyButton textByLang={{ en: 'Copy MD' }} />

text

  • 类型string
  • 默认值''

复制按钮上的文本,优先级比 textByLang 高。

LlmsViewOptionsProps

  • 类型LlmsViewOptionsProps
type Option =
  | {
      title: string;
      icon?: React.ReactNode;
      onClick?: () => void;
    }
  | {
      title: string;
      href: string;
      icon?: React.ReactNode;
    }
  | 'markdownLink'
  | 'chatgpt'
  | 'claude';

interface LlmsViewOptionsProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  options?: Option[];
  textByLang?: Record<string, string>;
  text?: string;
}

options

  • 类型Option[]
type Option =
  | {
      title: string;
      icon?: React.ReactNode;
      onClick?: () => void;
    }
  | {
      title: string;
      href: string;
      icon?: React.ReactNode;
    }
  | 'markdownLink'
  | 'chatgpt'
  | 'claude';
  • 默认值['markdownLink', 'chatgpt', 'claude']

自定义下拉菜单中的选项,默认支持 “复制 Markdown 链接”、ChatgptClaude

textByLang

  • 类型Record<string, string>
  • 默认值{ en: 'Open', zh: '打开' }

根据对应语言替换按钮上的文本。

text

  • 类型string
  • 默认值''

按钮上的文本,优先级比 textByLang 高。

同时生成多组 llms.txt

某些情况下,你可能生成多组 llms.txt,例如多语言站点。此时,你可以通过传入一个数组来实现。

  • 示例:
// rspress.config.ts
import { defineConfig } from '@rspress/core';
defineConfig({
  lang: 'en',
  plugins: [
    pluginLlms([
      {
        llmsTxt: {
          name: 'llms.txt',
        },
        llmsFullTxt: {
          name: 'llms-full.txt',
        },
        include: ({ page }) => page.lang === 'en',
      },
      {
        llmsTxt: {
          name: 'zh/llms.txt',
        },
        llmsFullTxt: {
          name: 'zh/llms-full.txt',
        },
        include: ({ page }) => page.lang === 'zh',
      },
    ]),
  ],
});