2023年のふりかえり

TL;DR 2023年に学んだ知識で2024年はマネーを獲得

2022年のふりかえり

laiso.hatenablog.com laiso.hatenablog.com

2023年にやったこと

After ChatGPT

Chat Completions APIのリリースを皮切りにプログラムからGPT-3,4の応答が呼び出せるようになったので「LLMアプリケーション」と呼ばれるようなジャンルにまでなり流行した

当サイトでも技術的な実験記事やら観念的な持論やら今年は色々書き散らした

まだハイプサイクルの峠をこえたんだかいないんだか明確でないので来年もしばらく続くんだろうと予測している

ChatGPTの使い方

「OpenAI Playgroundを使ってGPTを会話風テキスト生成ツールとして楽しむ 」は世間で流通しているプロンプトハックみたいなものに意味があるのか疑問があったので書いた laiso.hatenablog.com 「Bing AIチャットをデフォルトのウェブ検索にして使ってみた 」あたりの時期からはGoogle検索を使う機会がグッと減ったように思う laiso.hatenablog.com Bing AIチャットことMS Copilotは今はそんなに活用していないんだけど、膨大長文トークンページをMSの謎の技術力(Semantic Kernel?)で折り畳んで要約してくれるのPDF開いたりする時に補助的に使っている

「TwitterでフォローしていいかどうかもGPTに決めてもらう 」は実用しているわけではないけどTwitterを再開する動機になった laiso.hatenablog.com laiso.hatenablog.com 「英文を句構造文法に変換するやつ」「ChatGPTと英会話」はしばらくやってみたけどそんなに理解しやすいわけではなかった laiso.hatenablog.com laiso.hatenablog.com 「人類には早過ぎるLLMの話 」はサムアルトマン解任劇の最中に思想間対立に注目している人が少なかったので書いた laiso.hatenablog.com 自分はAI慎重派や効果的利他主義の考えに興味を持っていたところだったので、この解釈はすんなり受け入れられた

コーディング自動化

「GPTでソースコードからpatchを生成し続けたらプログラミングを自動化できるのでは???? 」や「GPT同士に対話をさせて自動でブログ記事を書くことができるのか?」は実際にできたし物凄い勢いでAPI課金されて後悔した laiso.hatenablog.com laiso.hatenablog.com コーディングは現在GitHubとVS Code周辺がどんどん発展していっているのあいつに任せてればよくない? と思いはじめている その一貫としてプログラムからローカルのCopilotに入出力できれば自動化できそうだなを思って内部プロトコルを調べた zenn.dev 「ライティングの哲学と未来のエディタの話 」では非コーディングな生産にもこれを拡大できるのでは、という展開をした laiso.hatenablog.com Code Interpreterが出た後はコード読解能力にも注目した、このUXは現在のCursorやGitHub Coplilot Chatに引き継がれている laiso.hatenablog.com laiso.hatenablog.com laiso.hatenablog.com

アプリケーション開発

今年の前半はLangChainLlamaIndexの実装を読みながらどんな風にGPTが活用できそうかなというのを考えていた

当初はJSONの応答をコントロールするのも以下のようにプロンプト側で工夫していた zenn.dev その後Function callingやJSON modeが追加され楽になった zenn.dev 開発をしていると、プロンプトAとプロンプトBのどちらが精度のよい結果が得られるのか? と思う場面が結構あって、そういう時モデル評価用のEvalsというツールが活用できた zenn.dev さらにそれを利用して巷で噂されているプロンプトハックみたいなものの検証もしていた zenn.dev 現在RAGと呼ばれている関連ドキュメントを埋め込み表現で類似検索してコンテキストとしてプロンプトに含めるやつも最初は試行錯誤で、とりあえずLangChainのnotebookが追加されたらみんなで試すみたいな雰囲気だった zenn.dev zenn.dev zenn.dev zenn.dev zenn.dev zenn.dev zenn.dev デプロイ先のVercelやCloudflare Workers上でチャットバックエンドのSSEなAPIを実装するノウハウがまだなかったので以下を書いた zenn.dev 今はVercel AI SDKがあるのでこっちになるべく寄せたい

4月になったらOpenAIからChatGPTに任意のツールを差し込めるようなプラグインの仕組みが公開されたので使い方を覚えた zenn.dev zenn.dev プラグインストアの今後はどうなるのか発表されていないが、ChatGPT上で対話したい時はActions in GPTsで自分のサイト上でヘッドレスに使いたい時はAssistants APIを利用する形になるのかなと思っている

「PaLM APIのファインチューニングではてな匿名ダイアリー風文章生成モデルを作る 」ではGoogle CloudのMLプラットフォームの使い方に詳しくなった laiso.hatenablog.com 後継モデルのGeminiはOpenAIのGPTモデルと価格競争力に優れそうなので出番があるかもしれない

Windowsマシンを用意したのも生成AIのモデルを動かすためにGoogle Colabの強いインスタンス借りるのはだるいな〜と思い自分のGPUが欲しくなったため laiso.hatenablog.com それまでは以下のようにSeamlessM4TやVOICEVOXの音声合成エンジンをColabを動かしてなんとかしていた zenn.dev zenn.dev 結局まだこのPCはそんなに活用していないんだけど久しぶりにWindowsの開発環境に触れているのが楽しい

クラウドプラットフォーム関連

