Skip to content

众包集成

在 Prolific、SONA、CloudResearch Connect 或任何传递参与者 ID 的样本平台上运行 Potato 研究,支持 URL 登录、完成码和注意力检查。

Potato 从平台把人送来的那个 URL 里读出参与者 ID,再在结束时显示一个完成码,众包标注就是这样收集的。Prolific、SONA 被试池、CloudResearch Connect、Clickworker 和 Microworkers 各有一个提供方,而 generic 提供方覆盖任何以同样方式工作的其他样本平台。Amazon Mechanical Turk 已于 2026 年 9 月 30 日关闭,所以原先在那里运行的研究必须迁到上述平台之一,下文“把研究迁出 MTurk”一节列出了具体步骤。

在开放端口上运行

众包工作者必须能访问到服务器,所以要把它跑在对互联网开放的端口上:

bash
potato start your-project -p 8080

工作者随后会到达 https://your-server:8080/。在它前面放一个反向代理来处理 TLS,做法见生产环境部署。

众包提供方

crowdsourcing 块指明平台。Prolific、SONA、Connect、Clickworker 和 Microworkers 有各自专用的提供方,而 generic 应付任何在 URL 里传 ID 并接受完成码的样本平台,比如 Besample、Positly、User Interviews、Testable Minds 或 Cint:

yaml
login:
  type: url_direct
  url_argument: response_id        # must match id_param below
 
crowdsourcing:
  provider: generic                # or prolific, sona, connect, clickworker, microworkers
  generic:
    platform_label: "Besample"     # shown on the done-page return button
    id_param: response_id          # URL parameter carrying the participant ID
    capture_params: [study]        # extra URL params to record
    completion:
      code: "BSMP-4432"
      redirect_url: "https://besample.app/complete?rid={worker_id}&code={code}"
      failed_code: "BSMP-FAIL"     # optional, for blocked participants

redirect_url 接受占位符 {code}、{worker_id}、{session_id}、{study_id},以及 capture_params 中列出的任何名称。

每个提供方都从 login.url_argument 所指定的 URL 参数里读取参与者 ID,所以要在 crowdsourcing 块旁边保留 login.type: url_direct,并把 url_argument 设成该提供方的 id_param。关掉密码提示的也是 url_direct 登录。不带 crowdsourcing 块的配置保持旧有行为,只靠登录本身读取 ID,下面 Prolific 的基本设置用的就是这种方式。

Prolific

基本设置

两项设置就能跑一个 Prolific 研究:

yaml
login:
  type: url_direct
  url_argument: PROLIFIC_PID   # the default
 
completion_code: "YOUR-PROLIFIC-CODE"

从 Prolific 过来的工作者会以其 PROLIFIC_PID 登录,不会被要求输入密码。他们做完后会看到完成码和一个返回 Prolific 的按钮。

Prolific 提供方

prolific 提供方为没有完成任务的参与者加了第二个码。被注意力检查拦下的参与者,或者没通过培训阶段的参与者,拿到的是 failed_code 而不是完成码:

yaml
login:
  type: url_direct
  url_argument: PROLIFIC_PID
 
crowdsourcing:
  provider: prolific
  prolific:
    completion:
      code: "C1ABCDEF"          # defaults to the top-level completion_code
      failed_code: "C1FAILED"   # optional

研究 URL

在 Prolific 的研究设置里,把 URL 设为:

text
https://your-server:8080/?PROLIFIC_PID={{%PROLIFIC_PID%}}&SESSION_ID={{%SESSION_ID%}}&STUDY_ID={{%STUDY_ID%}}

Prolific 会代入真实值。Potato 会把 SESSION_ID 和 STUDY_ID 与参与者 ID 一并记录下来。

完成后跳转

yaml
completion_code: "YOUR-PROLIFIC-CODE"
auto_redirect_on_completion: true
auto_redirect_delay: 5000   # milliseconds

不开跳转时,完成页会显示完成码(点击即可复制)和一个返回按钮;如果你希望工作者留一份完成码的记录,这是更稳妥的默认选择。

Prolific API 集成

对规模更大的研究,Potato 可以与 Prolific API 通信,从而释放被退回或超时的工作者占住的名额,并在服务器繁忙时暂停研究。把凭据放在单独的文件里:

yaml
# configs/prolific_config.yaml
token: "your-prolific-api-token"
study_id: "your-study-id"
max_concurrent_sessions: 30
workload_checker: true
workload_checker_period: 300

然后让主配置指向它:

yaml
login:
  type: prolific
 
prolific:
  config_file_path: configs/prolific_config.yaml
 
completion_code: "YOUR-PROLIFIC-CODE"

