0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「AI が学生に質問する」振り返りアプリを Nuxt 4 × Claude API で作ってみた【個人開発】

0
Posted at

1. はじめに

授業を支援するツールとして、Furilog というサービスを作りました。授業の最後に、学生が AI と対話しながらその日の学びを振り返ります。

実は、この手のものを作るのは2度目です。2年前にも似たようなものを作って公開しています。

ただ、最初のバージョンでは、学生の書いた内容が次の問いに反映されませんでした。

問いは教員があらかじめ作って登録しておき、あとはその順番どおりに出るだけ。いわゆるシナリオ型です。

学生が何を書いても、返ってくる問いかけは変わりません。やり取りの形は成立していても、問いの中身は最初から決まっています。

新しいバージョンでは、この「問いを作って登録する」という作業自体をなくしました。教員が用意するのは、授業で扱った内容とキーワードだけ。何を聞くかは、学生が書いた内容をもとに AI がその場で組み立てます。

シナリオ型と生成AI型の違い

こうして生まれ変わったのが Furilog です。同じ「振り返り」でも、中身はもう別ものになりました。

「登録するほどではないけれど、少しだけ触ってみたい」という方向けに、ログイン不要のデモを用意しました。

役割 デモページ
学生 https://www.furilog.com/demo/student
教員 https://www.furilog.com/demo/teacher

ただ、デモは決まったデータで動いているので、AI との対話まではできません。AI がどう聞き返してくるかは、実際にやってみるのが早いと思います。お試し用の授業を用意したので、よければこちらもどうぞ。

  1. Google アカウントでログインする
  2. アカウントの種別で「学生」を選ぶ
  3. 所属する学校は「東京都 → Furilogデモ大学」を選ぶ
  4. 下の表から、その日の曜日のクラスコードで授業に参加する
曜日 授業 クラスコード
月 情報リテラシー入門 FEQX442D
火 メディア論 O3WK65TM
水 生成AIとのつきあい方 X3FEEIDU
木 著作権と引用 9AAV5R3A
金 データの見方入門 VO84S67Y
土 食と健康 6V2W6MIR

2. 何を解決するサービスなのか

授業の振り返りは、紙のリアクションペーパー、LMS のフォームなど、さまざまな形で行われています。形式は違っても共通して起きやすいのは、学生側が「書いて提出したら終わり」になることです。

しかも、その振り返りは学生ひとりの中だけで完結します。 書いた内容に誰も反応しないので、深く掘れていたのか、それとも表面をなぞっただけだったのか、本人にも分からないまま終わります。 教員が全員分を読んで一人ずつ返せればいいのですが、負担が大きく、掘り下げまで手が回りません。

書いて提出したら、そこで終わってしまう

学生が振り返りを出したあと、本来なら教員が掘り下げて返す。Furilog では、この返す役を AI が引き受けます。

学生が振り返りを送ると、AI がその内容を読んで掘り下げてきます。曖昧なままの点があれば、その場で聞き返されます。出して終わり、にはなりません。 自分の言葉で説明し直すうちに、分かっているつもりだった箇所が見つかります。

そして教員は、この対話に一切手を入れません。 問いを考える必要も、一人ずつ返事をする必要もありません。それでいて、誰がどこでつまずいているかは、対話の記録と理解度の推移からまとめて確認できます。

学生:AI との振り返り対話

学生:AI との振り返り対話

教員:振り返り結果

教員:振り返り結果

3. なぜ作り直したのか ―― ReCap の課題

3-1. 決められた問いに沿って書くだけで、深掘りができなかった

ReCapの振り返りは、シナリオ型のチャットボットでした。あらかじめ用意した問いを、決められた順に出していきます。やり取り自体は成立しますが、学生が何を書いたかは次の問いに反映されません。

実際に教員が登録していたのは、例えばこういう問いです。

登録された問いが全員に同じように出る

問い自体は悪くありません。問題は、誰に対しても同じ問いしか出せないことです。学生Aのように踏み込んで書いても、学生Bのように一言で済ませても、次に来るのは同じ問い。「なるほど、ではもう少し詳しく」と掘ることができません。

こうなると、短く済ませてしまう学生も出てきます。もちろん丁寧に書く学生もいますが、適当に済ませようと思えば済ませられてしまうのがこの形でした。

