Skip to content

Многофазные сценарии

Стройте в Potato многоэтапные сценарии разметки с согласием, предварительным отбором, инструкциями, обучением и опросами после исследования, а также с условными вопросами в опросах.

Potato выполняет задачу разметки как одну фазу в более длинном сценарии, поэтому согласие, отборочные вопросы, инструкции, обучение и итоговый опрос можно разместить вокруг неё без отдельного инструмента для опросов.

Сценарий разметки с фазами опроса. Последовательные фазы окружают основную задачу разметки; все фазы, кроме разметки, необязательныСценарий разметки с фазами опроса

Доступные фазы

ФазаНазначениеОбязательна
consentСбор информированного согласияНет
prestudyОтборочные вопросы и демографияНет
instructionsИнструкции и правила выполнения задачиНет
trainingКвалификация с обратной связьюНет
annotationОсновная задача разметкиДа
poststudyОпрос и обратная связь после исследованияНет

Разметчики проходят включённые фазы в том порядке, в котором вы их объявили.

Базовая конфигурация

Блок phases задаёт порядок и указывает для каждой фазы её файл:

yaml
phases:
  order: [consent, prestudy, instructions, annotation, poststudy]
 
  consent:
    type: consent
    file: surveyflow/consent.json
 
  prestudy:
    type: prestudy
    file: surveyflow/prescreening.json
 
  instructions:
    type: instructions
    file: surveyflow/instructions.html
 
  poststudy:
    type: poststudy
    file: surveyflow/demographics.json

Фазе annotation не нужен file, потому что она использует annotation_schemes верхнего уровня проекта.

Типы фаз

Каждая фаза с файлом объявляет type, который говорит, каким этапом сценария она является. Допустимые значения: consent, prestudy, instructions, training, annotation и poststudy.

Задавайте type явно. Potato выводит его сам только тогда, когда имя фазы совпадает с одним из этих слов, поэтому фаза со своим именем должна объявить тип:

yaml
phases:
  order: [intro, consent, instructions, annotation, feedback]
 
  intro:
    type: prestudy          # custom name, so type is required
    file: surveyflow/intro.json
 
  consent:
    type: consent
    file: surveyflow/consent.json
 
  feedback:
    type: poststudy         # custom name, so type is required
    file: surveyflow/feedback.json

Возврат назад

Кнопка Back скрыта, когда предыдущей страницы нет, в том числе на первом экземпляре разметки. Чтобы разметчики могли возвращаться через границы фаз:

yaml
allow_phase_back_navigation: true

Если параметр выключен, разметчики всё равно могут возвращаться назад внутри фазы, например между экземплярами разметки.

Формат вопросов опроса

Фазы опроса читают массив JSON. У каждого вопроса есть id, текст text, который видит разметчик, schema с названием виджета и варианты choices:

json
[
  {
    "id": "consent_1",
    "text": "I certify that I am at least 18 years of age.",
    "schema": "radio",
    "choices": ["I agree", "I disagree"],
    "label_requirement": {"right_label": ["I agree"]}
  },
  {
    "id": "consent_2",
    "text": "I have read and understood the information above.",
    "schema": "radio",
    "choices": ["Yes", "No"],
    "label_requirement": {"right_label": ["Yes"]}
  }
]

Поддерживаемые типы схем

radio для одного варианта, checkbox или multiselect для нескольких, text для свободного текста, number для числового ввода, likert для оценочной шкалы и select для выпадающего списка.

Требования к ответам

label_requirement определяет, с какими ответами разметчик может продолжить:

json
{
  "id": "age_check",
  "text": "Are you at least 18 years old?",
  "schema": "radio",
  "choices": ["Yes", "No"],
  "label_requirement": {
    "right_label": ["Yes"],
    "required": true
  }
}

right_label перечисляет допустимые ответы, а required указывает, обязательно ли вообще отвечать на вопрос. Вопрос о согласии, который никто не может провалить, ничего не фиксирует, поэтому помещайте допустимый ответ в right_label, а не полагайтесь на формулировку.

Отборочные вопросы

Предварительный отбор идёт до основной задачи, и именно там место вопросам о соответствии критериям и о биографии участника:

yaml
phases:
  order: [prestudy, annotation]
  prestudy:
    type: prestudy
    file: surveyflow/prescreening.json
json
[
  {
    "id": "1",
    "text": "What is your native language?",
    "schema": "select",
    "use_predefined_labels": "language",
    "label_requirement": {"required": true}
  },
  {
    "id": "2",
    "text": "How familiar are you with this topic?",
    "schema": "likert",
    "choices": ["Not at all", "Slightly", "Moderately", "Very", "Extremely"],
    "label_requirement": {"required": true}
  }
]

Опросы после исследования

yaml
phases:
  order: [annotation, poststudy]
  poststudy:
    type: poststudy
    file: surveyflow/demographics.json
json
[
  {
    "id": "gender",
    "text": "What gender do you most closely identify with?",
    "schema": "radio",
    "choices": ["Male", "Female", "Non-binary", "Prefer not to say"],
    "label_requirement": {"required": true}
  },
  {
    "id": "feedback",
    "text": "Please share any feedback about this study (optional)",
    "schema": "text"
  }
]

Встроенные наборы меток

