Obsidianのクイックノートが増えすぎたので一括管理する方法を考えた

Obsidianのクイックノートが増えすぎたので一括管理する方法を考えた

クイックノートで特定のフォルダに新しくメモを作成する。作ったはいいものの、tagsで要素を決めてMoverで移動させるにも考える必要があるから面倒になる。 これは1箇所ですべてを賄おうとしているから起きる話で、inboxから他へ移動させるためには、メモを整理する仕組みそのものが必要だと考えた。 あなたはどうだろう。inboxに溜まったメモ、定期的に空にできている派? それとも見ないふりをしている派? 私は完全に後者だった。ただ数えてみたら、怠けているというより仕組みの設計が悪かっただけだとわかった。 発端:inboxが「置き場」ではなく「墓場」になっていた Obsidianのクイックノートは 07_workspace/00_Memo/_inbox に一次受けしている。思いついたことをすぐ書けるのはいいのだが、書くコストが低い分だけ溜まるスピードが処理するスピードを上回る。 一応、仕組みはあった。frontmatterに #防音Lab のようなブログタグを付けると Auto Note Mover が対応フォルダへ運んでくれる。理屈の上では自動化されている。 理屈の上では。 実際に数えたらこうだった。tags 件数note のみ 139その他(standfm / ClaudeCode / GA4 など) 5144件中139件がデフォルトの note のまま。 タグで動く仕組みなのに、タグが付いていない。自動化の前提そのものが成立していなかったわけだ。 なぜ付けないのか。付けるのが面倒だから、ではない。タグを1つ選ぶという行為が、実際には「このメモは何なのか」「どのブログに載るのか」「そもそも記事になるのか」を同時に判断させられるからだ。メモを開くたびにこの3つを考えるなら、そりゃ後回しになる。 診断:溜まる原因は「1件あたりの判断コスト」だった 144件を眺めてわかったのは、メモの熟度がきれいに4層へ分かれていることだった。層 件数種メモ(15行未満・問いだけ) 40育ちかけ(15〜39行) 37記事化圏内(40〜99行) 40レポート級(100行超) 28「スイスはなぜ秘匿性の高い銀行があるのか」の10行と、「エリート・アスリートの食事法」の343行が、同じフォルダに同じ顔で並んでいる。この2つを同じ手順で処理しようとするから止まる。 つまり問題は「整理していないこと」ではなく、整理という作業が1件ごとに重すぎることだった。ここを分解すれば動くはずだ。 構想:判断と移動を分ける 出した結論はシンプルで、「分類する」と「移動する」を別のコマンドに割るというもの。 _inbox/ ← 未処理(クイックノートの着地点) ↓ /inbox-triage 判定を書き込むだけ。行き先へは動かさない _triaged/ ← 判定済み・行き先待ち ↓ /inbox-flush 判定に従って機械的に移動。新たな判断はしない 各destination(ブログ / 09_Knowledge / 06_resource / 99_Planning …)分けるメリットは2つある。 1つ目は、判定フェーズでは「移動先が正しいか」を悩まなくていいこと。とりあえず判定を書き込むだけなので、間違っていても後から直せる。ファイルはまだ動いていない。 2つ目は、フォルダの残数がそのまま進捗になること。_inbox に何件あるかが未処理件数で、それ以外に指標を持つ必要がない。 実装:AIに読ませる範囲を2要素に絞る ここが一番効いた設計判断だと思っている。 自分のメモは、Templaterの都合で全件が同じ構造をしている。ファイル名がそのままH1で、その下に > [!important] のcalloutが1つ。 そして気づいたのだが、メモのネタは必ずこの2つに入っている。タイトルは自分が付けた問いそのものだし、importantには書いた瞬間の意図が入っている。本文は後から膨らんだ枝葉でしかない。 実際に測ったら、144件中130件(90%)のimportantに実テキストが入っていた。 だからAIに読ませるのは「ファイル名 + frontmatter + importantブロック」だけでいい。本文全体は読ませない。 これは効率の話に見えて、精度の話でもある。343行のメモを全部読ませると、AIは本文の細部に引きずられて「このメモは何なのか」を見失う。タイトルとimportantだけ渡したほうが、書いた本人の意図に近い判断が返ってくる。 20件で試したところ、判定不能はゼロだった。10行のメモも343行のメモも、同じ2要素だけで判定できた。 実装:判定は「分類」ではなく「アドバイス」を本体にする 当初は type: content のような分類ラベルを付けるだけのつもりだった。でもそれだと、ラベルが付いただけでメモは1ミリも前に進まない。 そこで、書き戻す内容の主役を「このメモをどう発展させるべきか」に変えた。分類はその副産物という位置づけにする。 実際の出力がこれ。 > [!tip] 発展の指標 > 判定: コンテンツ作成 → namagomi-techo(stage: seed) > 方向性: 生ごみ処理機ブログの購入動機そのものを扱えるテーマ。一般論ではなく浜松市の有料化状況を軸にすると、地元検索に刺さる。 > 次の一手: 浜松市の指定ごみ袋の価格と近隣市の価格を調べる > 不足: 自治体の一次情報、有料化前後のごみ量データ元のメモは「ごみ有料化による問題と課題について」で、importantには「まとめるべきだなと思った」の一行しか書いていない。それでも切り口まで戻ってくる。 ルールとして効いたのが「次の一手は動詞で終わる1文にする」「検討する・考えるは禁止」の2つ。「〜を検討する」で終わると、結局また判断が必要になって元の木阿弥になる。「浜松市の指定ごみ袋の価格を調べる」まで落ちていれば、5分あれば手が動く。 実装:データはfrontmatterに、指標は本文に 判定結果は2箇所に書き分けている。 --- created: 2026-06-18 19:29 updated: 2026-08-07 tags: - note # ← 触らない(後述) type: content # content | idea | task | resource | knowledge stage: ready # seed | ready dest: namagomi-techo triaged: 2026-08-07 ---frontmatterは機械が読む用。Obsidian Basesやdataviewで「type=content かつ stage=ready」のように絞り込める。 [!tip] は人間が読む用。フォルダを開いてメモを見たとき、次に何をすればいいかが目に入る。 type(何であるか)と stage(今すぐ動かせるか)を別プロパティにしたのもポイントで、1軸だと「記事化圏内40件」と「種メモ40件」が同じ content に混ざって、結局また選別が発生する。2軸なら「contentかつready」だけを取り出せる。 落とし穴:自動化ツール同士がぶつかる これは事前に気づけてよかった点。 Auto Note Mover の設定を見たら trigger_auto_manual: "Automatic" になっていた。つまり tags にタグを書いた瞬間にファイルが移動する。登録されているのは11ルール。tag 移動先#防音Lab #釣!浜名湖 #海上アングラー #シラバスハック #生ごみ手帖 #344net #ビジネス解剖 各ブログフォルダ#task _task#archive 22_Archives#自己啓発 #自分メモ 06_resource / 03_assetsもし判定を tags に書く設計にしていたら、triageした瞬間に全ファイルが飛び散って、「判定と移動を分ける」という設計思想そのものが壊れていた。 対処は単純で、判定は type / stage / dest という独立プロパティに書く。Auto Note Mover はタグしか見ないので反応しない。 そして逆手に取れる。flush(実際の移動)のときはタグを付けるだけでAuto Note Moverが運んでくれる。既存の自動化を壊さず、乗る。 自動化を足すときは、既に動いている自動化の発火条件を先に確認する。便利なプラグインが勝手に動くのは、意図しないタイミングでは事故になる。 落とし穴:思い込みで判定基準を作りかけた もう1つ、実測に救われた話。 > [!important] の中身が > ノートの要約 というプレースホルダのまま放置されているメモが14件あった。最初は「中身が空なんだから全部アーカイブでいい」と決めかけた。 実際に行数を数えたら、こうなっていた。区分 件数 例本文もない 7 次にやりたいことがないな(10行)importantは空だが本文が育っている 7 エリート・アスリートの食事法(343行)、乳酸値測定デバイスに関する調査レポート(109行)半分は中身がしっかりあった。importantを埋め忘れただけで、343行のレポートをアーカイブに放り込むところだった。 さらに、残る7件も捨てるべきではないと考え直した。「スイスはなぜ秘匿性の高い銀行があるのか」は本文こそ空だが、タイトル自体が良質な問いになっている。むしろこういうメモこそAIに方向性を出してもらう価値がある。 結果、archive は自動で付けない仕様にした。捨てる判断は人間がやる。 一括処理のルールを作る前に、1回数える。144件を相手にするとき、思い込みの誤差は7件の取り返しのつかない削除になる。 実装:デイリーノートから見えるようにする ここまでで仕組みは動くが、見に行かないと存在を忘れるという根本問題が残る。inboxが墓場になったのと同じ理由だ。 なので、triageしたメモにはチェックボックスを1行足すようにした。 - [ ] 【未整理】**ごみ有料化による問題と課題について**これをデイリーノートのdataviewで拾う。 ## 未整理メモ(triage済み・行き先待ち) ```dataview TASK FROM "07_workspace/00_Memo/_triaged" WHERE !completed AND contains(text, "【未整理】") SORT file.ctime ASC LIMIT 15 ```「【未整理】」というマーカーを付けているのには理由がある。メモの中には「気になる本20260519」のように、本文に読書リストの - [ ] を20個以上持っているものがある。マーカーなしでTASKクエリを書くと、デイリーノートが本のタイトルで埋まる。 もう1つ引っかかったのが、既存の「Task:no-complete」クエリが FROM "01_diary" に限定されていたこと。メモ側にチェックボックスを置いただけでは拾われないので、専用セクションを別に作る必要があった。 dataviewのTASKクエリを増やすときは、既存クエリのFROM範囲と本文に元からある - [ ] の2つを確認する。片方を見落とすと「表示されない」か「表示されすぎる」のどちらかになる。 結果:20件流してみた created の古い順に20件でテストした。type 件数stage 件数content 10ready 11knowledge 7seed 9idea 1resource 1判定不能ゼロ、タグの誤爆ゼロ、[!important] の改変ゼロ。処理そのものは想定通りに動いた。 面白かったのは、結果を見て設計のほうに疑いが出たことだ。 type: task が1件も出なかった。5分類のうち1つが空振りしている。自分のinboxは思索メモが主体で、実行タスクはそもそも流入していないのかもしれない。残り126件を流しても出なければ、4分類に縮めるのが正しいはずだ。 content の行き先が344netに8件集中した。専門5ブログのテーマに乗らないものの受け皿になっている。これは分類の問題ではなく、344net側にカテゴリ設計が要るという話だろう。 このあたりは20件流さないと絶対にわからなかった。設計書を完璧にしてから実装するより、20件で殴ってみたほうが早い。 未解決のまま残していること 冒頭に書いた通り、これは正解ではない。現時点で未解決の点を並べておく。 flush(実際の移動)はまだ実装していない。20件の判定精度を見てからにした。344netへの集中を見るに、残り126件を流して分布を確定させてからのほうが手戻りが少ないと考えている。 type の5分類は多い可能性が高い。task が空振りしているのが気になっている。 週次で回して新規流入と釣り合うかも未検証だ。計算上は週1回20件で足りるはずだが、実際に3ヶ月続くかは別問題。 そもそも「AIに方向性を出してもらう」こと自体が正しいのかという問いも残る。自分で考えるべきことを外注しているだけかもしれない。ただ、144件を前に手が止まっている状態よりはマシだと今は判断している。 作業中にも2件、新しいクイックノートが増えた。仕組みを作っている間にも流入は止まらない。そういうものだと思って付き合うしかないのだろう。 まとめ:数えてから仕組みを作る inboxが溜まる原因は怠慢ではなく、1件あたりの判断コストが重すぎることにあった。 144件を数え、熟度で4層に分け、判定と移動を別コマンドに割ったことで、20件のテストでは判定不能ゼロ・誤爆ゼロという結果につながった。それでも task 分類の空振りや344netへの集中など、20件流したからこそ見えた誤算も残っている。 設計を完璧にしてから動かすより、少数で殴ってみて穴を探すほうが結局早いんじゃないかなと思っている。

