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

在Next.js Vercel AI项目中添加Together AI作为自定义提供商

使用Vercel AI SDK结合Together AI生成对象(自定义提供商配置)

自定义提供商核心要求(官方文档翻译)

要对接Together AI,需实现符合Vercel AI SDK规范的自定义提供商,核心要点:

  • 必须实现createChatCompletion方法,同时支持流式和非流式两种响应模式
  • 完成SDK标准参数与Together AI API参数的映射
  • 将Together AI返回的响应格式转换为SDK可识别的结构
  • 支持传入API密钥、Base URL等配置项

1. 创建Together AI自定义提供商

新建文件lib/together-ai-provider.ts,实现完整的提供商逻辑:

import {
  ChatCompletionRequestMessage,
  ChatCompletionResponse,
  ChatCompletionStreamResponse,
  CreateChatCompletionOptions,
  Provider,
} from '@ai-sdk/provider';

// 创建Together AI提供商实例
export function togetherAI(apiKey: string): Provider {
  return {
    id: 'together-ai',
    name: 'Together AI',
    createChatCompletion: async (
      model: string,
      messages: ChatCompletionRequestMessage[],
      options: CreateChatCompletionOptions
    ) => {
      const { stream, ...restOptions } = options;
      // 构造Together AI API请求体(兼容OpenAI格式)
      const requestBody = {
        model,
        messages,
        stream: stream ?? false,
        ...restOptions,
      };

      // 发送请求到Together AI API
      const response = await fetch('https://api.together.xyz/v1/chat/completions', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${apiKey}`,
        },
        body: JSON.stringify(requestBody),
      });

      if (!response.ok) {
        throw new Error(`Together AI请求失败: ${await response.text()}`);
      }

      if (stream) {
        // 处理流式响应
        const stream = response.body;
        if (!stream) throw new Error('流式响应为空');

        return {
          type: 'stream',
          stream: new ReadableStream({
            async start(controller) {
              const reader = stream.getReader();
              const decoder = new TextDecoder();

              try {
                while (true) {
                  const { done, value } = await reader.read();
                  if (done) break;

                  const chunk = decoder.decode(value);
                  // 解析Together AI的SSE格式响应
                  chunk.split('\n').forEach(line => {
                    if (line.startsWith('data: ')) {
                      const data = line.slice(6);
                      if (data === '[DONE]') return;

                      try {
                        const parsed = JSON.parse(data) as ChatCompletionStreamResponse;
                        controller.enqueue(parsed);
                      } catch (e) {
                        console.error('流式响应解析失败:', e);
                      }
                    }
                  });
                }
              } catch (e) {
                controller.error(e);
              } finally {
                controller.close();
              }
            },
          }),
        };
      } else {
        // 处理非流式响应
        const data = await response.json() as ChatCompletionResponse;
        return {
          type: 'data',
          data,
        };
      }
    },
  };
}

2. 替换示例中的OpenAI为自定义提供商

参考生成对象的示例,修改后端API路由和前端组件:

2.1 后端API路由(app/api/chat/route.ts)

import { togetherAI } from '@/lib/together-ai-provider';
import { generateObject } from 'ai';
import { z } from 'zod';

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = await generateObject({
    // 指定Together AI模型(示例用Llama 3 70B)
    model: togetherAI(process.env.TOGETHER_AI_API_KEY!).model('meta-llama/Llama-3-70b-chat-hf'),
    messages,
    // 定义要生成的对象结构(与原示例一致)
    schema: z.object({
      name: z.string().describe('用户姓名'),
      age: z.number().describe('用户年龄'),
      interests: z.array(z.string()).describe('用户兴趣爱好'),
    }),
  });

  return Response.json(result);
}

2.2 前端组件(app/page.tsx)

核心逻辑与原示例一致,只需确保API调用路径正确:

'use client';

import { useChat } from 'ai/react';

export default function Home() {
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    api: '/api/chat',
  });

  return (
    <div className="max-w-md mx-auto p-4">
      <h1 className="text-2xl font-bold mb-4">对象生成示例</h1>
      {messages.map((m) => (
        <div key={m.id} className="mb-2 p-2 rounded bg-gray-100">
          <strong>{m.role}:</strong> {typeof m.content === 'string' ? m.content : JSON.stringify(m.content, null, 2)}
        </div>
      ))}
      <form onSubmit={handleSubmit} className="mt-4">
        <input
          type="text"
          value={input}
          onChange={handleInputChange}
          placeholder="输入提示词,例如:描述一个喜欢编程和徒步的28岁用户"
          className="w-full p-2 border rounded"
        />
        <button type="submit" className="mt-2 w-full p-2 bg-blue-500 text-white rounded">
          生成对象
        </button>
      </form>
    </div>
  );
}

3. 关键配置与排查

  • API密钥:在Vercel项目的环境变量中添加TOGETHER_AI_API_KEY,值为你的Together AI密钥
  • 模型选择:可替换为Together AI支持的其他模型,如mistralai/Mistral-7B-Instruct-v0.2
  • 常见问题:
    • 请求失败:检查API密钥是否正确、模型名称是否存在于Together AI的模型列表中
    • 格式错误:确认提供商的响应转换逻辑是否正确对齐SDK要求
    • 流式卡顿:检查网络连接或Together AI的API速率限制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 09:35:15