技術記事(Zenn・Qiita)でできること
技術記事は、自分が試したことや直したことを、ほかの開発者に向けて書く文書です。
chaff は、読み手を待たせる書き出しや、生成文によく出る形を機械で見つけます。ジャンルは blog/tech です。ジャンルを決めないときも、chaff はこのジャンルで見ます。
技術記事でよく起きること
技術記事は、AI に下書きを頼むことが増えました。そのまま出すと、生成文の形が残ります。
| 書き癖 | 例 |
|---|---|
| どの記事にも当てはまる書き出し | 「近年、開発の現場ではコンテナがますます当たり前になっています」 |
| 予告だけの文 | 「ポイントは、」「重要なのは、」「正直に言うと、」 |
| 誰も言っていないことを打ち消す対比 | 「これは単なる待ち時間ではありません」 |
| 数が合わない予告 | 「直したことは以下の 2 つです」の下に、箇条書きが 3 つある |
| 行き先の無いリンク | 記事の中に無い見出しへのリンク |
| 決まり文句の結び | 「いかがでしたでしょうか」「お役に立てれば幸いです」 |
chaff が見ること、見ないこと
このジャンルで見る主なルールは、次のとおりです。
| ルール | 見つけるもの | 動く条件 |
|---|---|---|
padded-intro | どの記事にも当てはまる書き出し | いつも |
closing-cliche | 決まり文句の結び | いつも |
announcing-opener | 「ポイントは、」のような予告で始まる文の重なり | いつも(info) |
contrast-framing | 「単なる X ではなく」のような対比の重なり | いつも(info) |
colon-lead-in | コロンで箇条書きへ渡す文の多さ | いつも(info) |
ai-generated-composite | 生成文の形が、一つの記事に 3 種以上そろったこと | いつも |
announced-count-mismatch | 予告した数と、箇条書きの数の食い違い | いつも |
broken-link | 記事の中に無い見出しへのリンク | いつも |
quote-without-source | 人の言葉として引いたのに、段落に出典が無い引用 | いつも(info) |
latin-spacing | 日本語と英数字の間の空白の、付け方の揺れ | いつも(info) |
empty-conclusion | 中身の無い結び | npx chaffjs test で AI に読ませたとき |
見ないことも決めてあります。
- コードが動くかは見ません。コマンドや設定の値が正しいかは、書いた人が試して確かめます。
- 数字が本当かは見ません。「9 分から 2 分」が測った値どおりかは、書いた人が確かめます。
- 外のサイトへのリンクが開けるかは見ません。見るのは、記事の中の見出しへのリンクだけです。
- 「AI が書いた」とは判定しません。生成文に多い形が重なった所を、読み返す目印として示すだけです。
かけてみる
準備がまだなら、先に準備するを済ませます。次の記事を kiji.md という名前で保存しました。この記事は、このページのために書いたものです。
# Docker のビルドを速くした話——キャッシュという見落とされがちな鍵
近年、開発の現場ではコンテナがますます当たり前になっています。本記事では、私たちのチームが Docker のビルド時間を短くした方法を詳しく解説していきます。
## 何が問題だったのか
CI でのビルドに、毎回**約 9 分**かかっていました。
これは単なる待ち時間ではありません。**開発の速さそのものを奪う問題**です。
正直に言うと、私たちは半年ほどこの問題を見ないふりをしていました。気づけば、待ち時間で一日に何十分も溶かしていました。
## 原因
ポイントは、Dockerfile の書く順番です。
調べて分かったことは次の通りです:
- `COPY . .` を `RUN yarn install` より前に書いていた
- そのため、ソースを1行変えるだけで依存の入れ直しが走っていた
- CI では前回のキャッシュを使っていなかった
重要なのは、キャッシュが黙って捨てられていたことです。ビルドは失敗せず、静かに遅くなっていました。
## 直したこと
直したことは以下の 2 つです:
- `package.json` と `yarn.lock` だけを先に `COPY` し、依存を入れてからソースを `COPY` する
- `docker build` に `--cache-from` を付け、前回のイメージをキャッシュとして使う
- `.dockerignore` に `node_modules` を足す
さらに、ビルドの結果を `docs/build-time.md` にまとめました。詳しくは[ビルド時間の記録](#ビルド時間の記録)を見てください。
## 結果
ビルドは 9 分から 2 分になりました。単に速くなっただけでなく、チームの生産性も飛躍的に向上しました。
いかがでしたでしょうか。この記事が皆さんのお役に立てれば幸いです。
ジャンルを付けてかけます。--compact は、1 件を 2 行にまとめて出す印です。
$ npx chaffjs kiji.md --genre blog/tech --compact
kiji.md blog/tech · 日本語 ジャンルは --genre から
1:39 info 節の長さのばらつきが 25% しかありません(35% 以上ほしい)
section-length-uniformity
3:1 warning 「近年」は、どの記事にも当てはまる書き出しです
padded-intro
3:1 warning 文の長さのばらつきが 35%(36% 以上ほしい)
sentence-rhythm
9:1 info 「単なる」など、対比の枠が 1000 字あたり 3.8 個あります(1.5 個まで)
contrast-framing
11:1 info 「正直に言うと」など、予告で始まる文が 3 個あります(3 個から)
announcing-opener
11:1 warning 「section-length-uniformity、sentence-rhythm、padded-intro、closing-cliche、contrast-framing、announcing-opener、colon-lead-in」が同じ文書にそろっています(7 種、3 種から)
ai-generated-composite
15:1 info 「ポイントは」など、予告で始まる文が 3 個あります(3 個から)
announcing-opener
17:1 info コロンで箇条書きへ渡す文が 1000 字あたり 3.8 個あります(2 個まで)
colon-lead-in
20:12 info 日本語と後ろの数字のあいだを詰めています(この文書はふつう空ける。5 箇所のうち 1 箇所が違う)
latin-spacing
20:13 info 日本語と前の数字のあいだを詰めています(この文書はふつう空ける。5 箇所のうち 1 箇所が違う)
latin-spacing
23:1 info 「重要なのは」など、予告で始まる文が 3 個あります(3 個から)
announcing-opener
27:1 info コロンで箇条書きへ渡す文が 1000 字あたり 3.8 個あります(2 個まで)
colon-lead-in
27:11 warning 「2 つ」と予告していますが、すぐ下の箇条書きは3項目です
announced-count-mismatch
33:46 warning リンク「[ビルド時間の記録](#ビルド時間の記録)」が指す「#ビルド時間の記録」の見出しがこの文書にありません
broken-link
37:22 info 「だけでなく」など、対比の枠が 1000 字あたり 3.8 個あります(1.5 個まで)
contrast-framing
39:1 warning 「いかがでしたでしょうか」で締めています
closing-cliche
39:13 warning 「お役に立てれば幸いです」で締めています
closing-cliche
指摘 17 件、動いていない rule 59 件
行の頭の 3:1 は、3 行目の 1 字目という意味です。
warning は直したほうがよい所、info は読み返す目印です。info は実行を失敗にしません。
最初に出る指針
ジャンルを決めると、chaff は結果の最初にそのジャンルの指針を出します。よい技術記事が満たすことを、原稿を確かめる問いの形で並べたものです。その下に、このジャンルで特に効く rule の名前が 1 行で出ます。
問いの多くはルールでは確かめられないので、指摘より先に読みます。 AI に書き直させるときも、AI は同じ指針に沿って書きます(AI にジャンルの指針を渡す)。
$ npx chaffjs kiji.md --genre blog/tech
指針: 技術ブログ(blog/tech)
下の指摘より先に、原稿がこれを満たしているかを確かめてください。
- 冒頭で、主張を 1 つに絞って言い切っているか(何が分かり、何ができるようになる記事か)
- 手順とコードが、書いてあるとおりに実行して同じ結果になるか
- 使ったバージョン(言語・ライブラリ・OS)と、試した日付を書いているか
- 試してうまくいかなかったこと、制約、前提を書いているか
- 結びが本文の言い直しではなく、次に読むもの・試すものを示しているか
このジャンルで特に効く rule: closing-cliche, empty-conclusion, padded-intro, paragraph-length-variance, quote-without-source, rule-of-three, section-length-uniformity, sentence-rhythm
chaff.yaml の guide: で書き換えられます。出さないときは --no-guide。
════════════════════════════════════════════════════════════
kiji.md blog/tech · 日本語 ジャンルは --genre から
…
パスや内容から推測したジャンルと、既定のジャンルでは、指針を出しません。違う種類の文書の指針は、かえって読み手を迷わせるためです。
--compact と --no-guide でも出しません。指針の文は、チームが chaff.yaml の guide: で書き換えられます(ジャンルの指針を変える)。
指摘の意味と直しかた
| 行 | 指摘 | 意味 | 直しかた |
|---|---|---|---|
| 3 | padded-intro | 「近年、」は、どの記事にも書ける書き出しです | 何に困っていたかから書き始めます。「CI のビルドに毎回 9 分かかっていました」 |
| 9、37 | contrast-framing | 「単なる X ではありません」と、誰も言っていないことを打ち消しています | 打ち消しを消し、言いたいことだけを書きます |
| 11、15、23 | announcing-opener | 「正直に言うと」「ポイントは」「重要なのは」と、予告で文を始めています | 予告を消し、中身から書き始めます |
| 17、27 | colon-lead-in | 「次の通りです:」と、コロンで箇条書きへ渡す文が続いています | 箇条書きの項目がつながっているなら、文に戻してつながりを書きます |
| 20 | latin-spacing | ほかは「9 分」と空けているのに、「1行」だけ詰めています | 「1 行」と空けて、記事の中で揃えます |
| 27 | announced-count-mismatch | 「2 つ」と書いたのに、箇条書きは 3 つあります | 数か箇条書きの、違うほうを直します |
| 33 | broken-link | 「ビルド時間の記録」という見出しが、記事にありません | 見出しを足すか、リンクを外します |
| 39 | closing-cliche | 結びの決まり文句です | 消して、読み手が次にすることで終えます |
| 1 | section-length-uniformity | 節の長さが揃いすぎています | 中身の多い節を厚くします。長さを合わせるために文を足しません |
| 11 | ai-generated-composite | 上の形が、一つの記事にいくつもそろいました | 部分直しで足りなければ、記事を書き直します(下の節) |
「一日に何十分も溶かしていました」「静かに遅くなっていました」のような比喩も生成文に多い形です。この記事では、chaff はこれを指摘していません。機械は、書き癖をすべて見つけるわけではありません。
生成文の形が多いときは書き直す
指摘を一つずつ消しても、太字と箇条書きが続く記事は生成文に読めます。そのときは、節ごとに書き直します。手順は AIっぽさを直す にあります。
| 直し方 | 直すもの | 向いているとき |
|---|---|---|
| 部分直し | 指摘された所だけ | 中身も構成もよく、言い回しだけが気になるとき |
| 書き直し | 節ごとに、記事の全体の形 | 部分直しをしても、まだ生成文に読めるとき |
書き直したあとは、npx chaffjs compare kiji.md 書き直した記事.md で、数やコマンドが落ちていないかを確かめます。書き直しの例と compare の画面も、同じページにあります。
意味を読む検査は AI に頼む
「結果」の節の結びに中身があるかは、意味を読まないと決まりません。
npx chaffjs test は、機械で絞り込んだ箇所だけを AI に送ります。
--dry-run を付けると、送らずに、送る箇所を確かめられます。
npx chaffjs test kiji.md --genre blog/tech --dry-run AI に送る箇所を見せる(送らない)
画面の前半は、機械の検査と同じです。その後に、次が出ます。
kiji.md 全 24 文のうち 1 箇所を送ります(API は呼んでいません)
1 箇所 結びに中身がない (機械で絞り込み済み)
最初の 1 件に送る文章:
ビルドは 9 分から 2 分になりました。単に速くなっただけでなく、チームの生産性も飛躍的に向上しました。
いかがでしたでしょうか。この記事が皆さんのお役に立てれば幸いです。
────────────────────────────────────────────────────────────
合計 1 箇所を送ります。--dry-run なので API は呼んでいません。
送り先: anthropic / claude-opus-5(認証なし)
実際に AI に読ませるには、API key が要ります。置き方は README にあります。
chaff.yaml の始め方
技術記事を置くフォルダに、次の chaff.yaml を置きます。
genre: blog/tech
language: ja
この chaff.yaml を置くと、npx chaffjs kiji.md --compact だけで、上の指摘が出ます。読み返す目印(info)が要らないルールは、rules: に off と書いて止めます(section-length-uniformity: off など)。チームで書き方を決めたら、チームの表記ルールを決める を読んで書き足します。
次に読むページ
- 生成文の形を直す手順は、AIっぽさを直す にあります。
- 一箇所だけ黙らせる方法と、ルールをゆるめる方法は、業務報告書でできること にあります。
- ルールごとの説明は、リファレンス にあります。
- ほかの種類は、文書の種類ごとにできること に戻って選びます。