コマンド

chaff のコマンドとオプションを一覧にしました。どれも、何が起きるかを横に一言添えてあります。自分で打つときは、chaff の前に npx を付けて npx chaffjs と打ちます。

コマンドの一覧

npx chaffjs --help で出る一覧を、表にまとめました。 npx chaffjs init --help のようにコマンドの後に --help を付けると、そのコマンドの行だけを出し、何も実行しません。

コマンド何が起きるか
npx chaffjs <file|dir|glob>...検査します。設定も API key も要りません
npx chaffjs .この場所の Markdown を全部見ます
npx chaffjs initchaff.yaml を作ります(端末ならジャンルを尋ねます。--genre でも決まります)
npx chaffjs init --plugin <名前>YAML だけのルールの束 chaff-plugin-<名前>/ のひな形を作ります(プラグインを作る)
npx chaffjs plugin-test [フォルダ]プラグインの各ルールを、そのルールの例にかけます。before は指摘され、after は指摘されないことを確かめます
npx chaffjs explain <rule>そのルールの意図と根拠を読みます
npx chaffjs genresジャンルの一覧を、何向けかと一緒に出します
npx chaffjs --versionchaffjs と、同梱の言語パッケージの版を出します
npx chaffjs rulesルールの一覧を、グループごとに表で出します。いまの段階もわかります
npx chaffjs rules --jsonいまの設定とルールの説明を JSON で出します。AI に渡す用です
npx chaffjs relax|strict|off <rule>ルールの強さを変えます。--why "理由" を添えます
npx chaffjs enable <rule>試験中のルールを 1 つだけ動かします(chaff.yaml に <rule>: normal と書きます)。設定 を見てください
npx chaffjs baseline <dir>いまある指摘を棚上げします
npx chaffjs suppressions <dir>stet で黙らせている指摘を数えます
npx chaffjs tree <file>文書を番地の付いた木にします。--format sexp か --format json で形を選びます
npx chaffjs cite <原文> <引用.json>回答の引用が原文にあるかを確かめます
npx chaffjs cite --scaffold <file>出典の無い引用を、出典を書き込む引用.json のひな形にします
npx chaffjs cite --url <URL> <引用.json>引用が Web のページにあるかを確かめます
npx chaffjs compare <前> <後>書き換えで事実(数・日付・URL・コード・名前・引用など)が落ちても足されてもいないかを確かめます
npx chaffjs facts <file>compare が照合する事実を、書き直す前の控えとして一覧にします
npx chaffjs ai-score <file>...AI らしさを低・中・高で簡易判定します。生成文に多い目印を、同じジャンルの人の文書と比べます。書いたのが AI かどうかは判定しません
npx chaffjs outline <file> [<後>]見出しの構成を出し、形(見出しの数・節の平均の長さ・箇条書きの割合・太字)を測り、構成を人の記事と比べます。2 つなら前と後を並べます
npx chaffjs fix-plan <file>書き直す人や AI に渡す「直す計画」を出します。指摘をルールごとにまとめ、直す方向と、直したあとの確かめのコマンドを付けます。--json で JSON に、--depth で書き直してよい深さを決めます
npx chaffjs grade <items.jsonl>model の出力を JSONL のまま採点します(指摘の率・事実・引用・合否)。何も送りません。--out <results.jsonl> で出力ごとの結果を書き、--json でまとめを JSON で出します
npx chaffjs skillClaude Code の skill を入れます。--global を付けると ~/.claude/ に入れます
npx chaffjs feedback <file> --rule <rule>誤った指摘や見逃しの報告の下書きを作ります。何も送りません
npx chaffjs test <file|dir>...意味を読む検査も動かします。API key が要ります
npx chaffjs eval <dir>手元の文書で閾値を測り直します

検査のときに付けられるオプションは、次のとおりです。

オプション何が起きるか
--compactエンジニア向けの 1 行形式で出します
--no-guideジャンルを決めたときに最初に出す、ジャンルの指針を出しません(ジャンルの指針を変える)
--watch保存のたびに見直し、変わったところだけ出します
--experimental試験中のルールも動かします
--genre <ジャンル>この回だけジャンルを決めます。chaff.yaml より優先します
--show-baseline棚上げした分も含めて全部見ます
--sarif <path>指摘を SARIF で書き出します。GitHub の PR の行に出すためです
--dry-runtest と一緒に使い、AI に送るものを見せるだけにします。API は呼びません
--include <glob>フォルダの中の Markdown のほかに、glob に合うファイルも検査します(--include "*.yaml")。設定 を見てください

