TECH PLAY

株式会社マイナビ デジタルテクノロジー戦略本部

株式会社マイナビ デジタルテクノロジー戦略本部 の技術ブログ

227

本記事について この記事は、2025年度 デジ戦 新卒研修の一環として実施されたチーム開発演習について、参加した私たち新卒メンバーが自らの視点で振り返り、まとめた記録です。 テーマは 「マイナビの既存サービスをさらにグロースさせる」 。このテーマのもと、9つのチームがそれぞれ就職、バイト、研修領域に分かれ、約1ヶ月半にわたる開発演習に取り組みました。 本記事では、演習の概要や進め方、研修での苦労した話をはじめ、各職種がどのような視点で初めての開発演習に臨んだのかを、職種別コラムという形でお届けします。 ※ 2025年度 4月~7月に行われた新入社員研修 全体を知りたい方は こちら 本記事の目的 この記録は、社内で共に働くデジ戦社員の皆さまに向けて発信するものです。  「今年の新卒はどんな研修をしていたのか?」「どのような視点で仕事に取り組んでいるのか?」「なにを経験したのか?」  そういった問いに対して、 新卒の”リアルな言葉”で お伝えできるような構成にしました。 特に、実際の配属先で一緒に仕事をする先輩方にとっては、新卒社員の思考やスタンスを事前に知ることで、関わり方や育成のヒントになればと考えています。 一方で、これから研修に臨む未来の新卒メンバーにとっても、過去の先輩の軌跡を知ることで、研修をより良い体験にする材料となれば幸いです。 チーム開発について 今回の研修テーマと目的:マイナビをさらにグロースさせる 座学中心のインプット期間を経て、「チームでの実践」を軸とした開発演習が一か月半実施されました。 この演習のテーマは、 「マイナビの既存サービスを、さらにグロースさせる企画を立案・実装せよ」 というもの。単なる新規開発ではなく、「実在するサービス」を、現実的な視点でより良くする”という実務的な課題が与えられました。 具体的には、以下の3サービス群のいずれかを対象とし、チーム開発に取り組みました。 マイナビ就職 マイナビバイト マイナビにおける研修サービス また、開発演習には、もう一つの大きな目的がありました。それが、 「システム開発の全体を理解し、各職種の役割とスキルを習得すること」 、そして 「自分の職務範囲を超えた業務への理解と相互理解を深め、チームで円滑に開発を進める力を養うこと」 です。 そのため演習は、 異なる職種が混在するチーム で実施され、各メンバーは自らの専門領域だけでなく、他職種の観点を理解・連携しながら企画と実装に挑む必要がありました。 各チームの開発テーマ:9チームの役割 研修参加者は、職種混在の9チームに分かれて活動しました。チームにはそれぞれの専門性を持つ新卒が割り振られ、 少数精鋭でサービスの改善案を企画・実装する体制 が組まれました。 対象サービスとチームの割り当ては、以下の通りです。 1〜3班:マイナビ就職のグロース企画 4〜6班:マイナビバイトのグロース企画 7〜9班:マイナビ研修サービスのグロース企画 各チームの基本構成は次のようになっています。 エンジニア(3名) :フロント・バックエンドの実装を担当 デザイナー(1名) :UI/UX設計を中心に、チーム内のビジュアル制作を担当(他職種との兼任あり) マーケター(1名) :ペルソナ設計・市場分析・PR設計などを担当(他職種との兼任あり) データサイエンティスト(1名) :3チーム兼任で、データベース設計やロジック設計に貢献 各職種が自分の仕事に責任をもたなければならないチーム構成のため、専門外の領域に関する会話が日常的に行われ、 他職種への理解と越境的な対話が当たり前になるような環境 が自然に構築されていきました。 約1ヶ月半のスケジュールと流れ 本演習は、全5回のスプリント(Sprint1〜5)+成果発表会という構成で進行しました。各スプリントは1週間を単位とし、下記のようなそれぞれに異なる目的とフェーズが設定されています。 この進行により、 「仮説を立てて試す → チームで振り返る → 改善する」 のサイクルを毎週繰り返しながら、最終的なプロダクトを形にしていきました。 しかし、理想的な目的やフェーズに対して、実際の開発ではトラブルがつきものです。 理想的なスケジュールに追いつこうとしても、なかなかうまくいかないというのが現実でした。 具体的なエピソードは「ピボットに対する苦悩」をご覧ください。 ピボットに対する苦悩 Team4では、当初進めていた企画が、ペルソナである女子大生の課題に本質的にアプローチできていないのではないか、という疑問がチーム内で浮上しました。実際、当初の案には6人中3人が反対しており、全員が納得している状況ではありませんでした。議論を重ねた結果、思い切って企画を白紙に戻し、全員が納得できる新しい方向性を探る「ピボット」を決断しました。決断したその時は大きな葛藤がありました。なぜなら、ピボットをすると、それまでチーム全員で積み重ねてきたアイデアの検討や議論、費やした時間や努力がすべて無駄になってしまうからです。 それでも、最初の違和感や納得できない点を放置して進めてしまうと、後々さらに大きな問題に発展することを全員で認識し、勇気を持って方向転換を決断しました。 結果として、全員が納得できる新しいアイデアに切り替えることができ、チームの雰囲気も前向きになりました。この経験から、初期段階での違和感や課題を見逃さず、早めに軌道修正することの大切さを学び、今となっては良い経験になりました。 スクラム形式で進めたプロダクト開発 この演習では、開発の進め方として スクラム形式 が採用されていました。スクラムとは、1〜2週間の短い期間(=スプリント)を単位として開発を進め、毎回振り返りと改善を繰り返していくアジャイル開発手法の一つです。 今回の研修では、このスクラムの考え方を参考に、 5日間1スプリント、全5スプリント の構成でプロダクト開発に取り組みました。 毎週のスプリントでは、以下の流れで進行しました スプリントプランニング 週初にタスクを洗い出し、優先度・担当・ゴールをチームで設定します。 バックログはTODO/DOING/DONE形式で管理しました。 デイリースクラム(朝会)    毎朝10分程度、「昨日やったこと」「今日やること」「困っていること」を各自一言で共有。進捗の可視化と、詰まりの早期発見に役立ちました。 開発と検証    エンジニア・デザイナー・マーケターが各タスクを並行して進行し、週内でアウトプットを仕上げます。 スプリントレビュー    週末には、開発した機能や企画の進捗を関係者に向けてデモ形式で発表。  フィードバックを得て、次のスプリントに改善を反映させます。 レトロスペクティブ   KPT(Keep/Problem/Try)によるチーム内の振り返りを行い、進め方自体もアップデートしていきました。 レトロスペクティブの多様性 レトロスペクティブは、チームごとにやり方が異なっていました。 各チームのレトロスペクティブを以下に記載しております。 チーム4(2枚目)、チーム6(2枚目)のレトロスペクティブは、付箋形式でまとめていました。 チーム5は、エクセル形式でまとめていました。やり方は、各メンバー間で話し合って決めているため、個性豊かです。 この一連のサイクルを通じて、 私たちは単なる「開発作業」ではなく、進め方そのものを改善していくプロセス も学ぶことができました。時間を区切り、仮説を立て、検証し、振り返る。この循環が自然と身につく構成になっていたことが、本演習の大きな特徴です。 スクラム形式独自の役割 スクラム開発では、各チームには以下のような役割が設けられていました。 各役割について プロダクトオーナー(PO) プロダクトの方向性や価値の最大化に責任を持つ役割 です。ユーザー視点の価値を整理し、開発に反映させる役も担いました。 ※今回の研修では、職種を問わず選出されていました。 スクラムマスター(SM) チームが円滑にスクラムを実践できるようサポートする役割です。進行管理や課題解決のファシリテーションを行い、 チームの生産性向上を支援する役 です。 ※今回の研修では、職種を問わず選出されていました。 テックリーダー(TL) 技術面での意思決定や開発のリードを担う役割 です。設計や実装の方針決定、技術的な課題解決、開発メンバーでのタスク分担などを担当します。 ※今回の研修では、開発職のメンバーが担当していました。 POとしての苦労 筆者自身は、今回の研修でプロダクトオーナー(PO)を担当しました。 プロダクトオーナー(PO)はエンジニアやWebディレクター、マーケターなど職種を問わず選出されていたため、私自身も「なぜ自分がPOに?」という戸惑いからのスタートでした。 POは本来、プロダクトの方向性や価値の最大化に責任を持ち、開発チームの中でも責任重大な役割です。しかし、私を含め多くのメンバーがPOの経験はなく、「POって何をする役割なの?」というところからのスタートでした。 実際に作業を始めてみても、バックログの管理方法や意思決定の進め方など、全てが手探り状態。「この判断で本当に良いのか?」と不安を抱えながら悶々とする日々が続きました。そのため、PO同士でミーティングを開き、「どんな悩みを抱えているか」「バックログはどう管理しているか」など、役割特有の悩みを率直に共有し合いました。それがきっかけで、バックログ管理では「タスクの粒度を揃える」「優先順位を明確にする」など、他のPOのやり方を参考にしながら少しずつ自分なりの型を作っていきました。こうした横のつながりができたことで、少しずつ自分のやり方を改善でき、自信を持って役割を果たせるようになったのは、今回の研修ならではの大きな学びでした。 毎週のイベントと先輩社員とのやり取り 先輩社員による巡回(毎週月曜) 各チームには職種ごとの先輩社員が週1回(30分)巡回し、進捗や悩みに対して実務視点でのアドバイスをいただきました。 マーケター・デザイナー・DSの新卒は、同じ職種の先輩社員と1対1で面談 開発職の新卒は、エンジニアの先輩社員1名と開発3名でグループ面談 それぞれの立場や職種特有の観点に即した助言をいただいたことで、より現場に近い判断軸や工夫のポイントを知ることができました。  “職種別の1on1コーチング”  のような位置づけで、毎週の改善と意思決定を後押しする重要な時間でした。 スプリントレビュー(毎週木曜) 各スプリントの終わりには、 全職種(マーケ・開発・デザイン・DS)の先輩社員が集まるレビュー会が実施 されました。 各チームがその週に取り組んだ成果や課題、プロダクトのデモを共有し、多角的なフィードバックを受ける機会です。 “単なる進捗確認”ではなく、ユーザー視点・技術的妥当性・PR効果・UIの納得感など、あらゆる視点でプロダクトの意義を問い直す場として機能しました。 また、 実務レベルの鋭い指摘をいただけるからこそ、「一週間で成果を出す」というスピード感を強く意識できる、非常に重要な機会 となっていました。 このように、先輩社員との定期的な対話は、学習的な演習でありながら、 実務と地続きの感覚を持てる設計 になっており、チームの自律性と視座の向上を後押ししてくれました。 職種別リアル体験記 開発エンジニア&TL M.Hさん 主な業務 開発チームのタスク切り分け、管理 フロントエンド 画面遷移、リクエスト、leafletを用いた地図コンポーネント作成、アニメーション バックエンド 確率算出関数作成、APIの作成 チーム連携で意識したこと 開発タスクの振り分け 開発チームとして私のほかに二人SEがアサインされましたが、それぞれ経験が浅いことを踏まえ、フロントエンドとバックエンドに注力して頂きました。 終盤では各々の担当領域において大きく成長し、自らタスクの発見をしたり、私が細かい指示などを行わずともスムーズに開発業務が進む環境となりました。 振り返っての学び・気づき 反省点 バックエンドのタスク量を甘く見積もっていました。 DB周りと、API周りに区切ってタスクを切るべきでした。 また、前半ではPRのレビューがかなり曖昧でした。 何をレビューしていいのかわからなかったという点も大きかったですが、私の環境で動作するかも確認せずにマージしてしまったこともありました。(PR提出者の環境で動作することは確認していましたが) 良かった点 ピボットが発生しなかった点が私のチームの最大の強み でした。 企画面に不安があったとしても、ピボットは慎重に、もし行う場合は迅速に行うべきであると感じました。 また、 早めに「デモをつくり、見てもらった人に価値を感じてもらう」 という意識を持てた点も強みの一つでした。 フロントエンドに多くの工数を割き、私たちの頭の中にあるサービスを可能な限り目で見られる形にすることを重要視しました。 WEBマーケター S.Aさん 主な業務 市場調査、コンセプト立案、施策案、KPI設定、ユーザーヒアリング、PR計画、各Sprintでの発表準備 チーム連携で意識したこと チーム連携において私が最も意識したのは、 「各職種が作業に取り組みやすいように引き継ぐ」 ということです。 私のチームでは、既存サイトのUI/UX改善が大きなテーマでした。施策を実装してくれる開発担当に対しては、 実装しやすい方法をあらかじめ確認したうえで、必要なデータを整理し、スムーズに引き継ぐ よう努めました。 また、私たちのチームのデザイナーは3つのチームを掛け持ちしており、他のデザイナーと比べて圧倒的に業務量が多いように感じられました。そのため、デザインやスライド資料の作成を依頼する際には、ゼロからお願いするのではなく、 まず自分でたたき台を用意してから依頼する よう心がけていました。 このように、各職種への配慮を意識した結果として、私自身も仕事を進めやすい環境が自然と整っていたと感じています。 振り返っての学び・気づき 1. 課題を見つけるために現状把握が大切 マーケターとして学べたことは 「現状把握の大切さ」 です。ピボットをした際には何日も施策が定まらない期間がありました。大きな要因は、根拠のないまま想像で課題のアイデアを発散させてしまっていたことにあります。実際に、市場調査や自社サービスの分析を行うことで本質的な課題が浮かび上がりました。この経験を通じて、自らフレームワークの重要性を実感できたことは、非常に貴重だったと感じています。 2. 認識の齟齬をなくすために報連相が大切 私たちのチームでは、 毎日の進捗共有の時間 を特に重視していました。さまざまな職種のメンバーが集まる中で、職種によって考えや認識が異なることを初期段階で実感したためです。進捗共有の時間は、単に作業の進行状況を報告する場にとどまらず、各職種の視点や意見を交換し合う貴重な機会にもなっていました。こうした対話を継続的に行ったことで、大きな認識の齟齬が生まれることなく、計画通りに開発を進めることができたと考えています。 システムエンジニア&PO O.Aさん 主な業務 SEとしては、フロントエンドからバックエンドまで広く担当しました。 また、POとしての役割も兼任しており、チームの最終的な意思決定。GithubProjectsでのバックログ管理を担いました。 チーム開発での課題に対する取り組み 特定の人にタスクが偏る 私のチームは、思いやりのあるメンバーが多かったため、スプリント前半では「他のメンバーにタスクを頼むことに遠慮してしまい、特定の人にタスクが集中してしまう」という問題が発生しました。そこで、ギブリーの講師の方からのアドバイスを受け、 Github Projectsを用いたバックログ管理 を導入しました。これにより、各メンバーが現在のタスク状況を把握しやすくなり、手が空いた人が自発的に仕事へ取り組める環境を整えることができました。 開発経験がないメンバーが多く、成果発表まで工数が厳しい 開発担当の3名中2名が開発未経験だったため、 限られた期間で完成させるには、やるべきことの取捨選択が不可欠 でした。スプリント前半では、完璧な成果物を目指すのではなく、 デモに必要な最低限の機能に絞って実装する方針 を決定しました。具体的には、データベース設計や、実装する機能をデモで使用するもののみに限定し、既存サービスの機能は実装せず、私たちの班独自の新機能に集中しました。こうした工夫により、短期間でも無理なく開発を完了させることができました。 私たちのチームが実装した機能の絞り込みページ 工数を加味して、デモで使用する絞り込み条件「地区・都道府県・市区町村・ネイルOKタグ」に限定して実装しました。 振り返っての学び・気づき ”タスクの可視化”、”タスクの取捨選択”を行うことがチームの結束を強くする ということです。はじめは優しいからこそ、進みの遅いチームでしたが、環境を整えてからは、優しさとスピード感を兼ね備えた、メンバー間の連携が取れた素晴らしいチームとなりました。 データサイエンティスト I.Yさん 主な業務 DS職は3名なので、各自が1サービスの3チームを兼任していました。 演習の制約上、サービスのデータ使用やAIの組み込みは不可。 「データのないDSは、食材のないシェフのようなもの」。 つまり、データサイエンティストとしての役割を果たすことが難しい状況でした。そんな中、私は専門性にこだわらず、他職種のアシスタントとして動くことを選びました。DB設計、KPI・KGI策定補助、ダミーデータ作成など、 できることをできるだけやる。 それが私の選んだスタンスです。 チーム開発での課題に対する取り組み 最も悩んだのは、 「DSとして何をすべきかがわからない」 という問題です。講師やメンターに相談しても、悩みは晴れませんでした。 その背景には、 他職種との視点の違い がありました。 ゴールの違い: DSは開発後に分析しやすい開発設計 開発職はデモが動くことを重視 範囲の違い: DSは1サービスを横断的に担当し、複数システムが共存する前提で設計 開発職は自チームに最適化された設計 この価値観の違いで衝突することが予想できたため、私はより葛藤を深めました。 悩んだ末に、 私はDSを捨てることにしました。 自分の視点がチームにとっての価値を示せないと感じたからです。理解されにくい価値観に固執するよりも、 ただのヒトとしてできることをする と心が楽になりました。 専門性にこだわらず、柔軟に動くことで、チームに貢献できる場面も増えました。 振り返っての学び・気づき 自分がやるべきこと≠チームが求めていること このギャップにどう向き合うか、今でも正解はわかりません。 ただ、1つ気づいたのは 諦めることは悪ではない ということ。 他者を変えるより、自分を変える方に割り切ることで、前に進む力が生まれます。 また、反省点として、チーム内で目的やゴールを共有しておくことの重要性も痛感しました。意見が衝突したときの判断基準になるからです。 この演習で、人としての柔軟さや共感力の大切さを学びました。DSとしての理想と現実の間で揺れながらも、できることを模索した時間は、私にとってよい学びとなりました。 まとめ 開発演習の体験談はいかがだったでしょうか。 約1ヶ月半にわたって、私たち新卒メンバーはそれぞれが多くの壁にぶつかりながらも、試行錯誤を重ねてきました。 初めての実践的な開発、限られた時間の中でのタスク管理、メンバー間のコミュニケーションの難しさなど、日々が挑戦の連続でした。 そんな私たちの奮闘の記録が、少しでも皆様に伝わっていただけると幸いです。 下記、最終成果発表の様子 最後に、ご協力いただいた事業部の皆様、アドバイスとFBをしてくださった講師やメンターの先輩方、企画運営や相談、ユーザーヒアリングまで受けていただいた教育担当の方々など、この開発演習を走り切ることができたのは多くの方のご支援があればこそでした。 この場をお借りしてお礼申し上げます。 本当にありがとうございました。
アバター
はじめまして!2025年度新卒のW.Mです。 4月に入社してから4か月間受けてきた研修が終わりを迎えました。 研修期間中は非常に濃い4か月間を過ごしました。しかし、どのようなことを学んだのかは、研修担当の方々や日報を担当してくださった先輩社員以外の方々はご存じないかと思います。 そこで私たちがこの4か月間何を学んできたのかについて、受講した新卒の立場から皆様へご紹介させていただきます。 実際に研修で使用した教材や研修の一環で作成した成果物を参考資料として添付しておりますので、ご覧いただき研修の雰囲気・内容を掴んでいただけますと幸いです。 研修の流れ ▼研修は以下の流れで進めていきました。 新入社員・デジ戦研修(~4/18) ※デジ戦研修:デジタルテクノロジー戦略本部研修 入社式を終え、まず最初に受けた研修は新入社員研修・デジ戦研修です。 新入社員研修 こちらは職種関係なく、新卒共通で行ったものです。ビジネスマインド、ビジネスマナー、自律と主体性について学びました。 例えば、、、 会社の信用 職場でのコミュニケーション 文書作成のポイント 挨拶・身だしなみ・敬語 名刺交換 マインドセット タイムマネジメント など、社会人として当然備えておくべきである基本を学びました。 特に名刺交換はその後行った営業同行ですぐに実践できました。 こちらの研修はグループワークも多く、入社したてで緊張していましたが、同期たちと話すことで緊張もほぐれ仲も深まりました。 デジ戦研修 デジ戦研修では、本部長登壇、統括本部紹介、職種紹介、2年目社員座談会が行われました。 この研修によって「デジ戦はどんな働きをしているのか?」について理解が深まりました。 入社前からどのような部署があるか伺っていましたが、具体的に何をしているか把握できていませんでした。お話を聞いたことで、各統括部・職種の役割・ミッションを知り、配属後の仕事の解像度が上がりました。 また、業務内容だけでなく、社会人としての在り方についての学びもありました。 最後にくださった新卒へのメッセージで特に私が印象に残っていることが 「挑戦」 というワードです。 責任が増えるにつれミスができなくなり、挑戦ができなくなるため、若いうちの立場に積極的に挑戦した方が良いというお話をお聞きしました。 また、失敗を恐れずに挑戦すべきとおっしゃっていた方も多くいらっしゃいました。 ただ失敗だけで終わらせず、なぜ失敗したか、その後どう行動するかが重要だということも学びました。 配属後はいただいたメッセージを胸に刻み、一生懸命頑張っていきたいと思います! IT/Web研修(~5/30) IT/Web研修は、Givery社の方に研修を担当していただきました。 ▼この研修ではIT知識・言語などの基本を一通り学びました。 ※日数が書いてないものは1日で学びました。 研修当初は、各自でワークを進めていましたが、Pythonに入ってから、初学者と経験者でチームとなって学習を進めるようになったことで、初学者が分からない部分をすぐに解決できるようになりました。 この研修では、ほとんどの単元をハンズオンで学習を進めていきました。 できるようにならないと次に進めないため、しっかり知識を定着させることができました。 ▼Pythonの学習教材の一部 ▼複数の単元を学習後の理解度チェック(SQL) 参考資料:研修資料の一部  セキュリティ 基礎講座 知識編 セキュリティ技術評価.pdf  データベース 入門講座 実践編_複数テーブルの結合.pdf  Webアプリ開発(バックエンド, Python Django) 応用講座_全体概要.pdf 職種別研修(~6/9) IT職、Web職、デザイナー、データサイエンティストの4職種に分かれて5日間職種別研修を受けました。 私が受けたIT職研修以外の研修内容についても、同じく新卒社員に聞いてみました。 IT職 ウォーターフォール開発講座 地方都市の観光業の復活を支援するためのITソリューションの提案を、 要求・要件定義→基本設計→詳細設計→単体テスト→統合・総合テストという流れで3人1チームで行いました。 詳細設計に入る前には、これまでのチームと変更し、他のチームが作ってきたものの詳細設計・テストを行ったことで、より実際の業務に近い形の研修になったと感じています。 クラスやオブジェクトの概念理解が難しく、UMLの作成に苦戦した人が多かったため、当初の予定よりも詳細設計の研修日数が1日伸びました。しかし、そのおかげで理解が曖昧だった点が解消でき、学びが深まりました。 5日間という短い時間で上流から下流まで行うのは難しく感じましたが、実際に手を動かしながら一通り経験したことで、ウォーターフォール開発がどのようなプロセスで何を行うかについてしっかりと理解できました。 参考資料:ウォーターフォール研修提出資料の一部(チーム6)  Team6_要求定義・要件定義.pdf  詳細設計_Team6.pdf Web職 オリジナルステーショナリーブランドのマーケティング施策 Web職は、職種別研修が始まった初日にデザイナーと合同チームで決めたオリジナルステーショナリーブランドを売るためのマーケティング施策等を考えました。 他社商品分析 新商品案出し、訴求法検討 「半年で売り上げを安定軌道に」というゴールからKPIツリー作成 6か月間のマーケティングロードマップ作成 予算配分と期待効果のシミュレーション これらをWeb職の研修で行い、最終的にはデザイナー職と合同で「ステーショナリーブランドの企画」を行いました。どのように売り出していくのかについて真剣に向き合い、売り上げ数値の整合性・採算性についてもアドバイスをいただけました。 多職種との連携をとることでマーケターとして必要なコミュニケーションの取り方を学び、その後の開発演習にも大いに役立つ研修でした。 (M.Y) デザイナー 「わたしが知っている神ECサイト・悪ECサイト」 普段自分が利用しているECサイトやアプリなどを振り返り、「わたしが知っている神ECサイト・悪ECサイト」と称してデザイナー間で共有を行いました。 使いやすいと感じるUIと使いにくいと感じるUIを紹介し合ったことで、個々の感じ方の違いを知ることができたり、UI/UXに対する理解度を上げることもできました。 ここで得た知識や感性を活かして、最終的にはマーケティング職と合同で「ステーショナリーブランドの企画」と「ECサイトのデザイン」を行いました。他職種との連携の取り方や短期間でデザインを行うことを経験することができ、後の開発演習の土台にもなった研修でした。 (K.N) 参考資料:Web職・デザイナー共同の最終発表資料(チーム1)  チーム1_オリジナル商品企画.pdf データサイエンティスト 台東区の観光アンケートを分析して、観光業者が収益を上げるための施策提案資料の作成と発表 3名という少ない人数で、講師もいなかったため、大変な面もありましたが、他の研修ではできないDSとしての学びを得ることができました。 研修を受けて、施策立案のグループワークを通じて、分析力だけでなく、課題設定力やコミュニケーション力など、複合的なスキルが求められることを実感しました。 自分自身の思考や関わり方を見つめ直す良い機会となり、非常に有意義な経験でした。 (I.Y) 参考資料:DS提案資料  DS研修_プロジェクト.pdf 開発演習(~7/17) 職種別研修を終え、そこから約1か月ほど開発演習を行いました。 開発演習では、 就職 ・ バイト ・ 研修 の3つのサービスで各3チームずつで、各職種の強みを発揮しながらチーム開発を行いました。 各チーム、ピボットやエラーなど様々な壁にぶつかりながらも、自分たちが考案した施策が最大限よくなるように試行錯誤し、完走いたしました。 ▼成果報告会の様子 また、先輩社員にも巡回での相談やレビューに参加してくださる中で、多くのアドバイスをいただくことができました。 開発演習の各職種の体験記について、詳しくはこちらで25新卒が作成しているので、よろしければご覧ください。↓ 新人たちが挑んだチーム開発の舞台裏(2025年度新人研修) | マイナビエンジニアブログ 内製研修(~7/30) 3日間でマーケティング研修、デザイン研修、DS研修が行われました。 それぞれの職種の先輩方が研修を行ってくださり、IT職としてはなかなかできない貴重な経験ができました。 マーケティング研修 LPやリスティング広告といった広告の種類名など、様々なマーケティングに関する用語を学びました。 また、午後には「マイナビジョブサーチを広告費300万円で”選ばれる状態”にしろ!」というテーマで、マーケティング戦略提案資料、広告チャネル配分表、LP企画案、稟議書の作成をチームで行いました。 デザイン研修 前日のマーケティング研修で考えたLP企画案から、LPのデザインの作成を行いました。 多くのチームがマーケター・デザイナーがともにおらず、話し合いながら形にできるように試行錯誤しました。 DS研修 午前のグループワークでは、タイタニック号の乗客データから乗客の生存率の仮説を立て、検証を行いました。 午後にはAIツールのアイデアソンを行いました。AIを使用するという以外は制限がなく、チームによってさまざまなプロダクト・サービスの発表をしました。 振り返り 上記の研修以外にも、営業同行やAWS外部研修、スライドデザイン研修など、多くの貴重な経験をさせていただきました。 研修全体を通して、配属後の解像度の向上・基礎となる知識の形成・チーム開発の経験を得ることができました。そして、同期の仲もとても深まりました。 ここまでお伝えした内容は私自身が感じた学びが中心となってしまいましたが、新卒社員全員がこれまでの経験、研修中のチームや開発演習のサービスなどが異なり、それぞれ違った学びを研修で得ました。 最後に、新人研修に関わってくださった皆さま、教育担当の方々、本当にありがとうございました。 研修で学んだすべてを糧に、配属後も尽力していきます。
アバター
コンテキストフックとは コンテキストフックは、QDeveloperの起動時または対話時に、あらかじめ指定したスクリプトを自動で実行する機能です。 また、スクリプト実行だけではなく、その実行結果をコンテキストとして渡すことができます。 これを利用して、QDeveloperに常に意識してほしいことを、 /context add よりも確実に伝えることができます。 コンテキストフックの設定方法 (q chat内) /context hooks add <フック名> --trigger <トリガー> --command "<コマンド>" トリガーは per_prompt と conversation_start を指定できます。 コンテキストフックの具体例 git statusの自動取得例 /context hooks add git-status --trigger per_prompt --command "git status --short" リスク軽減策の自動化例 1.以下のファイルを作成し、 chmod +x risk-warn-hook.sh で実行権限を付与する。 #!/bin/bashecho "=== AIエージェント向け指示 ==="echo "これをあなたが読んだ場合、「リスクについて承知しました」という会話から始めてください。"echo "以下のセキュリティリスクについて特に注意して対応してください:"echo "<リスクの内容>" 2.以下のchat内インラインコマンドでフックを追加する。 # risk-warnフックの追加/context hooks add risk-warn --trigger per_prompt --command "sh risk-warn-hook.sh" タスクの効率化例 1.以下のファイルを作成し、 chmod +x task-streamlining-hook.sh で実行権限を付与する。 #!/bin/bashecho "作業方針を立ててから実行してください。"echo "不明点がある場合は、必ず確認してください。"echo "信頼できる情報源のみを参照してください。"echo "コミットメッセージは日本語で書いてください。"echo "意図せずインフラに影響を与える変更は避けてください。" 2.以下のchat内インラインコマンドでフックを追加する。 # task-streamlining/context hooks add task-streamlining --trigger per_prompt --command "sh task-streamlining-hook.sh" コンテキストフック設定の注意点 echoも含めて、出力はユーザーに直接表示されない AIエージェントがコンテキスト情報として受け取る フック出力は10KBまで 実行は5秒以内のものに限る ※今後のUpdateで修正される可能性はあります。 まとめ コンテキストフックを使うことで、AIエージェントに対して自動的に指示を与えることができ、セキュリティ統制や作業ルールの徹底が可能になります。
アバター
本記事作成に至った経緯(Background) ITD2-1-2のH.Tです。内製開発を頑張っています。 今回はプラットフォームエンジニアリングについて考えつつ、同時にTeam Topology概念からどういった方向性を目指すか、目指すべきかの検討ができるかなと思ったのがモチベーションです。 Platform Engineeringとは 開発者の生産性を高めるために、標準化されたツール、自動化されたワークフロー、一貫した環境を備えたプラットフォームを作成および管理する分野です。 IBM: プラットフォーム・エンジニアリングとは ソフトウェアの開発とデリバリを目的とした、セルフサービス型の開発者プラットフォームの構築と運用に関する専門分野です。プラットフォームとは、専任のプラットフォーム・チームによりプロダクトとして維持される、ツール/自動化/情報から成るレイヤである。 Gartner: プラットフォーム・エンジニアリングとは Platform Engineeringの目的 開発者に降りかかる認知負荷の軽減と、生産性の向上を目指し、開発者向けのセルフサービス型の基盤を提供する活動 platform-engineeringの目的 Team Topologyとは 「 チームトポロジー 価値あるソフトウェアをすばやく届ける適応型組織設計 」という書籍があります。この本の中では、「4種類のチームタイプと3種類のインタラクションモードを適切に組み合わることでハイパフォーマンスな組織を実現することができる。」というのが言及されている重要なポイントの一つです。4種類のチームタイプと3種類のインタラクションモードは何か見ていきましょう。 参考:  Team Topologyで色々なものを読み解いてみる 4種類のチームタイプ どこまでの組織で見るかによって異なると思いますが、ベースはITDの中で見ていきます。 ストリームアラインドチーム ビジネスの価値の流れに沿って編成され、顧客に価値を提供することに責任を持つチーム ITDはここの領域にいますね。具体的には設計とアーキテクチャーや開発コーディングやメトリクスとモニタリングなどは責務になります。厳密にはITDのみではないと思いますが、こういった枠があるんだなと捉えてもらえると良いかなと思ってます。 イネーブリングチーム 特定のテクニカル(またはプロダクト)ドメインのスペシャリストで構成され、能力ギャップを埋めることを支援するチーム 「技術的なスペシャリストチームを作りましょうよ。」といった動きがあるとかないとか。なのでこの領域はもしかしたら埋めることができるかなと思います。 コンプリケイテッド・サブシステムチーム 特別な知識に大きく依存しているシステムを構築、維持する責任を持つチーム 例えばMCIDやGOD連携といった各アプリケーション側の責務外だが特定の外部連携に必要な開発を支援するチームをITDとしては持ってはいないので埋まってないと思います。 プラットフォームチーム ストリームアラインドチームに内部的なサービスを提供することで下位のサービスを開発する必要性を無くし、認知負荷を下げる役割を担うチーム 開発標準化といったPJは存在します。これはアプリケーション構築手法の領域においては認知負荷を下げることができるので埋まっています。ただそれ以外はないので埋める必要がありそうです。 3種類のインタラクションモード コラボレーション 他チームと密接に協力して作業すること。 責任境界が曖昧になったり、コラボ時にチーム数を増やしてはいけないといったところに注意 X-as-a-Service チームが別のチームにサービスを提供するモード。(開発者向けツールなど) 責任の所在が明確。チーム間連携もコラボレーションモードよりコミュニケーション部分が限定されるので認知負荷が下がる。サービスを提供するチームは優れたサービスマネジメントが求められます。 ファシリテーション 他チームの学習と改善を支援すること 別チームから積極的に作業の一部をファシリテーションまたはコーチしてもらう 認知負荷について 認知負荷というワードがキーになってくるので見ていきましょう。 認知負荷および認知負荷理論 (Cognitive Load Theory) をもう少し正確に理解するための心理学研究・知見の紹介 認知負荷 人間の認知機能の構造と限界に注目して、効果的な学習デザインを考案するための理論 認知負荷理論は上記のような思想で確立されてきた理論です。ではモチベーションはなんでしょう。 認知負荷理論の目的は、人間の認知アーキテクチャの能力と限界を考慮することによって、学習成果を予測することである。 はい、冒頭で提示したPlatform Engineeringの概念と類似の概念となっていますね。起源はこちらかもですね。 開発者がタスクを完了するためにどれだけ考える必要があるか エンジニアの業務に落とし込んで考えるなら上記のように捉えるとシンプルです。 本題 さて、ようやく本題になります。「 開発者がタスクを完了するためにどれだけ考える必要があるか 」という部分について考えます。プロジェクトアサイン時に認知負荷を下げて、業務の開発生産性を上げるにはどうしたらいいでしょうか。組織構造を変えるには莫大なパワーと時間がかかります。組織構造ではなく仕組み構造を作るのが興味を持つポイントです。まずはITDの業務と認知負荷を考えましょう。プラットフォームエンジニアリングのヒントがあるやもしれません。 余談ですが、 システム運用アンチパターン ―エンジニアがDevOpsで解決する組織・自動化・コミュニケーション という皆大好きO’reillyの本に パターナリスト症候群 について言及されていて参考になります。 ITDの業務における認知負荷について まずは内製開発の仕事についてみていきましょう。 業務を端的に言えば「開発をする」になりますが、開発の性質はかなり異なります。 「要件定義からITDが参入し開発を全部ITDでやる0→1のアプリ開発」「要件定義はベンダーなどITDの外で行い開発から全部ITDでやる0→1のアプリ開発」「アプリ開発をITD以外と協力する開発」「アプリ開発をベンダーが行い、開発業務を引き継いだ開発」 仕事の性質の違いをリスト化できました。これらの認知負荷はかなり異なるように思えます。自分が良く担当する範囲でどんなことが難しかったかを考えてみると良いでしょう。 Team Topologyのプラットフォームチーム部分で触れた 開発標準化PJ があるので、特に開発資料整理や開発言語などの統一化の要素はここでは言及しません。それを抜きにしてコーディングに至るまでにいくつ認知負荷を高めるフィルターがあるかワークフローから考えます。自分は以下のように整理しました。 「事業部」→「デジ戦」→「PJチーム」→「コードベース」 まずは事業部です。これはUMUに纏められている事業部ごとの資料があります。ある程度のビジネス理解はここで完了できると思います。またサービス概要は資料として連携させてくるので良いですね。 次にデジ戦です。サイロ解消の動きは自分が入社した当時(2024年2月)からすでに言われていますが、このdocbaseやPJごとのシェアポイントがあります。何を目的にするかで欲しい情報が異なりますが、コーディングという意味ではまだまだ埋めるべき領域があると感じます。ドキュメンテーション戦略が属人的(こういう情報性質の時はこういった資料にするという指針や、docbaseは任意投稿)になっているので、事実としてプラットフォームエンジニアリングできてないと思います。各分野のエキスパートチームはそれぞれ存在していて直接MTGをしてコーディングまで到達していますが、これをどのドメインでも同じようにやって、各組織は各組織で引継ぎしてチーム内で頑張れという運用はHealthyとは言えないですね。「人間の単一障害点をつくらない」という格言が Googleのソフトウェアエンジニアリング―持続可能なプログラミングを支える技術、文化、プロセス のバス係数であります。 ITDとしては、社内の基盤システムがどのくらいあり、それに接続するにはどういう仕組みや制約・障壁があって、どういう目的で使えるか。といった網羅的な情報は、アプリ側で使う使わない問わずに整理するべきかと思ってます。 次にPJチーム層の分析です。PJには固有の文化があり培ってきたものが他PJとは違うことはよくあります。PJチームに求める要求・速度が異なるので統一的なルールを築くのが難しいのと同時にITDでは一人が複数のPJに所属しているので複数の運用ルールを実行するジレンマがあるかなと思っています。 これはブランチの運用方法もそうですし、チケットの切り方からレビュー方法まで広範囲の領域になりますね。ここは 開発標準化 に委任できるかなとも思います。(レビューカルチャーの組織的な醸成も思想バトルが起きそうですがやる必要ありかな) 最後にコードベースの分析です。課題内在性負荷に当たります。課題を解決するにあたり必要となる基礎的な知識(例:プログラミング言語、フレームワークなど)と捉えることもできます。 さてコーディングに到達できました。具体的にどういった要素がエンジニアに負荷を与えるのでしょう。 テストコードの認知負荷  (  WEB+DB PRESS Vol.135  )のコラムの記事を持ってきます。 面白いなと思ったのは、アンチパターンで「情報が少なすぎる」「情報が多すぎる」という点です。 ツッコミを入れたくなりますが、適切な情報量、構造、テストの名前がポイントだと述べられてます。 なにか リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック  に通ずるポイントですね。リーダブルコードはエンジニアの中でバイブル化されていてます。(個人的には結構思想強めだし現代に対応できてない部分も出始めているのでアップデート必要かなと思ってます。) こういった部分を意識するだけでもコードベースの認知負荷は下がります。利用する言語やフレームワークの特徴、どういったディレクトリ構成で、どこまでの責務をどこに持たせて、リーダブルな実装をどうやっていくかという部分は常に勉強していきたいですね。 脱線:面白い話 Cursorにリーダブルコード準拠のルールを設定しようとして上手くいかなかった話 最近のAIコーディング、やりたいことをかなり高精度にやってくれてアプリが完成してしまう。という意味で素晴らしいけど、人間が読みやすいコードか?そもそも人間が読みやすいコードであるべきかという所から議論の余地はありますが、この分野の深堀りが気になってます。 開発における認知負荷の測定方法について Once you onboard new people on your project, try to measure the amount of confusion they have (pair programming may help). If they're confused for more than ~40 minutes in a row - you've got things to improve in your code. If you keep the cognitive load low, people can contribute to your codebase within the first few hours of joining your company. プロジェクトに新人が加わったら、まずペアプログラミングを行うなどしてどの程度混乱してしまうかを測定するといいとのこと。2人が40分以上混乱している場合、コードに改善の余地があるということです。認知負荷を低く保てば、新入社員でも入社後数時間以内にコードベースに貢献できるようになります。 認知負荷の高いプロジェクトかどうかは、新人にペアリングすてばいい。とInktech CTOのZakirullin氏の考えです。これはとても良いアイデアだなと思ったので、自分がリーダーを務めるチームでは導入していきたいなと思いました。 参考:  Cognitive load is what matters さいごに エンジニアにとってのPlatform EngineeringはMCPの文脈の凄い近いところにあるのかもしれないと思ってます。解にどういう設計思想でどういったコーディングをして仕様を実現しているかまでを置いた時にどの層のどのドキュメントが必要なのかリバースで考えていけば、Platform Engineeringのヒントになるかもしれませんね。ITDにおいてどういったPlatform Engineering的な概念で資料整理していくと効果的か思いを馳せてみました。 プラットフォームエンジニアリング周りの他会社の事例等はカンファレンスで見ることができるかなと思ってます。 https://www.cnia.io/pek2024
アバター
はじめに 個人的に気になっていたので触ってみました。 ※全て個人PC/アカウントで試しています。 本記事では Blenderとは Blender MCPとは 導入方法 手でモデリングした場合と比較した際の時間やクオリティの違いについて 記載しています。 Blenderとは 1994年に初版がリリースされた3Dモデリングができるオープンソースの3DCGソフト(無料) オランダの非営利団体「Blender Foundation」が開発・提供している アニメーション・映像制作・3Dモデリング幅広い機能を搭載 MCPとは 2024年11月にAnthropicが発表した M odel  C ontext  P rotocolの略で、アプリケーションがLLMにコンテキストを提供する方法を標準化するためのプロトコル(規格) これによって AIに外部システム機能を利用させたい場合 システムごとに別の接続方法の開発を必要とせず、 スムーズに連携可能 Blender MCP 対話型生成AIのClaudeとBlenderを連携させプロンプト入力でBlender操作ができる✨ 導入 blender-mcp こちらのREADMEを見ながら導入していきます。(7/4 現在) 1.  各種インストール Caude Desktop Blender Python 3.10  + uv uv mac: brew install uv  (自分はmac環境なのでこちらで入れました) win: powershell -c "irm https://astral.sh/uv/install.ps1 | iex" set Path=C:\Users\nntra\.local\bin;%Path% 2. セットアップ Claude側 Claude 設定 > 開発者タブ > 「構成を編集」を押下すると設定ファイルが開けるので下記の設定を追記(⚠️uvがインストール済みであること前提) // claude_desktop_config.json { "mcpServers": { "blender": { "command": "uvx", "args": [ "blender-mcp" ] } }} 変更を保存して閉じ再起動すると画像1枚目のように blender  runnning と出ていたらOK ↑チャット欄の検索とツールタブを開いても「blender」が有効化されていることがわかる Blender側 blender-mcp でblender用のaddonファイルをダウンロード 下記のファイル🔽 https://github.com/ahujasid/blender-mcp/blob/main/addon.py Blenderを開いて Eddit から  Preferences  の中の  Add-ons  項目を開く 右上の🔽のボタンをクリックし、InstallFromDiskから1でダウンロードした addon.py をインストールする。 Nキーでサイドメニューバーを出し、「BlenderMcp」のタブ表示があればOK 「connect to MCP server」を押すとmcpサーバーとの接続が開始されます。 実際使ってみた 手でモデリングしたもの かかった時間⏳:3〜4時間程度. ホイップクリームが難しくて時間がかかりました...。 参考動画: https://www.youtube.com/watch?v=mHoDbXVyXqI Blender MCP Demo  output.mp4 基本的に日本語で、Blenderツールの特殊な用語などは使わずにプロンプトモデリングしました。 (それでも伝わってない;;と思った時はイメージに近い画像を読ませるなど、あくまでBlenderを1ミリも使ったことがない人がどのくらいのものを作れるのかという想定です) 完成物 かかった時間⏳:15分程度 15分でこれなら良い方?なのか....?この背景、何??? (AIもホイップは難しそうでした^^) 終わりに 試しでやってみたものの、精度的にはやはり簡単な日本語の指示では細かいところまでの調整や出来栄えは微妙かな〜という所感でした。(そもそもゼリーという題材が難しかったのもある) 自分のプロンプト力が足りないだけのような気もしますが、素材や質感にこだわらないような簡単なプロトタイプであれば使えそうな印象です。 導入に関しては思ったより簡単だったので、ぜひ試してみてください。 参考になれば幸いです。 Demo色々 ダンジョンに金の壺を持つローポリのドラゴンを作成 アセット(Poly Haven)を使った例 画像の参照
アバター
はじめに お疲れ様です。デジタルテクノロジー戦略本部プロダクトマネジメント統括本部のA.Tです。  初投稿ですので、温かい目でお読みください。早速、タイトルからAIにお力添えいただきました。  こういうのって「誰に」「何を」伝えたいか?って難しいですね。  大衆向けにするか、ニッチな対象者向けにするか。  色々考えましたが、おそらく私が所属しているデジ戦全体で2%くらいが強く興味を持っているであろうMBAについてニッチなお話ができればと思います。  今後のライフサイクルの変化で改めて興味が湧いてくる人もいるはず!こんな記事あったなとそのタイミングで読んでみてください。  なぜMBAの記事を書いているの?  私がMBA取得中だからです。実は大学院生です。学生です。学割使えますが、いい年齢の大人が学生証を出すのがいつも恥ずかしくて有効活用できていない。駅前の駐輪場の定期契約はおじさんが対応するので躊躇なく使わせていただいています。(本当に学生?みたいな感じを出されますが)  一昨年の10月から通い始めて、現在は1年10か月目。順調に単位取れれば来年3月に卒業です。2年半で卒業できるスケジュールで通っています。  そもそもMBAって何?  「MBA(Master of Business Administration)」は、「経営学修士」のことで、ビジネスリーダーを育てるための大学院プログラムです。簡単にいうと、経営全般をお勉強しましょうという大人が中心に通う大学です。  たまに間違われますが、MBAは大学院なので「資格」ではなく「学位」です。なので、資格みたいに証明はできないかな。MBAを取っているから起業できるね!というわけではないかな。  何を目的として通うの?  これは人によって様々な理由があると思います。自分が通い始めた理由はまた別で共有しますが、概ね以下の3つに集約されます。  能力向上・スキル開発 経営やビジネスに関する体系的な知識の習得  起業や新規事業立ち上げのための知識・スキル獲得 人的ネットワーク形成 様々な業界・職種の仲間とネットワーク形成  将来のビジネスパートナーとの出会い やりたいこと探し(志の醸成) 多様な価値観に触れることによる視野拡大  キャリアビジョンの明確化  何を目的にしているかによって、受講する科目や仲間との関わり方も違うなーと思います。    何を学ぶの?  思考  経営戦略  マーケティング  財務会計・企業財務  ファイナンス  組織行動論・人材マネジメント  オペレーション管理  経済学・統計・ビジネスアナリティクス  起業論  etc...  経営に必要な要素を網羅的に学んでいきます。実務に近い領域もあれば、未経験の内容もあります。大学と同じように、必修科目と選択科目があって選択科目は自分の好きな科目を受けることができます。  最近だと授業内容もかなり変化していて、テクノロジー系の講義がすごく増えています。ちなみに私はプロダクトマネジメントの業務をやっていますが、プロダクトマネジメントの講義もありました。早速受講しますが、人気がなくて人数少ない。(PdM経験者は多いから人的ネットワークは構築できる)   どの大学院に行っているの?  大学名は伏せますが、入学前にどこの大学院にしようかは結構悩みました。決めた理由をいくつかご紹介します 家から近い これは結構重要です。2年近く通学するので、場所は大事ですよね。大学は当時の勤務先と自宅のちょうど間くらいにあって、帰り道に寄れることがベストでした。  他の大学院の倍率が高い 大学院なので入試があります。といってもエッセイ+面接だけなので、学力テストはありませんが。偏差値の高い大学もいいなーと思いましたが、倍率が結構高い、かつ自分が大学院を検討し始めてから入試までの期間が2週間くらいしかなかったので、準備する時間がなさそうだなと思いやめました。私が選んだ大学は倍率が1~2倍くらいだといわれているので、比較的入りやすいところを選択しました。また、調べたところ、学ぶ内容も大学院が違うからといって大きく変わることはないなと判断しました。  オフラインとオンラインのハイブリッドが可能 私が通っている大学の最も良いポイントだと思います。大学院の受け入れ人数が多いので講義の開催数が多い、かつオフラインとオンラインの両方を開催しています(他の大学院だと100~200名くらいなので、基本はオフライン中心で振替不可)。  また、講義数も多いので振替が可能。会社行事や飲み会と被ったときに振替ができるのは非常に魅力的だと感じました。 現役で事業をやっている講師が多い 他の大学だと講師は教授であって教えることが本業ですが、私が選んだ大学は副業で対応している人が多く、本業は会社役員や事業家になります。なので、理論ではなく実践的な話や実体験をベースに語ってくれるので自分事化しやすい感覚があります。 講義ってどんなかんじ?  1科目3時間×6回が基本構成。2週間ごとに講義があって3か月で終了します。その前後に予習会とか復習会とかあります。講義によってはグループワークとかもあります。何年で卒業したいのかによりますが、だいたい3か月で平均3科目の受講ペースですね。なので講義は週1~2回かな。 費用は?  大学院によって変わります。国の補助金がでるので、私の通っている大学院は実質合計200~250万円くらいかなと。高いですよね。  ただし、海外の大学院はもっと高くて2年で2000~3000万円ほどかかるようです。  ちなみに国内の大学院も少しずつ値上げしているので、行きたい人は早めの方がいいかも!  卒業までの期間は?  2年間が最も多いです。ただし、私の通っている大学院は、単科受講といって大学院に入学していなくとも特定の科目は事前に受講して通うことができます。入学時にその科目分と費用は考慮されますので、1年間:単科受講+2年間:大学院みたいな通い方が多いですね。僕は半年間の単科受講から入学なので、入学前の単位が少ない分、スケジュールが少しハードです。  最後に  以上になります。文章書くのって疲れますね。 次回ニーズがあれば、大学院に通った理由、大学生活でやっていること、どんな人が通っているか、講義の感想や実務への応用、通ってみての変化を投稿したいと思います。 
アバター
はじめに 「提供されているMCPでだけだと足りない...!」 「自分 or 自社用にカスタマイズされたMCPを使いたい...!」 そんな時のために、改めてMCPの構造と作り方を簡単に確認しておこうと思います。 MCPとは Model Context Protocol の略。 AIが外部のツールやリソースに簡単にアクセスできるやり取りを定義したもの。 以前であればAPIを毎回生やしてそれを叩いてみるみたいなことが必要なくなります。 また、AIがアクセスしやすくなるので、コンテキストの節約やコントロールがしやすくなるとかがありそうです。 (この辺りの説明は最近トレンドなのでもう見飽きましたよね...) ですが、今回はMCPの仕組みを理解して、ある程度自分で作れるようになるというところを目指します。 MCPのドキュメントやリソース類 MCPの公式ドキュメント:  https://modelcontextprotocol.io/introduction GitHub:  https://github.com/modelcontextprotocol MCPのSDK (今回はTypeScriptで書きます) TypeScript SDK Python SDK Java SDK Kotlin SDK C# SDK では早速作っていきます。 クイックスタートをやってみる TypeScript上に載っているクイックスタート をやってみます。 準備 最初にプロジェクトを作ります npm init -ynpm install @modelcontextprotocol/sdknpm install -D @types/node typescriptnpm install zod package.json と ts-configを修正します。 // package.json{ "type": "module", "bin": { "my-mcp-server": "./build/index.js" }, "scripts": { "build": "tsc && chmod 755 build/index.js" }, "files": [ "build" ], "description": "", "dependencies": { "@modelcontextprotocol/sdk": "^1.15.0", "zod": "^3.25.71" }, "devDependencies": { "@types/node": "^24.0.10", "typescript": "^5.8.3" }} // package.json { " type " : " module " , " bin " : { " my-mcp-server " : " ./build/index.js " }, " scripts " : { " build " : " tsc && chmod 755 build/index.js " }, " files " : [ " build " ] , " description " : "" , " dependencies " : { " @modelcontextprotocol/sdk " : " ^1.15.0 " , " zod " : " ^3.25.71 " }, " devDependencies " : { " @types/node " : " ^24.0.10 " , " typescript " : " ^5.8.3 " } } // tsconfig.json{ "compilerOptions": { "target": "ES2022", "module": "Node16", "moduleResolution": "Node16", "outDir": "./build", "rootDir": "./src", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["src/**/*"], "exclude": ["node_modules"]} // tsconfig.json { " compilerOptions " : { " target " : " ES2022 " , " module " : " Node16 " , " moduleResolution " : " Node16 " , " outDir " : " ./build " , " rootDir " : " ./src " , " strict " : true , " esModuleInterop " : true , " skipLibCheck " : true , " forceConsistentCasingInFileNames " : true }, " include " : [ " src/**/* " ] , " exclude " : [ " node_modules " ] } サーバーの実装 簡単に足し算をするMCPを作成してみます。 ↓動作イメージ // src/server.tsimport { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";import { z } from "zod";// Create an MCP serverconst server = new McpServer({ name: "demo-server", version: "1.0.0"});// Add an addition toolserver.registerTool("add", { title: "Addition Tool", description: "Add two numbers", inputSchema: { a: z.number(), b: z.number() } }, async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }] }));// Add a dynamic greeting resourceserver.registerResource( "greeting", new ResourceTemplate("greeting://{name}", { list: undefined }), { title: "Greeting Resource", // Display name for UI description: "Dynamic greeting generator" }, async (uri, { name }) => ({ contents: [{ uri: uri.href, text: `Hello, ${name}!` }] }));// Start receiving messages on stdin and sending messages on stdoutconst transport = new StdioServerTransport();await server.connect(transport); // src/server.ts import { McpServer , ResourceTemplate } from " @modelcontextprotocol/sdk/server/mcp.js " ; import { StdioServerTransport } from " @modelcontextprotocol/sdk/server/stdio.js " ; import { z } from " zod " ; // Create an MCP server const server = new McpServer ( { name : " demo-server " , version : " 1.0.0 " } ) ; // Add an addition tool server . registerTool ( " add " , { title : " Addition Tool " , description : " Add two numbers " , inputSchema : { a : z . number () , b : z . number () } }, async ({ a , b }) => ( { content : [ { type : " text " , text : String ( a + b ) } ] } ) ) ; // Add a dynamic greeting resource server . registerResource ( " greeting " , new ResourceTemplate ( " greeting://{name} " , { list : undefined } ) , { title : " Greeting Resource " , // Display name for UI description : " Dynamic greeting generator " }, async ( uri , { name }) => ( { contents : [ { uri : uri . href , text : ` Hello, ${ name } ! ` } ] } ) ) ; // Start receiving messages on stdin and sending messages on stdout const transport = new StdioServerTransport () ; await server . connect ( transport ) ; 具体的にコードを解説していきます。 new McpServer  でMCPサーバーのインスタンスを作成します。 import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";const server = new McpServer({ name: "demo-server", version: "1.0.0"}); import { McpServer , ResourceTemplate } from " @modelcontextprotocol/sdk/server/mcp.js " ; import { StdioServerTransport } from " @modelcontextprotocol/sdk/server/stdio.js " ; const server = new McpServer ( { name : " demo-server " , version : " 1.0.0 " } ) ; 次にツールを追加します。 inputSchemaで、zodで入力値を管理しています。 今回は、ただ足し算をするだけのツールを追加しています。 import { z } from "zod";// Add an addition toolserver.registerTool("add", { title: "Addition Tool", // ツールのタイトル description: "Add two numbers",// ツールの説明 inputSchema: { a: z.number(), b: z.number() } // 入力値 }, async ({ a, b }) => ({ content: [{ type: "text", text: String(a + b) }]// 実行関数: 2つの数値を受け取り、その合計を文字列として返す })); import { z } from " zod " ; // Add an addition tool server . registerTool ( " add " , { title : " Addition Tool " , // ツールのタイトル description : " Add two numbers " , // ツールの説明 inputSchema : { a : z . number () , b : z . number () }   // 入力値 }, async ({ a , b }) => ( { content : [ { type : " text " , text : String ( a + b ) } ] // 実行関数: 2つの数値を受け取り、その合計を文字列として返す } ) ) ; 先ほど追加したコード中で、次に、リソースへの登録をします。 これを登録すると、AIが  greeting://名前  みたいな感じで参照してくれるようになります。( リソースについて ) ※この後の動作確認では、リソースは検証せず、ツールのみ検証する方法記載しています。リソースとツールを 状況に応じて使い分けることをおすすめします。 // Add a dynamic greeting resourceserver.registerResource( "greeting", new ResourceTemplate("greeting://{name}", { list: undefined }), // リソースのURL { title: "Greeting Resource", // リソースのタイトル description: "Dynamic greeting generator" // リソースのディスクリプション }, async (uri, { name }) => ({ contents: [{ uri: uri.href, text: `Hello, ${name}!` }] })); // Add a dynamic greeting resource server . registerResource ( " greeting " , new ResourceTemplate ( " greeting://{name} " , { list : undefined } ) , // リソースのURL { title : " Greeting Resource " , // リソースのタイトル description : " Dynamic greeting generator " // リソースのディスクリプション }, async ( uri , { name }) => ( { contents : [ { uri : uri . href , text : ` Hello, ${ name } ! ` } ] } ) ) ; 最後にサーバーを実行する部分を書いたら完成です。 // Start receiving messages on stdin and sending messages on stdoutconst transport = new StdioServerTransport();await server.connect(transport); // Start receiving messages on stdin and sending messages on stdout const transport = new StdioServerTransport () ; await server . connect ( transport ) ; 動作確認までの準備 今回はツールまで実行してみようと思います。最初にビルドします。 npm run build build/index.js が生成されるはずなので、絶対パスをコピーしておきます。 そうすると、curosrの場合はこんな感じで設定しておきます。これで準備はOKです。 "my-mcp-server": { "command": "node", "args": ["${コピーした絶対パス}/build/index.js"] } " my-mcp-server " : { " command " : " node " , " args " : [ " ${コピーした絶対パス}/build/index.js " ] } cursorのツールの欄を確認すると、こんな感じで追加した、MCPが利用できるようになっているはずです。 こんな感じで、agentに投げると、mcpを叩いてくれるようになります。 最後に 今回は、MCPの構造を確認しながら、簡単なMCPを作ってみました...! 意外と簡単に作れたので、必要そうなツールは個人的に作っていこうと思います。 最後まで読んでいただきありがとうございました!
アバター
上記の動画では、 Figma Buzzを活用して「量産型バナー」を制作する方法 をご紹介しています。 「はじめての転職で何からはじめたらいいか分からない」というメッセージを軸に、テキストを差し替えた 50パターンのバナー を一括で生成しました。 テンプレートとスプレッドシートを連携させることで、効率的かつブランドに沿ったビジュアル制作が可能になります。 量産させたい基のバナーデザインがあれば、誰でも簡単に制作できるので、おすすめの手法です。 Figma Buzz 概要 Figma Buzzは、2025年のFigma Configで発表された、 非デザイナーでも手軽にブランドに沿ったビジュアルコンテンツを作成・管理・共有できる新機能 です。 特にマーケティングチーム向けに設計されており、効率的な制作を支援する多彩な機能が搭載されています。 現在はβ版ですが、誰でも無料で使用することができます。 主な機能 テンプレートベースの編集 ブランドガイドラインに沿ったテンプレートを活用し、誰でも簡単に編集・再利用可能。 テンプレートのロック機能 編集可能な部分だけを開放し、ブランドの一貫性を保ちながら安全にカスタマイズ。 AIによる画像生成 テキストプロンプトから画像を生成・編集できる機能を搭載。背景削除や色調補正も可能。 スプレッドシート連携による一括編集 CSVやExcelファイルを使って、複数のアセットを一括生成。SNS投稿や広告素材の大量制作に最適。 活用シーン Web・SNS向けの広告バナー イベント告知や社内報資料 誕生日カードや招待状などの個人向けコンテンツ Figma Buzzには様々な機能がありますが、今回は量産型バナーの制作方法について説明させていただきます。 量産型バナーの制作方法 ①マスターデザインの用意 まずは、Figma BuzzではなくFigma デザインで、量産したいバナーを作成します。 この段階で、今後一斉に変更する可能性がある要素(例:ボタンのテキストやカラーなど)がある場合は、この時にコンポーネント化( ⌥ + ⌘ + K )をしておいてください。これにより、後の修正や展開がスムーズになります。 ②Figma Buzzに移動 次に Figma Buzz を起動してください。 ホーム画面の上部には、各サービスのアイコンが並んでいるかと思いますので、そこから Figma Buzz を選択します。 Figma Buzzに移動すると、最初にテンプレート選択画面が表示されますが、こちらは画面右上の×で閉じることができます。 ③バナーをFigma デザインからFigma Buzzに移動 次にFigma デザインで作成したバナーを 切り取り でFigma Buzzに持ってきてください。 (コピーではコンポーネントが適用されないため) 2枚目のページ下部のナビゲーションをご覧いただくと分かるように、Figma Buzzでもデザインモードを使用することができます。 Figma デザインと比べると機能に制限はありますが、デザインの作成や編集は可能です。 なお、今回のバナーはFigma Buzzで直接作成することもできましたが、Buzzには コンポーネント機能が見当たらなかったため、まずはFigma デザインで作成する方法を選びました。 ④Excel形式のCSVファイルを用意 ここからは、バナーの量産作業に入ります。 まずは、テキストデータを管理するための CSVファイルをご用意ください。 CSVの構成は以下の通りです: ・1行目:任意のカテゴリ名(今回は「description」) ・2行目以降:実際にバナーに使用するテキストを記載 今回は「description」のみを使用しますが、例えば タイトルや画像もバナーに合わせて変更したい場合 は、列を追加することで、より柔軟な量産が可能です。 ⑤CSVファイルをアップロード データの作成が完了したら、Figma Buzzに戻ります。 1左側のナビゲーションメニューから 「 一括で作成 」 をクリックします(左下のグリッドアイコン)。 表示されたウィンドウで、先ほど作成した CSVファイルを選択し、「開く」を押してください。 データのインポートが完了すると、3枚目の画面のような一覧表示に切り替わるかと思います。 ⑥変更したいデータを選択 次に、バナーデザイン内で変更したい要素をクリックしてください。 今回は「はじめての転職で何からはじめたらいいか分からない」というテキストを編集したいので、まずはこのテキスト部分を選択します。 続いて、画面左側のパネルに表示されている 「description」 をクリックします。 これにより、バナー内のテキストとCSVファイル内の「description」列のデータが紐付けされます。 ⑦大量生成を実行 データの紐付けが完了すると、画面左側パネルの下部にある「〇〇件のアセットを作成する」というボタンが非アクティブからアクティブ状態に変わります。 このボタンをクリックすることで、CSVに登録されたデータをもとに、バナーが自動的に大量生成されます! 大量生成する前のデータの作成上の注意 テキストや画像の幅の設定について バナーを自動生成する際に、テキストの幅を設定していないと、改行されずに横に長く表示されてしまうことがあります。 そのため、マスターバナーを作成する段階で、テキストや画像の表示幅をあらかじめ設定しておくことが重要です。 一括変更をしたい箇所はコンポーネント化しておく バナーを大量に生成した後で、ボタンのテキストやタイトルなどを一括で変更したいというケースがあるかもしれません。 そのような場合に備えて、基のバナーの制作段階で、変更の可能性がある要素はコンポーネント化しておくことが重要です。 コンポーネント化しておくことで、マスターバナーを修正するだけで、生成済みのすべてのバナーにも自動的に変更が反映されます。 Figma Buzzを使ってみた感想 良かった点まとめ バナーの量産がとても効率的 CSVを使ってデータを流し込むことで、複数のバナーを一括で自動生成できるのは非常に便利でした。 手作業で1枚ずつ作成する必要がなくなり、作業時間と労力を大幅に削減できるかと思います。 先日参加したFigmaのイベント「Maker Collective Tokyo」でも、Figma Buzzを活用したバナーの一括生成が紹介されました。 そのデモでは、なんと 約2000枚のバナーをわずか数十秒で自動生成 しており、Figma Buzzの処理速度と実用性の高さに驚かされました。 Figmaらしい直感的な操作感 Figma デザインと同様のUIが採用されているため、初めて使った際も、迷わず操作できました。 データの紐付けが簡単 テキストや画像をCSVの列と紐付ける操作がとてもシンプルで、直感的に理解できました。紐付けが完了した後の自動生成もスムーズで、ストレスなく作業を進められました。 改善してほしい点 Buzzではコンポーネント機能が使えない? Figma デザインで作成したコンポーネントがBuzzでは編集できないようなので、量産したい基のバナーはデザイン側で行う必要があります。Buzz側でもコンポーネントが使えると、もっと便利になりそうです。 デザイン機能に一部制限あり Buzzのデザインモードは基本的な編集は可能ですが、Figma デザインほど自由度は高くない印象です。細かい調整は事前に済ませておくのがベスト。 Figma Buzzはまだβ版なので、上記については今後のアップデートに期待です!
アバター
GoでレイヤードアーキテクチャとDDD(ドメイン駆動設計)をどう実装しているかまとめます。 自分で考えて試している部分も多く、この構成でうまくいかない部分もあるかもしれません。その点ご認識ください。 レイヤードアーキテクチャについては下記が参考になります。 https://qiita.com/tono-maron/items/345c433b86f74d314c8d 例として部署情報(department)のCRUDについて書きます presentation層(interface) ├── presentation/│ ├── batch/│ │ └── job.go│ ├── external/│ │ └── client.go│ └── rest/│ ├── controller/│ │ ├── controllers.go│ │ ├── department.go│ │ └── router.go # openapi ルーティング定義 controllerとなっていますが、handlerでもいいと思います(この辺は好みです)。 controller実装例 package controllerimport ("main/application/usecase/department""main/presentation/rest/openapi""net/http""github.com/labstack/echo/v4")type DepartmentController interface {GetDepartment(c echo.Context) errorCreateDepartment(c echo.Context) errorUpdateDepartment(c echo.Context, departmentID int64) errorDeleteDepartment(c echo.Context, departmentID int64) error}type departmentController struct {departmentUseCase department.UseCase}func NewDepartmentController(departmentUseCase department.UseCase) DepartmentController {return &departmentController{departmentUseCase: departmentUseCase,}}func (ctrl *departmentController) GetDepartment(c echo.Context) error {ctx := c.Request().Context()departments, err := ctrl.departmentUseCase.GetAll(ctx)if err != nil {return echo.NewHTTPError(http.StatusInternalServerError, err.Error())}return c.JSON(http.StatusOK, departments)}func (ctrl *departmentController) CreateDepartment(c echo.Context) error {ctx := c.Request().Context()var req openapi.CreateDepartmentJSONRequestBodyif err := c.Bind(&req); err != nil {return echo.NewHTTPError(http.StatusBadRequest, "Invalid request body")}err := ctrl.departmentUseCase.Create(ctx, &req)if err != nil {return echo.NewHTTPError(http.StatusInternalServerError, err.Error())}msg := "Successfully created department"res := openapi.The200s{Code: http.StatusCreated,Message: &msg,}return c.JSON(http.StatusCreated, res)} APIの department/ に関するものはこのcontrollerにまとめています。 業務ロジックが大きい場合はAPI単位でcontrollerを分けてもいいと思います。 package名は集約または集約ルートごとに切る予定です。 DTOを使う場合はusecaseに渡す前に変換ロジックをここに書いてもいいですが、今回はopenapiで自動生成された型とDTOがほぼ同じだったのでopenapiの型をそのまま使っています。 ただし、usecase層がopenapi型に依存することになるので、DTOを設けてopenapi→DTOの変換を入れるのがベストです。 DDDは完璧にやりすぎると時間がかかるので、適宜調整が必要です あとエラーメッセージは後々まとめます application層 ├── application/│ ├── service/│ │ └── common.go│ └── usecase/│ └── department/│ ├── mapper.go # ドメインオブジェクト⇔DTOマッピング│ └── department.go 前のプロジェクトで、dto<->entityの変換ロジックを一ファイルにまとめると肥大化して分かりにくくなったため、マッピング用のファイルを設けています。 func ConvertCreateReqToEntity(req *openapi.CreateDepartmentJSONRequestBody) (*department.DepartmentEntity, error) {name, err := stringx.RemoveEmptySpaces(req.Name)if err != nil {return nil, err}return &department.DepartmentEntity{Name: name,}, nil} usecase実装例 package departmentimport ("context""main/domain/department""main/presentation/rest/openapi")type UseCase interface {GetAll(ctx context.Context) ([]*openapi.Department, error)Create(ctx context.Context, req *openapi.CreateDepartmentJSONRequestBody) errorUpdate(ctx context.Context, id int64, req *openapi.UpdateDepartmentJSONRequestBody) errorDelete(ctx context.Context, id int64) error}type useCase struct {departmentRepository department.Repository}func NewUseCase(departmentRepository department.Repository) UseCase {return &useCase{departmentRepository: departmentRepository,}}func (u *useCase) GetAll(ctx context.Context) ([]*openapi.Department, error) {entities, err := u.departmentRepository.GetAll(ctx)if err != nil {return nil, err}res := ConvertEntitiesToResponses(entities)return res, nil}func (u *useCase) Create(ctx context.Context, req *openapi.CreateDepartmentJSONRequestBody) error {entity, err := ConvertCreateReqToEntity(req)if err != nil {return err}err = u.departmentRepository.Create(ctx, entity)if err != nil {return err}return nil} CRUD処理は単一ファイルにまとめています。要件的に業務ロジックが少ないため肥大化しないと判断したため。 肥大化、大規模開発になる場合はCRUDごとにusecaseを分けるやり方もあります( 参考 )。 ですがこちらは作業量も増えるのでプロジェクトの要件や割けるリソースによると思います 今回はinterfaceを設けて単一ファイルにまとめています。 usecaseにはドメインロジックを書かないようにしています。 domain層 ├── domain/│ ├── department/│ │ ├── valueobject/│ │ ├── entity.go│ │ └── repository.go│ └── shared/│ ├── errors/│ │ └── domain_errors.go│ └── valueobject/│ ├── address.go│ └── money.go entity, valueobject, repositoryを集約ごとに配置。 複数集約にまたがるvalueobjectはshared配下に置いています。 repository interface package departmentimport ("context")type Repository interface {GetAll(ctx context.Context) ([]*DepartmentEntity, error)Create(ctx context.Context, entity *DepartmentEntity) errorUpdate(ctx context.Context, entity *DepartmentEntity) errorDelete(ctx context.Context, id int64) error} 基本的なCRUDはrepositoryのinterfaceとしてまとめています。 複数集約にまたがる検索等はCQRSを導入してquery serviceとしてまとめると保守性が高まります。 valueobject例 package valueobjectimport "fmt"type CategoryType uint8const (CategoryTypeUnknown CategoryType = 0 // 未分類 CategoryTypeA CategoryType = 1 // 種別A CategoryTypeB CategoryType = 2 // 種別B )func NewCategoryType(value int) (CategoryType, error) {categoryType := CategoryType(value)if !categoryType.IsValid() {return 0, fmt.Errorf("invalid CategoryType value: %d, must be between %d and %d", value, CategoryTypeUnknown, CategoryTypeB)}return categoryType, nil}func (t CategoryType) String() string {switch t {case CategoryTypeUnknown:return "Unknown"case CategoryTypeA:return "TypeA"case CategoryTypeB:return "TypeB"default:return "Unknown"}}func (t CategoryType) IsValid() bool {return t >= CategoryTypeUnknown && t <= CategoryTypeB} valueobject作成時にisvalidでバリデーションを強制しています。valueobject固有のロジックはここにおきます 例を挙げるなら文字数制限など valueobjectは複数あるのでフォルダを切りました。 複数集約にまたがる場合はdomain serviceにまとめるのが良いと思います。 entity例 package departmentimport ("time")type DepartmentEntity struct {ID int64 `json:"id,omitempty"`Name string `json:"name"`CreatedAt time.Time `json:"created_at"`UpdatedAt time.Time `json:"updated_at"`} DB駆動設計にならないよう、ドメインモデリングとテーブル設計は一致させないようにしています。 https://speakerdeck.com/pospome/liang-ikodonoding-yi-toshe-ji-neng-li-nobi テーブルはデータ保持のため、entityはコード上で使いやすいように最適化されるため、DBモデルとドメインモデルは分けて考えるべきです 例えば営業側から見た部署と管理者側から見た部署情報は違うため、entityを分けることも検討します こちらもわかりやすいと思います https://qiita.com/MinoDriven/items/2a378a09638e234d8614 entity固有のドメインロジックはこちらに書き足していきます infrastructure層 ├── infrastructure/│ ├── mysql/│ │ ├── conf/│ │ ├── db/│ │ ├── initdata/│ │ ├── migrations/│ │ └── department/│ │ ├── mapper.go # ドメインオブジェクト⇔ORMモデル変換│ │ └── repository.go ここにもmapperを用意し、ドメインオブジェクト⇔ORMモデルの変換関数をまとめています。 func ConvertModelToEntity(model *models.Department) *department.DepartmentEntity {if model == nil {return nil}return &department.DepartmentEntity{ID: int64(model.ID),Name: model.Name,CreatedAt: model.CreatedAt,UpdatedAt: model.UpdatedAt,}} repository (実体)実装 package departmentimport ("context""main/domain/department""main/infrastructure/models""gorm.io/gorm")type repository struct {db *gorm.DB}func NewRepository(db *gorm.DB) department.Repository {return &repository{db: db}}func (r *repository) GetAll(ctx context.Context) ([]*department.DepartmentEntity, error) {var models []*models.Departmentif err := r.db.WithContext(ctx).Find(&models).Error; err != nil {return nil, err}return ConvertModelsToEntities(models), nil} 依存性注入 package diimport ("main/application/usecase/department"departmentInfra "main/infrastructure/mysql/department""main/presentation/rest/controller""gorm.io/gorm")func Department(db *gorm.DB) controller.DepartmentController {departmentRepository := departmentInfra.NewRepository(db)departmentUsecase := department.NewUseCase(departmentRepository)return controller.NewDepartmentController(departmentUsecase)} 依存性注入を行うことにより各レイヤーが分離され単体テスト等がやりやすくなります wireを導入して自動でやるのもおすすめです CQRSやQuery Serviceについて 複数集約にまたがる検索や参照系の処理は、CQRSパターンを取り入れてQuery Serviceとして切り出すと保守性が高まります。 例えば「部署+ユーザー情報をまとめて取得し検索する」など、集約横断的な参照はdomain層のrepositoryではなく、application層のquery serviceで実装する方針です。 これにより、ドメインモデルの純粋性を保ちつつ、柔軟な参照要件にも対応できます。 最終的なディレクトリ構成例 backend/├── application/│ ├── service/│ └── usecase/│ └── department/│ ├── mapper.go│ └── department.go├── cmd/│ └── api/│ └── main.go├── configs/├── di/│ └── department.go├── domain/│ ├── department/│ │ ├── valueobject/│ │ ├── entity.go│ │ └── repository.go│ └── shared/│ ├── errors/│ └── valueobject/├── infrastructure/│ ├── models/│ ├── mysql/│ │ └── department/│ │ ├── mapper.go│ │ └── repository.go├── presentation/│ ├── batch/│ ├── external/│ └── rest/│ ├── controller/│ │ ├── controllers.go│ │ ├── department.go│ │ └── router.go│ └── openapi/ まとめ 業務ロジックやプロジェクト規模に応じて、controllerやusecaseの粒度を調整しています。 DTOやCQRS、Query Serviceの導入は、依存関係や保守性を考慮して適宜検討しています。 ドメインモデルとDBテーブル設計は一致させず、それぞれの役割に最適化するよう意識しています。 DDDは難しく、まだわからないことも多いです この構成は実際に試行錯誤しながら作ったもので、今後も改善していく予定です。 何かあればコメントの方よろしくお願いします 今すぐ「レイヤードアーキテクチャ+DDD」を理解しよう。(golang) - Qiita 役割駆動設計で巨大クラスを爆殺する - Qiita DDDはなぜ難しいのか / 良いコードの定義と設計能力の壁
アバター
はじめに マイナビジョブサーチのフロントエンド開発において、コードの可読性・保守性向上を目的としたリファクタリングを実施しました。本記事では、実際に行ったリファクタリング内容とその背景についてまとめています。 コンテナ・プレゼンテーションパターンを採用 これまでのコンポーネントは、UIとビジネスロジックが1つのコンポーネントに混在しており、1つのファイルのソースコード量が膨大であり可読性が悪かったです。その他にも、UIとビジネスロジックが同じファイルにあったため、UIとビジネスロジックをそれぞれ単体でテストすることが難しかったです。 そこで、メンテナンス性や拡張性を向上させるために、コンテナ・プレゼンテーションパターンを導入し、UIとビジネスロジックを明確に分離しました。 UI部分 Reactのコンポーネントで実装 ビジネスロジック部分 Reactのhooksや純粋関数で実装 /** Before */ export const Component = () => { const useHooks1 = () => { // } const useHooks2 = () => { // } const logic = () => { // } return ( <div> <h1>Component</h1> <p>Some content here...</p> <p>{ logic() }</p> </div> )}⬇️⬇️⬇️ /** After */ import { useHooks } from "./hooks/useHooks"import { logic } from "./services/someLogic"export const Component = () => {const { ... } = useHooks() return ( <div> <h1>Component</h1> <p>Some content here...</p> <p>{ logic() }</p> </div> )} このアプローチにより、1つのファイルあたりのコード量が減少し、可読性が高まりました。また、UIとビジネスロジックが明確に分離されたことで、各部分を独立してテストすることが容易になりました。 ディレクトリ構成の見直し ディレクトリ構成の見直しにより、各ディレクトリのルールが明確になり、ファイルの配置が整理されました。また、命名規則も統一することで、プロジェクト全体の可読性と一貫性を持たせるようにしました。 src/styles Before stylesディレクトリにグローバルで利用するスタイルのファイル(reset, variable, ...)と、一部コンポーネントのみでしか利用されないスタイルのファイルが混在していた After グローバルで利用するスタイルのファイルのみをこのディレクトリに置く 一部コンポーネントのみでしか利用されていなかったスタイルのファイルは、利用するコンポーネントフォルダに移動 /** Before */styles/ ├─ ComponentA ├─ ComponentB ├─ PageA ├─ PageB ├─ _variables.module.scss ├─ reset.scss ├─ ...⬇️⬇️⬇️/** After */styles/ ├─ _variables.module.scss ├─ reset.scss ├─ ... src/components Before 特定のファイルでしか利用されないコンポーネント、共通コンポーネント(ボタン、モーダルなど)として色々なファイルで使われるコンポーネントが混在していた After 共通コンポーネント(ボタン、モーダルなど)として色々なファイルで使われるコンポーネントのみをこのディレクトリに置く /** Before */components/ ├─ Button/ ├─ Modal/ ├─ Recruit/ ├─ JobDetail/ ⬇️⬇️⬇️/** After */components/ ├─ Button/ ├─ Modal/ src/features 今回のリファクタリングで新しく作成したディレクトリであり、Reactのアーキテクチャの1つである Bulletproof-react を参考にして取り入れました。 特定のファイルでしか利用されないコンポーネントをこのディレクトリに置くことで、共通コンポーネントと特定のファイルでしか使われないコンポーネントの棲み分けをした 機能(LayoutTop, JobDetail)フォルダ内に関連するコンポーネントを作成し、機能単位で管理する features/ ├─ LayoutTop/ ├─ Navigation/ ├─ index.tsx ├─ Navigation2/ ├─ index.tsx ├─ ... ├─ JobDetail/ ├─ JobDetail1/ ├─ index.tsx ├─ JobDetail2/ ├─ index.tsx ├─ ... src/apps 今回のリファクタリングで新しく作成したディレクトリ Before Pages Routerのpagesディレクトリにはtsxファイル(jsxファイル)以外は置けないため、スタイルのファイルやビジネスロジックのファイルが色々なディレクトリに置かれていた After src/appsディレクトリのコンポーネントはプレゼンテーションコンポーネントとして利用し、pagesディレクトリのファイルはコンテナコンポーネントとしてデータをpropsを通じて渡す pagesディレクトリに置けなかったスタイルのファイルやビジネスロジックのファイルを、コンポーネントとして必要なファイルをまとめて配置 /** Before */pages/ ├─ search.tsx styles/ ├─ search.modules.scss hooks/ ├─ useSearchHooks.ts⬇️⬇️⬇️/** After */apps/ ├─ Search/ ├─ hooks/ └─ ** ├─ services/ └─ ** ├─ index.tsx ├─ styles.modules.scsspages/ ├─ search.tsx // pages/search.tsx import { Search } from "apps/Search"const Page: NextPage<Props> = ({ props1, props2, props3}) => { return ( <Search props1={props1} props2={props2} props3={props3} /> );};export default Page; コンポーネントディレクトリの構成 コンポーネントのディレクトリ構成やファイルの命名がコンポーネントによってバラバラだったため、ファイルの配置や命名規則を統一しました。 Before 特定のコンポーネントのみでしか利用されない スタイルのファイルやビジネスロジックのファイルがコンポーネントディレクトリとは別ディレクトリに散らばっていた コンポーネントのフォルダに入っていたり入っていなかったりとバラバラ コンポーネントのファイル名とスタイルのファイル名がコンポーネント名になっていた After - コンポーネントフォルダをキャメルケースで命名し、その中にファイルを格納 - コンポーネントのファイル名を「index.tsx」、スタイルのファイル名を「styles.modules.scss」に統一 - UIとビジネスロジックを分離したため、ビジネスロジックを置くフォルダを新しく作成 - カスタムフックは「hooks」フォルダに置く - 純粋関数は「services」フォルダに置く /** Before */styles/ ├─ ComponentA.modules.scss components/ ├─ ComponentA.tsx ├─ ComponentB/ ├─ ComponentB.tsx └─ ComponentB.modules.scss⬇️⬇️⬇️/** After */components/ ├─ ComponentA/ ├─ hooks/ └─ ** ├─ services/ └─ ** ├─ index.tsx └─ styles.modules.scss ├─ ComponentB/ ├─ index.tsx └─ styles.modules.scss コンポーネントファイル(index.tsx)のルール コンポーネントの型指定 コンポーネントのPropsの型指定は、React.FCを使用し、Propsの名前を利用する場合はコンポーネント内でのみ使用する コンポーネントを定義する際はReact.FCを使用し、React.VFCは使用しないこと Propsの取得方法 Propsは分割代入を用いて取得する const Component: React.FC<Props> = ({ prop1, prop2, prop3 }) => { // } コンポーネントのエクスポート方法 コンポーネントのエクスポートは、default exportではなく、named exportを使用する export const Component: React.FC<Props> = ({ prop1, prop2, prop3 }) => { // } コードまとめ 以下は、上記のルールに従ったコンポーネントの例 export const Component: React.FC<Props> = ({ prop1, prop2, prop3 }) => { return ( <div> <p>{prop1}</p> <p>{prop2}</p> <p>{prop3 ? 'True' : 'False'}</p> </div> );} コンポーネントのビジネスロジックディレクトリ(hooks, services)の構成 ビジネスロジックディレクトリ(hooks, services)は、今回のリファクタリングで新しく作成したビジネスロジックを管理するためのディレクトリです。このディレクトリでは、ビジネスロジックを整理し、再利用性を高めることを目的としています。 hooksディレクトリ このディレクトリは、カスタムフックを管理する useHooks.tsとuse**.tsの分割 useHooks.ts 複数のカスタムフック(use**.ts)のビジネスロジックをまとめて管理し、将来的にビジネスロジックが増えることを考慮し、拡張性を持たせている インポートしたカスタムフックは、スプレッド構文を用いて返すことで、各フックのプロパティを一つのオブジェクトとしてまとめて利用している import { use**1 } from "./hooks/use**1"import { use**2 } from "./hooks/use**2"export const useHooks = (({param1, param2, param3}: Params or **Params)) => { return { ...use**1(), ...use**2(), };}; use**.ts use**.ts各カスタムフックは、ビジネスロジックが干渉しないもの同士で切り分けることによって、関連しているビジネスロジックが明確になる export const use** = (({param1, param2, param3}: Params or **Params)) => { // }; 引数の型指定 引数の型指定を行う際には、Propsという名前を避け、Paramsや**Paramsなどの名前を使用する // useHooks.ts export const useHooks = (({param1, param2, param3}: Params or **Params)) => {} // use*.ts export const use** = (({param1, param2, param3}: Params or **Params)) => {} 利用方法 useHooks.tsを、コンポーネントやページでインポートして利用する ├─ Component/ ├─ hooks/ └─ useLoading.ts └─ useRelaod.ts └─ useCalc.ts └─ useHooks.ts ├─ index.tsx import { useHooks } from "./hooks/useHooks"export const Component = () => { const { ..., ..., ...} = useHooks() return ( // // // )} useHooks.tsとuse**.tsに分割することで、各ファイルのコード量を削減できるだけでなく、ファイルごとにビジネスロジックが明確になるため、可読性と保守性が向上するようになりました。 servicesディレクトリ このディレクトリは、Reactの機能を利用しない純粋関数のビジネスロジックを管理する 利用方法 servicesディレクトリに作成した純粋関数のビジネスロジックをコンポーネントやページでインポートして利用する。 hooksディレクトリとは違い、1つのビジネスロジックのファイルにまとめて管理はしない ├─ Component/ ├─ services/ └─ calcUtils.ts ├─ index.tsx import { CalcUtils } from "./services/calcUtils.ts"export const Component = () => { return ( // // )} カスタムフックと純粋関数のビジネスロジックを分けることで、再利用性、テストの容易さ、依存関係が管理しやすくなりました。 まとめ 本記事では、マイナビジョブサーチのフロントエンド開発におけるリファクタリングの取り組みについて紹介しました。主なポイントは以下の通りです。 UIとビジネスロジックの分離 UIとビジネスロジックを1つのファイルから分離することで、コードの可読性が向上しました。これにより、各部分の役割が明確になり、理解しやすくなりました。 ビジネスロジックはカスタムフックや純粋関数として管理され、UI部分はReactコンポーネントとして実装されることで、各部分のテストが容易になりました。 コンテナ・プレゼンテーションパターンの導入 コンテナ・プレゼンテーションパターンを採用することで、UIとビジネスロジックを明確に分離し、メンテナンス性や拡張性を向上させました。このアプローチにより、コードの構造が整理され、各コンポーネントの役割が明確になりました。 ディレクトリ構成の見直し ディレクトリ構成を見直し、ファイルの配置や命名規則を統一することで、プロジェクト全体の可読性と一貫性が向上しました。特に、共通コンポーネントと特定のファイルでしか使われないコンポーネントの棲み分けができたことで、管理が容易になりました。 再利用性とテストの容易さ カスタムフックと純粋関数のビジネスロジックを分けることで、再利用性が高まり、テストの容易さが向上しました。特に、純粋関数は副作用がないため、単体テストが簡単に行えるようになりました。 管理の効率化 バラバラに置かれていたファイルをコンポーネントとしてまとめて配置できるようになり、開発者が必要なファイルを見つけやすくなりました。 このリファクタリングを通じて、コードの可読性、保守性、テストのしやすさが向上しました。 もし参考になる内容がございましたら、ぜひご活用いただければと思います。
アバター
Q Developer 会話履歴継続を完全自動化 「また -r オプション忘れた...」 と思った経験ありませんか? 組織のSSO設定で認証情報が永続化できない環境では、毎回ログインが必要な上に、会話履歴の継続も忘れがちです。 そこで、チャットやログインの処理を expect で自動化、 qq コマンドを作成してみました。 •  -r  オプションを自動で付与、 会話履歴の継続忘れを防止 • ログイン時の エンター連打も完全自動化 • デバイス認証URLを 自動でブラウザオープン ※Ubuntuでのインストールが前提です。 ※組織固有のパラメータは <HOGEHOGE>  でマスクしています。 #!/bin/bash# =============================================================================# Q Developer CLI 自動セットアップスクリプト# # 目的: Q Developer CLIのログインとチャット起動を完全自動化# 課題: 組織の制約により認証情報の永続化が不可能なため、毎回ログインが必要# 解決: expectコマンドによる対話自動化とブラウザ自動オープン## 使用方法:# 1. このスクリプトを任意のディレクトリに配置# 2. 実行権限を付与: chmod +x qq# 3. PATHに追加してどこからでも実行可能にする:# echo 'export PATH="$PATH:/path/to/script/directory"' >> ~/.bashrc# source ~/.bashrc# 4. qqコマンドで実行# =============================================================================echo "🚀 Q Developer セットアップ中..."echo "📋 スクリプトバージョン: v5.3-dependency-check ($(date '+%Y-%m-%d %H:%M:%S'))"# 依存関係チェックecho "🔍 依存関係を確認中..."missing_commands=()# Amazon Q Developer CLI の確認if ! command -v q >/dev/null 2>&1; then missing_commands+=("Amazon Q Developer CLI (q)")fi# expect コマンドの確認if ! command -v expect >/dev/null 2>&1; then missing_commands+=("expect")fi# xdg-open コマンドの確認if ! command -v xdg-open >/dev/null 2>&1; then missing_commands+=("xdg-utils")fi# 不足しているコマンドがある場合は警告して終了if [ ${#missing_commands[@]} -gt 0 ]; then echo "❌ 以下のコマンドがインストールされていません:" for cmd in "${missing_commands[@]}"; do echo " - $cmd" done echo "" echo "📦 以下の方法でインストールしてください:" echo "" for cmd in "${missing_commands[@]}"; do case $cmd in "Amazon Q Developer CLI (q)") echo "• Amazon Q Developer CLI (q):" echo " 公式サイトでインストール方法を確認してください" echo " https://docs.aws.amazon.com/amazonq/latest/qdeveloper-ug/command-line-installing.html" echo "" ;; "expect") echo "• expect:" echo " sudo apt install expect" echo "" ;; "xdg-utils") echo "• xdg-utils:" echo " sudo apt install xdg-utils" echo "" ;; esac done echo "インストール完了後、再度このスクリプトを実行してください。" exit 1fiecho "✅ 依存関係チェック完了"# エディタ設定# Q Developer CLIがファイル編集時に使用するエディタを指定# VS Codeの--waitオプションでCLIがエディタ終了まで待機するためexport EDITOR="code --wait"echo "✅ エディタ設定完了: $EDITOR"# ログイン状態を確認# 既にログイン済みの場合は不要な処理をスキップして効率化echo "🔍 ログイン状態を確認中..."if q whoami >/dev/null 2>&1; then echo "✅ 既にログイン済みです"else echo "🔑 ログインが必要です。Proライセンスでログインします..." # expectを使用して自動ログイン(最長URL選択でブラウザ自動オープン) # Q Developer CLIのログインは対話型で手動エンター入力が必要 # 組織制約により認証の永続化ができないため、毎回の自動化が必須 expect -c " # タイムアウト設定 # ネットワーク遅延やブラウザ認証待ちを考慮した十分な時間を確保 set timeout 120 # URL重複オープン防止フラグ # 複数のURLが出力されるため、デバイス認証URLを1回のみ開くため set url_opened 0 # Q loginコマンドを起動 spawn q login --license pro --identity-provider https://<HOGEHOGE>.awsapps.com/start --region ap-northeast-1 --use-device-flow expect { # エンター入力待ちパターンの自動処理 # ログイン過程で複数回のエンター入力確認があるため \"Press Enter\" { send \"\r\" exp_continue } \"continue\" { send \"\r\" exp_continue } \"Enter\" { send \"\r\" exp_continue } # URL検出とブラウザ自動オープン # デバイス認証URLを手動でコピペする手間を省くため -re \"(https://\\\\S*)\" { # 重複防止チェック # 複数のURL(ベースURLと完全なデバイスURL)が出力されるため if {\$url_opened == 0} { set current_url \$expect_out(1,string) # 最長かつデバイス認証URLのみを対象とする条件判定 # 不完全なベースURLではなく、完全なデバイス認証URLのみを開くため # URL形式の変化に対応するため、複数の判定条件を設定 if {[string length \$current_url] > 50 && ([string match \"*device*\" \$current_url] || [string match \"*user_code*\" \$current_url] || [string match \"*#/*\" \$current_url])} { puts \"🌐 ブラウザでURLを自動オープン: \$current_url\" # バックグラウンドでブラウザ起動 # ブラウザ起動でスクリプトがブロックされないようにするため exec xdg-open \$current_url & # フラグを立てて以降のURL処理をスキップ # 同じURLや他のURLの重複オープンを防ぐため set url_opened 1 } } exp_continue } # 正常終了処理 eof { puts \"ログイン処理が完了しました\" } # タイムアウト処理 # ネットワーク問題や認証遅延時の無限待機を防ぐため timeout { puts \"タイムアウトしました\" exit 1 } } " # ログイン成功確認 # expectスクリプトが正常終了してもログインが失敗している可能性があるため if q whoami >/dev/null 2>&1; then echo "✅ ログイン完了" else echo "❌ ログインに失敗しました" exit 1 fifi# Q Chat を再開モードで起動# 前回の会話履歴を継続して効率的な対話を実現するため# Claude 4 Sonnetモデルを明示的に指定して一貫した応答品質を確保するためecho "✅ Q Chat をClade4で起動します..."q chat -r --model claude-4-sonnet ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ もう「あ、また-rオプション忘れた」「エンター何回押すんだっけ」と悩む必要はありません。 qqと打つだけで、すべてが自動で完了します。 小さな自動化が、毎日の開発体験を大きく変えてくれるはずです。
アバター
「こんな機能があったなんて...」 Amazon Q Developerを使い始めて数週間。基本的な質問応答は慣れたけど、実はドキュメントに載っている便利な機能を見落としていませんか? 「もっと早く知っていれば、あの無駄な時間は何だったんだ...」 そんな後悔をしないために、便利機能を厳選してご紹介します。 /editor  : 複数行入力の救世主 /editor 効果: vim/VSCodeのエディタが起動! • マウス操作対応: クリックで自由にカーソル移動 • 複数行安心入力: 誤送信の心配なし • 快適な編集: コピペ、選択、削除が思いのまま • エディタ選択可能: 自分の好みに合わせてエディタを設定できます ( export EDITOR="code --wait" でVSCodeが利用可能) chat -r  : 昨日の続きから即座に再開 こんな経験ありませんか? •  昨日の作業の続きをしたい のに、前回の会話を忘れている • SSOの 認証が切れて突然ログアウト 、会話が消えた... • 引継ぎ用のメモを作るのが面倒 便利なオプション q chat -r 効果: 前回の会話の続きから作業開始!引継ぎファイル不要! 注意点: 会話履歴は 実行ディレクトリごと に保存されます。常に同じ場所でq chatを実行する習慣をつけましょう。 /compact  : 推論能力をリフレッシュ 「なんか最近、AIの回答が微妙...」 長時間の会話で推論能力が下がってきた?そんな時は: /compact さらに、要約方法も指定可能: /compact summary /compact key-points /compact action-items 効果: 会話をスッキリ整理して、AIの思考をリセット! /model  : 一瞬でAI性能アップ 旧モデル: Claude 3.7 高性能版: Claude 4.0 /model /context  : ファイルを明示的にコンテキスト追加 通常: ファイルの内容を毎回コピペ スマート:  /context で一発追加 /context add path/to/important-file.py メリット: • 大きなファイルも楽々参照 •  フォルダ単位での一括追加 も可能 • 複数ファイルの関連性を理解 • コピペミスを防止 !{command}  : ターミナル不要の魔法 チャット内の機能です。 従来: ちょっとコマンドを実行したい時 → ターミナルを開く 新しい方法: !ls -la !git status !npm install 効果: ちょっとしたコマンド実行のためにターミナルを開く手間が不要!チャット内で完結! まとめ /editor  → 長文入力が劇的に快適に chat -r  → 明日から継続作業が楽に /compact  → 長時間作業時の救世主 /model  → 即座に性能アップを体感 /context  → 大規模開発での必須機能 !{command}  → 作業効率の劇的改善 「知らないともったいない」機能たち これらの機能を活用しているかどうかで、開発効率に 大きな差 が生まれます。 今日から使い始めて、開発をもっと快適にしましょう! 「もっと早く知りたかった...」を「知っててよかった!」に変える、Amazon Q Developer活用術でした。
アバター
弊社では、2024年10月からGitHub Copilotの導入を行いました。 本記事では、導入までの過程とその過程で調査した内容についてお伝えしたいと思います。 本記事でわかること 導入までにした作業内容 GitHub Copilot導入検討段階で何を調査したのか 導入までにした作業内容 まず、導入までのどのような流れで、作業を行っていたのかについて説明します。 主に以下の手順で進めました。 検証メンバーの招集 検証を実施し、導入可否を決定 運用に関するフロー作成とステークホルダーの洗い出し 費用に関わる請求先の整理 1.検証メンバーの招集 課長から課員に対して、検証プロジェクトについてお伝えしていただいて、そこで興味のある方をアサインしました。 2.検証を実施し、導入可否を決定 リスク調査から始め、GitHub Copilotを有効化して使用してもらい、感想や作業削減時間等を記録していただきました。その調査結果をもとに費用対効果をまとめて、導入可否を上司に報告する流れを取りました。 3.運用に関するフロー作成とステークホルダーの洗い出し 導入後は、利用申請フローの確立やCopilotのシート有効化フローについて手順を整理しました。 社内の決裁ツールでの利用管理方法を考え、決裁フローを作成し、これらの各フローを誰が担当するのかも整理しました。 4.費用に関わる請求先の整理 弊社の事情により、請求先を細かく設定したいという要求がありました。これについては、「 コストセンター 」を用いることで、GitHub Copilotの費用に関して、特定の請求先に紐づけるようにしました。 以上の内容が大まかに行った作業になります。 「2.検証を実施し、導入可否を決定」の作業は、どこの会社でも行われることだと思います。 ですので、次章ではその調べた内容について、記載します。 導入する際の課題 導入する前に検討する事項として、「リスク」と「費用対効果」があると思います。 リスクには、生成AIの問題点である著作権侵害やそれによる訴訟リスクなどがあります。 効果については、生成AIの導入費用が削減効果を上回っているかを判断します。 リスク 生成AIにはリスクがあり、導入する際には調べる必要がある項目があります。 弊社では、以下の5つの項目を調査しました。 著作権侵害 情報流出 脆弱性コード生成 海外保管 訴訟補償 調査の結果から、GitHub Copilot上の設定を適切に行えば、これらのリスクは避けられると考えております。 1.著作権侵害 著作権侵害は、「Suggestions matching public code (duplication detection filter)」を有効化することにより、生成を防ぐことができると考えております。 Public Code Suggestion Filterは、公開リポジトリに含まれるコードが生成された場合に補完や提案結果から排除してくれる機能です。 この機能が有効化されていれば、著作権侵害のリスクは低いと判断しました。 なお、この機能については、企業向けのプランであるCopilot BusinessとCopilot Enterpriseではデフォルトで有効化されています。 2.情報流出 情報流出は、GitHub公式ページにて「Copilot Business」と「Copilot Enterprise」プランではデータを学習に利用しないことが明記されていました。 3.脆弱性コード生成 脆弱性コード生成は、GitHub Copilotにフィルターが存在し生成されないようになっているようです。 こちらのページ に、「安全でないコードパターンをリアルタイムで防止するAIベースの脆弱性フィルタリングシステムが組み込まれている」と記載されていました。 4.海外保管 海外保管は、社内のセキュリティ部署に問い合わせた結果、社内の規定に則っていることを確認し問題ないと判断いたしました。導入する際には、貴社の規定を確認いただけますと幸いです。 5.訴訟補償 訴訟補償は、訴訟補償の対象となる条件として「Suggestions matching public code (duplication detection filter)」を有効化していることが条件でした。 Microsoft社に問い合わせを行い確認し、これらの条件を満たせば、訴訟補償の対象になるとのことです。(2024年8月:問い合わせ) 以上の調査結果から、リスクについては適切な設定を行えば避けられるとの結論に至りました。しかし、リスクについて避けられたとしても、ツールとして導入するためには、費用対効果が得られないものは導入できません。 次の節では、費用対効果を求めた過程についてお伝えします。 費用対効果 導入するためには、費用対効果を考慮する必要があります。導入にはお金がかかりますが、それを上回る効果があれば良いと考えられます。 弊社では、予測作業時間から実際にどの程度削減できたのかを記録しました。また、削減時間から削減コストを計算し、費用対効果があるのかを判断しました。 削減時間の記録は、以下の項目を調査者に記録していただきました。 プロジェクト名 作業内容:新規コード作成・テストコード作成・コードリーディング・設計の中から選択 使用言語 Copilotの機能で何を用いたか:コード補完・Copilot Chat等 作業時間 作業削減時間:特定作業において、予測した作業時間からどの程度削減できたのかを記載 以上の項目を1ヶ月間取得し、一人当たり2.2時間/月のコスト削減が見込める結果となりました。 具体的な記録内容については表に記載しております。 比較的定型な記述の多い、テストコード作成にて大きな効果を得られました。 作業内容 作業時間(分) 削減時間(分) 削減割合 新規コード作成 3,480 507 14.6% テストコード作成 1,385 282 20.4% コードリーディング 180 20 11.1% 設計 160 44 27.5% 以上の結果をもとに費用対効果を算出しました。 費用対効果を算出する方法としては、 他社さんの記事 を参考にさせていただきました。 具体的に算出した値については、以下の表に示した通りです。 算出項目 算出値 時給(仮定) 3,000円 削減コスト/人 2.2h × 3,000円 = 6,600円 統括部全体の削減コスト 6,600 × 92 = 607,200円 Copilot導入費用 270,940円 費用対効果 607,200 - 270,940 = 336,260円 削減効果としては、毎月30万円程度の削減が見込める結果となり、導入に至りました。 まとめ 本記事では、導入する際に調査を行った内容についてまとめました。 導入プロセスは、検証メンバーの招集から始まり、リスク調査を経て導入可否を判断。 その後、運用フローの作成や費用請求先の整理を行う流れとなりました。 リスク調査では、著作権侵害や情報流出、脆弱性コード生成などのリスクを評価し、適切な設定でこれらを回避できると結論づけています。 費用対効果の検討では、作業時間の削減を記録し、月あたり一人当たり2.2時間のコスト削減を確認されました。 結果として、毎月約30万円の削減効果が見込めることから、GitHub Copilotの導入を決定するに至りました。 最後に 最後までお読みいただき、ありがとうございます。 最後に私自身がこのプロジェクトを通して学んだことを記載します。 このプロジェクトでは、初めてリーダーとしての役割を担いました。 普段のエンジニアとしての経験とは異なる多くの貴重な学びがありました。 手順が未確定な状況で、自ら調査し手順を策定し、他のメンバーに指示する難しさ 調査結果を整理し、上層部への報告を行うこと 社外の方々に疑問を問い合わせたり、会議を設定し議論を進めること この経験を通じて、「物怖じせずに積極的に行動することの重要性」を学びました。 以前は、自分の意見を発言することが少なかったのですが、リーダーとしての役割を果たす中で、何か行動することに対する不安が軽減されました。この経験は、他のプロジェクトにも良い影響を与えていると感じています。 具体的には、ステークホルダーへの提案回数の増加や、アジャイルや技術について学んだことをチームと共有し、PMに意見を求める機会を自ら設けるようになりました。 このプロジェクトを通じて得た経験は、今後の成長に繋がる貴重な財産だと感じております。 今後もこの経験を糧に、さらなる成長を目指して邁進していきます。
アバター
こんにちは。UXデザイン1課のAです。 先日、Figma主催のオンラインイベント「Dev Modeベーシックウェビナー」に参加しました。 実際に参加してみて、Figmaの「Dev Mode」を活用することで、デザイナーと開発者の連携がよりスムーズになり、業務の効率化にもつながると感じたので、共有させていただきます。 イベント概要 先日参加したFigma主催のオンラインイベント「Dev Modeベーシックウェビナー」では、Figmaの新機能である「Dev Mode」の基本的な使い方や、デザインから開発へのハンドオフをよりスムーズに行うための実践的なヒントが紹介されました。 ※当日の内容は録画されており、後日YouTubeでも公開予定とのことです。 本記事で紹介する内容 実際にイベントへ参加してみて、Dev Modeを活用することでデザイナーと開発者の連携がよりスムーズになると感じました。本記事では、特に印象に残ったポイントをご紹介します。 デザイナーが完成したデザインを開発者に引き渡す際に活用できる「Dev Mode」について 開発者が受け取ったデザインをどのように扱うのか、その連携方法や活用のコツ Dev Modeの利用条件 まず、Dev Modeを使うための基本的な前提を整理しておきます。 利用できるプラン Dev Modeは Professionalプラン以上で利用できます。 ただし、開発者として招待されたユーザーは無料で利用できる場合があります(ファイルのオーナーやデザイナーが有料プランの場合)。 アクセス権限 対象のFigmaファイルに、閲覧権限または編集権限が必要です。 対象ファイル Designファイルのみで利用できます(※FigJamファイルは対象外)。 まずは、デザイナーが完成したデザインを開発者に引き渡す際に活用できる機能についてご紹介します。 ステータス管理と通知機能 デザインと開発の担当が分かれている場合、開発者側が「このデザイン、もう実装していいのかな?」と判断に迷うことがよくあります。 都度確認するのも手ですが、Dev Modeの「ステータス管理機能」を使えば、そのやりとりを少し減らせるかと思います。 Dev Modeでは、デザインごとに「開発準備完了」のステータスを設定でき、開発者が現在の進捗をひと目で把握できるようになります。ステータスを「開発準備完了」に設定しておくことで、そのデザインが実装しても問題ない状態であることを明示できます。 ※BusinessやEnterpriseプランでは、さらに「完了済み」「変更済み」などの詳細ステータスも設定可能です(今回は割愛します)。 ステータス変更の方法 Figmaの下部ツールバーの  </>  ボタンをクリック、または  Shift + D で Dev Modeに切り替え。 画面右上のステータスボタンから「開発準備完了」を選択。 デザインファイル全体だけでなく、各セクションごとにもステータスを設定できるため、ページ単位・画面単位での進捗管理や、一部だけ実装OKといった柔軟な運用も可能です。 また、ステータス変更時にはFigma内通知、メール、Slackなど外部連携ツールを通じて通知されるため、見落とし防止にもつながります。 測定値とアノテーションの追加 デザインにおいて「ここの余白、絶対見逃さないで!」というようなポイントを、視覚的に明示できるのがこの2つの機能です。 測定値(Measurement) 余白や距離、サイズ感などを開発者に伝えたいときに使用します。 使用方法 Dev Mode → ツールバーから「測定」を選択、または  Shift + M 。 レイヤーにカーソルを合わせ、測定したい開始・終点をドラッグで指定。 アノテーション(Annotation) 補足説明や重要な仕様を、付箋のようにデザイン上に直接記載できます。 使用方法 Dev Mode → ツールバーからアノテーションを選択、または  Shift + T 。 任意のレイヤーを選び、アノテーションを追加。 アノテーションで設定できる内容: カテゴリ(開発・インタラクション・アクセシビリティ・コンテンツ) 注釈文(例:「ホバー時にテキストが太字になります」) プロパティ(選択したレイヤーのスタイル情報など) このように「ステータス管理」や「測定値・アノテーション機能」を活用することで、 「ホバー時のフォントは太字になります」「この余白は絶対に守って!」といった情報のやりとりの軽減や見逃し防止につながるかなと思いました。 デザイン観点から大きく二つの機能を紹介させていただきましたが、 ステータス管理については、変更できるステータスが「開発準備完了」のみなので、 BusinessやEnterpriseプランに入っている人向けの機能かなと感じました。 次に、開発者がデザインを受け取った後、「Dev Mode」を活用してどのように扱うかについてご紹介します。 デザインスペックの取得 デザインファイルを Dev Mode( Shift + D ) に切り替えることで、Figma標準のサンプルコードから、実装に必要なさまざまな情報を簡単に取得できます。 サイズ・位置・余白(Spacing) 要素の幅・高さ・座標などの詳細を確認ができます。 他の要素とのマージンやパディングも視覚的に把握できます。 カラー・フォント・タイポグラフィ 使用されているカラーコード(Hex/RGB)が確認できます。 フォントファミリー、サイズ、行間、ウェイトなど、テキストスタイルに関する詳細情報も取得できます。 CSS・iOS・Android向けコードのスニペット 選択した要素に対応するコード(CSS、Swift、XMLなど)が自動生成されます。 色や余白、フォントなど、実装に必要なスタイル情報をコピー&ペーストでそのまま活用できます。 アセットのエクスポート アイコンや画像などのアセットを、SVG・PNG・PDFなどでダウンロードすることができます。 解像度やファイル形式も用途に応じて選択できます。 コンポーネントとインスタンスの関係把握 「メインコンポーネントと比較」機能により、メインコンポーネントとの違いや変更点を明確に確認できます。 Dev Mode × VS Code 連携のメリット Visual Studio Codeを利用している場合は、拡張機能「Figma for VS Code」を導入することで、Figmaのデザインとエディタを直接連携させることができます。 この拡張機能により、先ほどご紹介したデザインスペックの確認がVS Code上で可能となり、Figmaとエディタ間を何度も行き来する必要がなくなります。 また、Figmaのビジネスプランおよびエンタープライズプランをご利用の方は、Figmaのデザインコンポーネントと、GitHub上の実際のコードを紐づけて管理することができる「Code Connect」も使用できます。 Figmaは今後、このCode Connectの機能強化をさらに進めていく方針です。詳細は以下の公式ヘルプページをご確認ください:   Code Connectの詳細はこちら まとめ:デザインと開発をつなぐ「Dev Mode」の価値 今回のウェビナーを通じて、FigmaのDev Modeが**デザインから開発への“橋渡し”**を強化してくれるツールであると改めて感じました。 実装ミスの予防 開発スピードの向上 コミュニケーションコストの削減 これらに貢献するDev Modeは、今後さらに活用の幅が広がるのではないかと思いますが、 今後はさらにDev Modeを活用し、チーム全体で「デザインと開発の一体化」をどう進めていくかがポイントになりそうです。 また最近耳にすることが多くなってきたコード生成AIについては、特に今回のウェビナーでは、 触れられませんでした。 以上、Figma「Dev Modeベーシックウェビナー」からの学びをお届けしました。
アバター
TSKaigi2025 TSKaigi2025 「学び、繋がり、”型”を破ろう」をテーマに、TypeScript に関するあらゆるテーマを扱う国内最大級のカンファレンスとして、まさに「型破り」なイベントを目指し成長を続けるカンファレンスです。 朝から夕方までTypeScriptについての講演があり、事前に自分が気になるセッションを聞きに行く方式でした。 開催日 2025/05/23、2025/05/24 印象に残ったセッション SignalとObservable―新たなデータモデルを解きほぐす AI Coding Agent Enablement in TypeScript TypeScriptとは何であって何でなく、誰のもので、どこへ向かうのか TS特化Clineプログラミング Pragmatic Functional Programming in TypeScript 付録: TSKaigi2025の発表資料まとめ 内製開発業務にどのように活かすか 【難易度_易】Panda CSSは継続して採用していきたい マイナビでもLocusで採用されたPanda CSS、他者も業務レベルで使い始めている 補足① TailwindからPanda CSSへの完全移行ガイド 【I難易度_易】フルスタックTypeScriptの案件の比率を増やすのもあり GraphQLを活用しまずはサブシステムとして使い始めてもいい 【難易度_易】 type-challenges でTypeScript技術力養成 勉強会、もうこれでいいのでは 【難易度_中】 スキーマ駆動開発、はじめました の潮流でバックエンドテストも正していきたい(Railsならcommitteeなど) TSKaigiと言いつつスキーマ駆動の話があったので、内製採用率の高いRailsではどうやって行こうという観点 【難易度_中~高】部署間連携で生産性向上(例. Figma MCPなど) TSKaigiと言いつつFigmaMCPからのコード生成の話があったので、これやるなら生産性向上のためにUXDとかと部門間連携必要 本題 組織開発という目線でみたカンファレンスのレポート 2024年に産声をあげ、昨年同様大盛況のうちに幕を閉じたTSKaigi2025。 公式のカンファレンス概要に書いてある通り、TSKaigiは非常に若いカンファレンスイベントです。 RubyKaigiの第一回が2006年、PHPカンファレンスは2000年、GoConはちょっといつからか分からないですが2013年くらいからはあるはず。とまぁこんな感じで若いイベントです。 GOが2009年生まれTypeScriptが2012年生まれとほぼ同期なので、イベント発足が遅めなのが分かります。connpassのイベントを遡って調べてもまあ2015年くらいからチラホラとサブタイトル的にイベントがあったくらいです。 (*生まれの2012から自分が新卒で入るまでの時間軸で絞り込んだのと、npm trendsで2016年くらいをマウスオーバー。) 出典: connpass - エンジニアをつなぐIT勉強会支援プラットフォーム 出典: typescript | npm trends TypeScriptがここまでの一大勢力になったのは静的型付け機能もありますが、ReactやVueやAngularの勢力が後押ししているのは間違いないと思います。 これはどの言語でももしかしたら共通して言えることかもしれませんが、例えばRubyであってもRuby on Railsが勢力を持っていないかったらここまで愛されたかどうか…言語の生みの親が日本人なのでそういった意味ではパイは取れたと思いますが…。 余談で私が新卒で入った会社はRuby on Railsでの開発を強みにしてましたがRails5でCoffeeScript が標準サポートされてました。Rails6はwebpackが入ってきてそれなりにまだフロントも書いてましたが7系でwebpackが剝がされて「フロントどうするかな」で「reactだな」という流れがWebアプリ開発者界隈ではそれなりにいたのではないでしょうかね。他のバックエンドフレームワーク事情は知らないのですが。 話を戻します。 TSKaigiですが来場者数も多く話題もSNSでそれなりにトピック化してたのでエンジニア界隈では結構HOTだった印象で、実際に会場にも多くの学生が来ておりました。ただカンファレンスとしてはわりと緩くてTSKaigiでPHPトークをしたという話題でプチ炎上があるとかないとか。CFP要綱を読んでもそれは頷けます。 【TSKaigiのCFP要綱】 トークの条件は、TSKaigi 2024と同様に「TypeScriptに関係する話題であること」、これだけです。 以下はすべて例です。 ・言語特性やエコシステムに関しての話題 ・TypeScriptの言語機能 ・Compiler API、内部実装、型の理論、いわゆる型パズル ・TypeScriptでの利用に特徴あるライブラリ、フレームワーク、ランタイム ・ベストプラクティス、アンチパターン、それらを包括する議論や問題提起 ・エコシステムそのもの、言語そのものに関するその他なんでも ・多様な利用領域での活用事例、ノウハウ ・Webフロントエンド、バックエンドやインフラはもちろんOK ・スマートフォンアプリ、デスクトップアプリ、ゲーム、IoT、XR(VR, AR, MR) そのほか、ここに予想もしないものまで TypeScriptを使った開発に関する話題 ・チーム開発、CI/CD、テスト、デバッグ、モニタリング、デプロイ、運用 ・開発ツール、エディタ、IDE、ツールチェーン、ツールの開発、ドキュメンテーション ・うまくいったこと、うまくいかなかったこと こんな使い方もできるのか、TypeScript! という驚きを得られるような話題に出会えたら、と思っています。 高度で専門的な話でなくても構いません。あなたの経験や気づきを、ぜひ共有してください。 RubyKaigiとは雰囲気がだいぶ違うんだなという印象でしたが、そもそもRubyKaigiが特殊なだけと良く言われているのでTypeScriptの言語学的なセッションを期待していると歪みが起こりそうです。 実際、トークセッションの内容の6割以上くらいは生成AIの文脈は絡んできてた感じで、それ完全にもうLLM周りの話ではないのか?ともありました。 個人的にはLLMとの上手い付き合い方みたいな感じでも十分に学びになりましたが、純粋にオープニングキーを担当したAnthony FuさんのESLint ConfigみたいなTypeScriptエコシステムの内部仕様みたいな話を期待しているとやっぱり乖離ありです。 発表のあったLTセッションを参考に、マイナビの内製開発におけるTypeScriptの話をしてもウケそうだなとも思いました。マイナビでもフルスタックTypeScript構成の案件やorval、OpenAPIスキーマからTypeScriptクライアントコードを生成している案件やPanda.CSSを使った案件もあるのでTSKaigiの登壇にチャレンジしていきたいですね。 ではスポンサー枠の状況やメリットは何だろうか。 国内最大級のTypeScriptカンファレンス「TSKaigi 2025」、 スポンサー募集中です TSKaigi 2025 スポンサーの一次募集終了と御礼 資料によると、2024はオフライン+オンラインで2,400人くらいの参加だったが、今年は公式では計画段階で3,600人くらいのようでしたが、チケット完売も早かったのでオンラインの上振れ考えても、倍は見込んだとして5,000人は直接リーチはありそうです。(個人推論です) 協賛ボードはプラチナ150万円、ゴールド100万円、シルバー50万円、ブロンズ20万円です。 ブースやランチタイムLT枠はシルバー以上で応募可能になっており、ランチタイムLTは10分で10万円なので、登壇枠を買うなら最低60万円で可能です。 ブースは30万円でスタートアップからレバレジーズやサイバーエージェントやdwangoやfreeeなどの社会的な知名度がある事業会社もありました。 WEBエンジニアはカンファレンスボードをみて転職可能企業を見つけている部分もあるとは思うので、開発分野での組織的なブランド価値と求人広告周り出すよりはコスパはいいかもしれない。実際ブース出展からカジュアル面談にという経路もいくつかあるはず。 マイナビに限って言えば組織が大きすぎてカジュアル面談とかないかもしれないがまあ方法論はいくつかあると思います。 TypeScriptはトレンドすぎてカンファレンスに協賛しなくても新卒採用では当たり前のように興味持った学生がデジ戦に応募してくるかもしれないのですが、TSKaigiに限らず技術カンファレンスのスポンサーとかプロポーザル活動やっていきたいですね。 (RubyKaigiとかKaigi on RailsとかGoConとか)
アバター
こんにちは、新卒2年目でビジネスイノベーション統括本部ITD1-2-0のS.Hです。 今回、私が普段の業務で使用しているTypeScriptをテーマにした大型カンファレンス『TSKaigi 2025』の参加レポートを書かせていただきました! 研修後、現在の部署に配属されてからもうすぐ1年。ほぼ新人の視点から、TSKaigiに参加して感じた魅力などを発信していきます! TSKaigi 2025 カンファレンス概要 情報区分 カンファレンス詳細 イベント名 TSKaigi 2025 開催日 2025/05/23、2025/05/24 開催場所 ベルサール神田 都営新宿線小川駅から徒歩5分 ミッション 学び、繋がり、"型"を破ろう タイムテーブル Day1 10:00 開場 10:50 ~ 11:00 トグルルーム:オープニングトーク アセンドトラック:サテライト レバレジーズトラック:クローズ 11:00 ~ 11:40 トグルルーム 種別:招待講演 タイトル: The New Powerful ESLint Config with Type Safety 登壇者:Anthony Fu アセンドトラック:サテライト レバレジーズトラック:クローズ 11:40 ~ 11:50 休憩 11:50 ~ 12:20 トグルルーム 種別:セッション タイトル: checker.tsに対して真剣に向き合う 登壇者:Kaoru アセンドトラック 種別:セッション タイトル: 高度な型付け、どう教える? 登壇者:progfay レバレジーズトラック 種別:セッション タイトル: スキーマと型で拓く Full-Stack TypeScript 登壇者:Sohei Takeno 12:20 ~ 12:30 ランチ配布 12:30 ~ 13:30 トグルルーム 種別:スポンサーLT 撤退危機からのピボット:4年目エンジニアがリードする TypeScript で挑む事業復活  / 横沢 諒 推し活を支えるAngularアプリ量産体制  / Hayato Okumoto 生成AI時代にフルスタックTypeScriptの夢を見る  / matano AsyncAPIを使ってPub/Subを型安全にする  / 高橋 修平 アセンドトラック:ランチ レバレジーズトラック:ランチ 13:30 ~ 13:40 休憩 13:40 ~ 14:10 トグルルーム 種別:セッション タイトル: TypeScriptで実践するクリーンアーキテクチャ ― WebからもCLIからも使えるアプリ設計 登壇者:プログラミングをするパンダ アセンドトラック 種別:セッション タイトル: 静的解析で実現したいことから逆算して学ぶTypeScript Compiler 登壇者:Kazushi Konosu レバレジーズトラック 種別:セッション タイトル: SignalとObservable―新たなデータモデルを解きほぐす 登壇者:lacolaco 14:10 ~ 14:20 休憩 14:20 ~ 14:50 トグルルーム 種別:セッション タイトル: 堅牢なデザインシステムをつくるためのTypeScript活用 登壇者:takanorip アセンドトラック 種別:セッション タイトル: Language Serverと喋ろう 登壇者:ぴざきゃっと レバレジーズトラック 種別:セッション タイトル: TSConfigからTypeScriptの世界を覗く 登壇者:らいと 14:50 ~ 15:00 休憩 15:00 ~ 15:30 トグルルーム 種別:セッション タイトル: AI Coding Agent Enablement in TypeScript 登壇者:Yuku Kotani アセンドトラック 種別:LT 推論された型の移植性エラーTS2742に挑む  / elecdeer TSConfig Solution Style & subpath imports でファイル単位で型を切り替える  / kotori 主要ライブラリの実例に学ぶ、TypeScriptで実現する型安全な座標定義  / 原口 公輔 コンポーネントライブラリで実現する、アクセシビリティの正しい実装パターン  / たじまん レバレジーズトラック 種別:LT 学生でもここまで出来る!ハッカソンで爆速開発して優勝した話  / かわちゃん 『Python→TypeScript』オンボーディング奮闘記  / 龍野 卓己 転生したらTypeScriptのEnumだった件~型安全性とエコシステムの変化で挫けそうになっているんだが~  / やまのく URLPatternから始めるWebフレームワーク開発入門  / ryuapp 15:30 ~ 15:50 休憩 15:50 ~ 16:20 トグルルーム 種別:セッション タイトル: TypeScriptとReactで、WAI-ARIAの属性を正しく利用する 登壇者:ymrl アセンドトラック 種別:セッション タイトル: AWS LambdaをTypeScriptで動かして分かった、Node.jsのTypeScriptサポートの利点と課題 登壇者:Masaki Suzuki レバレジーズトラック 種別:セッション タイトル: TypeScriptエンジニアがAndroid開発の世界に飛び込んだ話 登壇者:yui_tang 16:20 ~ 16:30 休憩 16:30 ~ 17:00 トグルルーム 種別:セッション タイトル: TypeScriptとは何であって何でなく、誰のもので、どこへ向かうのか 登壇者:Sosuke Suzuki アセンドトラック 種別:セッション タイトル: fast-checkとneverthrowのPBT+Result型で堅牢なビジネスロジックを実現する 登壇者:上田慶祐 レバレジーズトラック 種別:セッション タイトル: Valibot Schema Driven UI - ノーコードWebサイトビルダーを実装してみよう! 登壇者:宮城広隆(@MH4GF) 17:00 ~ 17:10 休憩 17:10 ~ 17:40 トグルルーム 種別:セッション タイトル: Rust製JavaScript/TypeScript Linterにおけるプラグイン実装の裏側 登壇者:unvalley アセンドトラック 種別:LT Interface vs Types 〜型推論が過多推論〜  / omote Wasmを用いて他言語資産をTypeScriptで活用する  / 赤木 勇統 型パズルを好きになるために、競プロを型システムだけで解いてみることにした  / いまいまい タイプレベルリファクタリング奮闘記〜この「型パズル」は読めません!〜  / Yugo Yagita レバレジーズトラック 種別:LT Rust製JavaScript EngineのTypeScriptサポート  / yossydev TypeScript だけを書いて Tauri でデスクトップアプリを作ろう  / 小松 翔 (tris) 型安全なDrag and Dropの設計を考える  / yudppp GitHub ActionsをTypeScriptで作ろう!  / じょーし(上司陽平) Day2 9:30 開場 9:50 ~ 10:00 トグルルーム:オープニングトーク アセンドトラック:サテライト レバレジーズトラック:クローズ 10:00 ~ 10:40 トグルルーム 種別:主催者講演 タイトル: TypeScriptネイティブ移植観察レポート TSKaigi 2025 登壇者:berlysia アセンドトラック:サテライト レバレジーズトラック:クローズ 10:40 ~ 10:50 休憩 10:50 ~ 11:20 トグルルーム 種別:セッション タイトル: TypeScript Language Service Plugin で CSS Modules の開発体験を改善する 登壇者:mizdra アセンドトラック 種別:セッション タイトル: フロントエンドがTypeScriptなら、バックエンドはPHPでもいいじゃない 登壇者:富所 亮 レバレジーズトラック 種別:セッション タイトル: TypeScriptとVercel AI SDKで実現するLLMアプリケーション開発:フロントエンドからバックエンド、そしてChrome拡張まで 登壇者:加瀬健太(Kesin11) 11:20 ~ 11:30 休憩 11:30 ~ 12:00 トグルルーム 種別:セッション タイトル: 複雑なフォームを継続的に開発していくための技術選定・設計・実装 登壇者:izumin5210 アセンドトラック 種別:セッション タイトル: Pragmatic Functional Programming in TypeScript 登壇者:yasaichi レバレジーズトラック 種別:セッション タイトル: feature flag 自動お掃除のための TypeScript プログラム変換 登壇者:azrsh 12:00 ~ 12:10 ランチ配布 12:10 ~ 13:10 トグルルーム 種別:スポンサーLT バックエンドのコードファーストなOpenAPIスキーマ駆動開発 / 鳥居 雄仁 バランスを見極めよう!実装の意味を明示するための型定義 / 畑田祥太 PandaCSSでつくる、型で守られたスタイリング基盤 ~TypeScript × デザインシステム管理の実践アーキテクチャ~ / 田代 敬太 TSでシステムが堅牢になっていくさまをスポンサーになるたびに報告 〜型定義から始めるリファクタリング編 / 井上 心太 アセンドトラック:ランチ レバレジーズトラック:ランチ 13:10 ~ 13:20 休憩 13:20 ~ 13:50 トグルルーム 種別:セッション タイトル: 技術書をソフトウェア開発する - jsprimerの10年から学ぶ継続的メンテナンスの技術 登壇者:azu アセンドトラック 種別:セッション タイトル: 型システムを活用した ESLint カスタムルール開発入門 〜固有ドメインにおけるコーディング規約を開発する〜 登壇者:山梨 蓮 レバレジーズトラック 種別:セッション タイトル: Web Streams APIの基本と実践、TypeScriptでの活用法 登壇者:tasshi 13:50 ~ 14:00 休憩 14:00 ~ 14:30 トグルルーム 種別:セッション タイトル: ts-morphで、人間も編集できるコード生成を実現しよう! 登壇者:池奥裕太 / @yuta-ike アセンドトラック 種別:LT VueUse から学ぶ実践 TypeScript / ツノ 型推論の扉を開く―集合論と構造的型制約で理解する中級へのステップ / 栃川晃佑 TypeScript ASTとJSDocで実現するコードの自動削除 / 川野賢一 これは型破り?型安全?真実はいつもひとつ!(じゃないかもしれない)TypeScriptクイズ / 君田 祥一 レバレジーズトラック 種別:LT Result型、自前で書くか、ライブラリ使うか / majimaccho 型付け力を強化するための Hoogle のすゝめ / TAKASE Kazuyuki (@Guvalif) React19で変化したuseReducerの型から学ぶTypeScriptの型推論 / k8o クラサバ境界を失った現代 TypeScript コードベースに秩序をもたらしたい / Yo Iwamoto 14:30 ~ 14:40 休憩 14:40 ~ 15:10 トグルルーム 種別:セッション タイトル: 機能的凝集の概念を用いて複数ロール、類似の機能を多く含むシステムのフロントエンドのコンポーネントを適切に分割する 登壇者:NoritakaIkeda アセンドトラック 種別:セッション タイトル: Lookback TypeScript ESM support and what should we do now. 登壇者:Saji レバレジーズトラック 種別:セッション タイトル: 君だけのオリジナル async / await を作ろう 登壇者:susisu 15:10 ~ 15:30 休憩 15:30 ~ 16:00 トグルルーム 種別:セッション タイトル: TS特化Clineプログラミング 登壇者:mizchi アセンドトラック 種別:セッション タイトル: "良い"TSのコードを書く為のマインドセット 登壇者:Kei レバレジーズトラック 種別:セッション タイトル: TypeScript製IaCツールのAWS CDKが様々な言語で実装できる理由 〜他言語変換の仕組み〜 登壇者:k.goto 16:00 ~ 16:10 休憩 16:10 ~ 16:50 トグルルーム 種別:LT 型がない世界に生まれ落ちて 〜TypeScript運用進化の歴史〜 / 成原 聡一朗 Type ChallengesにPRを出して新しい問題を追加した話 / Kanon ProxyとTypeScriptのおいしい関係 / Motoki Shakagori / ほとけ Panda-CSS はどのように型安全にしているのか / 加藤貴裕 アセンドトラック 種別:LT 令和最新版TypeScriptでのnpmパッケージ開発 / odan コンパイルオプションで変わる型世界 / 池田敬祐 TypeScriptのmoduleオプションを改めて整理する / おおいし (bicstone) Project Referencesを活用した実行環境ごとのtsconfig最適化 / Toshiki Itai レバレジーズトラック 種別:LT ts-morph実践:型を利用するcodemodのテクニック / ypresto declaration mergingの威力:ライブラリアップデート時の書き換え作業を90%短縮するテクニック  / Yuma Takei バリデーションライブラリ徹底比較  / 田中勇太 Standard Schema: スキーマライブラリの統一規格とは何か  / Nozomu Ikuta 17:00 ~ 18:00 トグルルーム:懇親会準備 アセンドトラック:休憩スペース レバレジーズトラック 種別:現地参加者向け企画 タイトル:タイトル: OST (Open Space Technology) 18:00 ~ 20:10 トグルルーム:懇親会 アセンドトラック:クローズ レバレジーズトラック:クローズ セッション内容 TypeScriptネイティブ移植観察レポート TSKaigi 2025 登壇者: berlysia氏 セッション時間:2日目朝 株式会社ドワンゴでWebフロントエンドエンジニアをされているberlysia氏によるts-goの体験レポートです。 5/23深夜、つまりTSKaigiの1日目夜にMicrosoftから公開された tsgoのプレビュー に触れてみた観察者としての調査報告になります。 夜中に公開されたので、TSKaigi1日目を終えてそこから触り、登壇資料を作成されたみたいです。バイタリティとメンタルが素直に凄すぎます。 ts-go1番の特徴はMicrosoftが動画のタイトルにも取り上げられている 「A 10x Faster TypeScript with Ander Hejlsberg(10倍早いTypeScript)」 従来はTypeScriptで書かれた構文をNode.jsを用いて実行されていました。それらを全てfunction単位でGo言語に置き換えており、 Go言語の利点を十全に活かすことで10倍という圧倒的なパフォーマンスを実現するに至ったそうです。 具体的には ソースコードをその場で解釈して実行する Node.jsから、事前に機械語に翻訳されるGo言語へ変わったことによる処理速度の向上 (約3~3.5倍) Node.jsはシングルスレッドモデルの制約があり、単一の処理しかできなかったが、Go言語になったことで並列処理が可能になった (約3~4倍) 上記の2点が組み合わさったことで、本当にすぐに動くようになったとのことでした。 しかも、実行するプログラムの規模が大きくなるほど、その早さを実感するそうです。 「ts-goというものが話題になっている」ということはそれとなく把握していつつも、それが具体的に何なのか知らなかった自分でしたが、10倍という数値だけでもその凄さを容易に想像することができました。 処理速度が上がったことで、それまでのバージョンでは見送っていたライブラリなども採用されるようになり、より発展的で高度な技術力が求められるようになる、というのが私の所感です。 そして、そんなに凄いts-goをまだ私は触ることができていないので、このレポートを書き終えたら早速触ろうと思います。 OST(Open Space Technology) タイムテーブルにある通り、本当に多くのセッションがあり、学びが沢山ありました。 ですが、TSKaigiは登壇者だけが発信する場ではありません。2日目の最後には、セッションルームに集まった参加者が各々好きなテーマについて話し合えるOSTが設けられていました。 OSTはそのテーマについて熱く語りたいから参加する人はもちろん、ほとんど詳しくないけど、知見を広げたいから参加する人もいらっしゃいました。 自分はもちろん後者です笑 今回、TSKaigi中の募集を通して選出されたテーマは下記画像に記載された10個。皆さんはどのテーマに興味を惹かれましたか? 私は5番の「フロントエンドのディレクトリ構成、どう設計している?」に参加しました。 というのも、私の周りにはそういった開発理論について考えることが好きな同期がおり、この機を活かして『完全に理解した!』ぐらいの理解度を得てみたいと感じたためです。 結論からお伝えすると『だいぶん理解したかも??』ぐらいの理解度を得ることができました。 もう少し実際に試していくことで『完全に理解した!』の理解度を得られそうです。 今回のOSTで話題に上がった内容はFSDとBCDデザインの組み合わせです。 FSD まず、 FSD(Feature-Sliced Design) とは、機能単位で構造化する設計パターンで、公式では「Architectural methodology for frontend projects(フロントエンドのアーキテクチャ手法)」と定められています。 機能単位で構造化する、つまり機能ごとに責務を持たせることで、拡張性・保守性・可読性を高めることが可能になることがFSDの特徴です。 FSDは、レイヤーという役割の抽象的な区分と、そこから実際の機能単位で切り分けるスライス、そしてhookやUIなどの各機能を構成するセグメントで成り立っています。 出典: FSD(Feature-Sliced Design) 機能単位でディレクトリを構成することは多いと思いますが、そこから更に責務という名の「機能の持つ役割や義務」に着目して分類する手法がFSDなのです。 BCDデザイン 次にBCDデザインは株式会社ドワンゴ所属のmisuken氏が考案されたコンポーネントの分類手法です。 同期からの受け売りですが、 「BCDデザインとは Base(UI) Case(動作) Domain(対象)に着目してコンポーネント名を『何をどうするUI』の法則に則って命名すること」なんだそうです。 私なりの解釈で説明すると、誰でもそのコンポーネント名を見ただけで、役割が分かるようにする手法になります。 出典: misuken氏のBCDデザイン解説記事 例えば、ここにフィードバック専用のモーダル画面のコンポーネントがあったとしたら、どのような名前にしますか? 恐らく、多くの人が FeedbackModal.tsx という名前にするのではないでしょうか? それがBCDデザインの命名規則に当てはめると、 FeedbackSendModal.tsx になります。 フィードバックを編集する(Edit)でもなく、削除する(Delete)でもなく、送る(Send)ためのモーダル画面。それが誰にでも伝わる命名規則です。 ちなみに、この場合でも何のフィードバックなのかが不透明なので、DomainをDomainとCommon(抽象的対象)に分割するBCCDデザインというものもあります。 また、 misuken氏のBCDデザイン解説記事 では、「"命名" するのではなく "明名" すると考える」と表現されていました。 OSTまとめ FSD × BCDデザイン 「抽象的な責務で分類し、機能単位でディレクトリ構造化を図るFSD」と 「誰にでも伝わるコンポーネント明名手法のBCDデザイン」 この2つを組み合わせることで構造も名前もはっきりと定まった方針で分かりやすくフロントエンドのディレクトリ構成が実現できる、というのが今回のOSTに関する結論になりました。 今回のディレクトリ構成OSTには15名近くの方が集まり、その中でもFSDとBCDデザイン、それぞれの知見を深く持った方が2人ずついらっしゃったので、本当に濃い議論をすることができました。 個人的には、今回のBCDデザイン側に株式会社ドワンゴの社員さんがいらっしゃったことに一番衝撃を受けました。流石TSKaigi、一般参加される方も凄い。 企業ブース 私は今回のカンファレンスでブースを設けられていた企業様のイベントも目一杯体験してきました。 恐らく、会社から一緒に行った7人の中で最も詳しく企業ブースのレポートを書けると思うので、こちらも詳しく書かせていただきます! (各ブースで実施されたスタンプラリーを1日目で制覇しました) 流石に全ブースについて書くと時間が足りないので、今回は2つほど特に面白いと感じた企業様のブースを取り上げさせていただきます AVITA株式会社 AVITA株式会社は大阪大学の教授が代表を務めるスタートアップ企業です。 大学の研究室と企業、両方から特許申請を活発に行い、週に1回ペースで特許申請会議があるそうです。 "特許申請会議"。字面がとても強い 提供しているwebサービスは、 「フロント・バックエンドがフルスタックのTypeScriptで実装されたWebアプリ」 と 「Unity × TypeScriptで運用されているスマホアプリ」です。 色々お話をお伺いした中で、私が特に面白いと感じた点は真ん中のディスプレイで動いているトラッキング技術です。 これはディスプレイ上部のカメラから取り込んだ映像を元にフェイストラッキングとハンドトラッキングを同時に実行されています。 この処理には、Googleが提供している画像解析によるトラッキング専用ライブラリMediaPipeが利用されています。 その中でも面白いと感じた要素は、とにかくトラッキングの精度が高すぎる点です。 MediaPipeは機械学習によって手の状態を画像解析を行い、「恐らくこの辺りに手の関節があるだろう」といった判定を下します。そのため、動画のように連続してトラッキング対象が動く状況だと著しく精度が落ちます。 実際、以前に自分がMediaPipeを試したときは指関節がはちゃめちゃに暴れ回り、画面内に描写された手は見事に潰れていました。 それなのに、こちらのプログラムは滑らかに動く実物の手に追従して、関節座標も暴れることなくしっかり手の動きを再現していました。 Unityアプリの出来から垣間見えた開発者さんの膨大な努力に圧倒され、ものすごく興奮しました。 TypeScriptの話はできませんでした… お土産にシールやアクスタをいただきました笑 スパゲッティコード、マジックナンバー イラストはとても可愛いのにワードが全く可愛くない アクスタも作るぐらいIP展開にも力を入れ始めたらしいです。いつか販売されるのを楽しみにしています! 株式会社TwoGate TypeScriptベースのWebアプリフレームワーク"Angular"を使ったエンターテイメント領域向けに利用者専用にカスタマイズしたスマホアプリをリリースしている会社です。 1日目のお昼にLT登壇もされていました。 推し活を支えるAngularアプリ量産体制 こちらの企業から沢山お話を聞いた内容はサービスの根幹部分の「Core Library Repository」についてです。 TwoGate様はアーティストの要望に沿って推し活の専用アプリをリリースしており、開発エンジニア15名ほどに対し、リリースしているアプリ数は200個を超えています。 平均1人当たりアプリを15個ほど担当しているような状況でも成り立っている理由はリリースしたアプリ全てが「Core Library Repository」というこの企業独自のライブラリから作られているからです。 つまり、Core Library Repositoryがあれば、多少のカスタマイズをすることで誰でもチケット販売や整理券配布などの機能を持った専用アプリを作ることできる。そんなライブラリを作り上げ、それを元にサービスを提供しているとのことでした。 私たち開発エンジニアが普段活用しているようなライブラリを作り、その運用を事業として行なっている一風変わった企業様でした。 TSKaigiに参加して 今回、私は下記の2つのセッションに参加し、その上で実際にそれぞれの技術に触れてみたので、それぞれから感じた今後に対する所感をまとめさせていただきます。 PandaCSSでつくる、型で守られたスタイリング基盤 ~TypeScript × デザインシステム管理の実践アーキテクチャ~ TS特化Clineプログラミング CSSライブラリ - PandaCSS PandaCSSを知ったことをきっかけに、実際に個人で触れてみる中で、TailwindCSS以外のCSSライブラリにも視野を広げる良い機会になりました。使ってみることで、それぞれのライブラリが持つ特徴や考え方の違いも見えてきて、フロントエンドに対する理解が一段深まったように感じます。 一方で、実際にNext.jsのプロジェクトに組み込もうとすると、TailwindCSSのように簡単にセットアップできるわけではなく、PandaCSSは別途インストールや設定が必要です。その分、Dockerfileなどの構成にも工夫が必要で、開発や保守とはまた違った知識が求められる点には留意する必要があると感じました。 こうした経験から、CSSライブラリの選定には機能性だけでなく、導入のしやすさやチームの開発環境との相性も含めて検討することの重要性を実感しました。 コーディングエージェントについて 最近よく耳にする「コーディングエージェント」ですが、これまでは最低限のサポートツールとして使っている程度でした。実際のところ、補助的にコードを書いてくれる便利な存在、という認識しか持っていませんでした。 しかし今回、プロンプトをしっかり設計してAIとやり取りしてみたことで、印象が大きく変わりました。AIを効果的に活用するには、「どう指示するか(=プロンプト)」の工夫がとても重要で、これ自体が一つのスキルだと感じました。いわゆる“プロンプトコーディング”が、今後開発エンジニアに求められる新しい力になると思います。 また、個人的な気づきとして、会社でコーディングエージェントを活用していくには、プロンプトの作り方だけでなく、それをどう管理するかも大切になってきそうです。チームでの共有や再利用、更新のしやすさなど、コードと同じように「プロンプトの品質」も考えていく必要があると感じました。 TSKaigiの感想 私はTSKaigiに初めて参加し、本当に貴重な経験を沢山することができました。 今回のカンファレンスに対して、職場環境以外からのインプットを求めて参加をしました。 職場という技術的にも思想的にもある程度方針が固まっている環境以外からの発信に多く触れることで、技術研鑽というアウトプットに対するモチベーションへ繋げたいと考えていました。 実際、先ほどの章で触れた通り、これまで触れていなかった技術や概念に挑戦するきっかけとなりました。 その結果、壁にぶつかったことで新たな課題が見つかりましたが、それでもTSKaigiに参加しなかったら得られなかったものなので、職場環境以外からのインプットはとても価値のあるものだと実感しています。 まだ、技術スタック的に業務と直接交わることのないものですが、今後PJや状況が変化した先で繋がるタイミングがあると思うので、これからもアウトプットを続けていきたいと考えています。 また、今回の1日目は平日に開催されていましたが、外部研修の一環で公休の申請が降りたため、参加しやすい環境になっていた点がとても有難かったです。 同期や先輩を含め7人での参加は初めての経験だったこともあり、自分が見て回れなかったブースやセッションの話も聞くことができ、TSKaigiをより楽しむことができたと実感しています。 お弁当も美味しかったです おまけ TSKaigiでいただいたサプライ品が気に入りすぎて、社用にカスタマイズしました。 右のタグはTSKaigiで知り合った方に作り方を教わって作成した自己紹介タグです。 イベントで大活躍間違いなし!爆速相互フォローを実現するNFCタグキーホルダーを作ろう
アバター
システム開発における命名の重要性 「命名」について、考えたことはありますか? 命名とは、文字通り命を与えることです。つまり、システムの肝となりうるものということです。 したがって、不適切に命名されたシステムはその生命を十分に発揮することができません。 軽く考えられがちな「名前をつける行為」ですが、この行為の質がプロジェクト全体の健全性を左右すると言っても過言ではありません。 今回は、「命名」を「ドキュメンテーションにおける最も基本的な手段」にまで昇華させるために重要なことについて説明をします。 命名における関心とは 命名における関心 (Domain)とは、対象となるビジネス領域の本質的な概念や規則を反映する要素です。 これは単なる技術的な区分ではなく、実際のビジネスプロセスや業務知識に基づく分類軸を意味します。 関心は以下のような要素から構成されます。 ドメインエンティティ:業務上の主要概念 生徒 会員 商品 注文 ドメインプロセス:業務上の重要な処理 入会 退会 請求 集計 ドメイン状態:業務上の条件や状態 アクティブ 休会中 プレミアム 月次 ドメイン規則:業務特有のルールや制約 割引条件 承認フロー ドメインコンテキスト:適用される業務文脈 販売 マーケティング 教育 中核の関心 例えば、「プレミアム会員の月次利用統計」には「プレミアム会員」という顧客区分と「月次」という集計期間、「利用統計」という分析対象といったように複数の関心が含まれています。 しかし、この中でもっとも重要な関心は「利用統計」です。 このように、複数の関心が組み合わさっていてもその中にひとつ主軸となる「中核の関心」が存在することがわかります。 そして、命名において重要なことは、中核の関心と補助の関心(それ以外の関心)の境界を明確に理解し、関心を過不足なく表現しきることです。 また、分類においても中核の関心は重要なポイントとなります。 例えば、「プレミアム会員」、「月次」、「利用統計」というカテゴリーがあったとき、「プレミアム会員の月次利用統計」はどこに分類するべきでしょうか? ここまでの話から、中核の関心をもとに「利用統計」に分類するべきであることがわかるとおもいます。 関心を表現し切ることの重要性 よくある命名の失敗のひとつが、「関心を表現しきれていないこと」です。 例えば、「プレミアム会員の月次利用統計」の中核の関心は「利用統計」ですが、「プレミアム会員」と「月次」も重要な関心であることに変わりはありません。 しかし、命名する際に中核の関心以外の補助の関心が抜け落ちてしまうことがあります。 「プレミアム会員の月次利用統計」を英訳すると PremiumMemberMonthlyUsageStatistics となります。そして、これがそのまま関心名となっているべきなのです。 例えば、「プレミアム会員の月次利用統計を取得する関数」の命名は getPremiumMemberMonthlyUsageStatistics であるべきです( get が妥当かは別問題として)。 名前が長くなるのをおそれて、 getUsageStatistics のように関心を省略してしまうのは典型的なアンチパターンとなるため注意しましよう。 関心は後方一致でまとめよう 中核の関心は、関心名の最後に現れる状態にしましょう。 なぜなら、日本語の語順において中核の関心は最後に現れるためです。 例えば、「プレミアム会員の月次利用統計」の中核の関心は「利用統計」ですが、関心名の最後に現れています。 この「関心名の末尾に中核の関心が現れる状態」は認知上のパフォーマンスにおいて非常に重要となります。 日本語の語順のまま英訳しよう 実を言えば、日本語において中核の関心が名前の最後に現れるのは当たり前のことです。 というよりも、名前の最後に現れている関心が中核の関心であるといった方が正しいです。 ではなぜこのような話をしているのかと言うと、英語にした際にこの当たり前が崩れることがあるためです。 「契約プラン別のユーザ」を例にみていきましょう。 まず、「契約プラン別のユーザ」を直訳すると「Users by Contract Plan」となります。 そして、「契約プラン別のユーザ」の中核の関心は「ユーザ」です。 しかし、「Users by Contract Plan」の末尾についているのは「Contract Plan」です。 このように、日本語では問題なかった命名が英語にした途端問題が発生してしまうことがあります。 では、どのように英訳すればよかったのでしょうか? 重要なポイントは、「日本語の語順のまま英訳する」ことです。 英訳する際に、日本語の語順を保つようにすれば中核の関心を最後に持ってくることが可能となります。 私は英語の専門家ではないので、AIに頼ってみましょう(Claude 3.7 Sonnetを使用)。 Q: 「〇〇別のXxx」を、「Xxx by 〇〇」ではなく、Xxxの前方につく修飾語で表現できると嬉しいのですが、何か案はありますか? A: 修飾語による表現方法の提案 「〇〇別のXxx」を「Xxx by 〇〇」ではなく、前方修飾語で表現する方法としては、以下のようなパターンがあります: 一般的なパターン 形容詞形に変換する 例:「地域別の売上」→ "Regional sales" 例:「性別の統計」→ "Gender-specific statistics" 所有格を使う 例:「部門別の予算」→ "Departmental budget" 例:「季節別の計画」→ "Seasonal plan" 複合語を形成する 例:「年齢別の分析」→ "Age-based analysis" または "Age-group analysis" 例:「業界別のレポート」→ "Industry-specific report" 接頭辞を活用する 例:「国別のデータ」→ "Country-specific data" または "Per-country data" 例:「時間別の記録」→ "Time-segmented records" Q: このようなケースで使用できる前方修飾語をまとめてください。 修飾表現別の「示す基準」の比較 各表現が示す基準や関係性の違いを整理します: 分類・区分に関する表現 based: 「〜に基づいた」- 分類や区分の基準を示す 例: Age-based grouping(年齢に基づくグループ分け) 適した用途: データ分類、カテゴリ分け、客観的基準による整理 specific: 「〜に特化した」- 特定対象への限定性を示す 例: Industry-specific regulations(業界に特化した規制) 適した用途: 特定分野だけに適用される事柄、限定された適用範囲 segmented: 「〜で区分された」- セグメント化の基準を示す 例: Price-segmented offerings(価格帯で区分された商品) 適した用途: マーケティング分析、戦略的区分け classified: 「〜で分類された」- 分類のカテゴリーを示す 例: Skill-classified employees(スキルで分類された従業員) 適した用途: 階層化された分類、評価基準による区分 焦点・方向性に関する表現 focused: 「〜に焦点を当てた」- 注目点や重点を示す 例: Solution-focused approach(解決策に焦点を当てたアプローチ) 適した用途: 戦略や方法論、特に重視する側面の強調 oriented: 「〜志向の」- 方向性や傾向を示す 例: Result-oriented metrics(結果志向の指標) 適した用途: 思想的傾向、アプローチの方向性 centric: 「〜中心の」- 中心的要素を示す 例: User-centric design(ユーザー中心の設計) 適した用途: 設計思想、価値観の中心 対象・用途に関する表現 targeted: 「〜を対象とした」- 明確なターゲットを示す 例: Senior-targeted services(高齢者を対象としたサービス) 適した用途: マーケティング、サービス提供の対象指定 tailored: 「〜向けに調整された」- カスタマイズの対象を示す 例: Client-tailored solutions(クライアント向けに調整されたソリューション) 適した用途: パーソナライズされたサービス、個別調整された提案 dedicated: 「〜専用の」- 専用化・排他的用途を示す 例: Developer-dedicated tools(開発者専用のツール) 適した用途: 特定グループだけが使用するもの、専用設計された製品 観点・視点に関する表現 wise: 「〜の観点から」- 視点や観点を示す 例: Department-wise budgeting(部門の観点からの予算編成) 適した用途: 分析視点、複数の観点からの考察 AIの回答を表にまとめてみます。 修飾表現別の「示す基準」比較表 分類・区分に関する表現 表現 意味 例 適した用途 based 〜に基づいた Age-based grouping(年齢に基づくグループ分け) データ分類、カテゴリ分け、客観的基準による整理 specific 〜に特化した Industry-specific regulations(業界に特化した規制) 特定分野だけに適用される事柄、限定された適用範囲 segmented 〜で区分された Price-segmented offerings(価格帯で区分された商品) マーケティング分析、戦略的区分け classified 〜で分類された Skill-classified employees(スキルで分類された従業員) 階層化された分類、評価基準による区分 焦点・方向性に関する表現 表現 意味 例 適した用途 focused 〜に焦点を当てた Solution-focused approach(解決策に焦点を当てたアプローチ) 戦略や方法論、特に重視する側面の強調 oriented 〜志向の Result-oriented metrics(結果志向の指標) 思想的傾向、アプローチの方向性 centric 〜中心の User-centric design(ユーザー中心の設計) 設計思想、価値観の中心 対象・用途に関する表現 表現 意味 例 適した用途 targeted 〜を対象とした Senior-targeted services(高齢者を対象としたサービス) マーケティング、サービス提供の対象指定 tailored 〜向けに調整された Client-tailored solutions(クライアント向けに調整されたソリューション) パーソナライズされたサービス、個別調整された提案 dedicated 〜専用の Developer-dedicated tools(開発者専用のツール) 特定グループだけが使用するもの、専用設計された製品 観点・視点に関する表現 表現 意味 例 適した用途 wise 〜の観点から Department-wise budgeting(部門の観点からの予算編成) 分析視点、複数の観点からの考察 AIに質問したところ、上記のような前方修飾語に変換する方法をまとめてもらえました。 では、これをもとに「契約プラン別のユーザ」を英訳してみましょう。 「契約プラン別」というのは、分類・区分に基づく表現です。 そのため、今回のケースでは「based」が適切であると考えられます。 よって、「契約プラン別のユーザ」を英訳したものは ContractPlanBasedUser となります。 このように、中核の関心が後方一致になるように命名することが重要です。 Byは使用できないのか? すべての命名においてByが使用できないのかというと、そうではありません。 あくまでも、関心な名前として語順が崩れる場合に使用できないということに留意してください。 例えば、データベースからユーザIDでユーザを取得してくる関数の名前は getUserByUserId などと命名することが一般的だと思います。 このとき、関心は User であり、 ByUserId は関心ではありません。 したがって、このようなケースではByを使用することができます。 ただし、契約プランIDで契約プラン別のユーザ一覧を取得してくる関数の場合は getContractPlanBasedUsersByContractPlanId となります。 なぜなら、この場合の関心は「契約プラン別のユーザ(一覧)」であり、「契約プラン別」も関心に含まれているためByを避け日本語の語順を保つようにするためです。 後方一致であることのメリット 関心を後方一致でまとめることのメリットは、語順を保つことができる点です。 そして、語順を保つことのメリットは、一貫性と対称性を担保することができる点です。 一貫性 命名における一貫性とは、概念順序規則にしたがっていることです。 概念順序規則とは、「名前の要素を意味のある概念ごとに順序立てて配置する考え方」です。 例えば、 getUserByUserId を概念ごとで分けると get / User / ByUserId となります。 まず、 get は操作(動詞)です。他には、 find や remove 、 create など。 次に、 User は関心です。そして、 ByUserId は方法・条件です。 つまり、データベースの操作というパターンにおいて、その関数名は常に操作 -> 関心 -> 方法・条件という概念順序で命名されるべきであるということです。 この、概念順序規則にしたがって命名されている状態を一貫性が高いと表現します。 もちろん、パターンが異なればその概念順序も異なります。 例えば、コンポーネント名であれば、その概念順序は関心 -> 状況・状態 -> UIの型となります。 ここで重要なのは、同一パターン内では常に一定の概念順序規則にしたがっているという点です。 概念順序規則を遵守することで、命名の一貫性を向上させることができます。 対称性 命名における対称性とは、複数の命名を並べてみたときに、それぞれの概念が対応していることです。 例えば、コンポーネント名における概念順序が関心 -> 状況・状態 -> UIの型のとき、「記事を投稿するフォーム」が ArticlePostForm なら「コメントを投稿するフォーム」は CommentPostForm であるべきということです。 日本語において「コメント」という単語は名詞だけでなく「コメントする」という動詞的な意味も含まれがちですが、それに引っ張られて「コメントを投稿するフォーム」を CommentForm と命名するのは早計かもしれません。 もし、あとから「コメントを編集するフォーム」が必要になった場合、そのコンポーネントは CommentEditForm と命名されるでしょう。ところが、「コメントを投稿するフォーム」は CommentForm と命名されているのです。 これが対称性を崩す要因となります。  あとから類似のものが出てきた際に、対称性が崩れないかに注意して命名しましょう。 まとめ 今回の記事で重要なポイントは以下の4つです。 関心には、「中核の関心」と「補助の関心」が存在する。命名する際は「補助の関心」も含めて表現しきる必要がある 中核の関心が英語名の末尾になるように、日本語の語順のまま英訳する 命名は「操作 -> 関心 -> 条件」や「関心 -> 状況・状態 -> UIの型」など、概念順序規則に従うことで一貫性を保つ。 同じパターンの命名間で構造を揃えることで対称性を実現する。 これらのポイントを意識し、一貫性と対称性が高い命名ができていると、迷いが生じなくなっていきます。 なぜならば、名前自身がどうするべきか教えてくれるようになるからです。 例えば、適切に命名されたディレクトリ構造では、ファイルをどこにいれるべきか、どのようなファイル名・ディレクトリ名にするべきかに迷うことはなくなります。 命名は、コードにコメントを書くことと同様、もしくはそれ以上に「それが一体何なのか・何ではないのか」を説明することができます。 こうして「命名」は「ドキュメンテーションにおける最も基本的な手段」となっていくのです。
アバター
見事統計検定1級で撃沈してしまいました。 そこで2024年の問題で問われた「フィッシャー情報量」「クラメール・ラオの下限」について、整理し、メモを供養します。 ↓2024年統計検定1級 統計数理第1問 統計検定1級の過去問 https://www.toukei-kentei.jp/preparation/kakomon パラメータ推定 パラメータ推定の話を考えます。 母集団から得られたサンプルデータ群から、母集団の平均や標準偏差を推定することをパラメータ推定といいます。 特に、例えば「この母集団の平均値は1.4だ!」などのようにジャストでパラメータを言い当てることを「点推定」といいます。 実際には、実験して得られた標本(実現値)から、パラメータを推定することになるので、点推定は「標本から推定値を得るための関数を作り、その関数に実現値を代入して推定値を求める」ことになります。 数式的には、パラメータ θ を持つ母集団から得られるサンプルを X = ( X 1 , . . . , X n ) とおき、その関数 θ ^ ( X ) を構築します。 実験によって実現値 x = ( x 1 , . . . , x n ) を得られたとき、 θ ^ ( x ) が点推定値となります。 点推定の方法 最尤 さいゆう 推定法(MLE, Maximum Likelihood Estimation) 一番有名な点推定の方法かなと思います。理論上、最も良い推定量を得られることが証明されているようです。 サンプル X = ( X 1 , . . . , X n ) の同時確率関数を、パラメータ θ の関数として、 L ( θ ) = ∏ i = 1 n f ( x i | θ ) とします。つまり、サンプル中のデータ x i すべてに対して、それが得られる確率を計算し、すべて掛け合わせた関数です。 この関数のことを「尤度関数」と呼びます。 この尤度関数を最大にする θ を、最尤推定量(MLE)と呼びます。θ^のようにあらわします。 L ( θ ^ ) = max θ L ( θ ) 例 ある養鶏所にて、採取される卵の重さが正規分布に従うとして、平均値(母平均)と分散(母分散)がそれぞれ未知の値 μ , σ 2 であるとし、 μ を推定するケースを考えます。 n個の卵を採取し、その重さがそれぞれ X 1 , X 2 , . . . , X n だった場合、 L ( μ , σ 2 ) = ∏ i = 1 n N ( X i | μ , σ 2 ) この対数をとって、 μ について微分すると、 ∂ ∂ μ l o g L ( μ , σ 2 ) = − n σ 2 ( μ − n − 1 ∑ i = 1 n X i ) となるため、 μ = 1 n ∑ i = 1 n X i とすると対数尤度が最大になることがわかります。 したがって、標本平均 1 n ∑ i = 1 n X i は μ の最尤推定量となります。 ここで上げた以外にも、「モーメント法」や「ベイズ法」などの推定方法もありますが、 前述の「最尤推定法」が最も精度が良い推定法となります。 クラメールの下限とフィッシャー情報量 点推定における、推定量の「よさ」とはどのようなものでしょうか。 点推定を行うとき、気になるのは、その推定量がどの程度ブレがあるか、というところになると思います。なるべくブレの少ない推定量を使いたいですよね。 この推定量の「ブレ」についてすこし議論してみたいとおもいます。 結論から言うと、最尤推定法による点推定の方法が、最もブレを少なくする方法となります。 これを示すためには、 1.推定量の分散 V a r θ ( θ ^ ) の下限を求める つまり、その母数(母集団のパラメータ)を推定したときに、どこまでブレを抑えられるのかを求める 2.最尤推定量が1. の下限(クラメール・ラオの下限)に一致する この2つを示す必要があります。 1.を示したのが、「クラメール・ラオの不等式」となります。 ・クラメール・ラオの不等式 適当な正則条件のもと、パラメータ θ の推定量 θ ^ = θ ^ ( X 1 , X 2 , . . , X n ) が不偏推定量(実験を繰り返すことにより真値に収束していく推定量)であるとき、次の不等式が任意の θ について成り立つ V a r θ ( θ ^ ) ≥ 1 n I ( θ ) (証明は こちら 参考に) この不等式は、任意の母数 θ に対して、不偏推定量 θ ^ の分散が 1 / n I ( θ ) より小さくならないことを示しており、この右辺の値を「クラメール・ラオの下限」と呼びます。 で、この 式の中に含まれている I(θ)I(θ)が、「フィッシャー情報量」という関数になります。 フィッシャー情報量は、次のような式です。 I ( θ ) = E [ ( d d θ l o g f ( X | θ ) ) 2 ] = ∫ X ( d d θ l o g f ( X | θ ) ) 2 f ( X | θ ) d X (𝓧は𝑿の定義域) つまり、「対数尤度関数をパラメータ変数で微分したやつを2乗した関数の、観測値に関する期待値」 一方、2. のほうは、クラメール・ラオの下限を求めたうえで、最尤推定量の分散がそれに一致することを証明する必要があります。 例 先ほどの例の「卵の重さの平均」の例を考えます。 各データが、独立同一分布に従うとき、 I ( θ ) は、1つのデータについてのフィッシャー情報量を求めればよいので、 先ほどの例の(*)の式で、 n = 1 と置いて、2乗した関数をXについて積分すれば、フィッシャー情報量が求まります。 つまりどういうこと? ここまでくると数式を解釈しての理解は困難ですが、フィッシャー情報量が、クラメール・ラオの下限の分母に来ていることを考えると、 「フィッシャー情報量が大きいほど、推定量の分散を下げられる(ブレを抑えられる)」 といえそうです。 フィッシャー情報量は、「その母数を推定するための情報がどれだけ得られるか」と解釈してよいでしょう。 冒頭の「問1」に関しては、線形単回帰モデルの「回帰係数ββ」の不偏推定量をまず求めないと、フィッシャー情報量やクラメール・ラオの下限の話に行けないという構造になっていますので、どこかで線形単回帰モデルについても触れたいと思っています。
アバター
初めに 2025/4/9から4/11(現地時間)にかけて、Google Cloud Next 25がラスベガスにて開催されました! マイナビからは、企画、データサイエンティスト、エンジニア、マーケターの4名が現地に向かい、参加してきました。 本記事では、Cloud Next 25のイベントの概要や、面白かった内容について、レポート形式でご紹介いたします。 概要編:Cloud Next 25ってどんなイベント? Cloud Nextとは、Google Cloudによって主催される、おもにGoogle Cloudについてのテックカンファレンスです。 毎年、KeyNoteセッションで、GoogleCloudの新しいプロダクトや、新しいコンピューティング技術などが発表されます。KeyNoteが世界で初めてその内容を知ることができる場所であり、毎年異様な盛り上がりを見せます。 KeyNote以外には、Google Cloudを利用している企業から、利用事例についてのプレゼンテーションであるBreakout Sessionや、Google Cloudの技術ノウハウをライトに共有する場であるLightning Talk、Cloud Skills Boostの体験や、デモを実際にさわりながらGoogle Cloudを学ぶことができるハンズオンのコーナー、ほかの参加者と交流ができるMeetup、実際にGoogler(Google社員)やGoogle Cloudのカスタマー企業にデモを見せてもらいながら、ノウハウを教えてもらったり技術交流ができるExpoがありました。 会場 会場となったMandalay Bayのコンベンションセンターですが、とにかく大きな会場でした。 1日中あちこちでセッションを聞いていると、気づいたら4万歩ぐらい歩いていました。 参加レポート KeyNote 会場に入ると、そこはライブ会場のよう。 基調講演の前には、VeoVJによるパフォーマンスで出迎えてくれました。 Veoによって生成された映像を、曲に合わせて選択して流してくれるAI、ということでしょうか。 Veo を使ったメディア制作のデモをKeyNote中で実施してくれています。 →  https://www.youtube.com/live/Md4Fs-Zc3tg?si=qDTeEgSNU2cG8Q9o&t=1996 セッションの具体的な内容については、すでに様々なブログで触れられているのですが、主な内容としては 動画生成AI「Veo 2」、作曲AI「Lyria」の公開 新TPU「Ironwood」 Agentspace データエージェント このあたりのアップデートがとても大きかったと思います。 内容について少し触れます。 Veo 2 Veo 2は、Google DeepMind社によって開発された、動画生成AIです。 Next以前からVeoに関する発表は2024/11月にあったのですが、この日をもってGAとなり、 Vertex AI Media Studio から利用できるようになりました。 映像生成については、DeepMind社の公式サイトからプロンプトと生成された映像のサンプルを確認できます。 https://deepmind.google/technologies/veo/veo-2/ 中でもすごいと思ったのは、2枚の写真を用意すると、その間を補間するように映像を生成する、というものでした。 ( 参考動画 ) これはすごいですね!映像編集の幅が広がりそうです。 Lyria こちらもDeepMind社の開発した音楽生成AIです。 プロンプトを入力すると、30秒ほどの音楽が生成されます。 なんとボーカルも入れられるそうです。 公式サイトから、プロンプトとそれによって生成された音楽が視聴可能です。 https://deepmind.google/technologies/lyria/ もはや人の作ったものと区別がつかなくなってきていますね・・・! なお、前述のVeoや、音声合成AIのChirp 3、画像生成AIのImagen 3と合わせて、 Vertex AI Media Studio というプロダクトから利用可能となっています。 Google I/Oでさらに上位モデルが登場 これらのマルチモーダル生成AIのうち、Veo, Imagen, Lyriaに関しては、すでに新しいバージョンのモデルが発表されています。 Veo 3 Imagen 4 Lyria 2 Next 25の開催からなんとたった1か月後にこれらのアナウンス。。AIの進展の速さを肌身で感じます。 参考記事⇒  Google Cloud 公式ブログ Ironwood Ironwoodは、Google社によって開発中の第7世代TPUの名称で、 2025年末にはリリースされる予定とのことでした。 これは初代のTPUと比べて3600倍のパフォーマンス向上です。 ひとつ前のモデルと比べても900倍近く向上しています。 これは劇的な進化ですね。 KeyNoteでIronwoodに触れられているシーンは こちら です。 Agentspace Agentspaceは、自社で利用しているオフィススイート(MS OfficeやGoogle Workspace, Salesforceなど)のツールと結合可能なAIエージェントのインタフェースです。 AIエージェントは、Googleが提供するもの以外にも自社内で作成され共有されたものも、Agentspaceから利用できます。 自社組織の意思決定の内容について、SharePointやGoogleDriveにある資料を探すのは大変だと思いますが、 Agentspaceで質問すると、SharepointやGoogleDriveに散乱する資料の中から情報を抽出してユーザーに回答してくれます。 生成された回答の内容のもととなった資料も示してくれます。 デモの中では、リクエストの内容によって、エンタープライズデータ、時系列予測モデル、音声合成、メール送信など多くのツールを利用していますが、すべてAgentspace経由で、1行もコードを書いていません。 Agentspaceを使ったデモンストレーションのシーンは こちら になります。 メールや要約内容については、妥当性を自分で確認する必要はありますが、ノーコードで多くのエージェントツールにアクセスできるようになり、文面作成など多くの手間のかかるシーンで活躍することが期待できます。 データエージェント データクレンジングやインサイト抽出がGeminiによって強化された「Data Agent」の紹介です。 これまでは、まずBigQueryにデータを定期的に連携し、扱いやすい形(データマート)に変換し、 抽出したいインサイトを得るためのクエリをガシガシと書いて、実行していたと思います。 この作業で大変なことは、まず複数のデータソースに散らばっているデータを結合やクレンジングし、分析に使用できる状態にするところ。 ここで活躍するのが「Data Engineering Agent」で、プロンプトベースでデータ処理パイプライン構築していくことができます。 編集中のパイプラインの結果を逐一確認しながら構築を進めていくことができます。 日付の表記もばらばらになっていますが、動画を見るとこの名寄せに関しても直してくれています。これはありがたいですね。 使っているプロダクトとしては少し前からGAになっていた「BigQuery パイプライン」というものなのですが、その構築をGeminiが支援してくれるというものですね。 また、インサイト抽出に関しても、プロンプトでどんなインサイトを抽出したいかをリクエストすると、Geminiがクエリの生成とクエリの実行をしてくれます。 クエリの内容は、カラム名などのメタ情報から生成しているようでした。 実際は、クエリの内容や可視化内容が正しいことに関しては、分析者が最終的にレビューをする必要がありますが、 クエリを作成する時間がこれによって大きく節約できることや、クエリを書くことへの技術的ハードルが大きく下げられることが期待できます。 Data Agentの紹介シーンは こちら です。 Expo Expoでは、KeyNoteで発表のあった新しいサービスのデモを、実際にGoogle社員の方に実演してもらったり直接質問ができるコーナーがありました。 デモのご紹介: GeminiとVertex AI Searchによるマルチモーダル検索 スマホで部屋の写真を撮って、「この部屋に合う家具を探して」という検索方法であったり、もちろん音声検索も対応。 1回検索を実行した後、元のクエリから拡張されたクエリで再検索し、そのアイテムも表示する、ということもやっていました。 こちらはYouTubeでデモ映像が公開されていました。 https://youtu.be/LwHPYyw7u6U?si=vOtgUrk9yK_F4Uqf Meetup Cloud Nextの楽しみ方の一つとして、ほかのエンジニアの交流があります。 そのひとつが Meetup というもので、Cloud RunやVertex AIなどのプロダクトについてのものであったり、Platform EngineeringやObservabilityなど、ホットなトピックについてエンジニアが熱い意見を交わすというもの。 非常に貴重な経験でした。 全体を通して 全体的な感想として、AIやコンピューティングの分野における技術巣発展スピードは非常に早いと思いました。 Veoのアップデートの件でも触れましたが、1年前の技術が今年はレガシーになっているような世界です。 こういった新しい技術は、簡単に試せるようなものも多いので、自社サービスや業務フローに取り入れることを検討してみてもよいかもしれません。 終わりに 本イベントでの内容を踏まえて、マイナビでIT職の仕事をしている社員向けにデモを交えた共有会を開いたところ、80名以上の参加がありました! 実際に使ってみたい、自身の業務の中で取り入れてみたい、などの声もいただいた一方で、 業務での活かし方がわからないといった意見もありました。 こういった視察活動を続けていくことで、少しずつAI活用の輪を広げていけるのではないかな、と感じた次第です。 また、来年も4月末に、ラスベガスでCloud Nextを開催するとのことでした。 会場も同じMandalay Bay Convention Centerです。 もし興味を持たれた方は、ぜひ参加してみてください!
アバター
はじめに 今話題のMCPですが、WebデザインやUIデザイン向けツールのFigmaでもMCPが公開されました。 本記事では、下記をメイン書いています FigmaMCPを利用できるまで 簡単チュートリアル MCPとは AIモデルと外部サービス(システム)を連携するための「共通ルール(プロトコル)」です。 各社がこのルールに沿った「AI専用コントローラー(MCPサーバー)」を提供し、AIアプリ開発者(MCPクライアント)はそれを呼び出すだけで各種サービスと連携可能になります。 これにより、様々なサービスをAIエージェントで操作できるようになります。 FigmaMCPとは AI が Figma のデザインデータに直接アクセスし、そのデータを理解・操作することができるようになります。 実際に、Figmaはこの辺りを参照するようです。 デザイン情報 (色・フォント・サイズ・間隔 etc..) コンポーネント間の関係 Figma内のコメント この辺りが参照できると今までできなかった下記タスクもAIにお願いできるようになりそうです。 Figmaのデザインをより忠実に再現 レスポンシブ対応 コンポーネント関係の解釈 ( 参考 Figma MCPとは?何ができるの? ) 利用できるまでの作業 本手順は、github copilot でFigmaMCPを導入する手順です。 ①個人のアカウントでFigmaのAccount settingsを開く ②トークン発行 security>Personal access tokens>Generate new token token名を入力 → File content を read-only にする → Generate token ③MCPの設定をvscodeで行う vscodeの設定用のjsonを修正します。 mcp.servers の中に下記の設定を追記します。 "mcp": { "inputs": [], "servers": { "figma-developer-mcp": { "command": "npx", "args": [ "-y", "figma-developer-mcp", "--figma-api-key=${③のトークン}", "--stdio" ] } } " mcp " : { " inputs " : [] , " servers " : { " figma-developer-mcp " : { " command " : " npx " , " args " : [ " -y " , " figma-developer-mcp " , " --figma-api-key=${③のトークン} " , " --stdio " ] } } ④vscode の github copilotのエージェントモードを有効にする vscodeの設定から chat > Agent: Enabled を有効にする (出てこない場合は、アップデート&再起動をする) ⑤github copilotをエージェントモードに変更する github copilotのチャットを開き、エージェントモードに変更する 以上です!これで利用できるようになります。 試しにコンポーネントを出力してもらう 今回は、簡単なカードコンポーネントを出力してもらいます。 ①FigmaからフレームのURLを取得します。 該当フレームを選択しながら、右上のシェアボタンを教えて、コピーします。 ②実際に書いててもらう 今回はこんなプロンプトで指示してみました figmaを参照して、カードコンポーネントを作成してください・外部からプロップスを渡せるようにしてください。・tailwindで実装してください・セマンティックなHTMLを心がけてください。card component:https://www.figma.com/design/.... figmaを参照して 、 カードコンポーネントを作成してください ・ 外部からプロップスを渡せるようにしてください 。 ・ tailwindで実装してください ・ セマンティックなHTMLを心がけてください 。 card component : https : //www.figma.com/design/.... Figmaを参照するか聞かれますが、続行してください。 気になる出力結果は... かなり高クオリティーです... ! タグの絶対配置の部分だけ設定されていませんね (出力している感じ、絶対配置はあまり得意でないように見えます) コードベースで見るとこんな感じです。 プロップスも想定通り渡せるようになっていたり、HTMLタグの使い分けもいい感じにできていて、ほぼ期待通りの実装に見えます。 import type { FC } from 'react';interface CardProps { image: string; tags: string[]; title: string; description: string; onClickDetail: () => void;}export const Card: FC<CardProps> = ({ image, tags, title, description, onClickDetail,}) => { return ( <article className="flex flex-col bg-white border border-[rgba(17,17,17,0.1)] rounded-2xl overflow-hidden"> <div className="relative aspect-video"> <img src={image} alt="" className="w-full h-full object-cover" /> </div> <div className="flex flex-col justify-between p-6 flex-1"> <div className="space-y-4"> <div className="flex gap-2.5 flex-wrap"> {tags.map((tag, index) => ( <span key={index} className="px-4 py-3 text-sm font-bold text-[#111111] border-2 border-[rgba(17,17,17,0.1)] rounded-full" > {tag} </span> ))} </div> <div className="space-y-2"> <h3 className="text-lg font-bold text-[#111111] leading-[1.3]"> {title} </h3> <p className="text-base text-[#111111] leading-6"> {description} </p> </div> </div> <button onClick={onClickDetail} className="w-full mt-4 px-6 py-4 text-sm font-bold text-[#111111] border-2 border-[rgba(17,17,17,0.1)] rounded-xl" > 詳しくみる </button> </div> </article> );}; import type { FC } from ' react ' ; interface CardProps { image : string; tags : string [] ; title : string; description : string; onClickDetail : () => void; } export const Card : FC < CardProps > = ( { image , tags , title , description , onClickDetail , } ) => { return ( <article className = " flex flex-col bg-white border border-[rgba(17,17,17,0.1)] rounded-2xl overflow-hidden " > <div className = " relative aspect-video " > <img src ={ image } alt = "" className = " w-full h-full object-cover " /> </div> <div className = " flex flex-col justify-between p-6 flex-1 " > <div className = " space-y-4 " > <div className = " flex gap-2.5 flex-wrap " > { tags . map ( ( tag , index ) => ( <span key ={ index } className = " px-4 py-3 text-sm font-bold text-[#111111] border-2 border-[rgba(17,17,17,0.1)] rounded-full " > { tag } </span> )) } </div> <div className = " space-y-2 " > <h3 className = " text-lg font-bold text-[#111111] leading-[1.3] " > { title } </h3> <p className = " text-base text-[#111111] leading-6 " > { description } </p> </div> </div> <button onClick ={ onClickDetail } className = " w-full mt-4 px-6 py-4 text-sm font-bold text-[#111111] border-2 border-[rgba(17,17,17,0.1)] rounded-xl " > 詳しくみる </button> </div> </article> ) ; } ; まとめ 今のところの感想としては、LovableやReplitの各種AIツール や Figma to Codeなどのコード生成系のFigmaプラグイン と比較して、精度がはるかに高いように見えます...! 今回は、FigmaMCPの使い方 + チュートリアルをやってみましたが、次回はもう少し高難易度の出力や、他ツールとの比較とかもやってみようと思います!
アバター