【AI社員実践記 第17話】既存の自動化に記事下書きを相乗り 「東京都」バグをテストで止めた

こんにちは、オフィスピコッツの小笹です。

ここ数回のAI社員実践記では、VPSの中へ仕事を増やしてきました。

サイト監視。

ドメイン期限チェック。

月次稼働率レポート。

リンク切れ巡回。

補助金の締切ウォッチ。

さらに、それらの定期処理が本当に動いているかを確認する「点呼」まで追加しました。

今回は、少し方向が違います。

新しい係は増やしません。

すでに毎週動いている「締切ウォッチ係」に、もう一つ仕事を追加しました。

その仕事は、

京都・滋賀プレスリリース(localpr.jp)へ掲載する補助金記事の下書きを作ること。

実装から反映確認までは約30分。

追加費用は0円です。

ただし今回、一番印象に残ったのは「30分で記事生成機能ができたこと」ではありません。

納品前にAIが書いたテストが、

「東京都」を「京都」と誤認するバグ

を1件見つけました。

もしテストを飛ばしていたら、京都・滋賀向けの記事に東京都限定の補助金を掲載していた可能性があります。

今回は、AIにコードを書かせるだけでなく、

AIにテストまで書かせる意味

を実感した回です。

自社メディアの記事更新は、どうしても後回しになりやすい

オフィスピコッツでは、

「京都・滋賀プレスリリース」

という地域メディアを運営しています。

京都・滋賀の事業者やイベント、商品・サービスなどの情報を掲載するサイトです。

その中では補助金情報も発信しています。

ただ、自社メディアの運営には一つ悩みがあります。

クライアントの制作や運営サポートが優先されるため、

自社サイトの記事を書く仕事は、どうしても後回しになりやすい。

「今週も補助金の記事を書こう」

と思っていても、

問い合わせ対応。

修正作業。

打ち合わせ。

別の記事。

そうしているうちに一週間が終わります。

情報がないわけではありません。

第12話で作った「補助金レーダー」が、毎朝Jグランツの公開情報を取得しています。

第13話で作った「締切ウォッチ」も、毎週金曜日に締切が近い補助金を抽出しています。

材料はすでに機械が持っている。

それなら、

「その材料から記事の下書きまで作れないか」

という話になりました。

新しい係を作るか、既存の係へ仕事を足すか

最初に考えたのは、

記事作成専用の新しいスクリプトを作る

方法です。

第6係として、

「毎週補助金記事を書く係」

を追加することもできます。

技術的にはそれほど難しくありません。

でも、ここで最近のAI社員実践記で学んだことが効きました。

仕組みを一つ増やすと、

  • cronの設定が増える
  • 動作確認が増える
  • 点呼の対象が増える
  • エラー時に確認するものが増える

ことになります。

第15話では、自動処理そのものを監視する「点呼」まで作りました。

つまり、

係を増やすことには、管理コストも付いてくる。

そこでAI社員へ、

「新しい係を増やさずにできない?」

と相談しました。

答えはシンプルでした。

「締切ウォッチの週報メールに、記事下書きも一緒に入れればいい」

です。

同じデータを2回取りに行く必要はない

第13話で作った締切ウォッチは、毎週金曜日に、

補助金レーダーが公開しているJSONデータを取得します。

その中から締切が近い補助金を選び、

週報メールを作ります。

すでに、

  • 補助金名
  • 締切
  • 残り日数
  • 対象地域
  • JグランツURL

を持っています。

つまり、

記事を書くために、もう一度Jグランツへデータを取りに行く必要はありません。

同じデータを、

週報メールにも使う。

X投稿案にも使う。

localpr.jpの記事下書きにも使う。

という形にすればいい。

今回は、

新しいシステムを作るのではなく、既存データの出口を一つ増やす

改修にしました。

こういう「相乗り」ができるようになったのも、ここまで仕組みを積み上げてきた効果だと思います。