tree と cite は 構造と引用 で、--sarif は CI で、grade は AI の評価(AI evals)に使う で詳しく説明します。

1 行ずつ短く見る

--compact を付けると、1 件の指摘を 2 行で出します。上の行は「行:列」「重さ」「本文」で、下の行はルール名です。

$ npx chaffjs sample.md --compact

sample.md   blog/tech · 日本語   ジャンルは既定から

  7:1     info    この文に中黒が 6 個あります(5 個まで)
                  no-nakaguro-parallel
  9:1     info    この文は 166 文字あります(160 文字まで)
                  max-sentence-length

指摘 2 件、動いていない rule 59 件

最後の行は、指摘の数と、動かなかったルールの数です。

書きながら見る

--watch を付けると、保存するたびに見直します。出すのは変わったところだけです。全件を出し直すと、何が変わったのか分からなくなるためです。

$ npx chaffjs article.md --watch

  1 ファイルを見ています。いまの指摘は 2 件です。
  保存するたびに、変わったところだけ出します。止めるには Ctrl-C。

08:21:41  article.md  ✓ 2 → 1 件   (-1 bold-density)
08:21:44  article.md  ✗ 1 → 2 件   (+1 closing-cliche)

✓ は指摘が減ったこと、✗ は増えたことを表します。括弧の中には、増えたり減ったりしたルールの名前が出ます。

試験中のルールも動かす

ほとんどのルールは、何も付けなくても動きます。試験中のルールは、まだ人の文書で測っていない新しいルールだけです。 --experimental を付けると、それも動きます。

npx chaffjs report.md --experimental

試験中のルールは、人の書いた文書で測ると既定に入ります。どの段で動くかは数で決まります(リファレンス)。

ルールの中身を見る

explain は、ルールが何を見て、なぜそうするのかを出します。 strict normal relaxed の裏にある数字と、いまの強さも出ます。

$ npx chaffjs explain max-sentence-length

  一文が長すぎる   (max-sentence-length)

  長い文は、読んでいるうちに主語を見失います。

  直しかた: 接続助詞のところで 2 文に割ってください。それだけで読めるようになります。

  書き直しの深さ: light(語と文を直す。構成と文体は残す)。chaff fix-plan --depth でこれより浅い深さを選ぶと、計画はこのルールを直さず、名前だけを挙げます。

  設定できる値:
    strict   一文 70 字まで
  → normal   一文 100 字まで
    relaxed  一文 140 字まで
    off      見ない

  この数字は 既定 のものです。ほかに technical / blog / blog/essay / business / business/email / docs / legal / legal/statute / legal/judgment / academic で別の数字を持っています。

  いまは normal です。

  変える:  npx chaffjs relax max-sentence-length --why "理由"

コマンドでルールを変える

relax strict off は、chaff.yaml を開かずにルールの強さを変えます。 relax はゆるめ、strict はきびしくし、off は止めます。番号の抜けのように数えるもののないルールでは、relax は指摘を消さずに一段軽くします(数えるもののないルール)。

$ npx chaffjs relax bold-density --why "図の説明で太字を多用するため"
bold-density を relaxed にしました(…/chaff.yaml)

chaff.yaml には、ルールの説明のコメントと、日付・理由・名前が入ります。

rules:
  # 太字の使いすぎ
  # 太字は読者の目を止める道具です。多用すると、どこも目立たなくなります。
  bold-density: relaxed # 2026-09-28 図の説明で太字を多用するため / isamu

chaff.yaml にもともと書いてあったコメントは壊しません。既に理由があるルールを変えるときは、--why で新しい理由が要ります。古い理由が新しい値に残ると、履歴が嘘になるためです。

$ npx chaffjs off bold-density
bold-density には既に理由が書かれています:
  2026-09-28 図の説明で太字を多用するため / isamu
値を変えるときは --why で新しい理由を書いてください。

ジャンルの一覧を見る

