くろみーの日報テンプレ

日常のつぶやき

レポジトリをまとめてアーカイブできる gh 拡張を作った

5月から dotfiles のパッケージ管理を mise に寄せる試みをやっている

zenn.dev

やってみて一番嬉しいのは Renovate によってツールのバージョンが自動的にチェックされ、最新版への移行PRを毎日立ててくれることだ

毎日 GitHub の通知欄を見に行って、Renovate の PR があるかチェックして、あったらレビューしてマージ…という生活を一ヶ月ほど続けていた

あるときふと gh-dep というツールがあったことを思い出して、わざわざ GitHub のサイトにアクセスしなくてもターミナルからRenovateのPRをマージする方法を思いついた

github.com

ここからようやく本題に入るが gh-dep を使うようになって気づいたのが、今はもう使わなくなったレポジトリに Dependabot の PR が大量に立っていることだった

そのまま放置しててもいいのだがなんとなく気持ち悪いと思って、レポジトリをアーカイブしたくなった

しかし量が多いのでブラウザで一つづつアーカイブしていくと日が暮れそうであった

ネットで探すと下記のようにレポジトリを一括でアーカイブする便利なワンライナーはあったのだが、個人的にはちょうど gh-dep みたいにインタラクティブにレポジトリをフィルタリングしてアーカイブできるようなツールが欲しかった

zenn.dev

既存のツールを探したが、探しても見つからなかったので自分で作ってみることにした

github.com

使い方はこんな感じ

Typeでフィルター、Spaceで選択、Enterで実行というシンプルな構成にした

gh extension なので以下のコマンドで簡単にインストールできる

gh extension install kromiii/gh-archive

これによって無事レポジトリが整理され gh-dep で快適にdotfileの運用ができるようになった

今の時代頑張ってワンライナーを書くよりもAIに任せて拡張機能を書き切ってしまう方がトータルで見ると早いということを感じた初夏であった

Gemini Live API を使って論文と対話できるZotero拡張機能を作った

5月から国立情報学研究所のクラウド基盤研究開発センターというところで働いている

大学院を出てから三年企業で働いていて、もちろん得たものは大きかったものの、錆びついてしまったスキルもいくつかあって、その一つが英語力だ

博士課程のときは研究室に留学生が多かったのもあって、留学経験がない人間にしては英語ができる方(自認)だった

今月上旬にオンラインでドイツの研究者と話す機会があったのだが、妙なところで度胸がある自分は、三年のブランクはあるもののどうせやってみたらなんとかなるだろと思っていた

結果ものの見事に撃沈してしまった

昔ならジャパニーズイングリッシュで発音は良くないけど、とりあえず英語の構文は成り立っていて、簡単な単語をいくつか組み合わせることで無理やり会話ができていたのだが、今はもはや会話が文章の体をなしておらず、相手にも気まずい思いをさせてしまった

これは何とかしないといけないと思い、あわてて昔やっていたオンライン英会話のサービスを調べたりしたのだが、安いものでも月額数千円はかかってしまうし、家庭を持った今となっては、毎回英会話講師と予定を合わせて決められた時間にレッスンに参加するのはちょっと難しい

そもそも今やAI時代なので、英会話の練習をするのに生身の人である必要もな以下と思って Gemini Live で英会話の練習をする方法を調べたら似たようなことをやっている人がいた

neoverseai.main.jp

英語の練習ならこれでもういいじゃんと思ったのだが、英語を使う場面がもうわかっているのであれば、最初からその文脈で練習をするのが手っ取り早いのではということで、ZoteroとGemini Live API を使って論文を題材にした英会話練習をするためのプラグインを作った

github.com

Zotero の設定画面で Gemini API Key を設定すると、開いている論文の内容をコンテキストとして読み込んだ上で Gemini Live が応答してくれるという仕組みとしては簡単なもの

Zotero の拡張機能は Zotero の内部APIにアクセスできるので、自前でPDFのテキスト抽出を考えなくても良いのはありがたかった

とりあえず動作確認も兼ねて何回か使っているが今のところは良い感じ

いわゆるテキストモデルと比べると音声モデルは値段が高くて、累計(おそらく)十数分ほど動かしてみての請求額はこんな感じ

とはいえそれでも生身の人間と話すよりは安いのと、論文について音声で議論できるというのはなかなかに得難い体験ではあって、しばらく自分用に使ってみようと思う

ぜいたく三昧

ぜいたく三昧というぬか漬けの素があって、最近よく使っている

www.kokujo.jp

ぬか漬けというとなんだかハードルが高い印象があったが、去年の今頃義母がやっているのを見ていてこれならできそうだと思って自分でもやってみることにした

