// 不自动运行(Next.js 路由处理器,npm run dev 后 POST /api/chat) // 服务端调用大模型并以流的形式返回;模型密钥只在服务端,浏览器拿不到。 export const runtime = "nodejs"; async function* fakeLLM(question: string, signal: AbortSignal): AsyncGenerator { // 真实项目:调用模型 SDK 的流式接口,并把 signal 传进去 const words = `关于“${question}”:签收 7 天内可以无理由退货。`.split(""); for (const w of words) { if (signal.aborted) return; // 用户停止或断开:不再继续生成(节省费用) await new Promise((r) => setTimeout(r, 30)); yield w; } } export async function POST(request: Request): Promise { const { question } = (await request.json()) as { question?: unknown }; if (typeof question !== "string" || question.length === 0 || question.length > 500) { return Response.json({ error: "question 必须是 1~500 字的字符串" }, { status: 400 }); } const encoder = new TextEncoder(); const stream = new ReadableStream({ async start(controller) { try { for await (const token of fakeLLM(question, request.signal)) { controller.enqueue(encoder.encode(token)); } } finally { controller.close(); } }, }); return new Response(stream, { headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-cache", "X-Accel-Buffering": "no" }, }); }