はじめに

先に実験の準備手順を確認したい方は、「要は何をすればいいのか」へ進んでください。

誰の、何のための記事か

今回は、ウェブで回答を集めるオンライン実験の枠組みで、(i) フィードバックを作る参加者に、対象の提出物(学習者の回答など)を入力させ、(ii) 生成AIにフィードバックを生成させ、(iii) (参加者に)そのフィードバックを修正させて記録する方法を紹介します。もちろんオンライン実験なので、細かい実験の要因の統制やランダマイズ(条件などの無作為な割り当て)も可能としています。

動機として、色々な分野で生成AIをフィードバックに使ってみたい(厳密には使ってみてほしい)気はするものの、実験しないとならない部分は多いわけです。例えば、フィードバックを生成させるにはどんなプロンプト(生成AIへの指示)が良いのでしょうか。他にも、そのプロンプトはどんな部分に修正が必要か、どのモデル(使うAIの種類)がよいか、どんな生成の設定が良いかなどなど。こうした検証には比較と実験、記録が必要になるわけですが、ゼロから用意するのは大変です。

そこで、今回は信頼できる参加者による小規模な実験を想定し、運用のしやすさを優先した構成を考えます。

flowchart BT
    accTitle: 今回作るシステムの全体像
    accDescr: 上段に外部サービス、中段に作成者と参加者のブラウザ、下段に操作する人を並べる。作成者はCognitionへ実験を登録してデータを取得する。参加者のブラウザはCognitionから実験コードを受け取り、OpenAIへ直接依頼し、結果をCognitionへ保存する。
    %% fit: width
    %% architecture
    %% flow: roundtrip
    R(["実験作成者"]) ---|"①実験作成<br/>⑨記録確認"| RB["`作成者の
ブラウザ`"]
    P(["実験参加者"]) ---|"④入力<br/>⑦編集"| B["`参加者の
ブラウザ`"]
    RB <-->|"②実験登録<br/>⑨記録取得"| C["`Cognition.run
実験の配信・保存`"]
    B <-->|"③画面取得<br/>⑧回答保存"| C
    B <-->|"⑤生成依頼<br/>⑥案の受信"| O["`OpenAI
文章生成`"]
    class C cognition
    class RB,B browser
    class O openai
    class R,P person

それぞれの構成要素の役割は以下の通りです。図の①〜⑨は、準備からデータ取得までの順序です。

  • 実験作成者:比較条件と画面を用意し、集まったデータを取得します。
  • 実験参加者:文章を入力し、AIの案を確認・編集します。
  • 作成者・参加者のブラウザ:ウェブページを開くアプリです。参加者はCognitionから受け取ったjsPsychコードをここで動かし、OpenAIへ直接依頼します。
  • Cognition.run:実験コードを配信し、回答を保存するオンライン実験サービスです。ネット越しに依頼を受けるサーバー側を担います。
  • OpenAI:ChatGPTの提供元で、今回は文章生成APIを使います。

汎用性はそれなりに高いとは思いますが、卒業研究に取り組む学部生から、修士・博士課程の大学院生、教員・研究者まで、アカデミアで実験を行う方を想定読者としています。反対に、「信頼できる参加者による、研究室内の小規模・短期間の実験である」という前提を踏まえないと、Web開発者が失神しそうな部分もあります。

実験を動かすための前提知識

以下は、前提知識に合わせて読み飛ばしてください。あまりPCに興味がない人に向けた説明も含まれています。

APIを使った文章生成

プログラムが別のプログラムに依頼するための窓口や決まりをAPI(Application Programming Interface)と呼びます。送る依頼がリクエスト、返ってくる返事がレスポンスです。今回は、参加者のブラウザからOpenAI APIへ指示と提出物を送り、生成された文章を受け取ります。

flowchart BT
    accTitle: APIへ依頼を送り、生成された文章を受け取る
    accDescr: 参加者のブラウザを下、OpenAIのサーバーを上に置く。ブラウザは指示、提出物、モデルの指定をリクエストとして送り、OpenAIのサーバーは文章を生成してレスポンスとして返す。
    %% architecture
    %% labels: opaque
    B["参加者のブラウザ"]
    Q["リクエスト<br/>指示<br/>提出物<br/>モデル指定"]
    O["OpenAIのサーバー<br/>APIで依頼を受け付け<br/>モデルで文章を生成"]
    S["レスポンス<br/>生成された<br/>文章"]
    B -->|"①依頼を組み立てる"| Q
    Q -->|"②送信する"| O
    B <-->|"④案を表示する"| S
    S <-->|"③結果を返す"| O
    class B browser
    class Q,S note
    class O openai
    linkStyle 0,1 stroke:#991b1b,color:#991b1b,stroke-width:1.6px
    linkStyle 2,3 stroke:#1e3a8a,color:#1e3a8a,stroke-width:1.6px,marker-end:none

APIの利用設定と料金はChatGPTの契約とは別です。文章生成の仕組みはOpenAIの公式ガイドにも説明があります。

モデル・生成設定・プロンプトの関係

実験では、使うモデルと生成の設定、AIへの指示、フィードバックの対象となる提出物を決めます。モデルが異なれば出力も変わるため、A/Bを比べる間は同じモデルと生成設定を使います。1

生成設定には、出力の長さの上限や、回答前の推論に割く処理の量を指定するreasoning effortなどがあります。使える設定はモデルによって異なります。2

指示は、ここでは次の二つに分けます。

  • システムプロンプト(system prompt):AIの役割や、応答の基本方針を指定する指示。
  • ユーザープロンプト(user prompt):その場の依頼や、課題の情報を伝える指示。

フィードバックの方針はシステムプロンプトに、課題や評価観点はユーザープロンプトに書き、提出物は評価する対象として渡します。どの要因を変え、どの設定を揃えるかを実験計画で決めます。

検索で根拠を参照させるなど、研究で比較条件を広げる際の選択肢もありますが、今回はツール(tool)を使わず、指示と提出物から文章を生成します。3

実験画面とデータの記録

jsPsychで画面を作り、Cognitionで実験を公開する基本手順は「jsPsychでミニマルな実験を作成」で、画面構成の基本は「jsPsych の基本的な機能を確認」で紹介しています。この記事では、最低限しか説明しませんし、今日日コードの説明はCognition上で使えるAIアシスタントがやってくれます。

ここでは、参加開始から終了までを一つのセッション、対象文章の入力から提出までを一つの課題試行(1セット)と呼びます。jsPsychのtrial(試行)は各画面・処理単位で、入力、AIの生成、提出などが別々の行として記録されます。今回は一つのセッションで3条件を各1回行い、各課題試行の記録を同じIDに結びつけます。Cognitionはtrialごとに自動保存します。4仕組みは公式のオフライン復旧の説明、保存・取得は公式のデータ管理の説明を参照してください。

一応メリットを言っておくと、参加者は各自の場所から取り組めるので、来室日時を調整する負担も減らせます。また、参加者ごとの条件割当も実験コードで組み込めます。

APIキーと暗号化・復号

OpenAIのモデルを利用するには、利用資格を示す秘密の文字列であるAPIキーが必要です。実験プログラムはこのキーを使って文章生成を依頼します。

今回は実験参加者のブラウザから利用させたいのですが、実験コードにキーをそのまま書くわけにはいきません。コード自体が漏れた時に面倒なことになります。

そこで、パスワードで元に戻せる形にする暗号化(encryption)を行います。元に戻す処理が復号(decryption)です。同意した参加者はセッション開始時に一度パスワードを入力し、ブラウザ内で復号したキーを、二つのAI条件を含む3課題のセッション中だけ使います。manual課題ではAPIを呼びません。この方法でも、復号できる参加者からキーを隠すことはできません。

「文字列で試す」では、公開の例文を使って暗号化と復号を試せます。APIキーは入力せず、別のパスワードで復号に失敗することも確認できます。5

方法の説明

やっとこさ、どうやって実験を設計して組むかの話です。

システムプロンプトをA/Bで比較する実験

変えるものと記録するものを分ける

通常のA/Bテストは二つの条件を比べます。この例では、AIの指示を変えるprompt_aとprompt_bに、AIを使わないmanualを加えた3条件を用意します。各参加者は一つのセッション内で3条件の課題を各1回、無作為な順で行います。セッション開始時に同意とパスワード入力を一度だけ行い、課題の途中で条件は変えません。6

実験での扱い 今回の内容
変えるもの prompt_a・prompt_bのシステムプロンプト、AIを使わないmanual条件
条件間で統制 課題・提出物の割当方、AI条件のモデルと生成設定、入力・提出の画面と手順
記録して比較 条件ごとのAI出力、採用の種類、編集前後の文章。必要に応じて評定や作業時間も加える

ここで、「どちらが良いか」の判断基準は先に決めておきます。例えば、内容が正確であること、わかりやすいこと、少ない手間で使えることは、それぞれ別の評価です。今回のサンプルで記録する採用や編集は、主に参加者がAIの案をどう使ったかを見るためのものです。

採用が多い、編集が少ないという結果だけで、内容の質が高いとは限りません。正確さや有用性を比べたい場合は、その観点で評価する質問や、別の評価者による判定を加えます。後から都合の良い指標だけを選ばないように、何を主な結果として比べるかを実験前に決めておきましょう。

課題へのフィードバックを作ってもらう場合

実験参加者は、提出物にフィードバックを付ける人だとしましょう。リハビリをする言語聴覚士でもいいですし、教員やTA、相互評価を行う学生などを想定できますね。参加者はAIの案を確認し、必要に応じて編集して、提出者に返すフィードバックを完成させます。この記事の読者は、この実験を設計・準備する側になります。

例えば、システムプロンプトAでは改善案を直接示し、Bでは提出者が改善点に気づくための問いを重視させる、といったシステムプロンプトの違いが考えられます(あくまで説明用の例で、研究に使うA/Bの文面は別途決めます)。

今回は、課題の指示や評価観点もユーザープロンプトに含めます。例えば、「課題はオンライン授業の利点と課題を説明することです。根拠の示し方について、短いフィードバックを作ってください」という依頼です。

用意するもの 今回の役割 具体例
システムプロンプト 実施者が決めるA/Bの条件 改善案を直接示す指示、改善を促す問いを返す指示
ユーザープロンプト 課題の指示、評価観点、その場の依頼 根拠の示し方について短く説明してください
提出物 フィードバックの対象 説明課題への回答やレポート
AIの案 AIが最初に生成した文章 提出物の改善点とその説明
最終フィードバック 参加者が確認して提出する文章 AIの案を編集した文章

同じ参加者が3条件を経験するため、参加者ごとの経験差は条件間で共有されます。一方、課題の難しさや実施順の影響は残ります。各条件で同じ対象文章を使うか、難しさを揃えた別の文章を使うかを決め、実際に送った内容と条件・順序を記録します。

参加者が進む画面

参加者はリンクを開き、説明に同意してからパスワードを一度入力します。このセッションにはAIを使う条件が二つあるため、全員がセッション開始時に一度だけキーを復号します。復号に失敗した場合は課題を始めず終了します。成功するとprompt_a、prompt_b、manualの課題が無作為な順に一つずつ始まります。各課題では対象文章を入力し、AI条件なら原案を確認・編集して提出し、manualなら自分で書いたフィードバックを提出します。manualの課題ではOpenAIへリクエストしません。

%%{init: {"flowchart": {"nodeSpacing": 12, "rankSpacing": 20, "wrappingWidth": 210, "padding": 8}}}%%
flowchart TD
    accTitle: 参加者が3条件の課題を行う画面
    accDescr: 説明への同意後、セッションの最初に一度だけパスワードを入力して復号する。prompt_a、prompt_b、manualの3条件を各1回、無作為な順で行う。各条件で対象文章を入力し、AI条件では生成・編集、manualでは手動作成を行って提出する。3試行の終了後にキーを消去する。
    A["説明・同意"] --> B["パスワード入力・復号<br/>セッション最初の1回"]
    B --> C["3条件を各1回<br/>順序を無作為化"]
    C --> D["対象文章を入力"]
    D --> E["AI条件:生成・編集<br/>manual:手動作成"]
    E --> F["提出"]
    F --> G{"3試行完了?"}
    G -->|"はい"| H["セッション終了<br/>キーを消去"]
    G -->|"いいえ"| D
    class H cognition

生成失敗時は、その条件内で同じモデル・入力のまま最大3回まで手動再試行できます。再試行しても生成できなければ、その条件の提出を作らず次の条件へ進みます。失敗履歴は保存します。7

実験システムの構成と通信

システムプロンプトとモデルは実験コードで指定し、参加者のブラウザからOpenAIへ送ります。AIの原案は生成のtrialで、編集して提出した最終文は提出のtrialで、それぞれCognitionへ保存します。

データが往復する経路(再掲)

冒頭の構成図と同じ①〜⑨に、ブラウザ内の処理と外部サービスの役割を対応づけています。双方向の矢印は、依頼とその返事が往復することを表しています。

flowchart BT
    accTitle: 参加者のブラウザから直接AIを呼ぶ構成
    accDescr: 上段に外部サービス、中段にブラウザ内の処理、下段に実験作成者と参加者を並べる。作成者のブラウザから実験コードを登録し、記録を取得する。参加者のブラウザではキーを復号してOpenAIへ直接依頼し、編集後の実験データをCognitionへ保存する。
    %% architecture
    %% flow: roundtrip
    R(["実験作成者"]) ---|"①実験作成<br/>⑨記録確認"| RB["`作成者のブラウザ
実験の設定・管理`"]
    P(["実験参加者"]) ---|"④入力<br/>⑦編集"| B["`参加者のブラウザ
キーの復号・表示・編集`"]
    RB <-->|"②コードを登録<br/>⑨記録を取得"| C["`Cognition.run
実験の配信・保存`"]
    B <-->|"③コードを受信<br/>⑧記録を送信"| C
    B <-->|"⑤指示・提出物を送信<br/>⑥AIの案を受信"| O["`OpenAI API
文章生成`"]
    class C cognition
    class RB,B browser
    class O openai
    class R,P person

OpenAIへ送る内容と返ってくる文章

生成ではAPIにモデルを指定し、課題の指示、フィードバック方針、提出物を送ります。APIからは、その提出物へのフィードバックが返ります。例えば、オンライン授業の利点と課題を説明する回答に対し、根拠の示し方を助言する文章を求めます。8

提出物に氏名などが含まれる場合は、送信前に確認します(「個人情報と外部送信」)。

実験で比べる指示と参加者が送った内容、AIの案、提出された最終文を記録します。実験内の参加IDと復号用パスワードは生成依頼に含めません。

入力・出力の量、モデル、生成回数で費用は変わるため、予備実験で一回分を確かめて見積もります。9

記録するデータの設計

参加1回分の記録をID(Identifier、識別用の文字列)で結び、AIの案と参加者の最終文章を対応づけます。4

記録する内容 主な情報
参加条件 参加1回をまとめるID、割り当てられた条件
AIへの依頼 実際に送ったシステムプロンプト、提出物を含む入力、モデル
AIの生成 生成された文章、失敗と再試行の履歴
人の提出 最終文章、AI案の採用判断、文章の変更有無

採用は参加者の判断として記録し、文章が変わったかどうかとは分けて扱います。失敗と再試行の履歴も残します。10 APIキー、復号用パスワード、実際の参加URL全体は、このデータに加えません。研究用の項目は実験コードで指定し、前の入力や生成結果はjsPsychに保存されたtrialデータから参照します。APIキーの復号・OpenAIへの通信・通信エラーの整理は共通ライブラリが担い、Cognitionは各trialデータを保存します。

要は何をすればいいのか

記事内の準備画面と、公開されているexperiment.jsの雛形を利用できます。OpenAIへの実接続とCognitionへの保存は未検証です。以下の順に進めます。

1. APIキーの準備

OpenAIのAPIキー作成画面にログインし、画面の案内に沿って、キーや利用量をまとめて管理するプロジェクトと今回の実験専用APIキーを作ります。詳しい流れは公式Quickstartを参照してください。APIキーそのものは決して公開しないでください。他人に知られると不正利用され、費用負担につながるおそれがあります。普段の研究や別のアプリで使っているキーは使わず、専用にします。

予備実験で一回分の使用量を確かめ、参加人数と呼出し回数から予算を見積もります。小規模な実験なら、請求設定で前払い方式を確認し、例えば20米ドル分を入金して、自動入金(Use auto-reload)をオフにします。APIキーは実験期間に合わせ、例えば30日後に失効するように設定し、実験終了後は期限を待たずに無効化します。11

「APIキーの準備」画面はブラウザ内で動き、入力したAPIキーやパスワードを外部へ送信しません。専用APIキーを暗号化し、「ファイルをダウンロード」でencrypted-api-key.jsを保存します。5

「パスワードをコピー」で復号用パスワードも控えてください。失うとこのファイルを復号できません。実施者だけが開けるメモや文書などに保管し、例えばGoogle Docsを使う場合は共有範囲を確認します。12 準備画面が生成する無作為な20文字を使い、人が決めた単語や日付、記事の例は流用しません。参加者には復号用パスワードを参加リンクとは別に案内します。13

2. Cognitionに登録して実験を配置する

Cognition.runで「Create an account」から氏名、メールアドレス、パスワードを登録します。すでにアカウントがある場合はログインしてください。必要に応じて公式のはじめ方を参照し、実験用のtask(実験を管理する単位)を用意します。

公開サンプルのexperiment.jsを開き、コード欄右上のコピーアイコン(Copy raw file)を押して全文をコピーし、CognitionのSource code欄へ貼り付けます。

共通ライブラリfeedback-utils.jsを開き、コード欄右上の「Download raw file」で保存します。

External JS(外部JavaScriptファイルの登録欄)には、保存したfeedback-utils.js、手順1で作成したencrypted-api-key.js、surveyプラグインのJavaScriptを登録します。External CSS(表示を整えるCSSファイルの登録欄)にはsurveyプラグインのスタイルシートを登録します。プラグイン(jsPsychで画面や操作を提供する部品)は、重複読込を避けるためsurveyを選ばず、html-button-responseとcall-functionを有効にします。

この雛形は、AIを使うprompt_a・prompt_b条件と、AIを使わず自分でフィードバックを書くmanual条件を含み、生成時に入力するのは対象文章だけです。課題と対象者、A/Bのシステムプロンプト、モデルと生成設定、結果の評価項目を決め、実験コードの設定へ反映します。比較で変える条件と揃える条件は、「システムプロンプトをA/Bで比較する実験」に沿って整理します。A/B比較だけにする場合はCONDITIONSを["prompt_a", "prompt_b"]にします。

同意しない場合はAPIキーを復号せず終了します。同意後、セッションの最初にパスワードを一度入力してキーを復号し、三つの条件を終えるまでメモリ内に保ちます。manual課題自体ではキーを使わず、OpenAIへのリクエストを行いません。セッション終了時にキーを消去します。

3. 課題で動作と保存を確認する

実験サンプルで用意した課題に一度テスト参加し、以下の流れと記録を確認します。

  • 同意後のセッション開始時に一度だけパスワードを求め、空・誤ったパスワードや改変された暗号化データの場合は、どの課題やAPI送信にも進まないこと。
  • 3条件が無作為な順で各1回実施され、AI条件では入力・生成・編集・採用判断・提出、manualでは対象文章とフィードバックの入力・提出が進むこと。
  • 生成失敗後に同じ条件・モデル・入力で手動再試行でき、各試行と提出内容が記録されること。
  • APIキー、復号用パスワード、参加URL全体がデータや動作の記録であるログへ入らないこと。

テスト参加後にCognitionからデータを取得し、参加IDで条件・入力・生成・最終文が結びつくこと、予定した集計・分析に必要な項目が揃うことまで、参加者を募る前に一度確かめます。OpenAIの予算設定と有効期間も管理画面で確認します。10

4. 参加者へ案内して実施する

Cognitionで公開した参加用URLを案内します。URLにパスワードを含めず、同意後のセッション開始用パスワードを別に伝えます。

実験コードのCONDITIONSにある次の3条件を、参加者ごとに無作為な順で各1回実施します。条件は課題ごとに切り替わります。

  • prompt_a:改善案を直接示すAI条件
  • prompt_b:問い返しを中心にするAI条件
  • manual:AIを使わず、参加者がフィードバックを作る条件

セッション全体では同意後に一度だけパスワードを入力します。manual課題の画面で追加の認証はなく、その課題ではOpenAIに接続しません。個人情報と同意説明は「個人情報と外部送信」の節に沿って確認します。

5. データを取得して実験を終了する

Cognitionからデータを取得し、「記録するデータの設計」に示した項目を確認します。AIへの依頼、生成結果と失敗履歴、参加者の最終文・採用判断・変更有無が対応していること、キーやパスワードが記録されていないことを確認します。実施後は実験用APIキーを無効にします。

6. データを分析する

「システムプロンプトをA/Bで比較する実験」で決めた評価項目に沿って、条件ごとに採用の種類や変更有無などを集計・比較し、生成失敗と再試行も確認します。結果の違いが、参加者の経験や課題の難しさ、失敗・再試行の偏りなどでも説明できないか検討します。

考察

APIキーを保護できる範囲

公開コードには暗号化したAPIキーを置き、復号用パスワードは参加者へ別に案内します。これにより、コードを入手しただけの人にキーがそのまま渡ることを防ぎます。ただし、復号できる参加者はキーを取り出せます。信頼できる参加者による小規模・短期間の実験を前提に、専用のキーを使い、終了後は無効にします。

外部にAPIサーバーを置く方法との比較

参加者のブラウザとOpenAIの間に、依頼を仲介するAPIサーバーを外部に用意する方法もあります。この方法では、APIキーをサーバー側で保管し、参加者へ渡さずに文章を生成できます。OpenAIの一般的な案内も、APIキーをサーバー側で管理する構成です。

比較する点 今回のブラウザから直接呼ぶ方法 外部にAPIサーバーを置く方法
APIキーの扱い 参加者のブラウザで復号するため、参加者はキーを取得できる サーバー側で保管し、参加者へキーを渡さずに済む
準備と運用 実験画面、暗号化データ、予算と期限を準備する 実験画面に加え、サーバーの公開、利用者の確認、保守が必要になる
検討する場面 信頼できる参加者による、小規模・短期間の研究室内実験 広く参加者を募る場合、長期運用、参加者にもキーを渡したくない場合

APIサーバーを用意すれば、参加者ごとの利用回数などをサーバー側で制限する処理も実装できます。ただし、サーバーの構築や利用者の確認、運用まで含めると説明が複雑になるため、その実装手順は今回は扱いません。この記事では、研究室内の信頼できる参加者を対象に、ブラウザから直接呼ぶ方法を説明しています。

参加リンクとパスワードの渡し方

参加用リンクと復号用パスワードは別々に伝え、URL・公開記事・実験コードにはパスワードを含めません。意図しない相手に渡った疑いがあれば、実験専用APIキーを無効にします。14

生成回数と費用をどう考えるか

参加者数、モデル、入力と出力の長さ、再試行回数で費用が変わるため、予備実験の結果から必要額を見積もります。成功後の再生成は行いません。15ブラウザで送信回数を抑えることはできますが、取り出されたAPIキーの利用を止めることはできません。参加者別の厳密な上限が必要なら、仲介サーバーを含む方法を検討します。16

個人情報と外部送信

提出物は参加者のブラウザからOpenAIへ送られ、実験データとしてCognitionにも保存されます。フィードバックの作成者に加え、提出物を書いた人や第三者の個人情報にも注意が必要です。所属機関の倫理審査や研究上の手続きに沿って、送信先、内容、保存期間、削除の扱いを整理し、同意説明に反映します。APIの保存設定を変更しても、OpenAI側の全ての記録がなくなるわけではありません。保存やデータ利用は、公式のデータ管理の説明を確認して決めます。


  1. モデルは、学習で調整された数値である重みを使って入力に続く文章を生成します。モデルの選択や生成設定はAPIで指定しますが、モデル内部の重みを実験者が直接変える操作ではありません。fine-tuning(追加データによる調整)は、既存モデルへ文章生成を依頼することとは別の処理です。OpenAIの追加学習サービスは新規利用者への提供を終了しており、条件を満たす既存利用者も新しい学習を実行できるのは2027年1月6日までです(元のモデルの提供終了が先の場合はその日まで)。追加学習したモデルの利用期限は元のモデルの提供終了日に従います(公式ガイド)。 ↩

  2. このサンプルでは、モデルにgpt-6-luna、推論量にreasoning.effort=none、出力候補の選ばれ方のばらつきを調整するtemperatureに0.3を使います。GPT-6系では推論effortがnone以外の場合、temperatureは指定できません。モデルや世代を変えると性能、応答時間、料金も変わるため、モデル名と設定を記録し、比較では揃えます(最新モデルのガイド)。 ↩

  3. 検索で根拠を確認する条件と比べる場合や、AIが指定した処理を自作プログラムなどで実行するファンクションコーリング(function calling)を使う場合は、指示だけで文章を生成する条件とは異なります。使った機能や参照情報を記録し、追加費用も確認します。詳しくはOpenAIのツールの説明を参照してください。 ↩

  4. feedback_session_idはセッション開始時に一度発行し、そのセッションの全trial行へ記録します。課題を表すsystem_prompt_typeは各課題の行へ記録します。Cognition内部のrun ID(実験実行を識別するID)をブラウザから取得できる公開APIは確認できていないため、独自IDを使い、Cognitionの列は上書きしません。jsPsych組込のtrial_indexは変更せず、各画面・処理の実施順を記録します。Cognitionへ保存された過去の行を後から書き換える設計にはしません。 ↩ ↩2

  5. 記事内の準備画面は暗号化ツールのREADMEと配布用ZIPから確認できます。「文字列で試す」は公開の練習用で、実験キーを入力する欄とは別です。誤ったパスワードで復号を試す場合は、暗号化後に復号用欄だけを20文字以上の別の値へ変え、元に戻すと同じJSONで再確認できます。暗号化・復号はブラウザ内で行い、実APIキーを使わない練習文字列で復号も確認済みです。準備画面が外部へ通信しないことも確認しています。 ↩ ↩2

  6. 実験コードのCONDITIONSにはprompt_a、prompt_b、manualを指定し、参加者ごとに順序を無作為化して各条件を一度ずつ実施します。課題の行では、実際の条件名をsystem_prompt_typeに記録します。試行順はjsPsych標準のtrial_indexで確認します。 ↩

  7. AI課題では、1回の生成を90秒で打ち切り、初回を含め最大3回(手動再試行2回)とします。タイムアウト(待機を打ち切る時間)、通信エラー、サーバーエラー、レート制限(rate limit)は再試行候補です。再試行可能な失敗ではエラーを表示し、参加者が再試行ボタンを押した場合だけ、その課題の同じモデル・凍結した送信内容で再送し、generation_attemptだけを増やします。自動再試行や二重送信は防ぎ、失敗のたびにai_feedback=null(値がないこと)と安全なapi_errorを持つ生成行を追加して、成功行で上書きしません。認証・利用枠(quota)超過・入力不備など再試行で解決しないエラーや上限到達時は、その課題を終了し、termination_reasonを記録します。成功した課題だけ提出行を作ります。技術的失敗で中断した課題の提出行はなく、残りの条件へ進みます。キーは最後の課題後に消去します。タイムアウト後にサービス側の処理が継続する場合もあるため、再試行が費用を増やす可能性を見込みます。 ↩

  8. Responses APIでは、基本方針をinstructions、その回の依頼と提出物をinputとして送る構成です。APIキーは認証に使いますが、復号用パスワードと実験内の参加IDは生成用入力に含めません。提出物に含まれる情報は入力として送られます。各生成は独立させ、過去の会話履歴や外部ツールを含めません。指示と入力の扱いはプロンプト設計の説明も参照してください。 ↩

  9. 文章量や料金の計算に使う単位をトークン(token)と呼び、文字数と一対一に対応するわけではありません。入力と出力の長さやモデルで費用が変わります。入力・出力の単価はモデルによって異なるため、APIの料金表で確認し、予備実験の使用量から見積もります。 ↩

  10. サンプルでは次の列を記録します。

    • 全trial行にはfeedback_session_idが付きます。課題に属する行にはその課題のsystem_prompt_type、各段階の行にはfeedback_phaseも記録します。順序はjsPsych標準のtrial_indexを使います。
    • 入力行には提出物submissionを保存します。生成行には実際に送ったsystem_prompt、入力文字列api_input、model、reasoning_effort、temperature、max_output_tokens、generation_attemptを保存します。成功時はAI原文ai_feedback、応答モデルresponse_model、応答IDapi_response_idを、失敗時はai_feedback=null(値がないこと)と安全なapi_errorを記録します。このサンプルに独立したuser_prompt列はありません。
    • 提出行にはsubmission、ai_feedback、final_feedback、採用判断adoption、変更有無text_changedを記録します。as_isはそのまま採用、editedは編集して採用、rejectedは不採用です。採用は参加者の自己申告として扱います。text_changedはAI原文と最終文が同じならfalse、異なればtrueとし、空白や改行だけの違いも変更に含めます。
    • manual課題では生成行を作らず、提出行のai_feedback、adoption、text_changedはnull、生成回数generation_attemptは0です。
    • 技術的失敗で中断した課題には提出行を作らず、termination_reasonを記録して残りの条件へ進みます。APIキー、復号用パスワード、参加URL全体は保存しません。

    ↩ ↩2

  11. 前払い方式では残高が尽きるとAPIの利用が止まりますが、停止の反映には遅れがあり、入金額を超える場合があります。自動入金は初期状態でオンなので、オフになっていることを確認します。月次請求の契約では入金額が請求に充当されるため、前払いした額だけで利用が止まるとは限りません(前払いの公式説明)。残高はAPIキーごとの予算ではありません。他のプロジェクトと残高を共有する場合などは、実験専用プロジェクトの金額上限も併用します。予算通知は利用を止める設定と異なります(Spend limits)。キーの有効期限は公式の運用ガイドを参照してください。 ↩

  12. プログラム開発では、APIキーなどを.envという設定ファイルに分けて保存することもあります。ファイル自体が暗号化するわけではなく、公開しない管理が必要です。本記事のブラウザ実験で用意する必要はありません。 ↩

  13. 準備画面の生成値は15バイト(120ビット)の乱数をURL-safe Base64で表した20文字で、英大小文字・数字に-と_を加えた64種類を使います。以下は別条件として、英大小文字・数字62種類から各文字を独立に一様生成する場合の目安です。NVIDIA GeForce RTX 5070 Ti 1台(本ツールと同じく1候補につき60万回の反復計算、毎秒7273候補)では、平均探索時間は8文字で約476年、12文字で約70億年、16文字で約10京年です。64種類から20文字を生成する場合は同じ速度で約2.90 × 10²⁴年となります。

    これは暗号文の復号照合を含まず、同じ速度のGPUを1台使い続けると仮定した理論上の平均です。人が決めたパスワードや、正しい値を1回入力して復号する時間には当てはまりません。長く無作為な値を使う理由を総当たり探索への余裕として示す参考値です。詳しい暗号処理は補助コードのREADMEを参照してください。 ↩

  14. 一般にURLはブラウザ履歴やアクセス記録などに残る場合があるため、参加用リンクと復号用パスワードを分けて伝えます。分けて渡すことだけで漏えいを防げるわけではありません(OWASPの説明)。 ↩

  15. 費用の上限側の見積もりは、参加者数 × AI課題数 × 1課題あたりの最大生成回数で呼出し数を出し、予備実験で測った1呼出しあたりの使用量とモデル単価を掛けます。この例ではAI課題が2件、各課題は初回を含め最大3回なので、1人あたり最大6回です。manual課題はAPIを呼びません。実際の利用量は参加者の入力、出力、失敗の頻度で変わります。 ↩

  16. ブラウザ内の回数制限は、実験画面から誤って多数回送ることを抑えるためのものです。APIキーを取得した人が別の場所から使うことまでは制限できません。参加者ごとに厳密な上限を強制する必要がある場合は、キーを参加者へ渡さず、認証・制限を実装した仲介サーバーを検討します。 ↩