genres は、書けるジャンル(文書の種類)を、群ごとに、何向けかと一緒に出します。

$ npx chaffjs genres

  ジャンル(文書の種類)を選ぶと、その種類の書き方に合わせて見ます:

  技術文書
    technical/spec          仕様書・RFC・設計文書。読み手に間違えさせないための文書
    technical/readme        README と開発者向けの説明

  ブログ
    blog/tech               技術記事。ジャンルを決めないときはこれで見ます
    blog/essay              自分の考えを書くブログのエッセイ
    blog/owned-media        会社や団体が読者に向けて出す記事

  ビジネス文書
    business/proposal       提案書・企画書・計画書
    business/report         報告書・白書・社内文書
    business/email          仕事のメールと手紙
    business/press-release  プレスリリースと、お知らせ
    business/meeting-notes  議事録・議事要旨

  法務
    legal/contract          契約書・利用規約・プライバシーポリシー
    legal/statute           法令・規則・社内規程・通達
    legal/judgment          判決文・決定
    legal/patent            特許の明細書と請求項

  説明書
    docs/manual             使い方の説明・手順書・ヘルプ
    docs/faq                問いと答えを並べたページ
    docs/glossary           用語と、その説明を並べたページ

  学術
    academic/paper          論文と、その要旨

  文学
    literature/fiction      小説・物語
    literature/essay        文学としての随筆。ブログのエッセイは blog/essay
    literature/poetry       詩・短歌・俳句
    literature/play         戯曲・脚本

  話し言葉
    speech/address          読み上げるために書いた演説・挨拶
    speech/transcript       話したことを書き起こした記録(会見・国会の会議録)

  この実行だけ:    npx chaffjs --genre legal/contract 契約書.md
  この場所に決める: npx chaffjs init --genre legal/contract   (chaff.yaml の genre に書きます)

--genre を付けると、その回だけジャンルを決められます。chaff.yaml の genre より優先します。画面の 1 行目は ジャンルは--genreから になります。

いつも同じジャンルにするには、npx chaffjs init --genre <ジャンル> で chaff.yaml を作るか、chaff.yaml の genre に書きます。ジャンルごとに見ないルールと足すルールは、ジャンルのページにあります。

いまある指摘を棚上げする

既にたくさんの文書があると、最初にかけたときに指摘が大量に出ます。全部直してから始めるのは無理なので、baseline でいまある指摘を棚上げします。

$ npx chaffjs baseline docs/

  1 ファイルを走査しました。

  0 件の指摘を .chaff-baseline.json に記録しました。
  以後、これらは報告されません。新しく増えたものだけが出ます。

  .chaff-baseline.json を commit してください。

以後は、棚上げした指摘は出ません。画面の 1 行目に、棚上げした数が出ます。

$ npx chaffjs docs/ --compact

docs/a.md   technical/readme · 日本語   ジャンルはパスから


指摘 0 件、動いていない rule 68 件

棚上げした分も見たいときは、--show-baseline を付けます。

$ npx chaffjs docs/ --show-baseline --compact

docs/a.md   technical/readme · 日本語   ジャンルはパスから


指摘 0 件、動いていない rule 68 件

CI に入れるときの使いかたは、CI で説明します。

黙らせた箇所を数える

stet で黙らせた指摘は、suppressions で数えられます。同じルールを何度も黙らせているなら、ルールを変える道を選ぶ時期です。

$ npx chaffjs suppressions docs/

  抑制されている指摘: 7 件

  bold-density                7 件  ← 設定の見直しを検討してください
      docs/g1.md, docs/g2.md, docs/g3.md ほか 4 ファイル
      理由: 用語集なので太字が多いのは意図的
      ルールごとゆるめる: npx chaffjs relax bold-density --why "..."

  理由が書かれていない抑制: 1 件
      docs/x.md

理由を書かずに黙らせた箇所も、ここに出ます。

Claude Code の skill を入れる

skill は、Claude Code に chaff の使い方を教える skill を入れます。かけ方、指摘より先にジャンルの指針を読むこと、指摘の読み方、直す・stet・relax --why の選び方、rules --json での設定が入っています。食い違う数字や日付の直し方、chaff test、生成された文章らしさの直し方、tree と cite、grade も入っています。 --global を付けなければこのリポジトリの .claude/skills/chaff/ に、付ければ ~/.claude/ に入ります。