実際に何人か触ってもらったのですが、返ってきた内容を読んでいて、自分でもそう感じました。

3-2. 深掘りしようとするほど、教員の負担が増えた

上の構造の裏返しとして、問いを作るのは教員の仕事でした。

その日に扱った内容へ踏み込んだ問いにしようとすれば、回ごとに考えて登録することになります。逆に、「今日の授業で分かったことは何ですか」のような汎用的な問いにしておけば使い回せます。ただしその場合、問いはその日の内容に踏み込めません。何をどこまで書くかは、学生の裁量に委ねられます。 丁寧に書く学生からは深い振り返りが返り、そうでなければ一言で終わります。

負担を減らすほど、問いは当たり障りのないものになります。

もっとも、これは当初の方針どおりでもありました。振り返りの中身は教員が自由に決められた方がいいと考え、問いは各自で用意する設計にしていたからです。仕様としては意図したとおりに動いていました。ただ、「振り返りを支援するツール」を名乗る以上、振り返りの設計そのものまで人間に任せきりでよいのか、というのが後から出てきた疑問でした。

ReCap:教員が問いを1つずつ登録する画面

※ 背景は登録済みの振り返り。1セットにつき Q1・Q2・Q3 と問いを用意する。前面が、その作成ダイアログ。

3-3. 同じことを2か所に書いていた

ReCap は Nuxt 3 と Rails API の2リポジトリでした。

例えば「授業に説明文の項目を追加したい」と思ったら、触る場所は2つありました。Rails 側でデータの定義を変え、フロント側でも型の定義を手で書き足す。片方だけ直して満足してしまうことが、何度かありました。

やりたいこと 触る場所
項目を1つ増やす Rails のモデル + フロントの型定義
入力チェックを足す Rails のバリデーション + フロントのバリデーション
API を1本足す Rails のルーティングとコントローラ + フロントの呼び出し

厄介なのは、揃っていなくても動いてしまうことでした。気づくのはたいてい、実際に画面を触ったときです。

加えて、Rails はスネークケース、フロントの TypeScript はキャメルケースと、命名規則が違います(course_date と courseDate)。データを送受信するたびに、この変換が要りました。

どれも致命的ではありません。ただ、分かれているから発生していた手間でした。

3-4. 対話の途中経過が、どこにも残らなかった

ReCap では「いま何問目か」「もう終わったか」「これまでのやり取り」を、すべてブラウザが握っていました。サーバーに送られるのは会話が最後まで終わったあとで、全メッセージをまとめて1回だけです。

つまり、学生が途中でブラウザを閉じたら、そこまでのやり取りは消えます。 サーバーは、その学生が振り返りを始めたことすら知りません。

対話の進行は、すべてブラウザの中にあった

ただ、これは手抜きではありません。シナリオ型では、次に何を出すかが最初から決まっています。仮に1往復ごとにサーバーへ送っても、サーバー側で判断することは何もありません。 通信を挟むぶん、表示が遅れるだけです。

問いは最初にまとめて取得済みなので、次に進む処理は「何問目か」の数字を1つ増やすだけ。進行をブラウザに置くのは、この設計では自然な選択でした。

実際、問いはすぐに表示できてしまいます。そこで実装には、応答を3秒待ってから表示する処理を入れていました。即座に返ってくると機械的に見えるため、あえて間を置いてチャットボットらしいテンポを作る、という工夫です。

ちなみに Furilog では、この処理は要らなくなりました。毎ターン AI が問いを組み立てるので、間は演出ではなく実際の生成時間になります。

以上の4つが、作り直しを決めた主な理由です。

どれも、一部を直せば済むものではありませんでした。問いをあらかじめ用意するという仕組みと、対話の進行をブラウザに置くという構成。この2つの前提から変える必要があり、それなら作り直した方が早いと考えました。

4. ReCap から Furilog で変えたこと

比較表