我が家ではぬか床にはジップロックを使っている

Lサイズを買うとぜいたく三昧が一パック丸々入るので便利

なんとなくぬか漬けは夏場に食べたい感じがあり、冬の間しばらく休止していたが春から再開した

ぜいたく三昧と言いつつ価格はリーズナブルで一袋330円

これで数ヶ月は持つんじゃないかと思う


最近巷でAI疲れなる単語がよく聞かれるようになった

何のことかというと、とにかくずっとAIを働かせていないと気が済まなくなってしまい、AIからの問い合わせに応え続けるうちにメンタルに不調をきたしてしまう状態のことらしい

自分はあまりその状態になったことはないが、AIに疲れたらぬか漬けをやってみるのもいいんじゃないかと思う

ぬか漬けをつければ自分が寝ている間も微生物が働いて勝手に食材を美味しくしてくれる

AIを並列で回したければぬか漬けを何個もつければいいだけの話で、これは全然難しくない

とはいえぬか漬けのスピード感で仕事をするのはなかなか許されない世の中になっているのも確かで、そう考えると何かを待っていられる時間というのは確かに贅沢なものなのかもしれない

ぜいたく三昧というのは価格のことじゃなくて時間のことを言っていたのか、とそれらしいまとめを置いてみる

zengin-rb の軽量版 gem として zengin-lite を作った

最近部署異動があり Good First Issue として銀行コードの絡むお問い合わせの対応をした

結論から言うと、銀行コードのバリデーションに使われていた zengin-rb という gem が最新の支店の追加に追従できていなかったことが原因だったため、当該の支店のバリデーションを個別に追加することで対応した

そのときの話を Omotesando.rb で話したときのスライドはこちら

speakerdeck.com

というような話を社内でもしていたら @akatsuura さんから

「この gem 使いやすいんだけどメモリ結構食うんだよね」

という話があり、調べたら確かにメモリ使用量だけでいうと重量級(サービスで上から数番目くらい)のgemだった

zengin-rb は gem が読み込まれる際に呼ばれる preload! メソッドが全銀行の全支店をメモリ上に展開するのだが、ご存知の通り(?)日本の銀行の数は多く、さらにそれぞれの支店まで全て読み込むとなると軽く10MBくらいはいってしまう

現代のProduction環境で10MBのメモリなんてほぼ気にしなくて良いと言われればそれはそうなのだが、なんとなくメモリ使用量の少ない zengin-rb を作るとしたらどんな感じになるんだろうかと気になったので作ってみた

rubygems.org

コードは GitHub で公開している

github.com

ZenginLiteのLiteはもちろん読み込みが高速という意味もあるのだが、今回メモリ使用量を削減するにあたって SQLite を使うことにしたのでその意味あいの方が強い

heap-profilerで読み込み時のベンチマークを取るとメモリ使用量だけで見れば zengin-rb の 1% ほどに抑えることができた

Total Memory Allocated:
  zengin-rb:   10.09 MB
  zengin-lite: 91.04 KB
  Difference:  10.0 MB
  Ratio:       zengin-lite uses 0.9% of zengin-rb

gemロード時のメモリ使用量が少ないということはgemの読み込みかかる時間そのものも少ないということで、zengin-lite は zengin-rb よりも4.1倍早く読み込むことができる

Gem Loading Time (require time):
  zengin-rb:   233.93 ms
  zengin-lite: 56.92 ms
  Difference:  177.0 ms
  Result:      zengin-lite is 4.1x faster (75.7% faster)

ベンチマークに使ったスクリプトはこちら

ただし副作用もあって、どんなシチュエーションでも zengin-lite の方が優れているというわけではない

  1. 依存関係が増える(SQLiteをbundleしているため)
  2. データ読み込み時に毎回クエリが走るので全銀行・全支店のイテレーションなどには不向き

このあたりはレポジトリの README に注釈として書いておいた

とはいえ自分たちのように単一の銀行・支店のバリデーションに使うだけなら全データをメモリにロードするよりも都度クエリしたほうがトータルではコスパ良い気がしていて、うまい使い分けができたらいいと思う

Claude Code の Plan モードはサブエージェントだった

今年の9月からClaude Code を使い始めた

カスタムスラッシュコマンドあたりまではまだギリギリついていける気がしてきたのだが、サブエージェントやらスキルやらが出てきたあたりからClaude Code のアップデートに完全についていけなくなってしまった

このままではまずいと思い、年末この本を買って読んだ

gihyo.jp

最新の情報はドキュメントにあるんだから公式のドキュメントを読めよという話もありつつ、やはり紙の書籍からしか得られない栄養というのはあるみたいで、1冊ざっと流し読みしたら最近のトレンド(サブエージェント、スキル、スペック駆動開発あたり)の概要はある程度つかめた気がする


