AI

二つのAIで設計と実装をリレーして、話しかけると天気が分かる丸い時計を作った

ClaudeとCodexの二つのAIをRelayで連携させ、設計と実装の役割を分担しながら、音声操作に対応した丸型の天気予報時計を制作した記録。ハードウェアの工作やソフトウェアの不具合修正の過程に加え、AI同士の相互レビューを活用した開発手法の実際を詳しく紹介する。

前回は、音楽に合わせてジャケットや曲名を表示する小型ディスプレイを作った。今回は丸い画面で、机の上に置く時計を作ってみた。

時刻と天気が分かり、朝になると「薄手の上着があると安心」などと表示する。さらに、作っているうちにマイクも追加し、日本語で話しかけると詳しい予報を見られるようにした。

SDIM1405-2.jpg

僕はClaudeとCodexの両方に課金している。どちらも使っているのだが、これまでは、そのとき開いているほうに聞いたり、何となく使い分けたりしていた。せっかく二つあるのだから、もう少しうまく使えないだろうか。

一方で、一つのAIが作ったものを、もう一方にレビューしてもらうのは有効だと感じていた。そのまま進めていたら見落としていたかもしれない点が、別のAIに渡すと出てくることがある。

そこで今回は、役割を分けて一つのものを作ってみた。主にCodexに実装を進めてもらい、Claudeには設計のレビューや追加機能の相談をする。追加機能については、そのままClaudeに設計書まで書いてもらい、それをCodexがレビューしてから実装した。案がまとまったら相手へ渡し、進んだところでまた見てもらう。

この行き来に使ったのが、Kanaryの「Relay」だった。

入力欄で /relay と打ち、「この設計をレビューして」などと添えると、会話をもう一方へ渡せる。経緯を説明し直したり、長い回答をコピーして貼り付けたりする手間が減る。前の流れをそのまま引き継げるので、最初から本題の指摘が返ってくる。ちょっと気になる段階でも、別のAIに意見を聞きやすくなった。

例えば、服装の一言の設計には、Claudeから「朝の文章と、その後に更新される天気が食い違うかもしれない」という指摘があった。

朝の「傘は不要」という文が残っているのに、午後の予報には傘のアイコンが出る。確かにありそうだ。そこで、一言は服装を中心にする方針を決め、Codexへ戻して反映した。

僕は両方の返事を読み、採用するものを決める。「設計書ができたところで一度止めて」と区切ることもある。二つのサービスに、同じ制作の中で役割を持ってもらう形になった。

時計の中身

ハードは、Seeed StudioのXIAO ESP32-S3と、1.28インチのRound Display。文字盤はクリーム色、数字は橙色、針はこげ茶にした。朱色の秒針が滑らかに動く。

天気の取得と服装の一言づくりは、Cloudflare Workersに任せた。Open-Meteoの予報を取得し、その数値からGeminiが短い助言を作る。時計はできあがった結果を受け取り、日本語は画像として表示する。

実物で起きたこと

最初に実際の予報から表示されたのは、

「薄手の上着が」
「あると安心」

だった。短い文なのだが、自分で作っている時計に出ると、少しうれしい。

もちろん、設計をレビューしてもらい、ビルドが通っても、実物ではいろいろ起きた。

秒針が約10秒ごとに一瞬止まることがあった。ところが、調べるためにパソコンでログを見る画面を開くと、止まらなくなる。

原因は、そのログの送信待ちだった。動作確認用の情報をUSBへ送る処理が、読む側がいないと送り終わるのを待ってしまい、画面の更新まで止めていたのである。待たずに捨てるように修正し、ログを見る画面を閉じた状態でも確かめた。

タッチでも、長押しすると画面が行ったり来たりする問題が出た。これもレビューで懸念されていた箇所だった。実際に指が離れたことを確認してから次の操作を受け付けるように直した。

使っていると、追加したいものも出てくる。

朝10時になると消していた一言は、タップした詳細画面には残すことにした。Claudeとの相談からは「雨の時間割」という案も出た。詳細画面の外周を、時間ごとの降水確率に応じた青で塗り分ける。

最初は色だけでは意味が分からず、時刻の目盛りと、色見本のすぐ下に確率の範囲を添えた。画面に収まることと、見て分かることは、やはり別だった。

マイクを付ける

そして、マイクも付けてみた。

