Le Vercel AI SDK est la manière la plus populaire de construire des fonctionnalités IA dans des applications Next.js, React, Svelte et Vue. Venice fonctionne immédiatement comme fournisseur compatible OpenAI.
Installation
npm install ai @ai-sdk/openai
Configuration du provider
Créez un provider Venice à l’aide de l’adaptateur compatible OpenAI :
// lib/venice.ts
import { createOpenAI } from '@ai-sdk/openai' ;
const openai = createOpenAI ({
apiKey: process . env . VENICE_API_KEY ! ,
baseURL: 'https://api.venice.ai/api/v1' ,
});
// Utilisez .chat() pour garantir la compatibilité avec l'endpoint chat completions de Venice
export const venice = ( modelId : string ) => openai . chat ( modelId );
L’utilisation de .chat() garantit que les requêtes vont vers l’endpoint /chat/completions de Venice. La syntaxe par défaut openai('model') peut utiliser des endpoints OpenAI plus récents que Venice ne prend pas encore en charge.
Streaming chat (Next.js App Router)
Route API
// app/api/chat/route.ts
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
export async function POST ( req : Request ) {
const { messages } = await req . json ();
const result = streamText ({
model: venice ( 'venice-uncensored' ),
system: 'You are a helpful, privacy-respecting AI assistant.' ,
messages ,
});
return result . toDataStreamResponse ();
}
Composant React
// app/page.tsx
'use client' ;
import { useChat } from '@ai-sdk/react' ;
export default function Chat () {
const { messages , input , handleInputChange , handleSubmit , isLoading } = useChat ();
return (
< div className = "max-w-2xl mx-auto p-4" >
< div className = "space-y-4 mb-4" >
{ messages . map (( m ) => (
< div key = { m . id } className = { m . role === 'user' ? 'text-right' : 'text-left' } >
< span className = "font-bold" > { m . role === 'user' ? 'You' : 'Venice' } : </ span >
< p className = "whitespace-pre-wrap" > { m . content } </ p >
</ div >
)) }
</ div >
< form onSubmit = { handleSubmit } className = "flex gap-2" >
< input
value = { input }
onChange = { handleInputChange }
placeholder = "Ask anything..."
className = "flex-1 border rounded px-3 py-2"
disabled = { isLoading }
/>
< button type = "submit" disabled = { isLoading } className = "bg-red-600 text-white px-4 py-2 rounded" >
Send
</ button >
</ form >
</ div >
);
}
Génération de texte (non-streaming)
import { generateText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const { text } = await generateText ({
model: venice ( 'zai-org-glm-5-1' ),
prompt: 'Explain zero-knowledge proofs in simple terms.' ,
});
console . log ( text );
Sortie structurée
import { generateObject } from 'ai' ;
import { venice } from '@/lib/venice' ;
import { z } from 'zod' ;
const { object } = await generateObject ({
model: venice ( 'venice-uncensored' ),
schema: z . object ({
recipe: z . object ({
name: z . string (),
ingredients: z . array ( z . string ()),
steps: z . array ( z . string ()),
prepTimeMinutes: z . number (),
}),
}),
prompt: 'Generate a recipe for chocolate chip cookies.' ,
});
console . log ( object . recipe . name );
console . log ( `Prep time: ${ object . recipe . prepTimeMinutes } minutes` );
import { streamText , tool } from 'ai' ;
import { venice } from '@/lib/venice' ;
import { z } from 'zod' ;
const result = streamText ({
model: venice ( 'zai-org-glm-5-1' ),
messages: [{ role: 'user' , content: 'What is the weather in Tokyo?' }],
tools: {
getWeather: tool ({
description: 'Get current weather for a location' ,
parameters: z . object ({
location: z . string (). describe ( 'City name' ),
}),
execute : async ({ location }) => {
// Votre appel d'API météo ici
return { temperature: 22 , condition: 'Sunny' , location };
},
}),
},
});
for await ( const part of result . fullStream ) {
if ( part . type === 'text-delta' ) {
process . stdout . write ( part . textDelta );
} else if ( part . type === 'tool-result' ) {
console . log ( 'Tool result:' , part . result );
}
}
Génération d’images
La génération d’images Venice peut être appelée directement aux côtés du AI SDK :
// app/api/image/route.ts
export async function POST ( req : Request ) {
const { prompt } = await req . json ();
const response = await fetch ( 'https://api.venice.ai/api/v1/image/generate' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . VENICE_API_KEY } ` ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
model: 'qwen-image' ,
prompt ,
width: 1024 ,
height: 1024 ,
}),
});
const data = await response . json ();
return Response . json ({ image: data . images [ 0 ] });
}
Chat multi-modèles (sélecteur de modèle)
Laissez les utilisateurs choisir parmi les modèles Venice :
// app/api/chat/route.ts
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const ALLOWED_MODELS = [
'venice-uncensored' ,
'zai-org-glm-5-1' ,
'qwen3-vl-235b-a22b' ,
'qwen3-5-9b' ,
];
export async function POST ( req : Request ) {
const { messages , model : modelId } = await req . json ();
if ( ! ALLOWED_MODELS . includes ( modelId )) {
return new Response ( 'Invalid model' , { status: 400 });
}
const result = streamText ({
model: venice ( modelId ),
messages ,
});
return result . toDataStreamResponse ();
}
// Composant client avec sélecteur de modèle
'use client' ;
import { useChat } from '@ai-sdk/react' ;
import { useState } from 'react' ;
const MODELS = [
{ id: 'venice-uncensored' , name: 'Venice Uncensored' , desc: 'Fast & uncensored' },
{ id: 'zai-org-glm-5-1' , name: 'GLM 5.1' , desc: 'Most intelligent (private)' },
{ id: 'qwen3-vl-235b-a22b' , name: 'Qwen Vision' , desc: 'Advanced vision + text' },
{ id: 'qwen3-5-9b' , name: 'Qwen 3.5 9B' , desc: 'Fastest & cheapest' },
];
export default function Chat () {
const [ model , setModel ] = useState ( 'venice-uncensored' );
const { messages , input , handleInputChange , handleSubmit } = useChat ({
body: { model },
});
return (
< div >
< select value = { model } onChange = { ( e ) => setModel ( e . target . value ) } >
{ MODELS . map (( m ) => (
< option key = { m . id } value = { m . id } > { m . name } — { m . desc } </ option >
)) }
</ select >
{ /* ... UI du chat ... */ }
</ div >
);
}
Intégration de la recherche web
Passez les paramètres Venice pour la recherche web :
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const result = streamText ({
model: venice ( 'venice-uncensored' ),
messages: [{ role: 'user' , content: 'What happened in AI news today?' }],
// Paramètres spécifiques à Venice
experimental_providerMetadata: {
venice_parameters: {
enable_web_search: 'auto' ,
},
},
});
Si experimental_providerMetadata n’est pas transmis, vous pouvez utiliser un wrapper fetch personnalisé ou appeler l’API Venice directement pour les fonctionnalités de recherche web.
Embeddings
Pour les embeddings, utilisez textEmbeddingModel() directement sur le provider :
import { embed , embedMany } from 'ai' ;
import { createOpenAI } from '@ai-sdk/openai' ;
const openai = createOpenAI ({
apiKey: process . env . VENICE_API_KEY ! ,
baseURL: 'https://api.venice.ai/api/v1' ,
});
// Embedding unique
const { embedding } = await embed ({
model: openai . textEmbeddingModel ( 'text-embedding-bge-m3' ),
value: 'Privacy-first AI infrastructure' ,
});
// Embeddings par lot
const { embeddings } = await embedMany ({
model: openai . textEmbeddingModel ( 'text-embedding-bge-m3' ),
values: [
'Venice AI provides private inference.' ,
'Zero data retention guaranteed.' ,
'OpenAI SDK compatible.' ,
],
});
Variables d’environnement
# .env.local
VENICE_API_KEY = your-venice-api-key
Modèles recommandés
Cas d’usage Modèle Pourquoi Applis de chat venice-uncensoredRapide, économique, sans filtrage Tâches complexes zai-org-glm-5-1Raisonnement phare privé Applis vision qwen3-vl-235b-a22bCompréhension d’images avancée Fort volume qwen3-5-9bLe moins cher à 0,10 $/1 M entrée, 0,15 $/1 M sortie Tool calling zai-org-glm-5-1Function calling fiable
Docs du Vercel AI SDK Documentation officielle du Vercel AI SDK
Modèles Venice Parcourir tous les modèles Venice