AIと二人三脚!GASでGoogleスライドに家系図を自動生成した話
こんにちは! AIとGAS開発、はじめました。
目次
こんにちは!
最近、AIと一緒にちょっと面白いことに挑戦してみたので、その記録をブログにしてみようと思います😊
テーマは、「Google Apps Script(GAS)を使って、Googleスライドに家系図を自動で描く!」というもの。ただコードを書いてもらうだけじゃなくて、私が細かく指示を出しながら、AIと二人三脚でゴールを目指す、そんなプロジェクトです。
この記事では、AIが最初に作ってくれたコードに潜んでいた意外な問題点や、それをどうやって解決していったのか、試行錯誤のプロセスをまるっとお届けします。GASを勉強中の方や、AIとの付き合い方に興味がある方の、何かのヒントになったら嬉しいです。


まずは「お約束」決め! 失敗から学んだ鉄壁のルール
今回の目標は、ビザンツ帝国マケドニア朝の祖、バシレイオス1世の家系図を作ること。歴史ロマンを感じますよね! でも、ただ描くだけじゃありません。今後のためにも、安定して動くちゃんとしたものを作りたい……。そこで、過去の苦い経験から学んだ、いくつかの「お約束」をAIに伝えました。
【私たちの開発ルール】
- レイアウトは賢く自動で!
- 人数や世代に合わせて、図形の大きさや場所はスクリプトが自分で考えて決めること。
- 作ったものがスライドからはみ出さないように、ちゃんと中に収めること。
- 図形や線がぐちゃっと重なったりしないように、キレイに並べること。
- 並べ方のルール
- 親子はちゃんと別の世代(階層)に置くこと。
- 夫婦やパートナーは同じ世代に。一人目のパートナーはすぐ右隣、二人目からはその下に並べていくこと。
- 線の引き方ルール
- 線を描くときは、ちゃんと
Lineオブジェクトを使うこと。 - これが最重要! 「BENT」(カギ線)は絶対に使わず、全部「STRAIGHT」(直線)で描くこと。
- どうしてもカクっと曲げたい線は、まっすぐな線を何本か組み合わせて、それっぽく見せること。
- 線の接続は、親子なら上下に垂直、夫婦なら左右に水平に。きっちり90度を守ること!
- 線を描くときは、ちゃんと
- その他
- とにかく、今まで遭遇したエラーが二度と起きない、たくましいコードにすること。
特に大事なのが、三つ目の「BENT(カギ線)は絶対に使わない!」というルール。以前、GASが賢く線を曲げてくれるBENTを使ったら、図形が真上や真横にあるだけでThe width should not be zero(幅がゼロだよ!)というエラーが出て、すごく困った経験があったんです。だから今回は、その便利な機能をあえて封印することにしました。
AIからの提案コードと、思わぬ「うっかりミス」
これらのルールを伝えて、AI(Gemini)が作ってくれたのが最初のコード。以前のエラー(moveメソッドがない問題)をちゃんと乗り越えた「計算が先、描画が後」というスマートな作りで、「お、さすが!」と思いました。
でも、よーく見てみると……。
「あれ……? これって……」
一番大事にしようねって話していたルールを、なんとAI自身が破ってしまっていたんです!
// 【問題があったコードの一部】
function drawElementsOnSlide(slide, nodes, lines, sizes) {
// ……(中略)……
lines.forEach(lineInfo => {
// ……(中略)……
if (lineInfo.type === 'parent_child') {
// ▼問題点1:親子関係にBENT(カギ線)を使ってる!
line = slide.insertLine(SlidesApp.LineCategory.BENT, startX, startY, endX, endY);
}
else if (lineInfo.type === 'spouse') {
// ……(中略)……
// ▼問題点2:二人目以降のパートナーにもBENTが……!
const lineCategory = (spouseOrder === 0) ? SlidesApp.LineCategory.STRAIGHT : SlidesApp.LineCategory.BENT;
line = slide.insertLine(lineCategory, startX, startY, endX, endY);
}
});
}
親子関係にも、二人目以降のパートナーにも、使わないでおこうねって約束したはずのSlidesApp.LineCategory.BENTが使われていました。これじゃあ、また同じエラーで悩むことになっちゃう!
AIに聞いてみたら、どうやら「カギ線は複雑な接続を自動でやってくれる便利な機能」という一般的な知識が、今回の「APIのクセを避けるための特別なルール」より優先されちゃったみたい。AIって賢いけど、こういう人間的な「今回はこっちが大事!」っていうニュアンスを伝えるのって、すごく大事なんだなと実感しました。
解決策は、地道で確実な「手作りカギ線」!
問題が見つかれば、あとは直すだけ!
今回の修正のメインイベントは、drawElementsOnSlide関数を作り直して、「BENT(カギ線)を使わずに、直線だけでカギ線っぽく見せる」ことでした。
1. 親子をつなぐ線の作り直し
親子をつなぐカギ線って、よく見ると三つのパーツでできていますよね。
- 親からまっすぐ下に伸びる線
- 子のいる場所まで水平に移動する線
- そこから子の真上までまっすぐ下に伸びる線
この三つのパーツを、それぞれ独立した「まっすぐな線」として描くことにしました。
// 【改善後】親子関係の線の描き方
const startX = fromNode.left + NODE_WIDTH / 2;
const startY = fromNode.top + NODE_HEIGHT;
const endX = toNode.left + NODE_WIDTH / 2;
const endY = toNode.top;
// 親と子のちょうど真ん中の高さ
const midY = startY + (endY - startY) / 2;
// 3本の直線で、カギ線を手作り!
const line1 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, startX, startY, startX, midY);
const line2 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, startX, midY, endX, midY);
const line3 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, endX, midY, endX, endY);
ちょっと手間はかかるけど、この方法ならどんな配置でもエラーが出ないので、すごく安心です。
2. パートナーをつなぐ線の作り直し
二人目以降のパートナーをつなぐ線も同じ作戦です。主たる人物の右側から出て、きゅっと下に曲がって、パートナーの左側につながる、あの線です。
これも三本の直線で再現します。
// 【改善後】二人目以降のパートナーの線の描き方
const startX = fromNode.left + NODE_WIDTH;
const startY = fromNode.top + NODE_HEIGHT / 2;
const endX = toNode.left;
const endY = toNode.top + NODE_HEIGHT / 2;
// 曲がり角(エルボー)のX座標
const elbowX = startX + HORIZONTAL_SPACING / 2;
// こちらも3本の直線で、カギ線を手作り!
const line1 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, startX, startY, elbowX, startY);
const line2 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, elbowX, startY, elbowX, endY);
const line3 = slide.insertLine(SlidesApp.LineCategory.STRAIGHT, elbowX, endY, endX, endY);
これで、すべての線が「STRAIGHT」だけで描かれるようになって、一番の懸念事項をクリアできました!
完成! 私たちの作った、思いやり設計のスクリプト
こうして出来上がった最終版のコードは、エラーが出ないだけじゃなくて、後から見返したときにも分かりやすいように、色々な工夫を詰め込みました。CONFIGオブジェクトで色やサイズの設定をまとめて管理できるようにしたり、一つ一つの関数が何をしているのかコメントをしっかり書いたり……。
今回のプロジェクトを通じて、AIは魔法の杖じゃないんだなって、改めて感じました。AIがすごいスピードでコードを書いてくれても、最終的に「本当にこれでいいんだっけ?」って、目的や背景を一番分かっている人間が確認して、軌道修正してあげることが大事なんですね。
さいごに:AIとのペアプロを終えて
大変だったけど、すごく勉強になったし、何よりAIと協力して一つのものを作り上げるのは、とっても楽しかったです!
このブログが、誰かの「やってみよう!」のきっかけになったら、すごく嬉しいです。