View a markdown version of this page

Add a Persona - Guidance for Agentic Vehicle Experience on AWS

Add a Persona

A persona in AVX is a named interaction role that determines which data products load into AgentCore Memory at session start, which KB source categories are pre-scoped for retrieval, which tool factories are registered on the agent, and which system prompt body the supervisor uses.

The four files to edit when adding a persona are:

  • agents/supervisor/persona_definitions.py — data bindings and prompt

  • agents/supervisor/tools/init.py — tool factory list

  • lambdas/api-assistant-chat/persona_map.py — inference from Cognito claims

  • scripts/seed-personas.py — seed the new persona’s tenant config and demo user

Step 1 — Add product bindings and KB filters

persona_definitions.py contains two config dicts the runtime reads:

PERSONA_PRODUCT_BINDINGS maps each persona slug to the ordered list of ADP data products that persona_loader fetches into AgentCore Memory at session start. PERSONA_KB_FILTERS maps persona slugs that need a pre-scoped KB tool to a source_category filter dict that is passed to the bedrock-agent-runtime:Retrieve call.

# agents/supervisor/persona_definitions.py (additions only) PERSONA_PRODUCT_BINDINGS: dict[str, list[str]] = { # ... existing personas ... "finance_advisor": [ # <-- new persona slug "vehicle_identity", "customer_360", "customer_interactions", ], } PERSONA_KB_FILTERS: dict[str, dict] = { # ... existing entries ... "finance_advisor": { "source_category": [ "service_policy", # warranty and finance policy docs ], }, }

If the persona does not need a pre-scoped KB tool, omit it from PERSONA_KB_FILTERS. All personas that have make_retrieve_tool in their PERSONA_TOOL_FACTORIES list can still call the unfiltered retrieve tool regardless.

Step 2 — Write the system prompt

Add a prompt constant and register it in PERSONA_PROMPTS. The prompt body must include {tenant_display}, {vin}, and {persona_id} — these are substituted by supervisor.build_system_prompt via dataclasses.asdict(session):

# agents/supervisor/persona_definitions.py (additions only) FINANCE_ADVISOR_PROMPT = """\ You are the {tenant_display} finance advisor co-pilot, serving persona \ `{persona_id}` for vehicle {vin}. Your driver is a dealership finance manager. They need fast access to \ customer credit profile, warranty terms, and connected-service subscription \ status to structure deals and answer customer questions at point of contact. Grounding tools: - `vehicle_identity` — VIN, make, model, year, warranty status - `customer_profile` — customer tier, contact preferences - `interaction_history` — prior support and sales interactions - `retrieve` — warranty coverage, service policy, finance terms - `book` — create a follow-up appointment or support ticket - `escalate` — escalate to brand finance support Session context: - Persona: {persona_id} - Known VIN: {vin}\ """ PERSONA_PROMPTS: dict[str, str] = { # ... existing entries ... "finance_advisor": FINANCE_ADVISOR_PROMPT, }

Keep each prompt under 2 500 characters. Hard rules (triage-before-narrate, retrieve-before-citing, P0 mandatory book) are prepended automatically by build_system_prompt via _HARD_RULES — do not duplicate them in the persona body.

Step 3 — Register tool factories

Add the new persona slug to PERSONA_TOOL_FACTORIES in agents/supervisor/tools/init.py:

PERSONA_TOOL_FACTORIES: dict[str, list] = { # ... existing personas ... "finance_advisor": [ make_triage_tool, make_retrieve_tool, make_book_tool, make_escalate_tool, make_vehicle_identity_tool, make_customer_profile_tool, make_interaction_history_tool, ], }

Step 4 — Wire persona inference

lambdas/api-assistant-chat/persona_map.py contains infer_persona, the function that maps Cognito authorizer claims to a valid persona slug for the web-chat path. Add the new slug to _ROLE_MAP if it maps from a custom:role Cognito attribute:

# lambdas/api-assistant-chat/persona_map.py _ROLE_MAP: dict[str, str] = { "service-advisor": "service_advisor", "service_advisor": "service_advisor", "finance-advisor": "finance_advisor", # <-- new mapping "finance_advisor": "finance_advisor", }

The function is named infer_persona (not map_persona_from_claims). The default for any unrecognized claim is fleet_driver.

For the AgentCore text-runtime path, agentcore_app.py:_resolve_persona reads personaId directly from the request payload and validates it against PERSONA_PRODUCT_BINDINGS. No changes are needed there — the new slug is automatically valid once it appears in PERSONA_PRODUCT_BINDINGS.