workload_checker 默认关闭,要自己打开。打开后,当活跃工作者超过 max_concurrent_sessions 时 Potato 会暂停研究,等人数降到该数值的 20% 时再恢复,但仅限于这次暂停本来就是监控器自己做的。你手动暂停的研究不会被自动重启。

回收被放弃的工作

当一份提交回到 RETURNED、TIMED-OUT 或 REJECTED 状态时,Potato 会释放该工作者已分派但未标注的条目,好让别人接手。他们已经完成的标注会保留。instance_reclaim 可以按状态改变这一行为:

yaml
instance_reclaim:
  enabled: true
  prolific:
    preserve_completed_annotations: true
    status_policies:
      TIMED-OUT:
        preserve_completed_annotations: true
      REJECTED:
        preserve_completed_annotations: false

SONA 被试池

SONA Systems 运营着许多大学用来发放课程学分的被试池。SONA 会在研究 URL 里为每位参与者放入一个唯一代码,Potato 就把这个代码当作参与者 ID:

yaml
login:
  type: url_direct
  url_argument: sona_code
 
crowdsourcing:
  provider: sona
  sona:
    hostname: yourdept.sona-systems.com
    experiment_id: 123
    credit_token: your-credit-token   # both from the client-side completion URL on SONA's study information page
    id_param: sona_code               # the default; must match login.url_argument

在 SONA 里把研究 URL 设为 https://your-server.com/?sona_code=%SURVEY_CODE%。参与者做完后,Potato 会通过 SONA 的服务器端学分接口自行发放学分,参与者不必再点链接回到 SONA。如果这次调用失败,完成页会改为显示 SONA 的客户端学分链接。每次发放都会记录在参与者的状态里,所以刷新完成页绝不会重复发放学分。

CloudResearch Connect

Connect 通过它的 Project Link 把参与者送到外部研究,参与者 ID 放在 participantId 里,另外可选地带上 assignmentId 和 projectId。Potato 会把这三项都记录下来。完成方式可以是一个固定的完成码,也可以是跳转到 Connect 项目设置中显示的完成 URL:

yaml
login:
  type: url_direct
  url_argument: participantId
 
crowdsourcing:
  provider: connect
  connect:
    completion:
      code: "ABC123"
      # or: redirect_url: "https://connect.cloudresearch.com/participant/project/<id>/complete"

Potato 不调用 Connect 的 REST API,所以审批和奖金都在 Connect 里处理。

Clickworker

Clickworker 的外部问卷订单会带着工作者的 ID 把人送到你的 URL,完成情况则对照你上传到 Clickworker 的完成码来核验:

yaml
login:
  type: url_direct
  url_argument: worker_id
 
crowdsourcing:
  provider: clickworker
  clickworker:
    id_param: worker_id      # the default
    completion:
      code: "CW-DONE-01"

该提供方还可以发送一条完成通知,通过 Clickworker 的平台市场 API 触发付款。这个回传功能是实验性的,因为它的接口约定无法对照公开文档核实;除非配置里在 postback_url 旁边设置了 experimental: true,否则它一直处于关闭状态。

Microworkers

Microworkers 的任务活动会要求每位工作者粘贴回一个叫 VCODE 的验证码,以证明自己已经做完。Potato 用工作者 ID 和活动 ID 计算出的 HMAC 来生成每位工作者的 VCODE,因此同一位工作者总是拿到同一个码,没有密钥的人猜不出码来,而提供方的 verify_vcode 方法会重新计算出码来核验一次提交:

yaml
login:
  type: url_direct
  url_argument: mw_id
 
crowdsourcing:
  provider: microworkers
  microworkers:
    id_param: mw_id                        # matches {{MW_ID}} in the campaign URL
    capture_params: [campaign_id, slot_id]
    vcode_secret: "keep-this-private"
    vcode_prefix: "mw-"                    # optional

在 Microworkers 上把活动 URL 设为 https://your-server.com/?mw_id={{MW_ID}}&campaign_id={{CAMP_ID}}&slot_id={{SLOT_ID}}。Microworkers 是一个开放的微任务众包人群,所以要搭配下文的注意力检查和黄金标准一起使用。

Amazon Mechanical Turk(已关闭)

Amazon Mechanical Turk 已于 2026 年 9 月 30 日永久关闭,不再接受 HIT,也不再输送工作者。Potato 的 mturk 提供方和 workerId 登录仍能加载,所以归档的 MTurk 配置还能启动,但不会有任何工作者访问到它。MTurk 集成页面保留了相关细节,供阅读旧研究配置的人参考。

把研究迁出 MTurk

