1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ChatGPTの出力をそのまま使うと"AI臭い"ので、リライトツール作った

1
Posted at

「なんかAIっぽい文章だね」と言われた日

先月、業務で使う提案書のドラフトをChatGPTに書かせて、軽く手直しして提出した。そしたらクライアントから「これAIで書きました?」と聞かれた。バレた。

正直ショックだった。自分なりに修正したつもりだったのに。それ以来「AI臭い文章とは何か」をずっと考えていて、パターンを分析してリライトツールを作ることにした。

AI臭さの正体を分解する

ChatGPTが生成する日本語テキストには、人間が書くとまず使わない表現パターンがある。自分が200本くらいの出力を分析して見つけた特徴をまとめる。

構文パターン

  • 「〜することが重要です」「〜が不可欠です」の多用
  • 「まず〜、次に〜、最後に〜」の三段構成
  • 「〜について詳しく見ていきましょう」という誘導表現
  • 段落の冒頭が「また、」「さらに、」「加えて、」で始まる率が異常に高い

語彙パターン

  • 「多角的」「包括的」「網羅的」の3連コンボ
  • 「革新的」「画期的」という大げさな形容詞
  • 「〜を活用して」「〜を踏まえて」の頻出
  • 「いかがでしたでしょうか」で締める

構造パターン

  • 各セクションの文字数が均一すぎる
  • 箇条書きが3〜5個でキレイに揃う
  • 結論が「まとめ」で始まり、内容の復唱で終わる

人間の文章はもっとムラがある。長い段落の後に一行だけの段落が来たり、話が横道に逸れたりする。AIの文章はそういう「ノイズ」がないから、逆に不自然に見える。

リライトのアルゴリズム設計

AI臭さを消すアプローチはいくつかある。

  1. パターン検出 → 置換: 定型表現を検出して、より自然な表現に置き換える
  2. 構造の揺らぎ挿入: 段落の長さを不均一にする、接続詞を間引く
  3. 口語表現の注入: 書き言葉すぎる部分にカジュアルな表現を混ぜる

全部を自動でやるのは品質が安定しないので、ツールとしては「検出してハイライト→ユーザーが選んで置換」というセミオート方式にした。

実装

パターン検出エンジン

まず、AI臭い表現をパターンとして定義する。正規表現だけだと限界があるので、形態素解析も組み合わせた。

interface AiPattern {
  id: string;
  category: "phrase" | "structure" | "vocabulary";
  pattern: RegExp;
  description: string;
  severity: "high" | "medium" | "low";
  suggestions: string[];
}

const AI_PATTERNS: AiPattern[] = [
  {
    id: "important-desu",
    category: "phrase",
    pattern: /することが(重要|不可欠|大切|必要不可欠)です/g,
    description: "AIが多用する「〜することが重要です」構文",
    severity: "high",
    suggestions: ["した方がいい", "しないと困る", "がカギになる"],
  },
  {
    id: "lets-look",
    category: "phrase",
    pattern: /について(詳しく|具体的に)見ていきましょう/g,
    description: "読者を誘導する定型表現",
    severity: "high",
    suggestions: ["の話をする", "を掘り下げる", "に触れておく"],
  },
  {
    id: "moreover-chain",
    category: "structure",
    pattern: /^(また、|さらに、|加えて、|その上、)/gm,
    description: "段落頭の接続詞連鎖",
    severity: "medium",
    suggestions: ["(削除して直接始める)", "ちなみに", "で、"],
  },
  {
    id: "comprehensive",
    category: "vocabulary",
    pattern: /(多角的|包括的|網羅的|革新的|画期的)(な|に)/g,
    description: "AIが好む大げさな形容詞",
    severity: "high",
    suggestions: ["幅広い", "全体的な", "新しい", "面白い"],
  },
  {
    id: "utilizing",
    category: "vocabulary",
    pattern: /を活用(して|し|する)/g,
    description: "「活用」の過剰使用",
    severity: "medium",
    suggestions: ["を使って", "でやって", "を入れて"],
  },
  {
    id: "how-was-it",
    category: "phrase",
    pattern: /いかがでし(た|ょう)でしょうか/g,
    description: "AI記事の定番締め",
    severity: "high",
    suggestions: ["(削除)", "参考になれば嬉しい"],
  },
];

これだけだとまだ甘いんだけど、パターンは随時追加していく設計。ユーザーがカスタムパターンを登録できる機能も入れた。

検出結果のスコアリング

テキスト全体のAI臭さを0〜100のスコアで出す。パターンの出現頻度と深刻度を掛け合わせて算出する。

interface DetectionResult {
  patternId: string;
  match: string;
  index: number;
  length: number;
  severity: "high" | "medium" | "low";
}

