You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vercel AI-SDK streamUI组件流式传输异常及相关技术疑问

Vercel AI-SDK streamUI 使用问题排查与疑问解答

正在学习Vercel AI-SDK,开发人物角色生成器——输入品牌上下文,按指定Zod schema生成人物角色属性。用streamObject实现的personaSchemaGeneration能正常返回文本流并展示,但改用streamUI实现personaSchemaGenerationUI时遇到以下问题:

遇到的问题

  • 文本流完成后返回的对象不符合定义的personaSchema类型;
  • 无法将LLM输出的符合personaSchema格式的数据正确传入React组件并展示;
  • 通用疑问:
    1. streamUI是否仅支持返回单个组件?生成10个不同人物角色是否需要独立调用10次?
    2. streamUI是否仅支持调用一个工具?添加多个工具时总是默认使用第一个。

相关代码

基于streamObject的实现代码(personaSchemaGeneration)

export async function personaSchemaGeneration(context: string) {
    'use server';
  
    const stream = createStreamableValue();
  
    (async () => {
      const { partialObjectStream } = await streamObject({
        model: openai('gpt-3.5-turbo'),
        system: 'You generate a persona basis the brand context.',
        prompt: 'Generate a persona for the brand in line with the following context: ' + context,
        schema: personaSchema,
      });
  
      for await (const partialObject of partialObjectStream) {
        stream.update(partialObject);
      }
  
      stream.done();
    })();
  
    return { object: stream.value };
  }

前端调用代码

const { object } = await personaSchemaGeneration(brandContext);
          
for await (const partialObject of readStreamableValue(object)) {
    console.log("Partial Obj",partialObject, "    ", object)
    if (partialObject) {
        setGeneration(
            JSON.stringify(partialObject, null, 2),
        );
    }
}
console.log("Final Obj",object)

基于streamUI的实现代码(personaSchemaGenerationUI)

export async function personaSchemaGenerationUI(context: string) {
    'use server';

    const result = await streamUI({
        model: openai('gpt-3.5-turbo'),
        system: 'You generate a persona basis the brand context.',
        prompt: 'Generate a persona for the brand in line with the following context: ' + context,
        schema: personaSchema,
        text:({ content }) => <Persona3 {...content} />
        },
      );
    
      return result.value;
  }

问题解答

1. 返回对象不符合schema类型

streamUI的text回调接收的content是LLM输出的原始文本,而非经过schema验证解析后的对象。需要手动将文本解析为JSON后,再用personaSchema验证:

text: ({ content }) => {
  try {
    const parsedPersona = personaSchema.parse(JSON.parse(content));
    return <Persona3 {...parsedPersona} />;
  } catch (e) {
    return <div>生成格式错误,请重试</div>;
  }
}

同时要修改prompt,明确要求LLM输出严格符合schema的纯JSON格式,避免多余文本干扰解析。

2. 无法正确传入React组件

  • 确保LLM输出无多余前缀/后缀文本,仅返回符合schema的JSON;
  • 按上述代码先解析验证数据,再将合法的属性传递给组件;
  • 若需流式更新组件,可在text回调中根据部分解析结果逐步渲染内容。

3. 通用疑问解答

a) streamUI是否仅支持返回单个组件?

streamUI单次调用返回一个流式组件输出,但生成多个角色有两种方案:

  • 方案一:调用10次streamUI,每次生成一个角色,并行或串行渲染结果;
  • 方案二:让LLM一次性输出包含10个角色的JSON数组,在text回调中解析后返回多组件容器:
    text: ({ content }) => {
      const parsedList = personaSchema.array().parse(JSON.parse(content));
      return <div className="persona-grid">{parsedList.map(p => <Persona3 key={p.id} {...p} />)}</div>;
    }
    
    需同步修改prompt,明确要求输出包含10个角色的JSON数组。

b) streamUI是否仅支持调用一个工具?

streamUI支持多工具调用,需通过tools配置项传入工具列表,并优化prompt引导模型选择合适工具:

await streamUI({
  model: openai('gpt-3.5-turbo'),
  system: '根据需求选择工具生成角色:需要行业数据用工具1,需要创意标签用工具2',
  prompt: `基于上下文生成角色:${context}`,
  schema: personaSchema,
  tools: [tool1, tool2],
  text: ({ content }) => <Persona3 {...content} />
});

模型默认选第一个工具通常是因为prompt未明确工具适用场景,补充场景说明即可解决。


内容的提问来源于stack exchange,提问作者blaziken105

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:02:07