✍️

AI執筆ブログを進化させた話 〜textlintとZenn GitHub連携編〜

に公開

こんにちは、株式会社 tacoms で SRE をやっている はぶちん (@modokkin) です。
9月に入って朝晩はだいぶ涼しくなってきましたね。前回の記事では「まだまだ暑い」と書いていましたが、ようやく秋の気配を感じられるようになりました。

さて、前回「Claude Codeを使ってAIにブログ記事執筆を任せてみた」という記事を公開してから約1週間。ありがたいことに多くの方に読んでいただきました。今回はその続編として、AI執筆の仕組みをさらに進化させた話をお届けします。

前回記事の反響とその後

前回の記事を公開した後、社内外から多くのフィードバックをいただきました。特に社内の方から「textlint-rule-preset-ai-writing」というツールを教えていただいたことが、今回の改善の大きなきっかけになりました。

また、記事執筆のハードルが下がったことで、これまで会社ブログへの投稿が中心だった私も、個人のZennブログを始めることにしました。実際、この仕組みを作ってから個人ブログの更新頻度が上がっています。

textlintでAI特有の文体を是正する

AIが生成する文章の課題

AIが生成する文章には、いくつか特徴的な癖があります。

  • 英語圏特有の言い回しをそのまま日本語に直訳したような表現
  • 「〜できます」のような冗長な表現
  • 不自然にカタカナを使いすぎる傾向
  • 「〜んです」という口語的な表現の多用

これらの問題を解決するために導入したのが、@textlint-ja/textlint-rule-preset-ai-writingです。

textlintの設定

.textlintrc.jsonに以下のような設定を追加しました。

{
  "rules": {
    "preset-ja-technical-writing": {
      "no-exclamation-question-mark": false,
      "ja-no-weak-phrase": false,
      "ja-no-mixed-period": {
        "allowEmojiAtEnd": true,
        "allowPeriodMarks": [")", "w", "…"]
      },
      "ja-unnatural-alphabet": {
        "allow": ["w"]
      }
    },
    "@textlint-ja/preset-ai-writing": true
  },
  "filters": {
    "comments": true,
    "allowlist": {
      "allow": [
        "Claude Code",
        "はぶちん",
        "tacoms"
      ]
    }
  }
}

この仕組みでは preset-ja-technical-writing を有効にすることが推奨されているのですが、あくまでテクニカルライティングを前提としているので、そのまま使うとかっちりとした文章になってしまいます。
ブログの記事はできるだけ気軽に読めるようにしたいと思っているので、自分の文体に合わせてルールを調整しました。
例えば、 ja-no-mixed-period という、末尾が句点で終わっていないと修正するルールがあるのですが、「w」や「…」で文を終わらせることがあるので、許可リストに入れました。

実際の修正例

実はこの記事も、初稿をAIが生成した後にtextlintで修正しています。以下が実際の修正例です。

修正前:

この機能を活用することで、ブログを書くことができるようになりました。

修正後:

この機能を活用して、ブログを書けるようになりました。

「〜することで」「〜ことができます」という冗長な表現が、「〜して」「〜できます」という簡潔な表現に修正されています。

Claude Codeとの連携

Claude Codeで記事を生成した後、自動的にtextlintを実行する仕組みも作りました。

# 記事生成後に自動実行
npx textlint articles/**/*.md --fix

これにより、AIが生成した文章を日本語として自然な表現へ自動的に修正できるようになりました。

Zenn GitHub連携への対応

なぜZennを選んだか

個人ブログを始めるにあたって、Zennを選んだ理由は以下の通りです。

  • GitHub連携により、記事をGit管理できる
  • Markdownで記事を書ける
  • 技術記事に特化したプラットフォーム
  • エンジニアコミュニティが活発

ディレクトリ構成の課題

しかし、Zenn CLIを使うためには、特定のディレクトリ構成にする必要がありました。

Zennが要求する構成:

my-blog/
├── articles/        # Zenn記事(ファイル名にルールあり)
├── books/          # Zennの本
└── images/         # 画像ファイル

現在の構成:

my-blog/
├── articles/
│   ├── hatena/     # はてなブログ記事
│   └── zenn-*.md   # Zenn記事
└── drafts/         # 下書き

解決策:ハイブリッド構成

