Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

推敲スキルを作ってみている

claudeに文章術の基本を教え込んでみている。今のところ結構良い感じに動いてくれてる感じがする。

やったこと

  1. 読者を1人に固定する
  2. 文章のテンプレートを1つ選ぶ (PREP法など)
  3. テンプレートの順に並べ、結論を先頭に置く
  4. 読者の判断に要らないものを削る
  5. 情報の強さを振り分け、強調を張り直す
  6. セルフチェックを通す
  7. 文単位の不自然さが残っていれば /yomiyasu を呼ぶ

この順にやってくれと指示するだけ。結構しっかりと読みやすくなる。個人的には1と3、5が結構効いてる感じがする。yomiyasuはとりあえず指定しているけど正直どれくらい効いているのかはよくわかってない(実は外しても問題ないかもしれない)。

使い方

以下のスキル全文を ~/.claude/skills/suikou/SKILL.md として保存して、あとは適当に PR作成して。本文は suikou して とか言えばOK。なんなら自分は pr-create スキルに最初から組み込んでいる。

スキル全文

---
name: suikou
description: PR本文・レビューコメント・Slackの文面・コミットメッセージ・調査メモを、読者を固定したうえで構成から推敲するスキル。「推敲して」「PR本文を書き直して」「この文章の構成を直して」「レビューコメントを整えて」という依頼や、これらの文面を新しく書くときに使用する。結論を先頭に置き、定番の型を1つ選んで並べ直し、拾い読みで要約になるよう強調を張り直し、読者が既に知っている前提と聞かれていないことを削る。文単位の不自然さ(非生物主語・比喩動詞・絵文字・文末コロン等)の除去は yomiyasu に渡す。
argument-hint: "[推敲対象のテキストかファイルパス] [--kind pr|commit|review|slack|notes]"
---

# suikou

文章を構成から推敲する。**読者を1人に固定し、型を1つ選んでその順に並べ、結論を先頭に出し、
読者の判断に要らない段落を削る。** 1文ごとの作り(非生物主語・比喩動詞・記号・文長)は
`yomiyasu` が担当するので、残っていれば最後に `/yomiyasu` を呼ぶ。

出力は書き直した結果だけにする。何をどう直したかの解説は、聞かれたときだけ出す。

## 手順

以下の節は、この手順と同じ順に並んでいる。

1. 読者を1人に固定する
2. 型を1つ選ぶ
3. 型の順に並べ、結論を先頭に置く
4. 読者の判断に要らないものを削る
5. 情報の強さを振り分け、強調を張り直す
6. セルフチェックを通す
7. 文単位の不自然さが残っていれば `/yomiyasu` を呼ぶ

## 1. 読者を1人に固定し、その人が知っていることは書かない

読者を決める目的は、既に知っている前提を書かないためにある。出力物の種類から、
下の定義で読者を決める。種類が分からなければ聞く。

下の定義は一例なので、「書かない(共有済みの前提)」はチームの状況に合わせて書き換える。

### PR本文

- **読者**: 同じ開発チームのメンバー。ただしこのPRのタスクについては初見
- **書かない(共有済みの前提)**
  - プロダクトの基本概念、日常的に触っている画面
  - 略語・チーム内呼称
  - チームが扱う業務ドメインの基礎知識
  - チームで使っている言語・フレームワークの一般知識
- **書く**
  - このPRが解こうとしている問題と、きっかけになった仕様やチケット
  - 変更前挙動・変更後挙動・影響範囲(フィーチャーフラグ・ほかの機能への波及)
  - 設計判断で迷った点と、他の選択肢を採らなかった理由
  - レビューで特に見てほしい観点、動作確認済みの範囲
- **口調**: 同僚に対する普通の口調。「〜させていただきました」も「〜っす」も使わない。
  断定で書ける箇所は断定で書く
- **やらない**
  - 「本PRでは〜を実装しました」のような自己紹介的な前置き
  - 差分から自明な変更カタログ(ファイル・関数の羅列)
  - 変更範囲外の背景説明

### コミットメッセージ

- **読者**: 未来の自分と、`git log --oneline` を眺めるチームメンバー
- **1行目**: 何が変わったかを動詞始まりで簡潔に書く。理由はbodyへ回す
- **body(必要なら)**: なぜこの変更が必要か。実装の詳細ではなく判断の背景を書く

