mcpField
D
dev-avatar-service

dev-avatar-service

github.com/picsartDevelopment6312 installsUpdated 2d ago
Repository

About dev-avatar-service

dev-avatar-service is a skill for building an endpoint that returns branded avatars, using a stable seed and a fallback chain. It covers generation, caching, initials-based SVG fallbacks, and batch preparation for existing users.

Key features

  1. 01Seed-based consistent avatars
  2. 02Photo and generated-avatar fallbacks
  3. 03Caching URLs by seed
  4. 04Initials-based SVG fallback
  5. 05Batch cache prewarming

Use cases

  1. 01Providing avatars at signup
  2. 02Filling profile images in forums or directories
  3. 03Showing placeholders during onboarding
  4. 04Preparing avatars for staging demos

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/picsart/gen-ai-skills --skill dev-avatar-service

After installing, type/dev-avatar-servicein Claude Code to confirm it loaded.

Details

From the project README

Avatar service

A service endpoint that returns a branded avatar for any user: photoreal, illustrated, or pixel, deterministic from a seed (user ID / email hash / initials). Built around a fallback hierarchy — real photo → upload → AI from initials → static default — with caching by seed so you pay once per user.

When to Use

  • New user signup where you need an immediate profile image.
  • Comment systems or forums that default to gravatars.
  • Team pages, directories, leaderboards without uploaded photos.
  • Placeholder avatars during onboarding before the user picks one.
  • Branded alternative to Gravatar / UI Avatars / DiceBear.
  • Mock data for staging/demo environments.

Not for: deepfaking real people from a single photo (wrong tool + wrong ethics), or stylizing an already-great uploaded photo — let users keep their own.

Prerequisites

Before building, ask (one message, 5 questions):

  1. Seed source: user ID, email hash, username, initials? Is it stable forever?
  2. Style: photoreal portrait, illustrated (Pixar/Disney-ish), flat vector, pixel art, claymorphic, monogram?
  3. Brand palette: accent color for backgrounds + monogram fallbacks.
  4. Storage + cache: S3/CDN + DB column, Picsart Drive URL, or KV key? TTL?
  5. Fallback chain: photo → AI avatar → initials-on-color → default SVG? Order matters.

Skip if the user hands over a detailed brief.

How to Run

  1. Decide the fallback hierarchy first. This is the whole service:

    1. user.photo_url          → return as-is
    2. cache.get(seed)         → return stored AI avatar URL
    3. gen-ai generate         → store URL + return
    4. initials on brand color → SVG fallback (no credits)
    5. static /default.png     → last resort
    
  2. Estimate + validate model.

    gen-ai models info recraftv4
    gen-ai pricing recraftv4
    gen-ai generate -m recraftv4 -p "illustrated avatar, seed abc123" \
      --aspect-ratio 1:1 --dry-run --debug
    
  3. Deterministic seed → prompt. Hash the seed into stable attribute picks. Never inject Math.random() or timestamps.

    SEED="u_482c91"
    # Pick palette + mood from the seed, not from RNG
    HUE=$(printf "%s" "$SEED" | shasum | cut -c1-2)   # 0-255 from hash
    gen-ai generate -m recraftv4 \
      -p "illustrated profile avatar, round frame, abstract humanoid silhouette, HSL hue ${HUE}, friendly neutral expression, flat vector, centered composition, studio background" \
      --aspect-ratio 1:1 \
      --negative-prompt "text, watermark, letters, realistic face, specific person" \
      --save-to-drive --drive-folder avatars \
      --json --no-input | jq -r '.url'
    
  4. Cache the URL (not the binary) keyed on the seed. Any store: Redis, KV, Postgres column, S3 + stable filename.

  5. Initials fallback (zero credits). When gen-ai is down, rate-limited, or over budget — return an SVG built from the user's initials on a hue derived from the same seed. Users never see a broken image.

    const initials = name.split(' ').map(p => p[0]).slice(0, 2).join('').toUpperCase();
    const hue = parseInt(sha1(seed).slice(0, 2), 16);
    const svg = `<svg viewBox="0 0 64 64"><rect width="64" height="64" fill="hsl(${hue} 70% 45%)"/><text x="32" y="40" text-anchor="middle" font-size="28" fill="#fff" font-family="system-ui">${initials}</text></svg>`;
    
  6. Wire the endpoint. /avatar/:seed → check photo → check cache → gen-ai → initials. 302 to CDN URL on success; inline SVG on fallback.

  7. Pre-warm the cache in batch for existing users so your prod rollout doesn't hammer gen-ai live:

    gen-ai batch run avatars-backfill.json -c 4 -o ./avatars-out
    

