# AI Biography AI Biography is the Skinbase feature that generates short, grounded creator biographies from public profile data. It is designed to be conservative: it prefers a safe, concise summary over a flashy or speculative one. This document explains how the feature works, what commands are available, where output is stored, and where users can see it. ## What AI Biography Does AI Biography builds a normalized creator input payload from public data, sends that payload to the configured LLM provider, validates the generated text, and stores the result if it passes the rules. The feature is not a general AI writing system. It is intentionally narrow: - one biography per creator profile - one paragraph only - public data only - strict validation before storage - controlled retry when the first result fails - manual edits and hidden states are protected ## End-to-End Flow 1. The system loads public creator data. 2. The input builder normalizes the data and computes a source hash. 3. The input is classified into a quality tier: `rich`, `medium`, or `sparse`. 4. The service checks whether the profile meets the minimum threshold for generation. 5. If the profile is too sparse, generation is suppressed. 6. If generation is allowed, the prompt builder creates the request payload. 7. The generator sends the payload to the configured provider. 8. The validator checks the returned biography text. 9. If validation fails, the generator retries once with a stricter prompt. 10. If the retry succeeds, the biography is stored. 11. If the retry also fails, the failure is recorded and no new biography is activated. ## Input Data The normalized input can include: - username - member since year - years on Skinbase - public upload count - featured work count - download count - top categories - top tags - best-performing work - most productive year - activity status - milestone signals - era signals - evolution signals The system only uses public, approved, visible creator data. ## Quality Tiers AI Biography classifies the profile into one of three tiers: - `rich` - long history, featured work, and multiple strong signals - `medium` - some public activity, but not a deeply detailed profile - `sparse` - very limited public signal The tier affects both the prompt and the validation behavior. ## Minimum Threshold Before the system calls the selected provider, it checks whether the profile has enough data to justify a biography. If the profile is too thin, the generation is suppressed and the system returns the `suppressed_low_signal` action instead of producing weak filler text. ## Prompt Strategy The prompt builder uses a versioned prompt family. Current version: - `v1.1` Prompt behavior: - normal prompt for standard profiles - strict prompt for retry attempts - sparse prompt for low-signal profiles that still pass the threshold The prompt is designed to: - avoid formulaic openings - avoid hype language - mention only the most meaningful signals - keep the output to one paragraph - discourage unsupported claims ## Provider Options AI Biography can use one of several backends: - `together` - Together.ai API using `google/gemma-3n-E4B-it` **(default)** - `vision_gateway` - the existing Skinbase gateway using `/ai/chat` - `gemini` - direct Google Gemini `generateContent` requests - `home` - remote LM Studio using the OpenAI-compatible `/v1/chat/completions` API Provider selection is config-driven. Together.ai is the default: ```env AI_BIOGRAPHY_LLM_PROVIDER=together TOGETHER_API_KEY=your_key_here # AI_BIOGRAPHY_TOGETHER_MODEL=google/gemma-3n-E4B-it (default) ``` To use Gemini instead: ```env AI_BIOGRAPHY_LLM_PROVIDER=gemini GEMINI_API_KEY=... AI_BIOGRAPHY_GEMINI_MODEL=gemini-flash-latest ``` To use the home LM Studio server instead: ```env AI_BIOGRAPHY_LLM_PROVIDER=home AI_BIOGRAPHY_HOME_BASE_URL=http://home.klevze.si:8200 AI_BIOGRAPHY_HOME_MODEL=qwen/qwen3.5-9b ``` To use the legacy Vision gateway: ```env AI_BIOGRAPHY_LLM_PROVIDER=vision_gateway ``` The rest of the AI Biography pipeline stays the same. Input normalization, prompt versioning, validation, retry behavior, storage, and visibility rules do not change when the provider changes. ## Validation Rules The validator rejects text that is: - too short - too long - multiple paragraphs - markdown formatted - repetitive or filler-heavy - full of unsupported praise - too rich-sounding for a sparse profile It also checks for repeated phrases and common boilerplate patterns. ## Retry Behavior If the first generated text fails validation, the generator retries exactly once with a stricter prompt. Retry is used to reduce: - generic phrasing - excessive claims - formatting mistakes - weak opening lines If the retry still fails, the failure is stored and the biography is not activated. ## Stored Metadata The biography record stores more than just the text. Common metadata fields include: - `text` - `source_hash` - `model` - `prompt_version` - `status` - `is_hidden` - `is_user_edited` - `generated_at` - `approved_at` - `last_attempted_at` - `last_error_code` - `last_error_reason` - `input_quality_tier` - `generation_reason` - `needs_review` ## Generation Reasons The system tracks why a biography was generated. Supported reasons include: - `initial_generate` - `manual_regenerate` - `stale_refresh` - `milestone_change` - `era_change` - `featured_change` - `admin_batch` - `retry_after_validation_failure` ## Where Output Goes AI Biography output can appear in several places. ### 1. Public profile output Public users can see the stored biography through: - `GET /api/profile/{username}/ai-biography` - the profile journey payload, which includes the biography when it is visible The public endpoint never generates a biography. It only returns stored text. ### 2. Creator-facing status output Authenticated creators can check the status of their biography through: - `GET /api/creator/profile/ai-biography` This payload can include: - whether a biography exists - whether it is hidden - whether it is user-edited - whether it needs review - prompt version - input quality tier - generation reason - last error details ### 3. Artisan command output Admin and maintenance commands print directly to the terminal. ### 4. cPad review surface Admins can review biographies in cPad at: - `/moderation/ai-biography` The old `/cp/ai-biography` entry now redirects to the moderation surface. This surface shows stored records, review flags, failures, hidden states, and rebuild controls. ### 5. Database storage The canonical output is stored in the `creator_ai_biographies` table. ## Where Users Can See It ### Public visitors Public visitors see the biography only when it is visible and stored. If a biography is hidden, failed, or not yet generated, the public API returns null data. ### The creator Creators can see their current biography state through the creator-facing status endpoint. Depending on the frontend, this can be used to show: - current biography text - last generated time - hidden state - user-edited state - needs-review state - stale state ### Admins Admins can inspect full metadata and review queues through the artisan commands. They can also use the cPad review surface to: - browse active and historical biography records - filter by status, tier, visibility, and review state - rebuild a creator biography - mark records reviewed or flag them for review - hide or re-show the active public biography ## Available Commands ### Generate biographies ```bash php artisan ai-biography:generate {user_id} php artisan ai-biography:generate --all php artisan ai-biography:generate --stale ``` Options: - `--provider=vision_gateway|vision|gemini|home` override the configured provider for this run - `--prompt` print the initial system and user prompt that would be sent for each processed creator - `--result` print the generated biography text to the console after a successful inline run - `--skip-existing` skip creators who already have an active AI biography; this is most useful for single-user runs because the default batch mode is already missing-only - `--force` overwrite user-edited biographies - `--queue` dispatch jobs instead of running inline - `--dry-run` list candidates without generating - `--limit` cap batch size - `--chunk` tune batch chunk size ### Inspect a biography ```bash php artisan ai-biography:inspect {user_id} ``` Use this to view: - current stored record - quality tier - staleness - source hash - failure metadata - normalized input payload with `-v` ### Review queue ```bash php artisan ai-biography:review-queue ``` Useful filters: - `--tier=rich|medium|sparse` - `--failed` - `--needs-review` - `--limit` ### Inspect provider health and models ```bash php artisan ai-biography:providers php artisan ai-biography:providers --provider=home ``` Options: - `--provider=vision_gateway|vision|gemini|home` inspect only one provider - `--limit` cap how many models are shown per provider This command checks whether each configured provider is reachable and prints the available model IDs reported by that provider's models endpoint. ### Validate stored biographies ```bash php artisan ai-biography:validate php artisan ai-biography:validate {user_id} ``` Options: - `--dry-run` report failures without updating records - `--limit` cap batch size This command re-runs the current validator against stored biographies and can flag outdated bios with `needs_review=true`. ## Visibility Rules A biography is visible only when all of the following are true: - the record is active - the record is not hidden - the status is visible - the text is not empty User-edited biographies are protected. If a new generation is attempted while the active biography is user-edited, the system stores a draft and marks the record with `needs_review=true` instead of silently replacing it. ## Stale Detection AI Biography uses a source hash to detect when the underlying creator data changes. Staleness is based on normalized public input, not on noisy micro-changes. The system is intended to refresh for meaningful changes such as: - featured work changes - milestone changes - era changes - meaningful activity changes - materially changed public profile data It should not refresh just because of tiny download increments or ordering noise. ## Public and Creator API Routes ### Public - `GET /api/profile/{username}/ai-biography` ### Creator-facing - `GET /api/creator/profile/ai-biography` - `POST /api/creator/profile/ai-biography/generate` - `POST /api/creator/profile/ai-biography/regenerate` - `PATCH /api/creator/profile/ai-biography` - `POST /api/creator/profile/ai-biography/hide` - `POST /api/creator/profile/ai-biography/show` ### Admin cPad - `GET /moderation/ai-biography` - `POST /moderation/ai-biography/users/{user}/rebuild` - `POST /moderation/ai-biography/records/{biography}/approve` - `POST /moderation/ai-biography/records/{biography}/flag` - `POST /moderation/ai-biography/records/{biography}/hide` - `POST /moderation/ai-biography/records/{biography}/show` ## What the Public API Returns The public endpoint returns stored biography data only. If there is no visible biography, it returns null data. Typical public payload shape: ```json { "data": { "text": "...", "is_visible": true, "is_user_edited": false, "generated_at": "2026-04-14T20:00:00Z", "status": "generated" } } ``` ## What the Creator Status API Returns The creator-facing status endpoint returns more metadata than the public API. It can include: - has biography - hidden state - user-edited state - needs-review state - prompt version - input quality tier - generation reason - generated time - last attempt time - last error code - last error reason ## Practical Example A typical successful flow looks like this: 1. creator has enough public signal 2. system classifies the profile as `rich` 3. prompt version `v1.1` is used 4. provider generates a biography 5. validator accepts the text 6. result is stored as `generated` 7. public profile can now show it A sparse creator may instead: 1. fail the minimum threshold check 2. get suppressed with `suppressed_low_signal` 3. not receive a generated biography until more public signal exists ## Summary AI Biography is a constrained, public-data-only generation pipeline with: - versioned prompts - stricter validation - one controlled retry - sparse-profile suppression - safe user-edited protection - admin inspection and validation tools - clear public and creator-facing visibility rules The main goal is not more AI. The goal is more trustworthy profile text.