サーバーレスとDB接続問題は今年は各種DBプロバイダーがホスティング側で解決しだしたのであまり気にする必要がなくなってきた zenn.dev とくにNeonがsocket接続を実行時にWebSocketに差し替えて解決していたのに感心した zenn.dev 現在はSocket APIさえ呼び出せばCloudflareがHTTPからTCPのレイヤーを維持して接続してくれる仕組みがあるのでより楽になりつつある zenn.dev 「サーバーレスをやめろ」に出てきたMRSKは現在はKamalという名前になって37signalsの本番環境で動いているらしい laiso.hatenablog.com Internet Computerは世間ではマイナーブロックチェーンの一種ぐらいにしか捉えられてないかもしれないが自分はアプリケーションをデプロイできるマイナーなプラットフォームとして強引に理解しているのでこの記事を書いた laiso.hatenablog.com 全く誰も興味なさそうだった

「AWS Lambda Go 1.x ランタイム終了を時系列理解 」はXのタイムラインで「Go言語オワタ」「サーバーレスの悲劇」みたいな反応をしている人たちがいたので、どゆこと? と思い調べた laiso.hatenablog.com こういう感じでSNSシェアで話題になっていることの確認をしにいくようなムーブが今年は多かった

「しずかなインターネットの技術スタックを調べる」や laiso.hatenablog.com

「デジタル庁でjQueryが何をしているのか 」もその1つ laiso.hatenablog.com これは中の人が「Drupalするならまず人脈・・」みたいな反応をしていたのがちょっと面白かった

SQLiteの本番サーバー活用の分野はLiteFSとD1が牽引していて、どちらもベンダーロックインがあるが、今年はD1がpublic betaになり、LiteFS Cloudというマネージドサービスが提供された zenn.dev どちらも無料からワンコインの予算感で運用できるようになっている

技術系の動画

今年は技術系の動画をよく見るようにした「React.js: The Documentary」や「TypeScript Origins: The Documentary」「Ruby on Rails: The Documentary」がおすすめOSSドキュメンタリー3点セットで感想記事を書いた laiso.hatenablog.com laiso.hatenablog.com laiso.hatenablog.com 他には「The shape of future builders: from design to deploy 」や「Video Editing in the Browser 」などのカンフェレンス系の動画も見ていた laiso.hatenablog.jp laiso.hatenablog.jp 記事にしていない範囲だとBunの作者インタビューが面白かった www.youtube.com 個人開発者としてゲームを作っているうちにツール作りがメインになってBunができたらしい

「光の速さが同じはずなのにbun installだけ何で早いの?」と疑問だったので詳しく調べた zenn.dev

フレームワーク関連

「Remove TypeScript」はある日いつものようにDHH周辺のXのタイムラインが荒れていて日常やね〜 とのほほんと眺めていたらいつも見かけないフロントエンド界隈のOSS有名人が沢山出てきて何事!? と思い動向を追っていた laiso.hatenablog.com 記事に書いたとうりこれはTurboの開発方針に関わる意思決定なので、言語論争だけしたい人が大量に流入してくるのに疑問を持っていたが、ある人がコメントで「DHHがブログで煽るからじゃない?」と言っててそれはそうと納得した

一方Turboのモバイルアプリ連携コンポーネントのStradaが正式にリリースされ、世間の話題にはなっていない zenn.dev Zenn全体でStradaの記事書いているのが自分だけという悲しい状況

「丁寧なDeno+JSX」ではサーバーサイドNext.jsは最適か? →MVCフレームワークに戻るか? →別の道も探すか? という今時の課題に自分なりの答えを出した laiso.hatenablog.com ここに書いてないことで特筆すべきこととしては最近はAstroのSRRも便利に使っている

「いまさら振り返るRxSwift」はXの弊タイムラインにいるiOS関係の人達がRxSwiftの学習コストについて議論していたので懐しくなって自分も振り返った laiso.hatenablog.com WebUIについては新しものが出てきたらとりあえずひとうり理解するルーチンの1ついう感じ laiso.hatenablog.com 「GPT-4の画像認識とPlaywrightでポケモン判定ツールを作る」ではGPT-4のAPIが未リリースだった頃に無理矢理使おうとして試行錯誤したもの https://zenn.dev/laiso/articles/fac48615b30046 GPTよいうよりむしろPlaywrightとChromiumの接続仕様の勉強になった

AWSコスト最適化大作戦

2023年の円安ドル高の市況でどこの企業も似たようなことをやっていそうだけど、自分もAWSインフラのランニングコストを削減するための作業を片手間にやっていた

そんなに特別なことはやっていなくてSpot InstanceやReseverved Instance、Saving Planを活用、余剰リソースを整理してアプリケーションも書き換えインスタンスの単価を減らす、というようなコスト最適化をするのに当たり前なことを作業の優先順位の一番上に持ってきた

これには「AWSコスト最適化ガイドブック」「Amazon Web Services コスト最適化入門 (技術の泉シリーズ(NextPublishing))」を参考にした

オライリー本

