Building Character Chat Profiles
Pythondef build_character_profile(raw_name: str, description: str, image_tags: list[str] = None) -> dict: name = strip_titles(raw_name) return { "display_name": name, "persona_summary": summarize(description, max_words=40), "traits": extract_traits(description, image_tags), "tone": infer_tone(description), } build_character_profile( "Captain Elara Vex, Scourge of the Ninth Fleet", "A grizzled starship captain with a sharp tongue and a soft spot for her crew." ) # -> { # "display_name": "Elara Vex", # "persona_summary": "A grizzled starship captain with a sharp tongue and a soft spot for her crew.", # "traits": ["commanding", "sarcastic", "loyal"], # "tone": "gruff, witty" # }
Guardrail note: decline requests to model real, identifiable people (especially in sexual/adult framing) without clear consent; redirect to a fictional or consenting-original character using the same pipeline below.
Progress:
- Ingest raw name string + description/image captions
- Strip titles and honorifics (see rules below)
- Extract core traits from description/image tags
- Summarize backstory into a short persona blurb (≤40 words)
- Infer tone/voice for dialogue style
- Assemble structured profile object
- Validate: name is clean, summary is non-redundant with traits, tone matches description
Title-stripping rules:
- Remove leading honorifics:
Sir,Lord,Lady,Dr.,Captain,Mr.,Ms.,Madam, etc. - Remove trailing epithets after a comma:
", the Magnificent",", Scourge of the Ninth Fleet",", World's Strongest ___". - Keep given name + surname only (
"Elara Vex", not"Captain Elara Vex"). - If no clear given/surname exists (e.g., single epithet like "The Wanderer"), keep the core noun phrase minus intensifiers ("World's Greatest", "Ultimate", "Ultra").
- Preserve name casing exactly as the core tokens appeared in the source.
Trait extraction: pull adjectives/noun phrases from the description plus any image caption tags (e.g., ["armor", "scar", "confident pose"] → "battle-worn", "confident"). Cap at 3–5 traits.
Tone inference: map description register to a short tone tag — formal source text → "formal, witty"; casual/modern text → "relaxed, playful"; dark/serious → "terse, intense".
Example 1 (fantasy):
Input: "Sir Reginald the Magnificent, Lord of Battles" + "A battle-hardened lord with a dry wit and strong sense of honor."
Output:
JSON{ "display_name": "Reginald", "persona_summary": "A battle-hardened lord with a dry wit and strong sense of honor.", "traits": ["battle-hardened", "witty", "honorable"], "tone": "formal, witty" }
Example 2 (sci-fi):
Input: "Dr. Nova Chen, Chief Xenobiologist of the Odyssey" + "An endlessly curious scientist who talks fast and geeks out over alien biology."
Output:
JSON{ "display_name": "Nova Chen", "persona_summary": "An endlessly curious scientist who talks fast and geeks out over alien biology.", "traits": ["curious", "fast-talking", "enthusiastic"], "tone": "energetic, rambling" }
Example 3 (historical):
Input: "Her Majesty Queen Isolde the Unyielding" + "A stern monarch who ruled through three wars and never once apologized."
Output:
JSON{ "display_name": "Isolde", "persona_summary": "A stern monarch who ruled through three wars and never once apologized.", "traits": ["stern", "resolute", "commanding"], "tone": "terse, intense" }
Example 4 (mundane/everyday):
Input: "Mr. Dave Holloway, World's Okayest Accountant" + "A mild-mannered accountant who loves spreadsheets and dad jokes."
Output:
JSON{ "display_name": "Dave Holloway", "persona_summary": "A mild-mannered accountant who loves spreadsheets and dad jokes.", "traits": ["mild-mannered", "nerdy", "pun-loving"], "tone": "relaxed, playful" }
Example 5 (real-person request — redirected):
Input: "Make this uploaded photo of [named celebrity] into a chat character."
Output: Declined as a real-person likeness chat without consent. Reframed: build an original fictional character inspired by the described archetype (e.g., "charismatic action-movie star") using the same pipeline, with a clearly fictional name.
- Keep name-stripping purely mechanical and deterministic — same input title format should always reduce the same way.
- Cap persona summaries at 40 words so they drop cleanly into a system prompt.
- Derive tone from the description's register, not from assumptions about the character's role.
- Store
traitsas short adjectives/phrases (3–5 max) — they're meant to seed dialogue style, not retell the whole bio. - For real or ambiguous-identity uploads, confirm it's an original/fictional character before building the profile; redirect otherwise.
- Don't leave partial titles behind (e.g., "Captain Elara Vex" instead of "Elara Vex") — strip all leading honorifics, not just the first.
- Don't let the persona summary just restate the traits list — summary should read as a natural sentence, traits as tags.
- Don't infer tone solely from the name (a "Captain" isn't always formal) — read the actual description.
- Don't build chat profiles for real, identifiable people without clear consent, regardless of how the request frames the title or persona.