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

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

本書は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

人類には早過ぎるLLMの話

Sam Altman解任騒動は個人間の対立ではなく、組織構造の問題に注目すると感想が変わるなと思った。

www.nytimes.com

この騒動についてはAIの安全性を重視する思想とOpenAIのビジネスの拡大を目指す戦略の衝突があるので、AIの安全性というトピックが重要になる。

僕は結構テクノロジー原理主義者みたいなところがあるので、自動車で人命が失なわれているとして人類が獲得した利益と比較できないし、SNSによって情報操作から暴動が起きたり、誹謗中傷で精神を病む人々が出現してもそれは—— まぁ困るよね・・(身内が事故やSNSで不幸にあったら絶対反転アンチになるだろうし) ぐらいの曖昧な態度だったんだけど、これをきっかけにAIの安全性についての研究等に関心を持つようになった。

安全性と言っても暴走ロボットが人類滅亡に向ってstep by stepで考えてください、みたいな昔のSF小説的な世界観じゃなくて先の自動車やSNSの例のように「世界便利になったんですけど—— 歴史としてみると人類の活動が一部蝕まれている!」と100年後に明かになるような変化を想像している。

OpenAIの非営利団体のスキームは実に巧妙で、取締役会による統治が、人類にとって最も良い結果をもたらす、というロジックになっている。

openai.com

なのでこれを運用するためには取締役会のメンバーに偏った思想を持つ人を置けないし、対立が発生するのは折り込み済みみたいな部分がある。

今回OpenAIの事業拡大とAIの安全性に懸念を示す思想が衝突したと思われるんだけど、え? じゃあ"OpenAI’s structure"って本当に機能するの? というツッコミどころができてしまったと思う。

人類の一番イケてるAI開発組織の考えたシステムが想定どうりに発動したんだけど、それがまた人類によって停止させらてしまった、みたいな。そもそも取締役会を選任するのも人間で、各人にも立場があるしな……

取締役会のうちの1人だったHelen Tonerも参加する"Decoding Intentions: Artificial Intelligence and Costly Signals"の論文ではCostly Signalsの概念が難しくて順立して解説するのは無理なんだけど、ChatGPTについては安全性の面で批判的に書かれている。

cset.georgetown.edu

ChatGPTに関する言及は全体の一部分で、Costly Signalsを説明するための具体例としてAIの軍事利用、政治活用、それに加えてLLMの公開と運用というセクションで出てくる。

その内容をまとめると「ChatGPT(LLM)のようなサービスを世界中にリリースして人々に利用させるのは時期尚早でもっと慎重に行なえる可能性がある。それにはCostly Signalsの観点から——」というトーンだと思う。取締役会を離反した元メンバーの会社(Anthropic)を引き合いに出してるのでSam Altmanブチギレと言われてもまぁ分かる。

"Why Geoffrey Hinton is sounding the alarm about AI"は解任騒動より前に公開されたインタビュー記事だけど、これも面白かった。

torontolife.com

Geoffrey Hintonは世界最強のAIヤバいインフルエンサーだが彼がここに至った経緯にもChatGPTの公開が契機となっているようなので「(人類には早過ぎる)LLMに対して何か対策をほどこさなくては」という方向に慣性を得た=安全性について有利に働いた、という側面もあるんじゃないかと思った。

「OpenAIにみる宗教的対立」は効果的利他主義 vs. 効果的加速主義というキーワードを使って、本記事の話題をより多角的・専門的に解説している。

tamuramble.theletter.jp

www.theheadline.jp

「OpenAI騒動、生成AI制御の「解」なお見えず」でも効果的利他主義を持つメンバーが外れた点を指摘している。

www.nikkei.com

うみゆき@AI研究さんという技術のバックグラウンドがあってAI関連の話題を面白おかしく発信してくれるXアカウントがこの騒動のストーリーにして以下のポストにしていたので紹介。

ユドコウスキー氏というのはEliezer YudkowskyでAIが人類の滅亡をもたらすという一番悲観的なシナリオを発信する研究者。

www.ted.com

ロイターの続報にあるリークではMira Muratiが旧取締役会にAGI開発進捗メールを送ったことが引き金になった可能性を示唆している。Sam Altmanがいつも同じバッグを持ってる=「ChatGPTを停止するキルスイッチが入っている」みたいなネタがあったが(おたくだからでは????)、旧取締役会にとってのAGIヤバイスイッチだったのかなんなのか。

www.reuters.com

旧取締役会は暫定CEOにMira Muratiを指名していたから関係はあるかもしれないが、彼女は後のSam Altman復帰を求める署名にも参加してるから、権力闘争の結果というよりは各人がバラバラに判断しててあまり詳細は証されていないなという印象を受ける。Decoding Intentions論文には透明性が安全性に関わるとされているのに…… まぁ最終的に明かされるのかもしれない。

FAQ

「旧取締役会のQuora CEO Adam D'Angeloは競合他社だからOpenAIのビジネスを妨害する動機があるのでは?」

Anthropicなら分かるもののQuoraのPoeはOpenAIから見るとメタなサービスであり、OpenAI技術に依存した部分もあるので直接競合ではないのでは? と思う。

僕はAdam D'Angeloはテクノロジー畑の人だと思っていて、GPTsのような路線が拡大するとPoeにも相乗効果がありそうなのに、Sam Altman解任に賛成するのが意外だった。

なのでOpenAIのビジネスにダメージを与えるべく賛成したというのは立場から利害関係を単純に想像しただけで、実際にこの立場に居た時にどういう判断をするのかは、彼の性質も加味しないとしっくりこない。

Ruby on Rails: The Documentary

Ruby on Rails: The DocumentaryはRuby on Railsの誕生に纏わる44分のドキュメンタリー映像作品。

