⌨️

AIの時代 テキストデータに身体性を持たせる試み

に公開

作ったもの

  • テキストを書く行為を録画・再生するライブラリ
  • キーイベントを全てキャプチャしてリズム、修正、ポーズなどの情報を保存
  • 入力時の挙動を再現して再生

https://github.com/pppp606/kakiato/

デモ

https://kakiato.dev

録画した文章の共有URLも生成できるので使ってみてくれると嬉しいです!

なぜ作ったか(だいぶ抽象的な話)

  • AIには(まだ)書けない文章を書きたい
  • AIには身体性が無い、のが限界という言説
    • 身体性を過剰に評価している気がする
    • 人間の方がセンサーが多く持っている、インプットするデータの解像度が高いぐらいの差だと思う
  • LLMが扱うテキストデータには身体性がない
    • これは間違いない事実
    • 文字そのものに身体性はないが、文字を書く(キーボードを打つ)という行為には身体性がある
    • 同じ文字列でも悩みながら何度も書き直したテキストと、興奮して出来る限りのスピードで入力したテキストの意味はたぶん違う
  • 文字を書く行為の身体性をテキストのメタデータとして保存したい

ライブラリの内容

Core: データスキーマと型

  • 時間軸上のイベント列として記録
  • 最終的なテキストだけでなく入力の過程を保存

ドキュメント構造:

{
  version: "0.1",
  session: {
    id: "uuid",
    user_agent: "...",
    device: "desktop" | "mobile" | "tablet",
    lang: "ja",
    source: "KakiatoRecorder"
  },
  initial_text: "",
  events: [
    { time: 0, type: "focus" },
    { time: 100, type: "keydown", key: "h", code: "KeyH", pos: 0 },
    { time: 120, type: "input", inputType: "insertText", data: "h", text: "h", pos: 1 },
    // ...
  ]
}
  • time: 記録開始からの経過時間(ミリ秒)。タイピングのリズムや間をデータして保持
  • pos: カーソル位置、どこで何が起きたか
  • text: inputイベントには編集後のテキスト全体を含める。レンダリングが楽
  • IME対応: compositionstart/update/endで日本語入力などの変換過程も記録

Recorder:編集操作をキャプチャ

  1. KeyboardHandler: 物理的なキー操作を記録

    • keydown/keyupで実際に押されたキーを取得
    • Shift/Ctrl/Alt/Metaなどの修飾キーの状態も保存
    • カーソル移動(矢印キー)などの検出に使用
  2. InputHandler: テキストの変更を記録

    • beforeinputで操作の意図(insertText, deleteContentBackward など)を取得
    • inputで実際の変更後のテキスト全体を記録
    • inputTypeによって「何をしたか」を判別(挿入/削除/貼り付けなど)
  3. CompositionHandler: IME入力を記録

    • デフォルト動作: 変換開始(compositionstart)と確定(compositionend)のみ記録
    • 変換が行われた事実と最終的に選択されたテキストを保存
    • recordCompositionDetails: trueの場合: 候補切り替えも記録
      • 例:「かんじ」→「感じ」→「幹事」→「漢字」の履歴も残る
      • ⚠️ 機密情報が含まれる可能性や、プライバシー保護の観点でデフォルトはオフ(デモサイトもオフです)
  4. SelectionHandler: テキスト選択・カーソル移動を記録

    • 選択開始位置、現在のカーソル位置、進行方向を取得
    • 範囲選択して削除などの動きを再現
  5. FocusHandler: 入力フィールドのフォーカス状態

    • どのタイミングで入力を開始/終了したかを記録

Player:テキスト入力を再現

  1. PlaybackEngine: タイムライン制御

    • 記録時と同じタイミングでイベントを発火
    • 速度変更(0.5x〜2x)時は時間をスケーリング
    • シーク機能もあり
  2. StateReconstructor: イベントからテキスト状態を再構築

    • inputイベントのtextフィールドを使ってテキスト全体を更新
    • カーソル位置・選択範囲を追跡
    • IME変換中の状態も管理
  3. TextViewer: ミニマルなビューワー

    • テキストと選択範囲を表示
    • 白・黒・グレーの3色のみのシンプルなUI
    • オプションでUIは変更可能

今後やりたいこと

  • ライブラリのデモを増やす
    • WebSocketでリアルタイムに再生
      • みんなで一斉に写経とか、ライブショートショート作成イベントとか楽しそう
  • vscodeのプラグイン化を検討
  • 収集するデータの拡張
  • 面白そうな用途
    • 教育目的で生徒の入力をみる
    • メンタルヘルス的なコミュニケーションで活用
    • 好きな作家がデータ作って売ってくれたら欲しい
      • 円城塔先生とか
      • 縦書き対応した方が良いかも

感じたこと

  • エンジニアもどんどん抽象的な話をしてよい(した方がよい)時代な気がしてきている
    • ポエム駆動開発
  • 相変わらずコードを書く必要は全くなかった
    • claude/codex で 50:50 ぐらいの割合
    • chatGPTで抽象的な話からスタート -> 仕様を決めてコーディングエージェントへの引き継ぎ書を作成 -> タスク分割して実行
  • 単純な静的コンテンツのCDN以外で初めてcloudflareを使った
    • Pages + D1
    • prismaのマイグレーションをD1で回すのに工夫が必要

Discussion