自分は県内一のオライリー本廃課金勢だと思っているんだけど、アカウンティング関連の整理していたら現在はPayPalが使えなくなっていて、オライリージャオパンや技術評論社のDRMフリーの電子書籍が買えなくなって困っていたので以下の記事を投稿した laiso.hatenablog.com その後Online Learning with O'Reillyのサブスクを契約して対応している本は読んでいたりした laiso.hatenablog.com さらに10月になるとクレジットカードでの決済に対応するアップデートが来ていたのでありがたく使わせてもらっている laiso.hatenablog.com Online Learning with O'Reillyの方のサブスクはこれはこれで色んな洋書を読めて便利だったので年間契約に移行した

メインエディタをVSCodeに乗り換えた

2023年のVS Code x GitHub Copilot関連の圧倒的進化速度を目の前にしてこれは第一エディタにしとかないと色んな機能がキャッチアップできないなと感じたのでJetBrains系から乗り換えた

ただしPHPのコーディング環境はPhpStormの方が快適なので、Laravel系の開発をする時だけ使っている

しかしXcodeでSwiftを書いている純iOSエンジニアたちは、サードパーティプラグインがあるとはいえ、このままVS Code x GitHub Copilot並の開発者体験に合流することはないんだろうか、というのがちょっと気になっている

(またはそれは自分の過小評価でXcode単体で充分足りる?)

AndroidからiPhone 15 Proに乗り換えた

XiaomiのAndroid端末を2年ほど使っていたので、2年ごとにiPhoneとAndroid端末を乗り換えるルールにしたがってiPhone 15 Proに乗り換えた laiso.hatenablog.com いっちょWear OSアプリ開発をはじめるかと購入したGalaxy Watch5がiOSとペアリングできなくてモチベーション下った laiso.hatenablog.com

OSSへの寄付

aquaskkに加えて、ずんだもんボイスでお馴染のVOICEVOXへの寄付をはじめた。

VOICEVOXは経済的価値を生み出している割に明かに資金流入の足りてないプロジェクトであるのでもっと支援者が増えてほしい hiho.fanbox.cc

2023年にやりたかったこと

去年に「GoやGraphQLやモバイルアプリ開発を勉強しとかな」と書いたけど、その時間を全部ChatGPT関連に流した感じ

これについては「次の技術選定で無理矢理ねじ込む」とか「案件を獲得して実践する」などでコミットメントを達成しようという気はなくて、自分の正確では「やらなかったということは必要なことではなかった」と結論付けることになった

一方「AI系の何かをやりたい」という目標はたぶん満たされており、「大規模フロントエンド開発の経験」は行動したいがうまくいかない、ぐらいの塩梅にあるのでストレッチゴールとしては丁度よかったのではないか

ということで次の目標を立てることにします

2024年にやりたいこと

LLMを活用したアプリケーションを開発する

せっかく2023年にいろいろキャッチアップして今までなかった知恵がついたので、これを使って個人でアプリケーションを作って公開したい

今のところ文章執筆や構成を自動化するアウトラインプロセッサーと作りたいと思っているけどマイナージャンルなので、それよりよいアイデアがあったらそっちに切り換えるかもしれない

技術書を書く

オライリーのサブスクでブラウザで本を読んでいるうちに「あれこれってブログでは?」という気分になってきて、技術書がブログみたいなもんなら自分にも書けるかもと思えてきた

今まで技術書というのは長い長い長期プロジェクトをひらすら続けないといけない上に書いたものを公開できないイメージだったのだけど、オライリーのEAP版とかPEAKSのような先に売る形態もあるし、コンテンツをWebに置いて販売も自分でするという方法でなんとか達成できないかと考えている

先のLLMを使った自動化はライターやエディター個人の能力を拡大するものだと思っているので、アウトラインプロセッサーを作るという目標ともリンクしている

とりあえず士気が上ってちゃんとした文章書くぞという気になり「理工系のためのよい文章の書き方」や「数学文章作法」を先日読んでいた

ニュースレターを配信する

ジャンルは全然決めていないんだけど読者を募って定期的にメール配信するようなコンテンツを作りたい

これにはsubstack.comやnote.comなどの色んなプラットフォームがあるんだけど、自分はGitHub Sponsorsの機能を使って運用したい

スポンサー募集ページは以下に作ったんですけど、今後コンテンツを発信していく際に宣伝しようと思うのでよかったら参加してください

github.com

動画を作る

VOICEVOXを触っていたことと関連するんですけど、スクリーンキャストや技術解説の動画を作ってみたい

これは技術書で書くような内容をさらにマスな層に届けるために必要なことだと思っていて、尊敬するプログラマーであるDHHやKent C. Doddsはよく考えたら動画活動を熱心にやっているのでどこにそんなモチベーションが? というのを昔から気になっていた

とくにKent C. DoddsはRemixを離れプログラマー界のバズレシピみたいなチームを自分たちで作り高額動画教材(現為替レートで17万円)を売っているので、どういう動機でこの活動をしているのか気になっている

事業を作る

今まであげた「アプリ開発」「技術書」「ニュースレター」「動画」すべてにつながることであるんだけど、それらを金銭の発生する事業に発展させないと深い取り組みにならないなと思っている

「新技術を覚えるために副業で請け負い開発をする」などを近い動機かもしれない

それはそれで責任を伴うからプライベートでやるには重いことなのかもしれないが、今まであまり意識したことがなかったのでやっていきたい

2023年に読んだ漫画やゲーム

漫画

今年読んだ中でおすすめなのはドラマ化もした「トリリオンゲーム」という作品