両方のプラットフォームに対応できるよう、以下のような構成にしました。

my-blog/
├── articles/           # Zenn用(GitHub連携)
│   └── *.md           # Zennフォーマット記事
├── hatena/            # はてなブログ用
│   └── *.md           # はてなフォーマット記事
├── drafts/            # 下書き(共通)
├── .textlintrc.json   # textlint設定
└── package.json       # Zenn CLIとtextlint

Zenn記事のフロントマター

Zenn記事には特定のフロントマターが必要です。

---
title: "AI執筆ブログを進化させた話"
emoji: "🤖"
type: "tech" # tech: 技術記事 / idea: アイデア
topics: ["claude", "ai", "textlint", "zenn"]
published: false # 下書きの場合はfalse
---

Zenn CLIのコマンド

よく使うZenn CLIコマンドをまとめました。

# 記事の新規作成
npx zenn new:article

# プレビューサーバー起動
npx zenn preview

# 記事のデプロイ(GitHub連携時は自動)
git push origin main

実装した自動化フロー

完全な記事作成フロー

現在の記事作成フローは以下のようになっています。

package.jsonのスクリプト

作業を効率化するため、npm scriptsも整備しました。

{
  "scripts": {
    "lint": "textlint articles/**/*.md hatena/**/*.md",
    "lint:fix": "textlint articles/**/*.md hatena/**/*.md --fix",
    "zenn:preview": "zenn preview",
    "zenn:new": "zenn new:article",
    "publish:zenn": "npm run lint:fix && git add . && git commit -m 'Publish to Zenn' && git push"
  }
}

困った点と解決策

1. textlintの誤検知

固有名詞や専門用語でtextlintが誤検知することがありました。これはallowlistへ追加して解決しました。

{
  "filters": {
    "allowlist": {
      "allow": [
        "Claude Code",
        "Tavily MCP",
        "EventBridge"
      ]
    }
  }
}

2. フロントマターの違い

Zennとはてなブログでフロントマターのフォーマットが異なる問題は、プラットフォームごとにテンプレートを用意することで対応しました。

3. 画像の扱い

Zennはimages/ディレクトリに画像を配置しますが、はてなブログは直接アップロードです。現在は手動で対応していますが、将来的には自動化したいと考えています。

成果と今後の展望

数値で見る成果

  • 記事執筆時間: 平均1時間 → 30分に短縮(体感値)
  • textlintによる修正: 1記事あたり平均15箇所の改善(実測値)
  • 投稿頻度: 月1回 → 週1回ペースに向上(目標)

今後やりたいこと

  1. 画像の自動処理: スクリーンショットの自動配置
  2. 複数AI活用: Claude以外のAIとの併用
  3. 分析機能: 記事のパフォーマンス分析と改善提案
  4. チーム共有: tacomsチーム内での仕組み共有

まとめ

AI記事執筆の仕組みにtextlintとZenn GitHub連携を追加することで、以下のメリットがありました。

  • textlintによりAI特有の不自然な表現が自動修正される
  • Zenn GitHub連携で記事のバージョン管理が容易に
  • 複数プラットフォームへの投稿が効率化
  • 記事の品質と投稿頻度が向上

前回の記事では「ブログを書くハードルが下がった」と書きましたが、今回の改善でさらにハードルが下がりました。この仕組みは、ブログ執筆だけでなくドキュメント作成全般に応用できると思います。

実際、この作業を通してClaude Codeを使った自動化のノウハウも蓄積できました。AIを活用した開発効率化は、まだまだ可能性があると感じています。

どなたかの参考になれば幸いです。


おまけ:実際のtextlint修正結果

この記事をtextlintでチェックした結果を載せておきます。AI執筆の文章がどのように修正されるか、参考にしていただければと思います。

# 実行コマンド
npx textlint drafts/2025-09-04-tech-ai-blog-writing-evolution.md

# 修正された箇所(一部抜粋)
 Fixed 15 problems
- "することができます" "できます" (5箇所)
- "〜を行う" "〜する" (3箇所) 
- カタカナの過剰使用を修正 (4箇所)
- 冗長な表現を簡潔に (3箇所)

このように、AIが生成した文章も、textlintを通すことで格段に読みやすくなります。ぜひ試してみてください!

Discussion