出力するのは、そのまま貼れるHTML

AI社員へ依頼したのは、

WordPressへそのまま貼り付けられる形

です。

毎週金曜の締切ウォッチが動くと、

これまでの週報に加えて、

  • 記事タイトル案
  • 導入文
  • 締切が近い補助金一覧
  • 受付中一覧へのリンク

などをHTML形式で生成します。

人間側は、

メールを開く。

内容を確認する。

必要なら少し修正する。

WordPressへ貼る。

公開する。

という流れです。

「記事を書く」から、

「記事を確認する」

へ仕事を変えるのが狙いです。

最初のテストでは、HTMLまで普通に出た

AI社員が改修コードを書きました。

サーバーへ反映する前に、まずテストモードで実行します。

すると、

補助金一覧に続いて、

localpr.jp向けの本文HTMLが出力されました。

既存の締切ウォッチをテスト実行。補助金一覧に続いて、WordPressへ貼り付けられる記事本文HTMLまで生成されました。

Jグランツの詳細URL。

補助金名。

締切までの日数。

対象地域。

そして最後には、

「受付中の一覧はこちら」

として、補助金レーダーへのリンクも入っています。

ここまでは順調です。

「これなら使えそう」

と思いました。

ただ、内容を眺めていると一つ気になるところがありました。

「京都・滋賀の記事」なのに、全国向けがかなり多い

今回の元データには、全国を対象にした補助金も入っています。

全国向けの補助金なら、京都や滋賀の事業者も対象になります。

ですから、掲載すること自体は間違いではありません。

ただ、

「京都・滋賀の補助金情報」

として記事を出す場合、

ほかの都道府県だけを対象にした制度まで混ざるのは避けたいところです。

そこで記事下書きに使う補助金については、

  • 京都府
  • 滋賀県
  • 全国

を対象地域として含むもの

に絞ることにしました。

全国は残す。

京都・滋賀も残す。

大阪府限定や東京都限定など、

京都・滋賀から使えない地域限定制度は外す。

そういうフィルタです。

判定ロジック自体は、とても単純に見えた

文章で書けば簡単です。

対象地域の文字列に、

京都

があれば掲載。

滋賀

があれば掲載。

全国

があれば掲載。

それ以外は除外。

AI社員も、そのルールに合わせてコードを書きました。

ここまでなら、

「数行足して終了」

でもおかしくありません。

でも今回は、AI社員がそのまま納品には進みませんでした。

地域判定の単体テスト

も作りました。

「京都府ならOK」「大阪府ならNG」を機械に確認させる

作ったフィルタについて、

いくつかの入力パターンを機械的に試します。

たとえば、

京都府

→ 掲載対象。

滋賀県

→ 掲載対象。

全国

→ 掲載対象。

大阪府

→ 対象外。

ここまでは想像どおりです。

ところが、そのテストの中で、

1件だけFAIL

が出ました。

入力された地域名は、

東京都。

本来は対象外です。

ところがプログラムは、

「掲載対象」

と判定していました。

原因は「東京都」に「京都」が入っているから

原因を聞いて、なるほどと思いました。

東京都

という文字列を分けると、

東 + 京都

です。

つまり文字列として見ると、

「東京都」の中には「京都」が含まれています。

人間なら、

東京都と京都府を間違えることはありません。

でも、

「文字列に『京都』という文字が入っているか」

だけで判定するプログラムにとっては、

東京都も京都です。

かなり単純なバグです。

でも、だからこそ厄介です。

コードを眺めていても、

「京都が含まれていたらOK」

という条件は、一見正しく見えます。

実データで東京都が入ってきたときに初めて問題になります。

テストを飛ばしていたら、そのまま公開されていたかもしれない

もし今回、

「コードできました」

「動きました」

「では本番へ」

と進んでいたら、

東京都限定の補助金が、

京都・滋賀向けの記事へ混ざる

可能性がありました。

技術的には小さなミスです。

サイトが壊れるわけでもありません。

