業務自動化の相談を受けると、ほぼ必ず最初に聞かれるのが「どこまで自動化できますか」だ。

しかし、私が実際に業務で回しているハーネス群 — 事業本部の予実管理で約30本・1万行、新設拠点の運営で12本・6,000行 — を見返すと、どれも自動化率を上げにいっていない。むしろ「ここは自動化しない」と明示的に書いた箇所が、設計上いちばん重要な部分になっている。

この記事は、その設計原則と安全装置の各論である。抽象論ではなく、実際に動いているコードが守っているルールを書く。

接続を3種類に分ける

方針はひとつだけある。相手のシステムに合わせて、接続の仕方を3種類に分けることだ。

① 公開APIがあるものは、直接叩く。

もっとも安定していて、失敗しても副作用が読める。認証情報を環境変数に置いてRESTを呼ぶだけなので、壊れたときの原因も特定しやすい。ドライブへの読み書き、チャットツールへの投稿、自社PMOのToDo取得、グループウェアのユーザー情報 — このあたりは全部この経路に寄せた。

② SSOの内側にしか画面が無いものは、ブラウザを動かす。

APIが提供されていない、あるいはシングルサインオンの先にしか画面が無いもの。ここはブラウザ自動化でログインし、セッションを保存して使い回す。グループウェアの予定表とワークフロー、法人向けECサイト、クラウド経費精算がこれにあたる。

速くもなければ壊れにくくもないので、①で届くならブラウザは使わない。順序を逆にすると、後から必ず後悔する。

③ どうしても届かないものは、手作業として明示的に残す。

そして、これが3つのうち最も設計上重要な項目だ。

外部共有チャネルには投稿できない。特定のチャットツールへの書き込みが権限的に通らない。紙と電話の窓口がある。こうした制約が判明した時点で、「ここは人がやる」とドキュメントに一行書き、自動化したつもりにしない

中途半端に半自動化すると、誰も責任を持たない区間ができる。「たぶんスクリプトが送ったはず」で止まっている連絡が、いちばん危ない。届かないものは、届かないと書く。それだけで運用は安定する。

取り返しのつかない操作を、事故で起こさない

もうひとつの柱が安全装置だ。全ハーネスに共通させているものを挙げる。

既定は必ず dry-run にする。 送信・提出・注文は、明示のフラグを付けるまで起きない。稟議も経費も注文も、確認画面まで進んでキャンセルするのが既定の動きになっている。件数と未マッチ項目を目で見てから流す。

書き込み系は「下書き」で止める。 稟議申請のハーネスには、提出フラグをコードごと持たせていない。一度実装したが、方針を決めた時点で削除した。提出した瞬間に承認者へ通知が飛び、巻き戻しコストが収集系の比ではないからだ。「入力の自動化」と「提出の判断」は分ける。こうしておけば、フォームの改定で入力がズレても、被害は「下書きが変」で止まる。

共有ファイルの上書きは、版チェック付きにする。 版を取得 → ダウンロード → 編集 → アップロード直前に版を再確認 → 上げる → 再ダウンロードして検証。表計算を誰かが開いているだけで版が上がるため、これが無いと他人の編集を黙って消す。実際、この手順を入れてから台帳の版ずれ事故が構造的に起きなくなった。

証跡のスクリーンショットを残す。 ブラウザ自動化は、通過した画面をすべてファイルに落とす。「本当にその画面まで行ったのか」を後から確認できることが、ブラウザ経路を許容する条件になっている。

「押せたこと」と「効いたこと」は、別物として検証する。 これは事故から学んだ。人事評価の一括投入で、確認モーダルを開いた時点で成功扱いにしてしまい、数十名分を「提出済み」と誤って記録したことがある。実際は全員が保存止まりだった。

以後、書き込みはすべてサーバ側の状態を引き直して確認する。稟議申請も、保存前に画面から実値を読み戻して突き合わせる。これで「意図しない別プロジェクトが黙って選ばれる」不具合を実際に2件検出した。ボタンを押せたことは、意図した結果になったことを何も保証しない。

冪等にする。 同じコマンドを二度流しても壊れないようにする。申請IDで冪等にする、内容のハッシュで upsert する、投入ログを残して再実行時にスキップする、flock で定時実行の多重起動を防ぐ。運用に乗せると「途中で落ちて、どこまで進んだか分からない」は必ず起きる。そのとき安心して再実行できるかどうかが、ハーネスを日常的に使えるかの分かれ目になった。

コアを1本にして、あとは薄いラッパにする。 稟議収集のコアは240行で、売上版・見積版・請求版はそれぞれ44行のラッパでしかない。フォーム名と出力先を変えただけで、フラグの処理はすべてコアに委譲している。AI駆動でスクリプトを増やしていくと、放っておけば似て非なる実装が並ぶ。増やす前にコアを抜くことを習慣にしないと、2か月で手に負えなくなる。

依存を足さない。 ドライブ操作のスクリプトは、OAuthからアップロードまで標準ライブラリだけで動くようにした。便利なSDKを入れれば短く書けるが、環境が変わったときに動かない。ハーネスは書き捨てが前提なので、短く書けることより、置いた場所で動くことを優先している。

出力の宛先ごとに書式を変える。 チャットツールの多くはMarkdownを解釈しない。**# も記号のまま画面に出る。貼る先が決まっている文章は、貼れる形で出力する。地味だが、これを怠ると「AIが書いた感じの読みにくい文章」が現場に流れ続ける。

相手システムは一貫していない、という前提で作る

実装中に踏んだ落とし穴を並べると、共通した性質が見えてくる。

  • 同一APIでも、エンドポイントごとに命名規則が違う(一方は snake_case、他方は camelCase。逆にすると必須項目エラーで落ちる)
  • 標準ライブラリのHTTPクライアントだと弾かれるが、curl なら通る
  • 認証ヘッダの種類を間違えると401、正しくても別要因で403
  • 予定表が空でも、実体は別のカレンダー側にあって埋まっている
  • 支払方法の選択肢が、稟議側の記載と1文字違うだけで差し戻される

どれも、事前のドキュメントを読んで防げるものではない。相手システムは内部で一貫していないという前提で作り、判明した仕様は都度ドキュメントに書き戻すしかない。逆に言えば、この書き戻しさえ続いていれば、AI駆動でハーネスを増やす速度は落ちない。

効果は「測っていないこと」から書く

最後に、効果の書き方について。

新設拠点のハーネスについて、私は導入前後の所要時間を実測していない。だから「何%速くなった」とは書けない。ハーネスが無かった頃と今とでは扱う案件の量も種類も違うので、比較する母数がそもそも揃わない。

代わりに載せられるものは2つある。置き換わった操作と、落ちなくなった失敗だ。この2つは事実として確認できる。

  • 共有台帳の更新は「ダウンロード→編集→上書き」から「版チェック付きの更新」に置き換わり、他人の編集を消す事故が構造的に起きなくなった
  • 現地への連絡は「その場で打って送る」から「文案をファイルに書いてから送る」に置き換わり、いつ何を伝えたかが引けるようになった
  • 打合せの日程調整は「複数人の予定表を目で突き合わせる」から「候補を出させる」に置き換わった

削減時間を試算で盛るより、この書き方のほうが検証可能で、相手にも役に立つと考えている。


なお、ここで挙げた原則は特定のツールに依存しない。導入の順番や、どの業務から接続すべきかといった各論は、ご相談の場でお伝えできる。