解决AWS Lambda部署Vercel AI SDK时StreamingTextResponse流未定义问题
问题描述
我正尝试通过Cloudfront、Lambda和API Gateway在AWS上部署我的NextJS Vercel AI SDK应用。想要修改useChat()函数,使其调用我的Lambda函数的API,该函数负责连接OpenAI并返回StreamingTextResponse。但目前StreamingTextResponse的body中的流始终为undefined,请问可以采取哪些措施修复?
相关代码如下:
page.tsx
"use client"; import { useChat } from "ai/react"; import { useState, useEffect } from "react"; export default function Chat() { const { messages, input, handleInputChange, handleSubmit, data } = useChat({api: '/myAWSAPI'}); ...
Lambda Function
const OpenAI = require('openai') const { OpenAIStream, StreamingTextResponse } = require('ai'); const prompts = require('./prompts') const { roleplay_prompt } = prompts // Create an OpenAI API client (that's edge friendly!) const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY || '', }); exports.handler = async function(event, context, callback) { // Extract the `prompt` from the body of the request const { messages } = event.body; const messageWithSystem = [ {role: 'system', content: roleplay_prompt}, ...messages // Add user and assistant messages after the system message ] console.log(messageWithSystem) // Ask OpenAI for a streaming chat completion given the prompt const response = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', stream: true, messages: messageWithSystem, }); // Convert the response into a friendly text-stream const stream = OpenAIStream(response); // Respond with the stream const chatResponse = new StreamingTextResponse(stream); // body's stream is always undefined console.log(chatResponse) return chatResponse }
解决方案
1. 修正Lambda响应格式(适配API Gateway规范)
Lambda直接返回StreamingTextResponse对象不符合API Gateway的响应要求,需要手动构造流式响应结构:
- 设置
Content-Type为text/plain; charset=utf-8,并添加分块传输相关头 - 将流直接作为
body返回,同时标记isBase64Encoded: false - 确保Lambda启用了响应流式功能(在Lambda控制台的函数配置中开启)
修改后的Lambda代码:
const OpenAI = require('openai') const { OpenAIStream } = require('ai'); const prompts = require('./prompts') const { roleplay_prompt } = prompts const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY || '', }); exports.handler = async function(event) { // 解析API Gateway传递的JSON请求体 const { messages } = JSON.parse(event.body); const messageWithSystem = [ {role: 'system', content: roleplay_prompt}, ...messages ] const response = await openai.chat.completions.create({ model: 'gpt-3.5-turbo', stream: true, messages: messageWithSystem, }); const stream = OpenAIStream(response); // 构造符合API Gateway要求的流式响应 return { statusCode: 200, headers: { 'Content-Type': 'text/plain; charset=utf-8', 'Transfer-Encoding': 'chunked', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', 'Access-Control-Allow-Origin': '*' // 根据需求配置跨域 }, body: stream, isBase64Encoded: false }; }
2. 启用API Gateway响应流式
AWS API Gateway默认不支持响应流式,需手动开启:
- 进入API Gateway控制台,选择目标API
- 进入“Settings”页面,找到“Response Streaming”选项,设置为启用
- 重新部署API到对应阶段
3. 配置前端useChat的流式支持
显式配置useChat的流式选项,确保前端正确接收流式响应:
const { messages, input, handleInputChange, handleSubmit, data } = useChat({ api: '/myAWSAPI', stream: true, headers: { 'Accept': 'text/event-stream' } });
4. 调整Cloudfront缓存配置
Cloudfront的缓存策略可能会中断流式传输,需针对API路径做如下配置:
- 在Cloudfront行为中,将
Cache-Control设置为no-cache - 确保允许
Transfer-Encoding头传递到源站 - 禁用该路径的缓存功能
5. 检查Lambda执行角色权限
确认Lambda执行角色拥有:
- 互联网访问权限(如果直接调用OpenAI公网API)
- 必要的日志权限,方便排查流处理过程中的错误
内容的提问来源于stack exchange,提问作者Dylariant
相关产品推荐
相关产品推荐

