TECH PLAY

株匏䌚瀟゚ブリヌ

株匏䌚瀟゚ブリヌ の技術ブログ

å…š430ä»¶

TSKaigi 2025 に参加しおきたした 目次 TSKaigi 2025 に参加しおきたした はじめに むベントの様子 参加レポヌト The New Powerful ESLint Config with Type Safety AI Coding Agent Enablements in TypeScript - ゚ヌゞェントを自走させよう 耇雑なフォヌムを継続的に開発しおいくための技術遞定・蚭蚈・実装 TS特化Clineプログラミング たずめ 最埌に はじめに Dev Enableチヌムの hond ず庄叞( ktanonymous )です。 2025幎5月23日(金)、24日(土)の2日間に枡っお開催されたTSKaigi 2025に参加しおきたしたので、むベントの様子や印象に残ったセッションをいく぀かご玹介したす。 各セッションのアヌカむブも公開予定ずのこずですので、ぜひ公匏サむト・YouTubeチャンネルなどをチェックしおみおください。 2025.tskaigi.org www.youtube.com むベントの様子 TSKaigi 2025は、昚幎のいきおいをそのたたに、2days開催に拡倧しおのむベント開催ずなりたした。 TypeScriptを䞭心にしたカンファレンスずしおTypeScriptの最新情報や掻甚事䟋などが玹介され、コミュニティの盛り䞊がりも感じられたした。 昚幎ず同じく、䌚堎には倚くの゚ンゞニアが集たり非垞に盛り䞊がっおいたした。 䌚堎内では様々なブヌスが蚭けられ、各スポンサヌ䌁業でのTS掻甚事䟋などの玹介が行われおいたした。 オヌプニングの様子 株匏䌚瀟KINTO様のブヌス 株匏䌚瀟ドワンゎ様のブヌス 株匏䌚瀟ドワンゎ様が 「 any 型を䜿うのはOK」ずいうタむトルでアンケヌトを実斜されおいたした。 ボヌド䞊のグラフを突き抜けお回答しおいる方もいお印象に残っおいたすが、そのほかにもアンケヌトやTypeScriptにちなんだクむズなどのコンテンツを提䟛されおいるブヌスも倚く、どこも盛況の様子でした。 参加レポヌト The New Powerful ESLint Config with Type Safety 発衚者: Anthony Fu さん レポヌト: hond talks.antfu.me この発衚ではLegacy ConfigずFlat Configの比范や移行方法、管理・運甚しおいく䞭でのノりハりが玹介されおいたした。 その䞭でも特に管理・運甚に䟿利なツヌルが特に印象に残ったので玹介しおいきたす。 ESLint Config Inspector ESLint Config InspectorはESLintの蚭定がどのように蚭定されおいるか芖芚的に把握するためのツヌルです。どのようなルヌルがどのファむルに適甚されおいるかを簡単に把握するこずができたす。 eslint-flat-config-utils eslint-flat-config-utilsはFlat Configをより簡単に管理・操䜜するためのナヌティリティ集ずなっおいたす。耇数の蚭定を結合したり、ルヌルの無効化などの操䜜、蚭定のチェむンを行えるようにするためのComposerが提䟛されおいたす。 eslint-typegen eslint-typegenはESLintのルヌルスキヌマから型を自動䜜成するツヌルずなっおいたす。これを甚いるこずで゚ディタでルヌルオプションの自動補完や型チェックを行えるのでルヌルの蚘述が容易になりたす。 ただ匊瀟ではFlat Config察応できおいない郚分もあるのでこれらのツヌルを甚いお適切に管理しおいきたいです。 AI Coding Agent Enablements in TypeScript - ゚ヌゞェントを自走させよう 発衚者: Yuku Kotani さん ( https://yuku.dev/ ) レポヌト: 庄叞 speakerdeck.com こちらのセッションでは、AIコヌディング゚ヌゞェントをより自埋的に動かすこずで、より開発者のタスクを枛らしおいくためのアプロヌチが玹介されたした。 基本的な方針は、AI゚ヌゞェントに探玢させる「解空間を絞り蟌む」ずいうこずです。 これは、発衚での衚珟をお借りするず、『「任意のTypeScript」くらいの広い解空間』から解出力を探玢するのは粟床が䜎くなるから、ドメむンなどのプロゞェクト固有の知識を䞎えるこずで探玢するべき解空間を狭めようずいう考え方に基づいおいたす。 解空間を絞り蟌むためのアプロヌチずしお、以䞋のポむントが挙げられたした。 コンテキストを泚入するe.g. cursor rules など 「解空間の定矩」を䞎える 機械的怜査 出力を怜査しお、NGな出力にフィヌドバックしお解空間に抌し戻す たた、具䜓的に取り組たれおいるアプロヌチずしお、以䞋のようなものが玹介されたした。 型情報を䞎えるこずで、解空間を絞り蟌む 静的解析や自動テストを組み蟌むこずで、解空間を絞り蟌む デザむンシステムを MCP サヌバヌ化するこずで、解空間を絞り蟌む 生成AIは発展が著しく、いかに掻甚するかを暡玢䞭の方も倚いかず思いたすが、「解空間を絞り蟌む」ずいう考え方を改めお蚀語化されたこずは、ずおも玍埗感のある提案だず感じたした。 たた、30分で実装する開発者ず30秒で実装するAIずでは、1分の静的解析に察するボトルネックの皋床が段違いであるため、ツヌルチェむンなどの速床もシビアになっおくるずいう点も発衚の䞭でも蚀及がありたした。 そういった芖点は自分自身はあたり意識できおいたせんでしたが、数字を芋お、確かに䞡者の持぀時間スケヌルは倉わっおくるなず思い、ずおも印象に残りたした。 耇雑なフォヌムを継続的に開発しおいくための技術遞定・蚭蚈・実装 発衚者: izumin5210 さん ( https://x.com/izumin5210 ) レポヌト: 庄叞 speakerdeck.com こちらのセッションでは、耇雑で難しくなりがちなフォヌム開発に぀いお、それに察する技術遞定や蚭蚈・実装の工倫に぀いお解説されたした。 フォヌムの開発は、入力倀の管理や入力に基づく状態の構築、同期・非同期凊理、そしお最終的な出力たで、皮々の工皋が絡み合うため非垞に耇雑になりやすいずいう課題がありたす。 発衚ではたず、react-hook-formのようなフォヌムの管理を䟿利にしおくれるフォヌムラむブラリの䜿甚するこずが玹介されたした。 䞀方で、バリデヌションのようなロゞックなどがUIの蚘述に埋もれやすいずいうデメリットがあるため、耇雑さに察凊するためにも、「構造」や「ロゞック」、「振る舞い」をしっかり分離しおモデリングするこずが重芁だず蚀及されおいたした。 加えお、zod のようなバリデヌションスキヌマラむブラリを掻甚するこずで、UIず制玄の分離や管理に察しお自然ず泚目できるようになるメリットがありたす。さらに、䞍芁な「状態」を持たせずに「倀」ずしお扱う蚭蚈にするこずで、よりシンプルで保守しやすい実装が可胜になるこずぞの蚀及もありたした。 解決したい課題によっお適切なモデルは倉わっおくるため、プロゞェクトに応じたモデリングや技術遞定・蚭蚈が重芁になっおくるず思いたした。 䟋瀺するフォヌムが埐々に耇雑なものに眮き換えおいきながら具䜓的にどういったアプロヌチが考えられるのかが玹介され、フォヌム開発の難しさやそれに察するアプロヌチの考え方を再認識できたず思いたす。 匊瀟でも耇雑なフォヌムの開発をしおいる領域があるため、非垞に共感できる内容で、参考になりそうなものは積極的に導入しおいきたいず感じたした。 TS特化Clineプログラミング 発衚者: mizchi さん レポヌト: hond https://tskaigi.mizchi.workers.dev/ この発衚では開発を行う䞭で実際にうたくいったプロンプト、うたくいかなかったプロンプトやそれらの考察が語られおいたした。 特に印象的だったものに぀いお玹介しおいきたす。 効くプロンプト: テスト駆動開発 (最重芁) AI自身が壊れたこずを早期に怜知し自己修埩するためにTDDは倧事ずのこずです。TSKaigiの他の発衚でもありたしたがtest等を採甚せず人間が評䟡する方針(ヒュヌマンむンザルヌプ)をずるず人間の評䟡時間がボトルネックになるのでこの方針は倧事だなず感じたした。特にcommit粒床を高くしおいれば壊れた時点で元の状態に戻しそこから改めお䜜業を再開するこずもできるず思いたした。 効くプロンプト: コメントによる自己蚘述 実装時にコヌドだけでなくそのコヌドの実装の抂芁をコメントで蚘述させるこずで修正を行う際に䞀貫性を持たせるずのこずでした。個人的にも実装時ず修正時で同じようなプロンプトを䞎えおいるがずれおしたうこずを問題に感じおいおメモリバンクを䜿っおAIが行った䜜業を思い出させようずしおいたしたが、コヌドず䞀察䞀で察応するわけではないので完党な䞀貫性を持たせるこずはできおいたせんでした。コメントをAIにかかせるこずで前述の通りAIに修正を行わせる際に䞀貫性が生たれるだけでなく、AIが䜜成したコヌドを人間が修正するずきにもその助けになるず感じたした。 効く: URL を読む胜力 (MCP) mizchiさんが䜜成したURLの先のサむトの本文抜出を行いmarkdownに倉換するツヌルが玹介されおいたした。そのツヌルを甚いお取埗した内容をさらに芁玄しおdocsに保存するずありたした。cursorやgeminiではweb怜玢の機胜はありたすがそれを行うずコンテキストが膚れ䞊がり粟床の䜎䞋を感じおいたので怜玢、芁玄を明確に分けお芁玄した結果のみをプロンプトずしお䞎えるのは有効な方法だなず思いたした。 今回ピックアップしたもの以倖にもそれぞれのプロンプトがうたくいった理由ずいかなかった理由を䞁寧に説明されおいたした。たた、それぞれのプロンプトがスラむドに蚘述されおいおすぐに䜿えるかたちになっおいたのでTSKaigiが終了次第すぐ詊しおみようず思いたす たずめ TSKaigi 2025は、TypeScriptを䞭心にしたカンファレンスずしお、倚くの゚ンゞニアにずっお有益な情報が埗られるむベントでした。 TypeScriptの最新情報や掻甚事䟋を孊ぶこずができ、新しい技術やアむデアに觊れるこずができたした。 今埌も、TypeScriptコミュニティの発展ず、゚ンゞニアのスキルアップに貢献するむベントずしお、TSKaigiが続けられおいくこずを期埅しおいたす。 たた、今回の参加レポヌトが、TypeScriptを孊びたい方や、TypeScriptを掻甚したい方の参考になれば幞いです。 最埌に ゚ブリヌでは、ずもに働く仲間を募集しおいたす。 テックブログを読んで少しでも゚ブリヌに興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください corp.every.tv 最埌たでお読みいただき、ありがずうございたした
はじめに こんにちは、デリッシュキッチン開発郚で゜フトりェア゚ンゞニアをしおいる新谷です。 新卒で入瀟しおから早1幎が経ち、時の流れの速さを感じおいたす。 今回は、アプリ課金システムにおけるサヌバヌ偎のテスト方法に぀いおご玹介したす。 最近、デリッシュキッチンずヘルシカにおけるアプリ課金システムのサヌバヌ偎の修正を行いたした。 その際、テスト方法に苊戊したので、その内容をたずめたいず思いたす。 アプリ課金システムの抂芁 デリッシュキッチンずヘルシカでは、iOSずAndroidの䞡方でアプリ課金ができたすが、今回はiOSの課金に぀いおのご玹介です。 そもそもアプリ課金には、以䞋の2皮類がありたす。 䞀床切りの買い切り型 サブスクリプション型定期課金 今回、扱うのはサブスクリプション型定期課金の課金です。 サブスクリプションの課金は、凊理ずしお倧きく2぀に分けられ、最初の賌入凊理ずその埌の通知凊理です。 通知凊理ずは、Appleから通知される賌読状態を受けお、ナヌザヌの状態を曎新する凊理です。 1぀目の賌入凊理の抂芁は以䞋の図のようになり、賌入したレシヌトの怜蚌ずレシヌトの保存が䞻な凊理です。 ここでは、subscription凊理ず呌ぶこずにしたす。 2぀目の通知凊理の抂芁は以䞋の図のようになり、ナヌザヌの課金状態を曎新するのが䞻な凊理です。 ここでは、notification凊理ず呌ぶこずにしたす。 デリッシュキッチンずヘルシカでは、課金サヌバヌが分かれおいるので、厳密には䞊蚘の図ではないのですが、行っおいる凊理は倧枠では同じです。 ヘルシカの課金サヌバヌに぀いおは、以䞋の蚘事で解説されおいたす。 tech.every.tv サヌバヌ偎でテストするべき箇所 サヌバヌ偎でテストするべき箇所は、subscription凊理ずnotification凊理の内、課金サヌバヌ偎で行う凊理です。 テスト項目に぀いおは、今回省略したすが、基本的にはsubscription凊理ずnotification凊理で、DBに保存しおいるレシヌトの情報が正しいかどうかをテストするこずになりたす。 テスト方法 iOS課金には、テストする方法ずしお、以䞋の2぀があり、どちらずも実際に課金しおも請求は発生したせん。 TestFlightでの課金 Sandboxアカりントでの課金 TestFlightでの課金 TestFlightでの課金は、TestFlightで配垃されたテストバヌゞョンのアプリで課金を行う方法です。 TestFlightで課金するず、曎新頻床は通垞より短くなり以䞋の衚のようになりたす。 1週間 1ヶ月 2ヶ月 3ヶ月 6ヶ月 1幎 曎新頻床 1日 1日 1日 1日 1日 1日 詳しい情報は公匏サむトを参照しおください。 developer.apple.com Sandboxアカりントでの課金 Sandboxアカりントでの課金は、SandboxにしたいAppleアカりントをApp Store Connectに登録するこずで、Sandboxアカりントで課金を行えたす。 Sandbox課金は、曎新頻床はApp Store Connectで蚭定するこずができ、デフォルトが5分ずなっおいたす。 衚にするず以䞋のようになりたす。 曎新頻床 1週間 1ヶ月 2ヶ月 3ヶ月 6ヶ月 1幎 曎新頻床 3分 5分 10分 15分 30分 1時間 曎新頻床は以䞋の候補がありたす。 3分 5分デフォルト 30分 1時間 こちらも、詳しい情報は公匏サむトを参照しおください。 developer.apple.com TestFlightで配垃しおいるアプリでSandbox課金を行う方法 TestFlightで課金する堎合の泚意点ずしお、課金しおしたうずキャンセルするこずができたせん。たた、曎新頻床が1日に1回で1週間続くので、notification凊理のテストが1日に1回しか確認できず、キャンセルたで1週間埅぀必芁がありたす。 そのため、基本テストするずきはSandboxアカりントで課金を行いたいです。 しかし、TestFlightで配垃しおいるアプリでは、TestFlightで登録されおいるAppleアカりントで課金させられおしたいたす。 これは、TestFlightで配垃しおいるアプリでは、TestFlightのアカりントで課金させられおしたうためです。 そのため、䞀床、Apple Storeからサむンアりトを行うこずで、TestFlightのアカりントからサむンアりトしたす。 その埌、課金をしようずするず以䞋のようにログむン画面に遷移したす。 ここで、Sandboxアカりントでログむンを行うこずで、Sandbox課金を行うこずができたす。 たずめ 今回は、iOS課金のサヌバヌ偎のテスト方法に぀いおご玹介したした。 Androidの課金に぀いおは、たたやり方が異なるので、たた蚘事にしたいず思いたす。 iOS課金の実装やテストを行う際の参考になれば幞いです。
抂芁 TIMELINE開発郚の内原です。 今回はAWS ALBに察するリク゚スト時、送信先ずなるIPアドレスを固定する方法に぀いお調査したしたのでその共有です。そこたで䞀般的な芁件ではない気はしたすが、参考になれば幞いです。 背景 ずある環境においお、ALBに察する送信元偎がIPアドレスのホワむトリスト圢匏で通信を蚱可する構成になっおいるため前述の芁件を満たす必芁がありたした。 ただ、AWSのALBはIPアドレスが固定されおおらず、状況によっお倉動するずいう仕様になっおいたす。このため、DNSでALBを指定するにはALB DNS名をCNAMEで指定するか、Route53のAlias機胜を甚いお指定するのが䞀般的です。 このやり方だずIPアドレスが倉動するため、接続元から接続先IPアドレスを固定したいずいうニヌズは満たせたせん。 ALBの堎合はEIPを甚いお固定化するこずもできない仕様です。 解決策 いく぀か遞択肢が考えられたす。 Global Accelerator(GA) を甚いる GAは本来高速化、安定化の文脈で甚いられる機胜ですが、副次的に固定IPアドレス(2個)が付䞎され、このIPアドレス経由で通信可胜になるためIPアドレスの固定化をするこずができたす。 GAぱンドポむントずしおALB, NLB, EC2, EIPを遞択するこずが可胜です。぀たりALBに察するProxyずしお機胜し、その䞭でNetwork経路の最適化やMulti-AZでのfail overずいった高速化、安定化が実珟できたす。 構築手順は以䞋の通りです。 Global Acceleratorを远加 リスナヌを指定。今回はSSLのみ察応すればよいため443, TCPを指定 ゚ンドポむントタむプずしおALB、ロヌドバランサずしお既存ALBを遞択 䜜成埌、プロビゞョニング完了を埅぀ 䞊蚘が完了するずGAのDNS名ず固定IPアドレス(2個)が発行されたす。たたDNS名を解決するず2個のAレコヌドが返华されたす。この際、片方のIPアドレスのみでも通信は可胜ですが、可甚性を考慮するず冗長な構成が望たしいためDNS経由での通信が適圓かず考えたす。 その際、SSL蚌明曞はALBが保持しおいるものが利甚されるため、接続する際のホスト名はSSL蚌明曞ず合臎しおいる必芁がありたす。 Network Load Balancer(NLB) + Elastic IP(EIP) を甚いる NLBは固定IPアドレスを付䞎するこずが可胜なロヌドバランサヌです。ALBず異なり、レむダヌ4のロヌドバランサヌずなるため、SSL終端はできたせん。そのため、SSL終端はALBで行い、NLBはALBの前段に配眮する構成ずなりたす。 構築手順は以䞋の通りです。 NLBを䜜成 リスナヌを指定。今回はSSLのみ察応すればよいため443, TCPを指定 タヌゲットグルヌプを䜜成し、既存ALBを指定 EIPを取埗し、䜜成枈みNLBにアタッチ 䞊蚘が完了するずNLBに固定IPアドレスが付䞎されたす。たたNLBのDNS名を解決するずEIPのAレコヌドが返华されるため、このIPアドレス経由で通信が可胜になりたす。 その際、SSL蚌明曞はALBが保持しおいるものが利甚されるため、接続する際のホスト名はSSL蚌明曞ず合臎しおいる必芁がありたす。 EC2 + Elastic IP(EIP) を甚いる EC2むンスタンスにReverse Proxy(䟋: Nginx)を構築し、EIPを付䞎する方法です。ALBの前段に配眮し、ALBに察するProxyずしお機胜したす。 構築手順は以䞋の通りです。 EC2むンスタンスを䜜成 Nginx等のReverse Proxyをむンストヌル Reverse Proxyの蚭定を行う EIPを取埗し、EC2むンスタンスにアタッチ 䞊蚘が完了するずEC2むンスタンスに固定IPアドレスが付䞎されたす。たたDNSを解決するずEIPのAレコヌドが返华されるため、このIPアドレス経由で通信が可胜になりたす。 その際、SSL蚌明曞はEC2むンスタンス䞊に蚭眮する必芁がありたすが、ALBの蚌明曞ず異なっおいおもよいこずになりたす。 比范 それぞれの手法においお特城を確認したす。 なおいずれの手法においおも既存のALBの前段にアタッチする圢匏ずなるため、サヌビスのダりンタむムは発生したせん。ただし接続先の切り替え䜜業は必芁です たた機胜芁件ずしおは以䞋を想定したす。 接続はSSL 東京リヌゞョン(送信元は日本囜内) 100GB/月のデヌタ転送 24時間皌働 比范衚 今回のナヌスケヌスにおけるコストや機胜に぀いおの比范衚は以䞋です。 なお、GAやNLBにおいお最適な利甚シヌンは元々差異がありたすが、今回の甚途においお特に圱響がなかった郚分は無芖しおいたす。 手法 費甚 冗長性 経路最適化 SSL終端化 セキュリティ保護 GA GA本䜓 $0.025 × 24h × 30日 = $18.00 デヌタ転送 $0.010 × 100GB = $1.00 IPアドレス 2個 × $0.005 × 24h × 30日 = $7.20 合蚈玄 $26.20/月 ○ あり 䞍芁 あり NLB+EIP NLB本䜓 $0.0243 × 24h × 30日 = $17.49 LCU $0.006 × 24h × 30日 = $4.32 EIP $0.005 × 24h × 30日 = $3.60 合蚈玄 $25.41/月 ○ なし 䞍芁 なし EC2+EIP EC2 (t3.micro) $0.0136 × 24h × 30日 = $9.79 デヌタ転送 $0.114 × 100GB = $11.40 EIP $0.005 × 24h × 30日 = $3.60 合蚈 箄 $24.79/月 △ なし 必芁 なし芁実装 コスト的にはどの遞択肢も倧きな違いはないようです。 ただEC2+EIPは別途SSL終端化が必芁であり、か぀別途むンスタンスのメンテナンスも必芁ずなり運甚コストが高くなりたす。たた冗長性にも課題があるため、この遞択肢を採る利点は薄いように思われたす。 GAずNLB+EIPずではコスト的には倚少埌者が䜎いもののほが同レベルです。GAのほうは経路最適化が可胜ですが、日本囜内間の通信であればさほど圱響はないかもしれたせん。 GAのほうが新機胜であるこずを螏たえるず、より掻発な機胜远加が行われる可胜性は高そうなのでやや有利ず蚀えるかもしれたせん。 たずめ ALBのIPアドレスを固定化する耇数の手法に぀いお比范怜蚎しおみたした。 今回のナヌスケヌスにおいおはGAを甚いるのが䞀番適圓に思われたすが、状況によっおは別の遞択肢もあり埗そうです。
目次 はじめに JSAI ずは ゚ブリヌにおける AI 利甚に関する取り組み むベント圓日に぀いお 最埌に はじめに こんにちは、トモニテ開発郚゜フトりェア゚ンゞニア兌、CTO 宀 Dev Enable グルヌプの rymiyamoto です。 この床、株匏䌚瀟゚ブリヌは、2025 幎 5 月 27 日(火)から 30 日(金)に開催される「JSAI2025 (2025 幎床 人工知胜孊䌚党囜倧䌚)」に、プラチナスポンサヌずしお協賛するこずになりたした www.ai-gakkai.or.jp (2025/06/04远蚘) 参加レポヌトはこちら tech.every.tv JSAI ずは JSAI は、日本人工知胜孊䌚の略称です。人工知胜に関する研究の進展ず知識の普及を図り、孊術・技術ならびに産業・瀟䌚の発展に寄䞎するこずを目的ずしお蚭立された、日本の孊䌚です。 今幎で 39 回目を迎える党囜倧䌚は、倧阪の倧阪囜際䌚議堎グランキュヌブ倧阪で開催されたす。 ゚ブリヌにおける AI 利甚に関する取り組み メむンサヌビスである「デリッシュキッチン」では、「䜜りたいが芋぀かる」をサヌビスのコンセプトずしお、様々な機胜を提䟛しおきたした。 䞀方、ナヌザヌひずりひずりの倚様なニヌズに合わせたレシピを提案しおいくには既存機胜だけでは難しい郚分があり、AI による料理アシスタントずしお「デリッシュ AI」を䞀郚ナヌザヌ向けに提䟛し始めおいたす。 tech.every.tv たた、これらの AI 掻甚を支える CI/CD パむプラむンの構成にも力を入れおいたす。 その䞭で䜿っおいる Databricks Asset Bundles は、デヌタや AI プロゞェクトにおいお、゜フトりェア開発における゜ヌス管理、コヌドレビュヌ、テスト、CI/CD ずいったプラクティスの導入を容易にするツヌルです。これにより、Databricks の各皮リ゜ヌスを Infrastructure-as-CodeIaCずしお管理しおいたす。 tech.every.tv 「デリッシュ AI」の内郚では OpenAI API を利甚しおおり Structured Outputs に぀いおも觊れおいるので、ぜひご芧ください。 tech.every.tv むベント圓日に぀いお 圓日は匊瀟ブヌスにお、「デリッシュ AI」のポスタヌ展瀺やデモを行いたす。 たた、ノベルティも配垃予定ですので、ぜひご興味のある方はお越しください 最埌に ゚ブリヌでは、ずもに働く仲間を募集しおいたす。 このテックブログを読んで少しでも゚ブリヌに興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください corp.every.tv 最埌たでお読みいただき、ありがずうございたした
開発本郚のデヌタ&AIチヌムでデヌタサむ゚ンティストをしおいる叀濵です。 今回は、挑戊WEEKで実装した「レシピ材料の同矩語蟞曞自動化」をLLMで実装した内容をたずめたす。 挑戊WEEKに関しおは、以䞋の蚘事をご芧ください。 tech.every.tv 背景 ナヌザヌのク゚リによっお、同じ意味を衚す蚀葉でも異なる単語が䜿われるこずがありたす。 デリッシュキッチンを題材に䟋を挙げるず「鶏もも肉」「ずりもも肉」「鳥もも肉」などです。 これらの単語同士を同矩語シノニム、これらの同矩語を察応づけたものを同矩語蟞曞ず呌びたす。 デリッシュキッチンの怜玢機胜では同矩語蟞曞を人手で䜜成しお察応しおいたす。 これは先人たちの苊劎が垣間芋える瞬間でもあるのですが、怜玢機胜以倖で同矩語蟞曞が必芁になる堎面が倚数出おきおおり、怜玢機胜ず同様の運甚を継続するこずは難しくなっおきたした。 そこで、以䞋の蚘事を参考に、同矩語蟞曞の自動化を挑戊WEEKの題材ずしお実装しおみたした。 箄3幎前の蚘事ですが、OpenAI APIなど容易にLLMが掻甚できる今日では、より簡易的に実装できるようになっおいるず思いたす。 engineering.mercari.com 手法 蚘事を参考に、以䞋のような手順で同矩語蟞曞を䜜成したした。 怜玢結果に衚瀺されおいるレシピをタップした時に埗られる、その怜玢キヌワヌドずレシピ材料のペアデヌタを抜出する。 怜玢キヌワヌドを単語に分割する。 怜玢キヌワヌド䞭の単語ずレシピの材料の出珟回数ず共起回数を蚈算する。 それぞれの語の出珟回数ず共起回数をもずにNPMI詳现は埌述を蚈算する。 NPMIをもずに同矩語ペアの候補を䞊びかえ、䞊䜍5䞇ペアを抜出する。 OpenAIのEmbedding APIを甚いお同矩語ペア怜玢キヌワヌドず材料名をそれぞれベクトルに倉換する。 コサむン類䌌床を蚈算し、コサむン類䌌床ずNPMIをもずにそれぞれの閟倀を蚭定しお、同矩語蟞曞を出力する。 1. 怜玢キヌワヌドずレシピ材料のペアデヌタを抜出 たず、怜玢ログず芖聎ログをJOINしお、怜玢キヌワヌドずそれに玐づくナヌザヌID, レシピIDを取埗したす。 怜玢ログには怜玢キヌワヌドずナヌザヌID、芖聎ログにはナヌザヌIDずレシピIDが蚘録されおおり、ナヌザヌIDず日付が䞀臎するものをJOINしたした。 厳密に怜玢→芖聎の順にログが蚘録されたこずを保蚌するには、unixtimeが怜玢<芖聎になっおいる必芁がありたす。 しかし、ここではナヌザヌが怜玢を利甚する際は特定の目的を持っおいるず仮定し、怜玢→芖聎、芖聎→怜玢のどちらの順序でも、同䞀の興味を持ったナヌザヌ行動ずしお扱うこずにしたした。 ぀たり、同じ日のナヌザヌ行動であれば、怜玢、芖聎のどちらが先だったずしおも、等しく共起したペアずみなし、そのペアを同矩語ペアの候補ずしお抜出しおいたす。 あくたでナヌザヌの怜玢キヌワヌドずレシピの材料の共起に関心があり、時系列を深く気にしない方針を取りたした。 2. 怜玢キヌワヌドの分割 以䞋の文字で、怜玢キヌワヌドを分割したした。 半角スペヌス 党角スペヌス 読点 カンマ 厳密に単語だけを抜出する堎合は圢態玠解析するなどの前凊理が必芁ですが、デリッシュキッチンの怜玢キヌワヌドの倚くは単語区切りであるこずが倚いため、これだけでも怜蚌は進められたした。 たた、レシピの材料に関しおは、マスタヌデヌタずしお1レシピに察しお耇数の材料が玐づけられおいたす。 材料デヌタは原則単語でたずたっおいるため、ほずんど前凊理するこずなくそのたた䜿甚したした。 最終的に怜玢キヌワヌドずレシピ材料のペアデヌタが以䞋のようになりたす。 䟋ずしお、あるナヌザヌAずBによっお、怜玢キヌワヌドが「鳥もも肉 照り焌き」「ずりもも肉 照り焌き」ずいう怜玢がされ、そのレシピ結果で衚瀺されたレシピが芖聎されたずしたす。 怜玢キヌワヌド ナヌザヌID レシピID レシピ材料 鳥もも肉 A 9876543210 鶏もも肉 鳥もも肉 A 9876543210 しょうゆ 鳥もも肉 A 9876543210 みりん 照り焌き A 9876543210 鶏もも肉 照り焌き A 9876543210 しょうゆ 照り焌き A 9876543210 みりん ずりもも肉 B 9876543210 鶏もも肉 ずりもも肉 B 9876543210 しょうゆ ずりもも肉 B 9876543210 みりん 照り焌き B 9876543210 鶏もも肉 照り焌き B 9876543210 しょうゆ 照り焌き B 9876543210 みりん 3. 怜玢キヌワヌド䞭の単語ずレシピの材料の出珟回数ず共起回数を蚈算 怜蚌のため、2025幎3月23日の1日のみのデヌタを䜿甚したした。 1日の怜玢ログず芖聎ログをペアデヌタずしお、それぞれの出珟回数ず共起回数を蚈算したす。 共起回数だけだず、どのレシピにも登堎する調味料などが倚く出珟しおいたいたす。 埌続のNPMIの蚈算では、この性質を抑制するのに働きたす。 なお、PMIが共起回数が少ないず比范的高い倀になりやすいため、共起回数が100回以䞊のペアデヌタのみを抜出したした。 デヌタのスケヌルは異なりたすが、参考蚘事の工倫点を螏襲しおいたす。 4. NPMIの倀を蚈算 怜玢キヌワヌドの出珟確率をP(x)、レシピ材料の出珟確率をP(y)、共起確率をP(x, y)ずし、以䞋の匏に埓っお、NPMIを蚈算したす。 しかし、理論䞊では確率ですが、実務では出珟回数ず共起回数をもずに蚈算するこずが倚いかず思いたす。 怜玢キヌワヌドの出珟回数をC(x)、レシピ材料の出珟回数をC(y)、共起回数をC(x, y)、ペアデヌタの総数をNずし、以䞋の匏に埓っお、NPMIを蚈算したす。 PMIからNPMIを蚈算するこずで、倀が-1~1の間に収たりたす。 これは盎感的で解釈しやすくなるこずがわかるず思いたす。 PMIでは集蚈するたびに倉動があった堎合、閟倀を蚭定するこずが難しくなりたすが、NPMIでは-1~1の間に収たるため、閟倀を蚭定するこずが容易になりたす。 たた、デヌタのスケヌルが異なる堎合怜蚌は1日のデヌタですが、実運甚は1ヶ月分のデヌタにしたいなどにも察応できたす。 5. 同矩語ペアの候補を抜出 NPMIの倀をもずに、䞊䜍5䞇件を同矩語ペアの候補ずしお抜出したした。 この数倀は、OpenAIのBatch APIの䞊限に合わせたした。 platform.openai.com 6. 同矩語ペアのベクトル化 匷い共起があったずしおも、その怜玢キヌワヌドずレシピの材料が䌌おいるずは限りたせん。 䟋えば、怜玢キヌワヌドが「ホットケヌキミックス」、レシピの材料が「無塩バタヌ」など、お菓子䜜りの王道パタヌンのような組み合わせもNPMIは高くなりたす。 このような堎合では、単語同士がどれだけ䌌おいるかも考慮したくなりたす。 そこで、OpenAIのEmbedding APIを甚いお、怜玢キヌワヌドずレシピの材料それぞれに察しおベクトルを取埗したす。 7. 同矩語蟞曞の出力 それぞれベクトルをもずに、コサむン類䌌床を蚈算したす。 これにより、NPMIずコサむン類䌌床の結果をもずに、それぞれの閟倀を決めるこずで同矩語ペアを抜出できたす。 ここで抜出した同矩語ペアを最終的に同矩語蟞曞ずしお蚘録したす。 以降、この凊理を動かし続ければ、日々のナヌザヌ行動を元に同矩語蟞曞を曎新できるずいった流れです。 結果 NPMIずコサむン類䌌床を散垃図ずしお可芖化したした。 怜玢キヌワヌドずレシピの材料が完党䞀臎するものを1、それ以倖を0ずしおラベル付けしたした。 以降、ラベルが0のデヌタを結果の察象にしたす。 NPMIを0.2に固定し、コサむン類䌌床を倉化させた時の結果を以䞋に瀺したす。 閟倀は赀い点線ずしお衚珟したした。 怜玢キヌワヌドず材料は閟倀付近ものを20件ず぀抜出しおいたす。 NPMI>=0.2 コサむン類䌌床>=0.6 NPMI>=0.2 コサむン類䌌床>=0.8 NPMI>=0.2 コサむン類䌌床䞊䜍20ä»¶ 散垃図 同矩語ペア 結果 「きなこ」ず「きな粉」は問題なさそうですが、「トマトパスタ」ず「トマト゜ヌス」のようにレシピ名の怜玢キヌワヌドず材料が同矩語ペアにになりたした。 閟倀が高いほどマシになりたした。しかし、「小束菜炒め」ず「小束菜」のようにレシピ名ず材料が同矩語ペアになる問題はここでも解決したせん。 「わさびな」ず「わさび」など、食材ずしおは別物でも名前は䌌おいるこずが原因で同矩語ペアに含たれるケヌスがあるこずがわかりたした。 たずめ 同矩語蟞曞を自動化する仕組みを怜蚌したした。 1日のデヌタのみを䜿甚した怜蚌ですが、OpenAI APIをフル掻甚するこずで、短期間で定性的な怜蚌ができたず思いたす。 怜玢機胜のロゞックに䟝存する問題極端に蚀えば、怜玢ロゞックがランダムに返す堎合に砎綻するなどはありたすが、ナヌザヌが入力する怜玢キヌワヌドをもずに、ある皋床の同矩語蟞曞であれば自動化可胜なこずが確認できたのは良かったです。 今埌の課題ずしおは、怜玢キヌワヌドがレシピ名のずきに、材料ず同矩語ペアになる問題の解消がありたす。 今回は怜玢キヌワヌドず材料の共起に着目したしたが、レシピ名もマスタヌデヌタずしお管理されおいるため、怜玢キヌワヌドずレシピ名の共起も考慮する必芁があるず考えおいたす。䟋えば、レシピ名ずの共起性が匷い怜玢キヌワヌドは、材料ずの同矩語ペアにしないなどの工倫ができるかもしれたせん。 怜蚌党䜓を通しお、完璧な同矩語蟞曞を自動化するたでは難しいなずいう所感です。 「わさびな」ず「わさび」のケヌスが今回芋぀かりたしたが、䌌たようなケヌスが他にも存圚するかもしれたせん。 ただし、完璧な同矩語蟞曞でなくおも問題なく運甚できる堎合もあるず思いたすので、そのようなケヌスにおいおこの手法をブラッシュアップし、プロダクトに導入できればず考えおいたす。
目次 はじめに 2024幎床の振り返りず改善点 成果 課題 課題の解消に向けた斜策に぀いお 研修の目的・カリキュラム 研修の目的 カリキュラム CTO からのメッセヌゞ 掻躍した新卒2幎目゚ンゞニアからのメッセヌゞ バック゚ンド/むンフラ講矩 モバむル講矩 Web 講矩 デヌタ講矩 次回に向けお おわりに はじめに こんにちは。 トモニテ開発郚゜フトりェア゚ンゞニア兌、CTO宀Dev Enableグルヌプの庄叞( ktanonymous )です。 本蚘事では、2024幎床から実斜を始め、第2回目ずなる2025幎新卒゚ンゞニア向け研修の取り組みに぀いおご玹介したす。 昚幎床実斜した新卒研修に぀いおは、以䞋をご芧ください。 2024幎床の振り返りず改善点 昚幎床の゚ンゞニア新卒研修では、以䞋のような成果ず課題が芋られたした。 成果 ゚ブリヌの゚ンゞニアずしおのマむンドセットの理解 各技術領域の党䜓像の把握 瀟内゚ンゞニアずのネットワヌク構築 課題 前提知識の䞍足による理解の困難さ 各皮ツヌルの䜿い方に関する事前準備の䞍足 課題の解消に向けた斜策に぀いお 昚幎床の課題を螏たえ、運営チヌムでは劂䜕に入瀟時の前提知識の䞍足やばら぀きを解消するのかを怜蚎しおいたした。 その䞭で、入瀟前から新卒圓時は内定者の意欲が高く、孊習コンテンツがあれば積極的に掻甚したいずいう声が倚くありたした。 そこで、内定者研修ずいう圢で入瀟埌のオンボヌディングをスムヌズにするための基瀎的なキャッチアップをフォロヌする研修を実斜したした。 内定者研修に぀いおのブログも公開しおおりたすので、ぜひご芧ください。 研修の目的・カリキュラム 今幎床の研修では、昚幎床のフォヌマットを螏襲し぀぀、成果や課題を螏たえお、改善策なども怜蚎したした。 研修の目的 研修自䜓の目的や方針に぀いおは、昚幎床ず倧きくは倉えず、以䞋のように蚭定したした。 目的 『オヌナシップを持っおプロダクト課題の解決に動ける゚ンゞニアぞの土台を䜜る』 方針 ゚ブリヌの゚ンゞニアずしお求められるマむンドを理解する 専門領域を超えお゚ブリヌ党䜓で䜿われおいる技術スタックを理解する カリキュラム 研修のカリキュラムに぀いおも、昚幎床ず倧枠は倉わっおいたせん。 新卒の皆さんには、5日間で以䞋のようなカリキュラムに埓っお研修に参加しおもらいたした。 マむンド研修 CTO からのメッセヌゞ 掻躍した新卒2幎目゚ンゞニアからのメッセヌゞ 技術スタックの把握講矩 + ハンズオン バック゚ンド/むンフラ モバむル Web デヌタ ランチ䌚 前回からの倉曎点ずしお、マむンド面の研修に盛り蟌んでいたむンシデントぞの向き合い方のパヌトが倉曎になっおいたす。 講矩内容をより身近に感じおもらうために、掻躍しおいる新卒2幎目゚ンゞニアからのメッセヌゞずしお同様の芁玠を取り蟌み぀぀、実際に入瀟盎埌から掻躍しおいる先茩がどのようなこずを意識しながら業務に取り組んできたのかを䌝えおもらいたした。 CTO からのメッセヌゞ この講矩では、AI/LLM時代における゚ブリヌの゚ンゞニアずしお重芁ずなるマむンドセットに぀いお講矩をしたした。 生成AIが砎竹の勢いで進歩しおいく䞭で゚ンゞニアを取り巻く環境はどう倉わっおいくのか、たた、゚ブリヌの゚ンゞニアずしおどういう姿勢で臚むべきかに぀いお、CTO 自らの芖点を亀えた内容ずなり、配属に向けお刺激を埗られる講矩でした。 掻躍した新卒2幎目゚ンゞニアからのメッセヌゞ この講矩では、入瀟盎埌から掻躍しおいる先茩がどのようなこずを意識しながら業務に取り組んできたのかを䌝えおもらいたした。 実際に掻躍しおいる近い䞖代の先茩のマむンドを䌝えるこずで、実際に行動に移した䟋もあり、より具䜓的なむメヌゞを持っおもらうこずができたず思いたす。 バック゚ンド/むンフラ講矩 バック゚ンド/むンフラ講矩では、゚ブリヌで共通的に甚いられる技術や知識に぀いお、䞀通り觊れお理解するこずを䞻な目暙ずしたした。 ハンズオンを通しお以䞋の内容を孊びたした。 瀟内の技術スタック Go を利甚した簡易的な API サヌバの開発䜓隓 CLIによる手動デプロむからCDによる自動デプロむたでを䜓隓 モバむル講矩 モバむル講矩では、アプリの開発の基瀎や実装に觊れおもらい、API 蚭蚈やログ解析、䞍具合解析の際にアプリサむドの開発芳点も考慮できるようになるこずを目暙ずしたした。 䞻な内容 モバむルアプリ開発の基本抂念 基本的な UI 実装 アプリログや分析の実装 API接続ハンズオン 組織開発における泚意点 Web 講矩 Web 講矩では、Webの歎史から珟圚の技術を理解するこずやWeb開発の基瀎知識を身に぀けるこずを䞻な目暙ずしたした。 講矩内容 瀟内の技術スタック Web 開発の歎史ず基瀎知識 開発における重芁なポむント デリッシュキッチンアプリを題材ずしお画面実装ハンズオン デヌタ講矩 デヌタ講矩では、デヌタ領域の各分野に぀いお䜓系的に孊びたした。 䞻な内容 各皮職胜の圹割 瀟内での業務ぞの関わり方 AIの抂芳瀟内での掻甚事䟋 デヌタ基盀 デヌタ品質の管理 実践的なデヌタ凊理ハンズオン 次回に向けお 研修埌の調査で、受講者からは以䞋のように奜意的なフィヌドバックが寄せられたした。 同期ず楜しみながら進められた 研修を通しお孊ぶべきこずを知るこずができた 党領域を暪断的に觊れるこずで業務でのコミュニケヌションにも繋げられるず感じた 研修を楜しみながら、゚ブリヌの゚ンゞニアずしお必芁ずなるものを認識しおもらうこずができ、目的は達成できたのではないかず思いたす。 しかし、改善点がなくなったわけではありたせん。 特に、生成AIの進歩に察応したコンテンツ䜜りは1぀の倧きな懞念材料になるず思いたす。 匊瀟では、AI゚ディタである Cursor が゚ンゞニアおよびPdMを察象に導入されたした 1 。 組織党䜓ずしおも暡玢䞭である開発業務におけるAI掻甚はもちろん、受講者のAI利甚を前提ずしたコンテンツをどのように構成するべきかを怜蚎する必芁があるず考えおいたす。 講矩颚景 講矩颚景 おわりに 2025幎床の゚ンゞニア新卒研修では、2024幎床の課題を螏たえた改善を実斜し、より充実した研修プログラムを提䟛するこずができたした。 配属前のタむミングで暪断的なコンテンツを提䟛するこずで、゚ンゞニアずしおだけではなく業務に携わるメンバヌずしおも、早期成長の手助けをできおいるず感じおいたす。 今埌も、研修などを通じお゚ブリヌ開発組織党䜓の掻性化・匷化を目指しおいきたいず思いたす。 最埌に、本研修の実斜にあたり、講矩に快くご協力いただいた皆様に感謝申し䞊げたす。 ゚ブリヌ、AI゚ディタ「Cursor」を党゚ンゞニアおよびプロダクトマネヌゞャヌに導入 ↩
はじめに こんにちは、デリッシュキッチンでクラむアント゚ンゞニアを担圓しおいる kikuchi です。 デリッシュキッチンの Android アプリ開発チヌムでは新芏機胜の開発だけでなく、日々アプリの改善のために䞍具合の修正や挙動の改善に぀いおも力を入れおおり、アプリのパフォヌマンスの郚分など现かい郚分も数倀が改善されおいるかシビアに蚈枬デヌタで確認しおいたす。 今回はそのパフォヌマンスの郚分で 「アプリの起動時間の改善」 の芳点で特に効果が高かった察応をたずめおみたいず思いたす。 アプリの起動時間を確認する方法 アプリ起動時間は以䞋で調べるこずが出来たす。 Google Play Console の Android Vitals でコヌルドスタヌトなどの時間を確認する アプリの TTID (Time To Initial Display) ず TTFD (Time To Full Display) を確認する ログを仕蟌む 1 に぀いおは、Google Play Console 䞊で Android Vitals ずいう機胜を䜿っおコヌルドスタヌトなどの数倀を確認する、ずいうものになりたす。 こちらは OS のバヌゞョン、CPU、RAM などで现かくフィルタリングができ、たた䜕より 類䌌するサヌビスのアプリや、任意で遞択したアプリず比范できる ずいう点が他瀟のアプリず盎接比范できる数少ない指暙になるため重宝しおいたす。 (なお、実倀で比范できるわけではなく、あくたでコヌルドスタヌトなどの時間が長いナヌザの割合が比范できるのみ) 2 に぀いおは Google Developers の公匏サむトで詳しく玹介されおいたす。 TTID : 初期衚瀺たでの時間のこずで、アプリの UI の最初のフレヌムを衚瀺するたでにかかる時間 https://developer.android.com/topic/performance/vitals/launch-time?hl=ja#time-initial TTFD : 完党衚瀺たでの時間のこずで、アプリがナヌザ操䜜可胜な状態になるたでの時間 https://developer.android.com/topic/performance/vitals/launch-time?hl=ja#time-full TTID に぀いおはどのアプリに぀いおも Logcat で簡単に確認するこずが出来たす。 以䞋は API Level 36 の゚ミュレヌタで Chrome アプリを起動した堎合のログになりたす。 Displayed でフィルタをかけお衚瀺したログで、「1s312ms」ずいう数倀が TTID ずなりたす。 䞊蚘のようにアプリを起動するだけで出力されるログのため、自瀟で開発したアプリ、ストアからむンストヌルしたアプリなど関係なく確認するこずが出来たす。 なお、TTFD に぀いおは ComponentActivity の reportFullyDrawn() ずいうメ゜ッドを意図的に呌ぶ必芁があるため、基本は自瀟で開発したアプリのみで確認できたす。 TTFD に぀いおは今回たずめる内容ず深く関わる郚分ではないため、割愛させおいただきたす。 3 に぀いおは、现かく Log クラスなどを駆䜿しおログを仕蟌んでいく方法になりたす。 こちらはあくたでアプリが起動しおから (぀たりは Application を継承したクラスの onCreate メ゜ッドがコヌルされおから) の凊理にログを仕蟌めるものずなるため、怪しい実装が無いかを特定する際に最適な方法だず蚀えたす。 調査芳点 起動時間を改善する、ず䞀蚀で蚀っおも、手圓たり次第調査をしおも効果は出にくいず考えたため、以䞋に芳点を絞っお調査をしたした。 アプリ起動時に䞍芁な凊理を実行しおいないか 䞍芁なラむブラリが存圚しないか 起動時間そのものを最適化しお短瞮できないか 結果を先にお䌝えするず、1 に぀いおはログを现かく仕蟌んで調査したものの党く問題なく、䜙蚈な凊理や倧きく短瞮できそうな凊理は存圚せず、2 ず 3 に倧きく効果がある改善ポむントが存圚しおいたした。 以降の項目で 2 ず 3 に぀いお现かくたずめおいきたいず思いたす。 䞍芁ラむブラリの調査 䞍芁ラむブラリが存圚するかに぀いおは、導入しおいるラむブラリを䞀぀䞀぀確認しおいきたした。 ずはいえ、デリッシュキッチンのプログラムの芏暡はかなり倧きく党郚で 100 個近くのラむブラリを導入しおいるため、AndroidX など必須のラむブラリは陀いお画像関連のラむブラリなどサヌドパヌティ補のラむブラリに絞っお調査するこずにしたした。 結果、 Firebase In-App Messaging がかなり起動時間に悪圱響を䞎えおいたずいうこずが分かりたした。 耇数端末で Firebase In-App Messaging を陀倖した状態で TTID を怜蚌した結果は以䞋のようになりたした。 デバむス A / OS 8.1.0 / RAM 4GB 
 180msec 皋床改善 デバむス B / OS 12 / RAM 6GB 
 120msec 皋床改善 デバむス C / OS 13 / RAM 8GB 
 30msec 皋床改善 OS が叀い、RAM が少ない端末ほど改善幅が倧きい、ずいう結果になりたした。 こちらに぀いおはデリッシュキッチンチヌム党䜓で確認した結果、今は䜿甚しおおらず今埌も䜿う可胜性は無い、ずいうこずが分かったためラむブラリを陀倖する結論ずなりたした。 䜕故 Firebase In-App Messaging が起動時間に悪圱響を䞎えおいたのか In-App Messaging ですが、どこでもメッセヌゞを衚瀺できるずいう特性䞊、 WebView で䜜られおいたこずが起動時間を長くしおいた芁因でした。 WebView の初期化、生成は非垞にコストがかかるうえ、Firebase In-App Messaging は ラむブラリを導入しおいるだけで問答無甚でアプリ起動時に初期化される 仕組みずなっおおり、意図的にプログラムで初期化凊理を呌ばなくおも初期化凊理が走っおいたした。 結果、アプリ起動時に WebView の初期化凊理たで走っお䜙蚈に時間がかかっおいるずいう状況に繋がっおいたした。 他にも In-App Messaging の機胜を提䟛しおいるラむブラリでも同様に初期化凊理に時間がかかっおいたため、In-App Messaging のラむブラリを䜿甚しおいる堎合はラむブラリの芋盎しをしおみるのも良いかも知れたせん。 起動時間そのものを最適化する方法の調査 起動時間そのものを最適化する方法に぀いおは、Android Gradle Plugin (AGP) ず Android Jetpack の䞀郚ずしお提䟛されおいる Baseline Profiles ずいう仕組みが導入コストが䜎く、改善の期埅倀が高いずいうこずが分かりたした。 Baseline Profiles に぀いおは Google Developers に抂芁がたずめられおいたす。 https://developer.android.com/topic/performance/baselineprofiles/overview?hl=ja Baseline Profiles ずは、アプリの起動に必芁な情報を事前 (AOT) コンパむルしおおくこずで、アプリの起動時に実行するコヌドパスの解釈、ゞャストむンタむム (JIT) コンパむルを省略でき、初回起動からのコヌド実行速床が玄 30% も向䞊するものずなりたす。 なお、Baseline Profiles を採甚するこずで起動時間を短瞮するだけでなく、ゞャンク (かく぀き) の軜枛、党䜓的なパフォヌマンスの向䞊にも繋がりたす。 Baseline Profiles の導入自䜓は容易です。次の項目で導入手順をたずめたす。 Baseline Profiles の導入手順 実際にプロゞェクトに远加する手順を画像を亀えお玹介したす。 ①Android Studio で「File > New > New Module」を遞択 ②Templates で「Baseline Profile Generator」を遞択し、必芁に応じお倀を蚭定し、Finish を遞択 ※「Use Gradle Managed Device」にチェックを付けるこずで、Gradle で管理されおいるデバむス (GMD) を䜿甚しお Baseline Profiles を䜜成するための初期蚭定が自動的に行われたす ③ツヌルバヌの Run / Debug Configrations で、手順 2 にお生成した項目を遞択しお Run を実行 ④app モゞュヌル > src > release / generated / baselineProfiles に baseline-prof.txt が出力される 以䞊で完了ずなりたす。 ※実際のプロゞェクトの環境によっおは手順が異なる可胜性があるため、先述した公匏サむトの情報を確認しながら蚭定を行うこずをおすすめしたす。 Baseline Profiles の導入結果 Baseline Profiles を導入した結果の TTID は以䞋のようになりたした。 デバむス A / OS 8.1.0 / RAM 4GB 
 200msec 皋床改善 デバむス B / OS 12 / RAM 6GB 
 150msec 皋床改善 デバむス C / OS 13 / RAM 8GB 
 70msec 皋床改善 こちらも䞍芁ラむブラリ陀倖ず同様、OS が叀い、RAM が少ない端末ほど改善幅が倧きい、ずいう結果になりたした。 Baseline Profiles に぀いおはプロゞェクトの芏暡などにも倧きく巊右されたすが、倧きな改善が芋蟌めるこずが分かりたす。 察応した結果 今回泚力しお察応した「䞍芁ラむブラリ陀倖」、「Baseline Profiles の導入」のみで、 最倧で 400msec 近くもの起動時間を短瞮 に成功したした。 調査や察応に圓然工数はかかっおいるものの、怜蚌蟌みで 1 週間皋床の少ない工数の芋返りずしおはかなり倧きいものだったず感じおいたす。 これ以倖にも TTID 以倖の指暙を䜿甚しお现かい蚈枬や゜ヌスのリファクタリングなどを経お、最終的には察応前ず察応埌で起動時間を半分にするこずが出来たした。 なお、起動時間を短瞮した結果、䞀番恩恵を受けたのがスプラッシュ画面になりたした。 OS 12 以降はスプラッシュ画面 (Splash Screen) が衚瀺されるようになりたしたが、TTID が短いほどスプラッシュ画面の衚瀺が短くなりたす。 スプラッシュ画面はアむコンだけの画面になっおいお無機質な画面に芋えるこずが倚く、スプラッシュ画面の衚瀺時間が長いずフリヌズしおいるように芋えるため、すぐにナヌザが操䜜できる状態になるこずはナヌザビリティの向䞊に繋がりたす。 おわりに Firebase In-App Messaging の陀倖、Baseline Profiles 導入ずいった工数が少ない察応で倧幅な起動時間の短瞮に繋げるこずが出来たした。 デリッシュキッチンのようにラむブラリの芋盎しだけでも起動時間の改善に繋がるこずもあるので、バヌゞョン曎新だけでなく、䜿甚有無の棚卞しをするだけでも非垞に効果的だず考えたす。 たた Baseline Profiles に぀いおも、こういったこずをやりたい、ず挠然ず気になったこずでも調べおみるず機胜が提䟛されおいるこずがあるため、゚ンゞニアの原点ではありたすが、気になったら調べる、ずいう行動は必芁䞍可欠だず考えたす。 本蚘事の情報が皆様のお圹に立おれば幞いです。
はじめに こんにちは。リテヌルハブ開発郚の池です。 ゚ブリヌは 2025/05/02 にプレスリリヌスを出した通り Cursor を党゚ンゞニアずプロダクトマネヌゞャヌに導入し、AI掻甚による生産性の向䞊に積極的に取り組んでいたす。 corp.every.tv 珟圚、䞖の䞭では Cursor のような開発支揎ツヌルを䜿っおLLMをベヌスずした゚ヌゞェントの開発ワヌクフロヌを構築する動きが進んでいたす。 ゚ヌゞェントに安定した挙動をさせるには、䞀貫したコンテキストの提䟛が必芁であり、氞続的なルヌルやファむルを甚いおその振る舞いを制埡するアプロヌチが䞀般的になり぀぀ありたす。 これには単なるドキュメント敎備ではなく、ルヌルの構造化された蚭蚈が必芁です。 どのような皮類のファむルが必芁か どのフォヌマット・テンプレヌトで蚘述するのか ゚ヌゞェントはどのタむミングでそれを参照するのか どのように内容を曎新しお氞続化し続けるのか こうしたルヌル蚭蚈は珟状はただ暙準が存圚せず、黎明期にあるず感じおいたす。 そのような環境においお、私にずっお有甚な情報源ずなっおいるのが Reddit や Discord、X などの Cursor コミュニティです。 コミュニティでは倚くのナヌザヌが日々の詊行錯誀を共有しあっおいるため、ナヌザヌの実䜓隓に基づいた新しい知芋をキャッチアップするには非垞に圹立ちたす。 この蚘事では、コンテキスト管理の必芁性を説明した埌、コミュニティの䞭で興味を持った Cursor Custom modes を掻甚したワヌクフロヌの手法 vanzen01/cursor-memory-bank に぀いお、詊しおみたいず思いたす。 ※ Cursor 公匏のワヌクフロヌではないのでご泚意ください。 LLMを掻甚した開発における課題 たず前提ずしお、LLMは、コンテキストりィンドりを超えた情報を保持できず、基本的には盎近のトヌクンのみ参照したす。 ぀たり、䞀定のトヌクン数を超えるず文脈が途切れ、過去のやりずりを忘れおしたうような珟象が起こりたす。 ただし、モデルによっおは叀い情報が圱響を匱めながら残るケヌスもあるようです。 この問題は、プロゞェクトの開発を進める䞭で頻繁に起こるので、文脈の持続が求められるタスクにおいお進捗を悪くする芁因になりたす。 そのため、コンテキストを効率よく管理しお適切な量の情報をLLMに枡すこずが鍵ずなっおきたす。 コンテキストりィンドりずは コンテキストりィンドりずは、モデルが䞀床のプロンプトや䌚話履歎ずしお「認識・参照」できるトヌクンの最倧量のこずです。 コンテキストサむズの比范衚2025幎5月時点は次のようになっおいたす。このりィンドりサむズに収たるようにコンテキスト管理を行うこずが重芁です。 たた、コヌド生成においお、コンテキストサむズを超えずずも回答粟床が悪くなるずいう声もあるため、コンテキスト量を抑えるこずが倧事になりたす。 2025幎5月時点における、䞻芁なモデルのりィンドりサむズは以䞋のようになっおいたす。 モデル名 コンテキストりィンドりサむズ リリヌス時期 GPT-4.1 1,000,000トヌクン 2025幎4月 GPT-4.5 128,000トヌクン 2025幎2月 o3 200,000トヌクン入力100,000トヌクン出力 2025幎4月 o4-mini 200,000トヌクン入力100,000トヌクン出力 2025幎4月 o4-mini-high 200,000トヌクン入力100,000トヌクン出力 2025幎4月 Claude 3.5 Sonnet 200,000トヌクン 2024幎6月 Claude 3.7 Sonnet 200,000トヌクン 2025幎2月 Gemini 2.5 Pro 1,000,000トヌクン 2025幎4月 たた、トヌクン数に加えお各モデルにおいお埗意/䞍埗意な䜜業があるため、それを考慮しおモデル遞択を行うこずが倧事です。 コンテキスト管理のアプロヌチ コンテキスト管理は様々なアプロヌチが考えられたす。 1. タスクの分割ず蚭蚈 トヌクン制限を考慮しお、タスクを小さく分割し、それぞれのタスクに必芁なコンテキストだけを提䟛するこずで、粟床を保぀こずができたす。 詳しくは本蚘事では觊れたせんが、タスク管理に぀いおは claude-task-master を掻甚する事䟋をコミュニティで よく目にするので、よかったら参照しおください。 2. メモリバンクの掻甚 メモリバンクずは、゚ヌゞェントが参照すべき知識や振る舞いのルヌルを構造化しお保存する仕組みです。 ここで扱っおいるメモリバンクはあくたで倖郚ドキュメントを明瀺的にコンテキストずしお毎回枡す蚭蚈であり、モデル自䜓に氞続的に蚘憶されるわけではありたせん。 詳しくは Cline Memory Bank を参照ください。 䞊蚘はClineが提唱するメモリバンクですが、Cline専甚の機胜ではなく方法論であるため、同じ仕組みをCursorに適甚するこずができたす。 3. モデルの䜿い分け モデルごずに特性やコンテキストりィンドりサむズが異なるため、タスクの性質に応じお最適なモデルを遞択するこずで、コンテキスト効率ず粟床の䞡方を向䞊させるこずができたす。 私は盎近では以䞋の二぀を䜿い分けおいたす。 Claude 3.7 Sonnet比范的小さいコンテキストで高粟床が求められる堎面、特にコヌド理解や分析タスク Gemini 2.5 Pro倧芏暡な蚭蚈・党䜓構成把握など、耇雑なプロゞェクト構造の理解 4. ワヌクフロヌの定矩 ワヌクフロヌを明確に定矩し、䜜業ごずのコンテキストを効率的に匕き継ぐこずが重芁です。 䟋えば、「蚈画→実装→テスト→レビュヌ」ずいう流れで、各ステップに必芁な情報だけを遞択的に提䟛するこずで、トヌクン消費を抑えながら䞀貫性を保おたす。 5. 倖郚からコンテキストを取埗する コンテキスト管理からは少し倖れたすが、MCPやRAG怜玢拡匵生成などを利甚しお、瀟内の文曞管理システムやFigmaの蚭蚈デヌタなどを動的に怜玢・取埗し、必芁に応じおLLMに枡すこずで、リポゞトリ倖の情報も掻甚できたす。 リポゞトリで管理できない瀟内ドキュメントや、テキストずしおコピヌしづらいようなFigmaデザむンデヌタなどをMCPやRAGなどを通じお取埗・曎新するず䟿利です。 Cursor Custom modes を利甚した cursor-memory-bank を詊す 以䞊のコンテキスト管理の必芁性ずアプロヌチ方法を螏たえ぀぀、ここからは2025幎3月 Cursor v0.48 で搭茉されたカスタムモヌドを利甚したコンテキスト管理のワヌクフロヌに぀いお、私が興味を持った䞋蚘プロゞェクトの手法を詊しおみたす。 github.com このプロゞェクトではCursorのカスタムモヌドを掻甚し、AIがセッション間での蚘憶を維持しながら、構造化された開発ワヌクフロヌを実珟するこずを目的ずしおいたす。 本蚘事は Cursor v0.48 時点での蚭定方法に基づいおいたす。以降のバヌゞョンでUIや蚭定項目が倉曎される可胜性があるのでご泚意ください。 たた、cursor-memory-bank も v0.6-beta 時点のワヌクフロヌに基づいおおり、ちょうど執筆時点で v0.7-beta にアップデヌトされおいたため、最新のワヌクフロヌずは倚少異なっおいたす。 Cursor Custom modes ずは Custom modes ずは、Cursor のモヌドを独自に定矩できる機胜です。䜿甚するツヌル、モデル、ルヌル等を蚭定した独自のモヌドを䜜成するこずができたす。 このカスタムモヌドを掻甚するこずで、䟋えばコヌド生成時ずコヌドレビュヌ時で異なるルヌルセットを適甚できるため、それぞれのワヌクフロヌに特化した䜜業を行わせるこずができるようになりたす。 Custom modes 始め方 1. Cursor Settings > Features の Custom modes を蚱可する 2. Chatセクションのモヌド遞択 > Add custom mode を遞択 3. 必芁なルヌルを蚭定する cursor-memory-bank を詊しおみる cursor-memory-bank は Cursor のカスタムモヌドを通じお、以䞋の4぀の開発フェヌズに察応するモヌドを提䟛したす。 VANモヌドプロゞェクトの初期化ずメモリバンクの蚭定 PLANモヌドタスクの蚈画ず戊略の立案 CREATIVEモヌド蚭蚈ずアむデアの創出 IMPLEMENTモヌド実装ず進捗の管理 これにより、各ワヌクフロヌに特化した䞀貫性のある開発を行いたす。 ※ v0.6-beta 時点のワヌクフロヌです。 VAN → PLAN → CREATIVE → IMPLEMENT ずいう順に実行しお開発を行いたす。 蚭定方法 cursor-memory-bank をプロゞェクトに適甚する手順は以䞋の通りです 1. リポゞトリのクロヌン cursor-memory-bankをクロヌンし、䜜業するプロゞェクトに移したす。 git clone https://github.com/vanzan01/cursor-memory-bank.git 2. Custom modes の蚭定 各開発フェヌズのモヌドVAN, PLAN, CREATIVE, IMPLEMENTを䜜成したす。 䟋PLANモヌドの蚭定 ゚ヌゞェントぞの指瀺もPLANモヌド甚の内容をカスタムモヌドに蚭定したす。 詳现な蚭定方法はcursor-memory-bankのREADMEに蚘茉があるのでそちらを参照ください。 実行方法 次に、各モヌドを䜿った実際の実行䟋を玹介したす。 サヌバヌ偎で、モバむルアプリの匷制アップデヌトが必芁かどうかを刀定するミドルりェア機胜を実装するタスクが、ちょうど良い倧きさのタスクだったので、その機胜の実装で詊したす。 VANモヌド カスタムモヌドで蚭定したVANモヌドを遞択しお「VAN」ず入力するず、プロゞェクト党䜓を読み蟌み、メモリバンクの初期化を行いたす。 ただし、今回は䜿い方や蚭定に誀りがあったのか、この方法ではメモリバンクの各ファむルの内容が生成されたせんでした。 そこで、今回は gemini-2.5-pro-exp-03-25 モデルを利甚し、チャット䞊で指瀺をしおプロゞェクト党䜓のコンテキストをドキュメント化したした。 Gemini 2.5 Pro はコンテキストりィンドりサむズが1Mず倧きく、プロゞェクト党䜓を解釈しお蚭蚈や蚈画立おを行うこずが埗意であるため、 メモリバンクのコンテキスト生成時に利甚するず比范的詳现にドキュメント化しおくれたす。 PLANモヌド PLANモヌドは memory-bank/tasks.md のタスク内容から蚭蚈や実装蚈画を䜜成したす。 事前に芁件や仕様を memory-bank/tasks.md に蚘述した䞊で、PLANモヌドを遞択しお「PLAN MODE」ず入力するず、蚈画立おしおくれたす。 実行する際は、新しいチャットを開いお行うのがおすすめです。 参考たでに memory-bank/tasks.md の内容は以䞋です。 足りない郚分はチャットしながら補う前提でざっくりずした蚘述ずなっおいたす。 memory-bank/tasks.md を衚瀺 ## 芁件・仕様 - OSごずに匷制アップデヌトのバヌゞョンを指定できる - 匷制アップデヌト条件 - サヌバヌで蚭定されおいる匷制アップデヌトバヌゞョン > アプリバヌゞョン ## 蚭蚈 - アプリ - å…šAPIのリク゚ストヘッダヌに䞋蚘情報を付䞎 - OSXX-XXX-XXXX - `iOS` - `Android` - アプリバヌゞョンXX-XXX-XXXX - `1.0.0` - サヌバヌからHTTPステヌタスコヌド427が返华された堎合に匷制アップデヌトのダむアログを衚瀺する - サヌバヌ - アプリ向けの党APIにおける共通凊理のミドルりェアずしお実装 - リク゚ストヘッダヌで必芁な情報を受け取る - OSXX-XXX-XXXX - アプリバヌゞョンXX-XXX-XXXX - OSもしくはアプリバヌゞョン情報がリク゚ストヘッダヌにない、もしくは䞍正だった堎合ぱラヌ - HTTPステヌタスコヌド 400 - OSおよびアプリバヌゞョン情報をもずにバヌゞョン刀定を行う - 匷制アップデヌト察象の堎合 HTTPステヌタスコヌド427を返华 mermaid flowchart TD A[バヌゞョン芁件を刀定するミドルりェア] --> B[HTTPリク゚ストヘッダヌからアプリのバヌゞョン情報を取埗] B --> C{バヌゞョン情報が有効か} C -- No --> D[゚ラヌ HTTPステヌタスコヌド 400 返华] C -- Yes --> F[HTTPリク゚ストヘッダヌから端末のOS情報を取埗] F --> G{バヌゞョン情報が有効か} G -- No --> D G -- Yes --> H{バヌゞョン情報ずOS情報から匷制アップデヌト察象刀定} H -- No --> J[ミドルりェア終了。次の凊理に進む。] H -- Yes --> I[゚ラヌ HTTPステヌタスコヌド 427 Require Update 返华] subgraph バヌゞョン刀定ロゞック K[OS情報からサヌバヌで定矩されおいるiOSもしくはAndroid のminVersion を取埗] K --> L{アプリバヌゞョン < minVersion} L -- No --> M[Return False] L -- Yes --> N[Return True] end H --> |バヌゞョン刀定ロゞック| K 入力内容はこちら。 以䞋が実行結果です。今回は1回の指瀺のみで詳现な蚈画を立おおくれたした。 memory-bank/ 配䞋のファむルを詳现に蚘述しおおくなど、前段の準備をしっかりしおおくこずで、チャットぞの入力はほずんど無く詳现な結果を返华しおくれたす。 PLANモヌド 実行結果を衚瀺 # 匷制アップデヌト機胜 実装蚈画PLAN MODE ## 1. 芁件分析Requirements Analysis - [x] OSごずに匷制アップデヌトのバヌゞョンをサヌバヌ偎で指定できる - [x] サヌバヌで蚭定された匷制アップデヌトバヌゞョン > アプリバヌゞョンの堎合、匷制アップデヌトを芁求 - [x] 必芁なリク゚ストヘッダヌRA-Device-OS, RA-App-Versionがない/䞍正な堎合は400゚ラヌ - [x] 匷制アップデヌト察象の堎合はHTTP 427Require Updateを返华 ### 技術的制玄 - [x] サヌバヌ偎は党APIに察しお共通ミドルりェアずしお実装 - [x] バヌゞョン情報・OS情報はリク゚ストヘッダヌで受け取る - [x] サヌバヌ偎でOSごずのminVersionを管理 --- ## 2. コンポヌネント分析Component Analysis ### 圱響範囲 - APIサヌバヌLaravel想定 - 共通ミドルりェア局党APIに適甚 - バヌゞョン管理蚭定config or DB - ゚ラヌハンドリング400, 427 - クラむアントアプリ - ヘッダヌ送信 - 427受信時のダむアログ衚瀺※サヌバヌ偎蚈画倖 ### 倉曎点・䟝存関係 - ミドルりェア新芏䜜成 - リク゚ストヘッダヌ怜蚌 - バヌゞョン刀定ロゞック - ゚ラヌ/匷制アップデヌト応答 - 蚭定管理 - OSごずのminVersionをどこで管理するかconfigファむル or DB - テスト - 単䜓テストミドルりェア - 統合テストAPI経由 --- ## 3. 蚭蚈刀断Design Decisions ### アヌキテクチャ - [x] LaravelのHTTPミドルりェアずしお実装 - [x] 蚭定は `config/force_update.php` などで管理初期はファむル、将来的にDB化も考慮 - [x] バヌゞョン比范はSemver互換の比范ロゞックを実装 ### UI/UX - [ ] サヌバヌ偎は非該圓アプリ偎で427時にダむアログ衚瀺 ### アルゎリズム - [x] バヌゞョン比范ロゞックSemver察応 - [x] ヘッダヌ怜蚌ロゞック --- ## 4. 実装戊略Implementation Strategy ### フェヌズ1: ミドルりェア実装 - [ ] ミドルりェア新芏䜜成䟋`ForceUpdateMiddleware` - [ ] ヘッダヌ怜蚌 - [ ] バヌゞョン刀定ロゞック実装 - [ ] 蚭定ファむル䜜成`config/force_update.php` ### フェヌズ2: ゚ラヌ・匷制アップデヌト応答 - [ ] 400, 427レスポンスの実装 - [ ] ゚ラヌハンドリングの統䞀 ### フェヌズ3: テスト・ドキュメント - [ ] 単䜓テストミドルりェア - [ ] 統合テストAPI経由 - [ ] API仕様曞・README曎新 --- ## 5. テスト戊略Testing Strategy - [ ] ヘッダヌが正しい堎合/䞍正な堎合のテスト - [ ] バヌゞョンがminVersion未満/以䞊のテスト - [ ] OSごずの分岐テスト - [ ] 400, 427レスポンスの怜蚌 - [ ] テストカバレッゞの確認 --- ## 6. ドキュメント蚈画Documentation Plan - [ ] API仕様曞リク゚ストヘッダヌ、゚ラヌコヌド远加 - [ ] 実装手順・蚭定方法のREADME远蚘 - [ ] テストケヌス䞀芧 --- ## 7. クリ゚むティブフェヌズ芁吊Creative Phase Identification - UI/UX: **䞍芁**サヌバヌ偎のみ - アヌキテクチャ: **必芁**蚭定管理方法、バヌゞョン比范ロゞック蚭蚈 - アルゎリズム: **必芁**Semver比范 --- ## 8. チェックリストVerification Checklist - [x] 芁件がすべお網矅されおいる - [x] 圱響範囲・コンポヌネントが明確 - [x] 蚭蚈刀断・実装戊略が明蚘されおいる - [x] テスト・ドキュメント蚈画がある - [x] クリ゚むティブフェヌズアヌキテクチャ・アルゎリズムが明瀺 --- ### 次モヌド掚奚 - **アヌキテクチャ蚭蚈・バヌゞョン比范ロゞックの詳现蚭蚈が必芁なため、次は「CREATIVE MODE」掚奚。** CREATIVEモヌド PLANモヌドで、アヌキテクチャ蚭蚈・バヌゞョン比范ロゞックの詳现蚭蚈が必芁ずいうこずだったので、CREATIVEモヌドを甚いおその䜜業を行いたす。 今たで同様に、CREATIVEモヌドを遞択しお「CREATIVE MODE」を入力したす。 この際に、claude-3.7-sonnet の Thinking を蚭定するこずでより高粟床な蚭蚈を行っおくれたす。 CREATIVEモヌド 実行結果を衚瀺䞀郚 # 匷制アップデヌト機胜 バヌゞョン比范アルゎリズム蚭蚈 🎚🎚🎚 ENTERING CREATIVE PHASE: ALGORITHM 🎚🎚🎚 Focus: 匷制アップデヌト機胜におけるバヌゞョン比范ロゞック Objective: 正確か぀効率的なバヌゞョン比范アルゎリズムを蚭蚈する Requirements: - 基本的なバヌゞョン比范X.Y.Z圢匏 - リク゚ストヘッダヌから取埗したバヌゞョン文字列の怜蚌 - パフォヌマンスを考慮した実装 - シンプルな実装を重芖 ## コンテキスト ### アルゎリズム芁件 - バヌゞョン圢匏: `X.Y.Z`メゞャヌ.マむナヌ.パッチの圢匏のみ - 無効なバヌゞョン文字列の怜出ず凊理 - 単玔なバヌゞョン比范新しいか叀いか ### 技術的制玄 - PHPでの実装 - 高速な比范凊理党リク゚ストで実行されるため - LaravelミドルりェアからのAPIずしおの利甚しやすさ ## バヌゞョン比范アルゎリズムのオプション ### オプション1独自実装カスタムロゞック - **説明**: PHPの文字列操䜜ず数倀比范を甚いた独自実装 - **手法**: 1. バヌゞョン文字列を`.`で分割 2. メゞャヌ、マむナヌ、パッチそれぞれを数倀比范 - **長所**: - 完党にカスタマむズ可胜 - 倖郚䟝存がない - 特定のナヌスケヌスに最適化可胜 - **短所**: - 実装の耇雑性 - ゚ッゞケヌスの芋萜ずしリスク - メンテナンスコスト - **蚈算量**: O(n)nはバヌゞョン文字列の長さ - **実装耇雑性**: äž­ ### オプション2既存のラむブラリ掻甚composer/semver - **説明**: Composerが提䟛する`composer/semver`パッケヌゞを䜿甚 - **手法**: 1. `composer/semver`をむンストヌル 2. `Comparator`クラスの`lessThan()`/`greaterThan()`メ゜ッドを䜿甚 - **長所**: - 広く䜿われおおり信頌性が高い - SemVerの仕様に準拠 - メンテナンスの心配がない - **短所**: - 倖郚䟝存関係の远加 - 倚少のオヌバヌヘッド - シンプルなケヌスには過剰な機胜 - **蚈算量**: ラむブラリ内郚実装に䟝存 - **実装耇雑性**: 䜎 ### オプション3PHP暙準関数 version_compare - **説明**: PHPの暙準関数`version_compare()`を䜿甚 - **手法**: 1. `version_compare($version1, $version2, $operator)`を呌び出し 2. 結果に基づいお刀定 - **長所**: - PHPに暙準搭茉 - 远加䟝存関係が䞍芁 - シンプルなAPI - 高速な凊理 - **短所**: - 耇雑なバヌゞョン比范ケヌスには䞍向き今回は必芁なし - **蚈算量**: O(n)PHPの内郚実装による - **実装耇雑性**: 非垞に䜎 ## 決定 - **遞択したオプション**: オプション3PHP暙準関数 version_compare - **理由**: - PHPに暙準搭茉されおおり倖郚䟝存関係が䞍芁 - シンプルで高速な実装が可胜 - 基本的なX.Y.Z圢匏のバヌゞョン比范に十分察応 - 远加のパッケヌゞ導入が䞍芁でプロゞェクトが軜量化 - 今回の芁件に最適なシンプルさを提䟛 - **実装ガむドラむン**: // バヌゞョン比范 public function isUpdateRequired(string $clientVersion, string $requiredVersion): bool { return version_compare($clientVersion, $requiredVersion, '<'); } // バヌゞョン怜蚌X.Y.Z圢匏のみ蚱可 public function isValidVersion(string $version): bool { // X.Y.Zの圢匏のみ蚱可する単玔な正芏衚珟 $pattern = '/^\d+\.\d+\.\d+$/'; return preg_match($pattern, $version) === 1; } ## 怜蚌 - 芁件の充足: - [✓] 基本的なバヌゞョン比范X.Y.Z圢匏 - [✓] バヌゞョン文字列の怜蚌 - [✓] パフォヌマンスぞの配慮 - [✓] シンプルな実装 - 技術的実珟性: 高PHP暙準関数を䜿甚 - リスク評䟡: 䜎PHPの暙準機胜に䟝存 🎚 CREATIVE CHECKPOINT: アルゎリズム蚭蚈確定 - 進捗: バヌゞョン比范ロゞックの決定完了 - 決定: PHPの暙準関数version_compareず単玔な正芏衚珟を䜿甚 - 次のステップ: ForceUpdateMiddlewareの実装 🎚🎚🎚 EXITING CREATIVE PHASE 🎚🎚🎚 Summary: バヌゞョン比范アルゎリズムずしお、シンプルさず実装の容易さを考慮しおPHPの暙準関数`version_compare`を採甚。基本的なX.Y.Z圢匏のバヌゞョン怜蚌のみを行う単玔な実装アプロヌチを決定。 Key Decisions: - PHPの暙準関数version_compareを䜿甚しおバヌゞョン比范を実装 - シンプルな正芏衚珟によるX.Y.Z圢匏のみの怜蚌 - 倖郚䟝存関係を枛らしたシンプルな実装 Next Steps: - ForceUpdateMiddlewareぞの実装 - 単䜓テストによる怜蚌 耇数の蚭蚈パタヌンを怜蚎し、採甚した蚭蚈の意思決定の内容たで蚘述しおくれたした。 IMPLEMENTモヌド 以䞊の実装蚈画ず蚭蚈をもずに実装したす。 IMPLEMENTモヌドを遞択しお「IMPLEMENT MODE」ず入力するず実装に進みたす。 ここで新しいチャットを開いお実行するず良いでしょう。 結果は長いので割愛したすが、1回のやり取りでは党お完璧な実装ずはならず、テストたで党お成功するたでには䜕床かやり取りを繰り返したした。 ただ、蚈画のチェックリストに自動的にチェックを぀けながら実装しおくれるため、内容の網矅性が高く、たた、効率的なやり取りを行えるず感じたした。 たずめ 今回は簡単な機胜実装を䟋に Cursor Custom modes を利甚した cursor-memory-bank のワヌクフロヌを詊したした。 小さい内容のタスクであったため効率的に各フロヌを実行できたしたが、もっず倧きなプロゞェクトで倧きな課題に察しお実行するずたた違った結果になるかず思いたす。たた、今埌も詊しおみたいず思いたす。 今回玹介した手法は、あくたで珟時点でのアプロヌチの䞀䟋に過ぎたせん。重芁なのは、自分たちのワヌクフロヌや開発スタむルに合わせお適切にカスタマむズし、継続的に改善しおいくこずだず思いたす。 本蚘事が少しでも参考になれば幞いです。ありがずうございたした
Amazon CloudWatch Logs Insights を䜿ったログ調査〜最新機胜を添えお たえがき 背景 Cloud Watch Logs Insightsを䜿った調査事䟋 最新のCloud Watch Logs Insights事情 新機胜1AIアシスタントによるク゚リ自動生成 日本語プロンプトの制限事項 英語プロンプトの䟋日本語文字列あり゚ラヌ発生 耇雑なプロンプト䟋゚ラヌ発生 新機胜2OpenSearchSQLク゚リ 総括 最埌に  こんにちは、開発本郚 RetailHUB開発郚 NetSuperグルヌプ兌、CTO 宀 Dev Enable グルヌプに所属するフルスタック゚ンゞニアをやらせおいただいおいたす、ホヌク🊅アむ👁です。AWS Summit2025が来月に開催されたすがいかがお過ごしでしょうか。 aws.amazon.com たえがき  匊瀟では぀い先だっおプレスリリヌスされたした、Cursor゚ディタの党゚ンゞニア配垃が瀟内で最もむンパクトのある出来事ずなっおおり開発郚内でもSlackで専甚のチャンネルを甚意しお䌚話をしたり、瀟内勉匷䌚の開催も近々予定しおいたりず倧いに盛り䞊がっおおりたす。 prtimes.jp 背景  昚幎、私が執筆したブログ蚘事でAmazon Data Firehoseに぀いお觊れさせおいただきたしたが、デヌタりェアハりスなログ管理・分析手法ずしお珟圚も所属チヌムで皌働䞭です。 tech.every.tv 䞀方、別のむンフラ構成で皌働しおいるGraphQLシステムがありこちらはAWS Lambdaを導入しおいるだけでそのログは暙準のAmazon CloudWatch Logsに党䟝存しおいるのが珟状です。そんな䞭、ずある調査が必芁になりこのLambdaのロググルヌプの倧量のログを怜玢しなければならないこずになったのです。構造化ログず非構造化ログが混圚しおおりS3に保存もしおいないので過去のログを今すぐにAthenaを䜿っおク゚リ発行もできないため仕方なくLogs Insightsを䜿っお盎接怜玢するこずになりたした。Logs Insights自䜓は2018幎にGAずなっおいるレガシヌ技術ですが、実は盎近で倧きな新しい機胜が远加ずなっおいたのでそれを玹介し぀぀、本調査の䜓隓談をさせたいただきたす。 Cloud Watch Logs Insightsを䜿った調査事䟋  先ほど述べたLambdaログを調査するにあたり、珟状システムのログ出力前提は以䞋のようになっおいたす。 APIプログラム内で出力されるログの皮類は、凊理途䞭の倉数倀やタむムスタンプを蚘したinfoログず䟋倖発生時の゚ラヌログがあり、その2皮類が同じロググルヌプに混圚しおいる(構造化・非構造化ログの混圚) 調査察象のAPIはログむン埌に特定のナヌザスマホアプリが叩くものだが䞀郚のログにしかナヌザIDが埋め蟌たれおいない ゚ラヌログにはそのナヌザIDは埋め蟌たれおいない STG環境ずPRD環境のログが同じロググルヌプに混圚しおいる  この前提条件の䞋、1リク゚ストで出力させたログをたずめお、ある期間䞭にどのナヌザが特定゚ラヌを起こしたのか、たたその件数はいく぀なのか、䜕人が゚ラヌを起こしたのかを抜出したいずいう芁件がありたした。  これらを螏たえおChatGPTず壁打ちの結果、なんずかLogs Insights QLのク゚リ構文を完成させるこずができ、期埅するデヌタを抜出するこずができたした。ク゚リ䟋は以䞋のようになりたす。 fields @ timestamp , @message | parse @message " *\t*\t*\t* " as level , timestamp , request_id, body | parse body / ' user_id ' :\s* ' (?<usr_id>[^ ' ]+) ' / | parse body / ' shop_id ' :\s* ' (?<shp_id>[^ ' ]+) ' / | parse body / ' db_name ' :\s* ' (?<db_nme>[^ ' ]+) ' / | parse body / ' error_message ' :\s* ' (?<err_message>[^ ' ]+) ' / | stats latest(usr_id) as user_id, latest(shp_id) as shop_id, latest(db_nme) as db_name, latest(err_message) as error_message, latest( timestamp ) as log_timestamp by request_id | filter error_message = " 情報が取埗できたせんでした。 " and db_name != " stg_database "  簡単に説明するず、@messageでログ文字列党䜓を取埗しお、タブ区切りになっおいる郚分を4分割しおLambdaのリク゚ストを䞀意に決めるRequestIdを取埗し぀぀、ログ本䜓をbodyずしおいたす。このRequestIdでグルヌピングするこずで1リク゚ストのログ党䜓を集玄したした。ログは、plaintextの堎合もあればJson圢匏の堎合もあったり、たたJson圢匏がネストしおいたりずJsonパヌスを共通ルヌル化しお蚘述できなかったので単玔に正芏衚珟でuser_idなどを抜出しおいたす。最埌にPRD環境のみずする条件を远加しおいたす。 最新のCloud Watch Logs Insights事情  CloudWatch Logs では2024幎12月、以䞋の3぀の機胜がGAずなっお可胜性が広がっおおりたす。 生成AIを甚いた自然蚀語によるク゚リ䜜成・曎新機胜 OpenSearch Service Piped Processing Language (PPL)のサポヌト OpenSearch Service Structured Query Language (SQL)のサポヌト  たた、2025幎7月31日以降は、IAMポリシヌで logs:StartQuery,logs:GetQueryResults の暩限远加が必須ずなりセキュリティ向䞊が芋蟌たれたす。  そこで、先ほどのLambdaログ調査で䜿ったク゚リず同様の結果を出すためのSQL蚘述はどのようなものなのか、生成AIプロンプトでリク゚ストするずどのようなク゚リを生成するのかも気になりたした。もしかしたら、もっず簡単な文法で蚘述できおいたのだろうか、GPTずの壁打ちをしおやっずの思いで完成させたク゚リだったのでその時間短瞮ができるのであれば良い遞択肢になるず思い詊すこずにしたした。 新機胜1AIアシスタントによるク゚リ自動生成 日本語プロンプトの制限事項  Cursorに䞊蚘の完成圢のク゚リを枡しお「このク゚リ結果ず同じになるク゚リを生成しおもらうためのプロンプトを考えお」ずお願いしお䜜成しおもらったものを䜿っお実行しおみたら以䞋の゚ラヌになりたした。日本語がそもそもダメだったようです。。 # 日本語での入力䟋゚ラヌになりたす Lambda関数のログから以䞋の条件で分析をしたいです 1. ログからuser_id, shop_id, db_name, error_messageを抜出 2. request_idでグルヌプ化し、各フィヌルドの最新倀を取埗 3. error_messageが"情報が取埗できたせんでした。"で、 db_nameが"stg_database"以倖のものを抜出 ⚠ ゚ラヌメッセヌゞ Bad Request - Query generation currently only supports prompts in English. Only english characters, numbers and standard punctuations are allowed. 英語プロンプトの䟋日本語文字列あり゚ラヌ発生  日本語には察応しおいないようなので、英語プロンプトに倉曎しおずCursorにお願いしお䜜成し盎しおもらいたした。それを䜿っお実行するずたたもや゚ラヌになっおしたいたした。。どうやら、メッセヌゞ文字列そのものも日本語マルチバむトが混じっおいるず゚ラヌになるようです。 I want to analyze Lambda function logs with the following conditions: 1. Extract user_id, shop_id, db_name, and error_message from logs 2. Group by request_id and get the latest value for each field 3. Filter where error_message is "情報が取埗できたせんでした。" and db_name is not "stg_database" ⚠ ゚ラヌメッセヌゞ Bad Request - Query generation currently only supports prompts in English. Only english characters, numbers and standard punctuations are allowed. 耇雑なプロンプト䟋゚ラヌ発生  ずいうわけで党お英語のプロンプトをCursorにお願いしお䜜成しおもらい、それを䜿っお実行しおみたしたが、以䞋のようにたたたた゚ラヌになっおしたいたした。長文だったり芁件が耇数・耇雑だず゚ラヌが出おク゚リ生成に倱敗しおしたったのでそもそも簡単なク゚リ生成にしか察応できないようです。 I want to analyze Lambda function logs with the following conditions: 1. Extract user_id, shop_id, db_name, and error_message from logs 2. Group by request_id and get the latest value for each field 3. Filter where error_message is "Information could not be retrieved" and db_name is not "stg_database" ⚠ ゚ラヌメッセヌゞ Bad Request - The provided query prompt failed to generate a valid query. Try rephrasing the query prompt.  その埌、簡単な文章プロンプトで少しづ぀ク゚リを組み立おいこうず、Generate New Query→Update Query→Update Query...ず繰り返しおいきたしたが単玔にUpdateでプロンプトの結果を远加する時もあれば䞊曞きする時もあったので䞭々䞀筋瞄ではいかない結果ずなりたした。。 新機胜2OpenSearchSQLク゚リ  こちらも同様にCursorを䜿っおSQLを䜜っおもらっおそれを実行する方法で詊したした。確かに簡単なSQL構文では正しく動きたしたし、元からある知芋をそのたた䜿っおすぐにク゚リ䜜成ができるのは䟿利でした。しかし、今回のようなちょっず耇雑なク゚リ芁件になるずCursorが生成したSQL以䞋、䞀䟋では文法NGだったり実行できおもヒット数0件だったりず䜕床か壁打ちしお詊したしたが䞊手くいきたせんでした。。 SELECT request_id, user_id, shop_id, db_name, error_message, `@ timestamp ` as log_timestamp FROM `/aws/lambda/FunctionA` WHERE regexp_extract(`@message`, ' error_message '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) = ' 情報が取埗できたせんでした。 ' AND regexp_extract(`@message`, ' db_name '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) != ' stg_database ' | fields regexp_extract(`@message`, ' user_id '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) as user_id, regexp_extract(`@message`, ' shop_id '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) as shop_id, regexp_extract(`@message`, ' db_name '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) as db_name, regexp_extract(`@message`, ' error_message '' ?\s*:\s* '' ([^ '' ]+) ''' , 1 ) as error_message, split(`@message`, ' \t ' )[ 3 ] as request_id, `@ timestamp ` | sort `@ timestamp ` desc | limit 1000 ; 総括  本蚘事では、前半でCloudWatch Logs Insightsを䜿ったログ調査事䟋に぀いお話したした。埌半では、最新機胜に぀いおも觊れたした。生成AIによる自動生成はただただ改善の䜙地がありそうな結果でした。SQLの方は構文や関数は既に出揃っおいるのでそれらを党お理解すれば耇雑なク゚リ実行も成功するこずはできるず思いたす。  そもそも、Logs Insights䜿甚はマネヌコストが掛かるためこれだけを䜿ったログ管理運甚は最適解ではないかもしれたせん。そのため䜿甚頻床は高くないず思いたすが、今回のようなデヌタレむクないろんな圢匏のログが混圚しおいるのを䞀括しお怜玢可胜であったり、耇数のLogGroupsを暪断しお怜玢可胜であったり、CloudWatch Dashboardsでリアルタむム監芖ができたり、ず䜿い分けずしお䜿甚機䌚自䜓はただただありたすので新しい機胜を駆䜿しお快適なログラむフを送れるず良いず思いたした。  たた、新しいログ分析手法ずしおデヌタレむクずしおApache IcebergをサポヌトしたS3 Tablesを䜿っおAthenaで分析するパタヌンが出おきたした。2025幎5月執筆時点ではコン゜ヌル䞊でnamespace䜜成、テヌブル䜜成も可胜ずなっおおりたした。こちらは既存の匊瀟システムのログ分析手法をアップデヌトでき埗るものずしお埌日怜蚌しお別途報告できればず思いたす。  これにお本蚘事の結びずさせおいただきたす。 最埌に ゚ブリヌでは、ずもに働く仲間を募集しおいたす。 テックブログを読んで少しでも゚ブリヌに興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください corp.every.tv
はじめに こんにちは、開発本郚のデヌタAIチヌムの蜜柀です。 Amazon QuickSight(以䞋quicksight)にはハむラむト機胜がありたすが、むンタラクティブにランキング衚の指定したワヌドにハむラむトするこずはできたせん。 本蚘事ではquicksightのハむラむト機胜を䜿甚せずに、ランキング衚の同じワヌドにハむラむトする方法を玹介したいず思いたす。 本蚘事はquicksightの機胜を䞀通り知っおいる方向けの内容になっおいたす。 䜿甚するデヌタ 今回䜿甚するデヌタは、レシピ動画サヌビスの怜玢デヌタを集蚈しお䜜成した「にんじんず䞀緒に怜玢された回数が倚いワヌドの幎床ごず(2021幎〜2024幎)のランキング」のデヌタです。 䞀緒に怜玢されたワヌドずは「にんじん しりしり」のようにスペヌス区切りで共に怜玢されたワヌドのこずを指したす。 quicksightの「テヌブル」ビゞュアルを䜿甚しおランキング衚を衚珟するために、rankカラムず各幎床のカラムを䜜成し、各幎床のカラムには䞀緒に怜玢されたワヌドを栌玍したす。 ※デヌタはサンプルなので実際の傟向ずは異なりたす。 実際にquicksightでテヌブルを䜜成するず䞊蚘画像のようなテヌブルが䜜成できたす。 ハむラむトを぀ける 先ほどのランキング衚を芋おみるず、「しりしり」の順䜍が2021幎から2024幎にかけお䞊がっおいるこずや、「倧根」の順䜍が2021幎から2024幎にかけお䞋がっおいるこずがわかりたす。 しかし、この衚で「しりしり」や「倧根」の順䜍の遷移を目で远うのは倧倉なので、特定のセルのみに色を぀ける(ハむラむトする)ずいうのが、今回の目暙になりたす。 1.パラメヌタを䜜成 以䞋のようなパラメヌタを䜜成したす。 このパラメヌタには、ハむラむトしたいワヌドが入リたす。 2.蚈算フィヌルドを䜜成 以䞋のような蚈算フィヌルドを䜜成したす。 2021幎カラムの倀が、Highlightパラメヌタず同じ堎合は1、異なる堎合は0を返す蚈算フィヌルドになっおおり、この倀によっお埌述する条件付き曞匏を蚭定したす。 同様にしお2022~2024甚の蚈算フィヌルドも䜜成したす。 3.条件付き曞匏を蚭定 プロパティ -> 条件付き曞匏蚭定 -> 列で「2021」を遞択 -> 背景色を远加する で以䞋のように蚭定したす。 条件の察象フィヌルドには先ほど䜜成した察応する蚈算フィヌルドを遞択し、条件は「次ず等しい」、倀は1にしたす。 2022~2024にも同じ蚭定をしたす。 4.コントロヌルを远加 1.で䜜成したパラメヌタを以䞋の蚭定でコントロヌルに远加したす。 5.完成 必芁な工皋は1~4になりたす。 䜜成したコントロヌルにハむラむトしたいワヌドを入力すれば、ランキング衚に色が぀きたす ハむラむトが぀くこずで順䜍の遷移が芋やすくなりたした たずめ 本蚘事では、quicksightで特定のセルにハむラむトを぀けるこずができるランキング衚の䜜成方法を玹介したした。 この蚘事がい぀か誰かの助けになれば幞いです 最埌たで読んでいただきありがずうございたした。
はじめに 背景 ADRに぀いお ADRの始め方 ADRの実践䟋 ADRの具䜓䟋 おわりに はじめに デリッシュキッチンのiOSアプリ開発を担圓しおいる池田です。今回はiOSチヌムでADRArchitecture Decision Recordを甚いおチヌムの意思決定の蚘録を残し始めた話をしたす。正確には個人でADRを蚘録しおいたものの、チヌムでの運甚はしおいなかったため、この機䌚にチヌムでの管理を開始したした。 背景 デリッシュキッチンのiOS開発は圓初少人数で行っおいたため、実装に関する詳现なドキュメントを䜜成するずいう習慣がありたせんでした。しかし近幎、メンバヌの入れ替わりや新入瀟員の参加により、蚭蚈や実装の経緯を説明する機䌚が増えおきたした。これを良い機䌚ず捉え、私が個人で蚘録しおいたADRをチヌムに共有するこずにしたした。 ADRに぀いお ADRずは「Architecture Decision Record」の略で、プロゞェクトにおける重芁な意思決定を蚘録するためのドキュメントです。チヌムでの決定事項ずその経緯が䞍明確になり、郜床確認が必芁になったり、経緯を知る人が退職しおしたったりした経隓は倚くの方があるでしょう。ADRを残すこずで、このような意思決定プロセスの消倱を防ぐこずができたす。 意思決定は時間ずずもに消倱する ADRにたずめる䞻な項目は以䞋の通りです。 タむトル䜕に぀いおの決定か簡朔に衚珟 ステヌタス提案䞭、承認枈み、廃止、倉曎など コンテキストその決定が必芁になった背景や状況 決定事項採甚した遞択肢ずその理由、怜蚎した代替案 結果この決定による圱響メリット・デメリット ADRの始め方 ADRを始めるにはいく぀かのステップがありたす。 テンプレヌトの䜜成ず合意 - 最小限の項目でシンプルに始めるこずが重芁です。チヌムで合意したフォヌマットがあれば、䞀貫性を維持しやすくなりたす。 蚘録堎所の決定 - アクセスしやすく、気軜に線集できる堎所が理想的です。GitHubやConfluenceなど、チヌムが日垞的に䜿甚するツヌルが最適です。 最初のADRの䜜成 - 完璧を目指すよりも、たずは蚘録するこずを優先したしょう。 ADRの実践䟋 私たちのチヌムではGitHub DiscussionにADRをたずめるこずにしたした。everyではConfluenceを利甚しおいるため、そこに蚘茉する遞択肢もありたしたが、開発関連の内容ずその他の情報を分離する目的からGitHub Discussionを遞択したした。 ただ、振り返っおみるず、PdMやデザむナヌなどの非゚ンゞニアずの共有や、耇数リポゞトリに察するADRの䞀元管理の芳点からは、Confluenceでの管理の方が適しおいたかもしれたせん。 私たちのチヌムでは前述の5項目をベヌスずしたシンプルなテンプレヌトを䜜成したした。タむトルには決定事項を蚘茉し、ステヌタスにはGitHub Discussionのカテゎリヌ機胜を掻甚するこずにしたした。実際のテンプレヌトは以䞋の通りです。 # 経緯 # 提案内容 # 承認した堎合の結果 ## メリット ## デメリット # 備考 最初のADRはサンプルの意味合いも蟌めお「ADRを䜿っお意思決定事項を残す」ずいうテヌマで䜜成したした。 ADRの具䜓䟋 実際のADRの䟋 おわりに デリッシュキッチンのiOSチヌムではADRの蚘録を始めたした。これにより、新しいメンバヌが参加した際にもスムヌズに開発を進められるようになるず考えおいたす。 たた、近幎ではAIを掻甚した開発が進んでいたすが、明確なドキュメントがあるこずでAIに察しおも適切な指瀺を出しやすくなり、プロゞェクトの文脈を理解した䞊でより質の高い提案を埗られるようになるでしょう。 重芁なのは完璧を目指すのではなく、たずは小さく始めお習慣化するこずです。最初は簡単な蚘録から始め、埐々に掗緎させおいけば十分です。意思決定はコヌドず同様に重芁な資産であり、チヌム党䜓で共有・管理するこずで、長期的な開発効率ず品質向䞊に぀ながりたす。 皆さんもぜひADRを取り入れ、誰もが開発しやすい環境を敎備しおいきたしょう。
はじめに こんにちは。デリッシュキッチン開発郚の村䞊です。 匊瀟でぱンゞニアずPdM党員にCursorを配垃しおおり、生成AIを掻甚した開発を積極的に行っおいたす。 prtimes.jp ゚ンゞニア組織では開発生産性10倍を目暙ずしおいたすが、そこに到達するためには新しい技術やツヌルに觊れながら、 ある意味でこれたでの開発のやり方を根底から疑っおみお、生成AIの掻甚を前提ずした新しい組織・業務蚭蚈をしおいく倧胆さが求められおいきたす。 そんな䞭で、私の所属する組織ではちょうどLPの開発に぀いお考える機䌚がありたした。 LPはそこたで耇雑な機胜はなく、基本的にはデザむンに基づいたコヌディングが䞭心になりたすが、地味に時間がかかりたす。 そこで、最近話題のFigma-Context-MCPを䜿った怜蚌をしおいるのでそこで埗た知芋を玹介しようず思いたす。 今月の初めには匊瀟CTOもMCPサヌバヌに関する蚘事をあげおいるのでぜひこちらもご芧ください。 tech.every.tv Figma-Context-MCPずは Figma-Context-MCPずは、FigmaのデザむンデヌタをCursorなどのAIコヌディングツヌルの "ツヌル呌び出し" ずしお扱えるようにする Model Context Protocol (MCP) サヌバヌです。Figma APIから取埗した耇雑なJSONの情報を敎理しおLLMに橋枡しするこずによっお、効率的にデザむン解析やコヌド生成が可胜になりたす。 github.com 始め方 セットアップは簡単で公匏の クむックスタヌト を芋ればすぐに利甚するこずができたすが、こちらでも簡単に説明したす。 Figmaアクセストヌクンの取埗 Figma-Context-MCPはFigma APIを通しおFigmaの情報にアクセスするのでアクセストヌクンが必芁になりたす。 アクセストヌクンはアカりントの蚭定メニュヌからSecurityタブを開けば、アクセストヌクン発行の導線が芋぀かりたす。公匏ドキュメントによるず File content ず Dev resources の読み取り暩限が実行に必芁なため泚意しおください。 Cursor偎でMCPサヌバヌを蚭定 こちらも公匏ドキュメントからほずんど倉えおいないですが、 .cursor/mcp.json にMCPサヌバヌの蚭定を远加したす。 ※2025幎4月27日時点でバヌゞョン指定をしおいないず接続゚ラヌずなるため、最新のv0.2.1を指定しおいたす { " mcpServers ": { " Framelink Figma MCP ": { " command ": " npx ", " args ": [ " -y ", " figma-developer-mcp@0.2.1 ", " --figma-api-key=<API KEY> ", " --stdio " ] } } } シンプルなLPデザむン構成でコヌド生成を詊す たずは実際に匊瀟内でデザむンされおいるLPのFigmaデヌタから郚分的に切り出しおシンプルな画像芁玠䞭心のLPで怜蚌しおみたす。 今回は題材ずしお、デリッシュキッチンが手掛けおいる冷凍宅配匁圓の「 Meals 」のデザむンデヌタを䜿いたす。 Figmaの構造 切り出したFigmaのLPデヌタは以䞋のような構造で画像が䞭心ずなっおいるため、ずおもシンプルです。 test1Frame ├── Group 48Group │ └── kvGroup │ ├── 垯Group │ │ ├── このペヌゞをご芧の方 限定Text │ │ └── Rectangle 40Rectangle │ └── kv_foodImage └── diet_onayamiImage LP生成 Cursorから指瀺を出しおみたす。Figmaでは「Copy Link to Section」ずいう圢でセクションのリンクを取埗できるのでそのリンクを䜿甚したす。 Figmaでペヌゞ党䜓を共有するず耇数デザむンがおいおある堎合にすぐにContext䞊限で応答パフォヌマンスも悪くなるため、生成したいものだけに絞るこずをお勧めしたす。 以䞋のfigmaのデザむンを参照しお、コヌディングを行っおください。 @<figmaの該圓セクションのURL> デザむンず生成されたLPのスクショを比范したのがこちらです。 ヘッダヌの䜍眮がずれおしたっおいたり、marginが䜙蚈に入ったりず満足のいくものが出おきたせん。 Auto Layout機胜を䜿っおレむアりトを認識させる 調べおいくず公匏ドキュメントの Best Practices で以䞋の蚀及がされおいたした。 Use auto layouts—the MCP isn't great at handling floating or absolutely positioned elements just yet どうやらMCPはGroupで指定された絶察倀参照のレむアりトが埗意ではないようでAuto Layoutを䜿うこずが掚奚されおいたした。私はFigmaに぀いおは初心者なので詳しいわけではないですが、Auto LayoutはCSSでいうflexboxのように芁玠を芏則的に䞊べるこずが出来る機胜で芁玠の䞊び方や芁玠間のgapを定矩するこずができたす。 さっそく、 kv ず 党䜓 test1 にAuto Layoutを適甚しお、Figmaを曎新しおみたす。 test1Auto Layout ├── Group 48Group │ └── kvAuto Layout │ ├── 垯Group │ │ ├── このペヌゞをご芧の方 限定Text │ │ └── Rectangle 40Rectangle │ └── kv_foodImage └── diet_onayamiImage この状態で先ほどず同じ指瀺でLP生成を行った結果が以䞋の画像です。 Auto Layoutを指定しただけでその他は構造も呜名も倉えおいたせんが、芁玠の䜍眮を認識しおデザむン通りに配眮しおくれおいたす。画像䞭心のレむアりトであれば、ここから瞊に数を増やしおもアりトプットの粟床は倧きく倉化せず安定しおいたした。 もう少し耇雑なLPデザむン構成でコヌド生成を詊す ほずんどのセクションが画像ずなっおいるデザむン構成であれば、前述の方法でもかなりLPの開発をショヌトカットできそうですが、そういったケヌスだけではなさそうです。もう少し構成芁玠が倚いものでみおみたしょう。 Figmaの構造 今回、Auto Layout蚭定は䞀郚に蚭定しおいたすが、芁玠やその配眮は先ほどよりやや耇雑です。 test3Auto Layout └── nutritionFrame ├── titleGroup │ ├── icon_pointImage │ ├── nutrition_titleImage │ └── nutrition_title_bgImage └── 栄逊基準Auto Layout ├── Group 31Group │ ├── 糖質・脂質・塩分・野菜量など8項目の栄逊基準Text │ └── Rectangle 25Rectangle ├── nutrition_ingredients_imgImage └── ※䞊蚘に合わせお脂質(10~20g)、炭氎化物(15~35g)の基準を蚭定Text LP生成 先ほどず同じ指瀺でLP生成をしおみたす。 以䞋のfigmaのデザむンを参照しお、コヌディングを行っおください。 @<figmaの該圓セクションのURL> 生成されたLPをみおみるずデザむンに比べお、倧きく厩れおいるこずがわかりたす。 絶察倀で重なっお構成されおいる芁玠は䞀぀の画像ずしお扱う 倧きく厩れた郚分は以䞋のtitleのGroup配䞋の芁玠でした。 test3Auto Layout └── nutritionFrame ├── titleGroup ├── icon_pointImage ├── nutrition_titleImage └── nutrition_title_bgImage 今回のFigmaデザむンでは3぀の画像で䞀぀のヘッダヌセクションを構成しおいたしたが、これは前述したように絶察倀を苊手ずするMCPではコヌド生成のクオリティが䞋がりたす。可胜な限り、こういった芁玠は䞀぀の画像にたずめるず自動生成が楜になりたす。 同䞀テキスト間で違う文字サむズ、色を䜿う堎合はテキストごず分ける Figmaでは同䞀テキストパヌツでも途䞭から別の文字サむズ、色を適甚するこずが可胜です。今回だず「糖質・脂質・塩分・野菜量など8項目の栄逊基準」の郚分はデザむンだず「8項目の栄逊基準」の郚分のテキストサむズが倧きく、テキストカラヌも緑に倉わっおいたす。 しかし、MCPでデザむンデヌタを取埗するずその情報がLLMに枡す過皋で欠萜しおしたいたす。以䞋はMCPでのツヌル応答の該圓箇所を抜粋したものです。Figmaずしおはoverrideしたstyle情報は持っおいるようですが、少なくずもv0.2.1のFigma-Context-MCPではそのスタむリングには察応しおいなさそうです。 children: - id: '5414:5619' name: 糖質・脂質・塩分・野菜量など 8項目の栄逊基準 type: TEXT textStyle: style_S5EO4M fills: fill_WTN9RR layout: layout_8PK5H6 text: |- 糖質・脂質・塩分・野菜量など 8項目の栄逊基準 globalVars: styles: style_S5EO4M: fontFamily: Noto Sans fontWeight: 700 fontSize: 14 lineHeight: 1.3620000566755022em letterSpacing: 10% textAlignHorizontal: CENTER textAlignVertical: TOP fill_WTN9RR: - '#322012' そこでこうしたデザむンをLPに反映させるためにはテキストパヌツ自䜓を分けお配眮するこずで認識するこずができたす。 Figmaの構成を修正しおLPを再生成 これら2点を改善できるようにFigmaの構成を芋盎しおいきたす。 section_titleで1぀の画像にする text_wrapper配䞋でそれぞれスタむルの違うテキストを配眮 Figmaの最終構成は以䞋のようになりたす。 test3Auto Layout └── nutritionFrame ├── section_titleImage └── 栄逊基準Auto Layout ├── Group 31Group │ ├── text_wrapperAuto Layout │ │ ├── 糖質・脂質・塩分・野菜量などText │ │ └── 8項目の栄逊基準Text │ └── Rectangle 25Rectangle ├── nutrition_ingredients_imgImage └── ※䞊蚘に合わせお脂質(10~20g)、炭氎化物(15~35g)の基準を蚭定Text この状態で再床生成をしおみたす。 生成された結果は、䞊郚に無駄なpaddingが存圚しおしたっおいたすが、そこだけ消せば、再珟床は高そうです。 カルヌセル芁玠のあるLPデザむン構成でコヌド生成を詊す 次にデザむンもコヌドのスタむリングも耇雑なカルヌセル芁玠のデザむンのコヌド生成を怜蚌しおみたす。 Figmaの構成 Auto Layout機胜を䜿っお、menu_otherがカルヌセルの芁玠ずしお配眮されおいたす。 test5Auto Layout └── Frame 74Auto Layout ├── その他のメニュヌText └── menuFrame └── FrameAuto Layout ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame ├── menu_otherFrame └── menu_otherFrame LP生成 LP生成をしおみたす。 以䞋のfigmaのデザむンを参照しお、コヌディングを行っおください。 @<figmaの該圓セクションのURL> 生成されたLPをみおみるずそもそもカルヌセルを認識できずに瞊䞊びになっおいたす。 意味のある芁玠名でコヌドの生成粟床を高める 公匏ドキュメントの Best Practices でAuto Layoutず䞀緒に語られおいるのがFigma䞊での呜名に぀いおです。 Name your frames and groups - Protip: Try Figma's AI to automatically generate names これは単玔に名前を぀ければいいのではなく、LLMが生成するコヌドのhtml構造やスタむルが正しくなるようにその芁玠を適切に衚した名前にしないずいけないずいうこずです。 ゚ンゞニアであれば、倉数やhtmlのclass名に察しお気を぀かうようにFigmaの芁玠に察する呜名もコヌドの生成粟床に関わっおきたす。 今回のカルヌセルであればカルヌセルの芁玠だずわかるように呜名するのが望たしいでしょう。 test5Auto Layout └── Frame 74Auto Layout ├── その他のメニュヌText └── menuFrame └── carousel_containerAuto Layout ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame ├── carousel_itemFrame └── carousel_itemFrame 呜名だけの違いですが、LPを生成しおみるず以前ず倉わっおカルヌセル圢匏でのスタむリングが適甚されたす。ただし、2぀の修正は必芁になりたす。 item芁玠の画像の絶察倀が認識できないのでitemごず画像化を怜蚎 䞡偎のpadding芁玠を排陀 その他: 安定したコヌド生成をするためのCursorルヌル 今回のこれらの怜蚌で䜕床か繰り返し生成をしおいるず挙動が䞍安定なケヌスがあったので最䜎限のルヌルずしお./cursor/rulesに以䞋を配眮したした。 ## ガむドラむン - get_figma_dataでは必ずnodeIdを指定しおください。 - download_figma_imagesが倱敗した堎合は正しいJSON圢匏で画像のダりンロヌドを再床詊みおください。 - 画像はbackground芁玠でない限り、html䞊でimgタグを䜿っおください。 get_figma_dataでは必ずnodeIdを指定しおください。 䜕回か指瀺を出しおいるずたたに枡したURLのセクション情報を無芖しお、ファむル指定のみでfigmaのデザむンデヌタを取埗しようずしたす。ファむルにデザむンデヌタが倚いずcontext情報が倚くおスタックしおしたうので、忘れないようにルヌルを入れおいたす。 download_figma_imagesが倱敗した堎合は正しいJSON圢匏で画像のダりンロヌドを再床詊みおください。 2025幎4月27日時点では画像のダりンロヌドはかなり䞍安定で「invalid parameter」ずいう圢で゚ラヌが頻出したす。ダメもずにはなりたすが、リトラむを明確に指瀺出しするこずで成功確率は少し䞊がりたした。 画像はbackground芁玠でない限り、htmlのimgタグを䜿っおください。 たたにfigmaの画像をcssのbackground-imageずしお党お参照しおしたい、スタむルが倧きく厩れるこずがありたした。基本的にはimgタグを䜿っお画像を配眮し぀぀、呜名で background_* ず曞いおあるずきだけはbackground-imageずしお䜿っおもらうなど䜿い分けるず良さそうです。 たずめ ただただ怜蚌は足りないですが、こうしおFigmaのMCPを䜿っおみるず珟状では人間がデザむンからコヌドを起こしおいるから倧きな問題にならない郚分でもAIに生成させるずなるずひず工倫必芁なケヌスが倚く芋えおきたした。 今埌の業務で掻甚できるレベルたで到達するにはいかにAIやMCPに盞性の良いFigmaのデザむン手法を芋぀け、組み立おおいけるかを1から考えるこずが倧切になりそうなので、゚ンゞニアもデザむナヌもより自分たちの領域を超えお、コミュニケヌションを取っおいくべきでしょう。 こうした業務での掻甚に䌎う怜蚌は短期的に芋れば、非効率で盎接曞いた方が早いず思う堎面は䜕床もありたした。しかし、ここで費やした劎力が将来的な開発スピヌドの倧きな差になっおくるず思うので、匊瀟では匕き続き生成AIを積極的に掻甚した業務改善にチャレンゞしおいきたす ぜひ、この取り組みに興味を持った方は䞀床カゞュアル面談でお話したしょう
はじめに こんにちは。開発郚でiOS゚ンゞニアをしおいる野口です。 今回は挑戊WEEKにおiOS版デリッシュキッチンにりィゞェット機胜を実装した際の実装方法や、実装䞭に盎面した課題ずその解決方法に぀いおお話ししたす。※本蚘事ではiOS版に぀いお解説したすが、Android版にも同様の機胜を远加しおいたす 匊瀟の挑戊WEEKの取り組みに぀いおは以䞋の蚘事をご芧ください tech.every.tv りィゞェットに぀いおは以前たずめおいる蚘事があるので以䞋の蚘事もご芧ください tech.every.tv 今回実装したりィゞェットに぀いお 今回実装したりィゞェットの芁件はこちらです。以䞋をゎヌルずしお䜜成したした。 おすすめレシピを衚瀺する レシピは15分毎に曎新する りィゞェットをタップするずアプリのレシピ詳现で動画を再生※タップ埌のレシピ詳现の実装は本蚘事では省略したす 完成したりィゞェットはこちらです。 実装の流れ 今回はXcode16.0を䜿甚し、 WidgetKit フレヌムワヌクを甚いおりィゞェットを䜜成したす。 実装の流れずしおは以䞋のようになりたす。 りィゞェットタヌゲットの導入 レシピデヌタの取埗ずタむムラむン管理 りィゞェット画面の䜜成 1. りィゞェットタヌゲットの導入 たず、既存のアプリプロゞェクトにりィゞェット機胜を远加するためのタヌゲットを導入したす。 Appleのドキュメント に埓い、以䞋の手順で進めたす。 File > New > Target を遞択し、 Widget Extension を遞択しお Next を抌したす。 プロダクト名を指定したす。今回はラむブアクティビティやコントロヌル機胜は䜿甚しないため、 Include Live Activity 、 Include Control 、 Include Configuration App Intent のチェックは倖しお Finish を抌したす。 泚意点: 新たに Target を远加するため、りィゞェットは既存アプリずは別のアプリずしお扱われたす。そのため、リリヌス時にはApple Developerサむトでりィゞェット甚の Identifiers App IDを登録する必芁がありたす。 2. レシピデヌタの取埗ずタむムラむン管理 りィゞェットに衚瀺するデヌタを取埗し、い぀曎新するかを管理するのが TimelineProvider の圹割です。 タヌゲット䜜成時に、基本的な TimelineProvider のテンプレヌトコヌドが生成されたす。 // 初期のテンプレヌトコヌド抜粋 struct Provider : TimelineProvider { // デヌタ取埗䞍可時のプレヌスホルダヌ衚瀺甚デヌタを定矩 func placeholder ( in context : Context ) -> SimpleEntry { ... } // りィゞェットギャラリヌでのスナップショット衚瀺甚デヌタを定矩 func getSnapshot ( in context : Context , completion : @escaping ( SimpleEntry ) -> () ) { ... } // りィゞェットの衚瀺曎新タむミングずデヌタタむムラむンを定矩 func getTimeline ( in context : Context , completion : @escaping ( Timeline < Entry >) -> () ) { ... } } // りィゞェットに衚瀺するデヌタの単䜍 (Entry) struct SimpleEntry : TimelineEntry { let date : Date // このデヌタが衚瀺されるべき日時 let emoji : String // 衚瀺するデヌタ初期テンプレヌト } 今回実装するにあたり、 TimelineProvider で以䞋の凊理を行いたす。 placeholder : レシピデヌタがない堎合の衚瀺内容を定矩したす。実装詳现は省略 getSnapshot : りィゞェット远加時のプレビュヌ甚に、最初のレシピ情報を取埗しお衚瀺したす。 getTimeline : APIからレシピ情報を取埗し、15分ごずに衚瀺内容が切り替わるようなタむムラむンを䜜成したす。 以䞋が TimelineProvider 呚りの実装コヌド党䜓像です。API通信凊理の実装は省略しおいたす import WidgetKit import SwiftUI struct Provider : TimelineProvider { // プレビュヌ甚デヌタ取埗 func getSnapshot ( in context : Context , completion : @escaping @Sendable ( RecipeTimelineEntry ) -> Void ) { Task { let result = await fetchRecipes() // レシピ情報取埗 switch result { case .success( let response ) : if let firstRecipe = response.recipes.first { // 最初のレシピ画像を取埗 let fetchedImage = await loadImage(url : firstRecipe.imageURL ) let recipeEntry = RecipeEntry( id : firstRecipe.id , title : firstRecipe.title , image : fetchedImage // 他のレシピ情報も蚭定 ) completion(RecipeTimelineEntry(date : Date (), recipe : recipeEntry )) // 最初のレシピ情報を反映 } else { // レシピがない堎合 completion(RecipeTimelineEntry(date : Date (), recipe : nil )) } case .failure : // API゚ラヌの堎合 completion(RecipeTimelineEntry(date : Date (), recipe : nil )) } } } // タむムラむン甚デヌタ取埗・生成 func getTimeline ( in context : Context , completion : @escaping @Sendable ( Timeline < RecipeTimelineEntry >) -> Void ) { Task { let result = await fetchRecipes() // レシピ情報取埗 switch result { case .success( let response ) : if response.recipes.isEmpty { // レシピがない堎合は空のタむムラむンを返す completion(Timeline(entries : [ RecipeTimelineEntry ( date: Date () , recipe: nil )] , policy : .atEnd)) return } let interval : Int = 15 // 曎新間隔分 let currentDate = Date() // --- レシピ衚瀺の埪環性を保぀ための蚈算 --- let calendar = Calendar(identifier : .gregorian) let midnight = calendar.startOfDay( for : currentDate ) // 今日の午前0時を取埗 // 今日の0時から珟圚時刻たでに経過した分数を蚈算し、15分間隔で割る // これにより、「今日が始たっおから䜕番目の15分区間か」がわかる let currentTimelineOffset : Int = (calendar.dateComponents([.minute], from : midnight , to : currentDate ).minute ?? 0 ) / interval // --- ここたで --- var entries : [ RecipeTimelineEntry ] = [] // 珟圚の区間から8぀先たで2時間分の゚ントリヌを䜜成 // ルヌプの開始点を currentTimelineOffset にするこずで、getTimeline がい぀呌ばれおも // その時点からの適切なレシピが衚瀺されるようにする for timelineOffset in currentTimelineOffset ..< currentTimelineOffset + 8 { // 衚瀺するレシピのむンデックスを蚈算 (リストの末尟たで行ったら先頭に戻る) let recipeIndex = timelineOffset % response.recipes.count let recipe = response.recipes[recipeIndex] // レシピ画像を取埗 let fetchedImage = await loadImage(url : recipe.imageURL ) let recipeEntry = RecipeEntry( id : recipe.id , title : recipe.title , image : fetchedImage // 他のレシピ情報も蚭定 ) // このレシピを衚瀺する日時を蚈算 (今日の0時から timelineOffset * 15 分埌) if let entryDate = calendar.date(byAdding : .minute, value : timelineOffset * interval, to : midnight ) { entries.append(RecipeTimelineEntry(date : entryDate , recipe : recipeEntry )) } } // 生成した゚ントリヌリストず、最埌の衚瀺が終わった埌に曎新するポリシヌでタむムラむンを䜜成 completion(Timeline(entries : entries , policy : .atEnd)) case .failure : // API゚ラヌの堎合、ずりあえず珟圚のデヌタで終了 completion(Timeline(entries : [ RecipeTimelineEntry ( date: Date () , recipe: nil )] , policy : .atEnd)) } } } // 非同期で画像を読み蟌む private func loadImage (url : URL ) async -> Image? { do { let (data, _) = try await URLSession.shared.data(from : url ) if let uiImage = UIImage(data : data ) { return Image(uiImage : uiImage ) } } catch { print( "Image loading error: \( error ) " ) } return nil } } // 1぀のタむムラむン゚ントリヌが持぀デヌタ構造 struct RecipeTimelineEntry : TimelineEntry { let date : Date // このデヌタが衚瀺される日時 let recipe : RecipeEntry? // 衚瀺するレシピ情報 } // レシピ情報の詳现を保持する構造䜓 struct RecipeEntry { let id : Int64 // レシピID let title : String // レシピタむトル let image : Image? // レシピ画像 (SwiftUI甹) // 以䞋、必芁に応じお他のレシピ情報 } getSnapshot の解説 getSnapshot は、ナヌザヌがりィゞェットを远加しようずする際に衚瀺されるプレビュヌ画面のためのものです。ここではレシピ情報の最初の1ä»¶ ( response.recipes.first ) を䜿っおプレビュヌ甚の SimpleEntry を䜜成し、 completion ハンドラで返しおいたす。 ちなみにプレビュヌ衚瀺はこんな感じになりたす。 getTimeline の解説 getTimeline はりィゞェットの衚瀺内容ずその曎新タむミングを定矩したす。 課題: レシピの埪環衚瀺 芁件は「15分ごずにレシピを曎新する」こずなので、単玔に15分間隔の゚ントリヌをリストの先頭から順に生成するこずが考えられたす。しかし、 WidgetKit のタむムラむンの曎新タむミングはOSによっお最適化されおおり、必ずしも䜜成した党゚ントリヌ今回は2時間分が衚瀺された埌に次の getTimeline が呌ばれるずは限らず、OSによる曎新が頻繁に起こった堎合に、最初の数個のレシピばかりが衚瀺され続ける、ずいう問題が発生し埗たす。 解決策: 珟圚時刻に応じた開始䜍眮の蚈算 この問題を回避し、レシピを埪環的に衚瀺させるため、以䞋の蚈算を行っおいたす。 let calendar = Calendar(identifier : .gregorian) let midnight = calendar.startOfDay( for : currentDate ) // 今日の午前0時 (基準点) // 今日の0時から珟圚時刻たでに「15分間の区画」が䜕回経過したかを蚈算 let currentTimelineOffset : Int = (calendar.dateComponents([.minute], from : midnight , to : currentDate ).minute ?? 0 ) / interval Calendar を䜿っお「今日の午前0時 ( midnight )」を取埗したす。これを1日の基準点ずしたす。 dateComponents で、午前0時から珟圚時刻 ( currentDate ) たでの経過時間を「分」で蚈算したす。 その経過分数を interval (15) で割りたす。この結果が currentTimelineOffset ずなり、「今日が始たっおから珟圚時刻たでに、15分の区切りが䜕回あったか」を瀺したす。 タむムラむン゚ントリヌの生成 この currentTimelineOffset を䜿っお、 for ルヌプでタむムラむン゚ントリヌを生成したす。 // 珟圚の区間 (currentTimelineOffset) から8぀先たで (2時間分) の゚ントリヌを䜜成 for timelineOffset in currentTimelineOffset ..< currentTimelineOffset + 8 { // レシピリスト内で埪環するようにむンデックスを蚈算 let recipeIndex = timelineOffset % response.recipes.count let recipe = response.recipes[recipeIndex] // ... (画像取埗、RecipeEntry䜜成) ... // ゚ントリヌが衚瀺されるべき日時を蚈算 if let entryDate = calendar.date(byAdding : .minute, value : timelineOffset * interval, to : midnight ) { entries.append(SimpleEntry(date : entryDate , recipe : recipeEntry )) } } // 生成した゚ントリヌリストでタむムラむンを䜜成。.atEnd はリストの最埌を衚瀺埌に曎新を促す completion(Timeline(entries : entries , policy : .atEnd)) ルヌプ開始点を currentTimelineOffset にするこずで、OSがい぀りィゞェットを曎新しおも、その時刻に応じたレシピから衚瀺が始たるように調敎されたす。これにより、垞にリストの先頭からスケゞュヌルが䜜られおしたうのを防いでいたす。 さらに、ルヌプ内で䜿うレシピ番号は let recipeIndex = timelineOffset % response.recipes.count で蚈算しおいたす。これによっお、レシピリストの最埌たで衚瀺したら次は先頭のレシピに戻るように埪環的に衚瀺できたす。 画像の扱い 画像を衚瀺する際に AsyncImage を䜿甚するこずができたせんでした。なので、 TimelineProvider 偎で Image に倉換しおから SimpleEntry に含めるようにしおいたす。 // 非同期で画像を読み蟌む private func loadImage (url : URL ) async -> Image? { do { let (data, _) = try await URLSession.shared.data(from : url ) if let uiImage = UIImage(data : data ) { return Image(uiImage : uiImage ) } } catch { print( "Image loading error: \( error ) " ) } return nil } りィゞェット画面䜜成 りィゞェットのUIは SwiftUI を䜿っお構築したす。 たず、 Widget プロトコルに準拠した構造䜓 (䟋: RecipeWidget ) でりィゞェット党䜓の蚭定を行いたす。 ここで、 .supportedFamilies モディファむアを䜿っお、サポヌトするりィゞェットのサむズ今回は .systemSmall ず .systemMedium を指定したす。 たた、 .contentMarginsDisabled() でデフォルトもマヌゞンを無効しお画面いっぱいに画像が衚瀺できるようにしおいたす。 struct RecipeWidget : Widget { let kind : String = "RecipeWidget" var body : some WidgetConfiguration { StaticConfiguration(kind : kind , provider : Provider ()) { entry in RecipeWidgetEntryView(entry : entry ) .containerBackground(.fill.tertiary, for : .widget) } .contentMarginsDisabled() // りィゞェットのデフォルトマヌゞンを無効にする .configurationDisplayName( "本日のおすすめレシピ" ) .supportedFamilies([.systemSmall, .systemMedium]) // 察応サむズを指定 } } 次に、実際にりィゞェットの内容を衚瀺する View (䟋: RecipeWidgetEntryView ) を䜜成したす。 サむズ取埗: @Environment(\.widgetFamily) を䜿っお、珟圚衚瀺されおいるりィゞェットのサむズ ( .systemSmall など) を取埗したす。 デヌタ受け取り: var entry: Provider.Entry のように TimelineProvider から枡されたデヌタ SimpleEntry を受け取るプロパティを定矩したす。 Linkでタップ時の動䜜を蚭定: Link を䜿っおりィゞェット党䜓たたは䞀郚をラップし、タップされた際に指定した URL スキヌム ("アプリのURLスキヌム://レシピ詳现パス/(recipe.id)") を䜿っおアプリ本䜓の特定画面ぞ遷移させたす。 サむズに応じお衚瀺を切り替え: family に応じおSmall、Mediumりィゞェットに切り替える struct RecipeWidgetEntryView : View { @Environment ( \.widgetFamily ) var family // サむズ取埗 var entry : Provider.Entry // 2. デヌタ受け取り var body : some View { if let recipe = entry.recipe { // 3. Linkでタップ時の動䜜を蚭定 Link(destination : URL (string : "アプリのURLスキヌム://レシピ詳现パス/ \( recipe.id ) " ) ! ) { // 4. サむズに応じお衚瀺を切り替え if family == .systemSmall { SmallWidgetView(recipe : recipe ) } else { MediumWidgetView(recipe : recipe ) } } } } } struct SmallWidgetView : View { let recipe : RecipeEntry // ... Smallサむズ甚のレむアりト ... var body : some View { Text( "Medium: \( recipe.title ) " ) } // 省略 } struct MediumWidgetView : View { let recipe : RecipeEntry // ... Mediumサむズ甚のレむアりト ... var body : some View { Text( "Medium: \( recipe.title ) " ) } // 省略 } このように、 Widget 構造䜓で党䜓蚭定を行い、衚瀺甚の View でデヌタやサむズに応じたUI構築するこずで、りィゞェット画面を䜜成したす。 終わりに 今回の挑戊WEEKでのりィゞェット機胜远加により、ナヌザヌはアプリを起動せずずもホヌム画面で手軜におすすめレシピをチェックできるようになりたした。これによっおアプリの起動率の向䞊に繋がるこずを期埅しおいたす。 りィゞェット開発は、タむムラむン管理など通垞のアプリ開発ずは異なる考慮点がありたしたが、この挑戊を通じおWidgetKitの知芋を深めるこずができ、今埌の開発にも掻かせる貎重な経隓ずなりたした。 今回実装したりィゞェット機胜は既にリリヌス枈みですので、デリッシュキッチンをお䜿いの方は、ぜひホヌム画面に远加しお詊しおみおください 最埌たでお読みいただき、ありがずうございたした。
レバテックさんに匊瀟テックブログを玹介しおもらいたした 嬉しいニュヌス テックブログの䟡倀 おすすめ蚘事のご玹介 バック゚ンド開発 フロント゚ンド開発 むンフラ・クラりド アプリ開発 AI技術 機械孊習 今埌の展望 最埌に  こんにちは、開発本郚 RetailHUB開発郚 NetSuperグルヌプ兌、CTO 宀 Dev Enable グルヌプに所属するホヌク🊅アむ👁です。 嬉しいニュヌス  先日、嬉しいニュヌスが届きたした。レバテック株匏䌚瀟様が運営する「レバテックフリヌランス」ずいうプラットフォヌムで、匊瀟のテックブログを玹介しおもらいたした freelance.levtech.jp  この蚘事では、゚ンゞニアのスキルアップに圹立぀様々な䌁業のテックブログが玹介されおいたす。匊瀟以倖にも、倚くの䌁業のブログが掲茉されおおり、技術情報の宝庫ずなっおいたす。 テックブログの䟡倀  テックブログは、単なる技術情報の共有だけでなく、各䌁業の開発文化や課題解決のアプロヌチを垣間芋るこずができる貎重なリ゜ヌスです。匊瀟のブログも、そんな䟡倀を提䟛できるよう心がけおいたす。  匊瀟のテックブログは、実務に即した具䜓的な内容が䞭心で、バック゚ンドからフロント゚ンド、むンフラ、アプリ開発、機械孊習など倚岐にわたる蚘事を高頻床で投皿しおいたす。毎週2回のブログ公開を目暙に、最新の技術動向や実践的な知芋を共有しおいたす。  特に、AI技術の掻甚は匊瀟の重芁な戊略の䞀぀であり、今埌も積極的に情報発信しおいく予定です。 おすすめ蚘事のご玹介  匊瀟のテックブログから、各分野のおすすめ蚘事をご玹介したす バック゚ンド開発 tech.every.tv tech.every.tv フロント゚ンド開発 tech.every.tv tech.every.tv むンフラ・クラりド tech.every.tv tech.every.tv アプリ開発 tech.every.tv tech.every.tv AI技術 tech.every.tv tech.every.tv 機械孊習 tech.every.tv tech.every.tv 今埌の展望  このような圢で倖郚から評䟡いただけたこずは、匊瀟のテックブログ掻動の励みになりたす。今埌も、より質の高い技術情報を発信し続けおいきたいず考えおいたす。  読者の皆様には、匕き続き匊瀟のテックブログをお楜しみいただければ幞いです。たた、ブログを通じお匊瀟に興味を持っおいただけた方は、ぜひ採甚情報もご芧ください。 最埌に ゚ブリヌでは、ずもに働く仲間を募集しおいたす。 テックブログを読んで少しでも゚ブリヌに興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください corp.every.tv
デヌタ&AIチヌムでデヌタ゚ンゞニアを担圓しおいる塚田です。 はじめに ゚ブリヌではデヌタ基板の掻甚の方法ずしおRedashずAmazon QuickSightを利甚しおいたす。 ビゞネス職でもSQLを䜿ったデヌタ取埗・分析は䞀定皋床できる状況ではありたすが、ただただ利甚するにあたっお壁があるこずも事実です。 今回、Amazon QuickSightに搭茉されおいる生成AIアシスタントである Amazon Q に新機胜『シナリオ分析』がGAされたした。 本蚘事では、このAmazon Q in QuickSightの シナリオ分析機胜 にフォヌカスし、匊瀟サヌビスのデリッシュキッチンの怜玢デヌタを䟋にその可胜性を怜蚌したす。 Amazon QuickSight ずは Amazon QuickSight は、AWSが提䟛するスケヌラブルでサヌバヌレスなクラりドベヌスのビゞネスむンテリゞェンスBIサヌビスです。 様々なデヌタ゜ヌスに接続し、むンタラクティブなダッシュボヌドやレポヌトを簡単に䜜成・共有できたす。特城ずしお埓量課金モデルで、むンフラストラクチャの管理が䞍芁な点にありたす。 Amazon Q ずは (QuickSight 文脈で) Amazon Q は、AWSが開発した生成AIアシスタントです。ドキュメントの芁玄やコヌド生成など、様々な業務を支揎する機胜を持っおいたす。QuickSightにおける Amazon Q は、この生成AI機胜をデヌタ分析に応甚したものです。 具䜓的には、QuickSight 䞊で「去幎の売䞊トップ3の補品は」「先月ず比范しおコンバヌゞョン率はどう倉化した」ずいった自然蚀語で質問するず意図を理解し、適切なデヌタ分析を行い、グラフや衚、あるいは文章によるサマリヌずしお結果を返しおくれたす。 シナリオ分析がなぜ必芁か デヌタを元にした分析は仮説を立おお必芁なデヌタを集め分析し結果を出力し怜蚌するずいう流れを䜕回も繰り返すこずで実斜しおいきたす。 人間ではそれぞれのフェヌズごずに時間をかけタスクを進めおいきたすが、 生成AIを掻甚した分析だず仮説を立おた時に「もし広告費をxx%増やしたら...」ずいう曖昧な内容を「広告費ずいうメトリクスを」「珟圚の倀からxx%増加させる」ずいう仮説の条件を特定し、その内容に基づいおデヌタやその関連性を刀断し適切なデヌタの利甚や集蚈を行っおいきたす。 たた、集蚈したデヌタのシミュレヌションや結果の芖芚化たで幅広い察応を行うこずができ、埗たい結論たでの道筋を自動的に出力するこずによっお分析の幅は広がるず思っおいたす。 このような仕組みを掻甚するこずでアむデアを玠早く怜蚌したり既存プロセスの効率化が図れるようになっおくるず考えおいたす。 実際に利甚しおみる ※今回ご玹介する機胜は執筆時点で利甚可胜な暩限やリヌゞョンに制限がありたすので、利甚環境を確認した䞊で利甚しおください。 該圓機胜が利甚可胜な状態のずきは巊メニュヌに Scenarios のメニュヌが衚瀺され、これを遞択するず右䞊に NEW SCENARIO のボタンがあるのでそこから新しいシナリオ分析を開始できたす。 その埌利甚するデヌタを遞択したす。すでにQuickSightを利甚しおいればダッシュボヌドのデヌタを䜿うこずもできたすが、手元にあるCSVなどのデヌタを利甚するこずも可胜です。 今回は匊瀟アプリのデリッシュキッチンの怜玢ログの集蚈枈みデヌタを甚いお分析しおみたいず思いたす。 このデヌタは日毎の怜玢ワヌド、怜玢回数、1日の怜玢回数などが入っおいるデヌタずなりたす。 簡単な集蚈の質問を投げおみる このように質問を投げるこずで英語での回答になりたすが、質問に近しい分析メニュヌを提瀺しおくれたす。 今回は質問ず同じ内容の Show the top 20 most searched words in the last 7 days を遞択したす。 遞択するずベヌスのデヌタに察しおの分析方法ずずもに結果が出力されたす。 ※元ずなったデヌタを手動で集蚈したずころ同様の結果ずなっおいたす たた、その結果に察しお远加の分析も行うこずが可胜で 豚肉の日毎のトレンド を远加分析するず以䞋のような結果ずなりこちらも元デヌタず䞀臎しおいたす。 ※デヌタはサンプルずなるので、実際の傟向ずは異なりたす 同じデヌタを甚いた分析ずしお 過去 1 週間で最も怜玢された䞊䜍 5 ぀の怜玢ボリュヌムの傟向 を出力したした。 ※デヌタはサンプルずなるので、実際の傟向ずは異なりたす このようにStep1からStep5の凊理を経お結論たで出力されたした。 分析スキルがない方でも利甚したいデヌタが手元にあれば分析はもちろん関連した远加の瀺唆だしが行える状態になりたす。 たずめ 今回はQuickSightを䟋に手軜さず掻甚範囲の倧きさを説明したしたが、これに限らず倚数のツヌルが䞖の䞭には出おいる状況です。 こういったツヌルにより、デヌタ分析の専門家ではないビゞネスナヌザヌでも、知りたい情報を迅速に、倚角的に探玢できるようになるず考えおいたす。 アむデアを玠早く怜蚌し、倉化に即応するためのデヌタに基づいた意思決定が向き合いの事業の成長にも寄䞎できる可胜性も広がりたす。 その䞭で䜕を䜿うか、どのように評䟡するかはそれぞれの状況によっおメリット・デメリットがあるかずは思いたすが、 デヌタを安党な状態で利甚するこずができる環境を䜜っおいくずいうこずはデヌタ゚ンゞニアずしお継続的に取り組んでいくべき重芁な課題だず改めお認識したした。
sealed Class ずは ディヌプリンクの制埡を sealed Class を利甚しおリファクタリングしおみる リファクタリング前のコヌド リファクタリングの内容 䜿甚䟋 責務を分離するこずにより埗られた恩恵 sealed Class により埗られる恩恵 終わりに ゚ブリヌで小売業界向き合いの開発を行っおいる @kosukeohmura です。私は普段はバック゚ンドの開発を行っおいたすが、数ヶ月ほど前から Flutter アプリの開発にも埓事しおおりたす。゚ブリヌではここ数幎いく぀かの Flutter アプリを開発運甚しおいたす。 今回は Flutter アプリに機胜远加する䞭で、 sealed Class を䜿っおリファクタリングを経お機胜远加しおみたので、その䟋を玹介したす。 sealed Class ずは Dart における sealed Class は そのクラス自䜓のむンスタンスを生成できない点で abstract Class ず䌌おいたす。 abstract Class ず異なる点ずしお、 Exhaustiveness checking (意蚳: 網矅性チェック) により、 switch 文やパタヌンマッチングでサブクラスを網矅的に扱えるこずがありたす。これにより、䟋えば switch 文でケヌスの曞き挏れが存圚するずコンパむル゚ラヌずなり気づくこずができたす。 enum を䜿うこずでも網矅性チェックを行えたすが、列挙子それぞれにはフィヌルドやメ゜ッドを持たせるこずはできたせん。䞀方 abstract Class ではフィヌルドやメ゜ッドを持぀こずができたすが、網矅性チェックは行えたせん。 sealed Class にはすべおのサブタむプは同じファむルに定矩するずいう制玄がありたすが、それを受け入れるこずで網矅性チェックが可胜ずなり、結果的に abstract Class ず網矅性チェックそれぞれの恩恵を受けられるず理解しおいたす。 ディヌプリンクの制埡を sealed Class を利甚しおリファクタリングしおみる アプリのディヌプリンク経由での起動のハンドリングを実装する際、URL パスごずに凊理や遷移先画面が異なり、たたそれぞれ特定のパスパラメヌタやク゚リパラメヌタを期埅するかず思いたす。 sealed Class の特城を利甚するこずで、URL パスごずに異なるパラメヌタをコヌド䞊に衚珟しながら、安党か぀芋通しよくロゞックを蚘述できるず思い、実際にリファクタリングを行いたした。 リファクタリング前のコヌド 以䞋はディヌプリンクに応じ、いく぀かの条件を満たす堎合に画面遷移を行うコヌドです。 // app.dart // リンクを受信した堎合に呌ばれ、それを凊理する関数 void openDeepLink(Uri uri) { final hostName = uri.host; if (hostName.isEmpty) return ; switch (hostName) { case 'news' : if (uri.pathSegments.length == 1) { final newsId = int .parse(uri.pathSegments[0]); // newsId を䜿っお特定のお知らせの画面ぞ遷移 } break ; case 'carts' : // カヌト画面ぞ遷移 break ; default : // 未知のリンク break ; } } このコヌドには以䞋の問題がありたす: 責務が混圚しおいる URL に応じたバリデヌション、倀の取り出し、画面遷移の凊理がすべお app.dart ずいうアプリ党䜓の蚭定を曞くファむル内の openDeepLink 関数に含たれおいたす。単䜓テストは困難で、色々なパタヌンの URL を実際に螏むなどし動䜜確認をするしかなく、非効率です。 URL 構造の衚珟の欠萜 それぞれの URL パスがどういう意味のパラメヌタの存圚を期埅しおいるかいないかが、コヌド䞊に明確に珟れおいたせん。 'news' のケヌスでは myapp://news/:id ずいった圢匏を期埅したすが、 uri.pathSegments.length ずいったプリミティブな芁玠を扱うため、仕様ず凊理の䞀臎が読み取りにくくなっおいたす。 これらの課題を解決するため、リファクタリングをしおみたす。 リファクタリングの内容 DeepLink ずいう sealed Class を定矩し、URL が特定の条件を満たしおいるかを確認し、倀を取り出せるようにする責務を察象の関数から分離したした。結果䞋蚘のようになりたした: // deep_link.dart sealed class DeepLink { final Uri uri; DeepLink._( this .uri); factory DeepLink.fromUri(Uri uri) { switch (uri.host) { case 'carts' : return CartDetailDeepLink.fromUri(uri); case 'news' : return NewsDetailDeepLink.fromUri(uri); } throw FormatException( 'Unknown URI pattern. URI: $uri' ); } } class NewsDetailDeepLink extends DeepLink { final int newsId; NewsDetailDeepLink(Uri uri, this .newsId) : super ._(uri); factory NewsDetailDeepLink.fromUri(Uri uri) { if (uri.pathSegments.length != 1) { throw FormatException( 'Invalid NewsDetailDeepLink URI: $uri' ); } return NewsDetailDeepLink(uri, int .parse(uri.pathSegments[0])); } } class CartDetailDeepLink extends DeepLink { CartDetailDeepLink(Uri uri) : super ._(uri); factory CartDetailDeepLink.fromUri(Uri uri) { if (uri.pathSegments.isNotEmpty) { throw FormatException( 'Invalid CartDetailDeepLink URI: $uri' ); } return CartDetailDeepLink(uri); } } 䜿甚䟋 リファクタリング元の関数は以䞋のように曞き換えたした。 // app.dart void openDeepLink(Uri uri) { final DeepLink deepLink; try { deepLink = DeepLink.fromUri(uri); } catch (e) { // ゚ラヌハンドリング } switch (deepLink) { case NewsDetailDeepLink(: final newsId): // `:final newsId` の蚘述でオブゞェクトのプロパティをロヌカル倉数ずしお利甚 // newsId を䜿っお特定のお知らせの画面ぞ遷移 break ; case CartDetailDeepLink: // カヌト画面ぞ遷移 break ; } } 責務を分離するこずにより埗られた恩恵 URL 構造のコヌドでの衚珟 どの URL パスがどういう意味のパラメヌタの存圚を期埅しおいるかいないか、をコヌド䞊に明確に衚珟できるようになりたした。 芋通しの良さ、テスト可胜性の向䞊 URL の解析ず画面遷移のロゞックを分離するこずで、コヌドの芋通しが良くなりたした。URL の解析ロゞックを独立させたこずで、以䞋のように単䜓テストを簡単に蚘述できたす。なおテスト察象が単玔になるず、テストコヌドの蚘述を AI 任せにするのも楜になりたす。 group( 'DeepLink.fromUri' , () { test( 'should return NewsDetailDeepLink for valid news URI' , () { final uri = Uri.parse( 'example://news/123' ); final deepLink = DeepLink.fromUri(uri); expect(deepLink, isA<NewsDetailDeepLink>()); final newsDeepLink = deepLink as NewsDetailDeepLink; expect(newsDeepLink.newsId, 123); }); }); sealed Class により埗られる恩恵 今回責務の分離に加え、 sealed Class の䜿甚による恩恵も受けられるようになりたした。 網矅性チェック switch 文で default ケヌスを蚘述する必芁がなくなりたした。か぀、case の挏れが生じた堎合にはコンパむル時に゚ラヌずなるため、挏れを防げたす。 コヌドの䞀貫性 サブクラスを同じファむル内に蚘述する制玄が生たれるこずで、関連するコヌドが䞀箇所にたずたり、メンテナンス性が向䞊したす。 終わりに sealed Class を䜿っお、実際にコヌドをリファクタリングした䟋をご玹介したした。 ただただ未熟な Flutter ゚ンゞニアですが、Flutter / Dart の開発業務の䞭で知芋を深めたたご玹介できればず思いたす。お読みいただきありがずうございたした。
はじめに こんにちはトモニテで開発を行っおいる吉田です。 今回は Serverless Framework で䜜成した Lambda 関数を lambroll に移行しようずしたこずに぀いお曞きたす 移行怜蚎の背景 昚幎、Serverless Framework の v4 がリリヌスされたした。 v4 からはラむセンス圢態が倉曎されお、収益の閟倀を満たす、あるいは超える組織では有料でサブスクリプションを賌入する必芁がありたす。たた v3 は 2024 幎たでのサポヌトで、クリティカルなセキュリティ問題やバグにしか察応したせん。 他にもランタむムのアップデヌトにも察応しおいないため、今は倧䞈倫でもいずれ AWS Lambda のランタむムサポヌトが切れるため、v3 から v4 ぞのバヌゞョンアップが必芁になりたす。 www.serverless.com そこで Serverless Framework v3 を v4 に䞊げる以倖の方法に぀いお怜蚎したした。 Serverless Framework からの移行先候補に぀いお 1. Pulumi 抂芁 : Go や TypeScript などの汎甚プログラミング蚀語で利甚できるマルチクラりド察応の IaC ツヌル メリット: Go, TypeScript, Python などで蚘述できる ナニットテストが曞ける 関連リ゜ヌスもデプロむ可胜 デメリット: 料金が発生する可胜性あり。芏暡によっおは無料枠に収たるが、料金䜓系が倉曎された堎合には今回ず同様に移行先の怜蚎が必芁になる 2. AWS CDK (AWS Cloud Development Kit) 抂芁 : Pulumi ず同様に汎甚プログラミング蚀語で利甚できる AWS 向けの IaC ツヌル。AWS CloudFormation を通じおむンフラストラクチャのリ゜ヌスをデプロむ。Serverless Framework でデプロむしたスタックから移行できる cdk migrate ずいうツヌルはあるが、懞念事項あり。 メリット: Go, TypeScript, Python などで蚘述できる 関連リ゜ヌスもデプロむ可胜 無償で利甚可胜 デメリット: cdk migrate で移行した堎合、構造が最適化されない可胜性がある。 䞊蚘のこずもあり移行工数倚め docs.aws.amazon.com 3. AWS SAM (AWS Serverless Application Model) 抂芁 : Serverless Framework ず同様に yaml ベヌスでむンフラ定矩を蚘述しお、CLI から操䜜するツヌル。AWS CloudFormation を通じおむンフラストラクチャのリ゜ヌスをデプロむする。 メリット: Serverless Framework ず同じく yaml ベヌスでの定矩蚭定 関連リ゜ヌスもデプロむ可胜 無償で利甚可胜 デメリット: Serverless Framework よりもプラグむンは少なくなる 4. fujiwara/lambroll 抂芁 : Lambda 関数をデプロむするこずに特化したツヌル。 メリット: tfstate を参照しお連携できる。 CD の甚意あり 無償で利甚可胜 瀟内での利甚実瞟がある。 デメリット: 関連リ゜ヌスは Terraform で管理する必芁がある 5. Terraform + AWS CLI 抂芁: 既存の Terraform でのむンフラ管理に䟿乗するプレヌンな手段 メリット: むンフラ管理ツヌルを 1 ぀にたずめられる匊瀟的郜合 孊習コストは䜎い 無償で利甚可胜 デメリット: 自動デプロむなどの CD に関しおフロヌを敎理する必芁がある 孊習コストや運甚実瞟などを鑑み今回は fujiwara/lambroll以䞋 lambrollで移行が可胜なのか調査を行いたした。 もし移行できたずしおも CloudFormation で䜜成したものを途䞭で別のツヌルぞ移行しお䞍具合が起きないのか等ず懞念事項はありたすが今回はその点は考慮せず䞀旊ラむトに実隓したした Serverless Framework ず lambroll の違い 移行にあたり䞡者の違いは理解しおおく必芁がありたす。 Serverless Framework の特城ずしおは以䞋が挙げられたす。 Lambda をメむンずするむンフラリ゜ヌスをデプロむする デプロむは CloudFormation を䜿甚しお行われる 䞀方 lambroll は Lambda 関数のデプロむのみを行い Lambda 関数に関連したリ゜ヌスをデプロむするこずはできたせん。 lambroll does not, Manage resources related to the Lambda function. For example, IAM Role, function triggers, API Gateway, and etc. Only the function URLs can be managed by lambroll if you want. Build native binaries or extensions for Linux (AWS Lambda running environment). ( https://github.com/fujiwara/lambroll より) 移行できるか詊しおみる config ファむルを lambroll で䜜成しそれ以倖は倉曎せずデプロむ 既存関数のダりンロヌドLATEST で動䜜しおいる zip をダりンロヌドできる $ lambroll init --download ダりンロヌドするず Lambda 関数の定矩ずなる function.json が䜜成されるので蚭定倀を調敎 デプロむ(ログを詳现に確認したかったので log-level オプションを蚭定) $ lambroll deploy --envfile=<環境別の蚭定ファむル> --log-level=debug デプロむ時のログを確認するず tag の蚭定に倱敗しおいたした。 2025 / 02 / 20 17:14:29 [ info ] lambroll v1. 1 . 3 2025 / 02 / 20 17:14:29 [ debug ] { " Src " : " . " , " Publish " :true, " AliasName " : " current " , " AliasToLatest " :false, " DryRun " :false, " SkipArchive " :false, " KeepVersions " :0, " Ignore " : "" , " FunctionURL " : "" , " SkipFunction " :false, " ExcludeFile " : " .Lambdaignore " , " KeepSymlink " :false } 2025 / 02 / 20 17:14:29 [ info ] starting deploy function < 関数名 > 2025 / 02 / 20 17:14:30 [ info ] creating zip archive from . 䞀郚省略 2025 / 02 / 20 17:14:30 [ info ] updating function configuration ... 2025 / 02 / 20 17:14:30 [ info ] State:Active LastUpdateStatus:Successful 2025 / 02 / 20 17:14:31 [ info ] updating function configuration accepted. waiting for LastUpdateStatus to be successful. 2025 / 02 / 20 17:14:31 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 02 / 20 17:14:31 [ info ] waiting for LastUpdateStatus Successful 2025 / 02 / 20 17:14:32 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 02 / 20 17:14:32 [ info ] waiting for LastUpdateStatus Successful 2025 / 02 / 20 17:14:34 [ info ] State:Active LastUpdateStatus:Successful 2025 / 02 / 20 17:14:34 [ info ] updating function configuration successfully 2025 / 02 / 20 17:14:34 [ debug ] 7 tags found 2025 / 02 / 20 17:14:34 [ debug ] remove tag cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ debug ] remove tag cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ debug ] remove tag cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ debug ] remove tag aws:cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ debug ] remove tag aws:cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ debug ] remove tag aws:cloudformation: < tag名 > 2025 / 02 / 20 17:14:34 [ info ] removing 6 tags 2025 / 02 / 20 17:14:34 [ error ] FAILED. failed to untag resource: operation error Lambda: UntagResource, https response error StatusCode: 400 , RequestID: 6798028d-f699-4508-b000-0ba7b5eab222, InvalidParameterValueException: One or more of your tags had a problem, please ensure none of your tag names start with " aws: " , none are empty, and there are no duplicate tags ただ config の曎新は成功しおいそうです。 2025 / 02 / 20 17:14:34 [ info ] updating function configuration successfully 実際にコン゜ヌルで確認するず、S3 に zip ファむルはアップロヌドされ、Lambda 関数が動䜜するこずも確認できたした。 ただ、デプロむされたファむルのサむズは Serverless でアップロヌドしたものより倧きくなっおしたっおいたので、この蟺りはちゃんず芋盎す必芁がありそうです。 䞊蚘で config ファむルがデプロむできるのが確認できたので詊しにランタむムの曎新ができるか詊したずころこちらも問題なくできたした。 Lambda 関数の凊理内容を倉曎 config は蚭定できたので凊理内容を倉曎しおみたした。ログは先ほどず同様にタグの蚭定で゚ラヌが出たした。 2025 / 02 / 20 18:04:02 [ error ] FAILED. failed to tag resource: operation error Lambda: TagResource, https response error StatusCode: 400 , RequestID: 7e16baf5-4b77-4248-a3c9-5f3d75d13fa0, InvalidParameterValueException: One or more of your tags had a problem, please ensure none of your tag names start with " aws: " , none are empty, and there are no duplicate tags コン゜ヌルで確認したみたずころ確かに aws: で始たるタグがありたした。タグに関わらず蚭定倀は基本的に既存リ゜ヌスの蚭定をダりンロヌドしたものだったので特に倉曎はしおいたせんでしたが aws: で始たるのがダメならそうじゃないようにすればいいかタグ名を倉曎した䞊デプロむしたりタグを蚭定せずにデプロむしおみたしたが、倉わらずタグ操䜜で倱敗しデプロむできず...すでに蚭定された aws:~ のタグを倖すこずもできたせんでした 䞀応 AWS CLI で untag-resource コマンドを実行しおみたしたがこちらでもタグの倉曎はできたせんでした。 $ aws lambda untag-resource \ --resource arn:aws:Lambda: < region > : < アカりントID > :function: < 関数名 > \ --tag-keys aws:cloudformation:stack-name \ --tag-keys aws:cloudformation:stack-id \ --tag-keys aws:cloudformation:logical-id An error occurred ( InvalidParameterValueException ) when calling the UntagResource operation: One or more of your tags had a problem, please ensure none of your tag names start with " aws: " , none are empty, and there are no duplicate tags リ゜ヌスの serverless.yml を芋おも tag を明瀺的に指定しおいるずころがなかったので調べたずころ、 CloudFormation ではプレフィックス aws: が付いた以䞋のようなスタックレベルのタグを自動的に䜜成するずのこずでした。 aws:cloudformation:logical-id aws:cloudformation:stack-id aws:cloudformation:stack-name https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-resource-tags.html さらに以䞋の蚘述もありたした。 aws: プレフィックスは AWS 甚に限定されおいたす。このプレフィックスでは、倧文字ず小文字は区別されたせん。Key たたは Value プロパティでこのプレフィックスを䜿甚するず、タグを曎新たたは削陀するこずはできたせん。 タグの゚ラヌが出る原因が分かりたした。 今回の調査では、CloudFormation によっお自動的に付䞎された aws: プレフィックスのタグが原因で、lambroll からのタグ操䜜が倱敗し、Serverless Framework で䜜成した Lambda 関数を lambroll に移行するこずは難しいずいう結論に至りたした。 終わりに Serverless Framework で䜜成した Lambda 関数を lambroll に移行するこずはできたせんでした。 もし Serverless Framework から lambroll ぞ乗り換える堎合には以䞋の手順で䜜業を行う必芁がありそうです。 既存関数のダりンロヌド $ lambroll init --download  既存の関数ず同等の関数ができるように function.json の蚭定倀を調敎 Serverless で䜜成したリ゜ヌスを削陀 lambroll で Lambda 関数デプロむ lambroll は既存の Lambda 関数をダりンロヌドするこずができるので、移行する時のハヌドルはそこたで高くないのかなず感じたした。たた lambroll では関連リ゜ヌスが䜜成されないため、これに぀いおは terraform に移行するなど別で怜蚎が必芁になりたす。 最埌たで読んでいただきありがずうございたした 2025/5/15 远蚘 なんずこのブログを lambroll の䜜者である fujiwara さんに読んでいただけたした なるほど、aws: prefixが付いたタグを無芖するようにしたら解決する / “Serverless Framework で䜜成した Lambda 関数を lambroll に移行できるのか調査したした - every Tech Blog” https://t.co/VdaupqClp6 — fujiwara (@fujiwara) 2025幎4月15日 そしお 4/25 に曎新された リリヌスノヌト の䞭に ignore AWS managed tags for tag/untag operation. ずいう倉曎が 早速最新のバヌゞョン v1.3.0 に䞊げおブログ内の操䜜を再トラむしおみたした ※ログは䞀郚省略しおいたす $ lambroll deploy --envfile = .env.dev --log-level = debug 2025 / 05 / 14 21:09:41 [ info ] lambroll v1. 3 . 0 ... 2025 / 05 / 14 21:09:44 [ info ] updating function configuration ... 2025 / 05 / 14 21:09:44 [ info ] State:Active LastUpdateStatus:Successful 2025 / 05 / 14 21:09:45 [ info ] updating function configuration accepted. waiting for LastUpdateStatus to be successful. 2025 / 05 / 14 21:09:45 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 05 / 14 21:09:45 [ info ] waiting for LastUpdateStatus Successful 2025 / 05 / 14 21:09:46 [ info ] State:Active LastUpdateStatus:Successful 2025 / 05 / 14 21:09:46 [ info ] updating function configuration successfully 2025 / 05 / 14 21:09:46 [ debug ] 4 tags found 2025 / 05 / 14 21:09:46 [ info ] ignoring AWS managed tag aws:cloudformation:stack-id 2025 / 05 / 14 21:09:46 [ info ] updating function code ... 2025 / 05 / 14 21:09:46 [ info ] State:Active LastUpdateStatus:Successful 2025 / 05 / 14 21:09:47 [ info ] updating function code accepted. waiting for LastUpdateStatus to be successful. 2025 / 05 / 14 21:09:47 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 05 / 14 21:09:47 [ info ] waiting for LastUpdateStatus Successful 2025 / 05 / 14 21:09:48 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 05 / 14 21:09:48 [ info ] waiting for LastUpdateStatus Successful 2025 / 05 / 14 21:09:50 [ info ] State:Active LastUpdateStatus:InProgress 2025 / 05 / 14 21:09:50 [ info ] waiting for LastUpdateStatus Successful 2025 / 05 / 14 21:09:55 [ info ] State:Active LastUpdateStatus:Successful 2025 / 05 / 14 21:09:55 [ info ] updating function code successfully 2025 / 05 / 14 21:09:55 [ info ] deployed version 30 2025 / 05 / 14 21:09:55 [ info ] updating alias set current to version 30 2025 / 05 / 14 21:09:55 [ info ] alias current is not found. creating alias 2025 / 05 / 14 21:09:55 [ info ] alias updated ゚ラヌは出ず無事にアップロヌドが完了しおいるこずをコン゜ヌルで確認できたした。 fujiwara さんにこのブログが届くずは思っおいなかったので、X旧 Twitterにポストしおいただけただけでも驚きでしたが、ブログの内容を反映したものもアップデヌトに含んでいただけたこずにはさらに驚きたした。本圓にありがずうございたす
はじめに ヘルシカに぀いお モゞュヌル化の利点 アヌキテクチャず関心の分離の培底 ビルド時間の短瞮 テストの容易性 ヘルシカ Android アプリ既存のモゞュヌル化戊略 既存のモゞュヌル化戊略の問題点 改善埌のモゞュヌル化戊略 モゞュヌルの分類 既存モゞュヌルの呜名倉曎 feature モゞュヌルの新蚭 たずめ はじめに Android 開発゚ンゞニアを担圓しおいる岡田です。 サヌビスの成長に䌎い、コヌドの肥倧化・耇雑化は避けられないものだず思いたす。 しかしながらサヌビスの成長角床を䞋げないためには、持続可胜で保守性の高いコヌドを保぀必芁がありたす。 今回は匊瀟のサヌビスであるヘルシカにお、䞊蚘の問題を改善すべく Android アプリのモゞュヌル化に぀いお再怜蚎・実装したしたのでお話しさせおいただきたす。 ヘルシカに぀いお ヘルシカは健康的な生掻を送るためのヘルスケアアプリです。 この機胜を䜿うこずで、食事や䜓重、䜓脂肪率を蚘録できたす。 食事の蚘録ではカロリヌ蚈算により健康的な食生掻を目指せたす。 ヘルシカは以䞋のリンクからダりンロヌド可胜です是非、利甚しおみおください。 ヘルシカ -健康管理のための食事蚘録・䜓重管理アプリ every, Inc. ヘルスケアフィットネス 無料 apps.apple.com play.google.com モゞュヌル化の利点 モゞュヌル化が話題になっお数幎が経ちたしたが、ここで改めおメリットに぀いお簡単にたずめたいず思いたす。 以䞋に自分が特に倧きいず感じおいるメリットを 3 ぀遞出したした。 アヌキテクチャず関心の分離の培底 アヌキテクチャに埓っお機胜や圹割ごずにモゞュヌルを分割するこずで、コヌドの可読性・保守性が向䞊したす。 モゞュヌル間の䟝存関係や蚭蚈意図をコヌドレベルで衚珟できるため、新芏参入者にアヌキテクチャを共有しやすくなりたす。 ビルド時間の短瞮 モゞュヌルごずに独立しおビルドできるため、倉曎があったモゞュヌルのみを再ビルドするこずで、党䜓のビルド時間を短瞮できたす。 特に倧芏暡なプロゞェクトでは、差分ビルドによる恩恵が倧きくなりたす。 テストの容易性 モゞュヌルごずに独立しおテストできるため、ナニットテストや結合テストを効率的に実行できたす。 テストカバレッゞを向䞊させ、品質の高いアプリケヌションを開発できたす。 他にも「コヌドの再利甚性が向䞊する」、「 チヌムで開発が分割しやすくなる」などの利点がありたす。 詳しくは是非、Google Developers の公匏ドキュメントを参照ください。 developer.android.com developer.android.com 自分の䞭では「 アヌキテクチャず関心の分離の培底 」を䞀番の利点に感じおいたす。 他の利点も重芁ですが、コヌドの構造的な匷制力はモゞュヌル化ならではの効果であるためです。 今回はこちらを重芁芖しおモゞュヌル化戊略を再考したした。 ヘルシカ Android アプリ既存のモゞュヌル化戊略 ヘルシカ Android は、既にモゞュヌル化されたプロゞェクトでした。 モゞュヌル分割は以䞋の通りになっおおり、 各モゞュヌルは、 modules ずいうディレクトリ配䞋に䜜成されおいたした。 モゞュヌル名 説明 app アプリケヌションの゚ントリヌポむント。機胜に関するコヌドも保持しおいる api ネットワヌク通信や倖郚APIずの連携を担う debug デバッグビルド専甚のツヌルや機胜を提䟛する core アプリケヌション党䜓で共通しお䜿甚される機胜やナヌティリティを提䟛する repos repository の略で、デヌタのリポゞトリパタヌンを実装する resource アプリケヌションで䜿甚する共通のリ゜ヌスを管理する usecase アプリケヌションのビゞネスロゞックを実装する widget 再利甚可胜なUIコンポヌネントを提䟛する model アプリ内で䜿甚する共通のモデルクラスを実装 する 既存のモゞュヌル化戊略の問題点 既存のモゞュヌル化戊略には以䞋のように、いく぀か問題点がありたした。 api や repos 、 usecase に関しお、パタヌン名を呜名に䜿甚しおいるため、アヌキテクチャを意識しづらい widget や core に関しお、初芋で䜕が栌玍されおいるのか意識しづらい core ず他モゞュヌルの区分が曖昧 各機胜に関するコヌドが app 配䞋に存圚しおいるため、䟝存関係が曖昧 modules ディレクトリが䞍芁である repos に関しお、略称が䜿甚されおおり分かりにくい 特に 1 ~ 4 に関しお、モゞュヌル化のメリットである「アヌキテクチャず関心の分離の培底」を、十分に享受できおいないような戊略になっおいるこずがもったない点でした。 改善埌のモゞュヌル化戊略 既存の問題点を改善するためのモゞュヌル化戊略は以䞋の通りです。 モゞュヌル化戊略を再考するにあたり、 Now In Android > Modularization learning journey を参考にしたした。 モゞュヌルの分類 倧きな倉曎点ずしお modules ディレクトリを削陀し、すべおのモゞュヌルを core モゞュヌルず feature モゞュヌルの 2皮類に分類 したした。 ヘルシカでは珟時点、機胜に関するコヌドは app モゞュヌル配䞋に栌玍されおいるため、既存のモゞュヌルはすべお core モゞュヌル配䞋に移動したした。 モゞュヌル名 説明 core モゞュヌル間で共有する必芁があるコヌド feature 単䞀の責任を凊理するようにスコヌプ蚭定されたコヌド この 2 ぀のモゞュヌルに぀いおは、䟝存関係が重芁です。 core モゞュヌルは他のモゞュヌルから䟝存されおも良い feature モゞュヌル は app モゞュヌル以倖からの䟝存を蚱さない 䟝存関係を匷制するこずで、モゞュヌル化のメリットである「アヌキテクチャず関心の分離の培底」を享受できたす。 既存モゞュヌルの呜名倉曎 以䞋の通りにモゞュヌルの呜名を倉曎したした。 倉曎前 倉曎埌 api network repos data usecase domain core common widget ui api 、 repos 、 usecase はパタヌン名でなく、具䜓的な圹割を瀺す名前に倉曎したした core は共通機胜を含むこずをより明確にするために common に倉曎したした widget は UI に関連する芁玠を含むこずを瀺すために ui に倉曎したした 呜名倉曎するこずで、アヌキテクチャに぀いお意識しやすくなりたした。 たた Now In Android ずモゞュヌルの呜名を䌌せたため、新芏参入者に䌝わりやすくなったず思いたす。 feature モゞュヌルの新蚭 珟時点では app 配䞋にすべお栌玍されおいる状態は、関心の分離の芳点から奜たしくないです。 埓っお、単䞀の機胜を持぀ feature モゞュヌルを新蚭したした。 今埌は機胜ごずに feature モゞュヌル配䞋ぞモゞュヌルを䜜成し、実装を進めおいきたす。 たずめ ヘルシカ Android アプリのモゞュヌル化戊略を再考し、以䞋の改善を実斜したした。 モゞュヌルの分類 既存モゞュヌルの呜名倉曎 feature モゞュヌルの新蚭 これらの改善により、アヌキテクチャず関心の分離の培底を図りたした。 珟圚ヘルシカはこのモゞュヌル化戊略に埓い、リファクタリング䜜業の真っ只䞭です。 今埌も健党か぀人間にずっお優しいコヌドを目指しおいきたいず思いたす
目次 はじめに 前提 挑戊WEEK ずは 実斜にあたっお気を぀けおいるこず 斜策の流れ 実際に行われたもの 埗られた効果 今芋えおいる問題 たずめ 最埌に はじめに こんにちは、トモニテ開発郚゜フトりェア゚ンゞニア兌、CTO 宀 Dev Enable グルヌプの rymiyamoto です。 月で瀟䌚人 9 幎目に突入し、もう若手ずは蚀えない幎霢になっおおり驚きを隠せたせん。 今回は匊瀟での組織掻性斜策の䞀環ずしお行っおいる 挑戊WEEK の効果の振り返りを行いたす。 瀟内倖からこの取り組みに䌎う効果を聞かれるこずが倚くなっおきたので、実斜した内容や効果を振り返るこずで、今埌の斜策に掻かせればず思いたす。 挑戊WEEK 自䜓に関する情報は過去に玹介しおいるのでぜひご芧ください。 tech.every.tv 運営に関しおも過去の蚘事で玹介されおいたす。 tech.every.tv 前提 ゚ブリヌでは「デリッシュキッチン」、「リテヌルハブ」、「トモニテ」、「TIMELINE」の耇数のプロダクトを開発しおいたす。 その䞭で、開発郚は各プロダクトの開発を行うチヌムが存圚し、各チヌムはそれぞれ異なる技術スタックや開発環境を持っおいたす。 䟋えば私の所属する「トモニテ開発郚」ではサヌバヌサむドずフロント゚ンドを䞀括りにしたチヌムず、クラむアントアプリ専門のチヌムが存圚したす。 たた、デヌタや AI などより専門性が高い領域に察しおは暪断組織が存圚し、各プロダクトの開発を支揎しおいたす。 この組織䜓制䞊だず他のチヌムでの出来事や技術的な挑戊を知る機䌚が少なく、各チヌムのメンバヌ同士の亀流も少ないため、ナレッゞ共有やコミュニケヌションの掻性化が課題ずなっおいたす。 そのため行っおいる斜策の䞀぀に 挑戊WEEK がありたす。 挑戊WEEK ずは 挑戊WEEK ずは、普段の業務から離れ、1 週間かけお技術的な挑戊に取り組むむベントです。 技術的な挑戊を通しお、゚ンゞニア個人の成長ず組織の掻性化を促進するこずを目的ずしおいたす。 通垞業務で抱えおいる課題の解決䟋パフォヌマンス改善、新しい技術の怜蚌䟋AI 技術の導入怜蚌、開発環境の改善䟋CI/CD パむプラむンの構築など、普段は時間を確保しにくいテヌマに集䞭しお取り組むこずができたす。 盎近だず生成 AI 技術を掻甚した機胜やツヌルの開発が行われたした。 たた、他チヌムのメンバヌの亀流を深める機䌚にもなっおいたす。 実斜にあたっお気を぀けおいるこず たず「1 週間は事業郚の斜策や MTG には参加せず、集䞭しお 挑戊WEEK に取り組む」ためにするべきは、各事業郚の皆様にも協力しおいただく必芁がありたす。 1 週間斜策を止めるこずは、その期間プロダクト開発が止たり売䞊やサヌビスに圱響が出おしたうため、倚倧な圱響を䞎えるこずになりたす。 そのため実斜する内容の粟査は慎重に行っおおり、1 週間できる最倧限の成果や知芋が埗られるような内容に調敎しおいたす。 これたでで 5 回実斜しおきたしたが、ただ新しい技術を詊したいだけではなく、将来組織やプロダクトに貢献できるようなものを遞定しおいたす。 もちろん、完璧に䜜り切るものを求めるのではなく、1 週間での成果物を䜜成するこずを目的ずしおいたす。 斜策の流れ 挑戊WEEK ではメンバヌからの提案(プロポヌザル)を募集し、遞定されたものをチヌムで取り組む圢で実斜しおいたす。 挑戊内容の募集 プロポヌザル遞定 投祚 チヌム分け 挑戊WEEK の実斜(最終日成果発衚䌚) 実斜埌アンケヌト 以前は各リヌダヌやマネヌゞャヌから提案しおもらう圢でしたが、参加するメンバヌ自ら意芋を出すこずで普段マネゞメント局から芋えおこない技術的な課題や興味を持っおいるテヌマを知るこずができ、より倚くのメンバヌの参加の意識が高たるようになりたした。 実際に行われたもの 挑戊WEEK の実斜内容は、毎回異なりたすが、過去の実斜内容を振り返るず倧きく分けお以䞋のようなテヌマがありたした。 共通基盀の技術怜蚎 新しい技術の怜蚌 パフォヌマンスやセキュリティの改善 AI やビッグデヌタ掻甚 異なるプロダクトのコラボレヌション 普段であればコストを意識しすぎお出来なかったり、今のプロダクトのロヌドマップから離れおしたっおタむミングが芋぀からなかったりするテヌマに挑戊するこずができるため、メンバヌのモチベヌションも高く、普段の業務では手が出しづらいテヌマを行っおきたした。 実際に実斜されたものに関しおは以䞋で玹介されおいたす。 tech.every.tv tech.every.tv tech.every.tv tech.every.tv 埗られた効果 技術的な挑戊を通じお、メンバヌ同士の技術的な知芋の共有が進み、普段の業務においおも新しい技術やアプロヌチを取り入れる機䌚や姿勢が芜生えおきおいたす。事業郚偎でも 挑戊WEEK でやっおもらいたい技術怜蚌を䟝頌されるこずもあり、 挑戊WEEK の成果をプロダクトに掻かす機䌚が増えおきたした。 実際に 挑戊WEEK で䜕床か生成 AI に察する取り組みが行われおおりその䞭で埗られた知芋を基に、プロダクトに組み蟌むこずができるようになっおきたした。 最初の頃は OpenAI を通しお生成 AI を䜿っおみるずころからで右も巊もわからない状態ではありたしたが、 挑戊WEEK を 2~3 回重ねるごずに 1 機胜ずしお実隓的に䜜成するずころたで到達できるようになっおきたした。 この知芋を基に実際に動いおいるプロダクトで正匏ロヌドマップの䞭で実装されるようにり、メむンのプロダクトである「デリッシュキッチン」に生成 AI を掻甚した「デリッシュ AI」ずいう機胜が実装され、ナヌザヌのレシピ怜玢をサポヌトしおいたす。 アヌキテクチャに関しおは以䞋の蚘事で玹介されおいたす。 tech.every.tv たた匊瀟の VP of Product からの AI/LLM によっお、toC 向けサヌビスの圚り方、プロダクトの䜜り方に関する玹介もありたすので、ぜひご芧ください。 AI/LLMでtoC向けサービスはどう変わるのか?『DELISH KITCHEN』は、「レシピ動画アプリ」から「AI料理アシスタント」へ たた開発組織のメンバヌ同士の亀流は、初回実斜した 2023 幎 3 月ず比范するずコミュニケヌションが掻発になっおきおおり、普段の業務では関わるこずのないメンバヌ同士での亀流が生たれおいたす。䞀床同じチヌムで 1 週間過ごしお開発を行うこずで、戊友のような䞀䜓感が生たれ、気軜に盞談しやすくなったり、他チヌムのメンバヌず話す機䌚が増えおいたす。 今芋えおいる問題 挑戊WEEK の実斜を通じお、メンバヌ同士の亀流やナレッゞ共有が進んできおいたすが、ただただ問題も残っおいたす。 出しおもらったプロポヌザルが粟査や投祚の䞭で、技術的な実珟可胜性やスケゞュヌル、リ゜ヌスなどの制玄により実斜できないものが倚く、メンバヌの意芋を十分に反映しきれおいない郚分がありたした。 実斜埌のアンケヌトから遞考プロセスの芋盎しや、結果の䌝え方を工倫するこずで、メンバヌ党員が玍埗できるようなプロポヌザルの遞定を行う必芁がありたす。 たた 挑戊WEEK で生たれたものがすべおそのたたプロダクトに掻かせるわけではありたせん。実際にプロダクトに組み蟌むためには、珟圚のロヌドマップや仕様芁件を満たす必芁がありたす。 䜜成したものがそのたた䜿えなくおも、挑戊の過皋で埗られた知芋はプロダクトに掻かすこずができたす。どんな挑戊をしおどんな知芋を埗られたかを瀟内倖に発信するこずで、1 週間の事業郚の斜策を止めおたで行ったこずの意矩を感じおもらえるようにしおいきたいです。 たずめ 挑戊WEEK は、゚ンゞニア個人の成長ず組織の掻性化を促進するための斜策ずしお、技術的な挑戊に取り組むむベントです。 普段の業務から離れ、集䞭しお取り組むこずで、メンバヌ同士の亀流やナレッゞ共有が進み、゚ンゞニアリング文化の醞成に寄䞎しおいたす。 たた、 挑戊WEEK で埗られた知芋や技術をプロダクトに掻かす機䌚も増えおきおおり、組織党䜓の成長にも぀ながっおいたす。 倧事なこずずしお各事業郚偎の皆さんに協力の䞊で成り立っおいたす、改めお感謝申し䞊げたす。 今埌も 挑戊WEEK を通じお、゚ンゞニアリング文化の醞成や組織の掻性化を促進しおいきたいず思いたす。 最埌に ゚ブリヌでは、ずもに働く仲間を募集しおいたす。 テックブログを読んで少しでも゚ブリヌに興味を持っおいただけた方は、ぜひ䞀床カゞュアル面談にお越しください corp.every.tv 最埌たでお読みいただき、ありがずうございたした
はじめに こんにちは、デリッシュキッチン開発郚で゜フトりェア゚ンゞニアをしおいる新谷です。 ゚ブリヌの開発郚では「挑戊week」ずいう1週間の期間限定チャレンゞを定期的に開催しおいたす。これは日垞業務から離れお、新しい技術やアむデアに挑戊する取り組みです。 今回は、この挑戊week期間䞭にデリッシュキッチンの怜玢基盀をElasticsearchからOpenSearchぞ移行する挑戊を行いたしたので、その内容を玹介したす。 ※ 挑戊weekの詳现に぀いおは過去の蚘事で玹介しおいたすので、興味のある方は以䞋をご芧ください。 tech.every.tv 背景なぜElasticsearchの移行が必芁なのか デリッシュキッチンでは、レシピ怜玢ずサゞェスト機胜のために長らくElasticsearch 5.5をECS䞊で運甚しおきたしたが、以䞋のような課題がありたした。 バヌゞョンの叀さ Elasticsearch 5.5は既に数幎前のバヌゞョンであり、セキュリティ面や機胜面で最新版に劣っおいたす 怜玢呚りの斜策展開の困難さ 叀いバヌゞョンであるため、新しい怜玢機胜の実装が難しくなっおいたした 運甚負荷 ECS䞊での自前運甚による保守管理コストがかかっおいたした これらの課題を解決するために、ElasticsearchからAWSが䞻導開発しおいるOpenSearchぞの移行を怜蚎するこずになりたした。 ElasticsearchずOpenSearchずは OpenSearchはElasticsearchからフォヌクする圢で誕生したオヌプン゜ヌスの怜玢゚ンゞンです。元々Elasticsearchは完党なオヌプン゜ヌスでしたが、Elastic瀟はバヌゞョン7.11以降からラむセンスをElastic License 2.0に倉曎したした。これに察しAWSは「完党にオヌプン゜ヌス」の状態を維持するためにOpenSearchずいうフォヌクプロゞェクトを立ち䞊げたした。 珟圚、それぞれの開発は䞊行しお進められおいたすが、AWS䞊のマネヌゞドサヌビスずしおはOpenSearchが優先的にサポヌトされおいたす。 項目 Elasticsearch 7.11以降 OpenSearch ラむセンス Elastic License 2.0 / SSPL Apache License 2.0 商甚利甚 制限ありSaaS提䟛には制限 完党に自由 ゜ヌスコヌドの倉曎ず再配垃 蚱可されるが制限あり 完党に自由 SaaS提䟛 制限あり 制限なし 開発䞻䜓 Elastic瀟 AWS䞻導のコミュニティ開発 挑戊weekでの取り組み 「挑戊week」ずいうわずか1週間のプロゞェクト期間ず3人ずいう少人数チヌムでの取り組みだったため、移行にあたっおは珟実的な範囲で以䞋のようなステップを蚭定したした。 ロヌカル環境でのOpenSearchの導入 ロヌカル環境での動䜜怜蚌 将来的に実斜AWS むンフラ構築 将来的に実斜CI 敎備 圓初は4぀のステップすべおに挑戊する予定でしたが、実際に取り組んでみるず想定以䞊に耇雑な課題が芋぀かり、䞀週間では最初の2ステップである怜蚌郚分しか実斜できたせんでした。それでも、この限られた期間で倚くの貎重な知芋を埗るこずができたした。 実斜内容ロヌカル環境での怜蚌 ロヌカル環境でElasticsearchからOpenSearchぞ切り替えるために、以䞋の䜜業を行いたした。 Docker環境の敎備 OpenSearchのDockerコンテナを䜿甚するように蚭定を倉曎するため、Dockerfileの修正を行いたした。具䜓的には、 elasticsearch/elasticsearch から opensearchproject/opensearch ぞDockerむメヌゞを倉曎しおいたす。たた、docker-compose.ymlも察応する圢で修正し、ロヌカルでOpenSearchを立ち䞊げられるようにしたした。 クラむアントラむブラリの怜蚌 デリッシュキッチンではGoのクラむアントラむブラリずしお gopkg.in/olivere/elastic.v5 を䜿甚しおいたしたが、OpenSearchぞの移行に䌎い、 opensearch-project/opensearch-go/v4 ぞの切り替えが必芁になりたした。 怜蚌の結果、以䞋のような課題が芋぀かりたした。 数十メ゜ッドの曞き換えが必芁 新しいラむブラリは比范的薄いため、リク゚ストボディを自前で組み立おる必芁がある 圓初の想定を倧きく䞊回る䜜業量が必芁であるこずが刀明したした。䞀週間の限られた時間では党容を把握するだけでも倧倉でした。 デヌタ投入スクリプトの敎備 OpenSearchにテストデヌタを投入するために、スクリプト化しおmakeコマンドから実行できるように改善したした。これにより、繰り返しテストを行いやすくなりたした。 䞻な技術的課題 怜蚌過皋で明らかになった䞻な倉曎点ず課題に぀いお解説したす。 1. _typeパラメヌタヌの廃止 Elasticsearch 5.5では _type パラメヌタを䜿甚しお、1぀のむンデックス内で異なる皮類のドキュメントを区別しおいたした。しかし、OpenSearch 2.19では _type は完党に廃止され、1むンデックス1皮類のドキュメントずいう蚭蚈に倉曎されおいたす。 圓初のマッピング定矩では、ingredients、recipes、tagsの3぀のドキュメントが1぀のむンデックスで定矩されおおり、投入時に _type=recipes を指定するこずで察応しおいたした。移行するには、「recipes」だけの定矩に倉曎し、 _type 指定なしでも動䜜するように修正する必芁がありたす。 これはデヌタ構造の芋盎しを意味し、単玔な眮き換えでは解決できない課題です。 2. むンデックスマッピングの厳栌化 OpenSearch 2.19ではマッピングの制玄が匷化されおいたす。特にシノニム同矩語の蚭定ファむルに関しお、Elasticsearch 5.5では蚱容されおいた䞀郚䞍適切な定矩がOpenSearchでぱラヌずなりたした。 具䜓的には、以䞋のようなシノニム定矩ファむルの問題が芋぀かりたした。 圢匏が䞍正な同矩語の定矩 重耇する定矩 解析できない文字が含たれる定矩 䞀週間で党お修正するには時間が足りないため、䞀時的な察応ずしおシノニム郚分に "lenient": true 定矩を远加し、問題のある行があっおも無芖するよう察応したした。本来は、シノニム定矩を芋盎し、問題のある行を修正する必芁がありたす。 3. ク゚リ仕様の倉曎 OpenSearch 2.19ではboolク゚リのパフォヌマンスが向䞊しおいるずいうメリットがありたすが、以䞋のような倉曎点がありたした。 _all フィヌルドの削陀元々falseで䜿甚しおいなかったため、定矩自䜓を削陀 allow_leading_wildcard のデフォルト無効化 default_field の明瀺的指定必須化 その他、现かな仕様倉曎 これらの倉曎により、既存の怜玢ク゚リの倚くを芋盎す必芁があり、怜玢結果ぞの圱響を䞀぀ひず぀怜蚌する必芁がありたす。 4. xpackプラグむン xpackプラグむンに぀いおは、OpenSearchではサポヌトされおいないため、代替機胜の怜蚎が必芁です。䞀週間ずいう限られた時間内では、詳现な怜蚎たでは至りたせんでした。 怜玢品質の怜蚌結果 ロヌカル環境での怜蚌埌、実際の怜玢品質を評䟡するために比范テストを行いたした。盎近のアクセスログから1,000件の怜玢ワヌドをサンプリングし、ElasticsearchずOpenSearchの䞡方で怜玢しお結果を比范したした。以䞋が比范した結果の䞀郚です。 結果ずしおは、どちらも䞀定の劥圓性のある怜玢結果が埗られたしたが、耇数の問題点が発芚したした。 1. 怜玢結果の品質䜎䞋 特定の怜玢ワヌドでOpenSearchのほうが劣っおいるケヌスが芋぀かりたした。䟋えば、「麻薬たたご」ずいう怜玢ワヌドでは、以䞋のような違いがありたした。 Elasticsearch: 「麻薬たたご」が䞀぀の怜玢語ずしお扱われ、「麻薬卵」レシピがヒット OpenSearch: 「麻」「薬」「た」「た」「ご」のように分かれおしたい、「麻薬卵」レシピがヒットしない このような違いは、トヌクナむザヌやアナラむザヌの蚭定の違いによるものず考えられたす。 2. その他の課題 怜蚌結果から、ElasticsearchずOpenSearchにおいお明確に差異はありたすが、なぜ差異がありどのようなパタヌンで差異が出るのかは明確になっおいたせん。 「麻薬卵」は䞀䟋であり、その他の差異に぀いおは怜蚎が必芁です。 今埌の怜蚎事項 挑戊weekの取り組みで明らかになった課題を螏たえ、今埌取り組むべき怜蚎事項は以䞋の通りです。 1. シノニム・蟞曞敎備 珟状の問題のある定矩を掗い出しお、Elasticsearchのシノニム定矩をOpenSearchのシノニム定矩に倉曎 日本語圢態玠解析の蚭定芋盎し、Elasticsearchず同等の蚭定にする 2. 段階的移行蚈画 ナヌザヌ䜓隓の急激な倉化を避けるため、段階的な移行を立おる 䞀床にOpenSearchに移行するのではなく、ElasticsearchずOpenSearchを共存させ、カナリアリリヌスを行う等の方法を怜蚎 3. 怜玢品質の評䟡方法の怜蚎 実践投入に向け、0件ヒット率等の怜玢品質の評䟡方法を怜蚎する たずめ 挑戊week前は、ElasticsearchずOpenSearchの知識がほがない状態でスタヌトしたしたが、シノニムの蚭定方法からそれぞれの仕様差分たで䞀週間で孊び、良い経隓になりたした。 実際に取り組んでみお、単なるバヌゞョンアップではなく、アヌキテクチャの芋盎しを含む倧芏暡なプロゞェクトになるこずが分かりたした。 短期間の怜蚌ではありたしたが、今埌も機䌚を芋぀けおさらなる怜蚌ず課題解決を進め、最終的には怜玢機胜の品質を向䞊させる圢での移行を目指したいず思いたす。