校对工作流程
构建一个能够检测并纠正文档中拼写错误的校对工具。
查看 GitHub 上的源码。
技术栈
- React + Next.js
- Vercel 提供的 AI SDK + OpenAI 模型
- Tiptap AI Toolkit
项目概述
此演示使用 AI Toolkit 的校对工作流程,实时对文档进行一系列小幅度的编辑。
安装
创建一个 Next.js 项目:
npx create-next-app@latest proofreader安装核心 Tiptap 包和适用于 OpenAI 的 Vercel AI SDK:
npm install @tiptap/react @tiptap/starter-kit ai @ai-sdk/react @ai-sdk/openai zod uuid安装 Tiptap AI Toolkit:
专业版包
AI Toolkit 是一个专业版包。安装前,请按照 私有注册表指南 配置私有 NPM 注册表的访问权限。
npm install @tiptap-pro/ai-toolkit @tiptap-pro/ai-toolkit-tool-definitions服务器设置
创建一个 API 端点,使用 Vercel AI SDK 调用 OpenAI 模型。如果你的后端不是 TypeScript,请参阅 非 TypeScript 后端。
在 API 端点内,使用 createProofreaderWorkflow 函数创建并配置校对工作流程。该工作流程包含一个可直接使用的系统提示,指导 AI 模型如何生成内容。
此外,需要在用户消息中包含以下两个属性:
content: 待校对文档的内容(详见客户端设置部分,如何获取内容)task: AI 要执行的任务,例如Correct all grammar and spelling mistakes(纠正所有语法和拼写错误)context: (可选)与任务相关的额外上下文或背景信息。
当 AI 模型生成响应时,API 端点会将建议流式传输给客户端。
// app/api/proofreader/route.ts
import { openai } from '@ai-sdk/openai'
import { createProofreaderWorkflow } from '@tiptap-pro/ai-toolkit-tool-definitions'
import { Output, streamText } from 'ai'
export async function POST(req: Request) {
const { content } = await req.json()
// 创建并配置校对工作流程(使用默认设置)。
// 其中包含可直接使用的系统提示和输出模式。
const workflow = createProofreaderWorkflow()
const result = streamText({
model: openai('gpt-5.4-mini'),
// 系统提示
system: workflow.systemPrompt,
// 用户消息
prompt: JSON.stringify({
content,
task: 'Correct all grammar and spelling mistakes',
context: 'This is a formal business document',
}),
output: Output.object({ schema: workflow.zodOutputSchema }),
})
return result.toTextStreamResponse()
}客户端设置
创建一个 React 组件,渲染编辑器并实时应用编辑。
首先,在开始校对流程时,调用 AI Toolkit 的 tiptapRead 方法读取文档。该方法返回一种针对快速、精准编辑优化的内容格式。
接着,调用 API 端点开始工作流程。组件利用 Vercel AI SDK 的 useObject hook 处理流式响应,从而边接收响应边实时应用编辑。
每当响应发生变化时,调用 AI Toolkit 的 proofreaderWorkflow 方法实时将编辑应用到文档。
选项 mode: 'preview' 允许在编辑实际应用到文档前预览编辑内容。否则,所有编辑会立即应用,不显示预览。
// app/proofreader/page.tsx
'use client'
import { experimental_useObject as useObject } from '@ai-sdk/react'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import { AiToolkit, getAiToolkit, proofreaderWorkflowOutputSchema } from '@tiptap-pro/ai-toolkit'
import { useEffect, useRef, useState } from 'react'
import { v4 as uuid } from 'uuid'
export default function Page() {
const editor = useEditor({
immediatelyRender: false,
extensions: [StarterKit, AiToolkit],
content: `<h1>语法检查演示</h1><p>This is a excelent editor for writng documents. It have many feature's that makes it very powerfull.</p>`,
})
const [isReviewing, setIsReviewing] = useState(false)
const [workflowId, setWorkflowId] = useState('')
const { submit, isLoading, object } = useObject({
api: '/api/proofreader',
schema: proofreaderWorkflowOutputSchema,
onFinish: () => {
setIsReviewing(true)
},
})
const operations = object?.operations ?? []
// 实时处理流式到达的部分结果
useEffect(() => {
if (!editor || !operations) return
const toolkit = getAiToolkit(editor)
toolkit.proofreaderWorkflow({
operations,
workflowId,
reviewOptions: {
mode: 'preview',
},
hasFinished: !isLoading,
})
}, [operations, workflowId, editor, isLoading])
if (!editor) return null
const checkGrammar = () => {
const toolkit = getAiToolkit(editor)
// 获取待校对文档的内容
const { content } = toolkit.tiptapRead()
// 每个工作流程必须有唯一 ID
setWorkflowId(uuid())
// 调用 API 端点开始工作流程
submit({ content })
}
return (
<div>
<EditorContent editor={editor} />
{!isReviewing && (
<button onClick={checkGrammar} disabled={isLoading}>
{isLoading ? '检测中...' : '检查语法'}
</button>
)}
{isReviewing && (
<div>
<p>文档中的更正已高亮显示。</p>
<button
onClick={() => {
const toolkit = getAiToolkit(editor)
toolkit.acceptAllSuggestions()
setIsReviewing(false)
}}
>
全部接受
</button>
<button
onClick={() => {
const toolkit = getAiToolkit(editor)
toolkit.rejectAllSuggestions()
setIsReviewing(false)
}}
>
全部拒绝
</button>
</div>
)}
</div>
)
}最终效果
通过额外的 CSS 样式,最终呈现的是一个具备实时语法检查功能的精美校对应用:
查看 GitHub 上的源码。
校对文档的一部分
要校对文档的子区域,请设置 range 选项。此参数接受一个描述文档将被校对区域的 Range。
例如,校对选中的内容:
// 创建一个 Range 来指定校对区域
const range = editor.state.selection
// 只读取选中的文档部分
const { content } = toolkit.tiptapRead({
range,
})
const operations = callApi(content)
// 在相同范围内应用操作
toolkit.proofreaderWorkflow({
operations,
range,
})对于大型文档,你可以使用 tiptapReadChunks 方法,将文档拆分成多个块并平行处理。每个块都包含一个 Range 以指明该块的区域。
显示审阅界面
在审阅界面中显示更改,方便用户接受或拒绝。
有两种方式:
- 使用 Tracked Changes 扩展来渲染审阅界面。更改会作为文档的一部分持久保存,并对其他用户可见。
- AI Toolkit 建议:一种基于装饰的界面,具有临时性,仅对当前文档用户可见。
通过设置 reviewOptions 参数来配置审阅界面。更改将以建议的形式显示,用户可以接受或拒绝。
await toolkit.proofreaderWorkflow({
// ... 其他选项
// 使用 Tracked Changes 显示审阅界面
reviewOptions: { mode: 'trackedChanges' },
// 使用 AI Toolkit 建议显示审阅界面
reviewOptions: { mode: 'review' },
})请参阅 审阅更改 指南,了解有关审阅界面的更多信息。
请查看 AI Toolkit 演示,了解如何将 AI Toolkit 工作流程与审阅界面结合使用的示例。