中でも一番驚いたのは Claude Code の Plan モードが実は(自分がマニア向けの機能だと思っていた)サブエージェントだったということだ

Plan モードは Claude Code 上で Shit + Tab を何度か押すと切り替わるモードの1つで、Plan モードになっていると Claude はコードの編集をせずに、コードベースから実装方針だけを立ててくれる

plan モードに切り替えた状態

実装の方針がよくわからずとりあえず Claude の意見だけ聞きたい時に便利で自分は好んで使っていたのだが、この本を読んでこの機能が実は Claude Code 上でサブエージェントとして実装されていることを知った

https://code.claude.com/docs/en/sub-agents#plan-subagent

サブエージェントになっていると何が嬉しいかというと親タスクのコンテキストを圧迫しないことだ

サブエージェントは親タスクから呼び出されると独立したコンテキストで調査を開始し、結果だけを親タスクに返す

こうすることによってサブエージェント内でどれだけのファイルを読み込んでも親タスクのコンテキストを圧迫しないので、調査用に大量のファイルを読み込んでも後の実装フェーズへの影響がない

Planモード、今まではClaudeの書き込みをブロックする機能くらいの理解しかしていなかったが、これを聞いてサブエージェントの使い所がちょっとわかった気がした

奈良時代の水筒

奈良時代からの水筒を持っている

といっても日本史の奈良時代ではなくて自分史の奈良時代だ

奈良に住んでいた2022-2023年の間を自分の中での奈良時代としている

同様に京都に住んでいた期間は京都時代、三鷹に住んでいた期間は三鷹時代とよんでいる

記憶の引き出しは時間で区切るよりも場所で区切ったほうが自然な気がする

何年何月に何をしていたかと言われてもパッと思い浮かばないけれど、この場所住んでいた時の感情はありありと想起することができる

この水筒を買ったのは奈良生活の最終日、就職のために東京へ向かう電車の待ち時間だった

就職先で無料で水が飲めることを知って感動した僕は、仕事内容などそっちのけで、これだけは準備しておかねばとあわてて購入した記憶がある

自分はモノを多く持たない主義なので奈良時代の持ち物いまほとんど手元に残っていない

写真の水筒は自分の持っている物の中ではかなり古参になってしまった

今日家族から新しい水筒をもらったのでこの水筒も今日限り

ものはなくなるけれど奈良時代の記憶はずっと色褪せずに残っている

一生ぶんの体育座りをしている

ここ最近、体育座りを酷使している。 というのも、子供の寝かしつけに非常に便利なのだ。

以前、寝かしつけからのベッド移行が難しいという話を書いた。

blog.kromiii.info

理化学研究所の研究によると、抱っこで寝かしつけた後、すぐにベッドに置くのではなく、5分ほど座って抱っこを続けてから置くと成功率が上がるらしい。

www.riken.jp

この記事では椅子に座った状態での寝かしつけが紹介されているが、自分が寝落ちしてしまうのが怖い。そこで編み出したのが、体育座りの膝に赤ちゃんを乗せ、45度くらいの角度で保持する方法だ。これなら安定感があり、自分も寝てしまう心配が少ない。

小学校の時、なぜあんなに体育座りをさせられたのか不思議だったが、すべてはこの時のための伏線だったのかもしれない。

スティーブ・ジョブズがスピーチで語ったように、未来を先読みして点と点を繋ぐことはできない。しかし、過去を振り返った時に初めて、その点と点が繋がっていることに気づく。

youtu.be

まさか、あの体育座りの日々が、数十年後の我が子の寝かしつけという形で繋がるとは。子供の穏やかな寝顔を見ながら、人生の不思議な縁(えにし)を感じている。

イシトビキャベツ『New Driveway』感想

先日オンラインで購入した書籍の感想

cabbage-shop.stores.jp

作者のイシトビキャベツさんは元会社の上司で、会社にいた時はトビーさんと呼ばれていた

キャベツがどこから来たのかは知らない

自費出版の本をオンラインで買うというのは自分としても初めての体験で、このまま代金を持ち逃げされないだろうかと心配していたら、Amazonプライムもびっくりの早さで届いた

現在絶賛子育て中ということもあり、なかなか本を読む時間は取れないのだが、光の速さで本を送ってくれたトビーさんに対する感謝もあって、子守りの合間にポチポチと読み進めた


読み進めていく中で思い出したのが、昔好きで読んでいた沢木耕太郎の『深夜特急』

www.shinchosha.co.jp

全6巻でそこそこボリュームのある旅行記なのだが、一度読み始めるとあっという間にその世界に引き込まれてしまう

