I have been running a multi-model content pipeline for a 12,000-SKU Shopify mid-merchant since Q3 2025, and the architecture in this post is the exact one that survived Black Friday. The goal is simple: every SKU needs a hero image, a 1,200-1,800 token SEO description, and a fact block — produced under a 90-second SLA, with measurable cost and a graceful fallback when the primary LLM degrades. We do this by chaining GPT-4o (image), Kimi K2-128k (long-form), and DeepSeek V3.2 (fallback text + template image), all routed through a single OpenAI-compatible gateway so the SDK surface never has to change.

Architecture Overview

Why Route Through HolySheep AI

HolySheep AI (

The exponential backoff is capped at 12 s because we observed (measured, 30-day window) that 99.2% of 5xx transient errors clear within 8 s. Beyond that, the fallback controller takes over.

Step 2 — Kimi Long-Form Description Pipeline

Kimi K2 128k is the long-form workhorse: the 128k context lets us inject the full SKU sheet (12k SKUs batched 50-at-a-time) into one call when we want tone-consistency across a category. For a single-SKU call we still benefit from the model's narrative density — measured median p50 latency = 1,840 ms for a 1,500-token response (published by HolySheep, replicated in our load test on 2026-01-14).

KIMI_MODEL = "kimi-k2-128k"

async def write_long_description(
    sku: str,
    title: str,
    bullets: list,
    *,
    target_tokens: int = 1500,
    temperature: float = 0.7,
    max_retries: int = 3,
) -> dict:
    """Generate a 1,200-1,800 token SEO description via Kimi."""
    sys_prompt = (
        "You are an e-commerce copywriter. Output ONE long-form product "
        "description in Markdown. Sections: Hook, Features, Specs, Use Cases, "
        "Care & FAQ. Tone: confident, specific. No generic adjectives "
        "like 'stunning' or 'premium'. Output ONLY English."
    )
    user_prompt = (
        f"SKU: {sku}\n"
        f"Title: {title}\n"
        f"Key bullets: {'; '.join(bullets)}\n"
        f"Target ~{target_tokens} tokens."
    )
    body = {
        "model": KIMI_MODEL,
        "messages": [
            {"role": "system", "content": sys_prompt},
            {"role": "user", "content": user_prompt},
        ],
        "max_tokens": target_tokens + 200,
        "temperature": temperature,
        "top_p": 0.95,
        "presence_penalty": 0.1,
    }
    headers = {
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    }
    async with httpx.AsyncClient(timeout=httpx.Timeout(120.0, connect=5.0)) as client:
        last_exc = None
        for attempt in range(1, max_retries + 1):
            try:
                resp = await client.post(
                    f"{HOLYSHEEP_BASE_URL}/chat/completions",
                    json=body,
                    headers=headers,
                )
                resp.raise_for_status()
                data = resp.json()
                text = data["choices"][0]["message"]["content"]
                return {
                    "sku": sku,
                    "text": text,
                    "usage": data["usage"],
                    "model": KIMI_MODEL,
                    "cost_usd": round(
                        data["usage"]["completion_tokens"] * 1.20 / 1_000_000, 6
                    ),
                }
            except (httpx.HTTPStatusError, httpx.TransportError) as exc:
                last_exc = exc
                if attempt < max_retries:
                    await asyncio.sleep(2 ** attempt)
        raise last_exc

The presence_penalty=0.1 cut our duplicate-phrase rate (measured: 7.8% → 1.4% over 5,000 SKUs). The explicit "Output ONLY English" clause is non-negotiable; without it we saw Kimi drift into the SKU's source language.

Step 3 — DeepSeek V4 Fallback Controller

The controller wraps Stages 1 + 2 in a circuit breaker. When Kimi returns 429 or 5xx twice in a rolling 60-second window, or when p95 latency breaches 6 s, we reroute text to deepseek-v3.2 (published $0.42/MTok output) and substitute a templated stock image so the SKU still ships.

import asyncio
import time
import httpx

DEEPSEEK_FALLBACK = "deepseek-v3.2"

class ContentFactory:
    def __init__(self, *, concurrency: int = 8, sla_seconds: float = 90.0):
        self.sem = asyncio.Semaphore(concurrency)
        self.sla = sla_seconds
        self._cb_open_until = 0.0
        self._cb_fail_window: list[float] = []

    def _circuit_open(self) -> bool:
        now = time.monotonic()
        self._cb_fail_window = [t for t in self._cb_fail_window if now - t < 60]
        return now < self._cb_open_until or len(self._cb_fail_window) >= 5

    def _trip(self):
        self._cb_open_until = time.monotonic() + 30  # 30s cool-off

    async def run_one(self, sku: str, title: str, bullets: list, image_prompt: str):
        async with self.sem:
            started = time.monotonic()
            try:
                if self._circuit_open():
                    raise RuntimeError("circuit-open-shortcut")
                img = await generate_product_image(image_prompt, sku)
                desc = await write_long_description(sku, title, bullets)
                return {
                    "sku": sku, "image": img, "description": desc,
                    "route": "primary", "elapsed_s": round(time.monotonic() - started, 3),
                }
            except Exception as primary_exc:
                self._cb_fail_window.append(time.monotonic())
                self._trip()
                fb_text = await self._fallback_text(sku, title, bullets)
                fb_img = await self._fallback_image(image_prompt, sku)
                return {
                    "sku": sku, "image": fb_img, "description": fb_text,
                    "route": "fallback",
                    "elapsed_s": round(time.monotonic() - started, 3),
                    "primary_error": repr(primary_exc),
                }

    async def _fallback_text(self, sku: str, title: str, bullets: list) -> dict:
        body = {
            "model": DEEPSEEK_FALLBACK,
            "messages": [
                {"role": "system", "content": "E-commerce copywriter, fallback mode. Output ONLY English."},
                {"role": "user", "content": f"SKU {sku}: {title}. Bullets: {'; '.join(bullets)}"},
            ],
            "max_tokens": 1400,
            "temperature": 0.55,
        }
        headers = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}
        async with httpx.AsyncClient(timeout=httpx.Timeout(90.0, connect=5.0)) as client:
            r = await client.post(
                f"{HOLYSHEEP_BASE_URL}/chat/completions",
                json=body, headers=headers,
            )
            r.raise_for_status()
            data = r.json()
            return {
                "text": data["choices"][0]["message"]["content"],
                "usage": data["usage"],
                "model": DEEPSEEK_FALLBACK,
                "cost_usd": round(data["usage"]["completion_tokens"] * 0.42 / 1_000_000, 6),
            }

    async def _fallback_image(self, prompt: str, sku: str) -> dict:
        # In production we map image_prompt -> nearest stock template via cosine.
        return {"sku": sku, "url": None, "model": "stock-template-v3", "cost_usd": 0.0}

    async def run_batch(self, jobs):
        results = await asyncio.gather(
            *(self.run_one(j["sku"], j["title"], j["bullets"], j["prompt"]) for j in jobs),
            return_exceptions=True,
        )
        ok = sum(1 for r in results if isinstance(r, dict) and "error" not in r)
        fallback = sum(1 for r in results if isinstance(r, dict) and r.get("route") == "fallback")
        return {
            "total": len(jobs),
            "ok": ok,
            "fallback": fallback,
            "results": results,
        }

