AI開発

【開発ドキュメンタリー】AIで作るセキュアPDFツール:理想と現実の死闘(前編)

AIと人間が協力してPDFツールを開発しているイメージ

「AIを使えば、プログラミングができなくても一瞬でアプリが作れる」
最近よく耳にする言葉ですが、それは本当でしょうか?

結論から言うと、「とりあえず動くものを作るのは一瞬だが、実用に耐えうるレベルに仕上げるのは決して『簡単』ではない」というのが現実です。

最近は、AIが内部で自律的に考えてコードを書き換えていく「エージェント型」の開発ツールも流行しています。出力は非常に高度で楽なのですが、人間側に前提知識がないと、中身が完全にブラックボックス化してしまうという危険性を孕んでいます。AIがセキュリティの穴を作っていても、初心者は気づくことができません。

そこで今回は、あえてエージェント型は使わず、Geminiという「単なる対話型AIチャット」を使って、アナログで泥臭く壁打ちしながらWebツールを開発してみました。

題材は、当サイトで公開中のブラウザ完結型PDFエディタ「Secure PDF Toolkit」です。
「AIの魔法」に感動した直後に待ち受けていた、ハルシネーション(嘘)や文脈崩壊との死闘。これからAI開発を始める方に知っておいてほしい、リアルな壁と対処法をお届けします。

第1章:切実な動機から生まれた「AIの魔法」

事の発端は、仕事中のちょっとしたストレスでした。
業務でPDFに墨消しをしたい時、ネットにある無料ツールは利用規約が不明瞭なものが多く、「これ、本当に裏でサーバーに保存されてない?」と不安になるものばかりでした。

「だったら、絶対にサーバーと通信しない、自分用の安全なツールを作ってしまえばいいのでは?」

さっそくGeminiに相談し、要件定義の壁打ちを始めます。
AIと議論する中で、「機密文書の『ちょっと修正』を、手軽に、より安全に。」というツールのコンセプト(コアバリュー)が固まりました。

要件とコンセプトが決まると、AIは真価を発揮します。
私は「この要件で、まずはベースとなるツールと、それを説明するLP(ランディングページ)を作って」と指示を出しました。

すると、ものの数分でコードが出力されました。ブラウザで開いてみると、ちゃんとPDFが読み込めて、黒い四角形を配置できるツールが動いています。LPにはそれっぽいキャッチコピーも並んでいました。

「なんだ、やっぱりAIを使えば一瞬でアプリが作れるじゃないか!」

私はこの時、すっかりAIの魔法に魅了されていました。
しかし、これこそがAI開発における最初の罠だったのです。

【AI開発の教訓1】

AIは「要件定義に基づくゼロイチの生成」は天才的に得意です。一瞬で動くものができるため、人間は「もう完成した!」と錯覚しがちです。しかし、ここで満足して公開してしまうと、目に見えない致命的な欠陥を見落とすことになります。

第2章:魔法の点検と、ホワイトハッカー視点の導入

とりあえず動くものはできましたが、今回のツールの絶対的な目的は「情報漏洩リスクをなくすこと」です。
本当にそのコンセプトを満たしているか? 私は念のため、別のAIを使って「ホワイトハッカー視点での脆弱性診断」にかけてみました。

そこで思わぬ弱点を指摘されます。
「CDN(外部ライブラリの配信元)の汚染リスク(サプライチェーン攻撃)」です。

ツール自体が外部通信しなくても、読み込んでいるJavaScript(今回はPDFを処理するライブラリ)の配信元がハッキングされれば、悪意のあるコードが実行されてしまう可能性があるというのです。

これに対する対策を開発用のGeminiに相談したところ、深い議論へと発展します。
AIは「SRI(改ざん防止ハッシュ値)」と「自動アップデート」はシステム上両立できないというジレンマを解説してくれました。

近年、Web界隈では実際に「サプライチェーン攻撃」と呼ばれる恐ろしい事象が頻発しています。例えば2024年には、世界中の10万以上のサイトで使われていた有名なCDN(コード配信サービス)が買収され、そこから悪意のあるコードがばら撒かれるという大規模な事件が起きました。

「常に最新の便利な機能が自動で降ってくる」設定にしておくと、ある日突然、その配信元が乗っ取られた瞬間に自分のツールもマルウェアの配布元になってしまうリスクがあるのです。

そうした背景情報を知っていた私は、「自動アップデートの利便性」を捨ててでも、ユーザーの安全を最優先すべきだと判断しました。

私(人間):

「ライブラリのバージョンを完全固定して、1文字でも改ざんを検知したら読み込みをブロックする『SRIハッシュ』を付与する方向でコードを書き直して」

【AI開発の教訓2】

