Next.js Pages Router中OpenAI GPT助手无输出问题求助
解决Next.js Pages Router中useAssistant钩子无响应的问题
问题根源
- 响应被覆盖:API路由中调用
AssistantResponse处理流式响应后,又通过res.status(200).json(...)发送了JSON响应,直接中断流式传输,导致前端useAssistant无法接收助手回复数据。 - AssistantResponse参数错误:Pages Router环境下,
AssistantResponse需要绑定req和res对象才能正确处理流式输出,原代码未传入这两个关键参数。 - 工具调用未处理:当助手触发工具调用时,原代码直接抛出错误,导致流处理中断。
修复后的API路由代码(pages/api/assistant/index.tsx)
import { NextApiRequest, NextApiResponse } from "next"; import { AssistantResponse } from "ai"; import OpenAI from "openai"; const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY || "", }); export const maxDuration = 30; export default async function handler(req: NextApiRequest, res: NextApiResponse) { if (req.method !== "POST") { return res.status(405).json({ error: "Method not allowed" }); } try { const input: { threadId: string | null; message: string; } = req.body; const threadId = input.threadId ?? (await openai.beta.threads.create({})).id; const createdMessage = await openai.beta.threads.messages.create(threadId, { role: "user", content: input.message, }); // 关键修改:传入req和res绑定响应流 await AssistantResponse( { req, res, threadId, messageId: createdMessage.id }, async ({ forwardStream, sendDataMessage }) => { let runStream = openai.beta.threads.runs.stream(threadId, { assistant_id: process.env.ASSISTANT_ID ?? (() => { throw new Error("ASSISTANT_ID is not set"); })(), }); let runResult = await forwardStream(runStream); while ( runResult?.status === "requires_action" && runResult.required_action?.type === "submit_tool_outputs" ) { const tool_outputs = runResult.required_action.submit_tool_outputs.tool_calls.map( (toolCall: any) => { const parameters = JSON.parse(toolCall.function.arguments); switch (toolCall.function.name) { // 这里添加你的工具处理逻辑,示例: // case "get_user_stats": // return { // tool_call_id: toolCall.id, // output: JSON.stringify({ total: 100 }) // }; default: // 避免抛出错误中断流,返回默认提示 return { tool_call_id: toolCall.id, output: JSON.stringify({ error: `未实现工具调用:${toolCall.function.name}` }) }; } }, ); runResult = await forwardStream( openai.beta.threads.runs.submitToolOutputsStream(threadId, runResult.id, { tool_outputs, }), ); } }, ); // 移除该行:AssistantResponse已处理响应,无需重复发送JSON // res.status(200).json({ threadId, messageId: createdMessage.id }); } catch (error) { console.error("Error handling request:", error); res.status(500).json({ error: "Internal Server Error" }); } }
前端组件注意事项(components/Statistics.tsx)
- 正确解析消息内容:
useAssistant返回的message.content是内容块数组,需正确提取文本。示例解析函数:
function parseContent(content: any) { const textContent = content .filter((block: any) => block.type === 'text') .map((block: any) => block.text.value) .join(''); // 根据助手返回的内容格式调整解析逻辑,这里假设返回JSON try { return JSON.parse(textContent); } catch (e) { return { whatsWorking: textContent, whatsNeedsImproving: '' }; } }
- 监听状态变化:提交消息后
status会变为'streaming',完成后变为'idle',可据此添加加载提示。
内容的提问来源于stack exchange,提问作者Evan Gordon
相关产品推荐
相关产品推荐