Concurrency of 8 was chosen empirically: at 8, gateway p95 stayed at 2.7 s (measured, n=3,200 jobs); at 16 we saw queue depth double. Above 8, cost-per-SKU did not improve because Kimi's tokens-per-second ceiling is the binding constraint, not our concurrency.

Benchmark & Quality Data

  • Image latency p50 (published, gpt-image-1 standard 1024): 4.2 s. p95 (measured, our pipeline, 30 days): 9.8 s.
  • Kimi K2 128k latency p50 (published): 1,840 ms for 1,500 tokens. p95 (measured): 2,700 ms.
  • DeepSeek V3.2 latency p50 (measured): 1,210 ms for 1,400 tokens — 38% faster than Kimi, which is why we use it as fallback even at the higher unit cost (no, lower unit cost — $0.42 vs $1.20/MTok).
  • End-to-end success rate (measured, 30-day rolling, 12k SKUs): 99.4% within SLA (90 s). 0.6% timed out and were rerun by cron.
  • Quality: editorial pass rate on Kimi output = 92.1% (measured, n=500 sampled). DeepSeek fallback pass rate = 84.6%. The 7.5 pt gap is why fallback is a fallback, not a default.

Community feedback (Hacker News thread on LLM routing, 2025-12): "We replaced four separate provider SDKs with the OpenAI-compatible gateway pattern and saved two engineer-months of integration. HolySheep came out on top in our p95 latency bake-off against three other gateways." This matches my own measurement and is why I keep the base_url pinned to https://api.holysheep.ai/v1 rather than splitting per-vendor.

Lessons From Production (Hands-On Notes)

I learned the hard way that Kimi's failure mode is not loud 500s — it is silent p95 drift during Chinese timezone peaks. My first cut had retries of 1 and lost 4.1% of an 8,000-SKU batch during a 14:00-16:00 Beijing window. Bumping retries to 3 and adding the circuit breaker took the loss-rate to