項目 旧:ReCap 新:Furilog 変えた理由
振り返りの仕組み 教員が登録した問いを順に提示 教員は授業概要・キーワード・モードを設定し、問いは AI が対話の中で組み立てる 深掘りできない・教員の負担が大きい、という ReCap 最大の課題への回答
構成 2リポジトリ(Nuxt 3 + Rails API) Nuxt 4 単一(Nitro の server routes で API を担当) 同一言語・同一リポジトリで開発効率を上げる
レンダリング SPA SSR Nuxt 4 に寄せた際に有効化。LP や規約ページなど、認証の要らない公開ページの初期表示が速くなった
認証 Firebase Auth + Rails で JWT 検証 Supabase Auth(Google OAuth) 認証が PostgreSQL 側にあり、発行されたユーザー ID をそのまま User の主キーに使える
DB / ORM PostgreSQL + ActiveRecord Supabase の PostgreSQL + Prisma TypeScript で型が通るため、フロントと同じ型定義を共有できる
AI OpenAI Anthropic Claude 振り返りの対話では日本語の自然さが要件になる。体感で Claude が適していた
UI Tailwind + 自作コンポーネント Tailwind + Nuxt UI 前回は1つずつ自作していた。用意されているものを使えば、作る手間がそのまま省ける
バリデーション yup Zod(フロント・サーバー共通) 同じスキーマをクライアントとサーバーの両方で使い回す

特に大きかった変更:問いを「持つ」から「生成する」へ

ReCap では問いがデータとして DB にありました。Furilog では、DB にあるのは問いを組み立てるための材料だけです。

ReCap と furilog のデータ構造の比較

ただし Furilog にも、問いの文面自体は残ります。ReflectionMessage がそれです。テーブルだけ見れば ReCap と似ています。違うのは、それが書き込まれるタイミングです。

ReCap の問いは、対話が始まる前に教員が書いた台本でした。対話はそれを順に読み出すだけです。一方 Furilog の ReflectionMessage に入るのは、AI が組み立てて学生に出したあとの文面、つまり記録です。読み出すためではなく、あとから見返すために残っています。

とはいえ、これで問いづくりが教員の手を完全に離れたわけではありません。負担がゼロになったとは言えないのも事実です。授業概要とキーワードは、依然として教員が用意します。

もっとも、授業には多くの場合シラバスがあり、その回で扱う内容も書かれています。想定しているのは、そこから持ってきてもらうことです。 シラバスがない授業もあるので、そこは各々になりますが、ゼロから文章を考える作業ではありません。

その日の内容に踏み込んだ問いを、毎回考えずに用意できる。 これが、教員の負担が減ったいちばん大きい点です。

5. 機能紹介

使い方の流れ

全体像を先に示します。そのうえで、主要な機能をいくつか紹介します。

教員と学生の使い方の流れ

教員の事前準備は、初回だけ授業の概要を設定し、2回目以降はその回のキーワードとモードを選ぶだけです(必要なら補足を添えられます)。

Furilog:振り返りの設定画面

※ 上が初回に設定するテンプレート。下が授業回ごとの設定で、毎回触るのはこちらだけ。

学生が振り返りを終えると、その内容はすぐ教員の画面に反映されます。個々の記録も、クラス全体の進み具合も、その都度確認できます。

学生:AI との振り返り対話

授業日になると、その回の振り返りができるようになります。AI が問いを投げ、学生が送った内容を踏まえて次の問いを生成します。

何往復で終わるかは決まっていません。 学生が主要な点を自分の言葉で説明できていれば、AI はそこで締めに入ります。逆に、曖昧なまま・説明が浅いままの点が残っていれば掘り下げます。

つまりしっかり振り返れている学生ほど、対話は短く終わります。 理解できている人を引き延ばしても意味がないので、意図的にそうしています。ただし短すぎても振り返りになりませんし、逆に延々と続いても困るので、下限と上限だけはこちらで決めています(この制御は8章で書きます)。

締めくくりには、フィードバックが提示されます。

Furilog:振り返りのフィードバック

学生:みんなの振り返り

振り返りをひとりで終えると、見えるのは自分の理解だけです。「自分だけが分かっていないのでは」と思ったまま終わることもあれば、逆に「分かったつもり」に気づけないこともあります。

同じ授業を受けた他の学生の振り返りを読めるようにしたのは、そこに気づきの機会を置きたかったからです。

  • 自分が引っかかった箇所で、他の人も同じように引っかかっている
  • 同じ授業を聞いていたのに、まったく違うところに注目している人がいる
  • 自分では思いつかなかった説明の仕方をしている人がいる

他の人の振り返りを読むこと自体が、そのまま学び直しになります。