$ npx chaffjs skill
Claude Code の skill を書きました: …/.claude/skills/chaff/SKILL.md
Claude Code を開き直すと /chaff で使えます。

もう一度実行すると、新しい版に置き換えます。中身の違うファイルは手で直したものかもしれないので、--force を付けないと置き換えません。

誤った指摘や見逃しを報告する

chaff が誤った指摘をしたとき、言うべきことを言わなかったときは、feedback が報告の下書きを作ります。

npx chaffjs feedback a.md --rule max-sentence-length --line 42   誤った指摘
npx chaffjs feedback a.md --missed --line 42                     見逃し

下書きは .chaff-feedback.md に書きます。中身は、版と OS、一つの指摘とその前後の 2 行ずつ、chaff.yaml のその rule の設定だけです。文書の全体は載せないので、読んでから送るかを決めます。chaff.yaml 全体も載せたいときは --with-config を付けます。送り方(gh issue create -R isamu/lab --title … --body-file .chaff-feedback.md、または題だけを載せたリンク)も画面に出ます。 chaff は何も送りません。届いた報告は、そのまま試験と修正になります。公開してよい文書は、指摘ごとの判定と一緒に isamu/chaff-corpus へ PR で足すこともできます。公開できない文書は URL とハッシュだけで記録できます。chaff-corpus の CI が、リリースごとにそれらの文書で chaff を流します。

書き換えで事実が落ちていないか確かめる

AI っぽい文章を、人の書いた文章へ大きく書き換えたいことがあります。言い回しを変えるだけでなく、文を組み替え、段落を入れ替え、要らない前置きを捨てる書き換えです。書き換えるのは AI に任せられます。けれども、大胆に書き換えるほど、人が読んで見つけるのは難しくなります。数字が一つ消えた、日付が一日ずれた、URL が抜けた、元に無い数字が増えた、といったことです。

compare は、その見落としを機械が拾う安全網です。書き換える前と後から、事実を同じ読み方で取り出して比べます。取り出す事実は、数、日付、時刻、URL、コード、固有名詞、引用、見出し、条項の参照、脚注です。閉じの引用符で開いた引用(”Visit the page.”)も引用として読むので、引用符を直しても、足された引用ではなく書き方だけ変わった引用になります。位置は見ないので、事実が段落ごと動いても問題にしません。判定に AI は使わず、同じ二つの文書からはいつも同じ結果が出ます。chaff は比べるだけで、書き換えません。

$ npx chaffjs compare before.md after.md
before.md → after.md

✗ 落ちた事実 2 件(before.md にあって after.md に無い)
  数: 1,200円  (before.md:3)
  URL: https://example.com/price  (before.md:3)

✗ 足された事実 1 件(after.md にだけある)
  数: 1,300円  (after.md:3)

i 書き方だけ変わった事実 3 件
  見出し: 料金改定のお知らせ → 料金が変わります  (1 行目 → 1 行目)
  日付: 2026年4月1日 → 2026/4/1  (3 行目 → 3 行目)
  数: 1,000円 → 1000円  (3 行目 → 3 行目)

照合した事実 5 件 → 4 件: 数 2→2、日付 1→1、時刻 0→0、URL 1→0、コード 0→0、固有名詞 0→0、引用 0→0、見出し 1→1、条項の参照 0→0、脚注 0→0
落ちた事実 2 件、足された事実 1 件
  • 落ちた事実と足された事実は失敗です。どちらかがあれば終了コードは 1 になります。書き換えでも、事実を作ってはいけないからです。
  • 書き方だけ変わった事実は情報です。1,000 と 1000、5 と 5、2026年4月1日 と 2026/4/1、言い換えた見出しは、同じ事実の別の書き方として扱います。
  • 綴りを直した名前も情報です。大文字と小文字だけの違い(Borrowmoney → BorrowMoney)か、元の文書が一度だけ書いた綴りを、二度以上書いた綴りに一字だけ直したもの(Mariana → Marianna)は、同じ名前の綴りを直したものなので、落ちた事実にも足された事実にもしません。名前のそれ以外の変更は、落ちた事実と足された事実のままです。
  • 最後の行は、種類ごとに前と後の数を並べます。0 件の種類も出すので、「落ちたものは無い」が「何も見ていない」と読まれることはありません。品詞の解析器が無いなど、読めなかった種類があれば理由を添えて出します。