日本のスタートアップやベンチャー業界のマネーゲームをモチーフに

プログラマーの主人公がハスラーな友達と起業して振り回されつつ要所ではハッカーとして覚醒して1兆企業目指すぞ的な漫画

池上遼一の劇画調で新興ビジネスを描いてるギャップ効果で面白くなっている気がする

元ネタがはっきり分かるぐらい、あからさまな業界あるあるが出てきて、ストーリー上のどんでん返しの為に無茶をしていて、時々「犯罪では?」とツッコみをうけている

あとはポットキャストで紹介されていたやつをそのまま購入する機会が多い

Middle Aged Developersポットキャストで紹介されていた「ひゃくえむ。」を読んだ

この作品は「ピンポン」のような才能と能力の関係をうまくドラマにしていて、プログラマーの世界も他人の才能や能力を否が応にも実感させられる環境なので楽しく読んだ

他にはマンガのラジオから「これ描いて死ね

中田オススメの今面白い漫画から「王様ランキング

読書の秋!マンガの秋!プレゼンするぞ!から「妻と僕の小規模な育児」「住みにごり」を読んだ

妻と僕の—— の福満しげゆきはガロ系の作家で、漫画家が漫画の中で漫画を描くエッセイ漫画みたいなものを大量に描いてる

作品はどれも<ドジっ子>特有のあるあるみたいなものが大量に描かれていて好みだったので「僕の小規模な失敗」「僕の小規模な生活」「生活」の過去作も購入した

「住みにごり」は家族愛の問題を青年誌っぽい暗めのトークンで描いた作品で、ミステリー要素はありつつも基本的にキャラクター造形で楽しむものっぽい

同じく家族愛がテーマの「一ノ瀬家の大罪」は「タコピーの原罪」の作者の新作で、だいたいいつもタイムリープしてる。絵柄は全然違うけど「住みにごり」似たような印象を持っている。

あとは「前科者」「天国大魔境」「ちいかわ」、アンチマン著者の「メイコの遊び場」などを読んだ

ゲーム

おすすめはパラノマサイトというゲームで以下に感想を書いた

laiso.hatenablog.jp

あとは「超探偵事件簿 レインコード」「ANONYMOUS;CODE」「WILL: A Wonderful World」などのノベル系のゲームが最近は多い

今は「ナツノカナタ」と「メグとばけもの」をやってる

スト6

9月頃に自作PCをわざわざ新規構築して「ストリートファイター6」を買った

laiso.hatenablog.com

アケコンがないのでキーボードでストレスフルにやってるけど地域的にマッチング人口が少ないので快適ではない

そう考えるとUAEやシンガポールのプロゲーマーとかすごい

スイカ

最近はスイカゲームを毎日やってる

スコア3000点を突破してダブルスイカを目指してる

store-jp.nintendo.com

PS: この記事は書影の表示のためにAmazon.co.jpの商品埋め込みリンクを利用しています。2023年の当サイトのアフィリエイト報酬は¥852でした

WebUIについて調べた

WebUIはデスクトップアプリを作るためのライブラリ。HTML, CSS, JavaScriptでフロントエンドを作り、バックエンドをC, C++, Python, Go, TypeScriptなどの言語で開発できる。システムにインストールされているWebブラウザで動作する

https://webui.me/webui.me

2023年にhassandragaさんが公開し、V言語コミッタのttytmさんらも参加した

本体はCで開発されていて、Python, Go, TypeScriptにバイディングが提供されている

似た技術としてはElectronやTauri、Gluonなどが存在する

laiso.hatenablog.com

zenn.dev

アーキテクチャについて

ElectronやTauriと比較すると、WebUIのアーキテクチャはWebアプリをブラウザで開くだけなのでより単純かつ制約が大きい

開発者にとってはブラウザを使ってプログラムにGUIを付けられるライブラリであり

ユーザーにはChromeのdesktop shortcutsのようにスタンドアロンなウィンドウで起動するWebアプリになる

他のフレームワークとの簡単な比較図を作った

Presentation Main Program Bridge
Electron Chromium Node.js IPC
Tauri WebView Rust IPC(JSON-RPC)
WebUI Web Browser C and bindings HTTP(WebSocket)

WebUIでデスクトップアプリを起動する時のフローが以下になっている

  1. Pythonなどで記述したMainプログラム(hello_world.py)を実行
  2. WebUIがシステムにインストールされているウェブブラウザを呼び出す
  3. 専用のプロファイルでMainプログラムが実行するhttp://localhost:53949を開いてデスクトップアプリっぽく見せる
git clone https://github.com/webui-dev/python-webui
cd python-webui/examples
pip install webui2
python hello_world.py
MyWindow = webui.window()
MyWindow.show(login_html) # 描画するHTMLのテキスト

このデスクトップアプリのシステムWindowは「Google Chrome」になっていて以下のプロセスで実行されている

ps x | grep .WebUI

/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --user-data-dir=/Users/laiso/.WebUI/WebUIChromeProfile --no-first-run --no-proxy-server --safe-mode --disable-extensions --disable-background-mode --disable-plugins --disable-plugins-discovery --disable-translate --disable-features=Translate --bwsi --disable-sync --disable-sync-preferences --disable-component-update --allow-insecure-localhost --app=http://localhost:53949

Mainプログラムとブラウザのブリッジ連携