エラー画面が出るわけでもありません。

むしろ正常にHTMLまで生成されます。

だから余計に気づきにくい。

読者から見れば、

「京都・滋賀の補助金記事に、なぜ東京都限定の制度が?」

となります。

プログラム上のバグが、そのまま記事の信頼性の問題になるところでした。

修正は1行。でも、その1行を見つけるためにテストが要る

修正そのものは大きなものではありません。

判定をする前に、

「東京都」

を別扱いにします。

そのうえで、

「京都」が含まれているかを確認する。

ただし、

東京都と京都府の両方が対象

という制度まで除外してはいけません。

そこで修正後は、

  • 京都府 → 掲載
  • 滋賀県 → 掲載
  • 全国 → 掲載
  • 大阪府 → 除外
  • 東京都のみ → 除外
  • 東京都+京都府 → 掲載

と、境界になるパターンまでテストしました。

結果は全件合格。

これでようやく本番反映です。

AIにコードを書かせるなら、テストも一緒に書かせる

今回の出来事で、かなり印象が変わりました。

AIへプログラムを書かせるとき、

これまでは、

「コードが動くか」

を主に確認していました。

でも、本当に怖いのは、

エラーにならず、間違った結果を返すコード

です。

今回の東京都問題は、その典型です。

プログラム自体は止まりません。

HTMLも生成します。

メールも送れます。

ただし、中身だけが間違います。

こういうものは、

「ちゃんと動いた」

だけでは見つけられません。

だから今後は、

AIへコードを書かせるときは、想定ケースと境界ケースのテストも一緒に作らせる

ことを基本にしたいと思います。

「東京都」をテスト項目に入れたのもAIだった

今回面白かったのは、

私が、

「東京都もテストして」

と指定したわけではないことです。

AI社員が地域判定のテストケースを作り、

その中の一つとして東京都を入れていました。

そして、自分で書いたコードを、

自分で書いたテストが落とした。

AIが、

「自分のコードには問題ありません」

とそのまま通したわけではありません。

コードを書く役と、

チェックする役を、

同じAIとの作業の中で分ける。

これは実務でかなり使えるやり方だと思います。

本番反映後も「本当に入れ替わったか」を確認

テストが全部通ったので、修正版をVPSへ反映しました。

ただし、ここでも、

「コピーしたから反映されたはず」

では終わりません。

サーバー上の実ファイルについて、

新しいバージョンの目印が本当に入っているかを検索します。

今回使ったのはgrepです。

修正版をVPSへ反映後、新バージョンの目印を検索。サーバー上の実ファイルまで更新されていることを確認しました。

新バージョンで追加した文字列を数え、

5

と表示されました。

つまり、サーバー上のファイルにも新しい版の変更点が入っていることを確認できました。

ここまでで反映完了です。

コードを書く。

テストする。

修正する。

もう一度テストする。

サーバーへ反映する。

反映後の実ファイルを確認する。

「作った」ではなく、「本番まで確認した」

ところまでが今回の作業です。

新しい係を増やさなかったので、点呼も増えない

第15話では、

「自動処理そのものが止まっていないか」

を確認するため、Uptime Kumaへ点呼を追加しました。

もし今回、

第6係として新しい記事作成スクリプトを作っていたら、

その係についても、

  • cron
  • 点呼
  • 監視
  • エラー時の確認

を増やす必要がありました。

でも今回は、

第5係の締切ウォッチへ仕事を追加しただけ

です。

金曜の朝に締切ウォッチが正常終了すれば、これまで通り点呼を返します。

記事下書き生成まで含めて一つの仕事です。

管理対象は増えていません。

機能だけが増えました。

これは今回かなり良かった判断だと思います。

自動化は「増やす」より「太らせる」方がいい場合もある

第9話以降、

「係を増やす」

という表現をよく使ってきました。

でも今回やってみて、

何でも新しい係にする必要はない

とも感じました。