『深夜特急』がユーラシア大陸を西へ進んでいったのに対して、『New Driveway』ではアメリカ大陸を東から西へ横断する話である

場所と時代こそ違うものの、今回の『New Driveway』でも旅のリアルな感情描写が魅力的だった

これは個人的な見解なのだが、「旅」と「旅行」の違いは何かと言われればそれはリスクをはらんだ見通しのつかなさだと思う

開幕冒頭に書かれていたこのフレーズはまさにそれを端的に表している気がした

長期旅行の直前は期待や高揚感より、日本の夏を楽しみたい気持ちや防衛本能的な不安が混ざった感情になる

誰に言われたわけでもない、自分が決めたことなのに、なんかやりたくないような気がする

とはいえもうここまで来たら行くしかない、出たとこ勝負だ

冒頭のフレーズは自分が昔長期のバイク旅に出かける前に感じた気持ちを思い出させてくれるような気がする


リスクをはらむ分、旅に出たことで得られる予想外の出来事(プラスもマイナスも)は、日常では絶対に得られなかったものだ

旅に出たからといって何かが変わるわけではないけれど、それでもその体験は自分の人生を確実に豊かにしてくれる

自分はこれまで日常のトビーさんしか知らなかったが、会社で見かける日常のトビーさんの裏で、こんな冒険が繰り広げられてたのかということを知ると、なんとなく昔の思い出も変わった味になった気がした

Siriの便利さに気づいた

これまでいわゆる音声アシスタントというものを毛嫌いしてきた

Windowsを買ったらまずCortanaをオフにする

iPhoneを買ったらまずSiriをオフにする

変なところにお金をかけなくていいから、どうかそっとしておいてくれというのが自分、そして全人類の声だと思っていた

しかし子育てを始めてから事情が変わった

おむつ替え、ミルク、抱っこ、全て両手が塞がるものばかり

育休に入る前は、優雅に読書でもしながら子育てをする夢を描いていたが、そんな幻想は一瞬で消え去ってしまった

スマホすら操作できず、ピヨログの記録すら追いつかなくなる状況の中で、最近ふとSiriの存在を思い出した

設定からオフにしたSiriを再びオン

「Hey Siri、ピヨログでおしっこを記録して」

話しかけるだけで、うんちやおしっこの記録ができるようになった

特別なデバイスは何もいらない

感動した私は、それから狂ったようにSiriを使うようになった


ある時抱っこでの寝かしつけに成功して、暇だからポッドキャストでも聞こうと思ってSiriに話しかけた

「Hey Siri, ポッドキャストを再生して」

ところが声が大きかったのか「Hey, Siri」の声で赤ちゃんがびっくりして起きてしまった

本末転倒とはまさにこのことなり

育休を取ることにした

先月子供が生まれたので、今日から3ヶ月育休を取ることにした

blog.kromiii.info

育児は思ったより5倍ハードで、今ちょうど一ヶ月が経過したところだが、ちょっぴり疲弊しながらこの記事を書いている

何がハードなのかと言われるとなかなか言語化が難しい部分はあるのだが、自分の場合はまだ力の抜きどころがわかっていなくて、常に緊張状態になってしまうのが大変

慣れの問題だと思うので、これから少しずつ肩の力を抜いていきたい


よく子育ては自分の子供時代の追体験だと言われるが、まさにその通りだと思う

kangaeruhito.jp

この記事は村井理子さんという方のエッセイで、子供を見ながら自分の子供時代を思い出したエピソード

自分は思い出せる最古の記憶が小学校1年生くらいなので、育児をする中で自分の子供時代の記憶が蘇ってくるという体験ができるのは、残念ながらもう6〜7年後になりそうだが、そうでなくても0歳の子育てを通して、0歳の自分の姿に想いを馳せてみるのも悪くないと思う

前世の記憶があるという一部の人を除いて、多くの人は自分の子供時代を知らない

あるときふと気がついたら人生が始まっているというのは、知らない間に映画館に来ていて、目が覚めたら上映中の映画の途中だった、みたいな感じだろうか


今でもかろうじて覚えているのが1999年にスターウォーズのエピソード1が公開された時

スターウォーズシリーズは当時もうすでに不動の人気を獲得していて、当時は世界全体がお祭り騒ぎ

我が家でももれなくレンタルビデオ店から借りてきたVHSをセットして意味もわからず見ていた記憶がある(残念ながら2つとも死語になってしまった)

その後しばらくして、ある程度分別がつくようになってから、スターウォーズシリーズが実はエピソード4から始まっていたという事実を知って、てっきりエピソード1から始まったと思い込んでいたゆとり世代の僕は衝撃を受けた記憶がある