匿名の付箋として並ぶので、誰が書いたものかは分かりません。授業回ごとに切り替えられるので、過去の回も遡って読めます。

Furilog:みんなの振り返り

教員:振り返り結果

対話そのものは AI に任せています。ただ、学生がいまどういう状態かは、教員に見えている必要があります。

学生 × 授業回の表に、受講者全員ぶんが並びます。スコアは5段階で色分けされ、まだ振り返っていない回は「—」で表示されます。気にかけたい学生が、表を眺めるだけで見つかります。スコアの推移はグラフで追えるので、クラス全体の理解度が上がっているのか、特定の回でつまずいたのかも見えます。

個別の対話を読みたければ、学生名から全文を開けます。まず表とグラフでクラス全体を眺め、気になった学生だけ対話を開いて確かめる、という使い方ができます。

Furilog:学生別の振り返り結果

※ 上がクラス平均スコアの推移、下が学生 × 授業回の表。スコアは5段階で色分けされ、まだ振り返っていない回は「—」になる。

振り返りの2つのモード

ReCap では、用意した問いを順に出すことしかできませんでした。Furilog は、学生が送った内容を読んだうえで次の問いを組み立てます。それなら、問いを重ねるだけでなく、聞き方そのものを変えられるのではないか。

そう考えて用意したのが、ティーチバックとメタ認知という2つのモードです。どちらも聞き返す相手がいると効くもので、その役を AI に任せています。

モード AI の振る舞い ねらい
ティーチバック 「知らない初心者」役として学生の説明を聞き、掘り下げ質問を投げる 人に教えることを通じて、自分の理解が整理される
メタ認知 対話の中で1〜5の自己評価を引き出す 「分かったつもり」と実際の理解のギャップに気づく

教員は授業回ごとにモードを選ぶことができます。

1つで足りるのでは、と思われるかもしれません。ただ、2つは引き出すものが違います。

ティーチバックは、説明させることで理解の穴を見つけます。分かっているつもりでも、いざ人に教えようとすると言葉に詰まる箇所が出てきます。AI が「初心者」役で聞き返すので、学生は噛み砕いて言い直すことになり、その過程で自分の理解が整理されます。

メタ認知は、理解度そのものを本人に評価させます。「5段階でいくつか」と問われると、根拠を考えざるを得ません。自己評価と、対話から見えた実際の理解にズレがあれば、そこが「分かったつもり」だった部分です。

前者は理解を深めるため、後者は理解の程度を測るためのものです。同じ「振り返り」でも、目的が違います。

6. 使用技術スタック

4章では「何を変えたか」を軸に並べたので、ここでは現在の構成だけを一覧にしています。

分類 使用技術
言語 TypeScript
フレームワーク Nuxt 4(SSR)
UI Nuxt UI、Tailwind CSS
DB / ORM Supabase PostgreSQL、Prisma
認証 Supabase Auth(Google OAuth)
ストレージ Supabase Storage
AI Anthropic Claude(Haiku 4.5)
バリデーション Zod
テスト Vitest、nuxt/test-utils
インフラ Vercel
CI/CD GitHub Actions
その他 unovis、nuxt/fonts

サービス構成

Furilog:サービス構成

データ構造

Furilog:ER 図

7. 技術選定で考えたこと

前回開発した ReCap は初めてのポートフォリオでした。最後まで作りきれるかが一番の不安だったので、すでに学んだものをベースに開発を進めていきました。バックエンドに Rails を選んだのも、チュートリアルで一通り触っていたからでした。

今回、頭にあったのは、ReCap を作っていて手が止まった場所です。理由は大きく2つありました。

1つは、Ruby と TypeScript を行き来していたことです。どちらも習熟していたわけではないので、書き方を調べながら進めることになります。調べる対象が2つあるぶん、Rails 側で詰まって調べ、フロントに戻ってまた別の作法を調べる。切り替えるたびに手が止まり、開発は思ったより進みませんでした。

もう1つは、同じことを2か所に書いていたことです。項目を1つ増やすのに2か所を直す、命名の違いを変換する、片方だけ直して気づかない。手間がかかるだけならまだしも、直し忘れはそのままバグになります。

そこで今回は、扱う言語を1つに絞り、同じことを2度書かなくて済むことを選定の基準にしました。