同じデータを使う。

同じ曜日に動く。

同じメールで届けばいい。

同じ失敗監視で十分。

そういう仕事なら、

新しい自動処理を一本増やすより、

既存の処理に相乗りする方が管理は簡単

です。

システムを作ること自体が目的ではありません。

人間の仕事を減らしつつ、

壊れにくく、

確認しやすくすることが目的です。

「新しく作れるか」だけでなく、

「今あるものに載せられないか」

を先に考える。

今回、一つ新しい基準ができました。

記事は自動公開しない

もう一つ、今回自動化していない部分があります。

WordPressへの公開です。

締切ウォッチは記事のHTMLまで作ります。

でも、自動でlocalpr.jpへ投稿はしません。

金曜朝に届いた下書きを人間が確認します。

タイトルを見る。

掲載する補助金を見る。

内容がおかしくないか確認する。

必要なら直す。

そのうえでWordPressへ貼り付けます。

第13話のX投稿案も同じです。

下書きは機械。

公開判断は人間。

今回の「東京都」問題を見ると、

この一段を残しておく意味もよく分かります。

テストでかなり防げます。

でも、最終的な情報発信については、

人が一度読む

という工程をまだ外すつもりはありません。

記事作成が「書く」から「確認する」に変わる

これまで補助金記事を書く場合は、

補助金一覧を見る。

締切が近いものを選ぶ。

タイトルを考える。

本文を書く。

リンクを付ける。

WordPressへ入れる。

という流れでした。

今回の改修後は、

金曜朝のメールを開く。

記事下書きを読む。

必要なら直す。

貼り付ける。

になります。

ゼロから文章を書く作業が、

確認と編集の作業

に変わります。

完全自動ではありません。

でも、実務ではこの差がかなり大きいです。

「10分なら書ける」

と思う仕事でも、

毎週続けば年間ではかなりの時間になります。

しかも、

「今週は忙しいから来週にしよう」

となりやすい。

先に下書きが届いていれば、

公開までの心理的なハードルも下がります。

今回の追加費用は0円

今回、新しいサービスは契約していません。

VPSは既存。

補助金データも既存。

締切ウォッチも既存。

メール送信も既存。

追加したのは、

記事下書きを生成する処理と地域フィルタ

です。

作業時間は、設計、テスト、バグ修正、反映確認まで含めて約30分でした。

追加固定費は、

0円。

今回も、

前に作った仕組みを次の仕事へ再利用する

形です。

第9話でVPSを使い始めたときに比べると、新しい機能を追加するためのコストはかなり下がってきました。

今回の結論

今回のテーマは、一見すると、

「補助金記事の下書きを自動生成した」

という話です。

でも、一番大きな学びはそこではありませんでした。

私が持ち帰ったのは3つです。

1. 新しい仕組みを作る前に、既存処理へ相乗りできないか考える

今回は第6係を増やさず、第5係へ記事生成を追加しました。

データ取得もメールも点呼も増えていません。

2. AIにコードを書かせるなら、テストも書かせる

「東京都」に「京都」が入っている。

数分で作った単体テストが、その小さなバグを本番前に止めました。

3. 自動化するのは下書きまで。公開判断は人間に残す

文章生成まで自動化しても、最終確認は人間が行います。

AIが書く。

AIがテストする。

人が判断する。

この分業が、また一段具体的になりました。

補助金情報は毎朝自動更新しています

今回の記事下書きの元データになっている補助金情報は、

京都・滋賀 補助金新着レーダー

で公開しています。

受付中の補助金を毎朝自動更新しています。

AI社員実践記は、まだ続きます。

この記事の監修小笹 通典(オフィスピコッツ株式会社 代表取締役)
京都産業21 登録専門家(No.46)/滋賀県DX協創パートナー/デジタル庁 デジタル推進委員。2002年開業、創業25年目。京都・滋賀を中心に1万件超のWeb活用・制作に携わる。 会社概要を見る