插入内容

在服务器上使用 AI 生成的内容替换当前选区,构建一个工作流。

查看 GitHub 上的源码

开始之前,请按照 授权指南 完成身份验证设置。

何时使用此工作流

如果你确定在 AI 请求期间文档不会发生变化,请使用 Server AI Toolkit 实现 insert content 工作流。否则,AI 可能会将内容插入到文档错误的位置。

在交互式编辑场景中,例如多个用户协作编辑的文档,请使用客户端 AI Toolkit 的 insert content 工作流

我们正在为这个 Server AI Toolkit 工作流开发一个新版本,使其能够在 AI 模型请求期间对其他用户对文档所做的更改保持鲁棒性。

1. 从 AI 服务器读取当前选区

insert-content 工作流首先从协作文档中读取被选中的内容。 调用:

  • POST /v3/ai/toolkit/read/read-selection
import { getAuthHeaders } from '@/lib/server-ai-toolkit/get-auth-headers'

const readResponse = await fetch(`${apiBaseUrl}/toolkit/read/read-selection`, {
  method: 'POST',
  headers: getAuthHeaders(),
  body: JSON.stringify({
    schemaAwarenessData,
    range,
    sessionId,
    format: 'shorthand',
    reviewOptions: {
      mode: 'disabled',
    },
    experimental_documentOptions: {
      documentId,
      userId: 'ai-assistant',
    },
  }),
})

const readResult = await readResponse.json()

if (readResult.output.isEmpty) {
  throw new Error('No selection available for insert-content workflow')
}

2. 获取工作流定义并构建提示词

获取工作流定义和模式感知提示词,然后将它们组合到 system 提示词中。 工作流定义来自:

  • POST /v3/ai/toolkit/workflows/insert-content
const workflowResponse = await fetch(`${apiBaseUrl}/toolkit/workflows/insert-content`, {
  method: 'POST',
  headers: getAuthHeaders(),
  body: JSON.stringify({
    format: 'shorthand',
  }),
})

const workflow = await workflowResponse.json()

const schemaResponse = await fetch(`${apiBaseUrl}/toolkit/schema-awareness-prompt`, {
  method: 'POST',
  headers: getAuthHeaders(),
  body: JSON.stringify({
    schemaAwarenessData,
  }),
})

const { prompt: schemaAwarenessPrompt } = await schemaResponse.json()

const result = streamText({
  model,
  system: `${workflow.systemPrompt}\n\n${schemaAwarenessPrompt}`,
  prompt: JSON.stringify({
    task,
    replace: readResult.output.content,
    context: readResult.output.prompt,
  }),
  output: Output.object({ schema: z.fromJSONSchema(workflow.outputSchema) }),
})

const workflowOutput = await result.output

使用 format: 'shorthand' 会让模型输出更紧凑,同时仍然会使用结构化输出模式对其进行校验。

3. 执行工作流并获取插入范围

将生成的简写字符串传递给执行端点。响应会包含新插入内容的范围。 调用:

  • POST /v3/ai/toolkit/execute-workflow/insert-content
const executeResponse = await fetch(`${apiBaseUrl}/toolkit/execute-workflow/insert-content`, {
  method: 'POST',
  headers: getAuthHeaders(),
  body: JSON.stringify({
    schemaAwarenessData,
    format: 'shorthand',
    input: workflowOutput.content,
    range,
    sessionId: readResult.sessionId,
    reviewOptions: {
      mode: 'disabled',
    },
    experimental_documentOptions: {
      documentId,
      userId: 'ai-assistant',
    },
  }),
})

const executeResult = await executeResponse.json()

在读取和执行之间复用同一个会话

读取选区这一步会返回一个 sessionId。在执行请求中传递同一个 sessionId, 这样如果 AI 读取之后选中的内容发生了变化,服务器就可以拒绝过时的编辑。

4. 在客户端恢复选区

在协作文档更新之后,再次选中插入的内容,这样用户就可以继续使用新文本进行工作。

const result: {
  sessionId: string
  range: { from: number; to: number } | null
} = await response.json()

if (result.range) {
  editor.commands.focus()
  editor.commands.setTextSelection(result.range)
}

已跟踪的变更

将此工作流与 Tracked Changes 扩展集成,以便在 AI 编辑文档后显示审阅界面,并允许用户接受 或拒绝更改。

POST /v3/ai/toolkit/execute-workflow/insert-content 的请求中,配置 reviewOptions 参数:

reviewOptions: {
  mode: 'trackedChanges',
  trackedChangesOptions: {
    userId: 'ai-assistant',
  },
  // 设置 `useDiffUtility: false` 以显示一条建议
  // 该建议会覆盖整个插入内容。
  useDiffUtility: false
}

查看 AI Toolkit demos,了解如何将 Server AI Toolkit 工作流与 Tracked Changes 集成的示例。

最终效果

完成的演示会替换当前选区,并保持新内容仍处于选中状态:

查看 GitHub 上的源码

下一步