わざと削った種類は --allow-dropped、わざと足した種類は --allow-added で失敗から外せます。外したものも一覧には残ります。

npx chaffjs compare before.md after.md --allow-dropped url        # URL は消してよい
npx chaffjs compare before.md after.md --allow-dropped url,quote  # カンマで並べられる
npx chaffjs compare before.md after.md --distinct                 # 一度でも書いてあれば残ったとみなす
npx chaffjs compare before.md after.md --compact                  # 1 件 1 行
npx chaffjs compare before.md after.md --json                     # AI が読んで直す

種類の名前は number、date、time、url、code、name、quote、heading、reference、footnote です。 --json には、落ちた事実と足された事実が行番号つきで入るので、書き換えた AI にそのまま渡して直させられます。ふだんは、同じ事実を書いた回数も比べます。本文を言い直すだけの「まとめ」を消すと、繰り返していた事実が一つずつ落ちたと出ます。--distinct を付けると、相手の文書に一度でも書いてある事実は残ったとみなします。相手のどこにも無い事実は、これまでどおり落ちた・足されたと出ます。そのため --distinct では、元の文書より多い回数(または少ない回数)書いた事実も通ります。確かめるのは、それぞれの事実があるかどうかだけです。見出しは、同じ深さで同じ文言の見出しが相手にあれば書いてあるとみなします。同じ深さの見出しが他に残っていても、消した見出しは落ちたと出ます。

書き直す前に事実を控える

一から書き直すときは、元の文を直すのではなく、文書が言っている事実から書き起こします。facts はその一覧を出します。compare が照合する事実を、種類ごとに行番号つきで並べます。 compare と同じ読み手で取り出すので、ここに並んだものが、書き直した後に照合される事実そのものです。

$ npx chaffjs facts before.md
before.md の事実 5 件(数 2、日付 1、時刻 0、URL 1、コード 0、固有名詞 0、引用 0、見出し 1、条項の参照 0、脚注 0)

数 2 件
  - [ ] 1,000円  (before.md:3)
  - [ ] 1,200円  (before.md:3)

日付 1 件
  - [ ] 2026年4月1日  (before.md:3)

URL 1 件
  - [ ] https://example.com/price  (before.md:3)

見出し 1 件
  - [ ] 料金改定のお知らせ  (before.md:1)

書き直したら npx chaffjs compare before.md <書き直した後> で、この一覧が残っているかを確かめます

--compact は 1 件 1 行、--json は種類・照合の鍵・書いたままの文字・行番号を全部出します。書き直す AI に控えとして持たせられます。

構成を測る

文を滑らかにする書き直しでは、骨組みが元のまま残ることがあります。見出しも、箇条書きも、太字も同じです。outline は骨組みを出して測ります。構成を変えたかどうかが、印象ではなく数で分かります。見出しを深さで字下げして並べ、それぞれの行と、その節だけの本文の長さを出します。測るのは 4 つです。見出しの数、節の平均の長さ(日本語は字数、英語は語数。本文の無い節は数えません)、本文のうち箇条書きの中にある割合、太字の数です。構成の下には、構成の AI らしさを出します。構成の項目ごとに、生成 AI が広まる前の人の記事と比べます。値が人の記事の何割より多い(揃っている)かを書き、9 割を超えた項目には ✗ を付けて、人の記事での中央値と、9 割の境を添えます。

項目は、1000 字あたりの見出しの数、1〜2 段落の節、節の長さのばらつき、決まった形の見出し、3 つの小見出しに分けた見出しです。続いて、はじめに・まとめの見出し、まとめが本文を言い直す割合、3 項目の箇条書きがあります。最後に、太字の札で始まる項目、絵文字の付いた見出し、メリットとデメリットの対を比べます。

構成の AI らしさは ✗ の数です。比べた項目の数と一緒に出し、重み付けも隠れた計算もしません。文書が小さくて測れない項目は、測っていない理由と一緒に挙げます。人の記事の分布は structure-baseline.yaml にデータとして置いています。ファイルを 2 つ渡すと、両方を出し、それぞれの値がどう動いたかを、構成の AI らしさも含めて並べます。