Mainプログラム側からブラウザの値を参照するにはJavaScriptコードを送る

res = e.window.script("return document.getElementById(\"MyInput\").value;")
if res.data == "123456":
    print("Password is correct.") 

逆にブラウザ側からMainプログラムの関数を呼び出す時はwindows.webuiオブジェクト経由でバインドしておく

def check_the_password(e : webui.event):
    #...

MyWindow.bind('CheckPassword', check_the_password)
<button onclick="webui.CheckPassword()">Check Password</button>

もしくはHTMLのid要素に暗黙的にバインドされている

<button id="CheckPassword">Check Password</button>

これを使うためにHTML側には <script src="webui.js"></script> のおまじないが入ってないといけない

この中身がwebui /bridge/で、TypeScriptで書いたWebSocketクライアントをさらにCのヘッダにhexにして埋め込んでいる

埋め込んだ文字列をローカルサーバーの /webui.js として返している

なんでそんなことを…… と最初思ったが、バイナリに埋め込み静的ライブラリとして配布するため?

その他の特性

  • あくまでライブラリでデスクトップアプリを配布用にパッケージングする仕組みなどはない
    • 例えばMainプログラムの実行にPythonが必要なら利用する環境にもインタプリタがないといけない
  • ブラウザの中で動いているローカルなWebアプリなので、その外側のOSの機能(システムメニューなど)まではアクセスできない

ドキュメントは https://webui.me/docs/

Disclaimer

この記事はWebUIのコア実装の理解に焦点を置いています。ElectronやTauriと比較し、WebUIの利用を薦めるものではありません

筆者はデスクトップアプリの開発にはプラットフォームの標準SDKを使います

デジタル庁でjQueryが何をしているのか

TL;DR: jQueryはDrupalのバーター

リニューアルするたびにWeb界隈の一斉レビューを受けることでお馴染のデジタル庁ポータルサイトがいつの間にかまたリニューアルされていて、フロントエンドがNext.jsからDrupalに変わって話題になっていたので1、私も旅券所持者として国政に関心を持ってゆく

また、まわりのフロントエンドエンジニアの間でjQuery氏の入庁について「モダンブラウザ全盛の時代に必要か?」と疑念がとなえられていたので、これも追求してゆきたい

どのような変更があったのか

システム変更の経緯はプロジェクトの関係者であるHal Sekiさんの発言が正確なところだと思う

私が理解した内容を勝手に作図してみたのが以下、脱Jamstackされた

JAMStack

Drupla

AstroやGatbsyなどのStatic Site Generator(SSG)を主軸にしたフレームワークと違い、Next.jsはインクリメンタルなビルドやサイトへのアップロードにフォーカスした機能をそなえていないので、ページ数が多くなるとビルド時間が長くなるというのは理解できる

SSGとSSRの併用・動的な切り換えを含め実現できるようNext.jsのサーバーを追加で立ち上げるって手もあるが「プレビュー機能や予約投稿など、元々CMSに備わっている機能も活用できない」とあるので、既に運用しているDrupal側に寄せたのだと思う

いつ変更されたのか

CrUX サイトスピード簡単比較(このサイトすごい)によると10月〜11月にかけて「OnLoad (リソース総読み込み時間)」が増加しているので、それを参考にWayback Machineを辿っていく

Drupal判定はページのJavaScriptに特定のオブジェクトが存在するかどうかで行われているのが独自研究で分っていたので2手がかりにした

その結果11月に新アーキテクチャになったというわけではなく、既に10月にはDrupalに移行済みだった

さらに遡って二分探索で時期を特定したところ、最終的には9月初旬に該当の変更があったことが分かった

ただ発表は11月にあったようだ

それ以前の6月にデジタル庁は新トップページの試行版を/experimental/で公開していた(現在はアクセスできない)

この更新はCSS ModulesからTailwindCSSベースに移行する意図だと思われる

<!-- 20230629060923/ -->
<section class="attention">
    <h2 class="attention__title">重要なお知らせ</h2>
    <ul class="attention__list">
        <li class="attention__item">
        </li>
    </ul>
</section>

<!-- 20230629060923/experimental -->
<section class="flex flex-col gap-12">
    <header class="flex items-center gap-4">
        <h2 class="text-pc-xl">重要なお知らせ</h2>
    </header>
</section>

この時点ではフロントエンドはNext.jsで生成された静的サイトのまま。この試行版の結果を踏まえて今回の変更に至ったのではないか

jQueryをどう使っているのか

jQueryの使用目的を調べるために、まず現在の最新サイトがどのようなJavaScriptを読み込んでいるのかを確認する

必要な個所だけを抜粋すると以下2つのJavaScriptファイルが読み込まれている

<script src="/assets/contents/js/js_ClXDO7hKtoW-lPIxg2611itLMSFuyA_7QOQFpHSZnkc.js"></script>
<script src="/assets/contents/js/js_sLGkDuawXY9ceUV6gA6ioeCD4o_nT-dduyMlEtshv-8.js"></script>

中身を読むと、それぞれ「開発者自身が記述したJavaScript」と「サードパーティのJavaScriptをバンドルしたファイル」という一般的なビルド結果ということが分かる

「サードパーティのJavaScript」ではjQuery v3系とDrupal JavaScript APIのコードが存在する