映画は最初から見るもの、途中から見るなんて言語道断と思い込んでいた自分は、このエピソード4から始まる奇妙な映画が世界中で大ヒットを記録したという事実が理解できなかった


とはいえ、よく考えると人生もエピソード1~3をすっ飛ばしていきなりエピソード4から見始めるようなもので、とりたてて騒ぎ立てるようなものではないのかもしれない

そう考えると育児というのはエピソード6からエピソード7へと進むのを止めて、エピソード1を見るような楽しさがある

もちろんこれは娘にとってのエピソード 1 であって、私にとってのエピソード 1 ではない

しかし子供の成長を見ることで、自分もこうだったんじゃないかとか、あのとき親はこう思っていたんじゃないかとか、現在まで続く物語の裏側を想像することができるのは楽しい

エピソード1の面白さを理解するには、1999年の自分には早すぎた

妻が妊娠中に作っていたアプリたち

妻が妊娠中に作っていたアプリたちをこの機会に紹介する(日本語の係り受けが複雑なので文脈から適切にパースしてもらえると)

pregnancy-meal-bot

聞き馴染みのない英単語だが、こういう感じのLINE Bot

食事の画像をアップロードすると、妊娠中に食べて良いものかどうかを判定してくれる

妊娠中の食事、結構トラップな組み合わせが多くてなかなか覚えるのが大変なのでこういうのがあったらどうだろうと思って作ってみた

蓋を開けてみると結局あまり使わなかったのだが、それはそれでよし

サーバーサイドはGASで動いていて、コードはこちらで公開中

github.com

LINE Botとして公開したかったが、医療・健康周りのサービスは色々と法律の規制が多そうなので断念

これまでGASは直接 Google App Script を書くことが多かったが、今回は clasp というパッケージを使って TS から生成する方針をとった

生成結果のデバッグがちょっと難しくなるのが難点だが、それ以外は使い慣れた言語でスムーズに開発できるのは良い

Baby Gender Reveal Generator

オンラインで Gender Reveal するためのサイト

Gender Revealとは、2000年代の米国で始まった胎児の性別を親しい人に知らせるイベント

本来はケーキや風船など趣向を凝らした演出でやるものらしいが、直接会えない人にも使えるようなアプリが欲しかった

ググれば出てきることは出てくるのだが、広告のついているものが多くてちょっと萎えていたところ、静的サイトでできるんだったら無料で広告なしで作れるじゃんと思って作ってみた

成果物はこちらで公開している

https://simple-gender-reveal.netlify.app/

使い方としては、まずは正解の性別をクリック、リンクが発行されるので、これをシェアすることで簡単に Gender Reveal を行うことができるという仕組み

https://simple-gender-reveal.netlify.app/reveal/omfegc9oc9q-enNmbWhiLWJveQ==

工夫したポイントとしてはURLから性別がわからないようにする部分で、単純な実装だとクエリパラメータで ?gender=male のようにしてパラメータを渡す感じになってしまうが、それだと本末転倒なので Base64 encode してなんとかした(目視でdecodeできる人には効果がないかもしれない)

サイトは bolt.new でAIにさっと作ってもらった

Netlifyと連携しているのでデプロイもほぼお任せでできたのは良かった

近況

えびさんのブログに触発されて、自分も近況を書いてみる

子供が生まれた

4月15日に子供が生まれた

自分にとっては大事件、とは言えなんとなく大々的に宣伝するのも憚られて、ひっそりとしずかなインターネットに当時の気持ちを書いてみた

sizu.me

しずかなインターネット、noteやはてなブログにはない独特の世界観があって、なんだかんだ離れられずにいる

博士フェスに出た

博士フェスというイベントに登壇した

博士フェスといっても、博士が集まってお祭りをするわけではなくて、社会人博士だったり博士卒就職の話だったり主にエンジニアのキャリアと博士号の話をするイベント

博士卒での就職については当時はかなり悩んだ思い出があるが、たまたま今読んでいた本やブログ記事が結構いいことを言っている気がして、その内容をベースに自分なりの考えをまとめてみた

speakerdeck.com

このあたりの考え方については、自分の中でまだ言語化できてない部分も結構あって、こういう機会をいただいたおかげで少しずつ棚卸しをさせてもらえるのがありがたい

iPhoneに変えた

スマホといえばAndroid、Android歴10年以上の自分だったが、今回の買い替えを機にiPhoneに機種変更してみた

正確には1日だけiPhone12を使ったことがあったのだが、重いのと操作性悪いので愛想を尽かして1日使って即メルカリに出してしまった前科がある