フロントとサーバーで言語を分けるのをやめた

フロントもサーバーも TypeScript に統一しました。調べる先を1つに減らし、書く場所を1か所にまとめるためです。

ReCap は Nuxt 3 と Rails API の2リポジトリでした。ただ、言語が分かれていると同じことを2回書くことになります。入力チェックは Rails の validates とフロントの yup に。型は Rails のモデルとフロントの型定義に。命名規則も違うので、送受信のたびに変換が要ります。

今回は Nuxt の server/ ディレクトリを使い、フロントもサーバーも TypeScript に統一しました。入力チェックは Zod のスキーマを1つ書き、#schemas というエイリアスで両側から読みます。型は Prisma がスキーマから生成するので、DB の定義を変えればサーバーの型が変わり、そのままフロントまで届きます。

項目を1つ増やすときに触る場所は1か所になり、片方だけ直して気づかないということがなくなりました。

効いたのは、それだけではありませんでした。調べる対象が TypeScript ひとつに絞られたぶん、同じ調べ方が次の場面でも使えます。 片方で覚えたことがもう片方でも通じるので、ReCap のときのような言語の切り替えで止まる時間がなくなりました。

認証とアプリのデータを別々に持つのをやめた

ユーザー情報を2か所で持たなくて済むよう、認証とアプリのデータを同じ PostgreSQL に載せました。

認証・ストレージ・リアルタイム通信は Firebase にも揃っています。それだけでは乗り換える理由になりません。違ったのはデータベースでした。

ReCap では、アカウントは Firebase、アプリのユーザーレコードは PostgreSQL。ユーザー情報が2か所に分かれていました。 両者を対応づけるコードは、自分で書く必要があります。

Supabase の認証は PostgreSQL の上に載っています。発行されたユーザー ID を、そのまま User テーブルの主キーにできました。

model User {
  id    String @id   // Supabase Auth のユーザー ID をそのまま使う
  email String @unique
  ...
}

対応づけのコードは丸ごと不要になりました。 ストレージとリアルタイム通信も同じ Supabase の上にあるので、ログインした状態のまま、つなぎのコードなしで使えます。

AI モデルだけは、別の基準で選んだ

ほかの選定は「同じことを2回書かない」が基準でした。モデルだけは違います。

振り返りの相手は AI なので、どんな口調で返してくるかが、そのまま体験になります。 事務的すぎると問い詰められている感じになり、砕けすぎると軽く見える。機能ではなく書き味の問題です。

いくつか試して、日本語の返しがいちばん自然だったのが Claude でした。ここは数字で比べられる部分ではないので、自分で読んで決めています。

8. 実装で工夫したこと

終わり方が、誰にも決まっていない

生成AI型にすると、まず前提が変わります。次の問いを作るには毎ターン LLM を呼ぶことになり、その呼び出しはサーバーの仕事です。ReCap では問いが登録済みだったのでブラウザの中だけで対話が完結していましたが、Furilog では1往復ごとにサーバーを通ります。対話の進行をサーバーが握っている、という状態になりました。

問題は、そのあとに出てきました。

シナリオ型のときは、終わりを考える必要がありませんでした。用意した問いを出し切ったら終わり。それだけです。

ところが問いを AI に組み立てさせた瞬間、終わりが誰にも決まっていない状態になります。

とりあえず動くものを作って試してみました。学生が短めに書いたときは、AI も早めに切り上げてくれます。浅いといえば浅いのですが、振り返りとしては一応それなりに成立していました。

困ったのは逆のほうです。話が広がると、AI はいくらでも質問を続けられます。学生が答えれば、その答えの中からまた次の問いが出てくる。放っておくと、いつまでもきりがない。

深く掘り下げたくて問いを生成型に切り替えたのに、今度は掘り下げの止め方がない。そういう状態でした。

終わってよい「範囲」だけを決めておく

やり方はいくつか考えました。往復数を固定する。学生に「終わる」ボタンを持たせる。教員に設定させる。

どれもしっくりきませんでした。固定すると結局シナリオ型と変わらず、深く話せている学生も、まだ何も言えていない学生も、同じ回数で終わります。学生に終わらせるのは、終わりの判断が理解度と関係なくなってしまう。疲れたから終わり、が通ってしまいます。

