Zum Inhalt springen

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 in KENNMARQ_API_KEY auf dem Server.
  • Schritt: das Modell wrappen: generateImage gibt 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
// 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

TypeScript
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
// 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

TypeScript
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