$ npx chaffjs outline before.md after.md
before.md の構成: 見出し 6、節の平均 113 字、箇条書き 17%、太字 8

  # CI のテストがたまに落ちる問題を解決した話——時差という見えない罠  (before.md:1)  52 字
    ## 何が起きていたのか  (before.md:5)  169 字
    ## 原因の調査  (before.md:15)  204 字
    ## 解決策  (before.md:29)  116 字
    ## 結果  (before.md:39)  25 字
    ## まとめ  (before.md:43)  113 字

構成の AI らしさ: 1(人の記事の 9 割を超えた項目の数。比べた 10 項目、人の記事 2779 本と比べて)
  · 見出しの多さ: 1000 字あたり 7.4  人の記事の 75% より多い
  · 1〜2 段落の節: 60%(平均 2.6 段落)  人の記事の 45% より多い
  · 節の長さのばらつき: 55%  人の記事の 65% より揃っている
  · はじめに・まとめの見出し: 1(後)  人の記事の 40% より多い
  · まとめが本文を言い直す割合: 7%(「まとめ」)  人の記事の 5% より多い
  ✗ 太字の見出しで始まる項目: 3 項目  人の記事の 95% より多い(人の中央 0、上から 1 割の境 0)
  · 人の記事でふつう: 決まった形の見出し 0%、3 つの小見出しに分けた見出し 0 か所、絵文字の付いた見出し 0 個、メリットとデメリットの対 0 組
  測っていない: 3 項目の箇条書き(箇条書きが 3 つ未満)

after.md の構成: 見出し 5、節の平均 101 字、箇条書き 0%、太字 0

  # CI のテストがたまに落ちる問題は時差が原因だった  (after.md:1)  72 字
    ## 何が起きていたのか  (after.md:5)  74 字
    ## 原因の調査  (after.md:9)  160 字
    ## 直したこと  (after.md:15)  112 字
    ## 結果  (after.md:19)  88 字

構成の AI らしさ: 1(人の記事の 9 割を超えた項目の数。比べた 9 項目、人の記事 2779 本と比べて)
  · 見出しの多さ: 1000 字あたり 7.9  人の記事の 80% より多い
  · 1〜2 段落の節: 100%(平均 1.3 段落)  人の記事の 85% より多い
  ✗ 節の長さのばらつき: 32%  人の記事の 95% より揃っている(人の中央 66、下から 1 割の境 43)
  · 人の記事でふつう: 決まった形の見出し 0%、3 つの小見出しに分けた見出し 0 か所、はじめに・まとめの見出し 0、太字の見出しで始まる項目 0 項目、絵文字の付いた見出し 0 個、メリットとデメリットの対 0 組
  測っていない: まとめが本文を言い直す割合(まとめの節が無い)、3 項目の箇条書き(箇条書きが 3 つ未満)

構成の変化(before.md → after.md)
  見出し: 6 → 5
  節の平均: 113 字 → 101 字
  箇条書き: 17% → 0%
  太字: 8 → 0
  構成の AI らしさ: 1 → 1
  見出しの多さ: 1000 字あたり 7.4 → 1000 字あたり 7.9
  1〜2 段落の節: 60%(平均 2.6 段落) → 100%(平均 1.3 段落)
  節の長さのばらつき: 55% → 32%
  決まった形の見出し: 0% → 0%
  3 つの小見出しに分けた見出し: 0 か所 → 0 か所
  はじめに・まとめの見出し: 1(後) → 0
  まとめが本文を言い直す割合: 7%(「まとめ」) → —
  太字の見出しで始まる項目: 3 項目 → 0 項目
  絵文字の付いた見出し: 0 個 → 0 個
  メリットとデメリットの対: 0 組 → 0 組

この例では、文は滑らかになり、箇条書きと太字は消えましたが、見出しはほとんど残っていて、構成はあまり動いていません。--compact は 1 節 1 行と、ファイルごとに構成の AI らしさと ✗ の項目を 1 行で出します。--json は構成と形と、構成の項目それぞれの値と位置を出します(2 つなら before と after)。測るだけなので、ファイルが読めれば終了コードはいつも 0 です。

