hogashi.*

日記から何から

AIのぽんこつがなぜなのかを少し理解した / 仕組みが好き

 Google 検索で「青亜麻」を検索したところ、 Google 検索に据え付けの Gemini が、読みを「あまあま」として解説し始めた。


 流石に違うんじゃないかと思って、あってる? と聞くと、間違いでした、と言う。なぜ聞くとわかることが一発目に間違ったまま出てくるのか気になって、そのまま技術的に解説してもらった。

hogashi-generated.hateblo.jp

 ざっくりとした理解しかできてないものの、

  • 今の LLM の基本のつくりが文章を形態素解析のように区切ってトークン化して扱うものである
  • 出力するときに、次の文字 (トークン) を作り出すにあたっては、局所的に推測するものである
    • 文章全体を常に見ながら (推敲しながら) 出力するわけではない
  • 知らない単語に遭遇したときには、持ちうる知識のすべての関連度がほぼ 0 になる
    • 相対的に直前の単語が関連知識として使われがち
  • 日本語には「熱々」のような繰り返しの言葉 (畳語というらしい) が存在する

…ということの組み合わせで、間違って繰り返したまま出力してしまった事例らしい (詳細な説明は 2511.12869 On the Fundamental Limits of LLMs at Scale にある)。

 これだけ分かっていながら、なんとかしてないのか? と聞くと、最近の研究ではやってます、とのこと。

  • 出力としてユーザに見せる前に一回推敲する (reasoning*1 というらしい)
    • これは対症療法的だけど、全体を見なかったのが見るようになるので、精度はあがる
    • Gemini とか Claude とかの思考モードみたいなのがそれっぽい?
  • トークン化をしない (ByT5*2 というやつなど)
    • UTF-8 のバイト列とか、画像とかとして扱うことで、知っている/知らない単語という区別をなくす
    • 論文をサラ読みすると、言語が混ざった文などで強みがあるとか書いてある
      • "フランス語のこの単語は日本語ではこう書く"という英語の文章、とか。フランス語英語日本語が混ざっているけど、全部 UTF-8 で解釈すればトークン化の難しさはない
  • 関連度の計算を線形にやる (Mamba*3 というやつなど)
    • 従来の方法では、持っている知識との関連度を計算するとき、すべての知識の関連度が 0 で、直前の単語の関連度が 0.1 とかだと、 ソフトマックス関数 - Wikipedia というので計算すると、直前の単語のほうをほぼ 100% として引き上げてしまう (Softmax というのが実数たちを割合にして合計で 1 にする関数のため) *4
      • これは Softmax が非線形な計算をしていて、実際は関連度そうでもないのに 100% という見え方になるのがよくない
    • 代わりに、知識の関連度の計算を線形にやると、どの知識も、直前の単語も、それなりに低い確率であるという見え方になる
    • これをやるために、知識の記録をするときも、入力に応じた重み付けの行列を掛け算するとのこと (Selective State Space Model というらしい)

 大分ふんわりした理解だけど、これまで全くわかってなかった状態に比べると、ある程度は仕組みを理解することができて、ぽんこつ出力を見ても、そういうこともあるよね、と思える度が上がった。

 こういう、日々のできごとを元にその仕組みを知る、という活動が好きだったな、と思い出せる良い回だった。勉強しようと身構えるとなかなか難しいが、これは何がどう動いてそうなっているのか? とか考えながら引き続き暮らしていきたい。

bashでgit worktreeを使うとき不便なのでpecoでpushdするコマンドつくったりPS1いじったりした

 git worktree list は素朴すぎてむずいので peco で pushd できるようにした。先駆者はたくさんいるが、僕も前に ghq list でやったことがあったのでそれをコピペして使っている。
 コミットハッシュとかブランチ名とかも出るけど、あったほうが当然わかりやすいので出す。絞り込むときはブランチ名でやるだろうし……。

function gw() {
  ARG_STR="$@"
  PECO_RESULT=$(git worktree list | peco --query "$ARG_STR")

  PECO_RESULT=$(echo -n "${PECO_RESULT}" | awk '{ print $1 }' | tr -d '\n' | perl -pe 's/(^ | $)//g')
  if [ ! -n "$PECO_RESULT" ]; then
    return 1
  fi

  if [ -d "$PECO_RESULT" ]; then
    pushd "$PECO_RESULT"
  fi
}
git worktree list が peco で選択できる様子

 PS1 は元々 __git_ps1 を使っていたのを、遅いなとか言って .git/HEAD を見るように変えてあった (なので upstream との差分とかの記号のアレは出してない)。
 これだと worktree では動かない (.git が単にファイルで gitdir: ... とか書いてあるだけなため) 。なので worktree なときには諦めて __git_ps1 をフォールバックとして呼ぶことにした。

- GITPS1='$(echo -n " $([ -f "$(pwd)/.git/HEAD" ] && cat $(pwd)/.git/HEAD | cut -d" " -f2 | tr -d "\n") " | perl -pe "s|refs/heads/||")'
+ GITPS1='$(echo -n " $([ -f "$(pwd)/.git/HEAD" ] && (cat $(pwd)/.git/HEAD | cut -d" " -f2 | tr -d "\n") || ([ -f "$(pwd)"/.git ] && __git_ps1)) " | perl -pe "s|refs/heads/||")'
worktree 内では __git_ps1 が呼ばれている様子