教員に設定させるのも違いました。手間が増えるというのもありますが、それ以上に何往復が適切なのかを事前に判断するのが難しい。授業の内容によっても、学生の書き方によっても変わります。結局は何度か試して感触をつかむしかなく、教員にその手探りを毎回させることになります。 それなら、こちらで決めて固定してしまったほうがいい。

落ち着いたのはこの形でした。往復数の下限と上限だけをサーバーが持って、その範囲の中は AI に任せる。

上限は、さっきの「いつまでも終わらない」を止めるためのものです。下限のほうは、短く終わったときに浅いまま流れてしまわないよう、最低限はこちらから掘らせるために置いています。

状態 AI への指示
下限に達していない まだ締めない。曖昧な点を1つだけ掘り下げる
下限〜上限の範囲 十分に振り返れたと思えば締める。掘る余地があれば続ける
上限に達した 必ず締める。新しい質問はしない

往復数と3つのフェーズ

毎ターン、サーバーが今どの状態かを計算して、AI へ渡す指示文の最後のひとブロックだけを差し替えます。

const turnPhase = reachedMax
  ? 'final'                                  // 上限 → 必ず締める
  : (reachedMin && selfEvalReady ? 'decide'  // 範囲内 → AI が判断する
      : 'continue')                          // 下限未満 → 必ず続ける

では、AI が締めたことをサーバーはどう知るのか。返ってくるのはただの文章で、終了フラグが付いてくるわけではありません。

そこで、締めるときは決まった一文で終えるよう頼んでおき、その一文が入っていれば締めたと判断しています。 この一文は、学生の画面にもそのまま表示される締めくくりの言葉でもあります。

まとめると、「終わっていいか」の判断は AI に、「終わっていい範囲」はサーバーにという分担です。全部 AI に任せると止まらないし、全部サーバーが決めるとシナリオ型に逆戻りする。その真ん中を探った結果がこれでした。

書いたとおりには動いてくれない

さて、ここまでの話には大きな前提があります。AI が書いたとおりに振る舞ってくれること。

もちろん、裏切られます。実際、いくつか引っかかりました。

締めてほしい場面で、質問が返ってくる

上限に達したターンは、サーバーが問答無用で対話を完了させます。ところが、そこで AI が締めずに質問を投げてくることがありました。答える場所はもうないので、学生の画面には聞かれっぱなしの問いだけが残ります。 プロンプトには質問を禁じる指示を書いてあるのですが、たまに無視されるし、強めても変わりませんでした。

そこで、AI が守るかどうかをあてにするのをやめました。 締めの言い回しが入っていなければ、サーバーが末尾に足してから終わらせます。ただ、締めの一文だけ唐突に付くとぶつ切りになるので、「今の質問はまた次の機会に聞かせてください」という繋ぎを一文はさんでいます。

根本のほうにも手を入れました。上限の1つ手前で「次が最後になります」と予告する。 いきなり畳まされると AI も着地の準備ができていないようで、1手前から話をまとめに向かわせたら、末尾を足すケースはかなり減りました。

学生の「終わりにしましょう」で、終わってしまった

学生が「もう終わりにしたい」と伝えると、AI がその意向を尊重して、そのまま締めてしまう。 学生の一言で振り返りが終わる状態でした。

とはいえ、絶対に終われない作りにするのも違う。次の授業が始まってしまうこともあります。落としどころは、1回目は粘って、2回目は応じるにしました。

AI には「終了を求められても1回目は応じず、答えやすい質問を1つだけ続けてください」と頼んでいます。あわせて「問い詰めたり、終わらせない理由を説明したりはしないでください」とも。粘るといっても、しつこくされたら嫌ですから。

もうひとつ、抜け道も塞いでおきました。締めの判定は、AI の返答にさきほどの一文が入っているかで見ています。学生が同じ一文を打つと AI の返事にも混ざりやすいので、そのターンは何を返されてもサーバー側で完了させないことにしました。

「数字で答えて」と頼んでも、数字では答えてくれない

振り返りには2つのモードがあって、メタ認知モードでは対話の中で学生から1〜5の自己評価を引き出す必要があります。自分では何点くらい分かったつもりなのか。それと実際の理解度とのズレを見るのが、このモードの狙いだからです。