本当にバレるとやばい個人情報とは何か

本当にバレるとやばい個人情報とは何か

「本名が流出した」 「個人情報が特定された」 こういう見出しを見ると、多くの人がとっさに最悪の事態を想像する。でも実際に何がどう危険なのか、と一歩踏み込んで考えたことはあるだろうか。 私は以前、個人情報という言葉をひとまとめに「バレたら終わり」の危険物として扱っていた。ただ、よく考えると個人情報にも危険度の差があって、メディアの伝え方はそこをあまり区別していないのではないか、と感じるようになった。 あなたはどうだろう。「本名バレ」を一番怖いと思う派? それとも別のものを警戒している派? 視点を変えると、名前そのものより、名前と何が組み合わさるかのほうが本質的な問題なんじゃないかと思えてくる。 「単体」の個人情報は、実はそこまで怖くない 名前、生年月日、勤務先、居住している市区町村——これらは単体で見れば、名簿や名刺、SNSのプロフィールなど、日常のあちこちに既に転がっている情報だ。 たとえば「田中さんという名前の人が静岡県にいる」という情報だけでは、誰もその人を特定できないし、危害を加えることもできない。世の中には同姓同名の人間が大量にいるし、市区町村単位の居住情報だけでは自宅にたどり着けない。 メディアが「個人情報が流出した」と報じるとき、この単体の情報だけが漏れたケースと、あとで触れる組み合わせ情報が漏れたケースを、同じ温度感で扱ってしまうことがある。これが「個人情報=とにかく怖いもの」という漠然とした恐怖につながっているのではないだろうか。 本当に怖いのは「特定」と「接触」ができる組み合わせ 個人情報が本当に危険になるのは、複数の要素が組み合わさって特定の個人にたどり着き、かつ接触できる状態になったときだ。 たとえば次のような組み合わせは、単体の情報よりはるかに危険度が高い。氏名 + 自宅の詳細な住所(番地・部屋番号まで) 氏名 + 顔写真 + 日常的な行動パターン(通勤経路・よく行く店の営業時間帯など) 氏名 + 勤務先 + SNSアカウント(本人への直接接触経路になる) 氏名 + 家族構成(子どもの通学先など、弱い立場の家族への接触経路になる)これらは「特定して、待ち伏せできる」レベルの情報になる。ストーカー被害や空き巣、詐欺のターゲティングは、だいたいこの組み合わせが揃った瞬間に現実の危害へ変わる。 SNSに趣味の投稿と一緒に自宅近くの風景を継続的に上げていると、本人が意図しないうちにこの組み合わせが完成してしまうことがある。一つひとつの投稿は無害に見えても、積み重ねると動線が丸見えになるわけだ。 もう一段階怖いのは「なりすまし」ができる情報 特定・接触より、さらに実害が直接的なのが本人になりすませる情報だ。クレジットカード番号・暗証番号・セキュリティコード 銀行口座番号と紐づく認証情報 パスワード(使い回しているサービスすべてに波及する) マイナンバーのような、行政・金融サービスと直結する識別子これらは特定や接触を飛び越えて、直接的な金銭被害や不正契約につながる。「本名が流出した」という見出しよりも、こちらの流出のほうが実害としては重いはずなのに、ニュースとしての衝撃度は「本名」や「顔写真」のほうが大きく扱われがちに見える。 なぜそうなるのか。おそらく「名前や顔がバレる」ことのほうが感情的に想像しやすく、記事として読まれやすいからだろう。パスワードやカード番号の流出は、被害の実感が湧きにくい分、見出しとしての引きが弱いのかもしれない。 メディアの伝え方が恐怖の基準をずらしている 個人情報という言葉が一括りにされることで、「何が漏れたら何が起きるのか」という具体的な因果が見えにくくなっている気がする。 「〇〇人分の個人情報が流出」という報道を見たとき、その中身が氏名・メールアドレスだけなのか、パスワードやカード情報まで含むのかで、取るべき対応はまったく違う。前者なら警戒レベルを上げる程度でいいが、後者ならすぐにパスワード変更やカードの利用停止が要る。 でも見出しの時点ではその区別がつかないことが多く、結果として「個人情報=とにかく怖い、よくわからないけど怖い」という漠然とした反応だけが残る。これはメディアの伝え方の問題であると同時に、受け取る側が「何と何の組み合わせが危険なのか」という基準を持てていないことの裏返しでもあるのではないだろうか。 まとめ:怖いのは名前より組み合わせ 個人情報の危険度は、名前や顔写真といった単体の情報そのものではなく、特定・接触・なりすましのどこまで届く組み合わせになっているかで決まる。 住所や行動パターンとセットになれば特定・接触のリスクになり、パスワードやカード番号が絡めばなりすましの実害に直結する。同じ「個人情報流出」という見出しでも、中身によって取るべき対応の重さはまったく違う。 見出しの衝撃度で怖がるのではなく、何と何が漏れたのかを自分で確認する癖をつけたほうがいいんじゃないかと思っている。