ドラッグアンドドロップ中のDOMの様子をdevtoolsで見たいときsetTimeoutでdebuggerを発動すると便利

 devtools を使うと、 HTML 中の要素の並びやスタイルを調べたり、その場で変更してみたりできる。しかし、ドラッグ中の要素のスタイルをいじりたい、となると、 devtools を開いているだけでは難しい場合がある。その状態で devtools をある程度操作しないといけないが、マウスカーソルをそっちに持っていくと見たい状態ではなくなってしまう、という困り方。

 簡単な例として、ドラッグアンドドロップで順序を変えられるリストに、ドラッグ中だけ色を反転するスタイルを当ててある。

ドラッグして順序を入れ替え
  • 一味唐辛子
  • 二子玉川
  • 和三盆

 動画(GIF)で貼っておくとこういう感じ。今回だと、ドラッグ中だけ .sortable-chosen という class 名が当たるので、ドラッグアンドドロップをやめると該当のスタイルを devtools でいじることができない。

ドラッグ中だけclass名が当たるため、ドラッグアンドドロップをやめるとスタイルをいじれない様子

 そういうときは setTimeout で自動で debugger を発動させると便利。 debugger - JavaScript | MDN
 Console タブで以下のように setTimeout を 2秒後とかに設定して実行しておき、画面内にマウスカーソルを持っていってデバッグしたい状態にしてキープする。 2秒たったら debugger が発動して画面がその状態で止まるので、 devtools を好きに操作できる。

setTimeout(() => { debugger; }, 2000);
2秒後に自動でdebuggerを発動させることで、ドラッグ中で停止してスタイルをいじれる様子

 これは必ずしも setTimeout じゃなくてもよくて、クリックを起点に element.addEventListener('click', () => { debugger; }) とかしてもいい。操作の中のどこで停止させたいか、に沿って、使いやすい方法で debugger を発動させると便利です。
 当たり前だけど、ソースコード中に debugger 文を書くと、最も狙ったタイミングで発動させられると思う。今回書いたのは、その場でちょっと見たいときや、ソースコードのどこでこうなっているかわからないときなど、ブラウザ上から発動したほうが楽なときに使いやすい方法でした。

Claude Codeと人間で行ったり来たりを通知じゃなく音楽でやるツールつくった

 agent-b2b というグッズをつくった。 Claude Code と人間が行ったりきたりするときに、 cmux で通知を受けるとかのかわりに、鳴ってる音楽が変わることで気づける back to back みたいなことができたらいいかもと思い、 Claude Code でつくった。今回エディタを開いていない。 GitHub - hogashi/agent-b2b: back to back between human and agent · GitHub

agent-b2b の操作盤

 README に貼ってるデモ動画はこんな感じ。音が鳴るので注意。 Claude Code が考え中はメロディがあり、人間待ちになるとキックとベースだけになる、とかができる。どれ流すかは設定できる。

youtu.be

 npx agent-b2b すると、 localhost で Web サーバが立つ。ブラウザでアクセスすると音を鳴らすページが開き、 Claude Code の hook を設定しておくと、状態が変わったときに POST されて WebSocket を経由して音楽が変化する。
 チェックをつけ外ししたり、シーケンサをいじったりして遊びつつ、 Claude Code とのコーディングを楽しんでみてください。

 通知がきて呼び戻されるよりは自然にストレスなく戻れるのではないかみたいな仮説があるけど、本当にそうかは不明。あと、この短さのループでこの素朴さでは飽きるので、もっとちゃんと音楽でやれるようにしてみたい。誰か fork などして拡張してくれ!!

 ちなみにシーケンサ自体で遊ぶのが普通に楽しいので、 GitHub Pages にデプロイしておいた AGENT-B2B - Back-to-back beats with your AI agent 。触ってみてください。お気に入りの設定ができたら、 export して保存したり人にあげたりしてみてください。

OSSあたたか日記

 あたたかい開発者の方からの細やかな気遣いに嬉しすぎて涙している。小さな小さな OSS でも、こういうあたたかさを支えに生きていくものだなと思う……。

github.com

 文脈の説明:

  • hogashi は VSCode 拡張機能として、 Git 管理されたコードベースのファイルを開いたときのカーソル位置に当たる場所を GitHub で開くためのパーマリンクをクリップボードにゲットできる、というグッズをつくっている
    • hogashi/repo1 の README.md の 3行目を開いてたら https://github.com/hogashi/repo1/blob/deadbeef.../README.md#L3 がコピーされるみたいなこと
  • これのつくりとして git remote を参照するように丁寧に作ったところ、偶然 GitLab 管理な repo でも動作していたらしい
    • hogashi は知らなかった
  • 件の方が GitLab でも (オンプレ版でも) 使えて便利なので、それを README に書かないか? と issue/pull req をくれた
    • Web サービス GitLab のほうはまだしも、オンプレ版 GitLab は手元で試せる環境ないから、あんまりちゃんとサポートできないかも、と伝えたところ、↑のような情報をくれて、ありがてえな……という状態