### レビューコメント・相談・依頼(Slack含む)

- **読者**: これから手を動かす相手。何をしてほしいかを最初に知る必要がある
- 型は2節の「依頼を先頭へ繰り上げた問題-解決策-利得」を使い、結論に「何が起きるか」を含める

### 調査ログ

- **読者**: 3ヶ月後に同じ問題にぶつかる自分とチームメンバー
- **書く**: 何を調べたか(クエリ・grep対象)、何がわかったか、結論、参照箇所(ファイル:行)
- **書かない**: 途中で捨てた仮説の全部、ツール出力の生ログ

### 説明・解説(会話での回答)

最初の段落(1〜2文)には、ファイルパス・クラス名・関数名・型名・ライブラリ名・
コードブロックを入れない。「何をするものか / なぜ必要か / どんな振る舞いか」を
ドメインの言葉で書き、実装用語は2段落目以降で使う。

依頼に「本質」「要点」「概要」「ざっくり」「変更量が多くて見えない」が含まれる場合は、
**回答全体を振る舞い・能力・意思決定のレベルに留める。** 実装識別子は並べず、
詳細な差分カタログは「詳しく」と続けて聞かれたときに初めて出す。

## 2. 型を1つ選び、決めるまで書き始めない

思いついた順に並べると、読み手は何の話かを最後まで掴めない。次の型から1つ選ぶ。

| 型 | 順序 | 向いている場面 |
| --- | --- | --- |
| 何-それが何-それで何 | トピックの提示 → 重要である理由 → どう活用するかの提案 | 調査結果の共有、新しく分かったことの報告 |
| PREP | 要点 → 理由 → 例示 → 要点 | 質問への回答、判断の説明 |
| 問題-解決策-利得 | 問題の提起 → 解決策の提示 → 付随する利得 | レビュー指摘、改善提案、相談 |
| 比較-対比-結論 | 類似点 → 相違点 → 結論 | 選択肢の検討、既存実装との突き合わせ |

**相手に何かしてほしい文章(レビュー指摘・相談・依頼)は、問題-解決策-利得の先頭に依頼を繰り上げる。**
並びは「何をしてほしいか → なぜか(何が問題か)→ 具体的にどうするか」になる。

- NG「〜について相談です。→ 調べたら〜でした。→ 原因は〜です。→ なので〜したいです」
- OK「〜に変えられませんか。→ いま〜という問題があります。→ 原因は〜。→ やり方は (a)(b)(c)」

## 3. 結論を最初の1〜2文で言い切る

**読み手が最初の段落だけで判断できる状態にする。** 経緯・調べた範囲・前提の説明は結論のあとに置く。

- NG「〜を確認したところ、〜という構造になっており、そのため〜の可能性があります」
- OK「〜が起きる可能性があります。原因は〜です」

判断を求める文(レビュー指摘・相談・提案)では、結論に**何が起きるか**を含める。
「実装が〜になっています」は事実であって結論ではない。「〜すると候補が減ります」が結論になる。

前置き(「1点相談です」「確認したところ」「〜について説明します」)は、どの型にも置き場所が無いので消す。

## 4. 「無いと読み手の判断が変わるか」で段落を削る

**各段落にこの問いを当て、判断が変わらない段落は消す。** 特に次の3つは残りやすい。

- 自分が調べた副産物、他に気づいた点、対応不要と判断した論点。1つの文書が答える問いは1つに絞り、
  それ以外は別の文書に分けるか書かない
- 読者が既に知っている前提(1節の「書かない」)
- 言い訳と、差分から自明なカタログ

## 5. 情報を本文・括弧・折りたたみに振り分け、太字は要約になる箇所だけに張る

全部を同じ強さの地の文で書くと、のっぺりして長く見える。各情報を次のどれかに置く。

| 段階 | 置くもの | 書き方 |
| --- | --- | --- |
| 本文 | 判断に要る結論・影響・理由 | 地の文。段落の先頭を太字の主張にする |
| 括弧 | 細かい判断の理由、補足の数値 | 1文に収める |
| 折りたたみ | 根拠そのもの(grep結果、DBの値、入力データ、再現手順) | `<details>` に入れる(PR本文・Markdownのとき) |

本文に置くかは「無いと判断が変わるか」で決め、折りたたむかは「確かめたい人だけが見るか」で決める。

