探索 Tiptap V3 的最新功能

服务器端工具(OpenAI Responses API)

本指南讲解如何使用 OpenAI Responses API 调用服务器端工具。示例展示了一个返回指定地点天气的工具。

提供代码演示

本指南包含代码演示,帮助你快速上手。参见 GitHub 仓库

首先,按照 OpenAI Responses API 工具格式 定义工具:

import OpenAI from 'openai'

const weatherTool: OpenAI.Responses.Tool = {
  type: 'function',
  name: 'get_weather',
  parameters: {
    type: 'object',
    properties: {
      location: {
        type: 'string',
        description: '获取天气的地点',
      },
    },
    required: ['location'],
  },
  strict: false,
}

接着,调用 OpenAI API 时,将该工具加入 tools 数组。

import {
  AiAgentToolkit,
  openaiResponsesAdapter,
  ChatMessagesFormatter,
} from '@tiptap-pro/extension-ai-agent-server'
import OpenAI from 'openai'

const { chatMessages, schemaAwarenessData } = request

const toolkit = new AiAgentToolkit({
  adapter: openaiResponsesAdapter,
  schemaAwarenessData,
})

const formatter = new ChatMessagesFormatter({
  initialMessages: chatMessages,
  adapter: openaiResponsesAdapter,
})

// 初始化 OpenAI 客户端
const openai = new OpenAI()

// 调用 OpenAI Responses API
const response = await openai.responses.create({
  model: 'gpt-4.1',
  input: [
    {
      role: 'developer',
      content: `
<你的系统提示>
${toolkit.getSystemPrompt()}
`,
    },
    ...formatter.format(),
  ],
  // 在 tools 数组中包含天气工具,及 AiAgentToolkit 的其他工具
  tools: [...toolkit.format(), weatherTool],
})

首先,将响应添加到 formatter,以便包含在对话中。

formatter.addAiResponse(response)

然后,检查响应中是否包含类似天气工具的服务器端调用;如果有,调用该工具并将结果添加到 formatter,然后再次调用 OpenAI API。

重复此过程,直到响应中不再包含服务器端工具调用。

const isGetWeatherMessage = (
  message: OpenAI.Responses.ResponseOutputItem,
): message is OpenAI.Responses.ResponseFunctionToolCall =>
  message.type === 'function_call' && message.name === 'get_weather'

let response: OpenAI.Responses.Response | null = null

while (!response || response.output?.some(isGetWeatherMessage)) {
  // 调用 OpenAI Responses API
  response = await openai.responses.create({
    model: 'gpt-4.1',
    input: [
      {
        role: 'developer',
        content: `${systemPrompt}\n${toolkit.getSystemPrompt()}`,
      },
      ...formatter.format(),
    ],
    // 在 tools 数组中包含天气工具,及 AiAgentToolkit 的其他工具
    tools: [...toolkit.format(), weatherTool],
  })
  // 将响应转换为 AI Agent 扩展所需的格式
  formatter.addAiResponse(response)

  // 处理天气工具调用
  for (const toolCall of response.output) {
    if (isGetWeatherMessage(toolCall)) {
      const args = locationSchema.parse(JSON.parse(toolCall.arguments))
      const weatherResult = await getWeather(args.location)

      // 将工具调用结果添加到 formatter
      formatter.addChatMessage({
        type: 'toolCallResult',
        toolName: 'get_weather',
        toolCallId: toolCall.call_id,
        result: weatherResult,
        isError: false,
      })
    }
  }
}

最后,当不再有服务器端工具调用时,使用 formatter 将响应转换为 AI Agent 扩展需要的格式。

const response = formatter.getResolverResponse()

formatter.getResolverResponse() 返回的值应作为你的 API 端点响应以及解析器函数的返回值。