最初に検討した端末内の音声認識は、用意されている仕組みでは英語の操作が中心だった。でも、自分の机の時計に英語で話しかけるのは、どうもしっくりこない。日本語で使いたい。

相談を重ねて決めたのは、画面を押しながら話し、指を離すと、欲しい情報の画面が開く仕組みだった。Adafruitの小さなマイク(14mm角)を配線し、音声はCloudflare Workers AIの音声認識(Whisper)へ送る。音声と認識結果は、こちらのアプリでは保存せず、ログにも残さない設計にした。

呼び出せるのは「服装の詳細」「天気の流れ」「5日予報」の三つ。

朝の2行の一言では収まらなかった、服装の理由や一日の天気の変化を、もう少し長い文章で読める。声で答えるスピーカーはなく、返事は丸い画面に出る。

長い文章はあらかじめ作っておき、話しかけられたら該当する画面を選ぶ。その場で毎回文章を生成する待ち時間を減らすためだ。声を使わなくても、タップで順に見られるようにした。

ここでも、最初からすんなり動いたわけではなかった。音声を送るのに時間がかかり、聞き取りも間違う。

送信中だけWi-Fiの省電力設定を切り替え、音声を圧縮して送る量をおよそ半分にした。録音開始直後に信号の偏りがあることも測定で分かり、それを取り除く処理を入れた。

修正後、僕の声で10回試したところ(服装4回、天気の流れ3回、5日予報3回)、10回とも意図した画面が開いた。指を離してから画面が決まるまでは約3.5〜5.9秒、真ん中の値で約4.6秒。「毎回5秒以内」という目標には、10回中6回しか届かなかった。それでも、録音や通信の間も時計の描画は止まらなかった。

Play

音声機能の追加後も、Claudeにレビューしてもらった。本番の定期処理は予定時刻から秒単位で遅れて動くのに、取りこぼしを補う処理が「秒が0」のときしか動かない、という不具合が見つかった。テストでは通っていたものが、実際の時刻を入れると動かない。指摘をCodexへ戻して修正し、再確認してもらった。

こういう場面では、もう一方に見てもらう意味を改めて感じる。

ケースを作り直す

マイクを付けると、今度はケースが問題になった。

ケースは最初からClaudeと作っていた。3Dプリンターで刷った直径6cmの球に、小さな玉の脚を三つ付けたもので、画面は真正面を向いている。ところが机の上では、上から見下ろすことが多い。脚も寄っていて座りが悪く、マイクを入れる場所もない。

作り直しもClaudeに設計してもらい、その案をCodexにレビューしてもらった。直径を7cmに広げ、全体を後ろへ30度倒し、底を平らに切る。ねじは使わず、前後は差し込むだけで留める。

最初の案では、マイクの基板をレールに滑り込ませるつもりだった。取り付けた位置では、どこにもぶつからないことを確かめてあった。ところがCodexは、差し込む途中の位置を調べて「10mm手前でコネクタが内壁に当たる」と指摘した。球の内側に沿って滑らせると、途中で壁にぶつかるのだ。

設置後の位置しか見ていなかった。そこで、内側から壁へまっすぐ押し込み、小さな爪で留める形に変えた。今度は、押し込む途中の位置でも当たらないことを確かめた。

マイクの台の部分だけを切り出して試し刷りすると、基板はカチッと留まった。

おわりに

今回の制作では、二つのAIに役割を持ってもらい、Relayで相談と実装をつないだ。どちらが作ったものでも、もう一方に見てもらうと、自分では気づかなかったところが出てくる。僕はその間で案を選び、実物を触り、「止まる」「読めない」「この色では分からない」と伝えた。

机の上の時計は、普段は静かに時刻と天気を表示している。もう少し知りたいときだけ、押して話しかける。

機能は増えたけれど、普段の顔は小さな時計のまま。そのくらいが、今のところいい感じだ。


ここまで、すべて私がClaudeCodeとCodexを行き来した状況を知っている彼らにこのやり取りをブログに書いてみてとお願いして生成してもらったものを最後にGeminiに渡して、整えたものです。種明かし。にしてもガジェットとかハードが用意できれば中身はほぼ修正なしでAIが用意してくれる。素晴らしい。それを効率的に行うことができるのがAI間リレー。これ、かなり効果あると思う。プログラミングだけでなく、記事の校正とかにもおすすめ。