TECH PLAY

セーフィー株式会社

セーフィー株式会社 の技術ブログ

221

この記事は Safie Engineers' Blog! Advent Calendar 2025 9日目の記事です。 はじめに こんにちは、エンジニアリングオフィスの横道 ( @m_yokomichi )です。 2025年、AI技術は私たちの予想を超えるスピードで進化を遂げました。いまや生成AIを使いこなせるか否かは、個人の生産性だけでなく、 エンジニアとしてのキャリア、ひいては企業の競争力そのものを左右する と言っても過言ではありません。 今後、活用できる層とそうでない層の差は広がる一方です。そのため、生成AIの活用は私たちセーフィーにとっても全社の重要課題であり、開発本部として組織的に向き合うべきテーマとなっています。 本記事では、開発本部全体で取り組んでいる「生成AI利用促進プロジェクト」について、以下のポイントを中心にご紹介します。 組織課題を解決するための「5つの戦略軸」 ボトムアップで進める実際の活動内容 導入による具体的な成果と今後の展望 単なるツールの導入事例ではなく、「組織文化をどう変えていくか」という観点での全貌をお伝えします。 はじめに 私たちが直面していた「5つの壁」 1. 情報収集の「非効率性」 2. 技術検証・導入の「属人化」 3. ナレッジの「サイロ化」 4. 活用機運の「温度差」 5. 技術的取り組みの「認知不足」 解決への戦略的アプローチ:5つの軸 プロジェクト全体構想図 軸1:情報収集活性化 📡 軸2:技術検証・導入 🛠️ 軸3:ナレッジデータベースマネジメント 📚 軸4:生成AI活性化 🔥 軸5:社外発信 📢 実際の活動と想定外の反響 20名の有志が集結 分科会による自律的な運営 成果と今後の展望 主な成果 今後のロードマップ おわりに 私たちが直面していた「5つの壁」 生成AI活用を組織的に推進しようとした際、私たちは大きく分けて5つの問題領域に直面していました。これらは、多くの開発組織が共通して抱える悩みではないでしょうか。 1. 情報収集の「非効率性」 外部の技術動向を個人がバラバラに追っているため、組織としてのインプットが非効率でした。「隣のチームも同じ調査をしていた」という車輪の再発明が起きており、組織としてのスピード感が損なわれていました。 2. 技術検証・導入の「属人化」 「この新機能を使いたい」と思っても、導入プロセスや評価基準が不明確でした。結果として、意欲あるメンバーの技術選定に時間がかかり、有益な技術の導入による機会損失が発生していました。 3. ナレッジの「サイロ化」 Aさんは高度なプロンプトを知っているのに、Bさんは同じ課題で躓いている。成功事例や失敗事例(アンチパターン)が共有されず、ノウハウが個人の頭の中だけに留まっていました。 4. 活用機運の「温度差」 「便利そうだけど、自分の業務での使い所がわからない」というメンバーも多く、一部の感度が高い層だけが活用している状態でした。 5. 技術的取り組みの「認知不足」 せっかく先進的な取り組みをしていても、それが外部に伝わっていなければ採用やブランディングには繋がりません。また、外部コミュニティとの接点が薄く、フィードバックを得る機会も不足していました。 解決への戦略的アプローチ:5つの軸 これらの課題を打破するため、私たちは「5つの軸」を定義し、戦略的なアプローチを開始しました。 プロジェクト全体構想図 まず、以下のサイクルを回すことで、生成AI(AI技術)の導入・定着を目指しました。生成AI利用促進チームがハブとなり、開発本部全体を巻き込んでいます。 ここからは、具体的な5つの軸について解説します。 軸1:情報収集活性化 📡 目的: 組織的な「アンテナ」の感度を高め、技術選定を高速化する 個人の努力に依存していた情報収集を、組織の活動へと昇華させました。 トレンドの定点観測: 最新ツールや事例をチームで分担して調査 導入ジャッジ: 利用方法が明確なものは「実務検証」へ、未導入技術は「企画」へとスムーズに移行させるフローを確立 軸2:技術検証・導入 🛠️ 目的: 新技術を「安全に」「素早く」試せる環境を作る 「使ってみたい」を「使える」にするための環境整備です。 環境整備: アカウント管理やLLM Proxy基盤の構築 ガイドライン策定: セキュリティや個人情報の取り扱い、機密情報の保持に関するルールを明確化し、安全に利用できる環境を提供 軸3:ナレッジデータベースマネジメント 📚 目的: 知見を「資産」化し、車輪の再発明を防ぐ DB構築: ベストプラクティス、失敗事例、プロンプトライブラリを一元管理 メンテナンス: 情報の鮮度を保つため、陳腐化した情報の更新フローを整備 テンプレート化: 開発、分析、ドキュメント作成など、用途別の「再利用可能なプロンプト」を整備 軸4:生成AI活性化 🔥 目的: 組織全体の「熱量」を上げ、文化を作る イベント開催: 勉強会、LT(ライトニングトーク)、ハッカソンなどを企画 横展開: 成功事例を部門を超えて共有し、「自分もやってみよう」という空気を醸成 軸5:社外発信 📢 目的: 取り組みを「価値」に変え、新たな知見を呼び込む アウトプット: 技術ブログやイベント登壇を通じた発信 還流: 社外からのフィードバックを社内に取り込み、さらなる改善につなげるサイクル 実際の活動と想定外の反響 戦略は描けましたが、私一人で実行できるものではありません。そこで開発本部全体からメンバーを公募したところ、予想外の反応がありました。 20名の有志が集結 当初は数名集まれば良いと考えていましたが、 約20名ものメンバーが手を挙げてくれました。 開発本部のエンジニアたちが、いかにこの課題に熱意を持っていたかの表れであり、非常に嬉しい誤算でした。 分科会による自律的な運営 メンバーの自主性を尊重し、前述の5つの軸ごとに「分科会」を組成しました。 週次・隔週で定例MTGを行い、それぞれの強みを活かしてアクションプランを実行しています。トップダウンではなく、現場のエンジニアが主導するボトムアップ型のプロジェクトとして機能しています。 成果と今後の展望 2025年9月の発足から数ヶ月、土台づくりに注力してきましたが、すでに目に見える変化が起きています。 主な成果 利用率の向上: Claude CodeのMaxプラン等の高度な機能を利用するメンバーが前月比で増加傾向。 学習文化の定着: 開発本部の 約半数 が生成AI勉強会に参加。 ナレッジベース稼働: 独自のデータベースが構築され、日々知見が蓄積されている。 ポータルサイト開設: ツールやガイドライン、最新情報を集約した「生成AIポータル」を公開。 今後のロードマップ 📍 短期(FY25年度内) 技術検証: LLM Proxy基盤の構築、Claude Teamプランへの移管。 活性化: LT大会の実施(11/27、12/11予定)、ハンズオン・ハッカソンの開催。 ナレッジ: プロンプトライブラリのカテゴリ拡充(コードレビュー、設計支援など)。 📍 中長期(来年度以降) 効果測定: 単なる利用者数ではなく、コード品質や開発速度など「生産性指標」への貢献を可視化。 全社展開: 開発本部で培ったノウハウを他部門へ横展開し、全社的なDXを支援。 文化の定着: 新入社員向けの「生成AI活用研修」などを通じ、AI活用を空気のような「当たり前」にする。 おわりに 生成AIを組織で活用できている状態にするには、個人の「点」の活動だけでは限界があります。組織全体で戦略的に取り組み、「面」の活動にすることで初めて、知見の標準化や文化醸成が可能になります。 今回ご紹介した「5つの軸」はあくまでセーフィーの一例ですが、組織的なAI活用に悩む皆様のヒントになれば幸いです。 セーフィー開発本部では、今後もイベント等を通じて知見をオープンにしていきます。「うちではこうしているよ!」という他社の皆様、ぜひ情報交換させてください!
アバター
この記事は  Safie Engineers' Blog! Advent Calendar  の8日目の記事です。 こんにちは、セーフィー株式会社でサイバーセキュリティを担当している金原です。 前回の記事「 セーフィーのサイバーセキュリティ戦略の作り方 」では、私たちが目指す「セキュリティが当たり前の文化」と「そこに到達するための戦略」についてお伝えしました。今回は、戦略の具体的な打ち手の一つ、 「脅威モデリング」 について深掘りします。 「脅威モデリング」と聞くと、専門用語が多くて「難しそう」「時間がかかりそう」と感じてしまうことはありませんか? 正直に言うと、私たちも最初はそうでした。 しかし、試行錯誤してたどり着いた結論はシンプルです。脅威モデリングの本質は 「関係者同士の対話を促進するコミュニケーションツール」 だということ。 今回は、一般的な脅威モデリングの手法を解説しつつ、それを「セーフィーではどう解釈し、運用しているか」という 実践的なナレッジ(=セーフィー流の型) をセットで公開します。これから脅威モデリングを始めたい方、もっと活用していきたい方の「生きた教科書」になれば幸いです。 そもそも「脅威モデリング」って何? なぜ今、私たちがこれを推すのか 脅威モデリングの進め方(解説とセーフィー流の実践) 4つの重要な質問 【問1】私たちは何に取り組んでいるか? ~モデルを作る~ 【問2】何が問題になりうるか? ~STRIDEでリスクを見つける~ 【問3】それに対して何をするのか? ~リスク評価と対策~ 【問4】十分にうまくできたか? ~ふりかえり~ セーフィーでの活用事例 1. セキュリティレビューへの「部分導入」 2. 「すぐに始められる」テンプレートの用意 3. 生成AIを「副操縦士」にする さいごに そもそも「脅威モデリング」って何? 一言でいうと、 「システムを作る前に、攻撃者の視点を踏まえ『起きたら困ること』を分析し、対策を考える活動」 です。 通常、開発の現場では「どんな機能を作るか(要件)」や「どうやって作るか(設計)」に集中しがちです。そこに 「何が問題になりうるか(セキュリティリスク)」 という視点をプラスします。 なぜ今、私たちがこれを推すのか 理由は大きく2つあります。 「シフトレフト」の世界標準だから NISTの「SSDF」やOWASPの「SAMM v2」など、主要なガイドラインで推奨されています。設計段階でリスクを潰すことで、手戻りを防ぐためです。 生きたセキュリティ教育になるから(★最重要) 私が特に重視しているのはこちらです。脅威モデリングを行うには、エンジニア、PM、セキュリティ担当者が集まって会話をする必要があります。 「ここのデータって、どういう流れでDBに入るんだっけ?」 「このAPI、認証なしで叩けたらマズいよね?」 こうした会話自体が、座学の研修よりもはるかに効果的な 「生きたセキュリティ教育」 になります。ドメイン知識とセキュリティ知識が、対話を通じてチーム全体に染み渡るのです。 脅威モデリングの進め方(解説とセーフィー流の実践) では、具体的にどう進めればいいのでしょうか? 基本は以下の 「4つの重要な質問」 に答える形で進めていきます。 ここで大事な心構えは 「完璧を目指さない」 こと。セーフィーでは、 「間違ってもいいから、まずはホワイトボードに絵を描いて話そう」 を合言葉にしています。 4つの重要な質問 【問1】私たちは何に取り組んでいるか? ~モデルを作る~ まずは、システムの「形」を可視化します。一般的には、データフローダイヤグラム(DFD)が推奨されます。 ■DFDの書き方(いきなり詳細を描かない) DFDは「データがどこから来て、どこへ行くのか」という流れに注目した図です。 以下の5つの要素で図を表現します。 プロセス (Process) :処理や機能(丸) データストア (Data Store) :DBやファイルなどのデータが留まるところ(二本線) 外部エンティティ (External Entity) :ユーザーや連携システム(四角) データフロー (Data Flow) :データの流れ(矢印) 信頼境界 (Trust Boundary) :インターネットと社内LANの間などの境界線(点線) よくある落とし穴が、「最初から詳細に描こうとして挫折する」ということ。私たちは 「抽象から具体へ」 という2ステップをおすすめしています。 ① コンテキストダイヤグラム でまずは「外」と「中」を分ける システム全体を1つの「箱」として捉え、外部(ユーザーや連携システム)とのやり取りだけを描きます。これだけで「守るべき範囲」が明確になります。 ② レベル0ダイヤグラム で内部構造を分解する 次に、箱の中身を主要なプロセスに分解し、データの保存場所(データストア)を描き足します。 ここで最も重要なのが 「信頼境界(Trust Boundary)」 という点線です。ここをデータがまたぐとき、脅威が発生しやすくなります。 必要に応じて、ここからさらにレベル1…、のように詳細化していきます。 ■セーフィー流の実践(厳密さよりも「対話の種」) 教科書通りの記号(丸や二本線など)を使おうとすると「これであってる?」と手が止まりがちです。私たちの現場では、 「ホワイトボード(またはMiro)に10分ぐらいで描けるレベルでいい」 としています。 厳密な記法より、 「データの流れ(線)」 が合っていればOK。 詳細な設計図である必要はない。先ほどの 「信頼境界(点線)」をまたぐ場所 がわかれば、そこが攻撃ポイントだと判断できる。 加えて、一度で終わりにせず、徐々に詳細度を上げていくスタイルを取っています。 📘 もっと学びたい方へ 具体的なDFDの作り方は、書籍『データフローダイアグラム いにしえの技術がもたらす システム設計の可能性』(大嶋和幸、松永守峰 / 翔泳社)が非常に参考になります。 【問2】何が問題になりうるか? ~STRIDEでリスクを見つける~ モデルができたら、次は「ここが攻撃されたらどうなる?」を考えます。 ここでのポイントは、高度なハッキング方法を語るのではなく、 「起きたら困ること」 を洗い出すことです。攻撃手法の話になると専門家しかわからなくなりますが、「困ること」なら関係者全員で議論できます。 ■STRIDEフレームワーク 脅威を見つける切り口として、 「STRIDE(ストライド)」 というフレームワークを使うと便利です。以下のような「問いかけ」をしながら問1で作成したDFD上に付箋で書き出していくとスムーズです。 頭文字 脅威の種類 問いかけの例 具体例(Webアプリ) S Spoofing (なりすまし) 私たちまたはユーザーは、なりすましが起きて何が困るか? 他人のアカウントでログインされる T Tampering (改ざん) 私たちまたはユーザーは、データ改ざんが起きて何が困るか? DBの値や通信内容を書き換えられる R Repudiation (否認) 私たちまたはユーザーは、否認できる状態で何が困るか? 「操作していない」と言い逃れされる I Information Disclosure (情報漏洩) 私たちまたはユーザーは、データ漏洩が起きて何が困るか? 個人情報や機密データが漏れる D Denial of Service (サービス拒否) 私たちまたはユーザーは、システムの停止/遅延が起きて何が困るか? システムがダウンして使えなくなる E Elevation of Privilege (権限昇格) 私たちまたはユーザーは、権限を越えた操作ができて何が困るか? 一般ユーザーが管理者操作を行う ■セーフィー流の実践:「思考停止を防ぐカンペ」として使う STRIDEを事前にすべて暗記する必要はありません。私たちは上記のような具体例をいくつか添えた表を「問いを立てるためのカンペ」として使っています。 レビューの場で問いかけるためのトリガーになれば十分です。エンジニアが「あ、それだとこういうことが起きると困りますね」と気づけば、それが立派な脅威分析です。専門用語を覚えるより、 「困ること」を言語化できること を重視しています。 📘 もっと学びたい方へ STRIDEやセキュア設計については、書籍『セキュアなソフトウェアの設計と開発 脅威モデリングに基づく普遍的アプローチ』(ローレン・コンフェルダー / 秀和システム)がおすすめです。 【問3】それに対して何をするのか? ~リスク評価と対策~ 脅威がたくさん出てくると、「全部直すなんて無理!」となってしまいますよね。 大事なのは、「同時にすべてを対策することはできない」 という前提に立つことです。リソースも時間も有限ですから、優先順位をつける必要があります。 リスクマップ: 「発生確率」×「影響度」で定性的に評価して優先度を決めます。 対策: リスク「高」のものから順にチケット化し、バックログに積みます。 ■リスクマップの例 ■セーフィー流の実践:必要に応じて評価方法を変える 教科書的には厳密にスコアリングして評価することが推奨されがちですが、全てのリスクでそれをやるとスピードが落ちてしまいます。 セーフィーでは、対象システムや情報の重要度に応じて「評価方法(物差し)」を使い分けています。 スピード感や柔軟性が求められる通常の機能は、「定性評価(高・中・低)」でスピーディに判断し、対策の要否を決めます。一方で、決済周りや特に重要な基盤システムは、「定量評価( CVSS や OWASP Risk Rating Methodology 等)」を用いて厳密にスコアリングし、監査にも耐えうる根拠を残します。もちろん、2つを組み合わせるケースもあります。 「スピード重視」と「厳密さ」のメリハリをつけること。これを私たちは大切にしています。 📘 もっと学びたい方へ リスク評価の深掘りには、書籍『脅威インテリジェンスの教科書』(石川朝久 / 技術評論社)が参考になります。 【問4】十分にうまくできたか? ~ふりかえり~ このふりかえりは飛ばされがちですが、実は脅威モデリングを組織やチームに浸透させるためには、とても重要な問いになります。 対策が妥当かどうかの評価も大事ですが、「脅威モデリングの進め方自体がどうだったか」 のふりかえりで経験学習のサイクルを回します。 ■セーフィー流の実践(10分で終わらせる「タイムボックス」) ふりかえりの手法は多数ありますが、セーフィーでは軽量に実施できる「+/Δ(プラス/デルタ)」を採用して、 「10分間」 という時間を区切って実践しています。理由は、重くすると続かないからです。継続性が大事。 「DFDのスコープが広すぎて議論が発散したね」 「××さんが詳しいから、次は呼ぼう」 こうした小さな改善の積み重ね(アジャイルなアプローチ)が、チームのセキュリティ筋肉を育てていきます。 📘 もっと学びたい方へ ふりかえりの手法や有用性を学ぶなら、書籍『アジャイルなチームをつくる ふりかえりガイドブック 始め方・ふりかえりの型・手法・マインドセット』(森 一樹/翔泳社)がおすすめです。 セーフィーでの活用事例 ここまで脅威モデリングの手法とセーフィー流の実践をお伝えしました。では、これを具体的にどのように現場に落とし込んでいるのか?私たちの現在の取り組みを紹介します。 1. セキュリティレビューへの「部分導入」 これまでチェックリストベースで行っていたセキュリティレビューの一部に、脅威モデリングを取り入れ始めています。 開発者から説明を受ける際、セキュリティチームが手元で簡易的なモデルを作り、「ここのデータの流れ、信頼境界またいでるけど大丈夫?」といった対話をします。 チェックリストだけでは見えない重要箇所のレビューができますし、静的なアーキテクチャ図よりもデータやプロセスの流れが整理できるので、開発者からも好評です。私自身も、多くのセキュリティレビューを実施する中で、「あれどうなってたっけ?」となったときに、レビュー時に作成したモデルを見ることで思い出すことができて助かってます。 セキュリティレビューで作った脅威モデルの例 2. 「すぐに始められる」テンプレートの用意 「準備が面倒」という心理的ハードルを下げるため、オンラインホワイトボードツール(Miro)に 「脅威モデリングテンプレート」 を作成しました。 DFDのパーツとSTRIDEの付箋、そして「進め方」があらかじめ配置されています。これを開けば、すぐに議論に入れる状態を作っています。 脅威モデリングテンプレート(Miro) 3. 生成AIを「副操縦士」にする ここが最近のホットトピックです。私たちは 生成AI(Gemini等) を積極的に活用しています。 ゼロから「どんな脅威がある?」と考えるのは、認知負荷が高い作業です。そこで、システムの概要やユースケースをAIに与えて、 「DFDのドラフト」や「想定される脅威リスト」 を出力させます。 もちろんAIの出力は完璧ではありません。しかし、 「AIが出した80点の回答」を、人間のエンジニアが「セーフィーの現場知識(ドメイン知識)」で修正・補完して100点にする というプロセスは、ゼロから考えるより圧倒的に効率的です。 例えば、「小規模なIoTクラウドカメラシステム」というお題でGeminiに出力させた例がこちらです。(注:セーフィーのシステムではありません) Geminiが出力したモデル(Mermaid) Geminiが出力したリスクの一例 「カメラの物理的盗難」といった、IoTならではのリスクまで指摘してくれています。これを叩き台にすることで、議論のスタート地点を大幅に進めることができます。 さいごに 脅威モデリングを組織に浸透させるために一番大切なこと。それは、 「最初から完璧を目指さない」 ことです。 最初から正解の図を作ろうとすると手が止まってしまいます。「間違っててもいいから、まずはホワイトボードに絵を描いて話そう」。このスタンスこそが、セキュリティ文化を作る第一歩だと私は信じています。 この記事を読んで、「ちょっと面白そうだな」と思った方は、ぜひ次の設計レビューで 「これ、攻撃者に狙われたとして、起きたら困ることは何ですかね?」 と問いかけてみてください。 セーフィーでは、こうした「対話」を大切にしながら、セキュリティを「専門家だけの仕事」から「従業員みんなの仕事」に変えていこうとしています。 「一緒に文化を作っていきたい!」という方がいれば、ぜひカジュアルにお話ししましょう! https://safie.co.jp/teams https://open.talentio.com/r/1/c/safie/pages/71628
アバター
この記事は Safie Engineers' Blog! Advent Calendar の7日目の記事です。 情報システムグループの松尾です。 以前、当ブログにて、情シスチームがアジャイル型の仕事の話へ変革した際の記事を書かせていただきました。 engineers.safie.link 今回はその続編として、アジャイルなチーム作りをさらに進める中で生まれた、 「もやもやリスト」を用いた継続的改善(カイゼン)の取り組み についてお話しします。 「隠れた負債」への気付き 心理的ハードルを下げる「もやもやリスト」 登録コストを下げる「仕組み」 「もやもや」から生まれた具体的なカイゼン 1. 入社フローにおけるプロセスの標準化 2. 障害対応の脱属人化(クロスファンクショナルなチームへ) リーダー任せにしない、持続可能な運用に向けて 「隠れた負債」への気付き スプリントを回す中で、日々の業務に埋もれがちな「小さな違和感」を放置することでも問題が発生することに気づきました。 「これは後で対応したほうがいいね」と会話には出るものの、タスク化されずに流れてしまい、忘れた頃に同じトラブルが発生して手戻りになることがありました。 これはアジャイルで言うところの 「透明性」 が欠けている状態であり、見えない技術的負債がチームに蓄積されている状態でした。 そこで私たちは、「完璧な解決策」を最初から求めるのではなく、まずは 「小さな違和感をチームで検知し、カイゼンする仕組み」 を作ることにしました。方針は以下の2点です。 ストックする(透明化): 「やらなきゃ」「ちょっと気になる」を可視化する場所を作る 振り返る(検査と適応): 定期的に見直し、再発防止の仕組みに変える 心理的ハードルを下げる「もやもやリスト」 この仕組みを回すため、Notionにデータベースを作成しました。 ここで重要なのは、 「タスク」として登録するのではなく、「もやもや」として登録すること です。 「タスク登録」と言われると、「完了条件は?」「期限は?」と考えてしまい、登録の心理的ハードルが上がってしまいます。 アジャイルなチームには心理的安全性が不可欠であるため、 「もやもやリスト」 という名前にすることで、未完成の状態でも気軽に放り込めるようにしました。 登録コストを下げる「仕組み」 運用も、徹底的にハードルを下げる工夫をしました。 手動登録: 朝会や雑談で出たものはその場で追加 Slack連携による自動登録: Slack上で課題らしき発言があった際、特定のスタンプを押すと自動的にNotionの「もやもやリスト」に起票される これにより、フロー情報として流れてしまいがちなSlack上の会話を、強制的にストック情報として蓄積する仕組みを整えました。 リストに入った項目は、2週間に一度のサイクルで棚卸しを行います。ここで初めて 「見守り(今は何もしない)」 か 「進捗中(タスク化する)」 かを判断します。 チームのリソースには限りがあるため、「もやもや」は全ての項目を改善するのではなく、現時点で は現状維持でも問題ないとチームで判断できたものは一旦、「現在の対応で継続する」 とすることもありました。 「もやもや」から生まれた具体的なカイゼン このサイクルを回すことで、実際にどのような改善が行われたかをご紹介します。 1. 入社フローにおけるプロセスの標準化 新入社員向けのITオリエンテーションについて、毎月の振り返りを通じてプロセスを改善しました。 作業フローの統一: 雇用形態ごとにバラバラだった手順を統一し、複雑性を排除(オペレーションミスの削減) フィードバックの反映: PC郵送時や代替機貸与時の「ヒヤリハット」をリストから拾い上げ、事前対策フローを追加 一度決めたルールを再確認し、発生した事象に合わせてフロー自体をアップデートし続けています。 2. 障害対応の脱属人化(クロスファンクショナルなチームへ) ネットワーク障害は、どうしても特定のエキスパートに依存しがちな領域です。しかし、アジャイルなチームは「誰かがいないと回らない」状態を良しとしません。 そこで、「もやもやリスト」に上がった障害対応を振り返り、 「従業員の業務を止める時間を極力短くする(MTTRの短縮) 」ことにフォーカスを絞った初動対応マニュアルを作成しました。 これにより、 ネットワーク専任担当者以外でも一次切り分けが可能になり、チーム全体での対応力が向上しました。 リーダー任せにしない、持続可能な運用に向けて 「もやもやリスト」の運用は、現在はグループリーダーである私がファシリテートすることが多いですが、長期的には チームメンバーの誰もが課題を発見し、自律的に改善サイクルを回せる(自己組織化)」状態 を目指していきたいと考えています。 今後は運用ルールのドキュメント化を進め、誰でもこのプロセスを運用できるようにしていきます。また、溜まっていく 「見守り」ステータスの棚卸しも定期的なイベントとして組み込み、「もやもやリスト」を健全に保つ仕組み を作っていく予定です。 来年以降も、こうした小さな「カイゼン」を繰り返し、変化に強い情シスチームを作っていきたいと思います。
アバター
この記事は セーフィー株式会社 Advent Calendar 2025 の12月6日の記事です。 こんにちは! セーフィー株式会社のAndroidエンジニアのジェローム( @yujiro45 )です🎄 昨年、私が書いた「 AndroidでSceneViewを使って、3D/ARを表示する 」という記事で、アプリに3D/AR機能を簡単に実装できるライブラリを紹介しました。 しかし現在、SceneViewはメンテナンスされておらず、コントリビューターさんの GitHubでのコメント によれば新しいリリースの予定はありません。 出典:Github, https://github.com/SceneView/sceneview-android/issues/623#issuecomment-3097955731 (2025/11/12アクセス) 本記事では、 Android XR の新しいライブラリ「 SceneCore 」を使って、アプリ内に3D/ARを表示する方法を説明します。 Android XRとは Android XRのEmulator作成方法 SceneView vs SceneCore 3Dモデルを表示する SceneView SceneCore ExoPlayerの動画を表示する SceneView SceneCore まとめ Android XRとは Android XR は、AR/VR向けのヘッドセットやスマートグラス用に作られた、AI搭載のAndroid OSです。アプリを3D空間に表示・操作でき、開発ではCompose for XRやSceneCoreなどのライブラリを使って実装します。 Android XRのEmulator作成方法 Android XRは、XRが対応した端末でしか使えないので端末持っていない場合は、XRのEmulatorを作成しないといけないです。 セッションの作成は、Android XR デバイスでのみサポートされています。互換性のないデバイスでセッションを作成しようとすると、結果は失敗します。 https://developer.android.com/develop/xr/jetpack-xr-sdk/add-session Android StudioのデバイスマネージャーでXRのカテゴリがあります。そこで、XRのEmulatorを簡単に作成できます。 SceneView vs SceneCore 3Dモデルを表示する 💡この記事では、SceneCoreの最新版(執筆時点)である 1.0.0-alpha08 を使用しています。 SceneViewは最新版の 2.3.0 を使用しています。 SceneViewとSceneCoreの違いを理解するため、両方のライブラリで「ドロイド君」の3Dモデルを表示してみましょう!٩( 'ω' )و 出典:Sketchfab, https://sketchfab.com/3d-models/android-7c30eda007684abbb78ea4b99d22fc2c  (2025/11/12アクセス) SceneView SceneviewexampleTheme { val engine = rememberEngine() val modelLoader = rememberModelLoader(engine) // 3Dモデル用のノードを作成 val modelNode = ModelNode( // 3Dモデルの読み込み (/res/raw) modelInstance = modelLoader.createModelInstance(R.raw.android) ).apply { // 3Dモデルの初期設定 scale = Scale( 1 / 40f ) position = Position( 0f ) } Scene( modifier = Modifier.fillMaxSize(), engine = engine, modelLoader = modelLoader, childNodes = rememberNodes { // モデルノードの追加 add(modelNode) } ) } 結果) 詳細は、以前の記事「 AndroidでSceneViewを使って、3D/ARを表示する 」で説明しているので、ぜひ読んでください〜😃 SceneCore Subspace { val session = LocalSession.current ?: return @Subspace val capabilities = LocalSpatialCapabilities.current var entity by remember(session) { mutableStateOf<GltfModelEntity?>( null ) } LaunchedEffect(session, capabilities.isContent3dEnabled) { // Full Spaceモードに切り替え if ( ! capabilities.isContent3dEnabled) { session.scene.requestFullSpaceMode() return @LaunchedEffect } // 生成は1回だけ if (entity == null ) { // 3Dモデルの読み込み (app/src/main/assets/models/android.glb) val model = GltfModel.create(session, Paths. get ( "models" , "android.glb" )) // 3Dモデルを作成する entity = GltfModelEntity.create(session, model).apply { // Positionを設定する setPose(Pose(Vector3( 0f , 0f , - 1.5f ), Quaternion.Identity)) // Scaleを設定する setScale( 0.2f ) } } } // Lifecycle管理 DisposableEffect(session) { onDispose { entity?.setEnabled( false ) entity?.parent = null entity = null } } } 結果)Android XRで3Dモデルを表示できました〜! SceneViewとSceneCoreの主な違いは以下となります。 SceneView SceneCore 3D Space Scene Subspace 3Dオブジェクト Node Entity 3DモデルのPath /res/raw/ app/src/main/assets/models/ Lifecycle対応 rememberEngine / rememberModelLoader / rememberNodes を使用すると、Compose がライフサイクルを面倒みるためlifecycleを対応するのは不要です。 SceneCore の Entity は XR側で自動破棄されないため、Composableの終了やセッション切替時に DisposableEffect(session) 内で明示的に解放しないといけないです(メモリリーク防止のため)。 3Dオブジェクトの追加方法 Scene を使うと、中に Node を作成できます。 childNodes = rememberNodes { add(modelNode) } のように Node を追加すると、表示されます。 GltfModelEntity.create(session, model) を呼ぶと、3Dモデル用の Entity が作成され、 .add() しなくても表示されます。 3Dスペースモードを切り替える 不要 Android XRのEntityを使う時、 session.scene.requestFullSpaceMode() のように、Full Spaceモードに切り替えないといけないです。 ExoPlayerの動画を表示する 出典:Pexels,  https://www.pexels.com/ja-jp/video/13299023/  (2025/11/12アクセス) SceneView SceneViewで以前の記事「 AndroidでSceneViewを使って、3D/ARを表示する 」で書いた通りで、Materialを作成しないといけないです。 class ExoPlayerVideoMaterial( engine: Engine, exoPlayer: ExoPlayer, private val materialLoader: MaterialLoader, ) { // SurfaceTexture作成 private val surfaceTexture = SurfaceTexture( 0 ).apply { detachFromGLContext() } // SurfaceTexture→Surface作成 private val surface = Surface(surfaceTexture) // Textureのために、FilamentのStream作成 private val stream = Stream.Builder() .stream(surfaceTexture) .build(engine) // Texture作成 private val texture = VideoTexture.Builder() .stream(stream) .build(engine) // VideoTextureを使ったMaterialInstance作成 val videoInstance get () = materialLoader.createVideoInstance(videoTexture = texture).apply { setExternalTexture(texture) } init { // ExoPlayerのSurface設定 exoPlayer.setVideoSurface(surface) } } SceneviewexampleTheme { // ExoPlayerの設定 val player = remember { ExoPlayer.Builder(context).build().apply { repeatMode = Player.REPEAT_MODE_ALL } } // さっきの作成したExoPlayerVideoMaterial val videoMaterial = ExoPlayerVideoMaterial(engine, player, materialLoader) val videoNode = PlaneNode( engine = engine, // 動画は16:9のため size = Size( 16f , 9f ), // NodeのMaterialInstance設定 materialInstance = videoMaterial.videoInstance, ) ARScene( //... childNodes = rememberNodes { // ノードの追加 add(videoNode) }, ) } 結果) SceneCore ExoPlayerの .setVideoSurface() を使うと Surface に再生できます。SceneCoreには SurfaceEntity があり、 Surface を提供するため、ExoPlayerを接続してXRで再生できます。 Subspace { val session = LocalSession.current ?: return @Subspace val capabilities = LocalSpatialCapabilities.current val context = LocalContext.current // 作成した SurfaceEntity を保持 var surface by remember(session) { mutableStateOf<SurfaceEntity?>( null ) } // ExoPlayer はコンポーザブルのライフサイクルに合わせて1つだけ val player = remember { ExoPlayer.Builder(context).build().apply { repeatMode = Player.REPEAT_MODE_ALL } } // Lifecycleのため DisposableEffect(session) { onDispose { player.clearVideoSurface() player.release() surface?.setEnabled( false ) surface?.parent = null surface = null } } LaunchedEffect(session, capabilities.isContent3dEnabled) { // Full Spaceモードの切り替え if ( ! capabilities.isContent3dEnabled) { session.scene.requestFullSpaceMode() return @LaunchedEffect } if (surface == null ) { // SurfaceEntity val surfaceEntity = SurfaceEntity.create( session = session, pose = Pose( // Positionを設定する Vector3( 0f , 0f , - 1.5f ), ), // 動画は16:9のため shape = SurfaceEntity.Shape.Quad(FloatSize2d( 16f , 9f )), ) // Scaleを設定する surfaceEntity.setScale( 0.25f ) // 最初の黒塗りを避けるため、1フレーム目まで非表示 surfaceEntity.setEnabled( false ) // ExoPlayerをSurfaceEntityに接続して再生(res/raw/video.mp4) val uri = RawResourceDataSource.buildRawResourceUri(R.raw.video) player.setVideoSurface(surfaceEntity.getSurface()) player.setMediaItem(MediaItem.fromUri(uri)) player.prepare() player.addListener( object : Player.Listener { override fun onRenderedFirstFrame() { screen.setEnabled( true ) } }) player.play() surface = surfaceEntity } } } 結果)Android XRで動画を表示できました!🎉 動画を表示するために、 SceneView と SceneCore の主な違いは以下となります。 SceneView SceneCore ExoPlayerの表示方法 VideoNode がコメントアウトされているので、動画再生用の Material を作成必要があります。 SurfaceEntity を使うと、簡単に動画再生できます。 まとめ SceneViewはメンテナンスされていないので、SceneCoreは有力な代替です。書き方はおおむね似ており、Googleが作っているライブラリです。ただし前述のとおり、Android XRに対応したデバイスでのみ動作します。一般的なスマートフォンでは実行できませんが、ぜひEmulatorで試して遊んでみてください! モバイルチームは開発する仲間を募集しています! open.talentio.com open.talentio.com
アバター
この記事は  Safie Engineers' Blog! Advent Calendar  の5日目の記事です。 はじめまして、クオリティマネジメントオフィス QCDグループの稲員です。 この記事を書こうと思った理由ですが、 2025年1月にセーフィーのQAチームにジョインしてしばらく経ちましたので、おじさんのQAエンジニアがセーフィーのQAチームでどんなことに取り組んできたか振り返ろうと思いました。 チームのテスト活動を改善するためにどのような施策を実行してきたのかを共有することで、QAエンジニアの方々や開発チームの方々にとって何かしらのヒントになれば幸いです。 MagicPodでのテスト自動化 QAフローの改善 スクラムの改善 MagicPodでのテスト自動化 QAを担当することになったシステムはちょうどテスト自動化をやろうというフェーズだったため、そのキャッチアップから行いました。 採用しているツールが「MagicPod」というもので、下記のような特徴があります。 AIによるスクリプト作成支援&自動修復 インストール不要な手軽さと、クラウドの端末やブラウザを使ってすぐにテスト作成可能 Webアプリ・モバイルアプリに対応 MagicPodは手軽さと直感的な操作ができるということで、こちらは低い学習コストで実装できるようになりました。MagicPodに詳しいメンバがオンボーディングをしてくれたのも大きかったです。 共有ステップや変数の活用、上手なデータ分割などテクニカルに使いこなそうとするとまた技術は必要になってきます。 一通りテストの自動化が完了できて、日々の運用にのせるというところが実現できたのはチームメンバの作業時間を日々固定で押さえたのが良かったと思います(強制労働) 日々固定の時間を確保して良かったポイントは以下です。 実装で困っているところを質問して解消しやすい 実装を進めるモチベーションになる 全件成功した朝は気持ちが良いです。鳥も猫もうれしそうです。 この「自動化の時間」があるおかげか、テスト自動化実装が終わった後に大きめの改修があってもテスト自動化は腐ることなく、運用を継続できています。 QAフローの改善 他に取り組んだのがQAフローの改善です。 部の目標であったテストにまつわる”工数削減”、”品質向上”、および現場の”不”の解消という軸で改善に取り組みました。 施策の一部 工数削減の方では自分でもっとこうしたいなと感じたことや、振り返りミーティングでメンバーから話題に上がったものを改善事項としてピックアップしました。 上記の改善が落ち着いてからはNotebookLMを使ってナレッジをまとめよう、非機能要件のテスト観点をシステマティックに盛り込もう、AIに不具合分析させよう、AIにテストケースレビューさせよう、などに取り組んでいます。 テスト設計で変えたところですと、改修内容によってはテストケースの粒度を大きくしてテストケース作成の工数を減らすようにしました。 テスト実施の方ではお客様はFirefoxをほとんど使用されていないという事がデータから分かったため、リグレッションテストは自動テストに任せて、手動でのテストを大きく減らしました。 テストの時間はいくらでもかけられますが、必要十分なテストを少ない時間でやるということを意識しています。 スクラムの改善 最後にスクラムの改善ということで朝のデイリースタンドアップの中に「チェックアウト」のコーナーを作るようにしました。 チェックアウトは”何を話しても良いよ”というコーナーで当番制です。 QA関係のお話をすることもあれば、好きな漫画や映画、最近話題の○○、おしゃれになりたいんやけどみんなどこで服買ってる、アタック25形式のクイズ勝負やろうや、猫の肛門から分泌される”肛門液(?)”がなんか足に付いててすごい臭いんですが、などなど朝から笑いが起きたりしていて楽しみな時間になっています。 これはチームの心理的安全性を高めるのに一役買っていると思います。 これらの取り組みを通じて、チーム全体が改善活動に対する意識を高め、より良いQAプロセスを追求する文化が醸成されつつあります。現状に満足せずに今後も継続的に改善を重ねていく予定です。 この数か月は、単にテストをするだけでなく、新しいチームとして成長するための基盤を築く期間でした。今後もより良いプロダクト品質とテスト品質を追求し、開発チームと共にお客様のカメラ管理を楽にする素晴らしいプロダクトを世の中に届けていきたいと思います。
アバター
この記事は  Safie Engineers' Blog! Advent Calendar  の4日目の記事です。 こんにちは。カルチャー&コミュニケーション室の おかだみかこ です。 カルチャー&コミュニケーション室は、社長直轄組織として社内外の広報活動等を担当しているチームです。「映像から未来をつくる」というセーフィーのビジョン実現に向けて「セーフィーカルチャー」を推進する活動も内包しています。 私は2025年4月、ちょうど当社の社員数が500名を超えたタイミングでセーフィーに転職しました。セーフィーが上場した2021年から比べると社員数は2倍以上。ビジネスも組織も圧倒的なスピードで成長している会社に入社したなあと思ったのを覚えています。 一般的に、組織が拡大すると「隣のチームが何をしているか分からない(サイロ化)」や「経営の意図が伝わらない」といった課題が生まれがちです。 多くの企業では社内報といえばテキストが多いと思いますが、私たちは「映像データ」を扱うテック企業として、テキストでは削ぎ落とされてしまう「熱量」や「文脈」こそが重要だと考え、「動画」による社内コミュニケーションを行ってきました。ということで、今回は私が担当している社内動画メディア「空フク」についてご紹介します。 「空フク」とは 現状把握のためのアクション 現在までに実施したこと 信頼関係をレバレッジする「公式発信」よりも「知っている人」 「動画の弱点」を補完する+αの要約テキスト コミュニケーションは続けること 「空フク」とは 端的にいうと、「空フク=動画社内報」と考えていただくとイメージがしやすいかと思います。スタートしたのは2023年10月で、今まで2年以上に渡り継続して社内向けの発信を続けてきました。 「空フク」は通称で、正式名称は「空飛ぶフクロウ~Safie's company newsletter~」です。セーフィーのシンボルマークでもお馴染みの「フクロウ」は知恵の象徴とされています。「空フク」の名前には、社員一人ひとりが持つ知恵をシェアし、お互いの知恵の循環を通じて、社内コミュニケーションを活発にしていきたいという想いが込められています。 空フクは2つのカテゴリで構成されています。 Sadoxサロン 社長の佐渡島さんがスピーカーとして語るコンテンツ フクロウたちの知恵泉 社員の活躍、部署の取り組みを語るコンテンツ 左:Sadoxサロン「2030年目指すこと_ストレッチ組織の課題と解決にむけて」 右:フクロウたちの知恵泉「デザインセンター_ロゴデザインの思想と、セーフィーがつくるデザインとは」 現状把握のためのアクション 私が担当になってまず行ったのはアンケートです。社員の「空フク」活用状況を知り、今後の企画において参考とするために行うことにしました。 結果として、90%以上の人が認識しており、社員の2/3は何らかのコンテンツは見たことがあるというポジティブな回答が得られました。一方で「見たことがない!」という社員も少なからずいる状況がわかりました。見る機会がなかった人は大きく分けると以下の3つに分類されることも把握できました。 忙しく見る時間がない 更新タイミング不明 そもそも存在を知らなかった 届ける相手である「社員」の皆様の声を確認したことで、実際に活動の方向性を決めることにも繋がったため、初手でアンケートをとったことは非常に有用でした。 現在までに実施したこと アンケートを実施した5月から現在まで、まずは短期目線ですぐにできることからアクションを行ってきました。大きく分けると「告知の工夫」と「さまざまな社員が登場する企画」です。このブログでは「告知の工夫」にフォーカスしてもう少し詳しくお話ししたいと思います。 信頼関係をレバレッジする「公式発信」よりも「知っている人」 突然の話ですが、友人から手紙を渡されたとしたら、そりゃ必ず目を通しますよね。それと同じで同じチームや関係性の深いメンバーからのSlackは目につくと思うのですが、あんまりよく知らない人からの全体に向けたSlackは見落としがちではないでしょうか。 「空フク」の告知は社内のSlackを活用して発信していますが、全体メンションでの私からの告知は、情報の「ノイズ」として処理されてしまう可能性があると感じていました。 そこで着目したのが、社内における「ソーシャルグラフ(人間関係のつながり)」の活用です。担当者から言われるより、普段関わりのある同僚から「出演したので見てください」と言われた方が、圧倒的に視聴意欲が湧くはず。 アナログな手法ですが、「出演者に告知協力をお願いする」というフローを組み込むことで、「点」の発信を「面」の広がりに変える工夫を取り入れました。 最近も、出演者からではないのですが、社員の方が面白いよとご自身のチームに発信していただいたことでアクセスが急増したケースがありました。そういう循環をもっと増やしたい。そのための前提としては社員の皆様が「これいい!」と思ってもらうコンテンツが重要です。企画自体も力を入れていますが、引き続き良いコンテンツ作りには特に時間を割いていきたいと感じました。 「動画の弱点」を補完する+αの要約テキスト 映像は圧倒的に得られる情報量が多いのがメリットです。一方で、「忙しい時に手を止めて動画を見るのは正直しんどい。倍速だとしても」というのは正直あるのではと思います。 そのため、空フクNotionページで公開する際に、興味があるトピックかどうかを数秒で判断できるように「動画で話されていること」を箇条書きで添えるようにする工夫もはじめました。 また、要約の作成にはNotebookLMに編集した映像を読み込ませて、そこからテキスト案を検討することで効率化も進めています。 コミュニケーションは続けること 担当を引き継ぐ際に前任担当者のコメントで最も印象に残ったことは「継続して発信し続けることを大事にしてきた」という話です。首がもげそうになるくらい同意をしました。それは、私もコンテンツの発信は継続して続けていくことが大事だと思っていたからです。 現在、セーフィーは開発本部を含めた5つの本部、500人以上の社員がいる会社に成長し、ビジネスも組織も更なる飛躍に向けてみんなで歩みを加速させています。 最後になりましたが、社内の戦略や開発秘話なども含まれるため、「空フク」を見ることができるのは社員だけの特権です。セーフィーのお仕事にご興味がある方は 採用サイト もぜひご覧ください。 safie.co.jp この記事を読んでいただいた方が、仲間となり動画を見たり、はたまた出演者として登場したりとする日が来るのを楽しみにしています。 今後もより「面白い」「役立つ」「楽しい」空フクの発信を期待していただけると嬉しいです!
アバター
はじめに この記事は Safie Engineers' Blog! Advent Calendar の3日目の記事です。 こんにちは、技術広報のたかぎ( @hitsan )です。 2024年の中盤から技術広報をはじめ、2025年はセーフィーにとって 「技術広報活動を本格始動させた年」 という、非常に大きな節目の1年となりました。 これまでも技術発信は行ってきましたが、今年は発信数を増やすことに注力しました。 本記事では、セーフィーの技術広報が掲げるミッションと、2025年に取り組んだ具体的な施策について振り返ります。 はじめに セーフィーにおける技術広報のミッション ファンを増やし、すごいを広げる 2025年の活動 1. イベント登壇数を増やしたよ 2. 技術広報専用Xアカウントをつくったよ 直近のイベント情報 BASEとセーフィーが語るバックエンド開発の技術的負債解消への道のり 生成AIで業務を改善しNight! さいごに セーフィーにおける技術広報のミッション ファンを増やし、すごいを広げる 技術広報として掲げている最大のミッション、それは 社内外にセーフィーのファンを増やすこと です。 この言葉には2つの意味が込められています。 「セーフィーって技術的に面白い会社だね」と認知してもらうこと。 エンジニア自身が自分たちの開発しているプロダクトはすごいと胸を張れる状態を作ること。 どれほどがプロダクトが良くても伝わらなければファンは増えません。このミッションを達成するために、以下のような3年計画を策定しました。 年度 フェーズ 2025年 発信文化の醸成 2026年 聞き手を意識した発信 2027年 テックブランドの確立 2025年の活動 2025年のテーマは「土壌づくりと発信文化の醸成」です。 文化を作るためには、まず行動の総量を増やす必要があります。そこで打席数を増やしました。 発信数(打席)が増えれば、「自分たちは技術発信をする組織だ」という認識が生まれる 第三者の目に触れることで、「自分たちが当たり前にやっていることは、実はすごいことなんだ」と気づける これらを実現するために、具体的に実行した施策をご紹介します。 1. イベント登壇数を増やしたよ 今年はイベントへの参加・開催数は昨年と比較して2倍になりました。 2024年までは依頼があれば登壇するというスタンスでした。2025年からは他社と共催してイベントを企画するようになりました。 企画から行うことで、ターゲット層や伝えたい技術テーマをコントロールできるようになり、以下のようなトピックを深く掘り下げることができました。 映像解析アプリケーションの開発プラットフォーム構築の紹介 若手エンジニアの活躍 大規模プロダクトにおける技術的負債の解消 企画から携わることで、参加者からのフィードバックをエンジニアへ直接還元するサイクルも作れています。 2. 技術広報専用Xアカウントをつくったよ 先月、セーフィー技術広報アカウント( @SafieDev )を新たに開設しました。 はじめまして!このアカウントは、セーフィーの技術情報やエンジニアの取り組みを発信するアカウントです🎉 エンジニアの皆さんが気になる情報をお届けします。 ぜひお気軽にフォローしてください! #セーフィー #エンジニア #開発者 #技術広報 — セーフィー技術広報 (@SafieDev) 2025年11月7日 これまでは企業公式アカウントから発信していましたが、以下の理由から独立させました。 エンジニア、PdM、デザイナーに特化した情報を届けたい エンジニアの日常的な取り組みや試行錯誤も発信したい 企業の公式アカウントよりも高頻度で投稿したい アカウントを分けたことで、テックブログの更新情報やイベント情報に加え、開発現場の空気感が伝わるような発信を強化しています。ぜひフォローをお願いします! 直近のイベント情報 12月は注目のイベントを2件開催します。ぜひご参加ください。 BASEとセーフィーが語るバックエンド開発の技術的負債解消への道のり 明日、12/4(木)にBASE株式会社様と共催でバックエンドの技術的負債にフォーカスしたイベントを開催します。セーフィーからは、大規模リアーキテクチャの取り組みについて紹介予定です。 safie.connpass.com 生成AIで業務を改善しNight! 12/15(月)には、生成AIを活用した業務改善イベントを開催します。 こちらはLTやセッションではなく、ワールドカフェ形式を採用。参加者全員で業務改善のアイデアをディスカッションする参加型イベントです。 safie.connpass.com さいごに 2025年の活動を振り返りましたが、正直に言えば、全員が自然と発信する文化にはまだ到達できていません。 今年はイベントという場を用意し、打席数を増やすことには成功しました。しかし、それが組織全体の習慣として定着し自走していくまでには、まだいくつものハードルがあります。 まだまだ手探りですが、これからも走り続けるので2026年のセーフィーの技術発信にも、ぜひご期待ください。
アバター
この記事は Safie Engineers' Blog! Advent Calendar 2日目の記事です。 はじめに 私にできること 新たに作ったもの アプリの紹介 作ったきっかけ 作り方 AWS Bedrockでお題を生成 Next.jsでUI実装 AWS Amplifyでデプロイ 終わりに はじめに こんにちは!セーフィーに25新卒で入社し、AI開発部に配属された川上です。 学生時代は研究で、人の歩き方を解析するAIの開発をしていました。 そして配属前に行われた研修では、社内備品を管理するアプリTreasure Collectionを開発しました。(Treasure Collectionの記事は後日掲載されるのでぜひご一読ください。) この記事では私が新たな技術領域を身に付けるためにアプリの開発に挑戦した話をしたいと思います。 私にできること 先に述べたように、学生時代はPythonをつかって映像の研究をしていました。そして研修のTreasure Collectionの開発では、入社するまでに体験したことがなかったフロントエンド領域を担当しました。研修を終えて、フロントエンドとバックエンド(データ処理)の領域を経験したエンジニアになれました。 しかしながら、インフラ領域が分からないという気づきも得ました。 Treasure CollectionはWebアプリで、デプロイなどのインフラ回りはすべてチームメンバーが実装してくれました。フロントエンドの技術は身につけられましたが、アプリをユーザーに届ける方法が分からないという状況になりました。 新たに作ったもの これから、研修を終えた後に開発した ice-breaker というWebアプリの紹介をします。このアプリを作ったことで新たな技術領域を体験でき、ユーザーに作ったものを届けられるようになったのでそこを共有できればと思います。 アプリの紹介 ice-breakerはミーティングなどの冒頭で行うアイスブレイク・チェックインのお題を提供します。 アイスブレイクとチェックインは少し異なるものですが、大まかに以下のように説明できます。 アイスブレイク、チェックインとは 目的:集まりの冒頭で、参加者の間の緊張をほぐし、場に活気や一体感を生み出すこと。 特徴:「場」の雰囲気づくりに焦点を当てる。 多くの場合、ゲームや簡単なアクティビティ形式で行われる。 参加者同士が気軽に話せるきっかけを提供し、本題に入る前の心理的な障壁を取り除く。 このアイスブレイク、チェックインはセーフィーに入社してから何度も行ってきました。そしてこの度、アイスブレイク、チェックインに役立つアプリを開発しました。 アプリにアクセスすると次のような画面が表示されます。 画面左側の“話題を生成”ボタンを押すとボタンの下にお題が表示されます。 参加者一覧に名前を入力し”追加”ボタンを押すと参加者が追加されていきます。 “次の発表者”ボタンを押すとボタンの左に次の発表者が表示され、発表済みに発表者が追加されます。 “次の発表者”ボタンを何度か押して、全員が発表済みに追加されると”終了!全員話し終わりました”と表示されます。 作ったきっかけ 配属前に行っていた研修の週次定例の冒頭に、10分程度のアイスブレイクを行っていました。 アイスブレイクのお題はその都度考えていたために、お題に困ることがありました。 また進め方はお題を考えた人が最初に発表して、発表した人が次の発表者を指名するという方式をとっていました。この進め方はアイスブレイクが盛り上がるいい方法でした。しかし、「全員発表した?」と確認したり「次誰にしよう」と悩んだりして、時間を使ってしまうためにアイスブレイクの予定時間を少し超えてしまうという問題もありました。 行っていたアイスブレイクのよさを保ちながら、困りごとを解決するためのアプリを作ってみようと思ったことがこのアプリを作ったきっかけです。 作り方 ここからはアプリの作り方を説明します。 AWS Bedrockでお題を生成 まず、アプリの核となるお題の生成についてです。 お題の生成は生成AIで行っています。生成AIはAWS Bedrockから利用しました。AWS Bedrockにアクセスし、APIキーを発行します。 Next.jsでUI実装 UIはNext.jsで実装しました。Next.jsを使った理由は研修で唯一身につけたフロントエンドの技術スタックだからです。 アプリの構成は以下のようになっています。 src/app/ ├── page.tsx # メインUI(クライアントコンポーネント) ├── api/ │ └── bedrock/ │ └── route.ts # Bedrock API呼び出し(サーバーサイド) └── components/ ├── addNames.tsx # 参加者追加コンポーネント └── participants.tsx # 参加者表示コンポーネント UIはシンプルなのですべての紹介は控えますが、工夫したことを2つ紹介します。 同じ話題が表示されないようにプロンプトを改善 api/bedrock/route.ts ではAWS BedrockのAPIにプロンプトを含んだ、API Requestを送信しています。そのコードは以下のようになっています。 import { BedrockRuntimeClient, ConverseCommand } from "@aws-sdk/client-bedrock-runtime"; import { NextRequest, NextResponse } from "next/server"; export async function POST(request: NextRequest) { try { const url = "xxx"; const history = (await request.json()).history || []; const payload = { "messages": [ { "role": "user", "content": [{"text": "ちょっと変わったアイスブレイクの話題を1つ返して。" + "過去の話題履歴: " + history.join(", ") }] } ], "inferenceConfig": { "temperature": 1.0, "maxTokens": 500, "topP": 1.0, } }; const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "Authorization": `Bearer ${process.env.NEXT_PUBLIC_API_KEY}` }, body: JSON.stringify(payload) }); const data = await response.json(); return NextResponse.json({ output: data }); } catch (error) { console.error("API Error:", error); } } 過去の話題履歴を page.tsx と連携してプロンプトに含めながら話題を何度か生成したときに同じ話題が表示されないようにしました。 Next.jsのサーバーサイドからAPI Rrequestを送信 以下のコードは page.tsx に実装した、話題を生成するときに実行される関数です。この関数ではまず api/bedrock にAPI Requestを送信します。これはNext.jsのサーバーサイドで実装されているAPIです。 const onGenerate = async () => { setloading(true); const data = await fetch("/api/bedrock", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ history: history, }), }) .then((res) => res.json()) .then((data) => { setResult(data.output.output.message.content[0].text); setHistory([...history, data.output.output.message.content[0].text]); }) .catch((error) => { console.error("Error fetching data:", error); }); setloading(false); }; 先に説明したようにAWS BedrockへのAPI Requestの送信は api/bedrock から行われます。 このようにAPIを経由してAWS Bedrockを利用していることには理由があります。それはAWS Bedrock への API Requestの送信はフロントエンドから行えないからです。セキュリティ上の理由でその仕様になっています。 今回開発に用いたNext.jsでは別途バックエンドサーバーを立てずにサーバーサイドにAPIエンドポイントを立てることができます。図らずも、開発中に生じた課題が解決され、スムーズな開発を進めることができました。 AWS Amplifyでデプロイ ローカル環境で動作確認を完了したら、デプロイの準備です。 デプロイはAWS Amplifyで行いました。AWS Amplifyを使って想像以上に手軽にデプロイを行えました。 AWS AmplifyへはGithub経由でアプリをデプロイできます。 作成したアプリをGithubへpushしたら以下のAWSのマニュアルに従って設定を行います。 https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/setting-up-GitHub-access.html#setting-up-github-app 設定後にAWS Amplifyにアクセスし、以下の流れでAWS Amplify上にアプリを作成します。プロバイダーはGithubを選択しました。 ここまで進めて、問題がなければすべてのアプリから、デプロイが始まっていることが確認できます。5分程度待つと、デプロイ済みに変わっていました。 この時点でもアプリはデプロイされアクセスすることができますが、もう一つ必要な設定があります。 環境変数の設定です。 すべてのアプリから、デプロイしたアプリをクリックします。サイドメニューのホスティング、環境変数を選択して、以下の画面に遷移します。 ここで変数はローカル環境で使う.envファイルで決めた変数名です。値は取得済みのAWS BedrockのAPIキーを入力します。 ここまで行うとアプリはローカルと同じように動作します。デプロイ・リリースの完了です。 終わりに この記事では私が初めて自身の力でデプロイを行ったアプリの紹介をしました。 アプリを作ってみて考えたことが大きく2つあります。 1つ目はソフトウェアサービスの理解度が上がったことです。これまではどうやったらサービスとして動作するんだろうという漠然とした疑問を抱えながら開発などを行っていました。そこをどうやったらいいか、手段を1つでも知れたことはとても良いことだと思います。 2つ目は別のAWSサービスも利用したいと思ったことです。私はAI開発に長い間携わってきましたが、それらはローカル環境のマシンで動作させるだけでした。これを機にオリジナリティを持ったAIを使ったアプリをユーザーに届けてみたいと思いました。 私がセーフィーに入社して8カ月経ちましたが、その間新しい技術領域を体験し身に着けながら課題解決に取り組めています。この記事を読んでいただいた人にとって、セーフィーで働きながらどのように技術を身に着け成長できるかが伝わると幸いです。
アバター
この記事は Safie Engineers' Blog! Advent Calendar  1日目の記事です。 はじめに そもそも「1on1」とは? 定義の再確認 1on1 のゴール(ありたい姿) 人にフォーカスした対話型1on1のすすめ 具体的な質問例1:「最近どう?」をより良くする工夫 具体的な質問例2:未来志向への誘導 1on1 は組織開発の最前線 最後に はじめに セーフィーの VPoE 兼 開発本部 エンジニアリングオフィス 室長の武田です。 2023年にセーフィーに入社し、エンジニア組織の組織開発に取り組むエンジニアリングマネージャーとして活動しています。セーフィーでは創業当初から 1on1 文化 が根付いており、私自身2025年には600件以上の1on1を実施しました。前職を含めたエンジニア組織開発の経験と、コーチングや本質行動学などの学びを活かしたトライ&エラーから得た、1on1の本質をご紹介します。 そもそも 「1on1」とは? 定義の再確認 私が考える1on1の定義は以下の通りです。 💡 1on1とは? 1on1とは、メンターとメンティーが定期的にマンツーマンで行うミーティングのこと。 人事評価を目的とした面談とは異なり、 人の成長促進と組織の活性化 を主な目的とする。上司・部下の関係性に限らず、人と組織の成長を促すための対話の場である。 この1on1の定義には 「これが正解」という型はありません。 1on1では「業務の話はすべきではない」という一般的な風潮もありますが、私はその限りではないと考えます。 なぜなら、メンティーが目の前の業務で困っているのに、それを解決してくれるかもしれない人に聞けないのはフラストレーションがたまるだけ。無理にキャリアの話に誘導するより、 メンティーが本当に求めている話 をすることが、結果的に成長につながります。 1on1 のゴール(ありたい姿) では、目指すべき1on1のゴール(ありたい姿)は何でしょうか。 それは 「次も1on1をしたい」 と思ってもらえる状況を作ることです。 1on1は、一度きりのイベントではなく 継続してこそ意味のあるもの になります。 前向きさを維持し、対話を重ねることで初めて、人の成長と組織の活性化という目的に近づけます。 メンターのスタンス メンティーの状況に合わせて臨機応変に対応する 具体的な行動 業務の話も、キャリアの話もする。コーチングもすれば、ティーチングもする 重視すること その瞬間や1on1直後に心地よい時間を作ることではない、時にはネガティブなフィードバックも必要 目指す状況  対話後、時間経過と共に気づきがあり、行動変容を促し、結果が伴うこと。そして、対話が継続できていること。 人にフォーカスした対話型1on1のすすめ 「次もやりたい」と思ってもらうためのコツ、それは 「対話しやすい状況」 を作ることです。 対話しやすさの鍵は、「事(コト)」ではなく 「人(ヒト)」にフォーカス した質問をすることにあります。 ✅ 「事」への質問 vs. 「人」への質問 例えば、メンティーが「釣りに行ってきました」と話した場合の質問例です。 質問の焦点 具体的な質問例 メンティーの受取られ方 事 (コト)  - どこ行きましたか? - 釣れましたか?     事実の深堀り 人 (ヒト)  - 楽しめましたか? - 釣り好きなんですか? 自分に向き合ってくれている と感じ、話しやすくなる 人の 感情(楽しい、好きなど)に寄り添う 質問を意識するとより話がしやすくなります。 例えば仕事で失敗したときはなぜ失敗をしたのか?ではなく、その時どう思った?どう感じたか?なぜそう感じたのか?メンターの自分はどう思ったか(例えば悲しかったとか)など、お互いの感情を深堀しシェアすることでより人に向き合えるようになります。 具体的な質問例1:「最近どう?」をより良くする工夫 1on1 の初めに「最近どう?」から始まることはよくあると思います。 ただ、この「最近どう?」だけでは、少しもったいないです。 最初の導入として、ぜひ メンターの所感 を付け加えてほしいです。 そうするとメンティーはより話しやすくなります。これは、 メンターの気持ち(感情)を先に伝えている ことで、共感を生みやすくスムーズな対話につながる効果があります。 より良い質問例 ポイント 最近どう? 〇〇定例での××の発表良かった。内容もだけど イキイキ話していて感動したよ ポジティブな所感 を伝え、話すきっかけを作る 最近どう? 残業時間が多くなっているようなので ちょっと心配 懸念点(心配) を伝え、安全な場で話すことを促す ❌ 注意すべき質問例 「最近どう?元気がないように思うけど大丈夫? 何かあった? 」は良い質問ではありません。 なぜなら「何かあった?」は、 事の深堀り につながるからです。本当に元気がないときは、日常の小さなことの積み重ねであることが多く、「特別なことはありません」という回答で対話が終わってしまう可能性があります。   〇 最近どう?元気がないように思うけど大丈夫? 心配です。 心配している気持ちを正直に伝えて反応を待ちましょう。 補足 ちなみに私は1on1が始まる前にその人のGoodポイントを探すという事前準備をよくやります。ネガティブな情報は広がりやすいですが、ポジティブな情報はなかなか表に出てきません。1on1でポジティブ情報が交換できれば組織全体の雰囲気にもつながります。ぜひ、EMはポジティブ情報を常に拾って1on1につなげてほしいと思います。 具体的な質問例2:未来志向への誘導 1on1は過去の振り返り(ふりかえり)になりがちで、ワクワクしにくい傾向があります。過去の結果は分かりきっているからです。 できるだけ 未来の話 に誘導しましょう。 質問例 目的 前回から今回までの 自己満足度、何点 ありますか?(100点満点で) メンティーの現状認識を引き出す (例:60点と回答)40点足りていないけど、その 40点を増やすためには何が必要ですか? 私も一緒に協力できることありますか? 次回までの Next Action をメンティー主体で決め、 未来の話 へ誘導する ここでのポイントは、メンティー側だけでなく、 メンター側のNext Actionも決めること (小さなことでOK)。お互いのコミットメントにより、一体感が生まれます。 1on1 は組織開発の最前線 会社や組織は人の集まりであり、 組織=人 です。 1on1は、その人のことを知るための 一番の手段 であり、組織開発の最前線です。1on1が機能することで情報が流通し、組織が活性化するきっかけになります。 ぜひEM(エンジニアリングマネージャー)の皆さんには、この1on1を使いこなしてほしいと思います。 正解がないからこそ面白い! この記事が、あなたの1on1を楽しむきっかけになれば幸いです。 📝 まとめ:人に向き合う1on1の5つの要点 1. 基本スタンス  1on1のやり方に正解はない (メンティーの状況に臨機応変に対応する) 2. 目的   人(と組織)が成長するために、人(と組織)に向き合う時間。 3. ゴール  「次も1on1をしたい」 と思ってもらうこと(継続による成長と成果) 4. コツ    「事」ではなく 「人」にフォーカス した質問で、より 共感と気づき を与える 5. 価値    組織開発の最前線として、 情報流通と組織活性化 のきっかけとなる 6. 願い   1on1 自体を楽しもう! 最後に 本記事では、私が取り組んでいる1on1の実践の一部をご紹介しました。 1on1 は奥深く自分自身もまだまだ足りていない部分があり、常にふりかえりを実施中です。 また、ポイントはほかにもある(例えば、1on1 の情報をどう他の人にシェアして組織変革に使っていくか)と考えており日々奮闘中です。またいつか別の機会にご紹介できればと思います。 最後に宣伝です!セーフィーでは 一緒に働く仲間を募集中 です! 少しでもご興味を持っていただけたら、ぜひ以下の 採用サイト を覗いてみてください。
アバター
はじめに こんにちは。セーフィーでサーバーサイドエンジニアをしている金成です。 本記事は、ffmpegを初めて使う方や、360度カメラのデワープ処理について学びたい方を対象にしています。専門的な知識は不要ですので、ぜひお気軽にお読みください。 セーフィーでは、半天球カメラなど、魚眼レンズを用いて広範囲を撮影する360度カメラの映像も取り扱っています。そのため、このようなカメラの画像や映像をデワープ (歪みを補正し、歪みの少ない映像に変換すること) するユースケースが存在します。仕事をする過程で、ffmpegのビデオフィルターを使った変換について調べたのでこちらで共有いたします。 はじめに ffmpegとvfオプションについて デワープの具体的な手順 まとめ ffmpegとvfオプションについて ffmpegは、動画や音声を記録・変換・再生するソフトウェアで様々な処理を行うことができます。その中でも、vfオプション(video filter オプション) は、入力に対し、映像を拡大する、一部分を切り取る、色を補正するなどの処理(フィルター) を適用することができる機能です。 簡略化すると、下記のようなシンタックスでオプションを指定することができます。 -vf <フィルタ名>=<フィルターごとのオプション> (実際にはもっと複雑な指定が可能です。詳細は公式サイトをご参照ください。 https://ffmpeg.org/ffmpeg-filters.html) 例えば、cropフィルターであれば、下記のようなコマンドで画面の一部を切り取った映像を作ることができます。 ffmpeg -i input.mp4 -vf crop=500:500:100:100 output.mp4 vfオプションの中には、v360フィルターがあり、360度カメラで撮影された魚眼などの映像をデワープされた映像に変換することができます。 デワープの具体的な手順 360度カメラの映像と環境の準備 今回は、ffmpegコマンドを使った360度カメラの変換について説明します。 利用するツールのバージョンは下記になります。 ffmpegのバージョンは7.1.1です。 デワープのためのffmpegコマンドの記述 デワープのためのffmpegコマンドの記述 今回は、v360フィルターを使って、半天球カメラなどで撮影された「魚眼 (fisheye)」形式の映像を歪みを補正した映像に変換します。 v360フィルターは下記のようなシンタックスで構成されており ‘v360=<入力の形式>:<出力の形式>:<key=valueで指定したオプション> といった形式で指定できます。 例えば、下記のコマンドであれば指定したオプションで、魚眼 (fisheye) の映像からデワープされた通常の映像に変換されます。 ffmpeg -i input.mp4 -vf ‘v360=fisheye:flat:v_fov=50:yaw=50’ output.mp4 v360フィルターでは、下記のような入力/出力先が用意されています。 e / equirect => Equirectangular projection flat / gnomonic / rectilinear => regular video fisheye => 魚眼 pannini => Pannini projection. and etc 入力/出力形式ごとに必要なパラメーターが変わり、様々な変換を行うことができます。 v360のフィルターでは、共通でyaw/pitch/roll などのカメラの視点をコントロールするオプションや、カメラの回転を制御するオプションがあります。 今回使用する flatフィルターでは、特にデワープ後の調整を行うため、出力するカメラの画角を以下のオプションで制御できます。 v_fov (垂直画角) h_fov (水平画角) d_fov (対角画角) これらのオプションを利用することで、変換後の映像を細かく調整することが可能です。 コマンドの実行例 例1: 上下の振り向け ffmpeg -i input.mp4 -vf v360=fisheye:flat:v_fov=50:pitch=<角度> output.mp4 例2: 左右の振り向け ffmpeg -i input.mp4 -vf v360=fisheye:flat:v_fov=50:yaw=<角度> out.mp4 例3: 右に振り向けた映像の左半分だけを切り取る ffmpeg -i input.mp4 -vf v360=fisheye:flat:v_fov=50:yaw=30,crop=iw/2:ih:0:0 output.mp4 まとめ このように魚眼の映像など360度カメラで撮影した映像は、簡単にデワープすることができます。画像や動画の変換に役立てていただければ幸いです。 セーフィーでは、このような映像解析技術を活用し、より高度なサービスを提供しています。興味をお持ちいただけましたら、ぜひ採用情報もご覧ください。
アバター
はじめに こんにちは、データドリブン推進室でデータエンジニアをやっている鶴です! みなさん、LightdashのTable calculation機能って使ってますか? 自分はLightdashを触っていて[+Table calculation]という表記を見かけた際に 「Table calculationってことは表計算機能のことか〜 Tableauとかにもある出力した結果データの中で集計したりするやつかな あると便利だよな…そのうち使う機会くるっしょ〜」 みたいなこと考えてあまり触らずスルーしてました… 同じような方もいらっしゃるのではないでしょうか? 実はLightdashのTable calculation機能はちょっと面白い機能になっているのでここでご紹介したいと思います! はじめに Table calculationを触ってみよう テンプレート機能もあります 実はこれだけじゃなかったTable calculation 最後に We are hiring! Table calculationを触ってみよう まずはQuerying from tablesから見たいテーブルを選択し、Resultの右上にある[+Table calculation]を押してみると… こんな画面が出てきます。 つまり出力したデータを使ってSQLを書いて集計する、という感じなんですね。 やはり表計算といえばウィンドウ関数ということで書いてみます! 今回サンプルで用意したスーパーマーケットデータで売上前日比を作ってみます。 ※本記事に登場する「さくらマート」は、サンプルデータ用に作成した架空の名称であり、実在のいかなる店舗・団体とも一切関係ありません SQLはこんな感じです。編集画面で文字を入力するとサジェストしてくれるので便利です。 ${sample_supermarket_sales.sum_of_total_price} / LAG(${sample_supermarket_sales.sum_of_total_price} OVER(${sample_supermarket_sales.sale_date_day})) このデータはソートを設定しているので一旦ORDER BYは記載せず進めてみます。 フォーマットはパーセント表示にしましょう。 保存して実行するとこんな感じになりました! またこの作った項目を直接フィルターに設定することができます! 右上のボタンを押すと[Filter by 売上前日比]があるので押してみると… フィルター欄に追加されました! これを使って前日売上比100%越えの日を出してみる、なんてこともできます。 テンプレート機能もあります ウィンドウ関数はSQLに慣れていない方だと正直難しい部分がありますよね… ですがLightdashにはテンプレートが用意されてます! [Sum of total price]の右上のボタンを押すと、Add quick calculationにテンプレートがあります。 Percent change from previous(前からの変化率)をクリックしてみます。 項目が自動で作成されました! 一応内容を確認するため項目右上を押し、Edit calcultationをクリックします。 内容的には先ほど自分が作ったクエリの内容に近いロジックがあり、それに対して1を引いている形になります。 なお、注意して欲しいのがLAG関数のORDER BYの箇所がDESCになっています。 日付で昇順にしたいためここは消しておきましょう。 ここは見たいものによると思うので適宜調整してください! 実行した結果はこうなりました。正直こっちの方がわかりやすいですね!w このようにテンプレートをうまく使うとサクッと作れます。 他にもテンプレートはあるのでぜひ公式ドキュメントの 解説ページ をご確認ください。 また今の時代はChatGPT先生やGemini先生などに聞けばわかりやすく教えてくれますし、作ってくれます。有効に活用していきましょう! 実はこれだけじゃなかったTable calculation さて、ここまで触ってきたTable calculationですが察しの良い方はこのことに気づいているかもしれません…  SQLで書けるってことはSQLでやれることは割と何でもできるのでは…? そうです、何でもできます。 たとえばこのようなCASE文を書いてバナナフラグを立てることもできます(Result typeはbooleanにしてます) ストアと商品の文字列を結合するようなテキスト計算もできます(Result typeはstringにしてます) なんか自分が思ってた表計算と違う…!!!! 集計した項目をさらに好きなようにデータ加工・計算できるので面白いと思います。 また少し前の Lightdashアップデート で作成した表計算項目を再利用できるようになりました。 つまりこうやって先ほど作成したバナナフラグとストアと商品の項目も合わせることが可能です。 作成した表計算結果をさらに計算して…みたいに広げていけるので柔軟性が上がっていいですね! 最後に Table calculationは定義されたメトリックで対応できなかった集計やデータ加工をカバーする機能となっていて利用される方はこういう機能があると認識されておいた方が良い機能だと思います! ただ公式ドキュメントにも 記載 がありますがこのTable calculationは一時的なニーズに対応するものとしては良い機能ですが、繰り返し再利用されている場合はdbt側の定義に追加して管理するようにした方が良いので管理者は適宜チェックしておきましょう。 We are hiring! 現在、データドリブン推進室では データエンジニア/アナリティクスエンジニアを大募集中 です! セーフィーのデバイスやアプリケーションからは1日あたり数十億件のログが発生し、データ量は線形的に増加しています。 このような超ビッグデータを効率的に処理し、ビジネスの意思決定に繋げるための仕組みを一緒に作ってみませんか? ご興味のある方は セーフィー採用サイト を覗いてみて下さい! よいLightdash Lifeを〜それではまた!
アバター
こんにちは!セーフィーでハードウェア開発を担当している持丸です。 ご存じの通り、「セーフィー」はクラウド録画サービスやソフトウェアを事業の中核とする会社です。 そして当然のように、クラウドやソフトウェアの技術をベースとしたエンジニアの割合が多い会社になります。 しかし、お客様に最高の体験をお届けするためには、映像の入り口となるカメラをはじめとした「ハードウェア」の存在が欠かせません。 今日は、普段あまり語られることのない、セーフィーのハードウェアへの熱い想いと、その品質を支える取り組みについてご紹介したいと思います。 すべては「お客様に寄り添う」ために 「ただ仕入れる」だけでは終わらない、セーフィーの製品評価 仕組みで支える品質。製品評価プロセスの標準化 不具合解析こそ、腕の見せどころ おわりに すべては「お客様に寄り添う」ために 私たちハードウェア担当が最も大切にしているのは、 「お客様に寄り添った製品(ハードウェア)を提供していく」 という、とてもシンプルな方針です。 お客様がどのようなシーンで、どのような課題を解決したいのか。 それを深く理解し、機能や性能はもちろんのこと、長期にわたって安心して使える品質、そして安全性を兼ね備えた製品をお届けすること。 それが私たちの使命です。 セーフィーが提供するハードウェア製品には、他社から購入した製品(一部をセーフィー向けにカスタマイズしたものを含む)と、自社で開発した製品の2種類があります。 今回は、特に他社製品をお客様にお届けする際の、私たちのこだわりについてお話しします。 「ただ仕入れる」だけでは終わらない、セーフィーの製品評価 他社製品を選定する上で、私たちは特に以下の2つのプロセスに多くの時間を費やしています。 お客様の利用シーンの把握と理解 提供する製品の設計思想の読み取り Fig1 なぜなら、この2つのステップを疎かにすると、「思い込み」によって後々大きな問題を引き起こしかねないからです。 「普通はこうのはずだ」といった思い込みを排除し、お客様の本当のニーズと製品の特性を正確に結びつける。 そして、関係者全員がその共通理解の上に立つことが、プロジェクト成功の鍵を握っています。 この考え方に基づき、私たちは以下のようなステップで製品の評価を進めています。 お客様の要求内容を明確にし、文書化する(ユーザー情報) 選択する製品の仕様(機能、性能、品質など)がお客様の要求を満たせているかを確認する(製品情報) カタログスペックだけでは確認できない項目を洗い出し、評価・検証を実施する(追加評価) Fig2 仕組みで支える品質。製品評価プロセスの標準化 「言うは易し、行うは難し」ですが、これらの製品評価プロセスが担当者のスキルや経験だけに依存してしまうと、品質にばらつきが生まれてしまいます。 そこで私たちは、誰が担当しても一定の品質を担保できるように、評価プロセスを前述のように標準化し、専用の入力フォーム(下記参照)や手順書を整備しています。 利用シーンの把握: 製品設置要件確認シート 製品の設計・安全思想の把握: 設置ガイドの確認シート、製品認証の確認シート 製品性能・品質の確認: 製品性能の確認シート、製品品質の確認シート Fig3 さらに、ソフトウェアエンジニアが多く在籍するセーフィーの特性を踏まえ、各シートの入力方法や注意点をまとめた手順書を準備しました。 これは、普段から設置業務、部材に触れている担当であれば用語にも精通していますし、どこにどういった情報があるかもすぐわかります。 しかし、頻度の低い人が作業を始めようとすると、思いのほか時間がかかったりもします。このような背景に対応するための手順書を作成しています。 Fig4 これらを用いることにより、ハードウェアの専門家でなくても、スムーズかつ網羅的に検証を進められる環境を整えています。 加えて、使用上の注意、安全上の注意、認証前提といった文言、用語、表現が各社で幅広く単純な検索ではマッチしないものには生成AIを用いることを想定し、対象項目を調査できるようにキーフレーズを併記しています。 多くの人が実感している通り、生成AIによる調査のメリットは、網羅的な抽出ができることにより、調査範囲が不十分なことによる抜け、漏れの発生を防ぐことができます。 しかしながら、調査者の経験・知識が少ない場合には、生成AIに入力するフレーズが十分でなく、このメリットが十分に享受できないケースの発生があります。 これらから、フレーズ例を併記し、出力結果が限定されすぎないようにしています。 Fig5 不具合解析こそ、腕の見せどころ このように確認を行った製品であっても販売後に、残念ながら何らかの不具合が発生することもあります。そんな時こそ、私たちハードウェア担当の腕の見せどころです。 解析の進め方で一番やりがちなことは、つい経験と勘に頼って解析を進めてしまうことです。 当たればよいのですが、当てが外れると原因究明が困難になることも多々あります。 我々は製造メーカーではなく、大量に世の中に製品を出荷しているわけではないので、解析ができる不具合対象機が数台程度であることが常です。 慎重にことを進めることが重要になります。 このようなことも踏まえながら、経験豊富なエンジニアも、そうでないメンバーも、同じ情報を残しながら解析を進められるよう、体系的な不具合解析フローを構築しています。 不具合報告の確認(不具合報告確認シート) 不具合品の外観(外観確認報告シート) 不具合再現(再現確認報告シート) 不具合品の分解(分解確認報告シート) 不具合品の解析(解析報告シート) 各シートには、HWエンジニアの経験してきた確認項目がリストされ、その内容を順次チェックしていくつくりになっています。 これにより、後戻りのない、的確な原因究明と、再発防止に繋げています。 Fig6 おわりに 今回は、セーフィーのハードウェアへの取り組み、特に他社製品を評価する際のプロセス及び不具合解析についてご紹介しました。 これは、 HWエンジニアを抱えるセーフィーだからこそのアプローチです 。 私たちの目標は、この HWエンジニアの経験や見識に裏打ちされた仕組み をさらに進化させ、HWエンジニア以外のメンバーを含めた全体の底上げをすることでお客様に品質の高いハードウェアを届けられるようにすることです。 次回は、もう一つの柱である「自社開発製品」について、詳しくお話ししたいと思いますので、お楽しみに!
アバター
こんにちは。セーフィー株式会社エンジニアの伊藤です。 今回のお話は、動画配信サービスを開発・運営されている皆さまへ 「UI/UX」 についてのお願いです。冒頭からかなり対象を絞った内容に感じられるかもしれませんが、きっと多くの方にも共感していただける部分があると思います。 どうぞ気軽にお読みいただければ幸いです。 まずは こちら をご覧ください。(※音が出ます) ※ iOS では上手く表示されない不具合があります。動作環境は PC がおススメです。 動画見ながら寝落ち問題 シークバーのツライところ 理想のシークバーの提案 まとめ おまけ(シークバーの作り方) ステップ1 設計図を書く ステップ2 座標変換 ステップ3 描画 ステップ4 再生位置の移動 & スケール変換 まとめ 動画見ながら寝落ち問題 さて、皆さんは「動画配信サービス」を利用していますか? YouTube、Netflix、Amazonプライム・ビデオ、他にも数えきれないほどのサービスが乱立していますが、現代人なら何かしら一つは使っているのではないでしょうか。中には、いくつものサービスに加入して、毎晩ついつい夜更かししてしまったり、休日は朝から晩まで動画漬け、、なんて方もいらっしゃるかもしれませんね。かく言う私も、そんな動画漬けの毎日を送っている一人です。 そして今回は、そんな生活の中でどうしても気になる “あるUI” について、一言物申したいと思います。 それは 「シークバー」 です。 私は普段、寝ころびながらスマホで動画を見ることが多いのですが、ついつい 寝落ち してしまうことがあります。気づけば動画は再生し終わっていて、「あれ?どこまで見たんだっけ?」と、後から見返そうとするのですが、そこで困るのがシークバーです。動画の総再生時間に対して、シークバーの表示があまりにも短く、指で正確に寝落ちした位置まで移動するのがとても難しいのです。 シークバーのツライところ 「いやいや、それって本当にそんなに難しいの?」とピンとこない方もいるかもしれません。そこで、どれくらい操作が難しいのかを定量的に検証してみましょう。 まず、シークバーの物理的な長さですが、スマホを横向きにしたときの画面幅に依存します。端末によって違いはあるものの、大きめのスマホでも画面の横幅はせいぜい 150mm 程度です。(ちなみに、私が使っているスマホは 110mm でした) ただし、これは画面全体の幅。実際のシークバーには左右にマージン(余白)があるため、バー自体の有効な長さはもう少し短くなります。ここでは仮に、シークバーの長さを 140mm としてみましょう。この状態で 2時間(= 7,200秒)の映画を見ているとすると、 1mm あたりの時間 : 7,200秒 ÷ 140mm ≒ 50 秒/mm さらに、指の腹の太さはだいたい 15mm くらいありますよね。つまり、 指先 1 本分に約 12 分 (=50秒 × 15mm)の映像が圧縮されているわけです。 この状態で「あと5秒戻りたい」と思っても、1mm以下の繊細な操作が求められます。まるでお米に字を書くようなものですね。しかも、苦労してシークバーを微調整したところで、動画が再生されるまでは、どの場面から始まるのか分かりません。「このシーンはまだ意識があったな」「あっ、ちょっと行きすぎた」そんなことを考えながら、スクリーンを何度も指でスリスリ。そして、行きすぎては戻し、戻しすぎては進める。こうして、微調整を何度も繰り返す羽目になるのです。 理想のシークバーの提案 そこで冒頭の動画の新しいシークバーの提案です。各社の動画配信サービスでぜひ採用していただきたい、 理想のシークバー を自分なりに実装してみました。 工夫したポイントは、主に以下の2つです。 1. シークバーのスケールを拡大・縮小できる 再生位置の指定は、マウスならドラッグ操作で、スマホならタッチ操作で行います。これ自体は一般的な操作ですが、ここに スケーリング機能 を加えました。 マウスホイールで拡大・縮小(スマホの場合はピンチイン・ピンチアウト) スケールを大きくすれば、ざっくり全体を早送り・巻き戻し スケールを小さくすれば、秒単位での微調整もストレスフリー 「まず大まかに探し → 細かく調整する」 という動作が、スムーズに完結できるのです。 2. 動画のサムネイルを表示して視覚的に検索できる シークバーの上に 動画のサムネイルを表示する 機能も加えました。これは最近のプレイヤーにもよく見られる機能ですが、今回の提案ではスケール拡大・縮小と組み合わせて使えるのがポイントです。 拡大時には、前後のフレームが視認できるようにし、シーンの切り替わりもひと目で把握できる 「どこで寝落ちしたか」が視覚的に探しやすくなる この2点を組み合わせることで、「あの場面を探したいのに見つからない」という、あのもどかしさから解放されるのではないかと考えています! まとめ 以上、現場からのお願いでした! ちなみに冒頭のデモのサムネイル部分の描画には、ブラウザにそこそこ負荷がかかっているようで、上手く動作しないことがあります。特に iOS ではサムネイルが上手く表示されない不具合が見つかっています。動作環境は PC がおススメです。 また今回作ったシークバーをお好きな動画でお試しいただけるように、 お手元の動画ファイルを読み込めるバージョン を用意しました。良ければこちらも使ってみてください。 動画配信サービスを手がける皆さま、どうかこの寝落ちユーザーの声に耳を傾けていただければ幸いです! おまけ(シークバーの作り方) ここからはエンジニア向けのお話しになります。せっかくなので、スケールを自由に変更できるシークバーの実装方法について解説したいと思います。 冒頭の動画サンプルでは、サムネイル表示などの機能も含めているため、コードが少し複雑になっています。そこで、今回はシーク機能に限定したシンプルな デモ を用意しました。こちらのコードをベースにして、具体的な実装ポイントや仕組みをわかりやすく説明していきたいと思います。ソースコードは こちら です。 実装方法はいくつか考えられますが、今回はWebアプリとしての開発ということで、 Canvas API を使って実装しました。Canvas API は標準的な描画処理のインターフェイスを提供しており、モバイルなど他のプラットフォームでも似たような機能やライブラリがあるので、比較的簡単に移植が可能だと思います。 ステップ1 設計図を書く まずはデザインを決めて、その設計図を描きましょう。Canvas API では点や線、長方形といった基本的な図形のほか、テキストや画像も描画できますが、どんなGUIを作るにしても、まずは 描きたいものを細かな要素に分解する ことが大切です。 サンプルは下図のようなデザインになっていますが、よく見ると線と長方形、そしてテキストで構成されていることが分かると思います。 こちらに細かく寸法を記入していきます。 寸法の取り方はセンス次第で自由に決めていただいて構いませんが、 このようなパラメータを変数としてまとめておく と、あとからデザインを調整するときにとても便利です。 const SEEKBAR_POS_Y = 60 ; const SEEKBAR_HEIGHT = 15 ; const SCALE_LINE_HEIGHT = 8 ; const SCALE_TIME_TEXT_SIZE = 16 ; const CURRENT_TIME_TEXT_SIZE = 28 ; const HEIGHT = 120 ; ステップ2 座標変換 続いて、シークバーの描画に必要な知識をインプットしていきましょう。 シークバーの横方向は、動画の時間の経過を表しています。ここで、動画の時間と画面上の描画位置を結びつけるために、 「座標変換」 という考え方が役立ちます。聞き慣れない言葉かもしれませんが、実は中学生のときに習った 一次関数 の考え方とほぼ同じものです。 今回作ったものは、まず図のように動画全体から、その一部を切り取った赤枠の部分を画面上に描画しています。このように考えると、 「動画の時間軸」と「画面の座標軸」 という、2つの異なる座標軸が存在していることになります。 ここで、動画の時刻を 、画面の水平方向の位置を とします。さらに、 画面の左端の位置に対応する時間: 画面1ピクセルあたりの時間幅: とすると、次のような変換式が成り立ちます。 こちらの式だけでは、時間軸と画面座標軸の変換を具体的にイメージしづらいと思うので、下記のように値を定義して、その関係を図示してみます。 画面の幅: 現在時刻: 画面の右端の位置に対応する時間: 動画の長さ: 図の上側の青色の直線が時間軸で、下側のオレンジ色の直線が画面座標軸になります。グラフにすると次にような直線(一次関数)です。 この直線の式の定数項である を変化させると、時間軸上で切り取る範囲が変わります。その結果、画面上ではシークバーの表示位置が左右に移動し、まるで時間が動いているように見えるのです。 また、直線の傾きを表す の値を変えると、画面上で切り出される時間の範囲が変わります。これにより、シークバーのスケールが拡大・縮小されたような見た目になります。 ちなみに今回のデザインでは、画面の中央の位置が現在時刻 ( ) をあらわしているので、 は現在時刻から画面幅の半分 ( )の時間を差し引いた値となり、次のように表せます。 というわけで、動画の切り出し位置を制御するための変数として現在時刻 ( ) 、スケールを制御するための変数として1ピクセル当たりの時間( ) 、この 2 つを保持しておけば十分です。 // 現在の時刻 currentTimeMs = 0 ; // 1ピクセルあたりの時間(ミリ秒) timeMsPerPix = 2400 ; 元の変換式に を代入して消すと、現在時刻 ( ) と1 ピクセル当たり時間幅 ( ) を用いた式に整理できます。 ここからさらに変形して イコールの形にすると、時間軸上の座標 を画面上の座標 に変換できます。 これらが動画の時間軸と画面の座標軸を行き来するための変換式になります。描画位置の計算のために頻繁に利用するので 関数化 しておきます。 pix2time ( pix ) { const startTimeMs = this. currentTimeMs - this. canvas . width / 2 * this. timeMsPerPix ; return pix * this. timeMsPerPix + startTimeMs ; } time2pix ( timeMs ) { const startTimeMs = this. currentTimeMs - this. canvas . width / 2 * this. timeMsPerPix ; return ( timeMs - startTimeMs ) / this. timeMsPerPix } ステップ3 描画 さて、準備が整ったので、いよいよ描画方法について解説していきます。 描画に用いる Canvas API の利用方法はここで詳しく解説はしませんが、長方形とテキストの描画しか用いないので、下記の2点だけ雑に理解していればオッケイです。 長方形の描画 (fillRect) テキストの描画 (fillText) 描画処理は draw() 関数 の中にまとめられていますが、少し長いので段階的に見ていきましょう。 背景の描画 まずは背景の描画から。ここでは、キャンバス全体を指定した色で塗りつぶしています。つまり、この時点では背景が真っ白になっているだけです。 ctx . fillStyle = SEEKBAR_BACKGROUND_COLOR ; ctx . fillRect ( 0 , 0 , this. canvas . width , this. canvas . height ) ; シークバー本体の描画 次にシークバー本体を描画します。バーの背景は画面の横幅いっぱいに長方形を描くだけです。その後に動画コンテンツが存在する部分を緑色で塗り分けます。 // シークバーの背景描画 ctx . fillStyle = SEEKBAR_BLANK_COLOR ; ctx . fillRect ( 0 , SEEKBAR_POS_Y , this. canvas . width , SEEKBAR_HEIGHT ) ; // シークバーの動画コンテンツがある部分を描画 const dataStartPosX = this. time2pix ( 0 ) ; const dataEndPosX = this. time2pix ( this. durationMs ) ; ctx . fillStyle = SEEKBAR_DATA_COLOR ; ctx . fillRect ( dataStartPosX , SEEKBAR_POS_Y , dataEndPosX - dataStartPosX , SEEKBAR_HEIGHT ) ; シークバーの目盛りの描画 続いて少し長めですが、シークバーの目盛りを描画しているコードをご紹介します。 ctx . font = SCALE_TIME_TEXT_SIZE + 'px sans-serif' ; const { scaleInterval , textInterval } = this. adjustScale ( this. timeMsPerPix ) const startTime = this. pix2time ( 0 ) const endTime = this. pix2time ( this. canvas . width ) const firstScaleTime = Math . floor ( startTime / scaleInterval ) * scaleInterval let i = 0 while ( 1 ) { const scaleTime = firstScaleTime + i * scaleInterval if ( scaleTime > endTime ) { break; } if ( scaleTime > this. durationMs ) { break; } if ( scaleTime < 0 ) { i ++ continue } // 目盛りを描画 const scalePosX = this. time2pix ( scaleTime ) const scalePosStartY = SEEKBAR_POS_Y + SEEKBAR_HEIGHT const scalePosEndY = scaleTime % textInterval === 0 ? scalePosStartY + SEEKBAR_SCALE_HEIGHT * 2 : scalePosStartY + SEEKBAR_SCALE_HEIGHT ctx . fillStyle = SEEKBAR_SCALE_COLOR ; ctx . fillRect ( scalePosX , scalePosStartY , 1 , scalePosEndY - scalePosStartY ) // 時間をテキストで描画 if ( scaleTime % textInterval === 0 ) { ctx . textAlign = 'center' ctx . textBaseline = 'top' ctx . fillText ( this. time2str ( scaleTime ) , scalePosX , scalePosEndY + 5 ) } i ++ } 最初に描画する目盛りの時間は以下のように計算しています。 const firstScaleTime = Math . floor ( startTime / scaleInterval ) * scaleInterval ここで使っている scaleInterval は目盛りの間隔を表す変数で、1ピクセルあたりの時間幅に応じて調整しています。この位置は、下図のように 画面の左端ギリギリの外にある目盛りの時間 を指しています。 最初の目盛りの位置が決まれば、あとは画面右端まで等間隔で線を描画していくだけです。 let i = 0 while ( 1 ) { const scaleTime = firstScaleTime + i * scaleInterval ・ ・ ループを抜ける判定 ・ const scalePosX = this. time2pix ( scaleTime ) ・ ・ scalePosX の位置に目盛りを描画 ・ ++ i } 現在時刻の描画 現在時刻を示す赤い線とテキストを描画して完成です。 // 中心の線を描画 ctx . fillStyle = SEEKBAR_CENTER_LINE_COLOR ; ctx . fillRect ( this. canvas . width / 2 , 0 , 1 , this. canvas . height ) ; // 現在時刻の文字背景を塗りつぶす const textBgWidth = 100 const textBgHeight = CURRENT_TIME_TEXT_SIZE + 5 const textBgPosX = ( this. canvas . width - textBgWidth ) / 2 const textBgPosY = ( SEEKBAR_POS_Y - textBgHeight ) / 2 ctx . fillStyle = SEEKBAR_BACKGROUND_COLOR ; ctx . fillRect ( textBgPosX , textBgPosY , textBgWidth , textBgHeight ) ; // 現在時刻のテキストを描画 ctx . font = CURRENT_TIME_TEXT_SIZE + 'px sans-serif' ; ctx . textAlign = 'center' ctx . textBaseline = 'middle' ctx . fillStyle = SEEKBAR_TIME_TEXT_COLOR ; const textPosX = this. canvas . width / 2 const textPosY = SEEKBAR_POS_Y / 2 ctx . fillText ( this. time2str ( this. currentTimeMs ) , textPosX , textPosY ) ; ステップ4 再生位置の移動 & スケール変換 最後に、マウスイベントに合わせて再生位置の移動やスケール変更を行っているコードを見ていきましょう。 まず、再生位置の移動はマウスのドラッグ操作に連動して currentTime を更新するだけです。 this .canvas . addEventListener ( 'mousedown' , ( e ) => { this. isMouseDown = true this. mousePosX = e . offsetX }) this .canvas . addEventListener ( 'mouseup' , () => { this. isMouseDown = false }) this .canvas . addEventListener ( 'mouseleave' , () => { this. isMouseDown = false }) this .canvas . addEventListener ( 'mousemove' , ( e ) => { if ( this. isMouseDown ) { const prevMousePosX = this. mousePosX this. mousePosX = e . offsetX const diffX = prevMousePosX - this. mousePosX const newCurrentTime = this. currentTimeMs + diffX * this. timeMsPerPix this. currentTimeMs = Math . max ( 0 , Math . min ( this. durationMs , newCurrentTime )) this. draw () } }) 次に、スケールの変更もシンプルで、マウスホイールの操作に応じて timeMsPerPix を調整するだけです。 this .canvas . addEventListener ( 'wheel' , ( e ) => { e . preventDefault () ; let newTimeMsPerPix = this. timeMsPerPix if ( e . deltaY > 0 ) { newTimeMsPerPix *= 1 . 1 } else { newTimeMsPerPix *= 0 . 9 } this. timeMsPerPix = Math . max ( MIN_TIME_MS_PER_PIX , newTimeMsPerPix ) this. draw () }) これで、マウス操作による直感的なシークとスケール調整が実現できます。タッチ操作もサポートしていますが、実装方法は過去に執筆した 記事 でも解説しておりますので、こちらを参考にしていただければと思います。 まとめ 長くなりましたが、以上が処理の全容になります。 今回解説した座標変換の考えを利用すれば、アイデア次第で色んなものが作れそうな気がしませんか?ちなみに座標軸を2次元に拡張すれば、GoogleMap のようなマップアプリも作れます。みなさまの何かのお役に立てれば幸いです。 最後までお付き合いいただき、ありがとうございました。
アバター
こんにちは!セーフィーでQAエンジニアをしている福山です。 今回は、入社間もない私が、他プロジェクトのQAメンバーを巻き込み、探索的テストで製品品質を向上させた経験をお話しします。 この記事は、特にこんな方々に読んでいただけると嬉しいです。 探索的テスト や新しい品質保証の取り組みを考えているQAエンジニアの方 チームや部署を横断した連携で、組織全体の生産性や品質を高めたいテックリードやマネージャーの方 新しい環境で自身の強みを活かして成果を出したい中途入社の方 課題:リリースを前に、担当チームだけでは見つけられない不具合の壁 成功の鍵は「巻き込む力」!他チーム連携で意識した5つの工夫 1. タイミングを見極める 2. 心理的ハードルを下げて「テストに集中できる」環境を作る 数値的な目標は慣れてから 気軽に共有できる場を設ける バグを見つけることだけが成果ではない 3. 上長を味方につける 4. モチベーションを維持する 週替わりの画面担当ローテーション 個別フォローと密なコミュニケーション 迅速なフィードバック 5. 共有の場から関係性を築く テスト結果を数値的に可視化 関連題材を用いた勉強会 挑戦の裏側:ぶつかった壁と、思いがけない発見 ぶつかった壁 実施時間と他業務との調整 自身の認知度と信頼感 思いがけない発見 メンバーの協力的な姿勢 多様な視点からの発見 まとめ:組織を動かし、成果を出すために必要なこと 課題:リリースを前に、担当チームだけでは見つけられない不具合の壁 セーフィーのQA部門には、合計16名のQAエンジニアがいます。それぞれが複数の製品を担当しており、私が担当する製品のQAメンバーは4名。残りの12名は別の製品に携わっています。 日頃からテストスクリプトを使った網羅的なテストと、探索的テストを並行して実施していましたが、担当プロジェクトのメンバーだけでは、どうしても見つけにくい不具合があると感じていました。 迫りくるリリースを前に「どうすればもっと品質を高められるだろう?」と考えた私がたどり着いたのが、 「他プロジェクトを担当するQAメンバーを巻き込む」 というアイデアでした。同じQAという職種でも、普段は別の製品に携わっているメンバーの新鮮な視点と専門的な経験を活かした探索的テストは、きっと製品の隠れた問題を発見し、品質を一段と引き上げてくれると確信したのです。 成功の鍵は「巻き込む力」!他チーム連携で意識した5つの工夫 他プロジェクトのQAメンバーに協力を依頼するにあたり、スムーズな連携と参加者のモチベーション維持が重要だと考え、以下の点を意識して準備を進めました。 1. タイミングを見極める テストの実施タイミングは非常に重要です。今回は、機能が90%以上実装されており、かつリリースまで1ヶ月半というタイミングで協力を依頼しました。未実装の機能が多いとテスターが混乱しますし、開始が遅すぎると開発への負荷も大きくなるため、このタイミングが最適だと判断しました。 2. 心理的ハードルを下げて「テストに集中できる」環境を作る 主担当ではない製品の探索的テストはどうしても心理的ハードルがあるため、できるだけハードルを下げ、スムーズに進むようにいくつか工夫を行いました。 数値的な目標は慣れてから まずは目的を意識しつつも慣れてもらうことを最初の目標にしました。裏では具体的な目標数値は設定していましたが、いきなり数値を提示すると逆効果だと考え、後から共有することにしました。 気軽に共有できる場を設ける Backlogへの直接起票はやめ、スプレッドシートに記入してもらう形式にしました。これにより、内容の精度や不具合の重複を気にせず報告できるため、心理的なハードルが下がります。 バグを見つけることだけが成果ではない 不具合が検出できなかった場合でもモチベーションを下げないよう、「不具合がない」ことも貴重な情報であることを伝えました。また「違和感」や「改善点」も歓迎し、UI/UX向上に直結する重要な情報だと強調しました。 3. 上長を味方につける プロジェクトを円滑に進めるには、上長(グループリーダー:GL)の理解と協力が不可欠です。私たちは2つのグループに分かれているため、他グループのメンバーを巻き込むには、各グループのGLの理解と協力が必要でした。事前に相談し、快諾を得るとともに貴重なアドバイスもいただきました。上層部のサポートは、プロジェクトを成功させる上で非常に心強い後押しとなります。 4. モチベーションを維持する 約1ヶ月半の探索的テストへのモチベーションを維持してもらうため、具体的な仕組みをいくつか導入しました。 週替わりの画面担当ローテーション 参加者には週ごとに担当画面を割り当て、飽きを防ぎながら主要機能を優先的にテストできるよう工夫しました。 個別フォローと密なコミュニケーション リモートワーク中心のメンバーには、DMなどを活用して積極的にコミュニケーションを取り、不具合検出の感謝を伝えたり、困っていることがないか確認しました。 迅速なフィードバック 報告された内容は、極力その日のうちに確認し、何かしら返信するように心がけました。迅速なレスポンスは、報告する側のモチベーション維持につながります。 5. 共有の場から関係性を築く テスト結果を数値的に可視化 毎週、テスト結果を数値的に可視化し、参加者全員に共有しました。これにより、自分たちの活動が製品品質にどのように貢献しているかを実感してもらいました。さらに、特に参考になった報告内容については、感謝の意を込めて共有し、参加者の努力を称えました。 関連題材を用いた勉強会 テストの中盤には、探索的テストに関する勉強会を開催しました。共通の題材を通して、お互いの考え方やテストスタイルを共有する機会を設け、チーム全体のテストスキル向上と連携強化を図りました。 挑戦の裏側:ぶつかった壁と、思いがけない発見 今回の取り組みでは、もちろん悩みもありましたが、幸運にも助けられる場面も多くありました。 ぶつかった壁 実施時間と他業務との調整 各メンバーの業務が見えない状況で、どの程度時間を捻出可能かは非常に悩ましい点でした。GLに相談し、最低1時間/週という下限値を設けて自主性に任せる方針を決定しました。 自身の認知度と信頼感 最も困ったのがこちらです。中途入社から半年弱ということもあり、普段接点のない他グループのメンバーに自身の存在を知ってもらい、信頼関係を築くことが課題でした。勉強会などを通じて積極的に自己開示を行い、少しずつ関係性を構築していきました。 思いがけない発見 メンバーの協力的な姿勢 通常、初めての試みでは様子見から入ることが多いものですが、率先してスタートダッシュを切ってくれたメンバーがいました。また、中盤でも熱心に多くの報告をくれたメンバー、そして終盤まで継続してテストに参加してくれたメンバーなど、様々な協力がプロジェクトを前進させました。 多様な視点からの発見 各メンバーがそれぞれの得意な観点や、様々な視点から不具合を検出してくれたのは大きな収穫でした。これにより、私自身も「こんな観点があったのか」と学びを深めることができました。この多様な視点こそが、探索的テストの真価だと改めて感じました。 まとめ:組織を動かし、成果を出すために必要なこと 他プロジェクトのQAメンバーを巻き込んだ探索的テストは、製品の品質向上に大きく貢献しただけでなく、部内間のコミュニケーション活性化にもつながる、非常に有意義な取り組みでした。 本記事の最大の価値は、製品の品質向上という 結果 だけでなく、 その成果を生み出した「他チームを巻き込む」ための具体的なプロセスとノウハウ を共有した点にあります。具体的な数値は皆さんのチームの状況によって変わるかもしれませんが、ここに書かれている工夫や考え方は、きっと皆さんの組織でも再現できると思います。 私自身のように中途入社でドメイン知識が少ないメンバーでも、今回の工夫を凝らすことで、きっと素晴らしい成果を生み出すことができるはずです。 本記事が、皆さんの品質保証活動の一助となれば幸いです。
アバター
こんにちは。25新卒エンジニアの中です。 大学院では、ある車の会社と共同で「機械学習を用いて物理シミュレーションを置き換える手法」について研究を行い、先日ローマにて行われたAI関連の学会でポスター発表してきました。エスプレッソもパスタもワインも美味しかったです。 このブログでは、入社してから4ヶ月弱で行われた新卒研修プロジェクトで学んだ、「全体像の可視化」の重要性について話していきます。 新卒エンジニア研修について 研修で直面した壁 プロジェクトの全体像が見えなかった初期フェーズ 振り返り会と「可視化」の徹底 Before After 研修を振り返ってみて 4月-5月前半:課題発見フェーズ もし全体像が可視化されていたら… 5月後半-6月前半:課題発見フェーズ2 6月後半-7月:開発と未来設計のフェーズ まとめ 新卒エンジニア研修について 今回のセーフィーの新卒エンジニア研修では、4月真ん中から7月末までの4ヶ月弱で、「社内課題を解決するためのプロダクト開発」を行ないました。この研修の最大の目的は、「プロダクト思考を体現し、エンジニアとして成長する」ことです。つまり、ユーザー目線に立ち、プロダクトを考え、それに沿って開発を進め、その上で成長していくことが求められました。 研修で直面した壁 研修プロジェクトが始まってすぐに私たちが直面したのは、『チーム全員でプロジェクトの全体像を把握すること』の難しさでした。私たちのチームには、以下の2つの目的がありました。 新卒研修プロジェクトの目的:プロダクト思考を身につけ、エンジニアとして成長する プロダクトの目的:ユーザーの課題を解決する プロジェクトの全体像の把握ができていないと、この2つの目的を同時に達成することは難しいと痛感しました。 プロジェクトの全体像が見えなかった初期フェーズ チームでの開発フェーズが始まった初期段階では、プロジェクトの進捗状況が把握できていませんでした。 口頭でのタスク管理:口頭で決まったことがタスクとして記録されず、それぞれのタスクの粒度もバラバラでした タスクの偏り:誰が何をするのかが曖昧になり、チーム全体でタスクを抱えている人と、そうではない人の差が大きくなっていきました。 漠然とした不安:目の前のタスクをこなすことに精一杯で、「本当にユーザーの課題を解決するものなのか?」「このプロセスが自身の成長に本当につながっているのか?」という漠然とした不安が常に付きまといました。 これは、プロジェクト全体の把握ができていないことにより、「自身の成長」と「ユーザーの課題解決」という2つの目的を見失っていたことが原因でした。 振り返り会と「可視化」の徹底 プロジェクト全体の把握ができていないという課題を解決するため、私たちは開発機関の中間地点で開催した振り返り会で現状を共有しました。そこで、私たちは以下のシンプルなルールを徹底することに決めました。 タスクは必ずチケットとして可視化し、粒度を揃える 具体的なルールは以下の通りです。 チケットは1~2営業日以内で完了するものに限定する 処理中のタスクは1~2個にする 複数のタスクが同日に並ぶ場合は、全てその日で終わらせられる場合のみとする このルールにより、メンバー間でタスクの共通認識が生まれ、スムーズに開発を進められるようになりました。 Before 弁当競合調査の中で何をするのか、どう調べるのかがわからず、進捗状況が一目で分かりづらい。開発本部会は1日のはずなのに4日分引かれており、その中で何をするのかがわからない。 After アイテム画面実装という親タスクに対し、何をするのかを小タスクとして設定し、進捗を確認しやすくなりました。 研修を振り返ってみて もし研修開始当初に「全体像の可視化」の重要性に気づけていたら、私たちのプロジェクトはもっとスムーズに進んだという仮定のもと、開発研修を振り返っていきたいと思います。 4月-5月前半:課題発見フェーズ この時期は、プロジェクトの進め方や課題を発見するための手法に関する知識が不足していました。 もし全体像が可視化されていたら… 最終ゴールの明確化:最終的に完成させるプロダクトの規模やビジョン、最終到達点をチームで明確に合意していれば、そこから逆算してマイルストーンを設定できたはずです Backlogの適切な運用:ゴールが定まっていれば、Backlogのチケットの粒度も自然と定まり、手探りでの運用を避けることができたはずです 5月後半-6月前半:課題発見フェーズ2 この期間は、メンバーが入れ替わりで研修に参加していたため、チーム内での進捗共有が不十分になってしまいました。 もし「全体像」が可視化されていたら... スムーズな進捗共有:プロジェクトの全体像が可視化され、Backlogに適切にチケットが反映されていれば、戻ってきたメンバーもすぐに状況を把握できたはずです チームの一貫性の維持:チームとしての判断軸が定まっていれば、メンバーが抜けても方向性がぶれることはなかったでしょう 6月後半-7月:開発と未来設計のフェーズ 開発期間は、当初の計画よりもミニマム開発の完了が遅れてしまいました。また、明確なルールがないままアジャイル的な進め方になったため、進捗の把握に苦労しました。 もし「全体像」が可視化されていたら... 運用を見据えた設計: 開発の初期段階から「運用しやすい設計になっているか?」「コストに見合う価値があるか?」といった問いに向き合え、属人化を避けるための人員配置や計画を立てられたはずです まとめ この研修プロジェクトを通して、私は技術的なスキルだけでなく、『チーム全員が同じ全体像を共有し、目的を意識して開発を進めること』が、プロジェクトの成功と自身の成長に不可欠だと学びました。 研修で直面した壁は、私たちを大きく成長させてくれました。配属されて数週間経った今、この経験を活かし、 自身の成長とチームとしての成果、両方の視点を持って行動すること を心がけています。 今後、この研修で開発したプロダクトは、社内運用に向けてチームで議論を重ねていきます。技術を学ぶだけではないこの新卒研修プロジェクトを経験できたこと、そして多くの壁をチームで乗り越えた経験は、これからのエンジニアとしてのキャリアにおいて、常に活かされていく大切な教訓です。
アバター
こんにちは! モバイルチームの夕田です! 先日開催された国内最大級のiOSエンジニア向けカンファレンス「 iOSDC Japan 2025 」に、セーフィーのiOSチームが参加しました! 今年セーフィーは本イベントに シルバースポンサー として協賛させていただきました! 下記 connpass のページをぜひご確認ください! yumemi.connpass.com おわりに 「ブログを書くまでがiOSDC」ということで、無事に私たちもiOSDCを締めくくることができました✌️ 最後になりますが、このような素晴らしいイベントを企画・運営してくださったスタッフ、関係者、スポンサーの皆様に心より感謝申し上げます。 来年も楽しみにしています!! セーフィーでは一緒に働くエンジニアの仲間を随時募集しています。 少しでも興味を持たれた方がいましたら、ぜひ下記の採用ページをご覧ください。 safie.co.jp
アバター
はじめに セーフィーの情報システムグループでグループリーダーをしている松尾と申します。 セーフィーは「映像から未来をつくる」というビジョンのもと、クラウド録画サービスを提供しています 。私たちのサービスは、防犯・見守りに留まらず、業務効率化や現場DXなど、様々なシーンで社会の「安心安全」を支えています。 情報システムグループ(以下、情シスG)では2025年1月から半年ほど、アジャイルを導入したプロジェクト・タスク管理を実施しました。 今回はこちらの取り組みについて、主に以下の内容を書いていきたいと思います。 はじめに なぜアジャイルを導入したか どのようにアジャイルを導入したのか アジャイル勉強会の実施 スプリントの実施 情シスアジャイルプレイブックの作成 アジャイルを実施するための環境づくり どのような変化があったか 細かい改善の例 半年間を振り返って おわりに なぜアジャイルを導入したか 「日々の問い合わせ対応に追われ、本来注力すべき中長期的なタスクがなかなか進まない…」多くの情報システム部門が抱える悩みではないでしょうか。 私たちセーフィーの情シスGも例外ではありませんでした。タスクは常に「実施中」のまま停滞し、定例報告は「進んでいない状況」の共有になりがちで、チームの士気にも影響が出始めていました。 具体的には以下のような問題がありました。 日々の社内からの問い合わせ対応と、目標設定に紐づく長期的なタスクを並行して実施しており、目標に紐づく長期タスクは各自が開始と終了を設定して進めているが、 突発的な業務などにより、タスクの進捗が遅れがちになっていた その結果、 タスクがずっと「実施中」のままとなり、進捗が見えづらい状態 となっていた 2週間毎に実施している定例では「タスクが進んでいない状況」を共有することになり、 メンバーのモチベーションも上がらない状態になっていた 進捗が見えないため、 適切なタイミングでチームでサポート出来ないというジレンマ があった これらの課題を解決するため、情シスGでは以下の目的を掲げました。 無理のない形でメンバーが成果を出せるようにする そのために、 成果を可視化し、チーム内外にすぐに共有できる状態 を作る 目標設定の状況を明確にし、進捗を正確に把握できる状態を作る 目標達成までのプロセスを細かく刻み、その方法が適切か、 より良い方法はないかを常に探求できるようにする 定例会議を、単なる進捗報告ではなく、 成果を共有する場 にする これらの目的を達成するためのアプローチとして、私たちは「アジャイル」な働き方に着目しました。 どのようにアジャイルを導入したのか アジャイル勉強会の実施 まず、チームでアジャイルを始めるにあたり、セキュリティチームと合同でアジャイルの勉強会を実施しました 。詳細はこちらの記事をご覧ください。 参考記事 engineers.safie.link この勉強会を通じて、アジャイルを導入する際には以下を気をつけるということを学びました。 フレームワークの 「やり方だけ」を取り入れることはしない こと アジャイルの原則とプラクティスの目的を理解し、 現状のチームに合ったものを取り入れ、自分たちのものにしていく こと 上記をふまえ、情シスGに合う形で以下のような形でアジャイルを取り入れてみることにしました。 まずは 「半年間のトライアル」 として始めてみる アジャイルの専門用語はできるだけ使わない 情シスGの中で 取り入れられることだけを利用 する 最終的に、この仕組みがメンバーが 無理なく成果を出すための仕事の仕方の型として定着する ことを目指す スプリントの実施 2週間を1つのスプリント(期間)とし、以下のサイクルで業務を進めていきました。 2週間でやること決め(スプリントプランニング) 2週間で実施することを決める 朝会(デイリースタンドアップ) 毎日実施し、問い合わせ対応とタスクの進捗状況、困っていることを確認する 定例(スプリントレビュー) 2週間で実施した成果を発表する ふりかえり(スプリントレトロスペクティブ) 2週間の振り返りを実施し、その中で優先度の高い対応すべきタスクを決める 情シスアジャイルプレイブックの作成 特に意識したのは、単にフレームワークを導入するだけでなく、「なぜこのプラクティスを行うのか」という目的意識をチーム全員で共有することでした。 そのために、各プラクティスの目的や具体的な進め方を 「情シスアジャイルプレイブック」 として言語化しました。 このプレイブックは、途中でチームメンバーが変わっても「無理なく成果を出す仕組み」が継続されるための、私たちのチームの重要な道しるべとなっています。 記載した主な内容 背景:なぜ情シスGがアジャイルに取り組むのか 目的と具体的な進め方 スプリント(2週間)の進め方 2週間でやること決め(スプリントプランニング) 朝会(デイリースタンドアップ) 情シス定例(スプリントレビュー) ふりかえり(スプリントレトロスペクティブ) Notionページに情シスアジャイルプレイブックをまとめています。 アジャイルを実施するための環境づくり アジャイル導入と並行して、メンバーが目標設定に集中できる環境づくりも進めました。 具体的には、やり方がある程度決まっている定常業務のマニュアルを整備し、業務委託のメンバーに対応してもらう体制を作ることで、正社員メンバーが課題解決に集中できるような環境作りを進めました。 どのような変化があったか スプリントを進めていく中で、以下のような変化が現れました。 スプリント開始1ヶ月ほど プロジェクトの全体像を把握 できるようになった 目標に沿って 一日のタスクを可視化 できるようになった 自分の目標と進捗を以前より意識 するようになった 他のメンバーが何の目標を立てているか 分かるようになった やることが明確になり、目標やマイルストーンを立てることで 相談しやすくなった 2週間単位のスプリントを意識し、具体的に何回のスプリントでプロジェクトを終わらせなくてはいけないと考えたことで、 プロジェクトの全体像を意識し、どこまで実施すれば完了なのか、ということを考える ようなったという意見が出てきました。 また、スプリントでは必ず設定したタスクを完了する必要があるため、 完了するために今日はどのタスクをやるべきかを意識する ようになりました。 タスクを意識することで、進めるうえでの課題点が分かるようになり、チームで 相談がしやすく なりました。 2回目スプリントのふりかえりの様子 スプリント開始2ヶ月ほど (アジャイルブックの作成により)タスク管理の取り組みを言語化できた ゴールが抽象的なプロジェクトへの恐怖感が少なくなった (とりあえず2週間のタスクを決めて進め、都度修正していくサイクルが出来てきた) タスクのプロセスを意識し、 できるだけ細かくタスク化するようになった タスクを細分化することで、スケジュールに沿った対応ができた 突発的なタスクを考慮して、 バッファを持たせた目標設定をする感覚が馴染んできた 前回の振り返りと比較することで、より意識して目標管理に取り組めるようになった 2週間単位での仕事の進め方に慣れてきたこともあり、チームで 2週間で実施可能なタスクの量の感覚が少しづつ分かってきた という意見が出てきました。その結果、突発的なタスクを考慮し、 ある程度バッファをもたせた目標設定が出来る ようになってきました。 また、2週間でタスクが区切られているということから、ゴールが抽象的だったり全体のタスクサイズが分からないものでも、 とりあえず2週間で出来る事を決めて、都度方向を修正していく 仕事の進め方が出来るようになってきました。 細かい改善の例 スプリントを繰り返す中で、タスク管理の方法を細かく変更をしていきました。 今回は一例として、朝会の運営方法をどのように変更していったかをご紹介します。 課題: 朝会のスピード感がない 改善策: Backlogの表示をガントチャートからボード形式に変更。「今日やること」のステータスを追加し、 現在取りかかっているタスクを分かりやすくした 課題: 誰かが困っていても、その内容が分かりづらい 改善策: 当番制だった朝会のファシリテーションをグループリーダーに固定 。各パートでメンバーに 「確認したいことはありますか?」という問いかけを入れる ようにした 課題: 「2週間やること決め」の場が、ただタスクを各自が決めるだけの場になってきている 改善策: 「2週間やること決め」でメンバーが2週間でやることを決めた後に、疑問点や知りたいことなど皆から意見をもらう問いかけを追加し、 コミュニケーションの場にするようにした 課題: 困っていることの相談が解決策の議論にまで発展し、朝会が長引いてしまう 改善策: 朝会を2部制に変更 。前半は定常業務中心のヘルプデスクパートとし、非定常業務の相談は後半に回すようにした 課題: 問い合わせ対応を誰がやるか、お見合いになってしまう 改善策: チームで話し合い、 一旦の対応として問い合わせ対応をチケットごとの輪番制に変更 した このように、2週間ごとにふりかえりと細かい改善を繰り返すことで、朝会の運営方法を少しずつ改善していきました。 半年間を振り返って 半年間のトライアルを経て、チームには以下の変化や文化が定着しました。 細かい確認と改善を繰り返す仕組み (アジャイルな仕事の進め方)がある程度、 チームに定着 した 2週間ごとの定例が、成果を発表できる場になった 細かく成果を発表していく仕組みになったことで、 目標設定の評価が以前より書きやすくなった 非定常の問い合わせ対応をタスク毎の輪番制にすることで、チーム内でのノウハウ共有が進んだ。 やったことのない分野もやってみる文化が根付いてきた 「完璧でなくてもいいので、とりあえずやってみる。解決しなければチームのメンバーに相談する、プロに頼る」 という雰囲気が定着した 「頼ることは悪いことじゃない」 というマインドが浸透した 細かい確認と改善を繰り返す仕事の進め方が定着したことで、プロジェクトを進めるうえで手戻りが少なくなったり、方向性を修正しながら動くということが出来るようになりました。 特に、 とりあえずやってみて、分からなければチームに相談する、頼ることは悪いことではない という文化が定着したことは、チームにとっても非常に重要な事だと考えています。 上記の文化が定着したからこそ、問い合わせ対応の輪番制でメンバーが実施したことがない問い合わせがあった場合でも積極的に対応したり、難易度が高いプロジェクトについてもまずはやってみて、チームに相談して進めていくことが出来るようになったと感じています。 半年間のトライアルについてふりかえりをした様子 おわりに 最後までお読みいただき、ありがとうございました。今回は、セーフィーの情報システムグループが取り組んだアジャイル導入の道のりをご紹介しました。 今回のアジャイルの導入はこれで終わりではなく、今回の取り組みでチームに今後も改善を続けていく予定です。 私たちの試行錯誤の過程が、同じようなチームの課題に悩む方や、情報システム部門の働き方に関心のある方にとって、少しでも参考になれば幸いです。
アバター
導入 お久しぶりです。戌亥です。晴れてセーフィー株式会社新卒エンジニアとなりました。( 参考 ) 研修で動画の仕組みに関して学ぶ機会があったのですが、そのうちの画像圧縮に関してイメージしづらい部分があると感じました。同期エンジニアで勉強会があり、今回はそこで話した内容を一部加筆修正して解説しようと思います。 導入 コンピュータでの画像の扱い方 YUVとは 離散コサイン変換(DCT) まとめ コンピュータでの画像の扱い方 画像圧縮の前に画像がデータとして扱われていることを知らない方向けに、画像がおおよそどのようにデータとして扱われているかを説明します。 説明のために画像を拡大して見ることができるアプリをGeminiで作成しました。 画像ピクセル拡大ツール (クリック固定機能付き) 画像を入力し、クリックした地点を8×8マスで拡大してみることができます。拡大だけでなく、RGB値で表示するモードとバイナリ値で表示するモードがあります。 こちらが画像を拡大した時の図です。左の画像の小さくオレンジ色になっている(セーフィーのロゴの嘴)部分が拡大されたものが右のグリッド図になります。 一般的に画像は0~255の256段階のRGB(Red, Green, Blue)値を各画素ごとにもっています。以下の画像は拡大したグリッド図をRGBの値で表したものです。 コンピュータは0と1で解釈するのでデータ量は2進数で考える必要があります。この0または1をビットと言う単位で考えます。 256は2進数で2 8 なので0~255を表すためには8ビットが必要です。画像において、このビット数を減らすのが画像圧縮です。 YUVとは YUVとはRGBやHSVなどと同じ色空間(色の表し方)の1つです。 人の眼の「輝度信号に対して敏感」と「色差信号に対して鈍感」という特性に合わせた表し方で、輝度信号Yと青色成分の色差U(または )と赤色成分の色差V(または )で構成されています。 ディスプレイに表示させる際やカメラで撮影した生のデータはRGBですが、この「色差信号に対して鈍感」という特性から、YUVに変換させることでビット数を減らすことができます。 これを体験できるアプリをGeminiを使って作りました。 YUV3層ビューワ ここに画像ファイルを上げると、YUVそれぞれの層がどのような役割をしているかが直感的にわかります。またこちらのスキップ数というのは、Yで縦×横、Uで縦×横、Vで縦×横とそれぞれ2次元の画素を持っています。これを何個ずつ進むかというものです。 例えばスキップ数が1であればその層は完全な情報です。スキップ数が2だと1つ飛ばして、飛ばしたマスはその前の値で埋められるので、同じ画素値が2つ連続することになります。そうした時の全体のビット数はYが100%、Uが50%、Vが50%となります。つまりビット数は2/3で67%ほどになります。これはYUV 4:2:2と呼ばれる方式と同じです。 YUV 4:2:0と呼ばれる水平・垂直方向にそれぞれ1つ飛ばしていく方式ではYが100%、Uが25%、Vが25%となりビット数は1/2となります。 アプリの方で試してもらうとわかる通り、Yをスキップするとすぐにわかりますが、UとVを少し飛ばしただけでは気づきません。こうして色差信号を減らしていくと圧縮することができます。 ITU-R BT.601というアナログ信号とデジタル信号を相互に変換するための規格があります。これによると、RGBとYUVの関係式は式1のように定義されています。 式1:RGB to YUV 離散コサイン変換(DCT) DCTは厳密には圧縮方法ではなく、圧縮のために必要な処理の1つです。変換のために画像に周波数の考えを導入します。 右のようなのっぺりとした濃淡の変化が少ない画像を低周波な画像、唐草模様や左の濃淡の激しい画像を高周波な画像といいます。自然画では高周波な画像が少なく、高周波成分を削ってしまってもあまり影響を与えません。そこでDCTを行って画像を周波数にしてから高周波成分を削ることで画質にあまり影響を与えずに画像を圧縮できます。 DCTの具体的な手法の前に、フーリエ変換という概念をお話しします。「全ての周期信号は正弦波の合成で表現できる」という考えがあり、これに基づき波形が永遠に続くと仮定して合成元の正弦波を導けます。ざっくりいうとこれがフーリエ変換であり、波形がどの周波数のどのくらいの強度の正弦波で構成されているかがわかるというものです。 DCTの式は式2で示すことができますが、勉強していた当時、これを見てもよくわかりませんでした。 式2:Image to Power DCTはフーリエ変換と似たことをやっており、画像の各層を2次元の波だと考え、ブロック単位で細かく分けた画像を周波数成分に分解します。 例えば8×8マス単位でDCTを行う場合、まず0~7Hzの波形を作ります。 そうすると下記の図のような8つの波形ができます。 図:0~7Hzの離散波形 それをもとに下記の図のような基底関数画像といわれるグレースケールの画像を作成します。これは2つの波の該当する部分を8×8の各マスで掛け算します。 図:基底関数画像(u, v)= (5, 2) このような画像を0~7Hzの8パターンを縦×横の計64パターンを用意します。 これは8×8マス単位でDCTを行うのであればどんな画像に対してでも同じ64パターンの画像を使います。 下記の図のように、生成した64パターンの画像と対象のブロックとの内績を取った値がDCT変換後の画素値となります。 図:DCT変換 DCT変換後の画像はブロック単位(この場合は8×8の画像)になります。分割した数だけDCT画像(係数)があるのでこの状態では圧縮されていません。画像が周波数情報に変わっただけです。 これを体験できるアプリも同様にGeminiを使って作りました。 DCT/IDCT可視化ツール 画像を入力し、クリックして範囲を指定するとその部分に対してDCT係数を計算することができます。出力されたDCT係数に対して全範囲を選択して逆DCTをすることで、元の画像に戻すことができます。当然範囲を限定して逆DCTをかけると圧縮によって元の画像とは少し違う結果となります。出力された表を見るとその画像の局所的なDCT係数がわかりますが、各係数がその周波数の影響を与える大きさだと思っていただけるといいです。ぜひいろんな条件で試してみてください。(逆DCT結果の画像がグレースケールなのはYUVのY成分のみで計算しているためです。) まとめ 動画圧縮の仕組みについてYUVとDCTを用いる部分について簡単なアプリを使って解説しました。YUVを用いることで色差情報を削ることができ、DCTを用いて画像を周波数成分にすることで画質に影響を与えない情報に絞って削ることができることがわかりました。大学で習っている当初はあまり何に使うのか理解できなかったフーリエ変換などの概念も、割と様々な場面で出てくることが多いので、昔の自分にしっかりやっておくよう忠告したいところです。 また私が調べていたときは、出力結果画像の差でみることができるYUVはまだしも、DCTに関しては64パターンの謎の画像(基底関数画像)の意味がずっとよくわからなかったので、今回のアプリで誰かの理解の助けになるとうれしく思います。 余談ですが、最近買った「H.264/AVC教科書」が図も交えてしっかり書かれていて個人的におすすめです。この記事で動画圧縮の仕組み等に興味を持ってくださった方は読んでみてもいいかもしれません。
アバター
こんにちは、iOS エンジニアの @monolithic_adam です。 iOSDC Japan が近づきましたね。今年は新しい会場で楽しみにしています。 #Safie は今年初めてシルバースポンサーとして参加させていただきます! 会場にてセーフィーのメンバーを見かけたら、ぜひ声をかけてください。 iOSDC Japan 2025参加情報 ノベルティー パンフレット クラウド録画サービス「Safie」について Our App Safie Viewer(セーフィー ビューアー) 最後に We are hiring! iOSDC Japan 2025参加情報 ノベルティー セーフィーオリジナルのアンブレラマーカーです。 ノベルティー付きチケットの方にはお届けされるはずなので、ご活用ください! パンフレット iOSDCブック内のパンフレットにも、以下の内容を掲載させてもらっています。 是非ともご覧ください! クラウド録画サービス「Safie」について 今年スポンサーとして初参加ということもあり、Safie(セーフィー)というサービスについてご存じない方ばかりかと思います。 この場で簡単にSafieについてご紹介させてください。 Safieのサービスについて 一言で言うと、カメラの映像をクラウド化するサービスで、iOSアプリとしてはカメラを操作したり、映像を閲覧するといった機能を提供しています。 Our App ということで、次にiOSアプリについて紹介させてください! Safie Viewer(セーフィー ビューアー) アプリは こちら からダウンロード可能 デモ機能により、無料・アカウントなしで体験可能です #SafieViewer ではいくつか特徴的な機能を提供する必要があり、 動画の再生 WebRTC / HLSのハイブリッド動画配信に対応 イベントや録画有無を表示するためのリッチなシークバー 広角撮影して歪んだ動画を3D空間で補正 参考: セーフィーの新製品「Safie Go 360」のAndroid実装 - Safie Engineers' Blog! トークバック機能 アプリから音声を入力、 WebSocket を経由してカメラから音声を再生 といった技術的にも面白い部分が色々とあります。 最後に 今年は新しい会場ですし、セーフィーも初スポンサーで色々とワクワクしています! 会場でセーフィーくんのTシャツを着ている人を見かけたら、是非ともお話ししましょう! 最高にiOSDCを盛り上げていきましょう!! ※ iOSDCに関しての最新情報は公式サイトや各イベントページをご確認ください 他社様と合同で非公式のアフターイベントもやります! yumemi.connpass.com We are hiring! モバイルチームでは、多様な環境で世界に向けたアプリをともに開発する仲間を募集しています! open.talentio.com
アバター
はじめに こんにちは、データドリブン推進室でデータエンジニアをやっている鶴です! 先日、 OSS BIツールについてのブログ記事 を同じチームの小宮が投稿しておりましたが、その中でご紹介していた「Lightdash」でカスタムチャートという機能があります。 個人的に気になっていた機能だったので実際に触ってみてどのような感じで使えるのか、グラフはどんな感じになるのかご紹介したいと思います! はじめに Lightdashのカスタムチャートとは カスタムチャートを触ってみる 最後に Lightdashのカスタムチャートとは Lightdashには 公式ドキュメント に記載があるように標準でさまざまなチャートを使うことができます。 2025/06時点では以下の10個のチャートがあり、普通に使う分には困らない感じです。 表 (Table) 円グラフ (Pie chart) ファネルチャート (Funnel chart) 棒グラフ (Bar chart) 面グラフ (Area chart) 折れ線グラフ (Line chart) 横棒グラフ (Horizontal bar chart) 散布図 (Scatter chart) 複合グラフ (Mixed chart) 数字表示 (Big Value) 参考:積み上げ棒グラフのイメージ 更にLightdashではビジュアライゼーションの表現の幅を上げる機能として カスタムチャート 機能があります。 この機能は Vega‑Lite をベースとした高度なビジュアライゼーション機能で、Lightdash上で標準グラフではできないようなグラフスタイルや細かい設定をJSONベースで作成できます。 (なお、こちらの機能は公式ドキュメントに記載があるようにまだベータ版となっておりますのでご注意ください) 使い方としてはとても簡単で以下のようにしていくと使えます。 「Query from tables」で対象テーブルを開く 対象ディメンションとメトリクスを選択し、Chartの「Configure」をクリック チャート設定の「Chart type」のリストの中にある「Custom」をクリック JSON編集画面が出てきます(簡単に編集できますね!) またこのカスタムチャート機能ですが最近の アップデート でテンプレート機能が搭載され、より触りやすくなりました! 今回は気になったいくつかのチャートを試しに作ってみてどんなグラフができるのか試してみます! カスタムチャートを触ってみる 最近実装されたテンプレートはカスタムチャートを開いた時に表示される「+Insert template」から選ぶことができるようです。 テンプレートをクリックするとJSONコードが生成され、自動的に集計対象がマッピングされる感じになってます。 このfieldで利用されている項目はResultsの下にあるSQLで自動生成されたSQLの項目名を利用しているようです。 なお、利用する項目によってうまく表示されなかったりするのでその場合は編集して調整して利用しましょう。 それでは気になっていたグラフをそれぞれ見ていきたいと思います! 棒グラフ (Bar chart) テンプレートを利用して適当に作成したサンプルデータの商品カテゴリと売上を使って棒グラフを選んでみました。 テンプレートを使うことでワンクリックで棒グラフが作られました! 当たり前ではありますが見た目は標準の棒グラフと変わらない感じですね。 ヒートマップ 会員ランクと地域の会員平均年齢を使ってテンプレートを使ってみましたがうまく項目が選ばれなかったため手動で編集し作成してみました。 現在ヒートマップは標準グラフにはなく、カスタムチャートのみの機能になるためこちらを使うことになりそうですね。 バブルチャート 商品カテゴリと売上、平均単価、平均顧客年齢を使い散布図のバブルチャートを作成してみました。 軸の scale プロパティで年齢のスケールを30歳以上にすることで見やすくしています。 おそらく標準の散布図ではサイズオプションがなかったためバブルチャートは作れないと思われますので利用したい方はこちらを使うことになるかなと思います。 分散積み上げ棒グラフ(人口ピラミッド) 次はテンプレートにないものを作ってみます。 vega-liteのexampleを眺めていて気になった 人口ピラミッド です。 サンプルコードを見よう見まねで作ってみたところいけました…! こういった手の込んだグラフはBIツールで作る経験がなかったので作れるんだなと感動しちゃいました。。。 こういったチャートが作れるのはメリットですね。 Tableauのリファレンスライン的な平均ライン 最後に棒グラフ上に平均ラインを 表示 させるexampleも試してみましたが苦戦しつつも表示できました。 なんだかんだ使うことありそうなラインです。 コードの工夫の仕方によっては目標値等のラインを設定できるのではと思います。 最後に 気になっていたカスタムチャートのいくつかのグラフや機能を触ってみました。 Lightdashはまだまだ成長の段階で他のBIと比べてビジュアライゼーションの面で実現できないことがあったりしますが、このカスタムチャート機能を使うことで痒いところに手が届くいい機能だなと思います。 しかしながらUIでぽちぽちっとグラフを作るようなBIツールの本来の操作と比べたらやはり難しい部分もあり、JSONコードを編集して作るのは苦労する面もありますのでChatGPT先生等にご教示いただきながら作ってみるといいかもしれません。 公式サイトにはサンプルコードがあるので流用できる部分も多いと思います。 またこのLightdashですが2025年6月現在でも高頻度で アップデート が行われており、今後も機能がさらに充実していくと思いますし、自分自身もかなり期待しています! Lightdashのチャート機能が気になっている方々の参考になれば幸いです!
アバター