AI らしさを簡易判定する

ai-score は、生成文に多い目印のうち、同じジャンルの人の文書にはめったに出ないものがいくつ出ているかを数えます。目印が 3 つから「中」、5 つから「高」です。書いたのが AI かどうかの判定ではありません。人の文書と比べて、読み返す場所が多いかどうかの目安です。

$ npx chaffjs ai-score before.md after.md --compact
before.md: ai-score high 7/28 ai-tell announcing-opener closing-cliche colon-lead-in contrast-framing structure:bold-labels ai-generated-composite:strict
after.md: ai-score low 1/27 section-length-uniformity

上の before.md と after.md は、前の節で構成を測った記事です。1 ファイル 1 行で、段階、目印の数と比べた項目の数、数えた目印を出します。 --compact を付けなければ、目印ごとに件数と、人の文書の何本に出たかを並べます。その画面は AIっぽさを直す にあります。 --format json(--json)は同じものを JSON で出します。短すぎる文書や、人の文書の基準が足りないジャンルでは、段階を出さずに理由を言います。ふだんの npx chaffjs <file> も、ファイルごとの報告の最後に 1 行で段階を出します(--compact では出しません)。測るだけなので、ファイルが読めれば終了コードはいつも 0 です。

直す計画を出す

fix-plan は、指摘を「直す計画」にまとめます。書き直すのは、計画を読む人か AI です。 chaff は書き直しません。どう直すかを示すだけです。

npx chaffjs fix-plan article.md           # 直す計画を Markdown で
npx chaffjs fix-plan article.md --json    # 同じものを JSON で
npx chaffjs fix-plan article.md --depth light            # 構成は残す計画

計画は文書の言語で書かれます。ジャンルを決めたときは、まずジャンルの指針が来ます。その種類のよい文書が満たすことで、書き直しはこれに沿わせます(指針)。次に、どの書き直しでも守ることと、勧める直し方があります。守ることは、事実を変えない・足さない、分からない具体は作らずに書き手に聞く、書き直しは 2 回まで、です。直し方は、部分直し、節ごとの書き直し、全面書き直しの 3 つで、それぞれの書き直しの深さも書かれます。 --depth light・structure・register(または chaff.yaml の fix_plan.depth)で深さを決めると、それより深く直すルールは名前と箇所の数だけが並びます(深さ)。続いて、文書全体の目印と構成の数、構成の目標が並びます。構成の目標は、構成の AI らしさと、人の記事の 9 割を超えた項目ごとの目標です。全面書き直しを勧める理由にもなります。そのあとに、指摘のあったルールごとに、直す方向、変えないもの、やりがちな間違い、直す前と後の例、見つけた箇所が並びます。最後に、書き直した文書にかける chaff・compare・outline のコマンドがあります。同じ文書なら何度出しても同じ計画になり、どこにも送りません。計画から確かめまでの例は「AIっぽさを直す」にあります。

意味を読む検査

chaff test は、機械では判定できないものを AI に読ませます。API key が要ります。鍵が無ければ、機械による判定だけを動かして、そう言います。黙って通しはしません。

npx chaffjs test docs/
═══ 機械による判定 ═══════════════════════════════
    同じ文章なら何度実行しても同じ結果になります

═══ AI による判定 ════════════════════════════════
    文章の意味を読んでいます。実行するたび結果が変わることが
    あります。おかしいと思ったら、そのまま無視して構いません。

    118 文のうち 4 箇所を読みました(残りは機械が対象外と判断)

  ⚠  数字の根拠がない            確からしさ 0.88

     「40%」がどう計算されたのか、いつと比べたのかが本文にありません。

     → 「(2026年4-6月、対前年同期、n=120)」のように括弧で添えてください

     この指摘が違うと思ったら:
       この箇所だけ黙らせる    <!-- stet: unsourced-number — 理由 -->
       ルールごとゆるめる      npx chaffjs relax unsourced-number

文書全体を AI に渡すことはしません。機械で候補を絞ってから、その箇所だけを読ませます。 risk-disclosure は、見出しに「リスク」があれば問い合わせもしません。