「cloudflare/computer」とは何か? MCPとの違い・使いどころをFAQ形式で整理する

「cloudflare/computer」とは何か? MCPとの違い・使いどころをFAQ形式で整理する

Cloudflareが公開している cloudflare/computer というリポジトリをご存知でしょうか。名前だけ見ると「Cloudflare上で何かを操作する管理ツール」のようにも読めますが、実態は少し違います。 この記事では、「AIエージェントにコードを書かせたい」「MCPと何が違うのか気になる」という人向けに、よくある疑問をFAQ形式で整理しつつ、リポジトリの中身と実運用のTipsをまとめます。リポジトリ: https://github.com/cloudflare/computer 現状: プレビュー版(API不安定、本番利用非推奨)まず結論: 一言でいうと何なのか 「AIエージェントに、クラウド上で消えない“作業場”(ファイルシステム+実行環境)を持たせるための基盤ライブラリ」です。 エージェントAIの「頭脳」(LLM呼び出しの部分)はこのリポジトリの範囲外で、Cloudflareのagentsリポジトリなど別レイヤーが担当します。computerが担当するのは、エージェントが実際にファイルを書いたり、gitやnpm、シェルコマンドを実行したりするための「体」の部分です。FAQ Q1. MCP(Model Context Protocol)と何が違うの? 似たような文脈で語られがちですが、レイヤーが異なります。MCP cloudflare/computer役割 LLMと外部サービス(Gmail、GitHub等)を繋ぐ会話プロトコル エージェントにファイルシステムと実行環境そのものを与えるインフラ例えるなら 「ツールを呼び出す窓口」 「エージェントが作業する部屋そのもの」MCPが「何ができるか(機能呼び出し)」を定義するのに対し、computerは「どこで作業するか(実行環境)」を提供する、と考えると整理しやすいです。 Q2. Cloudflareで運用している複数のWebサービスを、これで一括管理できる? できません。 これは既存の本番サービス群を横断的に操作する管理コンソールではなく、「エージェント1体につき1つの作業スペース(Durable Object)を安価に大量生産するための土台」です。 複数サービスを個別にエージェントへ触らせたい場合は、サービスごとに専用のWorkspaceインスタンスを立てる、という設計になります。「複数Workspaceを束ねて横断操作する上位のオーケストレーション層」は、このリポジトリの守備範囲外なので自前で組む必要があります。 Q3. 「専用のエージェントAIをクラウド上で稼働させるためのもの」という理解で合ってる? 方向性としては正しいです。ただし2点補足が必要です。エージェントAI自体(LLM呼び出し)は範囲外。 computerが提供するのは実行環境(体)の部分のみ。 「常時フル稼働」ではなく「必要な時だけ低コストで展開」に近い。 Cloudflareの Durable Objects はアイドル時に休眠し、必要な時に起きる設計のため、ユーザー単位・セッション単位で大量に並行稼働させてもコストを抑えられます。Q4. クラウド上のサンドボックスと何が違う? 「クラウド上のサンドボックス」という理解でほぼ正解ですが、一般的なサンドボックスとの決定的な違いは状態が永続化されることです。一般的なサンドボックス cloudflare/computerライフサイクル 実行が終わったら消える(使い捨て) Durable Object内のSQLiteに正規の状態として保持され続けるファイルシステム コンテナのローカルディスク 仮想ファイルシステムがDurable Object側にあり、実行環境側は後から同期される実行方式 1環境=1コンテナが基本 3種類の実行バックエンドを同じWorkspaceに対して使い分け可能つまり「サンドボックス」+「その中身が消えないように保存される仕組み」がセットになったもの、という理解が近いです。エージェントが同じプロジェクトに何日も断続的に作業しても、前回のファイルがそのまま残っている状態を安く維持できるのが売りです。 Q5. 今すぐ本番サービスで使ってもいい? 現時点では非推奨です。READMEには「プレビューのみの提供であり、APIは不安定でデザインも変更される可能性がある。実験・探索・プロトタイプ向けであり、現時点では本番利用に適さない」と明記されています。技術トレンドとして押さえつつ、実運用は今後のアップデートを待つのが無難です。リポジトリ構成の解説 cloudflare/computer は小規模なモノレポで、主要なディレクトリ・パッケージは以下の通りです。 cloudflare/computer/ ├── .agents/skills/ # エージェント向けのスキル定義 ├── docs/ # 設計仕様(将来構想。現在のコードの説明ではない点に注意) ├── examples/ # 実際に動かせるサンプル群 ├── packages/ # 中核パッケージ群 ├── AGENTS.md # エージェントとして作業する際の手引き └── CONTRIBUTING.md # 開発・テスト・コミット規約コアパッケージ(packages/)パッケージ 役割@cloudflare/dofs Durable Object SQLite上に構築された仮想ファイルシステム本体。同期プロトコルの部品も含む@cloudflare/computer-rpc Durable Objectとcomputerdの間で使われるcapnweb通信の型・ヘルパー@cloudflare/computerd サンドボックスコンテナ内で動く常駐デーモン。FUSEマウント+HTTP/WebSocket RPCサーバー@cloudflare/computer 上記を束ねる、Durable Objectから利用するトップレベルパッケージ(開発中)3つの実行バックエンドContainer — サンドボックスコンテナ内でcomputerdがFUSEマウントとして仮想ファイルシステムを展開。完全なLinux環境・実バイナリ・実ネットワークが使える、最も「本物のマシン」に近い方式。 Isolate shell — Dynamic Worker内で軽量シェル(just-bash)を実行。Workers RPC経由で直接Workspaceにアクセスするため同期のオーバーヘッドがない。 Isolate JavaScript — Dynamic Worker内でECMAScriptモジュールを実行。node:fs/promises相当のAPIやgit/artifacts用の信頼済みモジュールも使える。用途に応じてこの3つをworkspace.runtime.exec(source, { backend })という単一のエントリポイントで切り替えられる設計になっています。 サンプル(examples/)examples/container — コンテナ内でcomputerdを動かし、Durable Objectとcapnweb経由で通信する一番フルスペックな例 examples/worker / examples/worker-shell — コンテナなしでDynamic Worker上のシェルだけを使う軽量版 examples/think — エージェントがWorkspaceを作業ディレクトリとして使うチャットエージェントの例。一番イメージが掴みやすいサンプル examples/tutorial — 最小構成のチュートリアル。エージェントがコンテナ上でmarkdownを書き、pandocを実行するだけのシンプルな例パフォーマンス傾向(ベンチマークより) 公開されているベンチマーク(script/fs-bench.sh)によると、傾向は以下の通りです。得意な領域: stat、rm、mkdir tree、find tree、git init、git clone、npm initなどメタデータ操作中心の処理は、実ディスク(ext4)より高速なケースが多い 苦手な領域: 64MiB単位の大きなファイルの逐次読み書きはtmpfsや実ディスクより大幅に遅い(数十倍のオーダー) 実利用への影響: 大きなファイルI/Oが遅い一方、npm installのような実際の開発ワークロードでは実ディスクと同等程度の速度になっており、日常的な開発作業への実害は限定的コンテンツアドレス化されたブロックストアに512KiBチャンク単位でハッシュを取りながら書き込む設計のため、生スループットは犠牲になるが、変更差分だけを同期できる・重複排除できるというトレードオフになっています。運用するならこう使う: Tips 現時点はプレビュー版という前提で、試すなら以下のような使い方がおすすめです。 Tip 1: まずは examples/tutorial から触る いきなりexamples/containerのフル構成に挑むより、最小構成のexamples/tutorial(markdown書き込み+pandoc実行)から始めると、Workspace・runtime・execの関係性が掴みやすいです。 Tip 2: 「1エージェント=1サービス」の粒度でWorkspaceを分ける 複数サービスを扱いたい場合は、サービスごとに別々のWorkspace(Durable Object)を立てる設計にする。横断オーケストレーションは自前実装が前提になる点を最初から織り込んでおく。 Tip 3: 大きなファイルを大量に読み書きする用途には向かない ベンチマーク上、64MiB級の大きいファイルの連続読み書きは大きく遅くなります。ビルド成果物のキャッシュや動画・大容量データセットの置き場としてではなく、ソースコードや設定ファイルなど「メタデータ操作が多い軽量なファイル群」の置き場として使うのが現実的です。 Tip 4: バックエンドは要件で使い分ける本物のLinux環境やネットワークアクセスが必要 → Container 軽量なシェル操作だけで十分・同期オーバーヘッドを避けたい → Isolate shell JavaScriptロジックをサンドボックス内で完結させたい → Isolate JavaScriptTip 5: 本番投入は避け、PoC・社内ツールから READMEが明言している通り、まだAPI変更が入りうる段階です。エージェント基盤の技術検証や、社内向けプロトタイプでの採用に留め、本番のミッションクリティカルなサービスへの組み込みは次のメジャーアップデートを待つのが安全です。まとめ:作業場を持つエージェントという発想 cloudflare/computer を一言でまとめるなら、AIエージェントに「消えない作業場」を持たせるためのインフラであり、MCPと競合するものではなく組み合わせて使うものだ、ということに尽きる。MCPが「何ができるか」の窓口だとすれば、computerは「どこで作業するか」の部屋を用意する役割で、両者はレイヤーがそもそも違うわけだ。 象徴的なのは、Durable Object内のSQLiteに仮想ファイルシステムを保持する設計で、エージェントが同じプロジェクトを何日も断続的にいじっても前回の続きから作業できる点。使い捨てのサンドボックスとは前提が違う分、メタデータ操作は速いが大容量ファイルの逐次I/Oは遅いというトレードオフも受け入れる必要がある。 私自身はCloudflareを使っていないので今すぐ触る予定はないけれど、AIエージェントを常駐させて長期プロジェクトを任せたい人にとっては、状態を安く持続させる仕組みとして視野に入れておく価値があるはずだ。プレビュー版である今のうちにPoCレベルで触っておくのが、次のメジャーアップデートに備える一番現実的な動き方じゃないかなと思っている。