次乗り換えるならGalaxyかなぁと思っていたのだが、ミドルレンジのスマホでも10万円以上してしまうのを知って、それならiPhoneを試してみるかと思って乗り換えた次第

今回もやはりメルカリに出したい衝動を感じたものの、歳を重ねてある程度の忍耐力を身につけたのもあって、一ヶ月は粘ろうと思って使っている次第

機能面だけ見たらAndroidの方が良さそうな気もしつつ、今の日本人のネット環境はほぼほぼiPhoneで持っていると言ってもいい状況で、マジョリティの見ている世界を経験できるのは良い気がしている

魔の一ヶ月を乗り切って、なんとかiPhoneの操作スキルを身に付けたい

Anthropic Education Reportを読んでみた

昨日 Anthropic から Education Report なるものが公開されていたので解説してみる

技術系の人から見るとなんだそんなことかと思うかもしれないが、教育系の人から見ると結構面白い内容になっている

www.anthropic.com

レポートの新規性

序文に書かれているのは、このレポートのどこが面白いのかということ

we’ve conducted one of the first large-scale studies of real-world AI usage patterns in higher education, analyzing one million anonymized student conversations on Claude.ai.

結構強い文章だが、これまで教育研究が学生への聞き取り調査や統制された実験に頼っていたのに対して、Anthropic のレポートでは Claude.ai の実際の使用データを分析している点が新しい

この辺りはたしかに多くの教育研究者にとって耳が痛いポイントだろうと思う

というのも、大学の研究で対象とできるのはせいぜい多くても一つの学校単位のデータであり、それ以外の大規模データとなれば国の統計データに頼るしかないというのが現状で、それらのデータは Anthropic が所有しているデータ量と比べればはるかに少ないだろう

個人的には悔しさもあるが、今やこうした大規模なデータセットは国や大学ではなく企業が持っている現実があり、そうなると教育研究をリードする主体も徐々に変わっていくのかもしれない

ログの分析からわかったこと

Claude.ai には Clio というシステムがあり、これによりユーザーのプライバシーを守りながらログを収集することが可能らしい(自分は詳しい仕組みはまだキャッチアップしていない)

この Clio というシステムを使って収集された学生のアカデミックな活動に関連する 574,740 件の AI との会話を分析した結果、以下のようなことがわかった

学生が何に AI を使っているのか

最も頻度が高かったのが学習用のコンテンツの生成(39.3%)で、これには練習問題を作ったり、レポートの手直しを行ったり、教材の要約を作ったりすることが含まれる

次に多かったのが、課題に対する解説や答えを生成すること(33.5%)で、これにはいわゆるチーティング(不正行為)にあたるものも含まれる

この二つのカテゴリで全体の 72.8% を占めているが、内容を見るとたしかにそうだろうなと思うものが多い

第三位のデータ分析と可視化が 11.0%であることからも、学生が AI を使う目的は主に学習や課題のためであることがわかる

専攻分野ごとの AI 使用率の違い

専攻分野別に見ると、最も使用頻度が高かったのが Computer Science の学生で、これらの専攻分野の学生は米国全体だと 5.4%に過ぎないにも関わらず、Anthropic のデータでは 38.6%をこの専攻が占めていた

反対に、ビジネス、ヘルス、人文科学系の専攻の学生に関しては米国全体では 44.2%を占めるのに対して、Anthropic のデータでは 20.8%しかなかった

この結果が得られる仮説は以下の二つ

  1. 今の AI が得意な分野はコンピュータサイエンス系の分野であるため、学生もこの分野に集中している
  2. そもそもコンピュータサイエンス系の学生は AI を使うことに慣れているため、他の分野の学生よりも多く使っている

どちらもあり得そうな仮説で、Anthropic のレポートでも特にどちらかの仮説を支持するようなことは書かれていない

レポートには他にも専攻分野ごとの特徴的な使い方が書かれているので、興味のある方はぜひ読んでみてほしい

学生は AI に何を委任しているのか

「委任」というのは自分もあまり使わない単語ではあるのだが deligate をどう訳したらいいのか迷ったので使ってみた

ここでは教育心理学でよく使われる Bloom のタキソノミーを使って、学生が AI に何を委任しているのかを分析している

これによると、学生が AI に委任しているのは Bloom のタキソノミーでいうと「創造」と「分析」にあたる部分で、それらの土台となる「理解」や「記憶」に関してはあまり使われていないことがわかった

つまり現状 AI は高次の認知機能のサポートに使われているが、低次の認知機能のサポートにはあまり使われていないということだ

