---
title: "集成自定义 LLM"
description: "使用生成式 AI 扩展实现自定义 LLM，并在编辑器中重写解析函数。详细内容请查阅文档！"
canonical_url: "https://tiptap.zhcndoc.com/content-ai/capabilities/generation/custom-llms"
---

# 集成自定义 LLM

使用生成式 AI 扩展实现自定义 LLM，并在编辑器中重写解析函数。详细内容请查阅文档！

如果你想使用自己的后端提供对自定义 LLM 的访问，可以在扩展配置中重写下面定义的解析函数。

确保你返回了正确类型的响应，并且正确处理了错误。

> **注意！:**
>
> 我们强烈建议不要在前端直接调用 OpenAI，因为这可能导致 API
> 令牌泄露！你应该通过后端代理来保护你的 API 令牌安全。

## 访问私有注册表

高级 AI 扩展发布在 Tiptap 的私有 npm 注册表中。请按照[私有注册表指南](https://tiptap.zhcndoc.com/guides/pro-extensions.md)集成该扩展。如果你已经验证了你的 Tiptap 账号，可以直接前往[#安装](#安装)。

## 安装

为了使用自定义解析函数，你需要安装我们 Tiptap AI 扩展的高级版本。

```bash
npm install @tiptap-pro/extension-ai
```

### 同时使用自定义 LLM 和 Tiptap AI 云服务

如果你想在某些情况下依赖我们的云服务，确保你已按照[此处说明](https://tiptap.zhcndoc.com/content-ai/capabilities/generation/install.md#start-your-content-ai-app)设置了你的团队。

## 解析函数

你可以在扩展选项中定义自定义解析函数。请注意它们预期的返回类型如下：

| 类型         | 方法名                    | 返回类型                                          |
| ---------- | ---------------------- | --------------------------------------------- |
| completion | `aiCompletionResolver` | `Promise<string \| null>`                     |
| streaming  | `aiStreamResolver`     | `Promise<ReadableStream<Uint8Array> \| null>` |
| image      | `aiImageResolver`      | `Promise<string \| null>`                     |

使用 `aiCompletionResolver` 以非流式方式向编辑器添加文本。

使用 `aiStreamResolver` 直接将内容流式传输到编辑器，实现打字机效果。

确保流返回 HTML，以便 Tiptap 直接将内容渲染为富文本。此方式免去了 Markdown 解析器的需求，使前端保持轻量。

## 示例

### 在完成模式中重写特定命令的解析

本例中我们希望在调用 `rephrase` 动作/命令时，调用自定义后端。
其他所有情况均由 Tiptap Cloud 默认后端处理。

```js
// ...
import Ai from '@tiptap-pro/extension-ai-advanced'
// ...

Ai.configure({
  token: 'TOKEN_HERE',
  // ...
  onError(error, context) {
    // 处理错误
  },
  // 定义完成解析函数（注意：流式和图像需单独定义！）
  aiCompletionResolver: async ({
    editor,
    action,
    text,
    textOptions,
    extensionOptions,
    defaultResolver,
  }) => {
    // 根据 action、text 或其他条件判断
    // 决定是否使用自定义接口
    if (action === 'rephrase') {
      const response = await fetch('https://dummyjson.com/quotes/random')
      const json = await response.json()

      if (!response.ok) {
        throw new Error(`${response.status} ${json?.message}`)
      }

      return json?.quote
    }

    // 其他情况则转发至 Tiptap AI 服务
    return defaultResolver({
      editor,
      action,
      text,
      textOptions,
      extensionOptions,
      defaultResolver,
    })
  },
})
```

### 注册新的 AI 命令并调用自定义后端动作

本例中，我们注册了一个名为 `aiCustomTextCommand` 的编辑器命令，使用 Tiptap 的 `runAiTextCommand` 函数完成其余工作，并添加自定义命令的解析以调用自定义后端（完成模式）。

```js
// …
import { Ai, runAiTextCommand } from '@tiptap-pro/extension-ai-advanced'
// …

// 如果使用 TypeScript，请声明类型：
//
// declare module '@tiptap/core' {
//   interface Commands<ReturnType> {
//     ai: {
//       aiCustomTextCommand: () => ReturnType,
//     }
//   }
// }

const AiExtended = Ai.extend({
  addCommands() {
    return {
      ...this.parent?.(),

      aiCustomTextCommand:
        (options = {}) =>
        (props) => {
          // 你可以自行实现逻辑，比如获取所选文字并传递给特定命令解析
          return runAiTextCommand(props, 'customCommand', options)
        },
    }
  },
})

// … 这里初始化你的 Tiptap 编辑器实例并注册扩展

const editor = new Editor({
  extensions: [
    /* … 添加其他扩展 */
    AiExtended.configure({
      /* … 在此添加配置（token 等） */
      onError(error, context) {
        // 处理错误
      },
      aiCompletionResolver: async ({
        action,
        text,
        textOptions,
        extensionOptions,
        defaultResolver,
        editor,
      }) => {
        if (action === 'customCommand') {
          const response = await fetch('https://dummyjson.com/quotes/random')
          const json = await response.json()

          if (!response.ok) {
            throw new Error(`${response.status} ${json?.message}`)
          }

          return json?.quote
        }

        return defaultResolver({
          editor,
          action,
          text,
          textOptions,
          extensionOptions,
          defaultResolver,
        })
      },
    }),
  ],
  content: '',
})

// … 使用以下方式运行新命令：
// editor.chain().focus().aiCustomTextCommand().run()
```

### 在流模式下使用你的自定义后端

本例完全依赖自定义后端。

确保 `aiStreamResolver` 函数返回 `ReadableStream<Uint8Array>`。

请注意：如果你同时想使用流模式和传统的完成模式（非流模式），也需定义 `aiCompletionResolver`！

```js
// ...
import Ai from '@tiptap-pro/extension-ai-advanced'
// ...

Ai.configure({
  token: 'TOKEN_HERE',
  // ...
  onError(error, context) {
    // 处理错误
  },
  // 定义流解析函数
  aiStreamResolver: async ({ action, text, textOptions }) => {
    const fetchOptions = {
      method: 'POST',
      headers: {
        accept: 'application/json',
        'content-type': 'application/json',
      },
      body: JSON.stringify({
        ...textOptions,
        text,
      }),
    }

    const response = await fetch(`<YOUR_STREAMED_BACKEND_ENDPOINT>`, fetchOptions)

    if (!response.ok) {
      const json = await response.json()
      throw new Error(`${json?.error} ${json?.message}`)
    }

    return response.body
  },
})
```