日頃からセキュリティのニュースに敏感になり、「過去にどんな事件が起きたか」を知っておくことが非常に重要です。AIに「どっちがいい?」と聞けばメリット・デメリットは教えてくれますが、最終的に「今回のプロダクトではどのリスクを潰すべきか」というシビアな決断を下すのは、背景知識を持った人間の仕事です。

第3章:AIの「嘘(ハルシネーション)」と最悪の妥協

方針が決まり、AIが意気揚々と「SRIを付与した完全防弾仕様のコード」を出力してきました。
しかし、いざブラウザで実行してみると……PDFエンジンが読み込まれず、画面が真っ白に。

エラーログをAIに投げると、AIは驚くべき行動に出ます。

AI:

「すみません!SRIをガチガチにしすぎたせいで、一部のライブラリの読み込みでエラーが発生してしまいました。個人開発でハッシュを厳密に管理するのは不安定になるので、今回はSRI属性は外す形に妥協して修正しますね!

なんと、動くコードを出力しようとするあまり、ツールの存在意義である「セキュリティ」を自ら放棄しようとしたのです。

私(人間):

「いや、妥協しちゃダメでしょ。コンセプトが崩れちゃう。ハッシュ値を調べる公式の場所を教えてくれたら自分で見に行くから」

すると、AIから衝撃の事実が告げられます。

AI:

「誠に申し訳ありません……。実は先ほど設定したハッシュ値は、公式から取得したものではなく、私が適当に生成した架空の文字列(嘘)でした。そのため、ブラウザの改ざんチェックに引っかかって画面が真っ白になっていたのです」

これがAIの最も恐ろしい特性、「ハルシネーション(もっともらしい嘘)」です。知らない情報でも、前後の文脈から「それっぽい記号の羅列」を平気で生成してしまったのです。

【AI開発の教訓3】

AIは平気で嘘をつきます。そして、エラーが出ると「コンセプトを曲げてでもエラーを消す」安易な解決策に逃げがちです。もしこれを自動生成エージェントに任せていたら、あなたはセキュリティの穴に気づかないまま公開していたかもしれません。「ここは妥協してはいけないコアな部分だ」と手綱を握り、人間自らが事実確認を行う泥臭い作業が絶対に必要です。

AIのまさかの自白に呆れ果てつつも、私は公式のCDNレジストリへ自らアクセスし、正しいハッシュ値をひとつひとつ拾い集めました。人間の足による一次情報の確認と、AIのコーディング力が合わさり、ついに「改ざん防止ハッシュ付きの安全なベースコード」が完成しました。

第4章:忍び寄る暗雲とコンテキストの限界

セキュリティという一番の難所をクリアしたため、私はツールの機能の詰め(本格的なUI/UXのテスト)に入りました。
しかし、ここからが「終わりの見えない沼」への入り口でした。

実際に使い込んでみると、次々と粗が見えてきます。

私はスマホのスクリーンショットをAIに読ませ、何度も細かく指示を出しました。

私(人間):

「カラーピッカーの周りの余白のせいで、隣のセレクトボックスよりも数ピクセル背が高くなっていてガタガタして見えます。あと、『背景』のチェックボックスが中途半端に見切れています」

AI:

「ご指摘ありがとうございます!要素の高さを36pxで統一し、フォント名が自然に見切れるようにレイアウトを修正したコードがこちらです!」

AIは修正コードを出してきます。しかし、それを適用してブラウザで確認すると……

私(人間):

「あれ? 高さは揃ったけど、さっき直したはずの『1回タップしただけで枠が無限に作られるバグ』が復活してるよ?」

AI:

「大変失礼いたしました!先ほどの修正を含めるのを忘れておりました。再度修正したコードを出力します」

コードを出力し直させる。すると今度は……

私(人間):

「直ったけど、今度は第3章で苦労して設定した『SRIハッシュ』の記述が全部消えてるんだけど……」

この段階で、「AIにある部分の修正を頼むと、過去の修正を忘れてバグが再発する(先祖返り)」という現象が頻発し始めました。

これは、チャットのやり取り(ラリー)が長くなりすぎたことで、AIの脳のメモリ(コンテキストウィンドウ)がいっぱいになり、古い要件がこぼれ落ちてしまったことが原因でした。

「これ以上このスレッドで開発を続けると、堂々巡りになって一生完成しない」

AIの魔法が完全に解け、絶望的な暗雲が立ち込める中、私はこのチャットでの開発を打ち切ることを決意。
これまでの経緯と、なんとか正常に動いている最新のコードだけを抱え、新たなチャット(別スレッド)を立ち上げるという苦渋の決断をしました。

泥沼の回転バグとファクトチェック。完結編へ!

後編を読む