強調は、**太字だけを上から拾い読みしたときに全体の要約になる**よう張る。この基準を満たさない
強調は外す。目安は1段落に1箇所まで、1箇所は1文以内。

- 強調してよい: 結論、影響、判断してほしいこと、方針
- 強調しない: 識別子、ファイルパス、専門用語、「重要」「注意」のような合図

## 6. セルフチェックで1つでもNOなら、文ではなく並びを直す

出す前に全部通す。項目は手順の順に並べてある。

- [ ] 読者を1人に決め、その人が既に知っている前提を説明していないか
- [ ] 型を1つ選び、その順に並んでいるか
- [ ] 相手に何かしてほしい文章なら、依頼が先頭にあるか
- [ ] 最初の1〜2文だけ読んで、読み手が判断できるか
- [ ] 前置き(「確認したところ」「1点相談です」「本PRでは」)が残っていないか
- [ ] 1つの文書が答える問いが1つに絞れているか
- [ ] 各段落は、無いと読み手の判断が変わるか
- [ ] 太字だけ拾い読みして要約になるか。識別子・専門用語を強調していないか

useRefのcurrentをgetterで定義してアクセスされるまで計算しない

const latestCartItems = useLatest(cartItems);

const hasOutOfStockItemRef = useRef({
  get current() {
    return latestCartItems.current.some(item => !item.inStock);
  },
}).current;

思いつけば単純なんだけどコレでいける。

なお、useMemoで書いたほうが直感的でシンプルに理解できる

const latestCartItems = useLatest(cartItems);

const hasOutOfStockItemRef = useMemo(
  () => ({
    get current() {
      return latestCartItems.current.some((item) => !item.inStock);
    },
  }),
  [],
);

ChatGPTにパーソナルトレーナーになってもらう

めっちゃ簡単なアプリを作って1ヶ月半ほどトレーニングしているのだが、今のところ不満がほぼない。

Muscle Memory

動作原理、コンセプト

(動作原理ってほどでもないが)

このアプリの基本コンセプトは 「プロンプトと記録をまとめて保存してしまおう」 って感じ。とにかくシンプル。記録を外部に保存しておいて、使うときは記録ごと全文送信する。ハルシネーションもほとんど起きてない。

これは筋トレの記録です。

このプロンプトが送られてきたら、まず過去の記録を分析し、本日のトレーニングメニューを提案してください。その後、記録の更新を待ってください。

(略)

=====

records:
  - date: 2026-07-14
    exercises:
      - name: ワンハンドダンベルローイング
        weight: 24kg/手
        reps: [10, 10, 10]
        rest: 2分
        note: 左→右で実施

こんな感じのをChatGPTに送信すると、プロンプトに従ってメニューを考えてくれる。あとはやるだけ。

使い方

細かい使い方はこんな感じ。

  1. アプリを開く
  2. 「コピーしてChatGPTを開く」を押す
  3. ChatGPTが立ち上がるので、プロンプトのところで貼り付ける
  4. 今日のメニューが生成される
  5. それの通りにメニューをこなす

超カンタン。これだけで、前回までの記録を踏まえて今日やるべきメニューを考えてくれる。めっちゃ便利。さらに、「今日は別の種目にしてみようかな〜」と相談すればそのメニューも考えてくれる。

youtu.be

記録するほうもカンタン。

  1. 記録内容を適当に書く (結構いい感じに解釈してくれる)
    • 「インクライン 15 15 12 腕立て 20 20 15」とか書くと「インクラインベンチプレス 20kg 15,15,12」「腕立て伏せ 20,20,15」みたいによしなに解釈してくれる
  2. yamlが吐き出されるのでコピーする
  3. アプリに戻って「貼り付けて記録」を押す
  4. ペーストを押す

割と雑に書いても結構ちゃんと記録形式に直してくれる。

試行錯誤とか

当初はほんとうに 記録を出力する時にも全文出させて丸ごと保存していた。 まさに脳筋仕様。ただ、これだと3週間分くらいの記録で出力限界に引っかかってしまった。なので仕方なく差分だけ出して保存するようにした。出力時間も短くなったし今のところはこれで困ってない。