Potato поставляется с наборами меток для вопросов, которые повторяются в большинстве исследований, так что список стран не нужно вставлять в конфигурацию:

json
{"id": "country", "text": "Select your country", "schema": "select", "use_predefined_labels": "country"}

Доступные наборы: country, language, ethnicity и religion.

Поля свободного ответа

Добавьте к любому вопросу необязательное текстовое поле с помощью has_free_response. Без него вариант "Other" не имеет смысла предлагать:

json
{
  "id": "gender",
  "text": "What is your gender?",
  "schema": "radio",
  "choices": ["Woman", "Man", "Non-binary", "Prefer not to disclose", "Prefer to self-describe"],
  "has_free_response": {"instruction": "Please specify:"},
  "label_requirement": {"required": true}
}

Заголовки страниц

Заголовок страницы опроса задаётся в фазе, а не в файле вопросов:

yaml
phases:
  prestudy:
    type: prestudy
    file: surveyflow/consent.json
    header: "Please answer all consent questions"

Условные вопросы

Вопросы опроса могут появляться в зависимости от предыдущих ответов, так что уточняющий вопрос задаётся только тогда, когда он уместен. Поскольку вопросы опроса проходят через тот же конвейер, что и схемы разметки, условие ссылается на другой вопрос по его name:

json
[
  {
    "name": "prior_experience",
    "annotation_type": "radio",
    "description": "Have you previously worked on a text-annotation task?",
    "labels": ["Yes", "No"],
    "label_requirement": {"required": true}
  },
  {
    "name": "experience_details",
    "annotation_type": "text",
    "description": "Please briefly describe your previous annotation experience.",
    "label_requirement": {"required": true},
    "display_logic": {
      "show_when": [
        {"schema": "prior_experience", "operator": "equals", "value": "Yes"}
      ]
    }
  }
]

Скрытый вопрос исключается из проверки обязательных полей, поэтому, пока он не показан, он не блокирует кнопку Continue.

Стоит знать о трёх особенностях поведения. Условие может ссылаться на вопрос из любой фазы, поэтому вопрос после исследования может зависеть от ответа до исследования. Некорректный display_logic, например с неизвестным оператором или со ссылкой на вопрос, которого нигде нет, приводит к ошибке при запуске сервера, а не во время работы. А фаза instructions, указывающая на обычный файл .html, обходит конвейер схем, поэтому условия там не применяются.

С export_include_phase_data: true Potato заново вычисляет ответы каждого участника на стороне сервера и отбрасывает ответы на вопросы, которых участник не видел. Полный справочник операторов приведён в разделе Условная логика.

Полный пример

yaml
annotation_task_name: "Sentiment Analysis Study"
task_dir: "."
port: 8000
 
data_files:
  - "data/reviews.json"
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment of this review?"
    labels:
      - Positive
      - Negative
      - Neutral
    sequential_key_binding: true
 
phases:
  order: [consent, prestudy, instructions, training, annotation, poststudy]
 
  consent:
    type: consent
    file: phases/consent.json
 
  prestudy:
    type: prestudy
    file: phases/demographics.json
 
  instructions:
    type: instructions
    file: phases/instructions.html
 
  training:
    type: training
    file: phases/training_questions.json
 
  poststudy:
    type: poststudy
    file: phases/exit_survey.json
 
training:
  enabled: true
  data_file: phases/training_questions.json
  passing_criteria:
    min_correct: 3
  allow_retry: true
 
allow_phase_back_navigation: false
 
output_annotation_dir: "output/"
export_annotation_format: "jsonl"
 
user_config:
  allow_all_users: true

Фаза обучения берёт настройки из блока training верхнего уровня, а запись в phases только задаёт её место в порядке. Критерии прохождения и формат данных описаны в разделе Фаза обучения.

Устаревшая конфигурация

Старый блок surveyflow по-прежнему работает и читает страницы опроса как списки файлов .jsonl:

yaml
surveyflow:
  on: true
  order:
    - pre_annotation
    - post_annotation
  pre_annotation:
    - surveyflow/consent.jsonl
    - surveyflow/demographics.jsonl
  post_annotation:
    - surveyflow/exit_survey.jsonl

Миграция

Устаревший форматСовременный формат
surveyflow.on: trueБлок phases
surveyflow.pre_annotationphases.consent или phases.prestudy
surveyflow.post_annotationphases.poststudy
surveyflow.testingtraining.data_file
Файлы .jsonlФайлы .json с массивом

Рекомендации

Держите опросы короткими

Каждый лишний вопрос снижает долю завершений, а демографические вопросы, которые не используются в анализе, снижают её впустую.

Проверьте весь сценарий

Пройдите сценарий сами в браузере без сессии, прежде чем куда-либо отправлять ссылку. Сломанный сценарий раньше всего и незаметнее всего отказывает в двух местах: на согласии и при входе в систему.

Аккуратно отмечайте обязательные поля

Обязательные вопросы, которые могли быть необязательными, дают ответы, придуманные только для того, чтобы пройти страницу.

Краудсорсинг

Коды завершения настраиваются ключом completion_code верхнего уровня, а не в фазе после исследования:

yaml
completion_code: "POTATO2024"
auto_redirect_on_completion: true
auto_redirect_delay: 5000

Настройка платформ описана в разделе Краудсорсинг.

Что почитать дальше

Детали реализации описаны в исходной документации.