マーク・マンソンが選ぶ「あなたをより賢くする9冊の本」を眺めてみた

マーク・マンソンが選ぶ「あなたをより賢くする9冊の本」を眺めてみた

「この本を読めば人生が変わる」 自己啓発系のタイトルを見ると、つい大げさだと感じることがある。だいたい「また煽りか」と眉をひそめて、クリックしないで終わる。 でも著者でありYouTuberのマーク・マンソン(Mark Manson)氏が「9 Books That Will Make You a Smarter Person」というタイトルで紹介していた選書は、少し毛色が違った。 あなたはどうだろう。書評動画、タイトルで判断してスルーする派? それとも中身のリストだけは確認する派? 私は後者に近い。今回は、世界観を変えたという9冊の中身をそのまま眺めてみることにした。 動画の概要 紹介されているのは、いわゆるベストセラー自己啓発本ではなく、歴史・社会科学・メディア論・心理学にまたがる「過小評価されているが重要な本」だ。派手さより、前提を疑う視点を養う選書という印象を受ける。 1. 『The Mosquito』(邦題:蚊が歴史をつくった) — Timothy C. Winegard 人類史を「蚊」という視点から描き直した歴史書。ローマ帝国の崩壊からアメリカ独立戦争、奴隷貿易にいたるまで、歴史上の重大な転換点や戦争の勝敗は、蚊が媒介する病気(マラリアや黄熱病など)によって決定づけられてきたことを示している。 2. 『Science Fictions』(邦題:Science Fictions あなたが知らない科学の真実) — Stuart Ritchie 科学界、特に社会科学(心理学、経済学、社会学など)における「再現性の危機」を告発した本。70%以上の研究が再実験で同じ結果にならないという現状と、研究者がデータを捏造・改ざんしてしまう査読システムの歪んだインセンティブ構造を解説している。データに対する懐疑的な視点が養われる一冊だ。 3. 『Democracy for Realists』(未訳) — Christopher H. Achen & Larry M. Bartels 西欧的な「民主主義へのロマン主義的な幻想」をデータで打ち砕く一冊。多くの一般市民は政治課題について学ぶ時間が十分にないか関心がないため、純粋すぎる民主主義はかえって悪い結果を招くことがあると指摘する。民主主義を機能させるには、高度な教育を受けた専門家によるチェック&バランスが必要だと説いている。 4. 『The Denial of Death』(邦題:死の拒絶) — Ernest Becker 死への恐怖が人間の行動の原動力になっていると説く、心理学・哲学の名著。人間は無意識に死の恐怖から逃れるため、後世に名を残そうとする「不死のプロジェクト(政治、執筆、子育て、慈善活動など)」に投資する。これが人生に意味を与える一方、他者のプロジェクトと衝突したときに戦争や暴力が生まれると分析している。 5. 『Understanding Media』(邦題:メディア論) — Marshall McLuhan 「メディアはメッセージである」という有名な言葉を残した、メディア論の古典。流されるコンテンツの内容そのものよりも、テレビや本、SNSといった「どの媒体を通じて情報を消費するか」が、人間の脳の働きや社会の性質を決定づけると主張している。 6. 『The Lessons of History』(邦題:歴史の教訓) — Will Durant & Ariel Durant 膨大な歴史書『文明の物語』を執筆した著者が、人類の歴史から得た教訓をわずか100ページに凝縮した知恵の書。地理が帝国の運命に与える影響や、テクノロジーと地政学の関係、競争の普遍性など、12の明確な教訓がシンプルにまとめられている。 7. 『The Structure of Scientific Revolutions』(邦題:科学革命の構造) — Thomas S. Kuhn 「パラダイムシフト」という言葉を生んだ、科学史・認識論の古典。科学の大きな進歩は、既存のシステムに利害関係のない「完全な部外者」によってもたらされることが多いと指摘する。これは科学だけでなく、人間の組織全般(保守派と革新派の対立)にも当てはまる話だろう。 8. 『The WEIRDest People in the World』(邦題:WEIRD「現代人」の奇妙な心理) — Joseph Henrich WEIRD(西洋の、教育水準が高く、工業化され、裕福で、民主的な人々)の心理や認知行動が、世界の他の地域とどう異なるかを分析した本。なぜ中世に遅れていたヨーロッパで啓蒙思想や産業革命が起きたのかという問いに対し、カトリック教会が課した「厳格な婚姻法(一族間の結婚の禁止など)」が従来の封建的血縁構造を解体し、高い競争力と流動性を持つ社会を生み出したという仮説を提唱している。 9. 『Apocalypse Never』(未訳) — Michael Shellenberger 気候変動に関する過度な終末論やアラーミズム(恐怖を煽る言説)に対し、冷静な視点を提供する本。元気候活動家である著者が、現状は報道されているほど絶望的ではなく、過剰な恐怖の煽り立てはむしろ逆効果であると主張している。環境問題に対してスマートかつ楽観的なアプローチを提示する一冊だ。 まとめ:賢さは選書の癖に出る 9冊を並べてみて感じたのは、共通するテーマが「見えている前提を疑う」ことだったという点だ。 蚊が歴史を動かし、査読システムが科学を歪め、婚姻法が近代を作った——どれも表向きの説明とは別の因果を掘り起こす本ばかりで、ベストセラー自己啓発本のリストとは明らかに毛色が違う。 自分の世界観を変えた本を人に聞いてみると、その人が何を疑う癖を持っているかが透けて見えるものなんじゃないかなと思っている。