rule見るもの絞り込み
risk-disclosure提案にリスクが書かれているか見出しにリスクの節があれば見ない
empty-conclusion結びが本文の要約でしかないか最後の節に、前に書いていない数・コード・リンクが無いときだけ
unsourced-number効果を主張する数字に根拠があるか数字と効果の語が同じ文にあり、根拠が無いときだけ

同じ問いは 2 度目から .chaff-cache/ に当たるので、CI で何度回しても課金されません。

何が送られるかは、API key が無くても --dry-run で確かめられます。API は呼びません。

npx chaffjs test docs/ --dry-run
doc.md   全 6 文のうち 5 箇所を送ります(API は呼んでいません)

      1 箇所  リスクが書かれていない  (機械で絞り込み済み)
      2 箇所  依頼には期限と担当がある  (「お願いします」「ご確認ください」を含む文)
      1 箇所  議事録に決定事項がある  (絞り込めず全文)

チームの検査は checks.yaml に自然文で書きます。プログラムは書きません。 look_at を書くと、その「」の中の語を含む文だけを送ります。絞り込めなかった検査は全文を送り、そのことも画面に出ます。

checks:
  - name: 提案書に決裁者が書かれている
    use_for: business
    check: |
      決裁を求めている文書に、誰が決めるのかが書かれていること。
      役職名でも個人名でもよい。誰も特定できなければ、決まりに反する。
    level: normal
    how_to_fix: 「◯◯部長の承認をお願いします」のように、決める人を書いてください。

判定役は Anthropic と OpenAI から選べます。どちらを選んでも、rule も、AI に返させる形も変わりません。

ai_backend: openai     # 既定は anthropic
ai_model: gpt-5
backend認証既定モデル
anthropicANTHROPIC_API_KEY、または ant auth loginclaude-opus-5
openaiOPENAI_API_KEYgpt-5

鍵は .env に書いても読みます。シェルの環境変数があればそちらを使うので、一時的に別の鍵で試せます。 .env は .gitignore に入れます。chaff init が作る .gitignore には入っています。 Claude Code の Pro / Max のサブスクリプションは使えません。API は別の勘定で、認証情報の置き場も違うためです(~/.claude と ~/.config/anthropic)。

閾値を手元の文書で測り直す

既定の閾値は一般論です。自分たちの文章に合っているかは、測らないと分かりません。 chaff eval は、手元の文書を「人が書いて公開した良い文書」として扱い、閾値ごとに何件の指摘が出るかを並べます。

npx chaffjs eval examples/blog-ja/
  3 ファイルを corpus として 45 本の rule を測りました。

  ここにある文書は「人間が書いて公開した良い文書」として扱っています。
  そこで多く発火する rule は、閾値が現実に合っていない疑いがあります(目標: 5% 未満)。

  ※ corpus が 3 文書しかありません。5% を表すには 20 文書以上が要ります。
     いまは割合が「0 か全部」に振れるので、右端の密度(1万字あたりの指摘数)のほうを見てください。
  …

  一文が長すぎる   (max-sentence-length)

        50     3 文書 (100.0%)   指摘  87 件   1万字あたり 50.7
        70     3 文書 (100.0%)   指摘  28 件   1万字あたり 16.3
        85     2 文書 ( 66.7%)   指摘  12 件   1万字あたり 7.0
       100     2 文書 ( 66.7%)   指摘   4 件   1万字あたり 2.3  ← 現在
       125     1 文書 ( 33.3%)   指摘   1 件   1万字あたり 0.6
       140     0 文書 (  0.0%)   指摘   0 件   1万字あたり 0.0  ← 推奨
       150     0 文書 (  0.0%)   指摘   0 件   1万字あたり 0.0
       200     0 文書 (  0.0%)   指摘   0 件   1万字あたり 0.0
       300     0 文書 (  0.0%)   指摘   0 件   1万字あたり 0.0

    いまの閾値では 66.7% の文書が該当し、目標(5% 未満)を超えています。
    推奨: 140

    chaff.yaml に書くなら:  rules:
                              max-sentence-length: 140

推奨の値と chaff.yaml に書く形は出しますが、chaff は閾値を書き換えません。測った結果は手元の文書に対する答えであって、正解ではないからです。どの値にするかは人が決めます。文書が 20 に満たないときは、割合が 0 か全部に振れやすいので、右端にある 1 万字あたりの指摘数を見ます。