Drupal JavaScript APIが何かというと、Drupalの生成するページに対して追加の処理を実行するためのAPIである

https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview

「開発者自身が記述したJavaScript」のファイル側でスクロールの挙動をカスタマイズしている

/**
 * Scroll processing
 */
const viewScroller = () => {
  // If the URL has an anchor
  if (window.location.hash) {
    // Processing at "Back" screen transition
    // eslint-disable-next-line no-unused-vars
    window.addEventListener("popstate", (e) => {
      scrollToForFloatHeader(window.location.hash, 10);
    });
    scrollToForFloatHeader(window.location.hash, 300);
  }
};

Drupal.behaviors.viewer = {
  // eslint-disable-next-line object-shorthand, no-unused-vars
  attach: function (context) {
    viewScroller();
  },
};

他に得られた知識としては

  • コメントが英語
  • eslintが導入されている
  • jQueryがスコープに宣言だけされてAPIが使われていない(!)

ということが分った

「jQueryのAPIを直接使っていない」という事実が今回の記事の重要な点で、このサイトのフロントエンドはVanilla JavaScriptでなるべく実装されていることが読み取れる

DrupalのドキュメントにはJavaScript APIを利用するためにはjQueryをロードせよという記述がある

Note: Since Drupal uses jQuery.noConflict() and only loads JavaScript files when required, to use jQuery and the $ shortcode for jQuery you must include jQuery and Drupal as dependencies in the library definition in your MODULE.libraries.yml and add a wrapper around your function. https://www.drupal.org/docs/drupal-apis/javascript-api/javascript-api-overview

なのでjQueryの読み込みはDrupal JavaScript APIを使う上では必須なのだろう

jQueryの読み込みはしているということは前述の計測データの「OnLoad (リソース総読み込み時間)」が増加とつながる

追記: DrupalコアとjQueryの関係

この記事が多くの人に読まれたことで識者の人に追加情報をもらったので追記します

まず現在のDrupalを使うのにjQueryを依存に追加するのは必須ではないようだった

状況としてはこのサイトが「jQueryが必要なテーマやモジュールを使っている」という可能性がある

ただそれがどこで使われているのか、閲覧者側に見える個所なのか管理側なのかは分からなかった

サイト内検索にMARS FINDERが使われていることは通信内容から分かり、このモジュールはjQuery v2を独自に読み込んでいるが……