乳酸値測定デバイスを調べてわかった、感覚に頼らないトレーニングの作り方

乳酸値測定デバイスを調べてわかった、感覚に頼らないトレーニングの作り方

「もう限界」「息が切れた」「足が重い」 トレーニングの強度を決める基準が、こういう主観的な感覚だけになっていることはないだろうか。 私はずっと、この感覚頼みのやり方に少し疑いを持っていた。同じ「もう限界」でも、日によって基準がぶれる。数値で見られたらどれだけ楽だろう、と。 あなたはどうだろう。感覚でペースを作る派? それとも数字で管理したい派? 調べてみると、体内の乳酸値を数値化するデバイスはすでに存在し、実用化されていた。今回はその現状を整理しておく。 乳酸を測る目的は「疲労の犯人探し」ではない 乳酸はかつて「筋肉疲労の原因物質」と考えられていたが、現在の運動生理学ではエネルギー源であり、疲労そのものを引き起こす物質ではないことが判明している。 そのため乳酸値測定の主目的は、有酸素運動から無酸素運動へ切り替わる閾値(LT:Lactate Threshold/OBLA:乳酸蓄積開始点)を把握し、トレーニング判断に活用することにある。目的 目安となる乳酸値 活用場面限界の一歩手前を維持する 2〜4 mmol/L 付近 疲労を爆発させずに最大負荷を長時間維持するペース設定追い込み(高強度インターバル)の基準にする 6〜10 mmol/L 以上 感覚に頼らず十分な追い込みを客観的に確認休憩(ワークオフ)のタイミングを図る 一定レベルまでの低下 時間ではなく数値基準でセット間の休憩を管理これにより「息が切れた」「足が重い」といった主観的な感覚に代わり、客観的データに基づいて運動強度・休憩を切り替えられるようになるわけだ。 現場で使われているポータブル型3選 ワイヤレスで汗や間質液を測るタイプも研究・開発が進んでいるが、精度と安定性の面では指先などからわずかな採血を行うポータブル型(血中乳酸測定器)にまだ及ばない。アスリートやスポーツ科学の現場では引き続きこちらが主流だ。 ① ラクテート・プロ2(LT-1730) / アークレイ 日本の医療機器メーカーが開発した、国内のスポーツ科学・医療分野における代表的モデル。必要血液量は0.3 µLという極少量で、測定時間は約15秒。手のひらサイズで持ち運びやすく、補正操作が不要なため現場で素早く測定できる。 ② Lactate Scout Sport / EKF Diagnostics 海外のプロアスリートやコーチに多く採用されているグローバルモデル。必要血液量は0.2 µL、測定時間はわずか10秒。Bluetooth機能を内蔵し、対応する心拍計との接続やスマートフォン・PCアプリへのデータ転送が可能で、トレーニングデータのログ化に優れる。 ③ Lactate Plus / Nova Biomedical 欧米の陸上・自転車・水泳などのトレーニング現場で高いシェアを持つ米国製。必要血液量は0.7 µL、測定時間は約13秒。病院等で使われる医療用テクノロジーをベースにしており、ストリップ(試薬)のコストパフォーマンスに優れるため、頻繁に測定を行うアスリートに向く。製品名 必要血液量 測定時間 主な特徴・強みラクテート・プロ2 0.3 µL 15秒 国内での実績多数、高精度、使いやすさ抜群Lactate Scout Sport 0.2 µL 10秒 Bluetooth対応、アプリや心拍計との連携機能Lactate Plus 0.7 µL 13秒 コストパフォーマンスに優れ、海外で高評価なお血中測定器は「運動しながらリアルタイムに連続計測できない」「数分ごとに針を刺して採血する必要がある」という課題を共通して抱えている。 針を使わない次世代ウェアラブルの展望 針を刺さずに連続計測を行う非侵襲型デバイスの開発も進んでいる。方向性は主に2つある。 1点目は汗センサーパッチだ。肌に貼ったパッチが運動中の汗に含まれる乳酸を検出し、リアルタイムでスマホ等に転送する。慶應義塾大学発ベンチャーをはじめ国内外で研究が進み、医療用・プロスポーツ向けに実用化が始まっている。 2点目はマイクロニードル(間質液)センサー。CGM(持続血糖測定器)と同様に、皮膚下の間質液中の乳酸値を極小の針で連続測定する技術だ。 いずれも一般向けスマートウォッチへの搭載を見据えて開発が進むが、まだ一般ユーザーが気軽に入手できる価格帯・フォームファクタには至っておらず、現状は医療・専門スポーツ分野での利用が中心となっている。 汗センサー方式の最大の弱点は、発汗量の個人差と汗が出るまでのタイムラグだ。汗をかきにくい人や運動開始直後の「無汗状態」では乳酸値を正しく拾えず、トレーニングのタイミング判断にズレが生じる。このギャップを埋めるため、電気刺激で汗を強制的に分泌させるイオントフォレーシスや、NIRS・心拍変動・皮膚電気活動を併用してAIが乳酸値を予測補完するマルチパラメーター推定など、複数の技術アプローチが並行して研究されている。 オールインワン化を阻む物理的な壁 汗センサー・光センサー・微小針・電気刺激を1つのウェアラブル端末に完全統合した市販製品は、現時点で世界に存在しない。 理由は単純ではない。電気刺激回路・近赤外光の発光受光部・AIチップを同時稼働させると消費電力が大きく、スマートウォッチサイズでは数時間しか持たない。微小針による炎症や血流変化が、同じ面に配置した光センサーの精度を狂わせもする。発汗を伴うセンサーは水分・塩分に直接触れるため、精密な光センサーや回路との共存で防水・ノイズ対策が難しい。数日〜数週間で劣化する使い捨てバイオセンサーと、半永久的に使える光学センサー・心拍計を統合すると、構造が複雑化するか高価なデバイスごと使い捨てにせざるを得ない。 そのため世界の開発現場では、1端末への統合ではなく役割分担型のハイブリッド構成が主流になりつつある。腕に貼る使い捨てパッチが発汗に依存せず皮膚下から連続的に乳酸値を測定し、スマートウォッチが光学・心拍・体温を取得、スマホ・クラウド側のAIが両者のデータをリアルタイムで統合演算して「無酸素運動に切り替わった」タイミングを通知する、という組み合わせだ。この方式はすでにプロスポーツや医療の臨床試験レベルで実用化が始まっている。 まとめ:数値で切り替える時代は近い 現時点で最も信頼性が高く実用的な選択肢は、血中乳酸を測るポータブル型測定器であり、非侵襲型ウェアラブルの単体製品としての完成にはまだ物理的な壁が残っている。 その代わり、間質液パッチとスマートウォッチとAIを組み合わせるハイブリッド方式がすでに臨床レベルで動き始めていて、一般向け展開もこの延長線上にありそうだ。 「もう限界」を数値に置き換える日は、意外と遠くないんじゃないかなと思っている。