Quick Reference

Backfill 500 existing users:

{
  "defaults": {
    "model": "recraftv4",
    "aspectRatio": "1:1",
    "negativePrompt": "text, watermark, letters, realistic face, specific person"
  },
  "jobs": [
    { "id": "u_482c91", "prompt": "illustrated profile avatar, round frame, flat vector, hue 42, friendly neutral, studio background" },
    { "id": "u_91ac3b", "prompt": "illustrated profile avatar, round frame, flat vector, hue 128, calm expression, studio background" },
    { "id": "u_7de119", "prompt": "illustrated profile avatar, round frame, flat vector, hue 201, warm smile, studio background" }
  ]
}

Output lands at ./avatars-out/<user-id>.webp — upload to your CDN under the same key. results.json becomes the seed → URL lookup table.

Quick Reference

Sub-taskModelWhy
Illustrated / vector / flat avatarsrecraftv4Clean, consistent, cheap — ideal default
Photoreal portrait (synthetic, generic person)flux-2-proBest faces; use with generic descriptors only
Pixel-art avatarsrecraftv4 with pixel-style promptLowest credits, stylistic control
Stylize an uploaded real photo (opt-in)flux-kontext-pro + -i photo.jpgEdit model preserves identity
Cheap draft / style explorationgemini-3.1-flash-imageLowest per-call cost
Identity-locked variants across sizesideogram-character + -i master.pngSame face across multiple avatars

Verify live IDs with gen-ai models --mode image.

Procedure

  • Determinism = cacheability. Derive every variable attribute (hue, pose, expression) from a hash of the seed. Same seed → same prompt → same image → one credit forever.
  • Version the prompt template. Bump V=2 in the cache key when you restyle; old avatars age out, new ones regenerate on demand.
  • Fallback is not optional. Initials-on-hue SVG must always work. Never let the UI render a broken avatar because gen-ai 429'd.
  • Negative prompt matters. Always exclude text, watermark, letters, realistic face of specific person — avatars must not resemble real celebrities or render accidental copy.
  • Don't generate on every page load. Generate once per seed, cache forever (or until template version bump). A viral signup spike must not trigger a gen-ai spike.
  • Use Drive for storage. --save-to-drive --drive-folder avatars gives a stable CDN URL with no extra infra.
  • Pre-warm before launch. Batch-generate for existing users; don't migrate live traffic onto a cold cache.
  • Respect user uploads. If the user has uploaded a real photo, return that — never override. AI avatars are for missing photos only.
  • Rate-limit at the edge. Cap gen-ai calls per IP per hour. A bot probing /avatar/:random can burn your credit budget in minutes.

Pitfalls

PitfallFix
Regenerated avatar looks different on every refreshNon-deterministic prompt — hash the seed, derive attributes, no RNG/timestamps
Cache never invalidates after restyleVersion the prompt template (V=3 in the cache key)
AI renders real-looking faces resembling celebritiesAdd negativePrompt: "realistic face of specific person, celebrity, known individual"
Text or watermarks appear in the avatarAdd negativePrompt: "text, watermark, letters, logos"
Bot traffic burns credit budgetRate-limit per IP; allow only authed users to hit the generator; fallback to initials for anons
Gen-ai 429s cause broken avatar UISVG initials fallback must be the last step in the chain
Batch backfill half-failsgen-ai batch resume <out> retries only failures
Different avatar style across the appCommit the prompt template; never let callers pass raw prompts

Verification

Run gen-ai whoami to confirm authentication, then re-run the failed command with --debug.

Cost & time

TaskCreditsTime
1 avatar (Recraft V4, illustrated)1-2~4-8s
1 avatar (Flux 2 Pro, photoreal)3-5~10-15s
1 avatar (Gemini 3.1 Flash, draft)1~3-5s
Initials SVG fallback0<1ms
Cache read (KV/Redis hit)0~2-5ms
Batch of 500 at concurrency 4~750-1000~15-20 min

In steady state, expect >99% cache hit rate — near-zero ongoing cost.

See also

  • gen-ai-use.md — CLI reference, auth, scripting with --json --no-input / jq
  • gen-ai-batch.md — manifest shapes, batch resume, rate-limit strategy, Cloudflare Worker pattern
  • gen-ai-workflows.md — Workflow 6 (headshot studio) for stylizing uploaded photos
  • dev-og-image-service — same caching + determinism patterns for OG cards

Comments

Markdown supported