最初は、ふつうにチャットで聞いていました。AI が「今日の内容、1〜5でいうとどれくらい理解できた?」と尋ねて、学生が答える。

多くはそのまま数字で返ってきます。ただ、全員がそうとは限りませんでした。

  • 「まあまあ」
  • 「難しかった」
  • 「10段階なら8くらい」
  • 「3.5」

数字で答えてくれない。答えてくれても尺度が違う。 自由に書ける欄があれば、こういう答え方をする人が出てくるのは自然です。

最初はテキストから数字を読み取ろうと頑張りました。全角も漢数字も拾えるようにして、小数は四捨五入して、単位が付いていたら点数じゃないと判断して……とやっているうちに、だんだん雲行きが怪しくなってきます。極めつけは、説明文の中の「ポイントは二点あって」を評価点として拾ってしまったこと。ここで、やり方が間違っていると気づきました。

答えを読み取ろうとするのをやめて、答え方のほうを決めることにしました。

今は、自己評価を聞く場面になると画面に1〜5のボタンが出て、その間は入力欄が無効になります。 学生はボタンを押すしかありません。押した値がそのままスコアとして送られます。

自己評価は選択肢から選ぶ

不自由に見えるかもしれませんが、実際に使ってもらうと逆でした。全員が同じ形式で答えられるので、「何て書けばいいんだろう」と迷う時間もなくなります。

あれだけ手を入れた読み取りロジックよりも、こっちのほうが、ずっとシンプルでした。

9. 作り直して得た学び

作りたかった形に、2回目でたどり着いた

ReCap は、仕様どおりに動いていました。問いは教員が自由に決められて、学生はそれに沿って答える。当時考えていたとおりのものが、そのまま形になっています。

ただ、公開して人に使ってもらってから、物足りなさがありました。シナリオ型である以上、深いところまで振り返ってもらうのは、使い方のうえでどうしても難しい。

そこで出てきたのが、一人ひとりに合った振り返りができたら、もっといいのにという心残りでした。

Furilog で、ようやくそれが形になりました。学生が書いた内容から次の問いを組み立てる。自分が作りたかったのはこれだと、作ってみてはっきりした感じです。

自分で使うまで、出てこないバグがあった

学生になったつもりで実際に振り返りをやってみました。そこで、テストでは出なかった不具合が立て続けに見つかりました。

  • ストリーミング中にリロードすると、同じ質問が2つ並んで、以降ループする
  • 学生が「今日の振り返りはここまでにしましょう」と入力すると、そこで終われてしまう
  • 「1〜5で」と聞いても「まあまあ」「10段階なら8くらい」と返ってくる
  • 上限の回に、AI が質問したまま対話が終わる

どれもテストは全部通っている状態で起きています。 書いたテストは仕様どおりに動くことを確かめるもので、人が実際にどう操作するかまでは見ていません。

リロードすることも、途中で終わりたいと言うことも、数字で答えないことも、どれも普通の操作です。こちらが期待したとおりに使ってくれる人しか、想定できていませんでした。

直し方は8章に書いたとおりですが、見つかったのはコードを読んでいたときではなく、使っていたときでした。

AI を組み込むと、コストが設計に入ってくる

ReCap では、AI を呼んでいたのは最後のフィードバック生成だけでした。対話そのものは登録済みの問いを出すだけなので、やり取りが何回続いてもコストは変わりません。

生成AI型にすると、ここが逆転します。1往復ごとに AI を呼ぶため、往復数も入力の長さも、そのまま費用になります。

今回は入力文字数・出力トークン数・往復数のそれぞれに上限を置きました。

使われるほど費用が増える作りにした以上、どこで止めるかを決めることまでが設計でした。

10. おわりに

2年前に作ったものを、問いをあらかじめ用意する形から、その場で組み立てる形に作り直しました。

いまは良いものを作れたと思っていますが、ReCap のときも同じでした。 足りないものは、作って、人に使ってもらってはじめて見えてきます。Furilog にも、まだ気づいていないものがあるはずです。

だからこそ、触ってもらえるとうれしいです。まだの方は、1章のお試し用の授業からどうぞ。

使ってみた感想や、設計について「自分ならこうする」などご意見があれば、コメントで教えてください。サイトのお問い合わせフォームからでも大丈夫です。

最後まで読んでいただき、ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?