function detectAiPatterns(text: string): DetectionResult[] {
  const results: DetectionResult[] = [];
  
  for (const pattern of AI_PATTERNS) {
    // RegExpのlastIndexをリセット
    pattern.pattern.lastIndex = 0;
    
    let match: RegExpExecArray | null;
    while ((match = pattern.pattern.exec(text)) !== null) {
      results.push({
        patternId: pattern.id,
        match: match[0],
        index: match.index,
        length: match[0].length,
        severity: pattern.severity,
      });
    }
  }
  
  return results;
}

function calcAiScore(text: string, detections: DetectionResult[]): number {
  if (text.length === 0) return 0;
  
  const SEVERITY_WEIGHT = { high: 3, medium: 2, low: 1 };
  
  const rawScore = detections.reduce(
    (sum, d) => sum + SEVERITY_WEIGHT[d.severity], 0
  );
  
  // テキストの長さで正規化(1000文字あたり)
  const normalized = (rawScore / text.length) * 1000;
  
  // 0-100にクランプ
  return Math.min(Math.round(normalized * 5), 100);
}

スコアが50以上だと「かなりAI臭い」、30以下なら「人間っぽい」という目安にしている。自分の体感だと、ChatGPTの素の出力は大体60〜80くらいのスコアが出る。

置換ロジック

検出したパターンに対して、候補の中からランダムに選んで置換する。毎回同じ置換だとそれはそれで不自然なので。

function applyRewrite(
  text: string, 
  detections: DetectionResult[],
  mode: "auto" | "suggest" = "suggest"
): { rewritten: string; changes: Array<{ from: string; to: string }> } {
  const changes: Array<{ from: string; to: string }> = [];
  
  // indexの降順でソート(後ろから置換しないとindexがずれる)
  const sorted = [...detections].sort((a, b) => b.index - a.index);
  
  let result = text;
  
  for (const detection of sorted) {
    const pattern = AI_PATTERNS.find(p => p.id === detection.patternId);
    if (!pattern || pattern.suggestions.length === 0) continue;
    
    if (mode === "auto") {
      // ランダムに候補を選択
      const suggestion = pattern.suggestions[
        Math.floor(Math.random() * pattern.suggestions.length)
      ];
      
      if (suggestion === "(削除)" || suggestion === "(削除して直接始める)") {
        result = result.slice(0, detection.index) 
               + result.slice(detection.index + detection.length);
        changes.push({ from: detection.match, to: "" });
      } else {
        result = result.slice(0, detection.index) 
               + suggestion 
               + result.slice(detection.index + detection.length);
        changes.push({ from: detection.match, to: suggestion });
      }
    }
  }
  
  return { rewritten: result, changes };
}

後ろから置換するのは地味だけど大事なポイント。前から置換するとインデックスがずれてバグる。文字列操作あるある。

実際に使ってみた結果

ChatGPTに「フリーランスのメリットとデメリット」という記事を書かせて、このツールに通してみた。

  • 素の出力: AIスコア 72
  • リライト後: AIスコア 18

具体的には「〜することが重要です」が4箇所、「包括的な」が2箇所、段落頭の「また、」が6箇所検出された。これらを置換・削除するだけで、かなり人間っぽくなった。

ただし限界もある。AI臭さの原因は表面的な表現だけじゃなくて、論理展開の「きれいすぎる」構造にもある。メリット3つ・デメリット3つがバランスよく並んでる時点で、読む人が読めばAIだとわかる。このへんは自動化が難しい。

作ってみて学んだこと

AI臭さの本質は「予測可能性」だと思う。次に何が来るか予想できる文章はAI臭い。人間の文章は良い意味で予測を裏切る。急に個人的なエピソードが入ったり、話が脱線したりする。

このツールはあくまで「表面的なAI臭さ」を消すもので、文章の構造レベルの不自然さは人間が直す必要がある。とはいえ、定型表現を機械的に潰すだけでもかなり効果がある。

ツールは text.mildsolt.jp で公開中。テキストを貼り付けるとAIスコアが出て、検出箇所をハイライト表示する。置換候補もワンクリックで適用できる。

ChatGPTを業務で使ってる人は、提出前に一回通してみると安心感が違う。「AIで書きました?」と聞かれる回数は確実に減る。

まとめ

  • AI臭さの正体は定型表現・均一な構造・大げさな語彙
  • パターンマッチングだけでもスコア72→18まで改善できる
  • ただし論理構造の不自然さは人間が直すしかない
  • text.mildsolt.jp で無料公開中

AIの出力をそのまま使う時代は終わった。「AIに書かせて、人間が仕上げる」のが現実的なワークフローだと思う。そのとき、仕上げの手間を減らしてくれるツールがあると捗る。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?