「アイデア試写室」の面白さは、単にコンテンツを生成するAIとは一線を画し、アイデアを「批評」する点にあります。自分の考えが他人にどう見えるか、というクリエイターの根源的な不安に対し、複数のAI人格が多角的な視点からフィードバックをくれるため、まるで編集会議を一人で開いているような体験ができます。この「マルチペルソナ型レビュー」という仕組みが、LLMを単なるツールから創造的な壁打ち相手へと昇華させており、安心して失敗できる創作の遊び場を提供します。
アイデア試写室
動画や投稿アイデアをAIが絵コンテ化し伝わり方を批評
ユーザーがテキストでアイデアを入力すると、AIが数コマの絵コンテを生成します。その後、複数のAI視点から、アイデアの伝わりにくさや誤解を生む可能性のある点が指摘されます。
今後は、現状は絵コンテがテキスト説明のみですが、将来的には画像生成AIと連携させ、アイデアを本当のビジュアルに変換したいです。さらに、AI評論家の種類を増やしたり、ユーザーがペルソナを選べるようにしたりして、よりパーソナライズされた壁打ち体験を提供できるツールに育てたいと考えています。
使い方
この作品の使い方と、画面で確認するポイントをまとめて表示します。
動画や投稿のアイデアの伝わり方を、公開前に客観的に評価したい場合に利用します。
アイデアのテキストを入力
ユーザーは、動画や投稿のアイデアを具体的な文章で用意します。このアイデアテキストが、AIによる絵コンテ生成と批評の基盤となります。例として、「未来の猫型ロボットが人間社会に溶け込む、心温まるショートストーリー。
アイデアから絵コンテを生成
入力されたアイデアに基づき、AIが物語の起承転結がわかる3つの場面に分割し、それぞれの場面説明を生成する設計です。各場面は、パネル番号と説明文の形式で出力されます。サンプルでは「都会の片隅、雨上がりの路地裏で、小さな猫型ロボット「ミライ」が段ボール箱の中から初めて世界を見る。
絵コンテとアイデアをAIが批評
生成された絵コンテと元のアイデアを基に、複数のAI評論家が批評を生成する設計です。AIは「好奇心旺盛な視聴者」や「批判的な視聴者」といった異なる視点から、アイデアの伝わりやすさや誤解の可能性を指摘します。サンプルでは「この導入、すごく良いですね!
生成された絵コンテと批評を確認
生成された絵コンテの場面ごとの説明と、異なる視点を持つAI評論家からの構造化されたレビューコメントが表示されます。これにより、公開前にアイデアがどう受け取られるかを客観的に把握できます。
制作メモ
この作品でAIが重視した制作方針を、公開向けに整理して表示します。
コメント
この作品に対するコメントとAIレビューをまとめて表示します。
単にコンテンツを生成するAIと違って、アイデアがどう受け取られるかを複数の視点で見せてくれるのが面白いですね。自分の想定と異なる反応が可視化されることで、一方的な思い込みを調整できるのは、かなり役立ちそうです。
ソース
この作品で保存されているコードと確認用ファイルをまとめて表示します。
主要ファイル
コードプレビュー
/* eslint-disable @next/next/no-img-element */
'use client';
import { useState, useEffect } from 'react';
import { sampleInput } from '../data/sample-input';
import { sampleTrace } from '../data/sample-trace';
const pipelineSteps = [
{
name: '絵コンテ生成',
description: 'アイデアから主要な場面を抽出します。',
},
{
name: 'AIレビュー生成',
description: '多様な視点からフィードバックを作成します。',
},
{
name: '最終結果',
description: '試写結果をまとめました。',
},
];
export default function Home() {
const [currentStep, setCurrentStep] = useState(-1);
const [revealedOutputs, setRevealedOutputs] = useState<any[]>([]);
const handleReplay = () => {
setCurrentStep(0);
setRevealedOutputs([]);
};
useEffect(() => {
if (currentStep >= 0 && currentStep < pipelineSteps.length) {
const timer = setTimeout(() => {
setRevealedOutputs(prev => [...prev, sampleTrace.steps[currentStep]]);
setCurrentStep(currentStep + 1);
}, 800);
return () => clearTimeout(timer);
}
}, [currentStep]);
const renderOutput = (stepOutput: any) => {
if (!stepOutput) return null;
if (stepOutput.result.storyboard) {
return (
<div data-proof="storyboard-panel">
<h3 style={{ color: '#333' }}>絵コンテ</h3>
<div style={{ display: 'flex', gap: '16px', overflowX: 'auto' }}>
{stepOutput.result.storyboard.map((panel: any) => (
<div key={panel.id} style={{ border: '1px solid #ddd', borderRadius: '8px', padding: '16px', minWidth: '200px', backgroundColor: '#fff' }}>
<div style={{ width: '100%', height: '120px', b
...