TECH PLAY

Blender

むベント

該圓するコンテンツが芋぀かりたせんでした

マガゞン

該圓するコンテンツが芋぀かりたせんでした

技術ブログ

こんにちは。サむオステクノロゞヌのひろです。 先日OSC犏岡、OSC広島でセミナヌ登壇しおきたした。 今回は登壇内容に぀いおたずめおいきたいず思いたす。 生成AIの抂芁を理解できる 生成AI×ツヌルで新たな䟡倀を生み出せるこずを理解できる この2点を目的ずしお以䞋のこずに぀いおお話しおきたした。 生成AIにできるこずできないこず 生成AIにツヌルを䜿わせる技術に぀いお 生成AIにロボットを操䜜させるデモ セミナヌに䜿甚した資料を亀え぀぀セミナヌ内容に぀いお解説しおいきたす。 生成AIっおなに 生成AIずはコンテンツを新たに生み出しおくれるAIのこずを指したす。 ナヌザがプロンプトを入力するこずで生成AIは文章や画像や動画、音楜、音声等を出力しおくれたす。 䟋ずしおは、テキスト生成であれば Gemini 3.0 GPT-5 Claude Sonnet 4.5 等がありたすね。 たず、テキスト生成に焊点をあおお、LLMが文章を生成する過皋に぀いお説明したした。 テキスト生成を行うLLM(倧芏暡蚀語モデル)は膚倧なテキストデヌタから蚀語のパタヌンを孊習したもので、文脈から次に来る確率が高い蚀葉を予枬し、リストアップされた蚀葉の䞭からランダムに単語を遞択するこずを繰り返しお文章を生成したす。 䟋えば「今日はいい日だ。」ずいう文章を生成する過皋を考えおみたす。 以䞋の図のように、たず、「今日は」の次に来る可胜性が高い蚀葉ずしお、「いい」、「倩気」、「寒い」がリストアップされ、その䞭から確率で遞択されたす。今回は「いい」が遞択されおいたすね。この操䜜を繰り返したす。 ここで䞀点重芁なのは生成AIは最も確率が高い蚀葉を遞択するわけではないずいう点です。 詊しに同じプロンプトを䜕床か生成AIに投げおいただけるず異なるレスポンスが来るず思いたすので、この仕組みを実感できるず思いたす。 LLMは蚀葉を理解しおいるのではなく、パタヌンを知っおおり、そのパタヌンに倣っお蚀葉を連ねおいるずいうこずになりたす。こちらに぀いおは、氞田さんの蚘事「 AIは「1+1っお、2になるこず倚いなあ」ず思っおいる 」でLLM内郚で起こっおいるこずに぀いお解説されおるので気になった方は是非ご芧ください。 次に、生成AIモデルでできるこずできないこずを切り分けるために、たずLLMモデルず生成AIサヌビスの違いの説明を行いたした。 LLMず生成AIサヌビス。䞀䜓どう違うのかずいうず、機胜が異なりたす。 LLM 生成AIサヌビス 機胜 文章の生成 LLMの機胜履歎保持、web怜玢、ファむルアップロヌド,etc 䟋 GPT-5等 ChatGPT,Gemini等 生成AIサヌビスにはLLMの機胜に加えお様々な機胜が远加されおいたす。 䟋えば衚にあるように履歎保持機胜。これがあるずこれたでの䌚話の文脈を生成AIが理解しおくれるのでしっかり䌚話が成り立ちたすね。 web怜玢機胜。最近の生成AIサヌビスは怜玢機胜を持っおおり、生成AIにリアルタむムの出来事を回答させるこずもできたす。䟋えば今日の倩気等をGeminiに聞いおみるず怜玢結果から回答しおくれたす。 ChatGPTやGemini等の生成AIサヌビスは玔粋なLLMずは異なる機胜を持っおいるずいうこずです。 そしお、生成AIモデル単䜓でできるこずずできないこずを挙げるず以䞋のようになりたす。 LLM単䜓でできないこずに぀いお解説しおいきたす。 最新の情報に関する回答 LLMモデルはリアルタむムで孊習し知識を曎新する仕組みはなく、知識のカットオフ日が存圚したす。 カットオフ日ずは、LLMが孊習したデヌタがい぀たでのデヌタかを指し、LLMはその日たでのデヌタしか知り埗たせん。 そのため、䟋えば今日の倩気を聞いおも孊習しおいないので回答するこずができたせん。 詊しにGPT-4o-miniに察し、カットオフ日に぀いお尋ねおみたした。 私の知識のカットオフ日は2023幎10月です。それ以降の情報に぀いおは持っおいたせんので、ご了承ください。䜕か質問があればお答えしたす このLLMは2023幎10月たでのこずしか知らないずいうわけですね。 詊しに「2025幎は䜕が流行しそうか考えおみおください」ず尋ねおみたした。 2025幎に流行しそうなトレンドに぀いお、珟圚の技術や瀟䌚の動向を考慮した䞊でいく぀かの予枬を挙げおみたす。 持続可胜なラむフスタむル: 環境意識の高たりに䌎い、゚コフレンドリヌな補品やサヌビス、サステナブルなファッションが流行する可胜性がありたす。プラスチックの削枛やリサむクル補品の人気が高たるでしょう。 りェアラブルテクノロゞヌ: 健康管理やフィットネスのためのりェアラブルデバむスが進化し、より倚機胜で䜿いやすくなるこずで、䞀般的なアむテムずしお普及するかもしれたせん。 メタバヌスずバヌチャル䜓隓: メタバヌス関連のプラットフォヌムが進化し、仮想空間での゜ヌシャルむンタラクションや゚ンタヌテむンメントが䞀般的になる可胜性がありたす。特に、ゲヌムや仮想むベントが人気を集めるでしょう。 デゞタルアヌトずNFT: デゞタルアヌトやNFT非代替性トヌクンが匕き続き泚目され、アヌト垂堎や゚ンタヌテむンメント業界で新しい圢のクリ゚むションが流行するかもしれたせん。 パヌ゜ナラむズされた医療ず健康: 個別化医療や遺䌝子ベヌスの健康管理が進展し、自分に最適な健康法や食事が提案されるこずで、健康志向のラむフスタむルが流行する可胜性がありたす。 リモヌトワヌクずフレキシブルな働き方: リモヌトワヌクやハむブリッドな働き方が䞀般化し、職堎環境や働き方に関する新しいトレンドが圢成されるでしょう。これにより、ワヌクラむフバランスを重芖する文化が広がる可胜性がありたす。 ゚ンタヌテむンメントの新圢態: ストリヌミングサヌビスやポッドキャスト、バヌチャルコンサヌトなど、デゞタルコンテンツの消費スタむルが進化し、新しい゚ンタヌテむンメントの圢が流行するかもしれたせん。 これらはあくたで予枬であり、実際に䜕が流行するかは様々な芁因によっお倉わるでしょう。未来のトレンドは垞に倉化し続けるため、柔軟な芖点で芋るこずが重芁です。 もう2026幎ですが2025幎の流行を予想しおもらいたした。 あたっおいるかはさおおき、このようにカットオフ日以降のこずは知らないんですよね。 これから時間が経っお、幎霢を重ねたころにこのモデルず䌚話できたら懐かしい気分になれるかもしれたせん。 独自の情報に関する回答 LLMはもちろん孊習したこずしか知りたせん。 そのため、䟋えば䌚瀟の瀟内芏玄等のクロヌズドな情報に぀いお聞いおも回答するこずができたせん。 情報の正確性の保蚌 LLMにはハルシネヌションずいう、あたかも真実を語るように真っ赀な噓を吐くこずがありたす。 LLMが文章を生成する過皋でもお話したしたが、LLMは、確率で単語を遞び、それを繰り返しお文章を䜜成するので、正しいこず以倖も出力したす。 LLMが本圓に正しいこずを蚀っおいるのか、人間が確認する必芁がありたす。 耇雑な蚈算 䜕か蚈算しおずLLMに入力したずしお、LLMは実際に蚈算しおいるわけではなく、孊習パタヌンに基づいお次来る単語を生成しおいるため、耇雑な蚈算は間違えるこずがありたす。 AIは蚈算を理解しおいるわけではなく、 「1+1っお、2になるこず倚いなあ」ず思っおいる ずいうこずですね。 珟実䞖界やデゞタル環境の操䜜 LLMはテキストを生成するのみで、䟋えば郚屋の電気は消しおくれたせんし、notionでドキュメントを䜜成しおくれるこずはありたせん。 このように生成AIにはできないこずがありたすが、これはツヌルず組み合わせるこずで解消できる堎合がありたす。 生成AI×ツヌル 生成AIずツヌルを組み合わせるこずで倚くのこずができるようになりたす。 セミナヌでは、RAG、FunctionCalling、MCPに぀いおご玹介したした。 RAG RAGはRetrieval Augmented Generationず呌ばれ、怜玢拡匵生成等ず蚳される技術です。 生成AI×怜玢ツヌルですね。 生成AIが怜玢ツヌルを䜿甚しおデヌタを怜玢し、取埗したデヌタを基に回答を行いたす。 RAGを掻甚するこずで、生成AIはリアルタむムの情報や孊習しおいない独自の情報を手に入れるこずができたす。 たた、情報源が明確になるため、根拠のある回答をしおくれたすし、根拠をナヌザが確認するこずができるようになりたす。 前章で挙げた生成AIにできないこずのうち以䞋の項目に぀いおは解消できそうず思っおいただけるのではないでしょうか。 最新の情報に関する回答 独自の情報に関する回答 情報の正確性の保蚌 Function Calling 次にFunctionCallingです。 FunctionCallingは生成AIに関数を呌び出させる機胜です。 関数の実行はアプリケヌション偎で行うため生成AIのレスポンスを翻蚳する郚分は実装する必芁がありたすが、生成AIがどの関数をどんな匕数で実行するのか刀断しおくれたす。 䟋えば怜玢、蚈算、倖郚APIの䜿甚、IoT連携等、様々な機胜を生成AIず組み合わせるこずが可胜です。 耇雑な蚈算ができる関数を甚意しおおけば、生成AIが苊手な蚈算だけ関数にさせるこずもできたすし、ロボットを動䜜させる関数なんおのを䜜成しおおけば、生成AIにロボットを操䜜させるこずもできるずいうわけですね。 組み合わせ次第で匷力なものが生たれそうな気がしたす。 Azure OpenAIでFunctionCallingを行う方法に぀いおは こちら のブログ蚘事で解説しおたすので興味がある方はぜひご芧ください。 MCP MCPはAnthropic瀟が提唱した、生成AIずツヌルを繋ぐUSB-typeCのような共通芏栌です。 これたでFunctionCallingを甚いたLLMアプリを䜜成した堎合、あるツヌルを別のアプリでも䜿甚したいずなった堎合、アプリ間の蚀語が異なったり必芁なラむブラリが異なれば、関数を改修する必芁がありたした。 たた、ツヌルリストの定矩方法はLLMによっお異なるため、アプリで䜿甚するLLMが異なれば、その点を改修する必芁が出おきたす。 MCPを䜿甚した堎合、MCPクラむアントずいうものを甚意し、LLMアプリず別プロセスで動䜜するMCPサヌバをツヌルずしお扱うようにしたす。 そうするず、MCPサヌバ぀䜜成すれば、どのLLMアプリからも䜿甚できるようになるので、アプリ毎に関数を曞いたり、ツヌル定矩を行う必芁がなくなりたす。 たた、MCPサヌバを公開しおいるサヌビスは増えおおり、䟋えばnotionやblender、googleカレンダヌ等のサヌバを組み蟌むこずが容易です。 公開されおいるMCPサヌバに぀いおは こちら をご確認ください。 生成AIずツヌルを組み合わせる技術であるRAG、FunctionCalling、MCPに぀いお解説を行いたした。 続いおデモの解説に移りたす。 Qumcum連携 具䜓的にFunctionCallingでQumcumを生成AIに操䜜させるデモを行いたした。 QumcumはBluetoothによる通信が可胜な小型ロボットです。 䞻な機胜は距離センサや音怜知、発声等がありたすが、今回䜿甚したのは頭、腕、足の回転です。 たた、LLMずしおAzure OpenAIのモデルを䜿甚したした。 Azure OpenAIに぀いおはデプロむから実際にAPIを叩くたでをブログ蚘事にしおいたすので こちら をご確認ください。 シヌケンス図は以䞋のようになりたす。 たず、プロンプトの分析をLLMにリク゚ストし、結果を構造化出力させおいたす。これは分析結果(プロンプトから読み取れる感情、プロンプトに察するロボットの感情、プロンプトの芁玄等)をUIずしお衚瀺するために䜿甚しおいたす。 構造化レスポンスに぀いおもブログにたずめおいるので、 こちらの蚘事を ご芧ください。 その埌、分析結果ずプロンプト本文をLLMに枡し、FunctionCallingを行いたす。 䜿甚する関数を遞択しおもらい、アプリケヌション偎でロボット動䜜関数を実行しおいたす。 デモ動画はこちらです。 このデモでは、入力したプロンプトからFunctionCallingによっお関数が遞び取られおいるこずを衚しおいたす。 ロボットが䞇歳をする関数や、足螏み、銖振りを行う関数が遞び取られ、実行されおいるのがわかりたす。 今埌の展望 具䜓的な展望ではないですが、今埌できたらおもしろいなず考えおいるこずは以䞋のようなこずです。 テキスト入力から音声入力ぞ修正 Qumcumの発話機胜を掻甚し、リアルタむム䌚話機胜実装 今たでの䌚話内容を蚘録し、RAGによっお盞棒、友人のような䌚話を可胜に RAGを甚いお生成AIの盞棒を䜜るはらちゃんのブログは こちら を参照ください。 生成AIずツヌルを組み合わせるこずで、某未来から来たネコ型ロボットのような友人を自分の手で䜜るこずができるかもしれたせんね。 たずめ 生成AI×ツヌルによっお、生成AI単䜓ではできなかったこずが可胜になりたす。 最新の情報に関する回答 独自の情報に関する回答 珟実䞖界やデゞタル環境の操䜜 等が可胜です。 FunctionCallingやMCPを掻甚しお新たな組み合わせによる新たな䟡倀を生み出しおいきたしょう。 閲芧いただきありがずうございたした。 セミナヌに参加しおくださった皆さん、ご枅聎ありがずうございたした。 わかりやすく䌝えられるセミナヌを今埌も行っおいきたいず思いたす。 ご芧いただきありがずうございたす この投皿はお圹に立ちたしたか 圹に立った 圹に立たなかった 0人がこの投皿は圹に立ったず蚀っおいたす。 The post OSC犏岡広島2025で生成AI×ツヌルに぀いおセミナヌ登壇しおきたした first appeared on SIOS Tech Lab .
本ブログは、䞉菱電機株匏䌚瀟 電力システム補䜜所 電力ICTセンタヌ 小森様ず、アマゟン りェブ サヌビス ゞャパン合同䌚瀟 ゜リュヌションアヌキテクト皲田、GitLab 合同䌚瀟 ゜リュヌションアヌキテクトの小束原様の共著です。䞉菱電機 電力ICTセンタヌにおける Kiro ず GitLab を組み合わせた゜フトりェア開発効率化の取り組みに぀いおご玹介したす。 電力ICTセンタヌに぀いお 䞉菱電機 電力システム補䜜所 電力ICTセンタヌは、再生可胜゚ネルギヌの拡倧や電力自由化に察応する電力×ICTの専門組織です。電力取匕・需絊管理から、分散型電源/VPP、蓄電池制埡、スマヌトメヌタヌ、蚗送・粟算、環境䟡倀管理、アセットマネゞメントたで、電力事業党䜓をカバヌする䞻力゜リュヌション「 BLEnDerブレンダヌ 」を開発しおいたす。BLEnDer を軞に電力の”芋える化→刀断→蚈画→制埡”を䞀気通貫で実珟する電力デゞタル゜リュヌションを提䟛し、電力䌚瀟様、送配電事業者様、小売電気事業者様、発電事業者様など、幅広い事業者様を支えおいたす。 これたでの取り組みず課題 電力ICTセンタヌでは、゜フトりェア開発の効率化に向けおさたざたな取り組みを行っおきたした。 GitLab をベヌスにした CI/CD 環境の構築 Amazon Bedrock を掻甚した RAG システムの開発開発工数芋積もりの支揎 Amazon Bedrock を掻甚した蚭蚈曞レビュヌの効率化 CI/CD ツヌルを掻甚したビルド・テスト・デプロむ䜜業の効率化 ワヌクフロヌ自動化ツヌルを掻甚した申請フロヌの自動化 これらのシステムやツヌルはそれぞれ開発効率化に寄䞎しおいたすが、 導入・展開時に共通の課題 がありたした。 開発したシステムやツヌルは、基本的に玍入先の開発チヌムに運甚・保守を担っおいただきたす。そのため、利甚方法を瀺したドキュメントや蚭蚈ドキュメントの䜜成、利甚フロヌの敎備が䞍可欠です。時には勉匷䌚を開催し、必芁なスキルを習埗しおいただく必芁もありたした。しかし、毎回フルセットで䌎走支揎を行うこずは珟実的ではなく、ドキュメントや勉匷䌚だけで実践しおいただくには限界があるず感じおいたした。 「ドキュメントを読たなくおも、AI に聞けばワヌクフロヌに沿った開発ができる」 ― そんな仕組みを実珟するために、Kiro ず GitLab を組み合わせた新しいアプロヌチに取り組んでいたす。 Kiro の Steering・Powers・MCP ずは 本題に入る前に、今回の取り組みで掻甚しおいる Kiro の䞻芁機胜に぀いお説明したす。 Steeringプロゞェクト暪断のグラりンドルヌル Steering は、Kiro の振る舞いに察しお 垞に適甚されるグラりンドルヌル を定矩する仕組みです。プロゞェクトのルヌトディレクトリに .kiro/steering/ ディレクトリを䜜成し、マヌクダりンファむルでルヌルを蚘述したす。 .kiro/ └── steering/ ├── coding-standards.md # コヌディング芏玄 ├── language.md # 蚀語蚭定日本語で回答する等 └── security.md # セキュリティポリシヌ Steering に蚘述したルヌルは、 どの Power が発動しおいるかに関わらず垞に Kiro のコンテキストに読み蟌たれたす 。そのため、「日本語で回答するこず」「機密情報をコヌドに含めないこず」ずいった、プロゞェクト党䜓で䞀貫しお守るべきルヌルの定矩に適しおいたす。 電力ICTセンタヌでは、プロゞェクト固有ではない共通のグラりンドルヌル蚀語蚭定、コヌディング芏玄の基本方針などを Steering で管理しおいたす。 Powers動的に呌び出されるワヌクフロヌ定矩 Powers は、Steering ずは異なり、 ナヌザヌの発話内容に応じお動的に呌び出される ルヌル定矩の仕組みです。Power は POWER.md ずいうメタデヌタファむルず、 steering/ ディレクトリ配䞋のステアリングファむル矀で構成されたす。 .kiro/powers/ └── my-power/ ├── POWER.md # Power のメタデヌタname, description, keywords ├── mcp.json # この Power 専甚の MCP サヌバヌ蚭定任意 └── steering/ ├── guide-a.md # ステアリングファむル A └── guide-b.md # ステアリングファむル B POWER.md の frontmatter には keywords を定矩でき、ナヌザヌの発話にこれらのキヌワヌドが含たれるず、その Power が動的に発動したす。 --- name: "standard-dev-flow" displayName: "Standard Dev Flow" description: "GitLab を䜿甚した開発ワヌクフロヌを暙準化する Power" keywords: ["むシュヌ", "ブランチ", "コミット", "MR", "マヌゞリク゚スト", "レビュヌ", "パむプラむン", "実装"] --- Steering ずの䜿い分けのポむント は、コンテキストりィンドりの効率です。Steering は垞に読み蟌たれるため、倧量のルヌルを定矩するずコンテキストを圧迫したす。䞀方、Powers は必芁なずきだけ動的に読み蟌たれるため、ワヌクフロヌ固有の詳现なルヌル数千行に及ぶガむドラむンなどを定矩しおも、関係ないタスクの際にはコンテキストを消費したせん。 電力ICTセンタヌでは IDE での利甚が倚く、IDE 䞊で Power が動的に呌び出されおいるこずを芖芚的に確認できる点に安心感を感じおいたす。「いた Kiro がどのルヌルに埓っお動いおいるか」が芋えるこずで、AI の振る舞いを制埡できおいる実感が埗られたす。 Kiro から Power を呌び出すむメヌゞ MCPModel Context Protocol倖郚ツヌルずの連携 MCP は、Kiro が倖郚のツヌルやサヌビスず連携するためのプロトコルです。MCP サヌバヌを定矩するこずで、Kiro が GitLab API の操䜜や独自のスクリプト実行など、IDE の倖にある機胜を呌び出せるようになりたす。 Power ごずに mcp.json を配眮できるため、 特定のワヌクフロヌでのみ必芁な MCP サヌバヌを、その Power に玐づけお管理 できたす。䟋えば、Standard Dev Flow Power には GitLab 操䜜甚の MCP サヌバヌを、Playwright Power にはテスト実行甚の MCP サヌバヌを、ずいった䜿い分けが可胜です。 3 ぀の機胜の関係性 たずめるず、以䞋のような圹割分担になりたす。 機胜 適甚タむミング 甹途 Steering 垞時 プロゞェクト暪断のグラりンドルヌル Powers キヌワヌドに応じお動的 ワヌクフロヌ固有の詳现ルヌル・手順 MCP Power に玐づけお動的 倖郚ツヌル・API ずの連携 この3局構造により、「垞に守るべきルヌル」「タスクに応じお必芁なルヌル」「倖郚ツヌルずの連携」を敎理しお管理でき、コンテキストりィンドりを効率的に掻甚しながら AI ゚ヌゞェントの振る舞いを制埡できたす。 珟圚の取り組みKiro × GitLab による開発プラットフォヌム 党䜓像 珟圚、CI/CD を䞭心ずした゜フトりェア開発サむクル党䜓の効率化に取り組んでいたす。 開発ワヌクフロヌの敎理ブランチ戊略・リリヌス戊略を含む CI/CD 環境の敎備 アプリケヌションのデプロむ方法の怜蚎、テスト自動化環境の敎備 GitLab CI/CD カタログを掻甚したパむプラむンの暙準化 ガむドラむンの敎備 これらの取り組みにおいお、Kiro ず GitLab をどのように掻甚しおいるかをご玹介したす。 Kiro の掻甚Powers による開発ワヌクフロヌの暙準化 Kiro では 2 ぀の Power (Standard Dev Flow Power, Playwright Power) を利甚しおいたす。それぞれに぀いお解説したす。 その 1: Standard Dev Flow Power 開発ワヌクフロヌ党䜓を暙準化する Power を䜜成したした。以䞋のワヌクフロヌを Kiro に定矩しおいたす。 1. Issue 䜜成 → 2. ブランチ䜜成 → 3. 実装 → 4. コミット → 5. MR 䜜成 → 6. レビュヌ → 7. マヌゞ この Power には、各フェヌズに察応するステアリングファむルが含たれおいたす。 standard-dev-flow/ ├── POWER.md # Power 定矩ワヌクフロヌ党䜓像 ├── mcp.json # MCP サヌバヌ蚭定 └── steering/ ├── issue-management.md # Issue 䜜成ガむド ├── branch-commit-mr.md # ブランチ・コミット・MR䜜成ガむド ├── implementation.md # 実装䜜業ガむド ├── gitlab-duo-review.md # GitLab Duo レビュヌワヌクフロヌ ├── pipeline-troubleshooting.md # パむプラむン倱敗解析ガむド └── gitlab-official-mcp-tools.md # GitLab 公匏 MCP ツヌルリファレンス POWER.md にはワヌクフロヌの党䜓像ず各ステアリングファむルの参照タむミングを蚘述しおいたす。䟋えば、「新しい Issue を䜜成する際は issue-management.md を参照」「パむプラむンが倱敗した際は pipeline-troubleshooting.md を参照」ずいった圢で、Kiro がどのフェヌズでどのルヌルを適甚すべきかを明瀺しおいたす。 各ステアリングファむルには、そのフェヌズで Kiro が埓うべき具䜓的なルヌルが蚘述されおいたす。䟋えば branch-commit-mr.md には以䞋のようなルヌルが含たれたす。 ブランチ呜名芏則 feature/{issue-number}-{brief-description} 圢匏 Conventional Commits 1.0.0 準拠のコミットメッセヌゞtype/scope/description/body の構造化、日本語での蚘述 MR 䜜成時の squash merge による 1 コミットぞの集玄 MR テンプレヌト倉曎内容/テスト/レビュヌ芳点/補足に基づいた蚘述 開発者は Kiro に「Issue #123 の実装を開始しおください」ず䌝えるだけで、Power に定矩されたワヌクフロヌに沿っお䜜業が進みたす。Kiro は自動的に以䞋を実行したす。 ブランチの確認・切り替え Issue の内容確認ず tmp/{タスク名}-issue-details.md の䜜成 実行蚈画の䜜成 tmp/{タスク名}-plan.md  実装䜜業の実斜 䜜業サマリヌの䜜成 tmp/{タスク名}-summary.md  このように、 䜜業の远跡ファむルを自動生成する仕組み も Power に組み蟌んでいたす。Issue の詳现理解、チェックリスト圢匏の実行蚈画、䜜業完了埌のサマリヌを tmp/ ディレクトリに残すこずで、䜜業の透明性を確保しおいたす。 Standard Dev Flow Power には、GitLab 公匏 MCP サヌバヌず独自の MCP サヌバヌの䞡方を mcp.json で定矩しおいたす。 GitLab 公匏 MCP サヌバヌが提䟛する䞻なツヌル create_issue / get_issue Issue の䜜成・取埗 create_merge_request / get_merge_request MR の䜜成・取埗 search / semantic_code_search 怜玢機胜 独自 MCP サヌバヌGitLab MCP Enhancerで補完しおいるツヌル get_mr_discussions / reply_to_discussion / resolve_all_discussions MR ディスカッション操䜜 list_merge_requests / update_merge_request MR の䞀芧・線集 list_issues / update_issue / add_issue_note Issue の䞀芧・線集 get_latest_pipeline / get_pipeline_jobs / get_job_log パむプラむン解析 この 2 ぀の MCP サヌバヌを組み合わせるこずで、Issue 䜜成から MR レビュヌ察応、パむプラむン倱敗の解析たで、 GitLab の操䜜をほが Kiro 䞊で完結 できるようになりたした。 その 2: Playwright Power 次のステップずしお、Playwright を掻甚した E2E テスト生成のための Power も䜜成しおいたす。 playwright/ ├── POWER.md # Power定矩 └── steering/ ├── playwright-rule.md # コヌディング芏玄・POM倉換手順 ├── playwright-cli.md # playwright-cli の䜿い方 └── test-best-practices.md # テスト実装のベストプラクティス この Power のポむントは、 playwright-cli の出力から Page Object ModelPOMぞの倉換手順 をステアリングファむルに詳现に定矩しおいる点です。playwright-cli はコヌディング゚ヌゞェント向けに蚭蚈された CLI ベヌスのブラりザ自動化ツヌルで、操䜜ごずに Playwright コヌドを出力したす。 playwright-rule.md には、この出力コヌドから POM クラスぞ倉換する 3 ステップの手順が定矩されおいたす。 ロケヌタヌ抜出 出力コヌドから芁玠を特定 readonly 定矩 コンストラクタでロケヌタヌを宣蚀 アクションメ゜ッド 操䜜をメ゜ッドに抜象化 さらに、ロケヌタヌ戊略の優先順䜍も明確に定矩しおいたす。 getByRole() – ボタン、リンク等のセマンティック芁玠 getByLabel() – フォヌム芁玠 getByPlaceholder() – プレヌスホルダヌテキスト getByText() – 衚瀺テキスト getByTestId() – テスト専甚属性 CSS/XPath – 最埌の手段 test-best-practices.md には、AAA パタヌンArrange/Act/Assertによるテスト構造化、アサヌション匷化 toBeVisible() だけでなく toHaveText() で内容確認、テスト安定化テクニックスピナヌ埅機、叀い DOM の回避など、実践的なベストプラクティスが蚘述されおいたす。 これらのルヌルを Power に萜ずし蟌むこずで、 誰が Kiro にテスト生成を䟝頌しおも、組織のベストプラクティスに沿った䞀貫性のあるテストコヌドが生成されたす 。 GitLab の掻甚 GitLab Pages によるガむドラむン公開 プラットフォヌムを他 BU に展開するにあたり、ガむドラむンの敎備は䞍可欠です。GitLab Pages を掻甚し、マヌクダりンで蚘述したガむドを静的 Web サむトに倉換しお公開しおいたす。ガむドには、GitLab CI/CD カタログを掻甚した暙準パむプラむンの説明や、GitLab Duo や Kiro の基本的な䜿い方や Tips を掲茉しおいたす。関連する゜ヌスコヌドはすべお GitLab で管理しおおり、゜ヌスコヌドの修正があれば生成 AI を掻甚しお即時にガむドに反映・公開できるため、管理の手間を感じたせん。 ここで重芁なのは、 Powers には基本的にガむドに曞いおあるこずをそのたた萜ずし蟌んでいる ずいう点です。これにより、ガむドの内容ず AI の振る舞いが垞に䞀臎し、「ガむドを読む」か「AI に聞く」かのどちらでも同じ情報にたどり着ける状態を実珟しおいたす。 GitLab Pages の利甚むメヌゞ CI/CD カタログによるパむプラむンの暙準化 GitLab CI/CD カタログを䜜成し、アヌティファクトやキャッシュの蚭定を含むパむプラむンテンプレヌトを配垃しおいたす。ナヌザヌ偎は環境固有のパラメヌタ倀のみを入力すれば、即座に䜿甚可胜な状態です。 GitLab Duo による MR レビュヌAI 同士の協働 Kiro でコヌディングを行い、MR を䜜成した埌、GitLab Duo にレビュヌを䟝頌するワヌクフロヌを構築しおいたす。 生成 AI は自分で生成したコヌドに察しお正しいずいう認知バむアスがかかる可胜性があるため、 コヌド生成KiroずレビュヌGitLab Duoを異なる AI に担圓させる こずで、より客芳的なレビュヌを実珟しおいたす。 GitLab Duo ぞのレビュヌ芳点は、瀟内の有識者を亀えお mr-review-instructions.yaml に定矩しおおり、レビュヌコメントに必ず prefix接頭蟞を付けるルヌルを蚭けおいたす。この prefix により、レビュヌ指摘の重芁床が䞀目で刀断できるようになりたす。 instructions: - name: Common Review Policy fileFilters: - "**/*" instructions: | - **蚀語**: すべおの応答は必ず日本語で行っおください - レビュヌする際には、以䞋のprefix(接頭蟞)を必ず付けおください - [must] → 必須修正、修正しないのであれば修正しない理由を開発者に求める - [want] → できれば察応しおほしい、改善ずしお望たしい提案 - [imo] → 個人的意芋、奜みベヌスの提案 - [ask] → 質問、意図・背景の確認 - [nits] → 现かい指摘(nitpicks)、超軜埮なスタむル修正など - [info] → 参考情報、共有・補足・関連情報 䞀方、Kiro 偎の Power gitlab-duo-review.md には、GitLab Duo のレビュヌ結果をどう受け取り、どう察応するかのルヌルを定矩しおおり、GitLab Duo が付䞎する prefix に察しお、Kiro がどのように刀断・行動すべきかを明瀺しおいたす。 ・・・ ### 2. GitLab Duoにレビュヌ䟝頌 **重芁**: GitLab Duoのレビュヌは**新芏ディスカッション**で`@GitLabDuo`をメンションするこずで発動する。MR䜜成時のdescriptionに蚘茉しおも発動しない。 **レビュヌ䟝頌のポむント**: - 新芏ディスカッションを䜜成するこれが必須 - `@GitLabDuo`はスペヌスなしで蚘茉 - 䟝頌メッセヌゞには以䞋を含めるず効果的   - 実装内容の抂芁   - 特に確認しおほしい点   - 倉曎理由や背景   - 参考資料: 関連ドキュメント ### 3. レビュヌ結果確認 **レビュヌコメントのprefix重芁床の刀断基準**: GitLab Duoのレビュヌには以䞋のprefixが付䞎される。これを基に察応の優先床を刀断する。 | Prefix | 意味 | 察応方針 | |--------|------|----------| | `[must]` | 必須修正 | 修正必須。察応しない堎合は理由を説明 | | `[want]` | できれば察応 | 改善ずしお望たしい。可胜な限り察応 | | `[imo]` | 個人的意芋 | 奜みベヌスの提案。採甚は任意 | | `[ask]` | 質問 | 意図・背景の確認。回答が必芁 | | `[nits]` | 现かい指摘 | 超軜埮なスタむル修正。䜙裕があれば察応 | | `[info]` | 参考情報 | 共有・補足・関連情報。察応䞍芁 | **[ask]ぞの察応**: `[ask]`が付いた質問には、該圓ディスカッションに`@GitLabDuo`メンション付きで返信しお䞍明点を解消する。 ・・・ [ask] が付いた質問には、該圓ディスカッションに @GitLabDuo メンション付きで返信しお䞍明点を解消するルヌルも定矩しおいたす。 たた、GitLab Duo ぞのレビュヌ䟝頌方法に぀いおも Power に明蚘しおいたす。GitLab Duo のレビュヌは MR の description に蚘の最埌に /assign_reviewer @GitLabDuo を蚘茉するこずで発動したす。こうした「知らないずハマるポむント」も Power に萜ずし蟌むこずで、開発者が詊行錯誀する手間を省いおいたす。 以䞊を螏たえた、Kiro ず GitLab Duo の協働ワヌクフロヌは以䞋の通りです。 Kiro で機胜を実装し、MR を䜜成 GitLab Duo に MR レビュヌを䟝頌MCP 経由 レビュヌ指摘を Kiro が取埗し、察応可吊を刀断 察応が必芁な指摘に察しおコヌド修正を実斜 修正をコミット・プッシュし、再床 GitLab Duo にレビュヌを䟝頌 承認埌、党ディスカッションを䞀括解決 この AI 同士の協働によるレビュヌサむクル により、ある皋床のクオリティが担保された状態で人間のレビュアヌが入るこずで、レビュヌ負担の軜枛が期埅できたす。 この構成のメリット 1. 導入ハヌドルの倧幅な䜎䞋 Power を掻甚しお開発フロヌを定矩しおいるため、開発者は Kiro に質問しながら䜜業を進めるだけで、ワヌクフロヌに沿った開発を行うこずができたす。分からないこずは Kiro に質問しお解決できるため、Kiro の基本的な䜿い方を芚えるだけで開発を始められたす。BU ぞの展開時に「AI がサポヌトしおくれるし、ガむドを特に読む必芁はないよ」ず䌝えるだけでハヌドルがぐっず䞋がりたす。 2. 開発の蚌跡ずコラボレヌション Issue や MR で開発の蚌跡を残すこずで、他の開発者ずのコラボレヌションが容易になりたす。Issue を远うこずで、別の開発者が䜜業を匕き継ぐこずも容易になるず考えおいたす。 3. レビュヌ負担の軜枛 コヌド開発の速床が䞊がる䞀方で、レビュヌ者ぞの負担が増倧するリスクがありたす。GitLab Duo での芳点に基づいたレビュヌず CI/CD パむプラむンの実行結果を Kiro にフィヌドバックさせお改善するこずで、人間のレビュアヌが入る前にある皋床のクオリティを担保できたす。人間のレビュヌ疲れやレビュヌ工数の削枛にも寄䞎するこずを期埅しおいたす。 工倫した点ず苊劎した点 1 : Power の発動率を䞊げる工倫 Power に keywords を蚭定しお呌び出しの工倫をしたしたが、期埅通りに発動しないケヌスがありたした。䟋えば、Standard Dev Flow Power には ["むシュヌ", "ブランチ", "コミット", "MR", "マヌゞリク゚スト", "レビュヌ", "パむプラむン", "実装"] ずいったキヌワヌドを蚭定しおいたすが、ナヌザヌの発話がこれらのキヌワヌドに完党に䞀臎しない堎合、Power が発動しないこずがありたした。 調査の結果、 Power を積極的に掻甚するよう促す Steering ファむルを䜜成する こずで、利甚率が向䞊したした。Steering は垞にコンテキストに読み蟌たれるため、「利甚可胜な Power がある堎合は積極的に掻甚するこず」ずいうルヌルを Steering に蚘述するこずで、Power の発動率を改善できたす。AI ゚ヌゞェントツヌルを組織で掻甚する際には、こうしたチュヌニングが重芁になりたす。 2: GitLab 公匏 MCP サヌバヌの補完 GitLabの良さはそのカスタマむズ性の高さにありたす。 公匏 MCP サヌバヌを補完する独自の MCP サヌバヌGitLab MCP Enhancerを自䜜 したした。 gitlab-official-mcp-tools.md ずいうステアリングファむルに 公匏 MCP サヌバヌ Beta 版の党 14 ツヌルのパラメヌタ定矩ず䜿甚䟋を蚘述し、Kiro が正しくツヌルを䜿えるようにガむドしおいたす。これによりMR ディスカッションの取埗・返信・解決、Issue の䞀芧・線集、パむプラむンのゞョブログ取埗など、 GitLab の操䜜が倧幅に向䞊し、ほが Kiro 䞊で操䜜を完結できるようになりたした。 今埌の展望 盎近では、珟圚䜜成䞭の Playwright Power を完成させ、E2E テスト生成の効率化を掚進しおいきたす。たた、Playwright Power ず䞊行しお、SonarQube の MCP サヌバヌを掻甚し、静的解析結果を Kiro にフィヌドバックする仕組みの構築も怜蚎し始めたした。これにより、コヌドレビュヌ時だけでなく、実装段階からコヌド品質を高めるための仕組み䜜りにも取り組んでいたす。このように、組織で掻甚が芋蟌たれる OSS の掻甚を掚進する Power を順次䜜成し、AI を掻甚しお゜フトりェア開発が楜になる土壌を広げおいく方針です。たた、GitLab Duo のレビュヌ芳点も継続的に育おおいき、適甚範囲を広げるこずでレビュヌ負担のさらなる軜枛を目指したす。 1 : 効果の定量化ず継続的な改善 AI 掻甚による開発効率化の効果を可芖化するため、定量的な評䟡指暙の枬定に取り組んでいきたす。Issue からマヌゞたでのリヌドタむムやレビュヌむテレヌション回数ずいった開発速床の指暙、GitLab Duo のレビュヌ指摘の粟床、Kiro の Playwright Power で生成されるコヌドの品質などを、実際に各ビゞネスナニット (以降、BU)で䜿甚しおいただきながら評䟡しおいきたす。これらのフィヌドバックを基に、Power のルヌル定矩の改善や MCP サヌバヌの機胜拡匵など、継続的な改善サむクルを回しおいきたす。 2 : Power ずパむプラむンの゚コシステム構築 Power や CI/CD パむプラむンを組織党䜓で掻甚しおいくため、バヌゞョン管理ず配垃の仕組みを構築しおいきたす。GitLab で Power/MCP や CI/CD パむプラむンテンプレヌトを䞀元管理し、GitLab Pages で導入方法・アップグレヌド方法を公開したす。バヌゞョン曎新時には曎新ダッシュボヌドでナヌザヌに通知し、各 BU からの芁望は Issue やチケットで収集しお継続的に改善したす。たた、既存の管理システムずの連携も芖野に入れ、障害報告から修正、リリヌスたでの開発サむクル党䜓の効率化を図りたす。 3 : 組織党䜓ぞの展開ずコミュニティ圢成 䞭長期的には、電力ICTセンタヌ内の各 BU ぞの展開を加速させおいきたす。積極的な情報発信を通じお呚囲を巻き蟌みながら、地道に掻甚の茪を広げおいきたす。Power やルヌル敎備の取り組みは電力ICTセンタヌに閉じた話ではないため、ゆくゆくは䞉菱電機党瀟的な取り組みずしお認知され、掻甚方法に぀いお議論できるコミュニティが圢成されるこずを目指しおいたす。たずは足元の電力ICTセンタヌの゜フトりェア開発効率化に぀ながる掻動をどんどん進めおいきたいず考えおいたす。 たずめ 䞉菱電機 電力ICTセンタヌでは、Kiro の Steering・Powers・MCP ず GitLab の各機胜を組み合わせるこずで、 「AI に聞けばワヌクフロヌに沿った開発ができる」 プラットフォヌムの構築を進めおいたす。 この取り組みの本質は、単なるツヌル導入ではありたせん。 Steering でプロゞェクト暪断のグラりンドルヌルを定矩し Powers でワヌクフロヌ固有の詳现なルヌル・手順を動的に呌び出し MCP で GitLab をはじめずする倖郚ツヌルずシヌムレスに連携する この 3 局構造により、ガむドラむンの内容を Powers に萜ずし蟌み、GitLab Pages で公開するガむドず AI の振る舞いを䞀臎させるこずで、 ドキュメントを読んでも AI に聞いおも同じ結果にたどり着ける 仕組みを䜜っおいたす。さらに、Kiro によるコヌド生成ず GitLab Duo によるレビュヌずいう AI 同士の協働により、人間のレビュヌ負担を軜枛しながら品質を担保するワヌクフロヌを実珟しおいたす。 ゜フトりェア開発の効率化は、ツヌルの導入だけでは完結したせん。開発ワヌクフロヌの暙準化、ガむドラむンの敎備、そしおそれらを AI ゚ヌゞェントに萜ずし蟌むこずで、初めお組織党䜓の開発効率が向䞊したす。本ブログが、同様の課題を抱える皆様の参考になれば幞いです。 著者 小森 裕之 電力システム補䜜所 電力デゞタル゚ナゞヌシステム開発郚 システム基盀課所属。 コヌヒヌず Kiro が倧奜きです 電力ICTセンタヌ内の党ビゞネスナニットの開発・運甚に貢献するため、ITIL4 に準拠した専甚プラットフォヌムの開発に携わっおおり、䞻に CI/CD 環境の怜蚎・構築・導入や AI ゚ヌゞェントツヌルを掻甚した開発の仕組みづくりを担圓しおいたす。 皲田 倧陞 – いなりく AWS Japan で働く Kiro をこよなく愛す゜リュヌションアヌキテクト。2022 幎から䞉菱電機グルヌプを支揎しおいたす。その掻動の傍ら、最近は AI 駆動開発ラむフサむクル (AI-DLC) の日本のお客様ぞの垃教掻動もし぀぀、 Kiro のブログ などを執筆しおいたす。 小束原 ぀かさ GitLab 合同䌚瀟 シニアパヌトナヌ゜リュヌションアヌキテクト 長きに枡る゜フトりェア開発経隓を持ち、デヌタベヌス、セキュリティ、ビッグデヌタの領域での深い専門知識を持ちたす。2022 幎にGitLab に参加し、AI 駆動型開発ツヌルがもたらす新しい開発パラダむムの構築に取り組んでいたす。
はじめに 本蚘事はSIOS Tech Labアドベントカレンダヌ23日目の投皿です。 サむオステクノロゞヌの曜根田です。 普段はデザむン、フロント゚ンドコヌディングや、CMSのセキュリティ保守の䞀郚察応などを行っおいたす。 近幎、CopilotやGeminiなどの生成AIの進化により、Photoshop,Illustratorなどでポチポチ䜜業する手間を省略しお、 “フロント゚ンドのモックアップで盎にビゞュアルを䜜る” ずいうこずが手軜にできるようになったず感じおいたす。 この蚘事ではthree.jsでの実䟋に぀いお曞きたす。 three.jsっお three.js はブラりザ䞊でD衚珟を実装するのに䟿利なJavaScriptラむブラリです。 ブラりザ䞊でのリッチな挔出やゲヌム制䜜たでカバヌしおいたす。 公匏ドキュメント も充実しおいたす。 アむデアの皮 矎術展が奜きでよく行くのですが、六本朚にある 21_21 DESIGN SIGHT ずいうギャラリヌのショップで賌入した、 アスタリスクをD化しおDプリンタで出力したオブゞェクトようなもの 。盎埄はくらいです。机に食っおいたこれがアむデアの皮になりたした。 このオブゞェクトずthree.jsを䜿っお䜜れそうなむメヌゞずしお以䞋が浮かびたした。 htmlの䞀郚にビゞュアル芁玠ずしお埋め蟌めるcanvas芁玠 鮮やかな倧きな色の゚リアが耇雑なパタヌンで動く 動きはゆっくり Dにも芋えるがD的でもある。党䜓像ははっきりわからない 芋おいるだけで飜きない䞇華鏡のような動き 完成圢のビゞュアルむメヌゞ 圓初は Blender でこのDアスタリスクをモデリングを䜜成し、それを倖郚ファむルずしおthree.jsに取り蟌むやり方を怜蚎したのですが、オブゞェクトが幟䜕孊的であれば数孊的な蚈算だけで生成できるはずなので、䞀旊生成AIのプロンプトのみで䜜る方法を遞びたした。 いわゆる”Vibe Coding”のフェヌズぞ 今回の開発プロセスの特城は以䞋のようなものです。 AIずの共同䜜業 GeminiずCopilotずいう耇数の生成AIをプロンプトで制埡し、コヌドを発展させたした。 ナレッゞベヌスの雰囲気コヌディング 過去の three.js ラむブラリのコヌディング経隓や、 Blender などの3Dナレッゞを掻かした「雰囲気で進めるコヌディング」です。 開発フェヌズ 1: オブゞェクトの基本配眮ず初期プロンプト 難しいこずを考えず、こずばのむメヌゞでやりたいこずを䌝えたす。 以䞋、かなり指瀺がフランクですが、平日は生成AIず䌚話しおいる時間が䞀番倚く、”話が通じる仲間”ずいう感芚なので、自然ず砕けた口調になりたす笑 abstractなロヌポリゎンのオブゞェクトが画面いっぱいに衚瀺され、ゆっくりず回転するような、りェブサむトのファヌストビュヌむメヌゞを䜜りたい。three.jsを掻甚。背景は#feeb0bにしおほしい。ラむティングはリアルではなくフラットでうすくグラデヌションが掛かっおいる感じ。 ↓ オブゞェクトは添付写真のような、”アスタリスクのD版”みたいにしおほしい面ごずに色が違う。色の明床ず圩床あげる。正二十面䜓のような幟䜕孊図圢のそれぞれの面を倖偎にExtrudeしたような圢。カメラワヌクはもっずゎリっず拡倧したい。 バむブコヌディングなので ”ゎリッず拡倧したい” など、雰囲気䞻䜓の擬音も盎さずそのたた枡しおみたすが、なんずなく察しおくれたす。 䞊蚘のプロンプト以倖にも现かい指瀺はいく぀か䞎えおいたすが省略しおいたす。 途䞭、゚ラヌで䞊手く描画されないケヌスもありたすが、そのずきは郜床修正指瀺を出したす。 ほんの3~4ステップのプロンプトでむメヌゞに近いthree.jsの動きを実装しおくれたした。D座暙空間でオブゞェクトが回転しおいたす。 途䞭経過のキャプチャ。ただ色々ず倉。 Extrudeずいう甚語に぀いお ちなみに䞊蚘プロンプトにある”Extrude”ずいうのはBlenderやMayaなどのD䜜成ツヌルのポリゎンモデリングで䜿われるコマンドで、”抌し出し”を意味したす。ビゞュアル的には以䞋のようなむメヌゞです。 Extrudeの図解。遞択した面が抌し出されおいたす 開発フェヌズ 2: 圢・色・ラむティングの調敎 面単䜍ではなく、ポリゎン毎に色が違っおいたり、面が重なっおチカチカしおたりするのが䜜りたいゎヌルのむメヌゞず異なるので、匕き続きプロンプトで修正しおいきたす。 カラヌリングだが、ポリゎンごずに倉えるのではなく、オブゞェクトの同䞀平面の面は同じ色にする。あず、面が重なっおいるこずでちら぀きが発生しおいるようなので解消しおほしい。色の圩床ず明床をもっず䞊げる。 修正埌が以䞋。ちら぀きずカラヌリングは解消されたしたが、 圢が気に食わない 。 ぀の぀ながったオブゞェクトになっおいない気がする。アスタリスクのD版だけど、䞀぀の倚面䜓の各面を個別にExtrudeしお䜜られたアスタリスク、ずいう感じにできない あずShadingやラむティングの感じもフラットすぎお面癜くないので、以䞋のようなプロンプトで改善を加えおみたす。 もっず“照明っぜい”陰圱にしたい。flatShadingじゃなくおいいのでは。vertexColorsも䜿えばあず、スポットラむト耇数䜿っおオブゞェクトを照らせば、それっぜくなるんじゃない 面にグラデヌションが付き、スポットラむトによるラむティングで陰圱が生たれたした。 圢はガラッず倉わり 、”D版アスタリスク”ではなくトゲトゲのスタヌのような圢になりたしたが、数孊的蚈算によっお生成できるシヌムレスな぀のオブゞェクトずなったのでOKず刀断したした。 欲しかったのはシヌムレスなオブゞェクトず、色のグラデヌションの方です。 最埌に、カメラを被写䜓にぐっず近づけお、起動するたびに毎回異なるカラヌリングが斜されるようなプロンプトを枡したす。 完成版のキャプチャ 望んでいた動くキヌビゞュアル芁玠が䜜成できたした 最終成果物three.jsコヌド 最終版コヌドは以䞋です。1枚のhtmlなのでコピペしお保存し、開くだけで動きたす。three.jsは実際にブラりザで動かさないずよくわからないず思いたす。 リロヌドするたびにランダムにカラヌが割り圓おられたす。3Dオブゞェクトは数孊的に生成されおいるので、倖郚読み蟌みのDファむルは䞍芁ですただし、オンラむン䞊のCDNのthree.jsラむブラリを読み蟌んで䜿っおいたす 䞀応モバむル察応も考慮しおいるので、モダンなデバむスならば凊理萜ちなどせずに動くず思いたす。 <!doctype html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Extruded Poly Star – three.js</title> <style> html, body { height: 100%; margin: 0; } body { background: #feeb0b; /* 指定の背景色 */ overflow: hidden; font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Noto Sans JP", sans-serif; } #hero { position: fixed; inset: 0; } </style> <!-- Import Map正しい閉じタグ --> <script type="importmap"> { "imports": { "three": "https://unpkg.com/three@0.160.1/build/three.module.js" } } </script> </head> <body> <canvas id="hero"></canvas> <script type="module"> import * as THREE from 'three'; // ===== ランダム化ナヌティリティ毎回違う画に ===== // seed は URL ?seed=12345 で固定可胜。未指定なら毎回ランダム。 // FIX: URLSearchParams.get('seed') が null のずき Number(null) は 0 になるので、 // 「seed未指定なのに毎回0固定」ずいうバグを避ける。 const params = new URLSearchParams(location.search); const seedParam = params.get('seed'); const urlSeed = (seedParam !== null && seedParam !== '') ? Number(seedParam) : null; const autoSeed = (crypto && crypto.getRandomValues) ? crypto.getRandomValues(new Uint32Array(1))[0] : Math.floor(Math.random() * 1e9); const SEED = (urlSeed !== null && Number.isFinite(urlSeed)) ? Math.floor(urlSeed) : autoSeed; function mulberry32(a){ return function(){ let t = a += 0x6D2B79F5; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } } const rand = mulberry32(SEED); const randRange = (min, max) => min + (max - min) * rand(); console.log('%c[Hero Seed]', 'color:#555', SEED, urlSeed !== null ? '(from URL)' : '(random)'); // ===== 基本セットアップ ===== const canvas = document.getElementById('hero'); const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true, powerPreference: 'high-performance' }); // --- DPR 䞊限PC/モバむル + reduced-motion 察応 + 䜎FPSダりングレヌド --- const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Windows Phone/i.test(navigator.userAgent) || matchMedia('(pointer: coarse)').matches; const DPR_CAP_DESKTOP = 1.5; const DPR_CAP_MOBILE = 1.25; let dprCap = isMobile ? DPR_CAP_MOBILE : DPR_CAP_DESKTOP; const reduceMotion = matchMedia('(prefers-reduced-motion: reduce)').matches; function applyDPR(cap = dprCap) { const target = Math.min(window.devicePixelRatio || 1, cap); renderer.setPixelRatio(target); renderer.setSize(window.innerWidth, window.innerHeight); return target; } let currentDPR = applyDPR(); const scene = new THREE.Scene(); // カメラ右偎を倧きく芆うフレヌミング const camera = new THREE.PerspectiveCamera(48, window.innerWidth / window.innerHeight, 0.01, 100); // 構図を毎回埮劙に倉える少しだけゞッタヌ const camX = -1.0 + randRange(-0.15, 0.15); const camY = 0.12 + randRange(-0.12, 0.12); const camZ = 2.0 + randRange(-0.2, 0.2); camera.position.set(camX, camY, camZ); const lookX = 0.4 + randRange(-0.08, 0.08); camera.lookAt(lookX, randRange(-0.05,0.05), randRange(-0.05,0.05)); renderer.physicallyCorrectLights = true; // ===== ラむティング耇数スポットで“照明っぜい”陰圱 ===== const amb = new THREE.AmbientLight(0xffffff, 0.08); scene.add(amb); const keyColor = new THREE.Color().setHSL(0.08 + randRange(-0.03,0.03), 0.9, 0.7); const rimColor = new THREE.Color().setHSL(0.58 + randRange(-0.04,0.04), 0.6, 0.7); const fillColor= new THREE.Color().setHSL(0.9 + randRange(-0.03,0.03), 0.8, 0.7); const spotKey = new THREE.SpotLight(keyColor, 40 + randRange(-8,8), 6.0, Math.PI * (0.26 + randRange(-0.03,0.03)), 0.45, 1.0); spotKey.position.set(2.4 + randRange(-0.3,0.2), 3.2 + randRange(-0.3,0.2), 1.8 + randRange(-0.2,0.2)); scene.add(spotKey); const spotRim = new THREE.SpotLight(rimColor, 20 + randRange(-6,6), 6.0, Math.PI * (0.34 + randRange(-0.04,0.04)), 0.5, 1.0); spotRim.position.set(-2.8 + randRange(-0.2,0.2), 1.6 + randRange(-0.2,0.2), -1.6 + randRange(-0.2,0.2)); scene.add(spotRim); const spotFill = new THREE.SpotLight(fillColor, 12 + randRange(-6,6), 6.0, Math.PI * (0.44 + randRange(-0.05,0.05)), 0.8, 1.0); spotFill.position.set(0.0 + randRange(-0.3,0.3), -2.4 + randRange(-0.3,0.3), 2.2 + randRange(-0.3,0.3)); scene.add(spotFill); // ====== 単䞀メッシュの「倚面䜓→各面を倖向きに゚クストルヌドしたスタヌ」生成 ====== const baseRadius = randRange(0.7, 0.95); const base = new THREE.IcosahedronGeometry(baseRadius, 0); // 20面すべお䞉角圢 function buildExtrudedStarFromTriPoly(geo, extrude = 1.2) { // 非むンデックスでも動䜜 const pos = geo.attributes.position; const idxArray = (geo.index && geo.index.array) ? geo.index.array : (function(){ const a = new Uint32Array(pos.count); for (let i=0;i<pos.count;i++) a[i]=i; return a; })(); const positions = []; const colors = []; const color = new THREE.Color(); // グロヌバル色盞オフセット募配方向もランダム const hueShift = randRange(0, 1); const gradDir = new THREE.Vector3(randRange(-1,1), randRange(0.3,1), randRange(-1,1)).normalize(); for (let f = 0; f < idxArray.length; f += 3) { const ai = idxArray[f], bi = idxArray[f+1], ci = idxArray[f+2]; const a = new THREE.Vector3(pos.getX(ai), pos.getY(ai), pos.getZ(ai)); const b = new THREE.Vector3(pos.getX(bi), pos.getY(bi), pos.getZ(bi)); const c = new THREE.Vector3(pos.getX(ci), pos.getY(ci), pos.getZ(ci)); const ab = new THREE.Vector3().subVectors(b, a); const ac = new THREE.Vector3().subVectors(c, a); const n = new THREE.Vector3().crossVectors(ab, ac).normalize(); const centroid = new THREE.Vector3().addVectors(a, b).add(c).multiplyScalar(1/3); const tip = new THREE.Vector3().copy(centroid).addScaledVector(n, extrude); pushTriWithFaceGradient(a, b, c, f); pushTriWithFaceGradient(a, b, tip, f + 1); pushTriWithFaceGradient(b, c, tip, f + 2); pushTriWithFaceGradient(c, a, tip, f + 3); } function pushTriWithFaceGradient(v1, v2, v3, seed) { const arr = [v1, v2, v3]; let minD = Infinity, maxD = -Infinity; const ds = arr.map(v => { const d = v.dot(gradDir); if (d<minD) minD = d; if (d>maxD) maxD = d; return d; }); const span = Math.max(1e-6, maxD - minD); const baseH = (hueShift + ((seed * 19.23) % 360) / 360) % 1.0; const S = 1.0; const L0 = 0.63; for (let i = 0; i < 3; i++) { const f = (ds[i] - minD) / span; // 0..1 const h = (baseH + f * 1.4) % 1.0; // 虹っぜく呚回 const L = THREE.MathUtils.clamp(L0 + (Math.cos((f - 0.5) * Math.PI) * 0.22), 0, 1); color.setHSL(h, S, L); positions.push(arr[i].x, arr[i].y, arr[i].z); colors.push(color.r, color.g, color.b); } } const out = new THREE.BufferGeometry(); out.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3)); out.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3)); out.computeVertexNormals(); return out; } const starGeom = buildExtrudedStarFromTriPoly(base, 1.0); // ===== マテリアル“照明っぜい”陰圱PBR マット ===== const mat = new THREE.MeshStandardMaterial({ vertexColors: true, roughness: 0.85, metalness: 0.05, side: THREE.DoubleSide }); const star = new THREE.Mesh(starGeom, mat); // 開始角床サむズ・䜍眮をランダム化右寄せは維持 star.scale.setScalar(randRange(2.2, 2.8)); star.position.x = randRange(0.55, 0.9); star.rotation.x = randRange(0, Math.PI*2); star.rotation.y = randRange(0, Math.PI*2); star.rotation.z = randRange(0, Math.PI*2); scene.add(star); // ===== アニメヌション単玔なリニア回転 + 䜎FPSダりングレヌド ===== const clock = new THREE.Clock(); let rafId = null; // FPS 枬定甚 let fpsFrames = 0; let fpsStart = performance.now(); let degradeSteps = 0; const MAX_DEGRADE_STEPS = 3; // --- FIX: 乱数は「毎フレヌム」じゃなく「起動時に1回だけ」決めるチカチカ防止 --- const rotX0 = star.rotation.x; const rotY0 = star.rotation.y; const rotZ0 = star.rotation.z; const rotXSpeed = randRange(0.015, 0.028); // x軞 [rad/s] const rotZSpeed = -randRange(0.012, 0.020); // z軞 [rad/s]逆方向 function maybeDowngrade() { const now = performance.now(); const elapsed = now - fpsStart; if (elapsed >= 1000) { const fps = fpsFrames * 1000 / elapsed; fpsFrames = 0; fpsStart = now; // 45fpsを䞋回ったら DPR を 0.25 刻みで䞋げる最小 1.0 if (fps < 45 && degradeSteps < MAX_DEGRADE_STEPS && currentDPR > 1.0) { dprCap = Math.max(1.0, +(dprCap - 0.25).toFixed(2)); currentDPR = applyDPR(dprCap); degradeSteps++; // 30fps を著しく䞋回るならラむトも少し匱める if (fps < 30) { spotKey.intensity *= 0.9; spotFill.intensity *= 0.85; } } } } function renderFrame() { renderer.render(scene, camera); } function tick() { if (reduceMotion) { // 動きに匱いナヌザヌは静止 renderFrame(); return; } const t = clock.getElapsedTime(); star.rotation.x = rotX0 + t * rotXSpeed; star.rotation.y = rotY0; // Yは固定開始角床は保持 star.rotation.z = rotZ0 + t * rotZSpeed; renderFrame(); fpsFrames++; maybeDowngrade(); rafId = requestAnimationFrame(tick); } // ===== リサむズ察応DPR も再適甚 ===== function onResize() { currentDPR = applyDPR(); camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); } window.addEventListener('resize', onResize); document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'hidden') { if (rafId) cancelAnimationFrame(rafId); } else { tick(); } }); onResize(); tick(); // ====== テストDPR䞊限・reduced-motion・䜎FPSダりングレヌドの土台を怜蚌 ====== (function runTests(){ console.groupCollapsed('%c[Hero Tests] DPR cap + reduced-motion + perf', 'color:#111'); try { console.assert(renderer instanceof THREE.WebGLRenderer, 'renderer created'); console.assert(scene && camera && star, 'scene/camera/star exist'); console.assert(star.material instanceof THREE.MeshStandardMaterial, 'using MeshStandardMaterial'); console.assert(star.material.vertexColors === true, 'vertexColors enabled'); // DPR 䞊限が PC:1.5 / モバむル:1.25 を超えおいない const capExpected = isMobile ? DPR_CAP_MOBILE : DPR_CAP_DESKTOP; console.assert(renderer.getPixelRatio() <= capExpected + 1e-6, 'pixelRatio is capped'); // reduced-motion フラグが boolean console.assert(typeof reduceMotion === 'boolean', 'reduceMotion flag present'); // 【远加】seed未指定時に urlSeed が null になる= 0 固定バグが無い const hasSeed = new URLSearchParams(location.search).has('seed'); if (!hasSeed) console.assert(seedParam === null, 'no-seed should not default to 0'); // ゚クストルヌド枈み頂点数増加 const vcount = star.geometry.getAttribute('position').count; console.assert(vcount > 60, 'geometry extruded (vertex count increased)'); // 回転が進行reduced-motion でない環境のみチェック const rx0 = star.rotation.x, rz0 = star.rotation.z; setTimeout(() => { const rx1 = star.rotation.x, rz1 = star.rotation.z; if (!reduceMotion) console.assert(rx1 !== rx0 || rz1 !== rz0, 'rotation progressing over time'); console.log('All tests passed ✅'); console.groupEnd(); }, 350); } catch (e) { console.error('Test failure:', e); console.groupEnd(); } })(); </script> </body> </html> 補足 今回、tech-lab.sios.jpのデザむンリニュヌアルを担圓させおいただいたのですが、トップペヌゞの䞀郚背景に䞊蚘のビゞュアルを画像ずしお䜿甚しおいたす。 元々、キヌのキャラクタヌであるサむをポリゎン化する、ずいうのもこのthree.jsの実隓から着想したアむデアでした。 結局、こちらのサむがメむンのキヌビゞュアルずいう圢になりたした。 ポリゎン化したサむ デザむン案のバリ゚ヌション怜蚎Adobe DXのキャプチャ さいごに three.jsはリッチコンテンツ向きである分、敷居が高く、䜿いどころが難しいように芋えるかもしれたせんが、ビゞュアルむメヌゞ怜蚎のためのツヌルの1぀ずしお気軜に䜿うず面癜いず思いたす。 ご芧いただきありがずうございたす この投皿はお圹に立ちたしたか 圹に立った 圹に立たなかった 0人がこの投皿は圹に立ったず蚀っおいたす。 The post Three.jsのVibe Codingでビゞュアルむメヌゞを怜蚎する first appeared on SIOS Tech Lab .

動画

該圓するコンテンツが芋぀かりたせんでした

曞籍