AIの活用をフルで活かすためにするべきこと

AIの活用をフルで活かすためにするべきこと

「AIに自分の代わりをさせたい」——そう思ったことはないだろうか。 SNSの予約投稿ひとつとっても、AIにランダム性を持たせようとすると、そのランダムさ自体に余計なトークンを使ってしまう。それなら「A時になったら必ず━━」と決め打ちしたほうがわかりやすい。 あなたはどうだろう。AIには自分そのものを模倣させたい派だろうか。それとも、あくまで作業ツールとして割り切って使う派だろうか。 私の場合は後者ではなく、前者に近い。理想の人格をAIの中に作る、というアプローチをとっている。 理想の人格を作る理由 自動処理をするにあたって、個人の活動と自動処理を並べると違和感が出やすい。 例えばSNSだと、AIでもアルゴリズムで投稿する場合、時間指定をする必要がある。ランダム性を持たせて機械らしさを消すこともできるが、ランダムにすること自体に余計なトークンを使ってしまう。 予約投稿するのであれば、「A時になったら必ず━━」といった命令のほうがわかりやすい。 あなたの人格を作成する方法 新しくアカウントを作成して、第二の人格・理想の人格をそこに形成するべきかと思う。 AIにこう質問する。私の行動、言動をAIが模倣してくれるために必要なデータはどう取得するべきか? 私のルーティンを促すようにスケジューリングさせるにはどうするべきか?自分の言動とか言葉のくせを登録するなら、日記を毎日つけるのが手っ取り早い。興味のあるニュース分野がわかるし、書き言葉とか文章のクセを見つけることができる。 難点があるとすれば、「すぐ用意はできない」ことだ。日記の熱量にもよるけど、SNSの短文程度が30日分と、1000文字以上が30日では情報量がまるで違う。 日記をどこに記録するか OSにあるメモ帳でもいいし、GoogleDriveにあるドキュメントでもいいし、Obsidianでもいいし、Notionでもいい。 ClaudeだけでなくChatGPTなどの生成AIは、各種プラットフォームに直接アクセスすることができる。手間を減らすならクラウドサービスを使うのがいい。 なので手っ取り早い方法としては、無料で始められてAIと連携しやすく、かつツール自体にAIがあるNotionが楽だ。CLIでの使いやすさを重視するならObsidianやGoogleドキュメント。あとは好みの問題になる。 まとめ:第二の人格を設計する どれかしか使えない、ではなく、使えるものを使う——でいい。 理想の人格をAIに持たせるための一番のボトルネックは、ツール選びではなく自分のデータをどう蓄積するかだ。日記という地味な作業が、結局いちばんの近道になる。 私はまず自分の言葉のクセを可視化するところから始めようと思っている。

人はなぜ他者を差別するのか(読書感想文)

人はなぜ他者を差別するのか(読書感想文)

「差別と区別、何が違うんだろう」 そんな問いを何度も往復させられる本だった。 興味深い内容、でもなかった。ここにあるのは「差別をされた人の言葉」であり、その感想だ。 差別をしたとか、ヘイトスピーチをしたとか、誹謗中傷をした側の視点はほぼない。あったとしても判決事例とか開示請求の後の話で、それも誰でも思いつくようなつたない感想だけだ。 あなたはこの構成、物足りないと感じる派だろうか。それとも、それでいいと納得する派だろうか。 私はともすれば、その答えを欲しがっていたとは思わない。むしろそれが期待通りだったのではないだろうか、とさえ思っている。 差別と区別、何が違うのか 差別と区別は意味が違う。性質的には似ている。 ようするに、自分と違うものを認めないのが差別と区別だ。平等とは、差別や区別の概念が存在しない世界のことだろう。 それが実現しているなら、人も動物も自然も戦いをしないはずだ。戦いがなければ、誰かより秀でる必要がなければ、地球の生命体はここまで進化していないかもしれない。 だから「他者よりも」と考えるのは、本能で起きる行動じゃないかと私は考えている。 差別とかヘイトに傾倒する人は、その人の世界では間違っていない。 私からすれば、数多ある選択肢からそれを選んでしまっただけの話。同じコミュニティなら話は通じるだろうから、だから探すのではないだろうか。 なぜSNSで差別的な投稿はバズるのか SNSでそういった投稿がバズりやすいのは、いわゆるSNS警察と呼ばれる一定層へのリーチがあるからだ。 アテンションエコノミーといえば聞こえはいいけど、ありていにいえば、他人を騙すとか誘導するのが目的だ。 クルド人差別のことがあったけど、人種が違うのは区別のはずだ。人類皆兄弟というなら、人種という概念は存在しないはずだから。 白人、黒人、黄色——今だにカテゴライズされている。男性と女性で「性別」があるのも区別だ。 区別と差別は何が違うのか。差別は攻撃的な言葉として受け止められるだろうし、そう感じている人もいるだろうけど、区別と何が違うのだろうか。 人それぞれに答えがあるということ そういった考えを巡らせてくれた本だが、平易な意思の私だから咀嚼できる。 でも、両極端な人が読んだら、面白いほど意見が割れるんじゃないかなと思う。キレて本を破り捨てる人もいるだろうし、絶賛してシェアしつつ知見を振りまく人もいるだろう。 人それぞれ考え方は違うし、物事の捉え方も違う。そう思わないと、この世はやっていられない。私は私、お前はお前——このくらいがちょうどいい。 「お前がそう思うならそうなんだろ。お前の中ではな」のミームが浮かぶ。 あれはあれで、人それぞれに答えがあることを、1枚の画像で説明してくれている。あれを見てキレる人は、潜在的に自分がそうであると認識しているのかもしれない。危うさを感じているのか、それとも本能で避けたいのか。 「悪いものを排除すれば綺麗な世界になるのか」 特に人種差別とか犯罪者などの話は、裏側がどろどろしている。集団の中で1人が悪いことをすれば、他のすべても悪いことをしているように見えてしまう。 古い話だが、金八先生の「腐ったみかんの話」でいえば、箱の中で1個腐ったみかんがあると、他の綺麗なみかんも早く腐ってしまうという例え話だ。 同じ袋に入っているミニトマトの1個が腐っていたのは、直近で経験したことだった。1個だけ熟しすぎている果実とか、ぎゅうぎゅうに詰まっている長野のりんごとか、悪い部分はすぐ広がるんだけど、まあそこを取り除けば食えるじゃん、てね。 じゃあその話をくむと、悪いものを排除すれば綺麗な世界が生まれるのか。 ——それは違うだろう。正義だらけになると他を排除してしまうから、対立が生まれる。対立が出てくると、争うことになる。これは人類史がはじまって以来、現在でもある戦争がなくならなかった理由でもある。本質的には違うだろうけど、戦う(喧嘩する)のは何のためにするのかを、足を止めて考えるべきだろう。 まとめ:差別と区別は紙一重 差別と区別を分けているのは、結局のところ「攻撃性があるかどうか」という受け取り手の感覚でしかないのではないか、というのが読み終えての実感だ。 腐ったみかんを取り除けば箱がきれいになるわけではなく、排除は別の対立を生むだけ——それがこの本を読んで一番残った具体だった。 人それぞれ答えが違うことを前提にしないと、この手の話はいつまでも平行線をたどるんだろうなと思っている。