The fact that AI systems exhibit these skills does not preclude students from also engaging in the skills themselves—for example, co-creating a project together or using AI-generated code to analyze a dataset in another context—but it does point to the potential concerns of students outsourcing cognitive abilities to AI. There are legitimate worries that AI systems may provide a crutch for students, stifling the development of foundational skills needed to support higher-order thinking. An inverted pyramid, after all, can topple over.

この文章はなかなか考えさせられる内容で、AI に頼りすぎることで学生は基礎的なスキルが身につかないのではないかという懸念を示している

これを伝統的な教育研究者が言っているのであれば、なんだまだそんなこと言ってるのかと一蹴することもできそうだが、AI 開発の本家本元たる Anthropic が述べていることが意外だった

まとめ

Anthropic に Education Report なるものがあるとは知らなかったが、内容はなかなか面白いものだった

ちょうど最近も Anthropic が他社に先駆けて教育用途専用の AI を発表したとのニュースがあり、意外と教育分野に力を入れているのかもしれない

www.anthropic.com

この調査で使われている Clio についても時間があったら解説してみたいと思う

論文解説「MORF: A Post Mortem」

大学院で教育工学を専攻していた時の名残で、今でも Learning & Engineering というメーリングリストに登録しているのだが、先日コミュニティでこんな論文が話題になっていた。

https://dl.acm.org/doi/10.1145/3706468.3706478

タイトルは「MORF: A Post Mortem」。著者はペンシルベニア大学の Ryan Baker 氏と Denver 大学の Stephen Hutt 氏だ。自分の研究分野では有名な LAK(Learning Analytics and Knowledge)というカンファレンスで発表された論文。公開が 3 月 3 日と書いてあるからかなり最近の論文だ。

まず目を引くのはタイトルにつけられている "A Post Motem" というフレーズである。ポストモーテムといえば、何がしかのインシデント(トラブル)への検証や分析を指すが、自分が知る限りでは、あまり論文で好んで使われる単語ではないように思う。

というのも、あるプロジェクトのポストモーテムを書くということは、暗にそのプロジェクトが失敗だったと認めることになり、これは公的な資金を投入して行われた研究プロジェクトにとっては、あまり好ましいことではない。

なんでわざわざポストモーテムというタイトルとつけたのか気になって、自分の仕事とは関係ないのだがせっかくなのでちょっと読んでみることにした。

MORF とは

MORF とは The MOOC Replication Framework の略で、直訳すると MOOC のレプリケーションを行うためのフレームワークということになる。

MOOC のレプリケーションってなんぞやと思うかもしれないが、このフレームワークが生まれた背景には、Coursera や edX をはじめとする、大規模で無料のオンラインコース(Massive Open Online Course)が急速に普及し、多くのユーザーを獲得した経緯があった。

こうした大規模なオンラインコースには、多くの学習者によって蓄積された大量のデータがあり、これは学習者の行動や学習成果に関する貴重な情報源となる一方で、個人のプライバシーにも関わるセンシティブな情報である。

この問題を解決すべく生まれたのが MORF であり、要するに学習者のプライバシーを守ることを最優先におき、研究者が安全に大規模なデータセットを分析できるような MOOC のレプリカを提供するためのフレームワークということになる。

MORF の詳細については2018 年に発表された論文があるので、興味がある方はそちらを参照してほしい。GitHub に公式のレポジトリも公開されている。

github.com

なぜ失敗したのか

MORF の失敗要因はいくつか挙げられているが、自分が興味を持ったポイントについてかいつまんで説明してみる。

まずは Docker コンテナの問題。MORF はユーザーがどの言語を用いて分析しても問題ないように、ユーザーに自身の解析スクリプトを Docker コンテナとしてアップロードさせる仕組みを採用していたのだが、どうもこれが研究者にとっては技術的なハードルが高すぎたらしい。

これは自分も経験があるのだが、研究者の中にもいろいろなタイプがあり、Python や R で分析用の高度なスクリプトを書ける人が必ずしも Docker の基礎的な技術を身につけているかというとそうではない。特に Web 系の技術に疎い研究者にとっては Docker という言葉自体がなんなのかわからないという人も多い。そんな中で、分析用のスクリプトを Docker コンテナに詰め込むというのは MORF のユーザーである分析系の研究者にとってはかなりハードルが高い作業と言える。筆者らもこの点について、言語を問わないという意味で間口を広げたつもりが帰ってユーザーを限定する結果になってしまったと述べている。

次にデバッグと出力の問題。MORF では学習者のプライバシーを守るため、デバッグ用のエラーメッセージにも最小限の情報しか返さないようにしていたという。また分析結果についてもあらかじめ MORF 側で定義されたフォーマット以外の出力は表示されないようになっていたらしく、これも分析者の自由度を狭める結果となった。前者については上述した Docker の問題とも相まって、慣れない Docker を使うにあたってかなり MORF を使用するハードルを上げてしまっていたのではないかと思われる。

