Vercel AI SDK
Eine Middleware markiert, was das AI SDK erzeugt, für die KI-Verordnung der EU und für Kalifornien: jedes Bild aus generateImage und, mit einem gewrappten Modell, jeden Clip aus generateSpeech und jedes Video aus experimental_generateVideo. Sie funktioniert mit jedem Modell, das das SDK erreicht, über das AI Gateway oder ein Provider-Paket.
Auf einen Blick
- Paket:
npm install @kennmarq/ai-sdk, mit dem Schlüssel inKENNMARQ_API_KEYauf dem Server. - Schritt: das Modell wrappen:
generateImagegibt dann die markierten Bilder zurück und schlägt fehl, wenn sich eines nicht markieren lässt. - Modelle: alle, auch FLUX, GPT Image, Imagen und Recraft; Content Credentials, die ein Anbieter bereits hinzugefügt hat, bleiben erhalten.
- Geschrieben für: AI SDK 7 (das Paket ai), geprüft am 4. November 2026.
Jedes Bild markieren: die Middleware
// app/api/image/route.ts
import { generateImage, wrapImageModel } from "ai";
import { openai } from "@ai-sdk/openai";
import { kennmarqImageMiddleware } from "@kennmarq/ai-sdk";
const model = wrapImageModel({
model: openai.image("gpt-image-1"), // any image model, any provider
middleware: kennmarqImageMiddleware({
provider: "Acme Inc.", // your legal name
appName: "Acme Studio", // your AI system, with its version
appVersion: "2.1",
markets: ["eu", "us-ca"],
}),
});
export async function POST(request: Request) {
const { prompt } = await request.json();
const { image } = await generateImage({ model, prompt }); // already marked
return new Response(image.uint8Array, { headers: { "Content-Type": image.mediaType } });
}Bilder, die aus Eingabebildern entstehen, werden als edited markiert, die übrigen als created. Die Markierung jedes Bildes steht in providerMetadata.kennmarq.images, für seinen Nachweis. Um jedes Bild zu markieren, das ein Provider erzeugt, übergeben Sie die Middleware an wrapProvider als imageModelMiddleware.
Sprache und Video
import { experimental_generateVideo, generateSpeech } from "ai";
import { fal } from "@ai-sdk/fal";
import { openai } from "@ai-sdk/openai";
import { kennmarqSpeechModel, kennmarqVideoModel } from "@kennmarq/ai-sdk";
const origin = { provider: "Acme Inc.", appName: "Acme Studio", appVersion: "2.1", markets: ["eu"] };
const { audio } = await generateSpeech({
model: kennmarqSpeechModel(openai.speech("gpt-4o-mini-tts"), origin),
text: "Hello!",
outputFormat: "mp3", // MP3, WAV or M4A
});
const { video } = await experimental_generateVideo({
model: kennmarqVideoModel(fal.video("luma-ray-2"), origin),
prompt: "Waves at dusk",
});Sprache erhält AudioSeal im Ton, was niemand hört; Videos (MP4) erhalten Video Seal in jedem Einzelbild. Ein Video wird als Auftrag markiert, daher wartet der Aufruf darauf, und das Zeitlimit von experimental_generateVideo zählt die Wartezeit mit.
Oder erst generieren, dann markieren
// app/api/image/route.ts
import { generateImage } from "ai";
import { mark } from "@/lib/kennmarq"; // the helper from the Next.js guide
export const maxDuration = 60;
export async function POST(request: Request) {
const { prompt } = await request.json();
const { image } = await generateImage({ model: "bfl/flux-3-image", prompt });
const file = new Blob([image.uint8Array], { type: image.mediaType });
const marked = await mark(file, `image.${image.mediaType.split("/")[1]}`, { model: "FLUX.3" });
// Only the marked copy leaves this route. If mark() threw, the request fails instead.
return new Response(marked, { headers: { "Content-Type": image.mediaType } });
}Dieselben zwei Zeilen funktionieren in einer Server Action oder überall, wo Ihr Server generateImage aufruft. Das Modell kommt hier vom AI Gateway; mit einem Provider-Paket übergeben Sie stattdessen dessen Modell.
Mehrere Bilder auf einmal
const { images } = await generateImage({ model: "bfl/flux-3-image", prompt, n: 4 });
// One call each. One after another keeps a Free plan (10 calls a minute) well within its limit.
const marked: Blob[] = [];
for (const image of images) {
marked.push(await mark(new Blob([image.uint8Array], { type: image.mediaType }), "image.png"));
}Bilder, die bereits Content Credentials tragen
Einige Anbieter signieren ihre Bilder mit eigenen Content Credentials. Diese behalten wir als Bestandteil unserer bei, wie es der Verhaltenskodex der EU verlangt, und fügen Ihr Unternehmen und Ihre App, das Wasserzeichen und die fünf Angaben für Kalifornien hinzu.
Nächste Schritte
- Sie möchten lieber keine Hilfsfunktion pflegen?
mark()aus dem JavaScript-SDK nimmtimage.uint8Arrayso, wie es ist. - Videos und Audio laufen über dieselbe Hilfsfunktion: siehe Videos.
- Was jede Markierung trägt: Content Credentials und unsichtbare Wasserzeichen.
- Überlassen Sie es Ihrem Coding-Agenten: der Prompt.