また、MCPにする計画もしていたのだが(貼り付けが手間なので)、これはあまりうまくいかなかった。 実際に「Google driveから前回の記録を読み出してそれを元にメニューを考案、保存も勝手にやってくれる」って構成で作ってみたが、 driveへの接続時間が長くて使いものにならなかった。 (←書いてて思ったが、毎日定時で提案してくれるようなアプリであればdriveへの接続時間も問題にならないし、それで良くないか?)

グラフ機能も一応ある

yamlで保存してあるのでグラフもシュッと作れた。なかなか便利。まあそこまで見てはないけどたまにみてモチベが上げられてる。

まとめ: どの筋トレアプリより続けやすい

筋トレアプリは「入力しづらい」「今回のメニューを考えるのがめんどい」という問題がずっとあった。このアプリはそれらをAIを使うことで解決できている。シンプルなアイデアだったがちゃんとワークして嬉しい。みんなも筋トレやろう!

Gridfinityがよい感じ。自分だけの最強収納をつくる。

収納、好きですか。みんな大好きですよね。僕もです。

そして3Dプリンタ界隈にはGridfinityという最強ツールが存在します。今回はそれによっていかに収納が楽になるのか紹介します。

Gridfinityとは?

Gridfinityは、3Dプリンタで作れる収納用品のための規格です。

42mm角の基本単位グリッドと、グリッド上に載せる収納ケースの底面などが規定されています。

実際に印刷したグリッドを設置したのがこんな感じです↓ (ケースと同じ色なので分かりづらいですが…)

上に置くパーツは底面さえ規格に則っていればサイズ含めて自由に設計できるのが最大のポイントです。持ってるノギスがシンデレラフィットするケースを作って格納するなどもできます。

例えば「持ってる工具を入れるために1x4のサイズの箱を印刷しよう」とか「長ものを立てて入れるために1x1で高めのケースを印刷しよう」みたいな感じですね。

実際に作ったもの

僕はあんま凝ったことはせず、単にベースプレートに箱を載せるだけのシンプルなものにしてます。これだけでもかなり便利です。

グリッドに沿わせて図示するとこんな感じになってます。

9x4のベースの上に1x1や4x3、3x3みたいな異なるサイズのケースを積んでる感じです。

サイズが異なるものを重ねたいときは、フタを作っておくと積み重ねできて便利です。

僕はやってないですが、机の中の収納とかもこれで整理しやすいそうです。

便利ツール

グリッドフィニティジェネレータ | インタラクティブツール

これを使うと幅、奥行き、高さの異なるbinがサクッと作れます。これだけで8割くらいはカバーできてしまいます。

ラベル付きbin

これ印刷しておいてペンとかでラベルを書くとネジとかを収納するのに便利です

(実際に印刷したのがこれだったか忘れたんですが)

stackable lid これ印刷しておくとフタの上にbinを積めるので便利です

3Dプリンタを買った

3Dプリンタを買った

創作欲が爆発して色々と作ってしまっている

1. ペグボードを斜めに固定するパーツ

前面

背面

ペグボードは基本的にグッズを飾るために使ってるので、机に斜めに設置しないと見づらい問題があった。けど、デフォルトのクランプだと斜めに固定しようとするとやや不安定になったので、パーツを追加して斜めに固定できるようにした。

2. 卓上カレンダーフレーム

電子ペーパーで卓上カレンダーをつくる - Panda Noir

一昨年作った卓上カレンダーのフレームを、CAD書いて自作してみた。

前面

背面

中身

ちなみに昔のバージョンがこれ↓

昔のバージョン

…昔の方が良かったか?

3. ウェブカメラカバー

備え付けのカバーはフタ式なので、いつもフタがどっかに行く問題があった。スライドカバーにすることでフタがなくなる心配が消えたのでかなり便利になった。

(なんかライトの設定ミスって変な色味になってしまった)

使ったモデル: Elgato Facecam Privacy Shade - Free 3D Print Model - MakerWorld

まとめ: めっちゃ楽しい

CADで書いたものが意図通りに作れるとすごい興奮するし、印刷している様子を眺めてるだけでも結構楽しい。しばらくは3Dプリンタで遊ぶ日々が続きそう(3連休ほぼ全部使った)。

上で紹介したのは実用のものだけど、実は3Dプリントを快適にするためのグッズも結構印刷している。

これだけでも結構楽しい。何も作りたいものない人でもこれらは作れるのでおすすめ。