中小企業の賃上げが進まないのはなぜだろう

中小企業の賃上げが進まないのはなぜだろう

「賃上げ率が過去最高」というニュースを見た。 でも身の回りの中小企業で働く人から、そこまで景気のいい話は聞こえてこない。 ——このギャップってなんだろう。私はニュースの数字だけを見て、実感とのズレを感じることがしばしばある。 あなたはどうだろう。「賃上げ」というニュースを見たとき、素直に良い話だと受け取る派? それとも、どうせ大手だけの話だろうと思う派? 私は後者に近い。調べてみると、中小企業が賃上げしにくい理由は、円安や材料費だけでなく、もっと構造的なところにあるようだった。 賃上げできない最大の理由: 「価格転嫁」が進んでいない 中小企業庁の価格交渉促進月間フォローアップ調査(2026年3月時点)によると、価格転嫁率は54.2%(前回比+約1ポイント)。内訳はコスト要素によって差があり、原材料費は55.7%まで転嫁できている一方、労務費は50.0%にとどまる。つまり「材料費の値上がり分」はまだ転嫁しやすいが、「人件費を上げた分」を取引価格に乗せることは、より難しいという構造がある。 日本商工会議所の調査でも、コスト増加分について「ほとんどできていない」「していない」と回答した企業が合計48.4%にのぼる。約半数の中小企業は、コスト増をほぼ自社で吸収している状態ということだ。賃上げの原資は本来こうした価格転嫁で生まれるはずなのに、そこが機能していないので原資自体が細っていく。 26年春闘の実績: 賃上げ率は上がったが大手との差は埋まらない 2026年春闘での中小企業の賃上げ率は4.69%(前年比+0.04ポイント)。上昇はしているが、連合が目標に掲げる「6%以上」には届いておらず、大手企業との格差は依然として残っている。「賃上げ率が上がった」というニュースの裏で、価格転嫁が進まないまま原資を絞り出している中小企業が多いというのが、実態に近いのではないだろうか。 なぜ円安が絡むのか 原材料の多くを輸入に頼る業種では、円安が進むと輸入コストがそのまま上昇する(輸入インフレ)。ここで価格転嫁ができればコスト増を吸収できるが、転嫁率が5割程度にとどまる以上、円安による原材料高は利益を圧迫し、賃上げどころではなくなる企業も出てくる。 逆に言えば、円安は「価格転嫁が必要な理由」を増やす一方で、「価格転嫁できない企業」をより苦しくする方向に働いているわけだ。 なぜ国産は輸入品より高くなりやすいのか生産規模の違い: 国産は生産規模が小さく、大量生産によるスケールメリットが働きにくい。天候や季節の影響も受けやすく、供給が不安定になりがちで価格変動も大きい 労働生産性・人件費構造: 日本は労働生産性の面で不利があり、生産から流通まで含めたコストが割高になりやすい。輸入品は人件費の低い地域での大量生産によって単価を下げられる 為替の影響で逆転することもある: 円安が進むと輸入品側のコストが上がるため、これまで割高だった国産品と価格が拮抗したり、逆転する品目も出てきている(例: 牛肉やレモンなど)つまり「国産が高いのは品質が良いから」だけでなく、「生産規模が小さく、スケールメリットが働かない」という構造的な理由が大きい。これは中小企業が価格転嫁をしにくい理由(規模が小さく交渉力が弱い)とも、根っこが同じなんだと思う。 まとめ:価格の付け方が下手すぎる 賃上げの原資は「価格転嫁」で生まれるはずだが、中小企業は労務費の転嫁率が5割程度と特に弱く、原材料費以上に上げにくい。円安はこの構造の中で輸入コストを押し上げ、価格転嫁できない企業をさらに苦しくしている。国産が高くなりやすいのも、規模の小ささという同じ根っこの問題に行き着く。 根本にあるのは、日本企業全体が価格の付け方に慣れていないことなんじゃないかと思っている。周囲より安ければ売れやすいが利益は少なくなる、という市場原理のもとで、過去から現在まで「セール・割引」を主軸としたマーケットが続いてきた。安くて良いものが当たり前になってしまったぶん、モノに対する価値観だけは高いのに、高い金を払おうとしない市場になっている。 はっきり指摘して市場に介入するわけでもなく、「よくわからんけど物価は高いし賃金は相対的に安め」という状況をなんとなく受け入れている今の環境は、インフレよりマシだし国際的に見れば安定してはいる。ただ、企業比率の高い中小企業が価格相場の暗黙の足並みをやめて、商品価値に見合った適正な価格をつけることをためらわなくなったら、この現状はけっこう大きく変わるんじゃないかなと思っている。

キマリを通さない理由をプログラムで説明する

キマリを通さない理由をプログラムで説明する