MTurk 研究的配置大部分可以原样沿用,因为注意力检查、黄金标准、培训、分配和配额在每个平台上的工作方式都一样。迁移分五步:

  1. 选定平台。 Prolific 和 CloudResearch Connect 招募一般的研究人群,SONA 服务于大学自己的被试池,而 Clickworker 和 Microworkers 是开放的微任务众包人群,需要更严格的质量控制。
  2. 修改登录。 保留 login.type: url_direct,把 login.url_argument 从 workerId 改成新平台的 ID 参数(PROLIFIC_PID、sona_code、participantId、worker_id 或 mw_id)。
  3. 替换平台块。 删除 mturk 块,因为只要这个块还在,Potato 就仍会启动它的 MTurk API 客户端;然后从本页加入新平台的 crowdsourcing 块。
  4. 替换 HIT。 在新平台上创建研究或项目,把它的外部 URL 指向你的服务器,并在链接里带上该平台的 ID 占位符,再设置平台给你的完成码或跳转地址。
  5. 保留质量控制。 attention_checks、gold_standards 和培训阶段维持原样,这样结果仍可与 MTurk 的数据相比较。

质量控制

注意力检查

已知答案的条目,混进队列中:

yaml
attention_checks:
  enabled: true
  items_file: data/attention_checks.json
  frequency: 10
  min_response_time: 3.0
  failure_handling:
    warn_threshold: 2
    warn_message: "Please read items carefully before answering."
    block_threshold: 5
    block_message: "You have been blocked due to too many incorrect responses."

min_response_time 抓的是众包最容易碰上的那种失败:点得比任何人读完条目都快。

黄金标准

由专家标注的条目衡量的是准确率而非注意力,它们默认不作声,这样工作者得不到任何会教会他们答案的反馈:

yaml
gold_standards:
  enabled: true
  items_file: data/gold_standards.json
  mode: mixed
  frequency: 20
  accuracy:
    min_threshold: 0.7
    evaluation_count: 5

条目格式以及两者各自如何汇报,见质量控制。

自定义完成页

内置的完成页只处理一个完成码和一个返回按钮。当你需要的不止这些时,改用一个 surveyflow 页面来收尾:

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

结束页是一个 pure_display 条目,里面放你需要的任何链接或文字:

json
{"id":"1","text":"Thanks for participating. Click below to complete the study.","schema":"pure_display","choices":["<a href=\"https://app.prolific.com/submissions/complete?cc=YOUR-CODE\" target=\"_blank\">Complete Study on Prolific</a>"]}

完整示例:Prolific 研究

yaml
annotation_task_name: "Sentiment Analysis Study"
task_dir: .
 
login:
  type: url_direct
  url_argument: PROLIFIC_PID
 
completion_code: "SENT2024"
auto_redirect_on_completion: false
 
hide_navbar: true
jumping_to_id_disabled: true
 
user_config:
  allow_all_users: true
 
assignment_strategy: random
max_annotations_per_user: 50
num_annotators_per_item: 3
 
phases:
  order:
    - consent
    - instructions
    - annotation
  consent:
    file: data/consent.html
  instructions:
    file: data/instructions.html
  annotation:
    type: annotation
 
attention_checks:
  enabled: true
  items_file: data/attention_checks.json
  frequency: 10
  failure_handling:
    warn_threshold: 2
    block_threshold: 5
 
data_files:
  - data/main.json
 
item_properties:
  id_key: id
  text_key: text
 
annotation_schemes:
  - annotation_type: radio
    name: sentiment
    description: "What is the sentiment of this text?"
    labels:
      - Positive
      - Negative
      - Neutral
    sequential_key_binding: true
 
output_annotation_dir: annotation_output/
export_annotation_format: jsonl

监控研究进展

研究运行期间,/admin 上的管理面板会汇报完成率、每个条目的耗时以及注意力检查结果。访问它需要共享的 admin_api_key,或者一个带 view_admin_dashboard 权限的角色:

yaml
admin_api_key: "your-shared-key"
 
rbac:
  enabled: true
  user_role_assignments:
    researcher@university.edu: admin

用导出 CLI 把收集到的标注导出来:

bash
python -m potato.export -c config.yaml -f csv -o ./export/

最佳实践

  1. 先做小规模试跑 - 大规模上线前先找少数几位工作者跑一遍
  2. 给足报酬 - 自己计时做一遍任务,按真实耗时定价
  3. 把说明写清楚 - 附上例子和你预料到的边界情况
  4. 用注意力检查 - 尽早抓出乱点的人,而不是等到分析阶段
  5. 加上黄金标准 - 注意力和准确率是两种不同的测量
  6. 盯住面板 - 问题在第一天修起来很便宜,到第五天就很贵
  7. 事先定好拒收标准 - 工作者应当在开工前就知道标准
  8. 定期导出 - 不要等到研究结束才导

延伸阅读

实现细节见源文档、Prolific 参考和平台调研。