ポストモーテムの意義

このようにこの論文では MORF という分析フレームワークが広まらなかった要因として幾つかの課題が挙げられているが、そもそもなぜこのポストモーテムが必要だったのだろうか。

私はおそらく MORF のような課題は、教育工学分野の内外を問わず、多くの研究者が抱えている課題なのではないか、と思う。今回の件をより一般化していうと、フレームワークや研究の理念を優先させすぎると、ユーザー体験を損ない、結果として誰も使わないプロジェクトになってしまうということだ。

いくら崇高な理念に基づいたプロジェクトであっても、誰からも必要とされないものができてしまっては本末転倒である。

今回の論文でもネクストアクションとして、ユーザービリティテストの強化やコミュニティの育成が挙げられていた。プロジェクト(研究)の本質ではない部分で、よりユーザーに近いウェットな部分にも焦点を当てることが重要であるということだ。

近年プロダクト開発における PM (プロダクトマネージャー) という役割が注目されているが、技術や理念だけではない部分の重要性をこの論文からあらためて学べた気がする。

SlackのSocketモードに関する覚書

個人的に開発しているtbls-ask-agent-slackという Slackbot があるのだが、先日、退職された P さんという方からこんな質問が来た。

コード内に Signing Secret を使っている箇所がないが、リクエストの検証は正しく行われているのだろうか?という質問だった。

もう少し噛み砕い説明すると、例えばこのブログに書かれているように、Slack アプリはリクエストの検証のためにSlack Signing Secretを使うことが推奨されており、これがないと全世界からのリクエストを受け付ける状態になってしまい、あまりよろしくない。

最初にこの質問を受けたときは、なるほど、と思ったが、その後色々調べていくうちに、Socket モードを使っている場合はSlack Signing Secretが不要であることがわかったのでメモしておく。

Signing Secret の役割

まず最初に Slack Signing Secret の役割について整理しておく。主に前掲のブログの焼き増しになってしまうが、Slack Signing Secret の役割は HTTP リクエストの正当性を検証することである。

Slack からのリクエストには X-Slack-Request-TimestampX-Slack-Signature というパラメータがヘッダーに含まれており、Slack アプリ側は自身が持っているSigning Secretを使って、リクエストボディとタイムスタンプを使って生成されるハッシュがX-Slack-Signatureと一致するかどうかを検証することができる。

これの何が嬉しいかというと、同じハッシュキーを共有している Slack からのリクエストに対しては、同じ内容に対して同じキーを使ってハッシュを生成しているので必然的に一致する。一方で、自身が信頼していない送信元からのリクエストに対しては、同じ内容に対してハッシュ化を行っているが、ハッシュキーが異なるため、一致しない。

非常にシンプルな仕組みでありながら、ハッシュキーそのものは通信経路上に流れることはないため、安全にリクエストの検証を行うことができる。

Socket モードとは

そしてここから Socket モードの話に入ってくるのだが、大事な観点として、Slack の Socket モードは HTTP リクエストではないということを覚えておく必要がある。

先日 WebSocket の実装についての gurasan の資料がはてブで流れてきたが、まさにこれが今回の話ドンピシャの内容だった。

speakerdeck.com

Socket モードには HTTP リクエストと異なり、リクエスト・レスポンスという概念がない。つまり、通信の正当性はリクエストに対して行われるのではなく、接続そのものに対して行われることになる。

Socket モードでのリクエスト検証

前掲の資料にもあるとおり、Socketモードにおけるリクエスト検証は最初の接続確立時(ハンドシェイク)に行われる。ここで使われるのが Signing Secretと対になる概念であるSlack App Tokenである。

Slack アプリ側はこのSlack App Tokenを初回接続時のBearer Tokenに指定することで、Slack 側が正当なアプリであることを検証することができる(ref)。

つまり、HTTP リクエストでは Slack アプリ側がリクエストの検証をしていたのに対して、Socket モードを使ったアプリでは Slack 側がリクエストの検証を行うことで通信の正当性を担保しているということだ。

その後の対応

というわけで、最初にお伝えした通り、私が開発しているtbls-ask-agent-slack は Socket モードを使っているため、Slack Signing Secretは不要である。

とはいえたしかに何もドキュメントに書いていないのは不親切だなと思ったので、レポジトリの README にその旨を追記しておいた。

https://github.com/kromiii/tbls-ask-agent-slack/pull/79/files

というわけで、Socket モードを使っている場合はSlack Signing Secretは不要であることを覚えておこう。

気づきを与えてくれた P さんに感謝。