「召喚士は通す」 「ガードも通す」 「キマリは通さない」 ——FF10屈指の名シーン。プレイしていなくても、なぜか知っているレベルの場面だ。私はこれを久しぶりに思い出して、アルゴリズムの説明をするのにちょうどいいなとふと思った。 あなたはどうだろう。これはキャラクターの感情の話だと思う派? それとも条件分岐の話だと思う派? 私は後者で読みたい。名前を見て通す・通さないを決めているだけなら、コードにするとかなり短い。そして短く書けるからこそ、あとで困る形になっているのが見えてくる。 「キマリは通さない」をif文にする まず素直に書いてみる。門番が判定しているのは「誰が来たか」だけなので、こうなる。 function canPass(name: string): boolean { if (name === "ユウナ") return true; // 召喚士は通す if (name === "キマリ") return false; // キマリは通さない return true; // ガードも通す }3行で終わる。ここで大事なのは、キマリだけが名指しで弾かれているという構造だ。役割で判定しているわけではない。「弱いロンゾだから」という理由が、コード上では name === "キマリ" という1行に潰れている。 そしてゲーム中には続きがある。力を示せば通れる。ビランとエンケをボコせばいいわけだ。つまり判定に状態がひとつ増える。 function canPass(name: string, defeatedGuardians: boolean): boolean { if (name === "ユウナ") return true; if (name === "キマリ") return defeatedGuardians; // 倒していれば通れる return true; }これで「キマリの問題」が表現できた。ほかの誰も defeatedGuardians を要求されていない。同じ門を通るのに、キマリだけ追加条件が乗っている。早い話、これは門のルールではなくキマリ個人に貼られた例外というわけだ。 力を示すとは何か──サイコロで定義する defeatedGuardians を true にする条件、つまり「勝てるかどうか」を決めないと、この関数は動かない。実際のゲームには戦闘のアルゴリズムがあるが、ここではサイコロバトルに置き換えて考える。 前提はこうだ。イベントバトルであり、キマリの成長でパラメータが変わるタイプなので、順当に育っていれば負ける要素は薄い。なので次のように設定する。ロンゾ(ビラン・エンケ)は2以上を出せない。1d6を振っても最大2に丸められる キマリは強いので2未満を出さない。1d6を振っても最小2に持ち上げられる ロンゾ2人の出目の合計に、キマリが1回の出目で並べば勝ちconst roll = () => 1 + Math.floor(Math.random() * 6);const kimahriRoll = (floor: number) => Math.max(roll(), floor); const ronsoRoll = (cap: number) => Math.min(roll(), cap);function kimahriWins(floor = 2, cap = 2): boolean { return kimahriRoll(floor) >= ronsoRoll(cap) + ronsoRoll(cap); }ロンゾ側の合計は最大4にしかならない。キマリは最大6を出せる。感覚的には五分五分くらいだろうと思っていたが、6×6×6の216通りを全部数えると56.0%になった。 なぜ半々からずれるかというと、合計4(両方が2)になる確率が25/36とかなり高いからだ。そのうえでキマリが4以上を出す確率は1/2。ここが勝率の大半を決めている。 ちなみに判定を >= から > に変えると、つまり同点を負け扱いにすると38.9%まで落ちる。引き分けをどちらに寄せるかだけで17ポイント動くわけで、仕様の曖昧な一文がいかに効くかがわかる。 効いているのはキマリの下限ではない せっかく変数にしたので、数字を動かしてみる。まずキマリ側の下限(floor)を変えた場合。キマリの下限 勝率1(制限なし) 55.6%2 56.0%3 65.3%4 100%下限1と2で、勝率がほとんど変わらない。「キマリはつよつよだから2未満は出さない」という設定を入れたのに、0.4ポイントしか動いていないわけだ。理由は単純で、ロンゾの合計が2になるのは1/36しかないから、下限2が効く場面がほぼ来ない。 次にロンゾ側の上限(cap)を変えてみる。キマリの下限は2で固定した。ロンゾの上限 勝率2 56.0%3 33.8%4 21.3%こちらは一気に動く。上限を2から3にしただけで勝率が22ポイント落ちる。 ということは、だよ。この勝負を決めているのはキマリの強さではなく、ロンゾ側にどれだけ蓋をしたかのほうだった。「キマリを強くする」つもりで下限をいじっても数字は動かない。バランス調整をするなら触るべきパラメータは別にある、というのがコードにしてはじめて見える。 理論上は五分五分だろうと思っていたものが、数えてみると効いている変数が違った。この手のズレは、頭の中だけで考えていると気づけない部分だと思っている。 if文の列をやめて、ルールをデータにする さて、最初のコードに戻る。あのままだと通行人が増えるたびに if が伸びていくし、「なぜ通さないのか」という理由がコードのどこにも残らない。 そこで、判定の中身を書くのをやめて、ルールをデータとして並べる形にする。 type Traveler = { name: string; role: "summoner" | "guard" | "ronso"; provenStrength: boolean; // 力を示したか };type Rule = { match: (t: Traveler) => boolean; allow: boolean; reason: string; };const gateRules: Rule[] = [ { match: (t) => t.role === "summoner", allow: true, reason: "召喚士は通す", }, { match: (t) => t.role === "ronso" && !t.provenStrength, allow: false, reason: "力を示していないロンゾは通さない", }, { match: () => true, allow: true, reason: "それ以外は通す", }, ];function canPass(t: Traveler): { allow: boolean; reason: string } { const rule = gateRules.find((r) => r.match(t))!; return { allow: rule.allow, reason: rule.reason }; }先頭から順に評価して、最初に一致したルールが勝つ。ファイアウォールやルーティングの設定と同じ考え方だ。 この形にすると変わることが3つある。 1つ目は、name === "キマリ" という名指しが消えたこと。判定しているのは「力を示していないロンゾかどうか」という条件であって、個人ではない。同じ立場の誰が来ても同じ結果になるし、キマリが力を示せば同じルールのまま通れる。 2つ目は、理由が返り値に乗ること。通さなかったときに「なぜ」が一緒に返るので、門番のセリフをそのままログにできる。条件分岐の結果だけを返す関数は、あとからデバッグするときに何も教えてくれない。 3つ目は、ルールの追加が配列への1要素追加で済むこと。関数本体を触らなくてよくなる。順序に意味がある点だけ注意が必要で、match: () => true を上に置いた瞬間に全員通ることになる。 よくある質問 なぜif文の列のままだと困るのか? 条件が個人名に結びついたままだと、同じ立場の相手が増えるたびに分岐を足すことになる。さらに「なぜ通さないのか」という理由がコードから消えるため、あとで読んだ人が仕様の意図を復元できない。ルールをデータとして持てば、条件と理由をセットで保持できる。 サイコロの勝率はなぜ50%にならないのか? ロンゾ2人の出目の合計が4になる確率が25/36と高く、そこでキマリが4以上を出す確率が1/2だからだ。この組み合わせが全体の大半を占めるため、勝率は56.0%に落ち着く。同点を負け扱いにすると38.9%まで下がる。 バランス調整をするなら、どのパラメータを触るべきか? キマリ側の下限ではなくロンゾ側の上限を触る。下限を1から2に上げても勝率は55.6%から56.0%にしか動かないが、ロンゾの上限を2から3にすると56.0%から33.8%へ22ポイント落ちる。数値の効き方は実際に全パターンを数えないと見誤る。 まとめ:条件はデータで持つ 「キマリは通さない」は、コードにすると name === "キマリ" という名指しの1行になる。短く書けるし、その場では正しく動く。ただしそこにはなぜ通さないのかという理由が残らないわけだ。 サイコロに置き換えて数えてみたら、勝率は56.0%で、効いていたのはキマリの下限ではなくロンゾ側の上限のほうだった。強さをいじったつもりで0.4ポイントしか動かないパラメータを触る、というのはコードでも現場でもよくある話だと思う。 ルールをデータとして並べて、理由を返り値に乗せる。それだけで判定は個人から条件へ移るし、力を示したキマリは同じルールのまま通れるようになる。名指しの分岐を書きたくなったときほど、その条件に名前をつけられないか考えたほうがいいだろうなと思っている。