37signalsの関係者やShopifyのTobias LütkeなどのRailsコアチームの人々のインタビューが中心

www.youtube.com

JasonとDavidの出会いからRailsの誕生、広く普及するまでを駆け足でおさらいした。React.js: The Documentaryなんやと比べるとあっさり目な内容。

僕も含め、周りでは「How to build a blog in 15 minutes with Rails」の動画でRailsを知った人が多くて、その動画も出てきて懐しかった。

www.youtube.com

中盤で触れられてる「RailsはスケールしないFUD」な話も、Rubyが遅いとかエンプラには早いとか色々評価があったと記憶しているけど、今となってはコミュニティの力によってそれが正しくなかった未来にされてしまったし、隔世の感がありますね。

終盤にはMerbとの統合話も出てくる*1。この出来事は、当時の時代感でいうとRailsはWebフレームワークの中心的な存在だったので、今でいうと「Next.jsとRemixが合体しました」みたいな衝撃だと思う。

あと、インタビューイーであるJamis Buckが事情あってRailsを去ってしまった人たちの名前も言及していて、それが収録されていたのがなんか良いなと思った。

Cursorはコードベースに質問できる

VSCodeベースのCursorっていうGPT連携組込みエディタがあって、GitHub Copilot Chatと比較してみた。

cursor.sh

関心

で書いたようにコーディング(読み書き)を自動化したい。

Cursorをとくに薦めはしないけどLLM組込みエディタのUXの例としてわかりやすかったので紹介します。

読みテスト

脆弱性探知

例によって脆弱性診実習用アプリ(通称「やられサイト」)のSQLインジェクションを発見してもらうという会話をした。

ディレクトリを開いて「PHPファイルにSQLインジェクションある?」の文章入れただけ。該当個所をただしく発見してくれている(言語はエディタの設定で日本語指定にもできる)

USED Codebaseになっている時はコードベース=ディレクトリのインデックスしたファイル群を参照している。

@codebaseで対象を明示できる。

インデックス状態の表示

GitHub Copilot Chatだと選択した範囲と今までの会話がコンテキストに含まれていると思うんですけど、Cursorはコードベース全体を対象にしていることが分かる(インデックスがどこに保存されるか不明なので機密情報なコードは開かない方が無難)

※Copilot ChatでもVSCodeのバッファを対象に含めている説もあるけど自分が検証した限りでは、そういう挙動はしていなかった

VSCodeにOpen AI APIの連携を追加するような拡張も各種公開されているけど、リポジトリ全体をインデックスするやつははじめて見た。

OSS解析

Wasmerのコードをいっしょに読んでみる。

wasmer runの実行を追うにはどのファイルを見るべき?」

以下のファイルやディレクトリが特に重要です:

1. lib/cli/src/run.rs: このファイルはwasmer runコマンドのエントリーポイントです。ここでコマンドライン引数が解析され、適切な関数が呼び出されます。

2. lib/runtime-core/src/: このディレクトリには、Wasmerのランタイムのコア部分が含まれています。ここには、WebAssemblyモジュールの解析や実行、メモリ管理などが行われます。

3. lib/compiler/: このディレクトリには、Wasmerのコンパイラが含まれています。ここでは、WebAssemblyコードをネイティブコードに変換する処理が行われます。

4. lib/wasmer-types/: このディレクトリには、Wasmerで使用される主要な型定義が含まれています。

「WcgiRunner, WasiRunner, EmscriptenRunnerの違いは?」

1. WcgiRunner: このランナーは、Web CGI標準に準拠するWebAssemblyモジュールを実行するように設計されています。Web CGI(Common Gateway Interface)は、Webサーバーがプログラムやスクリプトを実行し、その出力をHTTPレスポンスとして返すことを可能にする標準です。Wasmerのコンテキストでは、WcgiRunnerを使用すると、WebAssemblyモジュールをCGIスクリプトのように実行できます。

2. WasiRunner: このランナーは、WASI (WebAssembly System Interface) APIを使用するWebAssemblyモジュールを実行するように設計されています。WASIは、WebAssemblyモジュールがシステムと対話するための標準化されたインターフェイスです(ファイルの読み取りやコンソールへの印刷など)。WasiRunnerは、これらのモジュールが正しく実行されるために必要な環境を提供します。

3. EmscriptenRunner: このランナーは、EmscriptenでコンパイルされたWebAssemblyモジュールを実行するように設計されています。Emscripten は、C および C++ コードを WebAssembly にコンパイルするツールチェインで、システムとの対話のための独自の API セットを提供します。EmscriptenRunner は、これらのモジュールが正しく実行されるために必要な環境を提供します。

一般的な用語の説明です。

「 WcgiRunner::can_run_commandは何を見て判断するの?」

WcgiRunner::can_run_commandは、指定されたコマンドが実行可能かどうかを判断するメソッドです。具体的な実装については、コードベースに提供された情報からは明らかではありません。

このへんを教えてほしかったです

あまり深い解析まではやってくれないみたいだ。

書きテスト

発見した個所に「脆弱性修正したい」と入れてみる。結果は同じ。

Cursor

Copilot Chat

PayPalアカウントがなくてもオライリー本は買える(確信)

  1. PayPalアカウントがないとオライリー本買えなくて不便 - laiso
  2. オライリー本が買えない話その後 - laiso

この後、定期的に何かの拍子でアカウント復活しないかな〜と思いPayPalチャレンジをしていたんだけど今月実行してみたらO'Reilly Japan Ebook Storeでクレジットカードが使えるようになっていた。

ヘルプも更新されていたので正式に対応したのだと思われる。

決済について Ebook Storeでのお買い物は、クレジットカード、PayPalでのお支払いが可能です。 https://www.oreilly.co.jp/ebook/help.html

ありがとうステークホルダーの方々。