UX session analysis
Moderated sessions become a corpus you can question. The transcript is joined to what was on screen at that second, so one query reaches every session at once and returns the moment rather than the recording.
Ask one question across every session and get every participant's answer, attributed. The query that defines this template is the roll-up: one task, every participant, with each result opening at the second it happened.
UX research teams running moderated usability sessions
Studio will also guide you to Three to five sessions from ONE study for zero-setup evaluation, then to a continuous data connection for production.
- sessionsOne object per recording, with study_id, participant_id, rig_id and task_id as fields. Those four are what every roll-up groups and filters on, so they are the schema decision that matters.
- session-scenesSegment documents with a 1408-dimension multimodal embedding, timing, transcription, and the on-screen text read off that segment.
- session-transcriptsThe spoken side as a 1024-dimension text embedding, carrying the study, participant and task through so a filtered question stays filtered.
How the namespace is wired
1 buckets, 2 collections, 0 clean views, 2 retrievers. The diagram generates the manifest below; they cannot drift apart.
Reward signals
How reviewer decisions move the thresholds
Thresholds at ingest drift as the corpus changes. The reviewers working the queue are the ones who see where a threshold is wrong first, so this template routes their decisions back into the model that set it.
None. No saves, no flags, no observer marks are recorded by the template as shipped.
None from the application. Mixpeek records retriever executions server-side, which is telemetry about queries rather than feedback about results.
mxp_retriever_executionsSystem collections in your namespace, on the same vector store as the rest of the template. They are yours to query.
The observers' notes are the ground truth this use case is missing: task start and stop, errors, and confidence per participant. That is an input to evaluation rather than a signal the template collects.
One file spins up the namespace. Generated from the diagram above. Also served at /templates/ux-session-analysis.namespace.yaml.
# ux-session-analysis: one manifest spins up the namespace.
# Platform manifest schema (GET /v1/discovery/schema). Validate with POST /v1/manifest/validate,
# apply with POST /v1/manifest/apply or the Deploy button. Wiring comes from the flow diagram:
# edges are bucket -> collection sources, collection -> retriever scope, retriever -> view.
version: '1.0'
metadata:
name: ux-session-analysis
description: "Namespace template ux-session-analysis. Generated from the flow diagram on mixpeek.com/templates/ux-session-analysis."
namespaces:
- name: ux-session-analysis
description: "Everything below lives in this namespace."
feature_extractors:
- name: multimodal_extractor
version: v1
- name: text_extractor
version: v1
# Data sources. A storage connection carries credentials, so it is created in Studio
# (or POST /v1/organizations/storage-connections) and synced into the bucket named here.
# clinic-recordings: s3, continuous, moderated session recordings from your rig, in your account -> bucket sessions
buckets:
- name: sessions
namespace: ux-session-analysis
description: "Fed by clinic-recordings (s3, continuous)."
schema:
properties:
content:
type: video
# Connect your own storage. Create the two secrets, uncomment, and apply again;
# apply live-tests the connection, so it must have real credentials to succeed.
# Until then the buckets above accept direct uploads.
# storage_connections:
# - name: clinic-recordings-connection
# provider: s3
# description: "Read-only access to the s3 location holding moderated session recordings from your rig, in your account."
# config:
# region: us-east-1
# credentials:
# type: access_key
# access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# bucket_syncs:
# - name: clinic-recordings-sync
# bucket: sessions
# connection: clinic-recordings-connection
# source_path: "sessions/"
# sync_mode: continuous
# polling_interval_seconds: 300
# skip_duplicates: true
# file_filters:
# include_patterns: ["*.mp4", "*.mov"]
# schema_mapping:
# mappings:
# content:
# target_type: blob
# source: {type: file}
# blob_type: video
collections:
- name: session-scenes
namespace: ux-session-analysis
description: "multimodal_extractor@v1 over bucket sessions. Feeds session-transcripts, find-the-moment, task-roll-up."
source:
type: bucket
bucket: sessions
feature_extractor:
name: multimodal_extractor
version: v1
input_mappings:
video: content
field_passthrough:
- source_path: study_id
- source_path: participant_id
- source_path: rig_id
- source_path: task_id
- source_path: file_location
- source_path: segment_id
- source_path: start_time
- source_path: end_time
enabled: true
- name: session-transcripts
namespace: ux-session-analysis
description: "text_extractor@v1 over collection session-scenes. Feeds find-the-moment, task-roll-up."
source:
type: collection
collection: session-scenes
feature_extractor:
name: text_extractor
version: v1
input_mappings:
text: transcription
field_passthrough:
- source_path: study_id
- source_path: participant_id
- source_path: task_id
- source_path: segment_id
- source_path: video_segment_url
- source_path: start_time
- source_path: end_time
enabled: true
retrievers:
- name: find-the-moment
namespace: ux-session-analysis
description: "Searches session-scenes, session-transcripts across 2 feature indexes with rrf fusion."
collections:
- session-scenes
- session-transcripts
input_schema:
query:
type: text
required: true
description: "What to look for; searched across every index below"
stages:
- stage_name: search
stage_id: feature_search
parameters:
searches:
- feature_uri: "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1"
query:
input_mode: text
value: "{{INPUT.query}}"
top_k: 25
- feature_uri: "mixpeek://multimodal_extractor@v1/vertex_multimodal_embedding"
query:
input_mode: text
value: "{{INPUT.query}}"
top_k: 25
fusion: rrf
final_top_k: 25
tags:
- template:ux-session-analysis
- name: task-roll-up
namespace: ux-session-analysis
description: "Searches session-transcripts, session-scenes across 1 feature index. Groups documents by participant_id."
collections:
- session-transcripts
- session-scenes
input_schema:
query:
type: text
required: true
description: "What to look for; searched across every index below"
stages:
- stage_name: search
stage_id: feature_search
parameters:
searches:
- feature_uri: "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1"
query:
input_mode: text
value: "{{INPUT.query}}"
top_k: 200
fusion: rrf
final_top_k: 200
- stage_name: group
stage_id: group_by
parameters:
group_by_field: participant_id
tags:
- template:ux-session-analysis