一方、[meta] Replace JQuery with vanilla Javascript in core [#3052002] | Drupal.org のチケットではcoreからjQueryを削除しようという議論が行なわれておりそれはまだ進行中のように見えるのでサイト管理者が作成するコンテンツ以外のinternalな場所で使われているのかもしれない

コメントくれたprogratiさん、uhyoさん、tom_k_enさんに感謝


以下言いたいことだけを言うコーナー

「jQueryを新規で使っちゃだめなの?」

  • 最新のjQueryそのものを使うことについてはさしたる問題はない。
  • 問題はjQueryをベースに作成されたライブラリがアクティブなのかという点にある。
  • サポートされなくなったバージョンや更新されなくなったライブラリを使うことが安全ではない、というのが一般的な答えかと思う
  • jQueryの機能は現在のブラウザが標準装備している(それがライブラリが維持されない理由でもある)のでそれを読み込まないだけでUXに関連する数値が改善できる。「その高速化は本質的ではない」「統計によると何msで売上がN上がる」などの言い分があるものの、あとは各人のUX改善にどういう視点で向き合うかという価値観の問題になる
  • また「非宣言的UIで複雑なGUIは作れない・パフォーマンスに欠点がある」という意見を持つ人もいると思う。私はその部分には持論はない
  • 何がjQueryを負債たらしめているのかを考察する | yamanoku Advent Calendar 2023

「やはり最新技術より枯れた技術で労働者確保」

  • 今回の更新のコンテキストとは関係なさそう
  • 自分は当事者としてそのプロジェクトにいる時にしかその手のことを気にしない
  • デジタル庁サイトの上流は業界内のハイクラス人材ばかりなので何使っても何とかなるのではないか(してください)

「最初からNext.jsやJamstack不要だったのでは?」

  • 静的コンテンツをCDNに乗せ配信するという現在のアーキテクチャだけ見ればそうだけど、NextのDraft ModeやVercelのWorkflowなどCMS向けの機能もあるしNext側に寄せる選択肢もあったからではないか
  • Vercelの人は梯子を外されてしまったけど笑

ライティングの哲学と未来のエディタの話

『ライティングの哲学 書けない悩みのための執筆論』を読んだ。

本書はWorkflowyを使いこなしている文筆家をTwitterで募ってそれぞれの活用法を紹介する座談会を4名で開催したら、文章執筆についての精神性の話題がメインになってしまい、それはそうと3年後に参加者に実際に原稿書かせてみて再度Zoomで座談会して1冊の本にしてみた。という変わった企画だった。

あとがき、が一番この本全体で起っていることを体裁立てて書いてあるので先に読むと分かりやすい。

僕は各人の著書をあまり読み込んだことがないので、実際の執筆の変化は分からないのですけど、3年後座談会では概ねみんな「雑に書いて世に生み出せた時点でえらい」というような方向性でまとまっており、自分と同意見だなと関心した(理科系の作文技術とちょうど対極みたいな)

sizu.me

アウトライナーの未来

ここからは一旦ライティングの哲学の部分の話題は忘れて、この本を読んだきっかけである文章執筆ツール系の話になります。

僕はプログラミングのコーディングとこういう文筆業のライティングを似たようなものとして捉えており、それは文系プログラマーの局地のような考えだと思うのだけど、2つを統合したような性質を持つ技術ブログというものをアウトライナーを使って10年以上書いてきた経験から「もっとツール側で問題を解決できるのではないか」と思うことが多い。

本書は座談会参加者がWorkflowyユーザーということもあって、エディタやアウトライナーなどの文章執筆ツールについても言及が多い。

各人ともWorkflowyで小説や実用書などのすべての執筆活動を行うわけではなく、スマホからメモを取る、とかエディタAにしたりBにしたりどんどん変える、などの行動を短い期間内で試行錯誤していた*1

これはこのトライアンドエラーも含めて執筆活動ということだと思うのだけど、「TODOアプリはラーメン屋」で書いたような人間の知的生産活動を現状のツールで受け持つのがそもそも難しいんじゃないかという点を思い出させる。

sizu.me

それでアウトライナーの話なんですけど、僕はこのエディタAにしたりBにしたりの過程に「プログラムでの自動化処理」もできると思っていて、そこに大規模言語モデルさんのパワーが使えるのではないかと考えている。

sizu.me

参加者の一人である読書猿さんにもそういう発言が多い。

一方で、ぼくが書く本を自分の代わりに書いてくれるプログラムをつくれないかなという思いもずっとあります。ぼくの書いている本の中身は既存のものなんです。タイトルとかコンセプトとか構成のアイデアは自分の頭から出たものですけれど、そうしてつくった枠組みに充塡するために中身を世界のどこかから取ってきている。だったらそのルールをプログラムの形で記述して、コンピュータが世界中の知識を巡って知識を拾って勝手に埋めてくれないものかなと 千葉雅也,山内朋樹,読書猿,瀬下翔太. ライティングの哲学 書けない悩みのための執筆論 (Japanese Edition) (p. 213). Kindle Edition.

OpenAI APIを裏で呼び出すWebのアウトライナーでもマシン上でモデルの推論を実行するデスクトップアプリでも、VS Code上の拡張で実現するでもどんな方法でもいいんですけど、システムに日本語入力システムがあるのと同じレベルで言語生成・編集機能が付いてる、っていうものを未来のライティング環境として想像している。

なので、階層のリストを要約して自動で親項目を挿入したり、箇条書きリストを自然言語で分類し直したり、マクドナルド理論よろしく*2 各項目を置き換え前提のテキスト補完を入れてしまう—— とか、今ある技術だけで何とかなりそうなのでプロトタイピングをしている。

『ライティングの哲学 書けない悩みのための執筆論』発刊の2021年時点ではChatGPTブームは来てないのでアップデートするような企画があったら面白そうだ。これだけツールを使いこなしている人達なら色々試しているはずなので

*1:この時点では本の原稿は最終的にScrivener に保存しておくのがトレンドのようだった

*2:https://gigazine.net/news/20130502-mcdonalds-theory/

Copilot ChatのAgents機能がすごそう

GitHub Copilot ChatのアップデートでAgentsという機能が追加されて@workspaceをつけて質問することでエディタのコンテキスト外のファイルも対象に回答してくれるようになった。

code.visualstudio.com

「プログラマー失業不可避」が噂されるCopilot Workspace*1とは別の機能なので注意。

以下Microsoft Copilotに翻訳してもらった要点:

LLMは、ある時点での公開リポジトリのデータで訓練されています。つまり、現在のコードについては何も知りません。コードについては一般的なことは知っていますが、ワークスペースの内容に関する必要な文脈を持っていないので、それに関する質問に正確に答えたり、ワークスペースの形式や機能に従った新しいコードを提案したりすることができません。

これを回避するために、GitHub Copilot Chatは、モデルがよりよく質問に答えられるようにするためのコードの断片を送ります(これを「Retrieval Augmented Generation」または「RAG」と呼びます)。1回答は、関連性の高いコードを見ることでよくなります。しかし、LLMに送ることができるコードの量(およびプロンプトによるガイダンス)には限りがあります。小さなプロジェクトであれば、これは通常問題になりません。しかし、大きなソースコードリポジトリを考えてみると、すべてのファイルの内容をモデルに送ることは不可能であることがすぐにわかります。よりよい回答を得るための解決策は、適切な量のリソースを合理的な時間内に使って、関連する文脈を送ることです。これを実現し、さらに多くのシナリオを解放するために、私たちはCopilot Chatにエージェントという概念を追加しました。

つまりCursorがやっていてくれたような機能がオフィシャルでサポートされている(さよならCursor)

laiso.hatenablog.com

VikParuchuri/markerを一緒に読んでみたところなかなか有能だった。

このリポジトリはPythonだが、ただCopilot Chat自体得意言語の差があるという説もある。

Agentsとは

@workspaceの@指示子を提供するパーツがAgentsという仕組みで、なんとこれはユーザーも追加することができるらしい。

Copilot Chatのコンテキストを拡張して任意のコードを実行でき、VS Code側で用意されたAPIを使うことができる。

全体の構造:

VS Code
├── GitHub Copilot Extension
├── GitHub Copilot Chat Extension
│   ├── Agents
│   │   ├── @workspace
│   │   ├── @vscode
│   │   ├── @cat
│   │   ├── @dall-e

実際に動作可能なAgentとして@cat@dall-eのサンプルにアクセスできる。

実装は以下の個所でここを書き換えることで独自のAgentを開発できる。

vscode-extension-samples/chat-agent-sample/src/extension.ts

@dall-eとかはこの中でAzure OpenAIのAPI叩いて画像生成してた。

Chat Completion APIを使ってる人ならお馴染みのI/Fで、以下のようにCopilotの内部のモデルへの問い合わせができる。

const access = await vscode.chat.requestChatAccess('copilot');
const topics = ['linked list', 'recursion', 'stack', 'queue', 'pointers'];
const topic = topics[Math.floor(Math.random() * topics.length)];
const messages = [
    {
        role: vscode.ChatMessageRole.System,
        content: 'You are a cat! Your job is to explain computer science concepts in the funny manner of a cat. Always start your response by stating what concept you are explaining.'
    },
    {
        role: vscode.ChatMessageRole.User,
        content: topic
    },
];
const chatRequest = access.makeRequest(messages, {}, token);
for await (const fragment of chatRequest.response) {
    progress.report({ content: fragment });
}
return { slashCommand: 'teach' };

まとめ

つまりAgentsを通じてエディタの中で自然言語とソースコードの組合せから情報を取り出したり、コードを更新したり実行したりするのがより柔軟になるので色々活用の幅が広がりそう。

Copilot Chatは最近GPT-4ベースになったので*2「以前使ってみたけど精度がいまいちだったな〜」という人も再度チェックしてみてください。

「しずかなインターネット」の技術スタックを調べる

追記

作者のcatnose99さんがより詳細を解説してくださいました

zenn.dev

/追記

ポエム特化のZenn2との噂の「しずかなインターネット」を使いはじめたので、ユーザーとしてどんな技術が使われているのかを確認していく。

sizu.me

おもむろにbuiltwith.comにかけてみる。

builtwith.com

ここで分かる情報はブラウザのDevTools眺めてても得られるのであまり収穫はない。

  1. 前段にCloudflareのCDNサーバーがいて
  2. Next.jsで生成されたレスポンスを返している

ことがわかる。

この時点ではキャッシュのみCloudflareなのか、Pages/WorkersでNext.jsのSSRごと動かしているのかは判断できない。

認証

Set-Cookie: __Secure-next-auth.session-token=が含まれているのでNextAuth.jsを使っているのが分かる。

next-auth.js.org

Emailでサインアップするとhttps://sizu.me/enter/callback/firebase-action?apiKey=...というリンクを送ってくるのでFirebase Authenticationでユーザーが管理されているのも分かる。

firebase.google.com

ストレージ(R2)

画像をアップロードすると r2.sizu.meというホストのURLが割り当てられ、Cloudflare R2が利用されているのが分かる。

developers.cloudflare.com

フロントエンドサーバー(Cloudflare)

/api/..以下がCloudflareを指すので完全に静的なexportサイトではないことが分かる。

ただ/dashboard以下のページは__NEXT_DATA__.nextExport=trueになっているのでSSGな部分とCSRな部分が混在している。

共通UIが静的でログインユーザーの情報は/api/..から取得しているのだと思う。

コンテンツキャッシュ(Cloudflare)

投稿の詳細ページは本文を含む完全なHTMLを返してきて__NEXT_DATA__.gssp=trueになるのでSSRなことが分かる。

ブラウザのナビゲーションで同じページを開くと/api/trpc/postDetail.getからコンテンツは取得される。

同じページをナビゲーションで2回開くとAPIにアクセスは発生しないのでクライアントサイドのキャッシュもあることが分かる。

バックエンドサーバー(Google Cloud)

ここから先はアプリケーションを調べても分からないし、人海戦術で作者のcatnoseさんの発言内容をチェックする(そもそも聞いたら教えてくれると思う *1 )

以下のポストはしずかなインターネット開発中のものと思われる

これによるとCloudflare Pages/WorkersでDB接続まではしていなさそうで、コアサーバーはCloud Runの方にありそう。

その場合、バックグラウンドジョブなどの実行もCloud Runベースになるだろう。

DBやRedisはそのままPlanetScaleとUpstashなのかもしれないが、定かではない。

APIサーバー(tRPC)

設定 https://sizu.me/dashboard/settingsから更新すると/api/trpc/user.updateに対してPOSTリクエストが送信される。

命名からしてtRPCが使われていそう。

trpc.io

API Routesの下でBFFとなるエンドポイントがあって、trpcサーバーのモジュールを通して、Cloud Runにあるバックエンドのサーバーと通信している?

追記

BFF→Cloud Runの二段階アーキテクチャではなしに、trpcサーバーからDBに接続する層もCloud Runで動作しているらしい。

まとめ

プレゼンテーション層とデータ層を処理するフルスタックなNext.jsアプリケーションがCloud Runで動いていて、Cloud Runの制約上発生するレイテンシをなくすためにその前段にCloudflare Workersでプロキシしているというアーキテクチャだということが分かった。

初期ZennがVercelとApp EngineのRails APIで構築されていたのを更にフルJavaScript版に進めた感じがしますね。

zenn.dev

zenn.dev