【ITニュース解説】Building a Bedtime Stories App
2025年09月22日に「Dev.to」が公開したITニュース「Building a Bedtime Stories App」について初心者にもわかりやすく解説しています。
ITニュース概要
AppleのFoundation ModelsとImage Playgroundを活用し、寝物語アプリを開発した。これらはデバイス上でテキストと画像を生成でき、高速性とプライバシーを両立する。構造化された出力や的確なプロンプト設定が重要で、互換性確認やエラー処理も開発の成功に不可欠だ。
ITニュース解説
Appleの最新技術であるFoundation ModelsとImage Playgroundを活用し、子ども向けの寝かしつけ物語アプリが開発された。このアプリは、デバイス上で物語のテキストと画像を生成するという特徴を持つ。これにより、処理が高速に行われ、ユーザーのプライバシーが保護される利点がある。本記事では、このアプリのバックエンドロジック、具体的には構造化された物語の生成方法や画像の作成方法について、開発者が得た知見が詳細に解説されている。
まず、開発環境のセットアップが重要だ。アプリを安定して動作させるためには、互換性を確認する必要がある。具体的には、iOS 18以降、またはmacOS 15以降のApple Silicon(A17 Pro、M1チップ以降)を搭載したデバイスが必須で、Apple Intelligenceが有効になっている必要がある。XcodeではFoundationModelsとImagePlaygroundという二つのフレームワークをインポートする。FoundationModelsはテキスト生成を、ImagePlaygroundは画像生成を担当する。モデルデータは初回使用時にダウンロードされるが、サポートされていないデバイスを早期に特定するため、利用可能性を事前に検証することが推奨される。
次に、生成される物語の構造を定義する。大規模言語モデル(LLM)が混乱しないよう、構造体はシンプルに保つことが重要だ。開発者は@Generableマクロを用いてStoryResponseという構造体を定義した。この構造体は、物語のタイトル、段落、画像の説明、カテゴリ、概要、登場キャラクターといったフィールドを持つ。特に、段落はParagraphというネストされた構造体として定義されており、各段落の順序とテキストを保持する。各フィールドには@Guideアノテーションが付与されており、これはLLMに対して「タイトルは5語以内」「画像説明は物語を補完するもの」といった具体的な指示を与える役割を果たす。これにより、期待通りの、質の高い出力を得ることが可能となる。
モデルとセッションの初期化も重要なステップだ。まず、SystemLanguageModel.defaultを使用してデフォルトの言語モデルを取得する。モデルが利用可能かどうかをmodel.availabilityで確認することで、Apple Intelligenceが無効なデバイスや古いハードウェアでの問題を早期に検知できる。次に、LanguageModelSessionを初期化し、セッションに明確な指示を与える。この指示は、モデルが「3歳から7歳の子ども向けの語り部」として振る舞い、シンプルで夢のような言葉遣いとポジティブなテーマを使用するよう促すものだ。また、出力する要素(タイトル、段落数、画像説明など)の形式もここで指定する。明確な指示がないと、予期せぬランダムな物語が生成される可能性があるので注意が必要だ。
プロンプトの作成は、LLMから望ましい応答を引き出すための鍵となる。特にAppleのローカルモデルからクリーンで安全な応答を得るには、具体的で詳細なプロンプトが必要だ。開発者は、子どもの名前や物語のテーマ(例:「空を飛ぶことを学ぶ勇敢な小さなドラゴン」)をプロンプトに含め、生成してほしい要素(5語以内のタイトル、3〜5段落、主要なシーンの画像説明など)を箇条書きで明確に指定した。さらに、物語のトーン(楽しく、心を落ち着かせ、忍耐力をテーマに)も明記する。加えて、GenerationOptionsオブジェクトで生成時のオプションを設定する。temperatureは0.7に設定され、これは創造性を保ちつつも、あまりに予測不能にならないように調整する値だ。0.8を超えると物語がランダムになりすぎることが分かったという。maximumResponseTokensは応答の最大長を制限し、今回の場合は約300〜400語に相当する600トークンに設定された。
言語モデルからのレスポンスをストリーミングで受け取り、画像を生成するプロセスも解説されている。session.streamResponseメソッドは、言語モデルからの部分的な応答をリアルタイムで処理することを可能にする。この際、StoryResponse型のバッファ変数をデフォルト値で初期化し、ストリーミング中に受け取った部分的な応答を累積していく。これにより、最終的な完全な物語の構造体が得られる。ストリーミング中は、部分的に生成されたタイトルや段落、画像説明などの内容がログに出力され、デバッグに役立つ。物語のテキスト生成が完了したら、ImageCreatorを使用して画像を生成する。ImageCreatorは、生成されたfinalStory.imageDescriptionを基に画像を生成する。ImagePlaygroundStyle.animationを指定することで、子ども向けの親しみやすいアニメーションスタイルの画像が生成される。この際、画像生成モデルが人物の描写に制約があるため、動物や物体、環境定義に焦点を当てた短く具体的な画像説明(例:「光る森の上のドラゴン」)がより良い結果を生むと述べられている。
開発中にはいくつかのエラーに遭遇し、その解決策が共有されている。テキスト生成では、長すぎるプロンプトが原因で.tokenLimitExceededエラーが発生したが、maximumResponseTokensを600に設定することで解決した。画像生成では、不適切なimageDescriptionが原因でエラーが出たが、プロンプトを調整することで改善された。ストリーミング処理では、部分的な応答の扱いに苦労したが、storyBufferに値を累積することで解決した。最適化の観点からは、テキスト生成ではtemperatureを0.6から0.8の範囲に保ち、セッションを再利用して文脈を維持することが推奨される。画像生成では、短いimageDescriptionを使い、速度のために1枚の画像に限定することが効果的だ。また、古いApple Siliconデバイスでは画像生成に遅延が生じるため、実機でのテストが重要だと指摘されている。
さらに高度な拡張機能として、プロンプトを連鎖させる方法も紹介されている。例えば、まず物語のテーマからタイトルだけを生成し、そのタイトルを含めて全体の物語を生成する、というように複数の推論ステップを踏むことで、より洗練された物語を作り出すことができる。また、ユーザーの好きな動物などの入力を用いて物語をパーソナライズしたり、セッションを再利用して物語の続編を生成したりすることも可能だ。これにより、ユーザーにとってより魅力的で一貫性のある体験を提供できる。
この寝かしつけ物語アプリの開発を通じて、AppleのFoundation ModelsとImage Playgroundを組み合わせて、高速でプライバシーが保護されたストーリーテリングエンジンを構築する方法が示された。@GenerableマクロはStoryResponseの出力を構造化し、streamResponseはリアルタイムでのテキスト生成を可能にし、ImageCreatorは子ども向けのビジュアルを追加した。開発者にとっての重要な教訓は、デバイスの互換性を早期に確認すること、正確なプロンプトを作成すること、そしてLLMの問題を避けるために構造体をシンプルに保つことだ。ターゲットデバイスでのテストはパフォーマンスのボトルネックを発見するのに役立ち、imageDescriptionの微調整は動物、物体、環境定義のみを含む適切な表現で堅牢な画像を生成するために重要だった。今後の改善点としては、プロンプトの調整による多言語サポートやAppleの音声APIとの連携によるナレーション追加、ImagePlaygroundStyleの他のオプションの試行や物語ごとの複数画像の生成によるビジュアル強化などが考えられる。キャラクターの背景を事前に生成するなど、推論を連鎖させることで物語を深めることもできるだろう。まずは小さく始め、頻繁にテストし、プロンプトを洗練させることがLLMの出力を最大化するための鍵となる。