在开发 AI 应用时,LLM(大语言模型)的不确定性是开发者必须面对的挑战。网络波动、配额限制(Rate Limits)、模型过载或输出内容被安全策略拦截,都可能导致请求失败。
Vercel AI SDK Core 提供了一套标准化的错误处理机制,无论是普通的文本生成还是流式传输(Streaming),都能优雅地捕获和处理异常。本文将基于官方文档,详细介绍如何在 Vercel AI SDK Core 中构建健壮的错误处理逻辑。
1. 基础文本生成错误处理 (Regular Errors)
对于非流式的 generateText 或 generateObject 方法,错误处理非常直观。SDK 会抛出标准的 JavaScript Error,你只需要使用 try/catch 块即可捕获。
这适用于处理 API 密钥错误、余额不足或网络超时等问题。
代码示例
TypeScript
javascript
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
async function main() {
try {
const { text } = await generateText({
model: openai('gpt-4-turbo'),
prompt: '为我写一个素食千层面的 4 人份食谱。',
});
console.log(text);
} catch (error) {
// 在这里处理错误
// 可以在这里判断 error 的类型,例如是否为 APICallError
console.error('生成文本时发生错误:', error);
}
}
2. 流式传输错误处理 (Streaming Errors)
在处理流式响应时(streamText 或 streamObject),错误处理的逻辑稍微复杂一些,因为错误可能发生在连接建立阶段,也可能发生在流传输的过程中。
场景 A:简单流处理 (Simple Streams)
如果你使用 textStream 进行简单的文本迭代,如果流在传输过程中断开或发生错误(且不支持错误分块),SDK 会抛出一个标准的错误。你应当在 for await...of 循环外层包裹 try/catch。
TypeScript
javascript
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
async function streamExample() {
try {
const { textStream } = await streamText({
model: openai('gpt-4-turbo'),
prompt: '为我写一个素食千层面的 4 人份食谱。',
});
for await (const textPart of textStream) {
process.stdout.write(textPart);
}
} catch (error) {
// 捕获流传输过程中的中断或网络错误
console.error('流传输中断:', error);
}
}
场景 B:全流处理 (Full Streams with Error Support)
对于更高级的用例,建议使用 fullStream。它可以返回不同类型的"部分"(Parts),包括文本增量、工具调用以及错误信息。
这种方式允许你精细地处理流中的特定事件。注意,即使使用了 fullStream,依然建议在外层保留 try/catch 以捕获那些无法作为流部分发送的致命错误(如初始连接失败)。
TypeScript
javascript
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
async function fullStreamExample() {
try {
const { fullStream } = await streamText({
model: openai('gpt-4-turbo'),
prompt: '为我写一个素食千层面的 4 人份食谱。',
});
for await (const part of fullStream) {
switch (part.type) {
case 'text-delta': {
process.stdout.write(part.textDelta);
break;
}
// 处理流中的错误部分
case 'error': {
const error = part.error;
console.error('流中接收到错误:', error);
break;
}
// 处理流中断
case 'step-finish': {
// 步骤结束(例如工具调用完成或生成结束)
break;
}
default: {
// 处理其他类型的 part
break;
}
}
}
} catch (error) {
// 处理流建立失败等致命错误
console.error('发生致命错误:', error);
}
}
3. 处理流的中断 (Handling Aborts)
在实际应用中(尤其是聊天机器人),用户可能会在生成完成前点击"停止"按钮。这时你需要处理 abort 事件,以便进行清理工作或更新 UI 状态(例如移除"正在输入"的指示器)。
SDK 提供了 onAbort 回调函数,它会在流被 AbortSignal 中断时触发,而不会触发 onFinish。
使用 onAbort 回调
TypeScript
javascript
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
async function abortExample() {
const { textStream } = await streamText({
model: openai('gpt-4-turbo'),
prompt: '写一篇关于量子物理的长文章。',
// 当流被中止时调用
onAbort: ({ text }) => {
// text 参数包含中止前已生成的完整文本
console.log('生成被用户中止。已生成内容长度:', text.length);
// 在这里执行清理逻辑,例如保存草稿
},
onFinish: ({ text }) => {
console.log('生成正常完成。');
},
});
try {
for await (const textPart of textStream) {
process.stdout.write(textPart);
}
} catch (error) {
// 处理中止以外的错误
}
}
总结
健壮的 AI 应用离不开完善的错误处理。Vercel AI SDK Core 提供了多层级的错误捕获机制:
- Try/Catch : 适用于所有
generate方法和stream方法的外层防护。 - Error Parts : 在
fullStream中精细处理流传输过程中的错误。 - onAbort: 专门处理用户主动取消请求的场景。
掌握这些模式,能让你的 AI 应用在面对网络抖动和模型异常时依然保持优雅和稳定。
标签: #Vercel #AI #TypeScript #前端开发 #大模型