---
title: "管理和审查 AI 响应"
description: "使用内容 AI 存储将 AI 响应保存、重新生成并插入到你的 Tiptap 编辑器中。更多内容请参阅我们的文档！"
canonical_url: "https://tiptap.zhcndoc.com/content-ai/capabilities/generation/text-generation/manage-responses"
---

# 管理和审查 AI 响应

使用内容 AI 存储将 AI 响应保存、重新生成并插入到你的 Tiptap 编辑器中。更多内容请参阅我们的文档！

- **1. 激活试用或订阅**

  在账户中开始一个 [免费试用](https://cloud.tiptap.dev/v2?trial=true) 或 [订阅入门计划](https://cloud.tiptap.dev/v2/billing)。
- **2. 集成 AI 提供商**

  在你的 [AI 设置](https://cloud.tiptap.dev/v2/cloud/ai) 中配置 OpenAI，或查阅
  [自定义 LLM 指南](https://tiptap.zhcndoc.com/content-ai/capabilities/generation/custom-llms.md)。
- **3. 从私有注册表安装**

  要安装前端扩展，请按照 [设置指南](https://tiptap.zhcndoc.com/guides/pro-extensions.md) 验证登录 Tiptap 的私有 npm 注册表。

AI 扩展将当前状态存储在其扩展存储中，路径为 `editor.storage.ai`。它跟踪 AI 响应的当前状态以及任何过去的响应。

> **Interactive demo:** [AiStorage](https://embed-pro.tiptap.dev/preview/Extensions/AiStorage)

| key            | type                                                                                    | 定义                                                                                                                                            |
| -------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| state          | `'loading' \| 'error' \| 'idle'`                                                        | 当 AI 正在生成响应时，状态设为 `loading`。响应生成后，状态设为 `idle`。出现错误时，状态设为 `error`。                                                                             |
| response       | `string \| undefined`                                                                   | AI 最近生成的消息。当状态为 `idle` 时，如果是字符串，则为之前生成的消息；若为 `undefined`，则表示尚未生成消息。状态为 `loading` 时，该值为 AI 目前生成的 HTML 或文本（流式响应时）。状态为 `error` 时，值为 `undefined`。 |
| error          | `Error \| undefined`                                                                    | 生成的错误，仅在错误状态下设置                                                                                                                               |
| generatedWith  | `{ action: TextAction; options: TextOptions; range: undefined \| Range; } \| undefined` | 描述上一条生成响应时所用参数的选项；仅当将内容插入编辑器时，会设置 `range`                                                                                                     |
| pastResponses  | `string[]`                                                                              | 存储之前成功生成的响应，最新的排在最前。接受或拒绝响应时会清空该数组。                                                                                                           |
| initialContent | `Slice \| null`                                                                         | 插入 AI 响应前编辑器的内容。用于通过 `aiReject` 命令撤销 AI 响应。                                                                                                   |

## 访问 AI 存储

你可以通过扩展存储访问当前 AI 生成的状态。

```ts
const aiStorage = editor.storage.ai || editor.storage.aiAdvanced

if (aiStorage.response.state === 'error') {
  // 发生的错误
  aiStorage.response.error
}

if (aiStorage.response.state === 'loading') {
  // AI 模型正在生成的响应
  aiStorage.response
}

if (aiStorage.response.state === 'idle') {
  if (aiStorage.response) {
    // 成功的响应
    aiStorage.response
  } else {
    // 尚未请求响应
  }
}
```

## 审查 AI 生成的内容

AI 扩展提供命令，用于在将 AI 生成的内容插入编辑器后审查它。

### `aiAccept`

标记 AI 响应为已接受。这会清空 `pastResponses` 数组并将 `initialContent` 设为 `null`。

```ts
editor.commands.aiAccept()
```

### `aiReject`

将编辑器内容重置为先前的内容。

```ts
editor.commands.aiReject()
```

> **多次调用 AI 命令后重置为初始值:**
>
> 如果连续多次调用 AI 命令，`initialContent` 属性会被设置为上一次命令的内容。因此，当调用 `aiReject` 时，编辑器的内容会重置到上一次 AI 命令执行前的状态。若要重置到所有 AI 命令执行之前的状态，可以调用带有 `regenerate` 选项设为 `true` 的命令。例如：`editor.commands.aiSummarize({ regenerate: true })`。

### `aiRegenerate`

使用与上一次请求相同的参数重试 AI 响应。

```ts
editor.commands.aiRegenerate()
```

## 在插入响应前预览 AI 回复内容

想在 AI 内容插入编辑器之前预览响应吗？你可以对任意 AI [TextOption](https://tiptap.zhcndoc.com/content-ai/capabilities/generation/text-generation/built-in-commands.md#text-command-options) 使用 `insert: false`，响应结果会存储在扩展存储中，但不会插入到编辑器内容。

```ts
editor.commands.aiTextPrompt({
  text: '将这段文字改写得更正式些',
  stream: true,
  insert: false,
  format: 'rich-text',
})
```

之后，你可以使用 `aiAccept`、`aiReject` 和 `aiRegenerate` 命令。

### `aiAccept`

该命令用于用户接受 AI 响应时执行。默认行为是将响应插入编辑器，具体行为可根据传入选项改变。

| key      | type                                     | 定义                                                                                                       |
| -------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| insertAt | `number \| { from: number, to: number }` | 当为 `number` 时，接收响应并插入到编辑器起始位置；当为 `{ from: number, to: number }` 时，接收响应并替换从 `from` 到 `to` 位置的内容为 AI 响应内容。 |
| append   | `boolean`                                | 如果为 `true`，则不是替换当前选区，而是追加到当前选区后面。                                                                        |

未传入选项时的默认行为是接受响应并将其插入编辑器，替换当前选择内容。

```ts
// 接受响应并插入到编辑器中
editor.commands.aiAccept()

// 接受响应并插入到编辑器起始位置
editor.commands.aiAccept({ insertAt: 0 })

// 接受响应并插入到编辑器末尾
editor.commands.aiAccept({ insertAt: editor.state.doc.content.size })

// 接受响应并追加到当前选区后面
editor.commands.aiAccept({ append: true })
```

### `aiRegenerate`

该命令用于用户想重试 AI 响应时执行，它会使用上一次 AI 文字操作的全部选项，并将响应添加到 `editor.storage.ai.pastResponses` 数组。

| key      | type                                     | 定义                                                                                                                                    |
| -------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| insert   | `boolean`                                | 是否将重新生成的响应插入编辑器                                                                                                                       |
| insertAt | `number \| { from: number, to: number }` | 未指定时，重新生成的响应会插入到上一次响应的位置。当为 `number` 时，重新生成响应并插入到编辑器起始位置；当为 `{ from: number, to: number }` 时，重新生成响应并替换从 `from` 到 `to` 位置的内容为 AI 响应内容。 |

未传入选项时的默认行为是重新生成响应并插入到编辑器，替换当前选区。

```ts
// 重新生成响应并插入编辑器
editor.commands.aiRegenerate()

// 重新生成响应并插入到编辑器起始位置
editor.commands.aiRegenerate({ insertAt: 0 })

// 重新生成响应并插入到编辑器末尾
editor.commands.aiRegenerate({ insertAt: editor.state.doc.content.size })

// 重新生成响应并追加到当前选区后面
editor.commands.aiRegenerate({ append: true })
```

### `aiReject`

该命令用于用户拒绝 AI 响应时执行，它会将扩展状态重置为初始的 idle 状态，并清空所有 `editor.storage.ai.pastResponses`。

| key  | type               | 定义                                         |
| ---- | ------------------ | ------------------------------------------ |
| type | 'reset' \| 'pause' | 是否重置 AI 为 idle 状态，或只是暂停当前响应。默认是 `'reset'`。 |

```ts
editor.commands.aiReject()

// 不会清空 editor.storage.ai，方便保留当前响应内容
editor.commands.aiReject({ type: 'pause' })
```

## 高级示例（预览 AI 响应）

扩展存储的一个用例是渲染 AI 生成内容的预览。 `tryParseToTiptapHTML` 函数利用你的编辑器 schema 将 AI 响应生成 HTML 预览。

```tsx
// 以 HTML 形式显示响应
import { tryParseToTiptapHTML } from '@tiptap-pro/extension-ai'

// 尝试将当前消息解析为 HTML，解析失败则返回 null
tryParseToTiptapHTML(editor.storage.ai.response, editor)

// 尝试将之前的响应解析为 HTML，解析失败则返回 null
tryParseToTiptapHTML(editor.storage.ai.pastResponses[0], editor)

// 如在 React 中示例
function PreviewComponent({ editor }) {
  const htmlResponse = tryParseToTiptapHTML(editor.storage.ai.response, editor)
  /* 由于先用 prose-mirror 解析内容，该渲染是安全的 */
  return <div dangerouslySetInnerHTML={{ __html: htmlResponse }}></div>
}
```

请参见下方我们的演示示例了解完整代码。

> **Interactive demo:** [AiPrompt](https://embed-pro.tiptap.dev/preview/Extensions/AiPrompt)

## 与协作功能一起使用

当你在使用 [Tiptap 协作](https://tiptap.zhcndoc.com/collaboration/getting-started/overview.md)的 AI 生成时，使用 `insert: false` 存储的响应仅对请求者可见。其他用户看不到内容，直到该响应通过 `aiAccept()` 接受后才共享，这样你可以先预览和审查 AI 内容，再与团队共享。
