TECH PLAY

BASE株式会社

BASE株式会社 の技術ブログ

576

この記事はBASEアドベントカレンダー 2025 の 6 日目の記事です。 エンジニアの右京です。BASE では今年、表示速度の改善を目標にすべてのショップページへ Cloudflare を導入しました。これは、その過程や技術面の簡単な解説です。 記事は前後半になっており、この記事は前半で、Cloudflare を導入〜直後までの話題となります。 モチベーション ショップページの表示が遅いことに尽きます。サービスが大きくなり、機能が増えていく中で処理が増え、速度が犠牲になってしまうのはある程度は仕方ないことだとは思います。とはいえレスポンスを返し始めるまでに 1 秒以上かかるようなケースもザラにあり、そこにアクセスのスパイクが重なると 10 秒以上返ってこない、オートスケーリングや手動でのスケーリングが都度必要… と、成り立ってはいるものの「良い」とは言えない状態でした。 一方でオーナーが利用する管理画面とは異なり、ショップページは在庫などの一部のデータを除けば、利用者によって変わる表示も極一部で、ほとんど静的サイトのような作りになっています。そこで、Edge Worker でのコンテンツのキャッシュがスピード面でもインフラ面でも効果が期待できるだろうということで Cloudflare の導入検討を始めました。 vs CloudFront BASE は基本的に AWS に乗っかって動いているので、 Cloudflare の特に Workers への対抗馬として CloudFront + Lambda@Edge / Functions があります。今回検討していた時点では技術面では以下の点を考慮して、採用を見送りました: 独自ドメインの証明書の問題 CloudFront をショップページとして扱う場合、証明書を CloudFront に配置する必要がある 具体的な数値は出せないが、現状のドメインをすべてカバーするためには複数のディストリビューションを管理する必要があり、現実的ではない コンテンツをキャッシュすることを前提とした設計 CDN なので当たり前といえばそうだが、あくまでキャッシュされているコンテンツに対する操作という印象 BASE では特定の会員のみが利用できるシークレット EC 機能を同じ仕組みの上で提供しているので、キャッシュ前提となるのが扱いづらい KV やストレージの自由度 コンテンツのキャッシュ以外にも何かしらのメタ情報はストアできる必要があるだろうという前提があった CloudFront KeyValueStore があるものの、Edge Worker からは読み取り専用 Cloudflare の Workers KV と比べるとどうしても取り回しが難しいように感じた 現在ではどうかというと、AWS 側でもこれらを解決するようなソリューションが発表されており、状況が変わっていることに注意が必要です。 aws.amazon.com Cloudflare を導入する 当然ですが、 Cloudflare が BASE のアプリケーション(Origin と呼ぶ)よりもエンドユーザーに近い位置で動作する必要があります。そのため、これまで Internet → Origin だった経路を、 Internet → Cloudflare → Origin に変更する必要があります。ここで問題になるのがショップページのドメインです。 ショップページのドメインには 2 つのパターンがあります: BASE の管理ドメインのサブドメイン base.shop / base.ec / theshop.jp のようなドメインを BASE が管理 これのサブドメインとして、例えば example.base.shop でショップページを配信 オーナーの持ち込み独自ドメイン 独自ドメイン App で CNAME を利用して任意のドメインでショップページを配信 前者の場合は特に問題はなく、経路変更を行うだけで済みます。詳細な内容はそれぞれの都合で異なると思うので割愛しますが、Origin に Cloudflare からアクセスされるサブドメインを新たに用意しておき、DNS 設定を切り替えることで経路が次のように変更されます: [導入以前] Internet ──▶ example.base.shop(Origin) [切替後] Internet ──▶ example.base.shop(Cloudflare) ──▶ from-cloudflare.base.shop(Origin) from-cloudflare の部分をユーザーが作ったり上書きできないようにしておく必要はありますが、大した問題ではないでしょう。このタイプのドメインは特にメンテナンスを必要とすることなく、無停止で移行していきました。 問題は後者のオーナーの持ち込みドメインです。前述のように CNAME で管理されており、オーナーが設定した DNS では CNAME cname.thebase.in となっています。Cloudflare を通すという理由でこれをすべてのオーナーに変更してもらうのは現実的ではないので、なんらかの方法で設定を維持したままドメインが Cloudflare へ解決される必要があります。ここで登場するのが SSL for SaaS です。 Cloudflare SSL for SaaS developers.cloudflare.com qiita.com ドキュメントの説明にもある通り、カスタムドメインをサポートする機能です。簡単に言ってしまうと、 持ち込みドメインをBASE 管理下にあるドメインと同様に from-cloudflare.* へ転送する機能です。 developers.cloudflare.com Custom Hostname を作成し、 SSL 証明書が発行された状態で cname.thebase.in が Cloudflare を向くようになると、持ち込みドメインが Cloudflare を通過してから Origin へ到達するようになります。 この切り替えは停止メンテナンスで行ったのですが、メンテナンス中にすべてのアクティブな独自ドメインを Custom Hostname として登録し、証明書の発行を終えるのは現実的ではなかったため、事前に Pre-validation という仕組みを使って移行の準備を進めていました。 developers.cloudflare.com Pre-validation を使うと、現行のアプリケーションを稼働させたまま Cloudflare 側に SSL 証明書を配置しておくことができます。BASE では HTTP Tokens の方を使用していて、Custom Hostname を作成すると Cloudflare の Dashboard もしくは API から検証用の http_url と http_body を得ることができます。 { " result ": [ { " id ": " 24c8c68e-bec2-49b6-868e-f06373780630 ", " hostname ": " app.example.com ", // ... " ownership_verification_http ": { " http_url ": " http://app.example.com/.well-known/cf-custom-hostname-challenge/24c8c68e-bec2-49b6-868e-f06373780630 ", " http_body ": " 48b409f6-c886-406b-8cbc-0fbf59983555 " } , " created_at ": " 2020-03-04T20:06:04.117122Z " } ] } https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-validation/pre-validation/ より引用 ドキュメントでは ownership_verification_http というフィールドでそれが返ってきていますが、このフィールドは少し時間が経過すると使用することができず、そのタイミングまでにレスポンスを準備できない場合は ssl フィールドに含まれる http_url と http_body を使う必要がありました。 { " result ": { " ssl ": { " status ": " pending_validation ", " http_url ": " http://app.example.com/.well-known/acme-challenge/uVKCkPGJZt2PewfPPQxSRe8QTDDyq_DzOLZ4AK5T1Vg ", " http_body ": " uVKCkPGJZt2PewfPPQxSRe8QTDDyq_DzOLZ4AK5T1Vg.LNFwUG0womdgXgxKtKU4B6bqUXvBkIouc5BNejjQTh0 " , }, } } 定期的にこの URL に Cloudflare からアクセスがあり、 http_body の内容を返すことができれば検証に成功し、Custom Hostname が有効になって SSL 証明書が配置されます。簡単に図にすると以下のようになり、一時的に SSL 証明書が 2 つになります: [Origin] app.example.com [Internet] ────────────────▶ 元々ある SSL 証明書 ◀──────────────── アプリケーションの動作 create apps.example.com ◀──────────────── ドメインの登録や更新をトリガーに作成 [Cloudflare] /.well-known/acme-challenge/uVK... ────────────────▶ ◀──────────────── uVK.... apps.example.com の SSL 証明書が事前に発行される 移行準備中 ──────────────────────────────────────────────────────────────────────────── 切り替え後 [Internet] [Origin] │ app.example.com 元々あった SSL 証明書は不要に │ │ ▼ from-cloudflare.* [Cloudflare] ────────────────▶ アプリケーションの動作 SSL証明書 切り替えメンテナンスの事前準備として、すべてのドメインを事前に Cloudflare に登録、 SSL 証明書が発行された状態にしておき、実際のメンテナンスでは NS の切り替えのみにすることで、比較的短い時間での切り替えが完了しました。 また、これ以降は SSL 証明書の管理を Cloudflare が行ってくれるようになります。自前での更新が不要になるので、これも利点の一つと言えるでしょう。 切り替え直後のトラブル 過去の動作との不整合で一部個別対応が必要なケースはあったものの、特に大きな問題はなく切り替えを終えることができました。ただ、少し想定外だったことが 2 つあったので、それを書いてこの記事は締めようと思います。 Cloudflare を通った時点でデフォルトのキャッシュが動作する 何も設定をしていない場合、一般的にキャッシュできるとみなされるアセットのキャッシュが自動的に始まります。デフォルトの挙動は以下で確認することができます: developers.cloudflare.com 殆どの場合は困らないと思いますが、動的に JS を作成したり、ビルド済み JS をアプリケーションから配信している場合は注意が必要です。影響は軽微だったものの一部動的に生成されているものがあり、これが原因で不具合が発生しました。 この設定は Cache Rules を作成することで上書きすることができます。切替時はすべてを Bypass する設定にしておくのが無難に思いました。 developers.cloudflare.com O2O 管理している Cloudflare より前に別の Cloudflare がいる状態です。Cloudflare のアイコンがオレンジなので Orange-to-Orange というらしいです、可愛いですね。 developers.cloudflare.com この状態が存在することを認識していないと、「キャッシュをしていないはずなのに Cloudflare がキャッシュを返している」という状態になったときに混乱します、しました。 これは持ち込まれるドメインの DNS が Cloudflare の場合に起こります。CNAME を設定する際に自身の Cloudflare でも Proxy をするという設定があり、これを使うとオーナー側の Cloudflare でコンテンツをキャッシュできるようになります。こうなると、こちらが管理できる範囲よりユーザーに近い場所でキャッシュが起こってしまい、基本的には手が出せない状態になってしまうので、個別でなにかしらの解決をする必要があります。 おわりに 明日は続けて Cloudflare Workers でのコンテンツのキャッシュについて書きます。よろしくお願いします!
アバター
はじめに この記事はBASE Advent Calendar 2025の5日目の記事です。 devblog.thebase.in こんにちは!Pay IDのEngineering Sectionでエンジニアリングマネージャーを務めている岡部( @rerenote )です。今回はPay ID…ではなく、社内の有志で活動している iikanji-conference-toudanチームによる「技術イベント・カンファレンスのスポンサー活動」について、今年の取り組みをまとめてご紹介します。 iikanji-conference-toudanチームとは? iikanji-conference-toudanチームは技術イベント・カンファレンスへBASEから登壇する人たちを応援するために立ち上げられました。社内の有志メンバーで構成されています。 登壇資料のレビュー相談をはじめ、こういう技術イベントがあったよ、こういう発表がおもしろかったよなどのカジュアルトーク、スポンサーブース出展時にはブース企画なども行なっています。 2025年のスポンサー活動一覧 「登壇するメンバーをもっと後押ししたい!」という思いから、技術イベント・カンファレンスへのスポンサー協賛活動に取り組みました。協賛活動を通してBASEメンバーのトークを見つけてもらうきっかけ作りにもなっています。 協賛したのはBASEで採用しているPHP、TypeScriptのカンファレンス。今年はこの2つの技術領域でコミュニティとの繋がりを深める一年になりました。カンファレンス運営のみなさま、参加者のみなさま、このような場をいただき本当にありがとうございました。 各イベントの詳細は、以下のレポートにまとめています。登壇者コメントや参加メンバーによるレポート、ブース企画についての内容もありますので読んでいただけたら嬉しいです。 PHPerKaigi 2025(3/21-3/23) devblog.thebase.in PHPカンファレンス小田原 2025(4/12) devblog.thebase.in TSKaigi 2025(5/23-5/24) devblog.thebase.in PHP Conference Japan 2025(6/28) devblog.thebase.in おわりに 私は過去に個人で勉強会を主催したり、技術イベントやカンファレンスのスタッフとして数年活動していた背景があり、技術コミュニティやカンファレンスという場そのものがとても好きです。iikanji-conference-toudan に参加している一番の理由は、そうした好きな場所に、少しでも貢献できたら嬉しいと思っていることが大きいのかもしれません。 BASEでは会社全体でOSSやコミュニティを応援する文化があり、このような活動を行えることにいつも感謝しています。 2026年もイベント・カンファレンスでの登壇を応援したり、スポンサー活動を通してコミュニティを盛り上げていければと思っておりますので、どうぞよろしくお願いいたします。 プロダクト開発も好きだけど技術コミュニティも好き!という方でBASEに興味を持っていただいた方は、エンジニア募集中ですので採用情報もぜひ覗いてみてください! binc.jp 明日のBASEアドベントカレンダーは @yaakaito さんの記事が登場する予定です!お楽しみに!
アバター
はじめに この記事はBASEアドベントカレンダーの4日目の記事です。 devblog.thebase.in EC作成サービスBASEのプロダクト開発チームでエンジニアリングマネージャー(EM)をしている @tanden です。 私たちのチームではこの1年ほど、開発組織のケイパビリティをどう可視化し、継続的に改善していくかについて考え方の整理と運用に取り組んできました。「今の組織はどこが強みで、どこに伸びしろがあるのか?」を共通の視点で語れるようにするため、SPACEのようなフレームワークにヒントを得ながら、組織を立体的に捉えるための「補助線」を引くことを目指しました。 この記事では、私たちが整理した「開発組織のケイパビリティ可視化」のコンセプトと運用方法について紹介します。まだ取り組みの途中ですが、組織運営のヒントになれば幸いです。 ケイパビリティ可視化の取り組み振り返り EC作成サービス BASE のプロダクト開発組織ではこれまで、Four Keys を開発チームのケイパビリティ指標として捉え、Google Apps Script などを用いてプルリクエストのマージ数やリードタイムを計測し、改善につなげてきました。 マージ数やリードタイムは今も継続して追いかけている重要な指標で、計測と振り返りをセットで運用することで一定の成果を得られています。 一方で、複雑さが増すプロダクト開発・運用の実態を捉え、組織として継続的に改善サイクルを回していくには、これらの指標だけでは不十分ではないか——そんな考えが徐々に生まれていきました(課題感に共感いただける方もいるのではないでしょうか)。 そんな中で、これまでの取り組みを振り返りから、主に以下の3点が課題として挙がりました。 組織としての方向性や全体像が曖昧だった 本来であれば「どんな組織を目指すのか」という前提に沿って指標を選ぶべきでしたが、その背景や全体像を描き切れていませんでした。 プルリクエストの指標だけでは複雑な開発を捉えきれない マージ数やリードタイムは重要ですが、プロダクト開発を多面的に理解し、改善サイクルを回すには要素がやや不足していました。 一定の改善ラインを越えると伸びしろが見えづらくなる プルリクエスト関連の指標は、ある程度最適化されるとそれ以上の改善余地が小さくなり、チームの状態把握はできても、次のアクションにつながりにくくなっていました。 ケイパビリティ可視化のコンセプトと目的 そこで私たちは、これまでの反省を踏まえつつ、開発組織のケイパビリティ可視化の枠組みづくりに取り組むことにしました。 「汎用的な生産性や開発力指標は存在しない」という前提のもと、上記3つの課題を反転させるため、以下のコンセプトのもと進めました。 個別指標の妥当性よりも、開発組織の能力の全体像と方向性を描いてから指標の位置づけを明らかにする 複数指標を利用して組織の能力や状態を多面的に測れるようにし、定期的に計測指標を入れ替えることで改善のきっかけを提供し続ける 指標を達成できるかどうかよりも、改善後の組織やチーム・個人の理想状態をイメージできるかどうかを重視する 上のコンセプトを満たしつつ、対話を通じた未来へのアクションプラン作りと改善の実行・計測のサイクルを回すこと目的に、ケイパビリティ可視化の取り組みを進めました。 『サーベイフィードバック入門 p.28』(中原淳著)を参考に作成 開発組織の4つのケイパビリティ 開発組織のケイパビリティ可視化を進めるために、まず開発組織のあるべき姿を描いていく必要があります。開発組織のあるべき姿を描くために、この取り組みの中では Evidence Based Management(EBM) という考え方を参考に、全社やプロダクト開発組織において定義されているミッション・ビジョン・バリューと整合させる形で、開発組織のケイパビリティを4つの分野に整理しました。 サービス価値の維持 ユーザーが今現在価値を感じて利用しているサービス上の機能提供を維持し続けること。 全社におけるミッションやビジョンとの整合性 「人生のオーナーを増やす社会基盤」(基盤=いつ・いかなる状況でも利用できる信頼性が高いもの) プロダクト開発組織のミッションやビジョンとの整合性 「ショップが成長していくことを支えるサービスであり続ける」 「トラフィックを適切に受け止めて、決済を無事に完了させる」 素早い価値提供 新しい価値を提供するまでに必要な時間を限りなく短くすること。 全社におけるミッションやビジョンとの整合性 価値提供スピードについての言及はないが、スタートアップとしてのスピード感で価値提供・価値創出を行い、社会基盤の構築を目指すことは暗黙的な前提 プロダクト開発組織のミッションやビジョンとの整合性 ハイスループットなプロダクト開発組織を目指す 新しい価値の実現 まだ実現できていない価値(機能や体験)をテクノロジーの力で実現すること。 全社におけるミッションやビジョンとの整合性 「あたらしい決済で、あなたらしい経済を」 プロダクト開発組織のミッションやビジョンとの整合性 「多様なニーズに応える機能改善をし続ける」 「サービスの成長にチャレンジしていく」 参考として、BASEグループとプロダクト開発組織のMissionやVision、Foundationがまとまっている会社紹介資料を掲載させていただきます。 手前味噌ですが素敵なMission / Vision / Foundationなのでご覧いただけると嬉しいです。 speakerdeck.com speakerdeck.com 組織・ワークエンゲージメント 組織体制(組織)やワークエンゲージメントは上の3つのケイパビリティを支える土台として位置づけます。仮に上の3つのケイパビリティを高いレベルで実現できるスキルや経験を有していたとしても、ネガティブな雰囲気で溢れ疲弊した組織では、もてる力を十分に発揮することはできません。 プロダクト開発に直接関わるケイパビリティだけでなく、組織に関する指標やワークエンゲージメントの可視化と改善も目指しています。 組織における実際の運用 4つのケイパビリティ分野における理想像(未来づくり)を起点として、可視化と対話の流れを作るために、組織が日々運用しているOKRと結びつけることをまず目指しました。 開発組織として達成したい目標(Objective)がどのケイパビリティ領域に紐づいているのかを明確にすることで、以下のつながりを意識しやすくなります。 いま自分たちは組織として何を伸ばそうとしているのか / どんな課題があるのか その施策をやる理由は何なのか KPIが示す変化はどの能力の成長を意味しているのか 事業目標とOKR(施策含む)、ケイパビリティ領域のマッピングは、以下の画像のようなイメージになります。 このように事業目標、OKR、ケイパビリティを重ね合わせることで、それらが一本の線でつながり、チームの前進をより的確に捉えられるようになります。 実際にやってみてどうだったのか 実際に運用を始めてみると、上記以外のメリットや取り組みの難しさもでてきました。ここでは簡単にご紹介できるものに限りますが、いくつか共有させてください。 施策の偏りに気づける 大規模なプロダクトを日々運用する上で、システムのパフォーマンス改善や利用パッケージのアップデートなど、今あるシステムを維持するだけでもやるべきことは山積みです。EC作成サービスBASEの運用においても同様で、「サービス価値の維持」分野の施策が多くなりがちでした。一方で、そこばかりに力を割いてしまうと、Four Keys計測の取り組みが後回しになるなどの弊害が生じます。 そのため、OKR施策を検討する際には、まず1年間の最重要領域を決め、その領域に優先的に施策の枠を確保し、残りを他の領域に割り当てるようにしています。 ちなみにFY2025では「素早い価値提供」分野を最重要領域と定めて取り組みを進めてきました。詳細については、12月8日のアドベントカレンダーでEMの @takashima から共有させて頂く予定です。 「新しい価値の実現」分野は難しい 「新しい価値の実現」分野は、定義にある通り「まだ実現できていない価値(機能や体験)をテクノロジーの力で実現すること」を目指すことになります。この分野は、普段の開発とは異なる技術スタックやそれらを使ったUI/UXの検証など、開発研究・R&Dの要素を含みます。成果が不確実な試行錯誤が必要であり、難易度も高いため、どうしても後回しになってしまっているのが現状です。 とはいえ、AI活用をはじめ、やるべきことはたくさんあります。プロダクト開発組織として引き続き取り組んでいきたいテーマです。 おわりに プロダクト開発組織のケイパビリティ可視化の取り組みについて紹介しました。4 つのケイパビリティ領域を定義し、それらを OKR と結びつけることで、組織として何を伸ばそうとしているのか、施策の意図や成果がどの能力に紐づくのかをより明確に捉えられるようになったのではないかと感じています。開発組織の目標管理や成長を考えるための新しい「補助線」として、読者の方の参考になれば幸いです。 まだ道半ばではありますが、これからも組織の未来づくりと可視化、そして対話のサイクルを重ねながら、プロダクトと開発組織の継続的な成長を目指していきたいと考えています。 BASEでは、今後のプロダクト成長を支える技術戦略や開発基盤の構築をリードしていただけるテックリード候補を募集しています。 ご興味があれば、ぜひ採用情報をご覧ください。 open.talentio.com 明日のBASEアドベントカレンダーは @rerenoteさんからの記事です。お楽しみに!
アバター
はじめに この記事は🎄🎅 BASE PRODUCT TEAM BLOG Advent Calendar 2025 🎅🎄の3日目の記事です。 devblog.thebase.in こんにちは! BASE 株式会社 Pay ID 兼 BASE PRODUCT TEAM BLOG 編集局メンバー の @zan_sakurai です。 私の所属する Pay ID では一部のアプリケーションでGoを採用しており、日々Goらしいコードを書くことを意識して開発を行っています。 読者のみなさまは「Goらしさ」という言葉を聞いたことがある、もしくは使ったことはありますか...? 私も日々の開発シーンで聞いたことも使ったこともありますが、実際に「Goらしさとは何か?」と問われると、私も正直言葉に詰まってしまいます...。 とはいえ「Goらしさ」とは曖昧なままではあるのもよろしくないので、 本記事では一旦「Goらしさ」/「Goらしいコード」とは、Goの言語仕様だけでなく、Goの設計思想や慣習に沿ったコードを指すこととして、 Go の特徴の一つである interface を題材に、今回は「Goらしい」 interface の書き方について掘り下げてみたいと思います。 「Goらしい」 interface を書く Go の interface の特徴は多岐にわたりますが、 今回は Go Wiki: Go Code Review Comments#Interfaces に記載されている内容を掘り下げていこうと思います。 具体的なコード例はGo Code Review Commentsがとても良くまとまっているので、そちらもぜひ御覧ください。 ステップ1: interface が本当に必要になるまで書かないのが「Goらしい」 Go Wiki: Go Code Review Comments の Interfaces の章には以下のように記されています。 Do not define interfaces before they are used: without a realistic example of usage, it is too difficult to see whether an interface is even necessary, let alone what methods it ought to contain. 引用元: Go Wiki: Go Code Review Comments#Interfaces 端的にまとめてしまうと必要性が出てきたらinterfaceを定義せよ、という旨です。 私のようなJavaなどのOOP言語からGoに来た人は、最初に抽象型を定義してから具体的な実装を作る傾向があるかもしれませんが、 Goでは具体的な実装を行ってから必要性が出てきた時に初めてinterfaceを定義するのが「Goらしい」書き方のようです。 過度な抽象化による複雑化、いわゆる「インターフェース汚染」などと巷では呼ばれていますが、このようなことを避けるために、interfaceを書くタイミングに慎重になることが推奨されているようです。 Go Code Review Comments の例を参考に、ステップ1を踏まえたコードを書いてみました。 package consumer import "interfaceidioms/step1/producer" // 何らかの処理を行う構造体 // producerパッケージのThingerを内部に持つ type ThingerConsumer struct { t producer.Thinger } // 何らかの処理を行うメソッド func (tc ThingerConsumer) DoSomething(input producer.Input) bool { return tc.t.Thing(input) } // いわゆるファクトリ関数 // consumer.NewThingerConsumer(producer.NewThinger()) のような使われ方が想定される. func NewThingerConsumer(t producer.Thinger) ThingerConsumer { return ThingerConsumer{t: t} } package producer // 何らかの入力データを表す構造体 type Input struct { Content string } // 何らかの処理を行う構造体 type Thinger struct { // snip... } // 何らかの処理を行うメソッド func (t Thinger) Thing(input Input) bool { return input.Content == "" } // いわゆるファクトリ関数 func NewThinger() Thinger { return Thinger{} } 特に何の変哲もない?コードですが、ステップ1を踏まえたコードになっています。 「Goらしい」interfaceを書く上での最初のステップは、 本当にinterfaceが必要になるまで書かないこと です。 ステップ2: 消費する側に interface を定義すると 「Goらしい」 ステップ1で 本当にinterfaceが必要になるまで書かないこと を述べましたが、実際にinterfaceを書く必要性が出てきた場合、どう書くと「Goらしい」のでしょうか? またまた Go Wiki: Go Code Review Comments の Interfaces の章からの引用ですが、以下のように記されています。 Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values. The implementing package should return concrete (usually pointer or struct) types: that way, new methods can be added to implementations without requiring extensive refactoring. 引用元: Go Wiki: Go Code Review Comments#Interfaces これも端的にまとめてしまうと、interfaceは実装を提供する側ではなく、消費する側のpackageに定義すべき、という旨が記載されています。 この点も私のようなJavaなどのOOP言語からGoに来た人は、実装を提供する側でinterfaceを宣言したくなるかもしれませんが、 Goでは消費する側でinterfaceを定義するのが「Goらしい」書き方のようです。 Go では明示的にimplementsを宣言せず、Duck Typing的に暗黙的にinterfaceを満たすので、 ステップ1で直接呼びだしている箇所も後からinterfaceに置き換えるリファクタリングは容易です。 また、消費する側が使うメソッドだけをinterfaceに含めば良いので、小さなinterfaceを定義できます。(いわゆるインターフェース分離の原則。) 小さなinterfaceですので、テスト時に必要な振る舞いだけを持つinterfaceを満たすモック実装を用意するのも容易です。 Go Code Review Comments の例を参考に、ステップ2を踏まえたコードを書いてみました。 package step2goodconsumer import "interfaceidioms/step1/producer" // step1で使ったproducerパッケージの変更はなく、そのままstep2goodconsumer側でinterfaceを定義できる. // Thinger interface を定義 // これがいわゆる消費者側のinterface. type Thinger interface { Thing(input producer.Input) bool } // 何らかの処理を行う構造体 // producerパッケージのThingerを内部に持つ type ThingerConsumer struct { // interface型を使うように変更 t Thinger } // 何らかの処理を行うメソッド func (tc ThingerConsumer) DoSomething(input producer.Input) bool { return tc.t.Thing(input) } // いわゆるファクトリ関数 // DIなりでよしなに入れ替えよう. func NewThingerConsumer(t producer.Thinger) ThingerConsumer { return ThingerConsumer{t: t} } 実際のstep1との差分も少なく、step2goodconsumer側の判断でproducerの変更なく、容易に interface を使った書き方にリファクタリングできることがわかります。 $ diff -u --label "step1/consumer.go" --label "step2/consumer.go" \\ step1/consumer/consumer.go step2goodconsumer/consumer.go --- step1/consumer.go +++ step2/consumer.go @@ -1,11 +1,18 @@ -package consumer +package step2goodconsumer -import "interfaceidioms/step1/producer" +import "interfaceidioms/step1/producer" // step1で使ったproducerパッケージの変更はなく、そのままstep2goodconsumer側でinterfaceを定義できる. + +// Thinger interface を定義 +// これがいわゆる消費者側のinterface. +type Thinger interface { + Thing(input producer.Input) bool +} // 何らかの処理を行う構造体 // producerパッケージのThingerを内部に持つ type ThingerConsumer struct { - t producer.Thinger + // interface型を使うように変更 + t Thinger } // 何らかの処理を行うメソッド @@ -14,7 +21,7 @@ } // いわゆるファクトリ関数 -// consumer.NewThingerConsumer(producer.NewThinger()) のような使われ方が想定される. +// DIなりでよしなに入れ替えよう. func NewThingerConsumer(t producer.Thinger) ThingerConsumer { return ThingerConsumer{t: t} } 「Goらしい」interfaceを書く上での次のステップは、 消費する側に interface を定義する です。 番外編: Accept interfaces, return structs / Accept Interfaces, Return Concrete Types Accept interfaces, return structs という言葉を聞いたことはありますか? いわゆる interfaceを受け入れ、具体的な型を返す、というidiomです。 この際に改めて原典を探ってみましたが、詳しく言及しているようなものはあまりないように見受けられました。 もし原典をご存知の方がいらっしゃいましたら、ぜひ教えてください。(以下触れている箇所) https://go-proverbs.github.io/ https://github.com/go-proverbs/go-proverbs.github.io/issues/37 https://github.com/google/styleguide/blob/gh-pages/go/decisions.md ステップ1とステップ2を踏まえた上で、ですとproducer側でinterfaceを定義するケースはまだないので、自ずと Accept interfaces, return structs になるのかと思います。 余談 今回はあえて、producer側で定義するinterfaceについては触れませんでした。 実際に https://github.com/golang/go で標準ライブラリのコードを見てみると、producer側でinterfaceを提供しているケースも多々あります。 続編を書こうと思いますので、ご期待いただけますと幸いです。 さいごに 最後に改めて「Goらしい」 interface を書くステップをまとめます。 本当にinterfaceが必要になるまで書かないこと 消費する側に interface を定義する 読者のみなさまが「Goらしさ」に触れるきっかけの一助になれば幸いです。 参考資料 Go Wiki: Go Code Review Comments Effective Go https://go-proverbs.github.io/ https://github.com/go-proverbs/go-proverbs.github.io/issues/37 https://github.com/google/styleguide/blob/gh-pages/go/decisions.md 宣伝 Pay ID ではエンジニアを募集中です!ご興味があれば採用情報もぜひご覧ください! open.talentio.com 明日は、BASEアドベントカレンダーは @tanden さんの記事です。お楽しみに!
アバター
はじめに この記事はBASEアドベントカレンダーの2日目の記事です。 devblog.thebase.in こんにちは、 BASE Feature Dev1 Group で PHPer をしている @meihei です。今日は Gopher です。 この記事では、外部サービスの Webhook を AWS Lambda (Function URLs) で受け取り、SQS にいれる設計と実装、そして、それら全体が正常に稼働しているかを監視するやり方について書きます。 1. 前提とアーキテクチャ 前提として BASE が連携する外部サービスでイベントが発生した際、その通知を Webhook 経由で受け取り、必要なユースケースを後続ワーカーが実行できるようにつなぐ仕組みを設計します。 技術要件 外部サービスの中には EventBridge の Partner Event Source を利用して直接イベントを受信できるものもあります。しかし、今回の対象サービスは EventBridge 連携に対応していないため Webhook を利用しています。Webhook の正当性については、署名ベースの検証によって確認しています。 また、Webhook を受信するエンドポイントは BASE の PHP アプリケーションサーバーでは処理せず、サーバーレス環境(Lambda)で受信する方針としています。後続のワーカーは、既存のコンテナ基盤上で稼働する PHP プロセスによって実行されます。 ビジネス要件 今回は、BASE から外部サービスへ API 経由で商品連携を行った後に、商品審査ステータスの変更が発生し、その審査ステータスを受け取って BASE 側の連携ステータスを更新するユースケースについて解説します。 ここで求められるビジネス要件は以下のとおりです。 許容遅延 :リアルタイム性は必須ではありませんが、できる限り早く反映されることが望ましい。 処理漏れへの対応 :処理漏れは設計上許容せず、万が一発生した場合は必ず SQS Dead Letter Queue (以下、DLQ)に退避させ、後続の運用フローで確実に回収できるように。 二重通知への対応 :外部サービスから同一イベントが複数回送られたとしても、後続ワーカー側で冪等性を担保し、重複処理を許容。 通知順序のズレ :順序入れ替わりは発生するものとして扱い、最終的に正しい状態へ同期されていれば問題なし。 これらの要件から最終的に以下のような構成になりました。 SQS は Standard Queue を使用し、外部サービスのシークレットキーなどは AWS Systems Manager のパラメータストアを利用しています。 2. インフラ(Terraform+lambroll) 本構成で必要となるAWSリソースは以下の通りです。 *1 IAM: Lambda 実行用の Role と Policy Lambda: Webhook を受信する Lambda Function(Function URLs) SQS: イベントを後続ワーカーへ受け渡すための Main Queue と Dead Letter Queue Systems Manager & KMS: 外部サービスのシークレットキーを保管するためのParameter Store と KMS Key BASE ではインフラ構築に Terraform を、Lambda のデプロイには lambroll を利用しています。これらは別々のリポジトリで管理されていて、アプリケーションエンジニアでも安全かつ容易に AWS リソースを管理でき、Lambda のコードは継続的デリバリーが可能な体制になっています。 Terraform 編 Terraform は一般的な AWS 構築を行いますが、Lambda だけは異なります。 aws_lambda_function のリソースは Lambda を作成する時と、削除する時だけに使用し、最初にダミーファイルをデプロイします。その後は source_code_hash や runtime , environment などの情報に差分を検出しても変更を適用しないように設定しています。これらは lambroll 側で行います。 また、 BASE では Terraform をモジュール化して管理しており、インフラエンジニアや SRE でなくても、必要なパラメータを入力すれば標準的な AWS リソースを安全に作成できるようになっています。 例えばこんな感じです。 // lambda.tf module "lambda_hogehoge_integration_webhooks" { source = "../modules/lambda" function_name = "hogehoge-integration-webhooks" ... } // sqs.tf module "hogehoge_integration_webhooks" { source = "../modules/sqs_dead_letter" name_sqs = "hogehoge-integration-webhooks" dead_letter_queue_arn = module.hogehoge_integration_webhooks_dead.sqs_arn ... } module "hogehoge_integration_webhooks_dead" { source = "../modules/sqs" name_sqs = "hogehoge-integration-webhooks-dead" ... } module からアタッチするポリシーも設定出来るので、送信先 SQS への sqs:SendMessage 、シークレットを格納している SSM Parameter Store への ssm:GetParameter 、そして Parameter Store 経由で Secrets Manager のシークレットを参照するための kms:Decrypt だけをアタッチして、最小権限になるようにします。 また、Lambda Function URL の設定は lambroll 側ではなく Terraform 側で定義しました。 lambroll 編 lambroll は、AWS Lambda に特化したシンプルなデプロイツールです。Terraform でインフラ(関数そのものや IAM ロール、Function URL など)を作成しつつ、アプリケーションコードのビルドとデプロイは lambroll に任せることで、役割を分離しています。 github.com まず、Terraform で作成した既存の Lambda 関数を、Lambda 専用リポジトリ側から管理できるように初期化します。 lambroll init --function-name hogehoge-integration-webhooks --download このコマンドにより、対象の関数設定を取得し、 lambroll 用の設定ファイル( function.json )が手元に生成されます。 { " Architectures ": [ " arm64 " ] , " Environment ": { " Variables ": { " APP_KEY ": " {{ must_env `APP_KEY` }} ", " APP_SECRET_NAME ": " {{ must_env `APP_SECRET_NAME` }} " } } , " Handler ": " bootstrap ", " Runtime ": " provided.al2023 ", ... } function.json では Terraform で ignore の設定をしている環境変数やランタイムを指定します。 コードを書き換えた後の Go のビルドとデプロイは次のように実行します。 go build -v -o ../build/bootstrap lambroll deploy --src="build" この一連のフローは GitHub Actions 上から自動でビルドとデプロイが走るようになっています。 3. 実装(Go) Lambda のコードは Go 言語で実装しています。後続ワーカーはドメインロジックを担うため BASE のアプリケーションと同じ PHP を採用していますが、Lambda 側ではビジネスロジックを持たないため採用言語に強い制約はありません。 今回は外部サービスの公式ドキュメントが Go のサンプルを提供していたこと、社内で Go の利用実績があることから、Lambda は Go で実装する方針としました。 次のようなディレクトリ構成で進めています。 hogehoge-integration-webhooks/ build/ bootstrap src/ go.mod go.sum main.go Makefile function.json .env まず、 init 関数では Lambda 起動時に一度だけ実行される初期化処理として、SQS クライアントの生成とシークレットの取得を行います。ここで作成したクライアントやシークレットはグローバル変数として保持し、各リクエスト処理で再生成しないようにしています。 func init() { ... // SQSクライアントを作成 sqsClient = sqs.NewFromConfig(cfg) // SSM Parameter Store から APP_SECRET を取得 ssmClient := ssm.NewFromConfig(cfg) withDecryptionc := true param, err := ssmClient.GetParameter(context.TODO(), &ssm.GetParameterInput{ Name: &appSecretName, WithDecryption: &withDecryptionc, }) appSecret = *param.Parameter.Value ... } main 関数では lambda.Start(handler) を呼び出し、実際のリクエスト処理は handler 関数に集約しています。 handler では署名の検証と SQS へのメッセージ送信だけを担当させ、ビジネスロジックは持たないようにしています。署名検証に失敗した場合は 404 を返すことで、認証まわりの情報を外部に漏らさないようにしています。 func handler(ctx context.Context, request events.LambdaFunctionURLRequest) (events.LambdaFunctionURLResponse, error ) { // 事前検証 ... // 署名を検証 if !verifyWebhookSignature(request.Body, authHeader, appKey, appSecret) { return events.LambdaFunctionURLResponse{ StatusCode: 404 , }, nil } // リクエストBodyをそのままSQSに送信 _, err := sqsClient.SendMessage(ctx, &sqs.SendMessageInput{ QueueUrl: &sqsQueueURL, MessageBody: &request.Body, }) if err != nil { log.Printf( "Failed to send message to SQS: %v" , err) return events.LambdaFunctionURLResponse{ StatusCode: 500 , }, err } // 成功の場合空で返す return events.LambdaFunctionURLResponse{ StatusCode: 200 , }, nil } 今回の Lambda は「受け取った Webhook を検証し、そのまま SQS に流す」ことだけに専念しており、後続のワーカーがビジネスロジックを実行する前提のため、リクエスト Body をそのまま SQS に送信するシンプルな実装としています。 もしビジネス要件の異なる複数種類の Webhook を単一のエンドポイントで受け取る必要がある場合は、この handler 内でイベント種別(リクエスト Body 内の値)などに応じて送信先のキューを振り分ける構成にすると、FIFO Queue が使用可能後になったり、後続のワーカーを用途ごとに分離しやすくなります。 4. 監視・運用 前提として BASE では New Relic でも AWS サービスのインフラの観測を行っています。 New Relic では以下の様なダッシュボードを用意し、ひと目でサービスの状態が把握出来るようになっており、万が一異常が起きてもアラートを設定していて slack へ通知されるようにしています。 ダッシュボード編 この連携の状態を把握するための「入り口」として New Relic のダッシュボードを用意しています。ダッシュボードを開けば、構成・ステータス・関連リソースへの導線がひと目で分かるようにすることを意識しています。 まず、ダッシュボードの一番上には全体構成が分かる図を配置します。New Relic では Mermaid 記法でダッシュボード内に図を記述できるため、 Lambda Function URL → Lambda → SQS → ワーカー というイベントの流れを示した簡単な構成図を載せています。 参考: Mermaid記法でダッシュボードにアーキテクチャ図など視覚的な表現が可能に! #AWS - Qiita 次に、この連携に関わる周辺情報へのリンクをまとめた Markdown テキストを置きます。具体的には、対象 Lambda 関数や SQS キューの AWS コンソールへのリンク、関連する GitHub リポジトリ、ドキュメントなどを並べておき、運用時にここからすぐに辿れるようにしています。 その下には、主要なメトリクスをサービスの流れに沿って並べます。入口となる Lambda については Invocations 、 Duration 、 Errors 、 Throttles を New Relic 経由で可視化し、エラーやスロットルの有無をすぐ確認できるようにしています。SQS については、 SentMessages / ReceivedMessages / DeletedMessages といったトラフィックの傾向に加えて、 ApproximateAgeOfOldestMessage 、 ApproximateNumberOfMessagesNotVisible 、 ApproximateNumberOfMessagesVisible を配置し、キュー滞留や詰まり具合を一目で判断できるようにしています。 (LatencyのSLOはうまく計測出来ておらず、0となってしまっている…) これらを「入口 → キュー → 下流ワーカー」の順番で並べることで、どのレイヤーで異常が起きているかを直感的に追えるダッシュボード構成としています。 アラート設定と運用 New Relic アラートでは、各レイヤーで重要なメトリクスを監視対象として、異常を最速で検知し、slack へ送るようにしています。 Lambda では Errors と Throttles を監視し、失敗が発生した場合は Slack へ即時通知されるようにしています。Lambda の失敗時は、外部サービス側の Webhook リトライが発生しているかの確認を行います。 SQS 側では ApproximateAgeOfOldestMessage と ApproximateNumberOfMessagesVisible をアラート条件に設定し、キューの滞留や処理遅延が発生した場合に通知します。これにより、下流ワーカーの負荷増大を早期に把握できます。 さらに、DLQ にメッセージが入った場合は、件数が1件以上であることをトリガーとして Slack に通知しています。 5. まとめ 今回の構成は、Webhook を受け取り、後続ワーカーへ処理を引き渡すことを目的としたシンプルなアーキテクチャでした。入口となる Lambda Function URL は軽量で扱いやすく、ビジネスロジックを後続ワーカー側へ集約したことで責務が明確になり、機能追加や修正にも柔軟に対応できる構造になっています。 今回の事例が、今後の設計や運用を進める際の参考になれば幸いです! BASE ではアプリケーションエンジニアが設計からインフラ・監視まで幅広く活躍することが出来ます。興味があれば採用情報もぜひご覧ください! binc.jp 明日は、BASEアドベントカレンダーは @zan_sakurai さんの記事です。お楽しみに! *1 : Cloudwatch Logsもありますが、ここでは省略して書いています。
アバター
この記事は BASEアドベントカレンダー の一日目の記事です。 こんにちは!BASE株式会社で開発担当の役員をしている、えふしんです。 僕も今、BASEグループ全体を視野に「AIを経営資源としてどうアップグレードするか」を日々考えています。 2025年の締めくくりにふさわしく、 今日は“生成AIの憂鬱”について書いてみたいと思います。 AIツールが乱立する時代に、企業は何を選び、どこから撤退するべきか 2024年から2025年にかけて、企業のIT環境は一気に騒がしくなりました。 Slack に AI がつき、Notion に AI がつき、 Google に Gemini が載り、 Microsoft は Copilot を標準にし、 そして OpenAI は ChatGPT Enterprise を大々的に展開し始めています。 どのサービスも「今度こそ、これ一つで生産性が劇的に上がります」と主張する。しかし、企業の中に身を置いていると、そんなに単純な話ではないわけです。 Enterprise SaaSは、Enterpriseプランなどの高額なプランにAI拡張機能を載せています。これは数年後のAIプロダクトの風景では多分ありえない光景で、「あたりまえのAI時代」の前段階が故に高付加価値機能として置かれていると考えます。 もちろん、これはAI発展のストーリーの1ページで、OSSだって最初からOSSが生まれてくるのではない。プロプライエタリな製品を大企業がお金を払って普及させてくるからこそ、クローンとしてOSS化して多くの人が使えるようになり世界が拡がるというのは、ここ数十年のITの歴史ではないでしょうか。Linuxを使うユーザーが、インストールされている素敵なライブラリ一つ一つに適切なアウトカムを認識して使っているなんてことはないわけです。 だからと言って、この流れを無視して、ある意味フリーライドできる時が来るまで待つのも違うと思ってしまうわけです。これぞAIバブル。 この流れをどう乗りこなしていくか。未来と現状のギャップ。発展途上の過渡期だからこそ、“生成AIの憂鬱”が広がっています。 AIの導入はワクワクより「疲労」のほうが先に来る Slack AI を買うべきか? Notion AI の方が効果が高いのか? Copilot や Gemini はどうする? ChatGPT Enterprise を入れるべきか? 気づけば、どのSaaSも「AI検索できます」「自然言語で仕事ができます」と言い始め、企業はコア実装である生成AIが類似なものであろう複数のAI機能に同時に課金するような状況に追い込まれている。 こうした“AI疲れ”は、技術的な問題というより、意思決定する側の負担が大きすぎるところに原因がある。導入判断だけでなく、撤退判断がもっと難しい。 導入時には派手に謳われた生成AI機能も、いざ組織に入ってしまうと、多少期待外れだったとしても「使い慣れたツールをやめたくない」という声が必ず出る。生成AIが汎用的が故に、特定のユースケースが恩恵を受けてしまったところから、引き剥がすのは難しい。 その結果、企業の中には“サンセットできないツール”が静かに積み上がっていく。 意思決定者は、ここまで予測し、ある意味非情とも言える決断を覚悟しないと入れられません。それ故に撤退基準の仕組み化が必要という考え方もありますね。 なぜAIツールがこんなに乱立してしまうのか 理由は単純で、各サービスが「社内で最初に質問される場所」を狙っているからだと考えます。 Slack は会話の中心にいる。 Notion はナレッジの中心にいる。 Google はドキュメントの中心、Microsoft はメールと会議の中心。 そして OpenAI は「生成AIそのものの中心」にいる。 それぞれが「うちをAIの入口にしてほしい」と主張し、結果として企業側は、複数の“AIフロントエンド”と向き合わざるを得なくなる。 いずれ企業毎の重要な情報が集まっているコアとなるAIが中心となり、周辺のフロントエンドにさまざまなツールが存在する構造になるかもしれないが、今はまだ早い。 AI導入の本質は、生産性やコスト削減だけではない よくAI導入のメリットは「業務効率化」「コスト削減」と語られる。 もちろんそれも重要だが、2025年現在の企業にとって、もっと重要な価値がある。 それは 新人のレバレッジではないでしょうか。 生成AIを使うと、まだ経験が浅いメンバーでも、会話ログからプロジェクトの背景を掴んだり、文章の下書きを素早く用意したり、技術的な不明点を自分で解消したりできる。 結果として、組織は「人を増やさずに回る領域」を増やせる。 (人員削減という言葉は使わないが、チームが肥大化しないという“健全さ”を保つためにAIは効く) この“レバレッジ”は、AI導入における一番の価値だと思っています。 ソーシャルではシニアの方が恩恵を受けて、新人が採用されなくなったり入り込む余地がなくなるんじゃないかと言われているが、僕は必ずしもそうだとは思っていません。 「生成AIの憂鬱」を超えるために、企業がすべきこと AIツールは導入しただけでは価値になりません。組織文化と技術構造が噛み合って初めて成果につながります。 導入でも撤退でも重要なのは、「どのレイヤーでどのAIが本当に必要か」 を冷静に見極めること。 Slackでのキャッチアップには Slack AI が向いている。 会社ナレッジには Notion AI が向いている。 横断的な調査や下読みには ChatGPT Enterprise という選択肢もあるが、何をどこまで統合するかは組織の成熟度次第。 AIの時代は、ツールが増えること自体よりも、“どれを選び、どれを手放すか”の判断 が企業を悩ませる。 引き続き悩み続けます。皆さんのご意見もお聞きしてみたいです。 おわりに 生成AIによって、働き方も役割もこれから大きく変わっていきます。AIのセンスと自分の専門性を掛け合わせて、新しい価値をつくれる時代です。 BASEグループでも、そんな環境に一緒に取り組んでくれる仲間を探しています。もし興味があれば、採用情報もぜひ覗いてみてください。 binc.jp
アバター
こんにちは!BASE PRODUCT TEAM BLOG 編集部です。 そろそろ年の瀬ですが、みなさまいかがお過ごしでしょうか。 今年も恒例のBASEメンバーによるアドベントカレンダーを開催します! 毎年公開しているアドベントカレンダーも今年で8回目を迎えます。 過去の様子 2024年のアドベントカレンダー 2023年のアドベントカレンダー 2022年のアドベントカレンダー 2021年のアドベントカレンダー 2020年のアドベントカレンダー 2019年のアドベントカレンダー 2018年のアドベントカレンダー 今年も1日1記事に限定せずたくさんのバラエティ豊かな記事を公開する予定です。 公開され次第以下のカレンダーも随時更新していきますので、ぜひお楽しみに! 日付 執筆者 タイトル 2025年12月1日 @Shinichi Fujikawa 生成AIの憂鬱 2025年12月2日 @ema Webhook を AWS Lambda で受け取り SQS へ流す 〜設計から監視まで〜 2025年12月3日 @zan “goらしさ”について考えてみる #1 interface編 “Accept interfaces, return structs” を添えて。 2025年12月4日 @tanden プロダクト開発組織でのケイパビリティ可視化に向けた取り組み 2025年12月5日 @rerenote 登壇もコミュニティも応援したい!技術イベント協賛まとめ 2025年12月6日 @yaakaito Cloudflare でショップをちょっとだけ速くしてみた - 導入/SSL for SaaS 編 2025年12月7日 @yaakaito Cloudflare でショップをちょっとだけ速くしてみた - キャッシュ/Workers 編 2025年12月8日 @takashima 開発量向上の話 2025年12月9日 @okinaka LocalStack の EventBridge Scheduler にある制約とその対処法 2025年12月10日 @FujiiMichiro 「テキストレビューAI」導入による、ブランドデザインの最適化 2025年12月11日 @komaki 文字を読むのが苦手な自分との付き合い方 2025年12月12日 @ykagano 何か書く 2025年12月13日 @UenoKazuki AI での業務改善についてなにか書きたい 2025年12月14日 @02 最速振込にてmysql instant algorithmを使って無停止でテーブルにカラム追加した話をします 2025年12月15日 @Capi ツール導入を行う際に気をつけたいことを紹介します 2025年12月16日 @NojimaTomoya なんかかく 2025年12月17日 @izuhara 業務自動化でBASEを支えるCSEチームの変遷 2025年12月18日 @ImazekiShota 分析基盤におけるSQL自動生成の話 2025年12月19日 @OtsukaHiroki New RelicのダッシュボードをTerraformで出す話 2025年12月20日 @Satoshi Ohki OpenFeature OR Uber fx 2025年12月21日 @OgasawaraYuki BASEにおけるサービスレベルマネジメントのこれまでとこれから 2025年12月22日 @matzz(Yusuke Matsubara) 【2025年版】モニタ・キーボード・マウスの3種の神器のトレンドを考える or 社会人のための現代栄養素の基礎知識 →個人blog 2025年12月23日 @yaakaito 未定!!!!!!!!!!1 2025年12月24日 @UedaHayato エンジニア組織の組織設計どうしてる?〜BASE事業開発チームの組織変遷〜 2025年12月25日 @mkawaguchi 未定です!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
アバター
はじめに CTOの川口 ( id:dmnlk ) です。 先日AWS Japan様にご協力いただきBASE社内で Amazon Bedrock AgentCore を利用したワークショップを開催したのでそのリポートです。 AWS Japan様と日々お話をさせていただく中で社内でのAgent開発を行うにあたり、そもそもAgentとはどういうもので何ができて何を利用できるかといった体系的な知識をまだ持ち合わせいないことを課題感として話しており せっかくなので Amazon Bedrock AgentCoreを使ったワークショップを開催しAgent開発に触れてもらうことができるのではないかと打診をいただき開催したものとなります。 Amazon Bedrock AgentCoreワークショップ このワークショップには全事業部から参加メンバーを募りました。 現状の業務で触れる機会のないメンバーにも新しい技術などに触れてもらう良い機会だと思ったため現在の業務内容に関わらず広く募りました。 その結果30名程度のメンバーが参加してくれました。 奇しくも Amazon Bedrock AgentCoreが開催日の一週間前にGA したこともあり触れやすかったのではないかと思います。 弊社オフィスにAWS Japanの方たちをお招きし、前半は座学でAgentとはなにかやAgentCoreがどのようなものかを講義いただき、途中から用意していただいたハンズオン環境でAgentCoreを利用したAgent開発を行いました。 特に準備は不要で各メンバーがそれぞれ使える環境が用意されていたので特に環境構築で詰まることなくワークショップに取り組めたのは良い体験でした。 ワークショップ自体は 下記リポジトリを基本とした形のようで後に見返すこともしやすいのは助かりました。 github.com 個人的に事前にAgentCoreは触れていたので、自分もサポートに回りつつ改めてAgentCoreを触るいい機会となりました。 Agent開発において動作させる環境や記憶装置などは必要だが開発するアプリケーションとは別に考えることが多く面倒が多いですが AgentCoreを利用することでそれらの苦労が減るというのは開発体験として心地の良いものです。 本番ワークロードではo11yなども重要になっていきますがそれらもケアされていることは安心に繋がります。 予算管理という側面ではAgentCoreの課金体系である 「CPU リソースについては、エージェントがアクティブに処理しているときに課金されます (LLM 応答を待機しているときの I/O 待機期間への課金はありません)」 というところはお気に入りな部分です。 実際にワークショップに参加したメンバーは普段はPythonを書いたりしないので不慣れな部分もあったようですが、皆基本的に問題なく進められたようで Agent開発の基本は抑えられて手札が増えたのではないでしょうか。 おわりに 必要があるから技術を学ぶというのはもちろんですが、必要になる前から事前に手札を増やし素振りをしていくことは重要ですのでこのような機会を設けられたのはエンジニアの知的好奇心を満たしつつ プロダクトにAIやAgentをどのように組み込めるかといった新たな視点をもたらすのにいい機会だったと思います。 ご協力いただいたAWS Japanの皆様に感謝しています。 これからもこのような機会は積極的に活用し日々の開発を超えた新しいプロダクトへの技術導入ができるようにしていきたいと思っています。 BASE株式会社ではエンジニアを採用募集中ですのでご興味あればご応募お待ちしております。 binc.jp
アバター
はじめに 本文中とサムネイルの画像に登場するキャラクターは、 PHPカンファレンス福岡2025 の公式キャラクターです。 公式のガイドラインのもと、配布されている素材を利用させていただいています。 Product Development Division で PHPer をしている ema ( @meihei )です。 2025年11月8日に開催された PHPカンファレンス福岡2025 に参加し、BASEのエンジニアも2人登壇しました。また、開催の後日に社内でPHPカンファレンス福岡2025のふりかえり会を行いました。 この記事では登壇スライドの紹介と、そのふりかえり会の様子をお届けします! 登壇者コメント かがの @ykagano 「決済システムの信頼性を支える技術と運用の実践」というテーマで登壇させていただきました! speakerdeck.com 長年、決済システムを開発してきた経験から、特にクレジットカード決済における具体的な設計と運用のノウハウをお伝えさせていただきました。 なぜDB設計で非正規化が必要なのか 300 TPS 超の負荷テストとボトルネック対策 データの増加を見据えたバッチ設計 会場では発表内容について質問をいただいたり、知らない世界なので面白かったといった声をいただき、大変嬉しく思いました。 ご参加いただいた皆様、ありがとうございました! meihei @app1e_s 「隙間ツール開発のすすめ」というテーマでLTをさせて頂きました。 speakerdeck.com 自分は普段から隙間を見つけてはツールを開発しているのですが、そのやり方やAI時代での開発の方法などを、自分の経験からまとめたスライドとなっています。 実例で挙げたように皆が必要なものは公式から提供されますが、まだ提供されていないものや自分だけが必要なものは、パパッと AI に書いてもらって作ると良いなって思っているので、そこのあなたも是非! ふりかえり会 PHPカンファレンス福岡2025では良い発表が多かったので、それら知識が身になるように、ふりかえりによるグループ学習を行いました。 ふりかえりでは、よくあるフレームワークは使わずに輪読会で用いられるようなフォーマットを使いました(今回は retty さんの社内輪読会のやり方を参考にしています) engineer.retty.me やりかた ルール 適当に付箋を拾い、書いた人の話を聞きつつわいわい話す 近い内容の付箋だなと思ったら書いた人が自分で近くに寄せる 感想は青、気づき・学びは黄、疑問・深掘りは赤を使う 進め方 テーマの優先順位を決める 5分間付箋を貼る時間 1テーマ10〜20分話す 各発表のふりかえり FigJamで行い、計4つの発表について話しました。 予防に勝る防御なし(2025年版) - 堅牢なコードを導く様々な設計のヒント / 和田 卓人 さん BASEではどこでどう使われているか、他社の事例ではどうか、今後、自分たちのコードにどう活かしていけそうかを整理しながら話していました。 特に「SimpleとEasy」「ValidateとParse」については、「 Clojureと「Simple Made Easy」 」や「 Parse, don’t validate 」などの発表資料以外のところからも参考文献を持ってきて、白熱した議論となりました。 バグと向き合い、仕組みで防ぐ / __rina__ さん BASE社内のインシデント対応フローと見比べてどうか、エンジニアとQAの”変更”に対する意識の違いなどを話しました。 ポストモーテムは有志で行われているものの、インシデント対応チームで行っているわけでもなくフローにも組み込まれていないので、今後フローに組み込むように改善できないかなどの提案もありました。 AI 時代だからこそ抑えたい「価値のある」PHP ユニットテストを書く技術 / 河瀨 翔吾 さん ユニットテストの重要性を理解できたし、Before と After があって発表がわかりやすかったので「このパターンはどうなんだ?」などの具体的なところまで議論を行いました。 また、BASE内でのテストルールの確認や、コーディングルールの確認も行いました。 AI 時代だからこそ学ぶべき PHP の基礎 / めもり〜 さん 知識の幅を広げるためにどんなことができるかを振り返りつつ、今仕事でどんなことをやっているという話をしました。 テストやCIなどガードレールに関する話は、「予防に勝る防御なし(2025年版) - 堅牢なコードを導く様々な設計のヒント」や「AI 時代だからこそ抑えたい「価値のある」PHP ユニットテストを書く技術」でも同様の主張されているところがあり、発表を並べてふりかえり会を行ったからこそ、知識の結びつきが見えてきて学びがありました。 おわりに 今回で最後となるPHPカンファレンス福岡でしたが、感慨深くもとても楽しいカンファレンスでした。10年間、本当にお疲れさまでした!! 開催の準備をしていただいたスタッフの方々、登壇してくださった皆様、カンファレンスに協賛してくれたスポンサーの皆様、そして、PHPカンファレンス福岡を盛り上げてくれたPHPerの皆様、ありがとうございました! BASE ではカンファレンス登壇者が何名も在籍しています。興味があれば採用情報もぜひご覧ください! binc.jp
アバター
はじめに こんにちは!BASE BANK Dept にいるフルサイクルエンジニアの02です。 今回はFull Cycle Developers Night #2 ~エンジニアはどこまでビジネスを知るべき?~というBASE株式会社(以下、BASE)、株式会社CARTA HOLDINGS(以下、CARTA)、MOSH株式会社(以下、MOSH)で共催したイベントについて、当日の様子をお届けします! 開催したイベントについて base.connpass.com Full Cycle Developer(以下、フルサイクルエンジニア)とは、Netflixが2018年に提唱したエンジニアのあり方の一つです。フルサイクルエンジニアは、コードを書くだけでなく、設計から運用までソフトウェアプロダクトのライフサイクル全体に責任を持ちます。 Full Cycle Developers at Netflix — Operate What You Build devblog.thebase.in そんなフルサイクルエンジニアを主軸としたイベントが、Full Cycle Developers Nightです。今回は「エンジニアはどこまでビジネスを知るべき?」をテーマに、事業との向き合い方についてパネルディスカッションしました! パネルディスカッションの様子 パネルディスカッションの前に、各パネラーから自社のビジネスモデルや組織形態について、スライドを用いて5分程度で解説してもらいました。 今回のテーマ「エンジニアはどこまでビジネスを知るべき?」では、ディスカッション中に各社のビジネスモデルや組織形態の話が出てくることが想定されました。そのため、事前に理解してもらった上でパネルディスカッションを始める流れにしました。 各パネリストとモデレーターの様子 パネルディスカッションでは、以下のようなテーマで話しました! 「ビジネスサイド」具体的に誰を想像していますか? どんな役割分担でどこまで意見をだしている? どういった失敗から「ビジネスを知らねば」と思ったか? フルサイクルエンジニアとして、企画をエンジニア発信で進めることはあるか?その場合、何を根拠に提案しているか? コードを書く開発業務だけに集中したいエンジニアに、どうマインド変革を促せばよいか? フルサイクルエンジニアの立場で、PdMにしてもらって嬉しかったこと・やりやすくなったことは何か? 途中からは参加者からもXでテーマを募集し、盛り上がりを見せました!当日の盛り上がりは、Xのハッシュタグからもご覧いただけます! #full_cycle_nightのタイムライン パネルディスカッション中の様子 おわりに Full Cycle Developers Night #3 も開催したいと思っています!フルサイクルエンジニアや事業との向き合い方に興味がある方は、ぜひFull Cycle Developers Night #3 でお会いしましょう! BASE BANK Deptでは、事業をエンジニアリングするフルサイクルエンジニアを募集してます。 ご興味がある方は、ぜひ下記のURLから採用ページをご覧ください! binc.jp
アバター
自己紹介 BASEでエンジニアインターンをしている吉川唯音です。趣味は音楽で、作曲や編曲をしています。この度10月9日をもって、インターンを無事に終えることになりました。約2ヶ月のBASEでのインターンを通して、感じたことや学んだことについて語っていこうと思います! インターン入社の経緯 自分は普段から多様なクリエイターとの接点があり、周囲ではBASEを利用している方も多く、そのため以前からBASEという存在を知っていました。そうした背景もあり、サポーターズの1on1イベントに参加した際により強く興味を持ち、面談を経て応募に至りました。そして選考が進み、8月からインターンとして入社しました。初めてBASEを訪れた際には、大きなガラス張りのエレベーターとオフィスの開放感のある雰囲気に驚いたことを今でも覚えています。 BASEで実際にやったこと ショップ管理画面全体のデザインリニューアル開発 私はBASEで「ショップ管理画面全体のデザインリニューアル開発」にジョインし、フロントエンドの実装を担当しました。普段はReactを扱うことが多いのですが、BASEではVueを用いて開発を進めました。特に印象に残っているのは「デザインシステム」の考え方です。大規模なプロダクトであるからこそ、将来的な拡張性を意識し、一箇所の修正が全体に反映される仕組みや、新しい機能を追加しやすい設計が整えられていました。単なる見た目の調整ではなく、フロントエンドにおける本質的で重要な仕組みを体験できたと感じました。 ▲新管理画面 ▲旧管理画面 iOS 26 対策 2ヶ月目はiOS 26 対策にもジョインしました。iOS26のリリース前に、シミュレーターで検証や修正を進めました。プロダクトの規模が大きい分、前提知識や全体構造の理解が求められ、影響範囲を考慮しながらコードを書くことの難しさを強く実感しました。BASE独自に構築された仕組みや、フロントエンドの中枢にあたる部分に触れることは難しかったですが、実装していてとても面白いと感じました。 "プロダクト"とリリース体験 また、この経験を通じてAIエージェントに対する考え方も変わりました。AIは人間の意図や文脈を完全には理解できないからこそ、プロダクトの構造や本質を踏まえ、影響範囲を見据えた設計・実装を行うことがエンジニアにとって不可欠だと学びました。 インターン最終週には、自分が担当した実装箇所が無事にリリースされるのを見届けることができ、とても嬉しく感じました。実際にプロダクトとして動いている様子を見たときは、感動しました。長く続いていたプロジェクトに参加し、限られた期間の中でリリースの場面にも立ち会えたことは、本当に幸運であったと感じています。 インターンを通じて感じたこと 特に学びになったこと BASEでのインターンを通じて特に学びとなったのは、「 プロダクトに向き合う姿勢 」と「 実務としてのスクラム開発 」です。 入社してまず驚いたのは、プロダクトに対する考え方でした。「コードを記述する」ことにとどまらず、「なぜその機能を作るのか」「ユーザーはどのように利用するのか」といった背景までを深く考える文化があります。エンジニアだけでなく、デザイナーやPdMの方々と一緒に議論し、提案を交わしながらプロダクトを形にする。そこには「難しいことをシンプルにする」という思想が強く根付いており、これはプロダクト全体や日々の業務に反映されていると感じました。この経験を通して、エンジニアにはコードを書くことだけでなく、ドメインを理解し、本質的に価値のあるものを見極める視点が不可欠だと実感しました。 さらに、BASEのインターンで特に貴重だったのは、実際にエンジニアの方々と同じチームでスクラム開発に参加できたことです。レトロスペクティブやスプリントレビュー、デイリースクラムといったスクラムイベントに、開発メンバーの一員として加わりました。プロダクトのゴールに適切に向かえているか、チームの状況はどうかといった点について、日々活発に議論しながら開発を進める経験はとても刺激的でした。このように実務としてのスクラム開発を体験できたことは、他のインターンでは得られない、大きな学びとなりました。 こうした学びを自分なりにアウトプットし、自分が所属するコミュニティでの開発や自己開発にも取り入れるなど、より前向きにチャレンジできるようになりました。コミュニティ内部のインターンでは、フロントのデザインシステムによる共通化やレトロスペクティブのファシリテーション、開発するプロダクトに対して積極的に向き合っています! BASEのすごいと思ったところ BASEに入社して最初に感じたことは、受け入れ体制がしっかり整っていることでした。入社前の面談では「今まで新卒を採用したことがなく、教育制度や受け入れ体制が十分ではない」と伝えられていましたが、実際には予想以上に丁寧に受け入れていただき、とても驚きました。インターン期間中はメンターとしてついていただいた先輩エンジニアに、開発業務から日々のサポートまで手厚くフォローしていただき、社会人経験の少ない私にとって非常に心強く感じました。 また、BASEの魅力を強く感じたのは「プロダクトに対する一貫した思想」と、充実した開発環境の両立です。ユーザー視点を大切にしながら「難しいことをシンプルにする」文化が根付いている一方で、Android実機をWebブラウザからリモート操作・管理できるツールがBASE内で用意されるなど、開発環境にはギークさもありました。こうした環境の中で、AIでは生み出せない価値やプロダクトへの愛着を肌で感じることができました。 インターンを考えている学生に向けて BASEでのインターンは、チームの一員として受け入れられ、実際の開発業務に携わることができます。そして他の企業では経験できない貴重な学びがあります。また、メンターランチでは費用補助があり、美味しいご飯を楽しみながら、インターン期間中に参加したPJ外の方と交流することができました。特にオムライスが美味しかったです。 さらに、BASEには1on1や全社集会、部活動といった制度が整っており、多くの社員の方々と関わる機会がありました。インターンとして参加する中で、さまざまな視点や刺激を得られる、とても恵まれた環境だったと感じています。 1on1では先輩エンジニアの方と技術的なお話をさせていただいただけでなく、人事・PdM・CSといった他職種の方々とも対話する機会をいただきました。将来のキャリアや就活についての相談から、BASEでの開発体制や技術に関する具体的なお話まで、幅広く学ぶことができました。 BASEで働くメンバーはとても親切で、多方面に優れていると感じました。だからこそ、エンジニアリングの実務だけでなく、カルチャー面でも多くの学びが得られるインターンだと強く感じました。ぜひBASEのインターンを通じて、その両方を体験していただきたいです!
アバター
はじめに BASEでソフトウェアエンジニアをしている Futoshi Endo( @fendo181 )といいます。 以前、同じチームの Kumar さんが以下のタイトルで記事を執筆されました。 「BASEでの開発体験を向上させるための取り組み」 devblog.thebase.in この記事では、生成AIの活用によって、メンバー全員がフロントエンドとバックエンドの両方を担当できるようになった、という挑戦について触れられていました。 今回のプロジェクトでは、メンバー全員がフロントエンドとバックエンドの両方を担当できるようにするということにチャレンジをしました。メンバーは以前から専門領域を広げたいという意欲を持っていましたが、学習コストやペアプログラミングにかかる時間的負担を考慮し、プロジェクトの進行を優先せざるを得ませんでした。 しかし今回、AIツールの活用によってこれが実現可能となりました。 自分はまさにこのプロジェクトのエンジニアメンバーの1人であり、AIツールの力を借りることで、バックエンドの領域から、フロントエンド開発に挑戦することができました。 この記事では、どのように生成AIを活用して学習・開発を進めたのか、具体的な体験をベースに紹介します。 AIを“頼れるエキスパート”として活用し、スキルを拡張する 今回のプロジェクトでは、主に React + TypeScript を用いた機能開発が中心でした。 プロジェクト初期は「フロントエンドもやってみたい」という気持ちはありつつも、ReactやTypeScriptの文法に不慣れな自分にとっては、 「何が分からないのかすら分からない」状態 で、不安の方が大きかったのを覚えています。 まず取り組んだのは、 Reactの公式ドキュメントのチュートリアル をベースにした写経です。 基本的な構文やライフサイクル、Hookの使い方などを手を動かしながら覚えていきました。 しかし、それだけでは実務のコードはなかなか読めるようにはなりません。 PRレビューにおいても、変更内容の意図が掴めずに苦労していたのが実情です。 そこで活用したのが、 ChatGPT や GitHub Copilot Chat といったAIツール です。 わからないコードの説明や、PR内容の要約、APIや型の補足など、質問を投げることでその場で壁打ちができる環境が構築できました。 その後は、技術書やサンプルコードを写経しながら実装力を強化し、壁にぶつかるたびにAIに質問を重ねることで、 学習のトライアンドエラーを高速に回すことができました。 特に印象に残っているのは、1ヶ月前は理解できなかったコードが、自分でAI Agentを活用し、出力されたコードの意図をすべて理解し、業務でも活用できるコードへと変わっていった実感です。 たとえば、最初はAIが生成したコードの正誤すら判断できませんでしたが、繰り返しのやり取りと経験の積み重ねによって、 「どの部分が怪しいか?なぜそうなるか?」を自然と説明できるようになっていた のです。 当初は「フロントエンドに関連する機能改善で20本ほどPRを出せたら十分」と考えていましたが、プロジェクト終盤には 60本以上のPRを提出 しており、予想以上の成果につながりました。 もちろん、新規ページ追加や、APIへリクエストを行う為のClient追加のような機能開発から、細かなUI調整や文言変更なども含まれていますが、ReactとTypeScriptの知識がほぼゼロの状態から始めた自分にとって、この実績は大きな自信になりました。 この経験から強く感じたのは、 生成AIは単なる効率化のツールではなく、学習の初動コストを下げ、スキル拡張を加速する存在である ということです。 今後、「生成AIでコードを書く」だけでなく、生成されたコードが正しいかを判断する能力=レビュー力・設計力がますます重要になると考えています。 その意味で、AIとの理想的な関係性は以下のように整理できるのではないかと思っています。 得意な領域 → 生成AIを活用し、生産性を最大化する 不得意な領域 → 生成AIを“頼れるエキスパート”として活用し、学習のスピードを上げる AIと上手く付き合うコツは得意な領域では積極的に生成AIを活用し、生産性を上げ、不得意な領域では頼れるエキスパートとして活用し、学習をするのが良い近道なのではないかと思っています! まとめ 今回紹介したようにAIを活用することでこれまで専門外だったフロントエンド領域に挑戦することができました。一方で、AIを使う中で一貫して意識していたのが、 How(やり方)に偏りすぎないことの重要性 です。 Claude CodeやCodex CLIなど、AI Agentによるコードの自動生成は非常に便利ですし、私自身も Zennで記事 を書くほど積極的に活用しています。 しかし、ソフトウェアエンジニアとして本当に重要なのは、 「なぜその実装を選ぶのか?」「設計意図は何か?」というWhyの部分 です。 ユーザー体験、アーキテクチャ、保守性、チーム内の運用方針など、Whyを考慮することで、より本質的な開発ができると確信しています。 AIは間違いなく、これからのエンジニアにとって欠かせないパートナーになります。 だからこそ、自身の成長へつながる使い方と、上手く付き合っていくのがこれからのAI時代のエンジニアに求められるスキルセットだと思っています! 最後に宣伝で、BASEにおけるAI活用や開発スタイルにご興味を持っていただけた方がいれば、ぜひ採用ページもご覧ください! binc.jp 今後も、プロジェクトで得た知見を継続的に発信していきます。 最後までお読みいただき、ありがとうございました! おわり!
アバター
はじめに こんにちは、BASE株式会社 上級執行役員 SVP of Development の藤川です。 今年、生成AIの活用は経営課題の一つとして大きな注目を集めています。 開発担当役員という立場としても、この変化を肌で感じる必要があると考え、何年ぶりかにソースコードと向き合い、実際にプルリクエストを出してみることにしました。 ソースコードから離れていた10年間 最後にBASEのソースコードを書いていたのは、2016年頃まで。 上場に向けて、採用活動や組織拡大がマネジメント課題として本格化し、マネージャ育成やエンジニア採用、IT内部統制、情報システム整備といった役割が増えていく中で、自然と現場のコードから離れていきました。 その後、システムは大きく進化していきました。 開発環境のDocker化、本番環境のコンテナ化、テスト導入、React/Vue.js採用、モジュラモノリス化、CakePHP依存度の低下、PHP5から7〜8への移行…。 自分が作った開発チームの人たちの手で、気付けば、今のコードやサーバ構成はすっかり「浦島太郎」状態になっていました。 CursorでBASEのコードをキャッチアップ 最初の壁は、この10年分の変化をどう取り戻すか。 以前からのBASEのシステム構造は頭に入っていたので、その知識をベースにAIを使いながらキャッチアップしていきました。 使ったのはAIエージェントアプリの「Cursor」です。 Dockerfileやドキュメントを一つひとつ読むには時間がかかりますが、これらの情報やソースコードを下地としてCursorに質問すると、必要な情報を整理してくれます。 合間の時間を活用しながら進め、ほぼ誰にも質問せずに1週間で開発環境を再現できました。 どうしてもわからない部分だけ、CTOにヒントをもらう程度で済みました。 特に驚いたのは、ソースコードだけを元に「BASE Apps」という概念をCursorが理解してくれたことです。 BASE Appsとは、抽選販売機能やTikTok Shop連携などの機能を、後からショップにインストールできる仕組みです。 使い始めのBASEはシンプルなまま、必要に応じて高い機能を追加できるようにすることで、お店の成長に合わせた柔軟な情報アーキテクチャを実現しています。 この構造をAIが説明してくれたとき、正直ちょっと感動しました。 実際にPRを出してみた 環境構築が終わり、手元のDocker環境でBASEの開発環境が動くようになったので、新入社員やインターンの人に割り当てられるオンボーディング用のチケットプールから、ちょっとした不具合修正のチケットを割り当ててもらいました。 チケットに書いてある要件をプロンプトとしてCursorに渡すと、修正案を生成してくれます。チケットに書いてある要件が適切かつ具体的であればあるほど、修正案の生成は精度が高くなります。 それを元にコードを書き換えてプルリクエストを出すことに成功しました。 コード自体は当社のエンジニアの仕事場ですから適当なコードは出せません。できるだけ丁寧に内容のチェックをしました。ここまではほぼほぼ短時間での作業なのですが気の使い所です。 エンジニアからは丁寧なレビューが返ってきましたが、振り返ると「必要以上に大きな修正だったかもしれない」と感じています。 理由は、フロントエンドとバックエンドが別リポジトリで管理されており、Cursorがそれぞれの中で最適解を導いた結果、全体としては少し大げさな修正になっていたためです。 今のCursorの管理単位はリポジトリ単位になるため、リポジトリ間の関係性については人間が俯瞰して補う必要があり、そこは甘かったなと痛感しました。また、その解像度でコードレビューをしてくれた当社エンジニアはマジですごいなと改めて思いました。 レビューを通じて感じたこと レビューの指摘自体は正しく、Webサービスの変更において最小限の修正が望まれるという考え方には納得です。 今回のケースではCursorが生成したコードは「動作的には正しい」ものでしたが、それが「チームとして最適なコード」であるとは限りません。 AIが導いた“技術的に正しい解”と、プロダクトとして“望ましい解”は必ずしも一致しない 。 このギャップは今回の大きな学びでした。 一方で、AIが生成したコードを人間が精緻にレビューするのは工数がかかります。 過剰にレビューするのは非効率にもつながり、今後は「どこまで人力で見極めるか」の基準づくりが重要になると感じました。 なお、今回のレビューは、上級執行役員からのプルリクエストということもあり、普段より丁寧に対応してくれた可能性があります(もしかすると警戒もあったかもしれません 笑)。普段のメンバー同士であれば、もう少し軽いレビューで済んだかもしれません。 なので、逆にこれほどの時間をつかってもらって申し訳ないなと思ったのが正直な感想で、アウトプットをCTOや開発チームに委ねていて、自分自身で責任を持ちきれない今の役割においては、気軽にプルリクは出せないなとも思いました。 生産性と責任のバランス AI活用で避けて通れないのが、「どこまで人間が最終責任を持つべきか」という課題です。 AIが出したコードが正しく動いているなら、そのまま通すべきか? それとも品質を優先してさらに精緻化するべきか? この答えは一つではなく、チームやプロジェクトによって変わります。 だからこそ、開発チーム全体でレビュー方針を共有し、最適なバランスを探ることが大切です。 そしてもう一つ、AI活用は Biz・PdM・エンジニアといった役割間の業務の「のりしろ」を増やす可能性 を秘めています。 MCPなどを活用してソースコードに直接アクセスし、コードを元データとして新規開発のプロトタイプを作ったり、企画検討や初期見積もりを高精度に進めたりする未来は、もう遠くありません。 役割を超えて協業するための「のりしろ」を増やすことが、AI時代の開発組織に求められる視点 だと感じています。 この「のりしろ」があることで、Biz・PdM・エンジニアが同じデータを共有し、より速く高精度な意思決定ができる未来が見えてきます。 将来的にはAIの処理性能が向上し、複数プロジェクトや複数Webサービスを横断してカバーできるようになるでしょう。 その時に備え、現時点での最適解を常に更新し続けるチームでありたいと考えています。 おわりに〜生成AIの可能性 今回、久しぶりにコードへ戻りPRを出す中で感じた一番の収穫は、現場を離れていたベテランエンジニアでも、AIを活用すれば短期間でキャッチアップできると実感できたことです。 採用やマネジメントに注力していたエンジニアリングマネージャにとっても、生成AIは「現場感を取り戻すための強力な手段」になり得ます。 小さな修正でも構いません。AIを足がかりにコードへ再び触れることで、意思決定の精度やチーム理解は大きく変わります。 ただ正直、今回は「PRを出すとレビューしてもらうのが申し訳なく、遠慮してしまう」気持ちもありました。 だからこそ、AIに任せきりにするのではなく、自分なりの意見を持つためにも、まずはコードに触れてみることが大切だと思います。 これはマネージャだけの話ではありません。 現場のメンバーも「今のやり方がベスト」と思い込まず、AIを取り入れることで新しい速度感や発想を手に入れられます。 AI活用への温度差は、やがて成果や成長速度の差に直結します。 AIは、現場とマネージャの距離を縮め、チーム全体を底上げするツールです。 重要なのは「使うかどうか」ではなく、 「どう使い、どう組織に取り込むか」 です。 半年後、一年後にチームとしてどこまでスピードと精度を高められるかは、いまどれだけ実践と学びを積み重ねられるかにかかっています。 AIをチームの戦力に変えるために、今のうちから試行錯誤を重ね、未来の開発組織の在り方を自分たちで形作っていくことが大切です。
アバター
CTOの川口 ( id:dmnlk ) です。 ブログタイトル通りイベントをやります。2025/08/06(水)19:00 〜 21:00です。 base.connpass.com BASEでは、サービス運営13年目を迎えた今だからこそ直面している技術的課題や、その乗り越え方について、現場のエンジニアが率直に語るイベントを開催します。 日々の開発に加えて、10年以上継続するサービスならではの知見や悩み、リアルなエピソードをお伝えする予定です。 参考までに、以下の記事で取り上げたようなトピックにも触れる予定です: devblog.thebase.in パネルディスカッションではあまり外部に出てこないプリンシパルテックリードと話します。 社内記事ではこういうのとか devblog.thebase.in 個人ではこういう記事とか書いてます。 yaakai.to 社内で一番Claude codeとかを触っているはずなんでそのあたりについても色々話を聞こうと思っています。 今回のイベントは採用活動の一環ですが、「今すぐ転職したい」という方だけでなく、 「ちょっと話を聞いてみたい」くらいの温度感の方も大歓迎です。 懇親会では技術的な雑談もできるので、ぜひ気軽にご参加ください。 なお、「connpassで登録すると転職活動がバレそうで不安…」という方は、XなどでDMいただければ個別に対応します。
アバター
CTOの川口 ( id:dmnlk ) です。 ブログタイトル通りイベントをやります。2025/08/06(水)19:00 〜 21:00です。 base.connpass.com BASEでは、サービス運営13年目を迎えた今だからこそ直面している技術的課題や、その乗り越え方について、現場のエンジニアが率直に語るイベントを開催します。 日々の開発に加えて、10年以上継続するサービスならではの知見や悩み、リアルなエピソードをお伝えする予定です。 参考までに、以下の記事で取り上げたようなトピックにも触れる予定です: devblog.thebase.in パネルディスカッションではあまり外部に出てこないプリンシパルテックリードと話します。 社内記事ではこういうのとか devblog.thebase.in 個人ではこういう記事とか書いてます。 yaakai.to 社内で一番Claude codeとかを触っているはずなんでそのあたりについても色々話を聞こうと思っています。 今回のイベントは採用活動の一環ですが、「今すぐ転職したい」という方だけでなく、 「ちょっと話を聞いてみたい」くらいの温度感の方も大歓迎です。 懇親会では技術的な雑談もできるので、ぜひ気軽にご参加ください。 なお、「connpassで登録すると転職活動がバレそうで不安…」という方は、XなどでDMいただければ個別に対応します。
アバター
はじめに こんにちは!Data Platformチームでデータエンジニアとして働いている @shota.imazeki です。 弊チームでは、従来の分析基盤を段階的に刷新する取り組みを進めており、その第一歩として、ECS上で動かしていたAirflowをAWS上のマネージドサービスである Amazon Managed Workflows for Apache Airflow(以下、MWAA)に移行しました。 もともとはインフラ管理の手間を減らすことが目的でしたが、結果としてバッチ処理時間が大幅に短縮されるという意外な効果も得られました。 この記事では、ECS上のAirflowからMWAAへの移行に至った背景や、工夫したポイント、得られた改善効果などを紹介していきます。 移行に至った背景 これまでBASEではECS上でApache Airflow v1を運用していましたが、運用負荷が高く、インフラ周りの管理には別チームの支援をお願いすることもありました。またECS用に稼働しているRDSのストレージ容量が逼迫しつつあったことも大きな課題の一つでした。 また、Airflow v1ではサポートされていないオペレーターや機能があり、ワークフローの設計・実装に制限が課されていました。従来の分析基盤を刷新していくにあたり、これらの制約は大きな障壁になると判断し、基盤の中核を担うオーケストレーションツールであるAirflowから着手することにしました。 その結果、Airflowのメジャーバージョンアップデートにあわせて、インフラ管理の負荷を軽減できるマネージドサービスであるMWAAへの移行を決断しました。 環境構築と移行準備 最初にMWAAの公式ドキュメントを参考にしながら環境構築を行いました。事前に必要なものとしては、バージョニングが有効化されたS3バケットのみで、それ以外のVPCやセキュリティグループ、IAMロールについてはMWAAのマネジメントコンソール上で作成しました。 参考: https://docs.aws.amazon.com/ja_jp/mwaa/latest/userguide/get-started.html この環境構築の段階で工夫したことや躓いた点があったため、次にそれらについて触れていきます。 1. SSH鍵やAPIトークンなどの機密情報をSecrets Managerで管理する ECSで運用していた際は、Airflow上の環境変数やAirflow Variable, ConnectionにSSH鍵やAPIトークンなどを設定して管理してました。ただし、どこにどの情報を置くかの基準が曖昧になっており、管理が煩雑化していたため、移行に合わせて管理方法を見直しました。 MWAAでは S3にファイルとして配置して参照する方法 もありますが、以下の観点からSecrets Managerに統一しました。 セキュリティ管理の観点 情報更新時の作業負荷軽減と安全性向上 MWAAへの移行に伴い、機密性の高い情報は全てSecrets Managerに保存し、Airflowから直接参照する設計 に切り替えました。 MWAAのAirflow設定オプション MWAA環境構築時に、Airflow設定オプションで[カスタム設定を追加]を選択し、以下のキーと値のペアを追加します。 secrets . backend : airflow . providers . amazon . aws . secrets .secrets_manager. SecretsManagerBackend secrets .backend_kwargs: { " connections_prefix " : " airflow/connections ", " variables_prefix " : " airflow/variables " } MWAAからSecrets Managerへのアクセス設定 MWAAからSecrets Managerに安全にアクセスできるよう、IAMロールとポリシーを設定しました。セキュリティを考慮して、 airflow/* という名前の Secretsのみアクセスできるようにスコープを絞っています。 参考: https://docs.aws.amazon.com/ja_jp/mwaa/latest/userguide/mwaa-create-role.html#mwaa-create-role-attach-json-policy { "Version" : "2012-10-17" , "Statement" : [ { "Effect" : "Allow" , "Action" : [ "secretsmanager:GetResourcePolicy" , "secretsmanager:GetSecretValue" , "secretsmanager:DescribeSecret" , "secretsmanager:ListSecretVersionIds" ], "Resource" : "arn:aws:secretsmanager:{リージョン}:{アカウントID}:secret:airflow/*" }, { "Effect" : "Allow" , "Action" : "secretsmanager:ListSecrets" , "Resource" : "*" } ] } Secrets Manager側の設定 Secrets Managerにて、以下のように名前を付けて情報を保存します。複数のパラメータをまとめたい場合はJSON形式にしておくと、Airflow側で分割して取得する必要がなく便利でした。 airflow/connections/SSH_CONNECTION { "conn_id" : "SSH_CONNECTION" , "conn_type" : "ssh" , "host" : "192.0.2.0" , "login" : "centos" , "port" : 22 , "extra" : { "private_key" : "-----BEGIN RSA PRIVATE KEY----- \n <秘密鍵の内容は伏せています> \n -----END RSA PRIVATE KEY-----" } } airflow/connections/GCP_CONNECTION { " conn_type ": " google_cloud_platform ", " extra ": { " project ": " sample-project ", " keyfile_dict ": { " type ": " service_account ", " project_id ": " sample-project ", " private_key_id ": " abc123def456 ", " private_key ": " -----BEGIN PRIVATE KEY----- \n <秘密鍵の内容は伏せています> \n -----END PRIVATE KEY----- \n ", " client_email ": " sample-sa@example.com ", " client_id ": " 1234567890 ", " auth_uri ": " https://accounts.google.com/o/oauth2/auth ", " token_uri ": " https://oauth2.googleapis.com/token ", " auth_provider_x509_cert_url ": " https://www.googleapis.com/oauth2/v1/certs ", " client_x509_cert_url ": " https://www.googleapis.com/robot/v1/metadata/x509/sample-sa%40sample-project.iam.gserviceaccount.com " } } } airflow/variables/API_TOKEN abcdefg1234567890 DAGからの利用例 その後、DAGファイル上で以下のようにコードを書くことでSSH鍵やAPI_TOKENを利用することが可能になります。 from airflow.providers.ssh.operators.ssh import SSHOperator from airflow.providers.google.cloud.operators.bigquery import BigQueryExecuteQueryOperator from airflow.models import Variable # Secrets Manager に保存された SSH Connection を利用 ssh_task = SSHOperator( task_id= 'ssh_task' , ssh_conn_id= 'SSH_CONNECTION' , command= "echo 'Hello MWAA!'" , dag=dag, ) bq_task = BigQueryExecuteQueryOperator( task_id= 'bq_task' , sql= "select 'Hello MWAA!'" , use_legacy_sql= False , location= 'asia-northeast1' , gcp_conn_id= 'GCP_CONNECTION' , dag=dag, ) # Secrets Manager に保存された API トークンを取得 token = Variable.get( 'API_TOKEN' ) これにより、従来の環境変数やAirflow Connection、S3によるファイル管理と比較して、より明確かつ安全に機密情報を一元管理できるようになりました。 2. フォルダ構成の整理 MWAAではDAGファイル以外にも、以下のような共通リソースを利用するため、dagsフォルダ配下に用途ごとに整理しました。 dags/ ├── sample_dag1.py # DAGファイル ├── sample_dag2.py ├── plugins/ # カスタムオペレーター、フックなど │ └── custom_operator.py ├── sql/ # クエリファイル │ └── sample_query.sql └── common/ # 共通関数やユーティリティ └── utils.py MWAAのS3バケットでは、dagsフォルダ直下がPythonモジュールパスとして認識されるため、DAGファイルと同じ階層配下( dags/ )に共通リソースをすべてまとめています。 そのため、DAGファイル内では以下のようにシンプルにインポートできます。 from common.utils import some_function from plugins.custom_operator import CustomOperator SQLファイルの利用方法 Airflowで利用するクエリは以前から .sql ファイルで管理しており、この運用をMWAAでも継続しています。DAGのtemplate_searchpathにsqlフォルダを設定することでBigQueryExecuteQueryOperatorにファイル名を指定すればクエリを実行できます。 from airflow.providers.google.cloud.operators.bigquery import BigQueryExecuteQueryOperator # DAGオブジェクトの作成(詳細は省略、SQLファイルの検索パスのみ記載) dag = DAG( dag_id= 'base_dwh' , template_searchpath=[ '/usr/local/airflow/dags/sql' ], ) bq_task = BigQueryExecuteQueryOperator( task_id= 'bq_task' , sql= 'sample_query.sql' , # sqlディレクトリ配下のファイル use_legacy_sql= False , location= 'asia-northeast1' , gcp_conn_id= 'GCP_CONNECTION' , dag=dag, ) もちろんJinjaテンプレートにも対応しており、DAG実行時に動的に値を埋め込むことも可能です。以下は、Airflowの組み込みマクロ( {{ ds }} )と、DAG側から params を使って渡した値の両方を SQLファイル内で利用する例です。 -- sample_query.sql SELECT column1, column2 FROM `sample_dataset.sample_table` WHERE DATE (column_date) = ' {{ ds }} ' AND category = ' {{ params.category }} ' DAG側では、 params に値を渡すことで、SQLファイル内のJinjaテンプレートが展開されます。 from airflow.providers.google.cloud.operators.bigquery import BigQueryExecuteQueryOperator bq_task = BigQueryExecuteQueryOperator( task_id= 'bq_task' , sql= 'sample_query.sql' , use_legacy_sql= False , location= 'asia-northeast1' , gcp_conn_id= 'GCP_CONNECTION' , params={ 'category' : 'category1' }, # params で category を指定する例 dag=dag, ) 3. GitHub Actions で MWAA への自動デプロイ ECS時代もCircleCIを使ってCI/CDによるデプロイを行っていましたが、MWAAではS3にファイルを配置する方式になるため、移行にあわせてGitHub Actionsに切り替え、デプロイ方法も見直しました。 構築した内容 GitHub Actionsによって以下を自動化しました。 mainブランチへのマージ時に、DAGファイル・plugins・共通処理・SQLファイルなどに変更があれば、S3にアップロードする。 以下はそのGitHub Actionsのサンプルです。 name : Deploy MWAA DAGs on : push : branches : - main paths : - 'dags/**' jobs : deploy : runs-on : ubuntu-latest steps : - name : Checkout repository uses : actions/checkout@v4 - name : Configure AWS credentials uses : aws-actions/configure-aws-credentials@v2 with : aws-region : ap-northeast-1 # 使用している AWS リージョン aws-access-key-id : ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key : ${{ secrets.AWS_SECRET_ACCESS_KEY }} - name : Sync DAGs to S3 run : aws s3 sync dags/ s3://sample-airflow-dag-bucket/dags/ --delete - name : List uploaded DAGs run : aws s3 ls s3://sample-airflow-dag-bucket/dags/ なお、 requirements.txt が更新された場合はMWAA環境の更新が必要です。現在は手動で対応しているものの、今後はGitHub Actionsによる自動反映も検討しています。 ただし環境更新中は一時的にMWAAが停止するため、バッチ処理への影響がないタイミングで実行する必要があり、このあたりは慎重に検討していきたいと考えています。 4. requirements.txt で発生した問題と対処 MWAAでも外部APIを利用するために、requirements.txtにライブラリを記載してインストールしています。ECS時代から利用していたgoogle-ads, facebook-businessなどの広告系API用ライブラリも引き続き使用していました。 発生した問題 MWAAでrequirements.txtを更新した際、次のような問題が発生しました。 一部のライブラリ(google-ads, facebook-businessなど)のインストール時にエラーが発生 MWAAはpip installが1つでも失敗した場合、全てのインストールが中断される(All or Nothing)仕様 そのため、全てのDAGで必須なapache-airflow-providers-*系ライブラリがインストールされず、DAGが動作しなくなる 原因 Airflow公式が提供しているconstraintsファイルと requirements.txt に記載したバージョン指定が衝突していました。たとえば、MWAA v2.8.1(Python 3.10)の場合、以下のconstraintsファイルが適用されます。 https://raw.githubusercontent.com/apache/airflow/constraints-2.8.1/constraints-3.10.txt このconstraintsファイルに含まれるバージョンと異なるバージョン(google-ads==22.0.0 など)を明示的に指定してしまうと、バージョン衝突によってインストールエラー → 全てのインストールが失敗ということになります。 参考: https://airflow.apache.org/docs/apache-airflow/stable/installation/installing-from-pypi.html#constraints-files 対応策 ローカル環境でAirflowのconstraintsを適用した状態で pip install を検証するようにしました。 # 仮想環境を作成 rm -rf venv python -m venv venv source venv/bin/activate # pip / setuptools / wheel を最新化 pip install --upgrade pip setuptools wheel # constraints を適用してインストール pip install -r requirements.txt \ -c https://raw.githubusercontent.com/apache/airflow/constraints-2.10.3/constraints-3.10.txt 特に以下に注意しています。 MWAAのバージョンごとに対応するconstraintsファイルを適用すること インストールしたいライブラリがconstraintsファイルで制約されているか確認すること 必ずローカルでインストールが成功することを確認してから、MWAAに反映すること MWAAへの移行作業 デプロイやSecrets管理などの仕組みが整ったので、実際の移行作業自体は比較的シンプルでした。 移行の進め方 DAGごとに独立していたため、全てを一度に切り替えるのではなく1つずつ順に移行・動作確認 TriggerDagRunOperatorを用いたDAGのみ、まとめて切り替え 影響範囲の小さいDAGから順に移行することでリスクを抑制 v1の時は実装上の都合からBigQueryのクエリ実行やSlack通知などで自作していたOperator / Hookを以下の観点からAirflow公式のProviderに置き換え 保守・メンテナンスコストの削減 Airflowバージョンアップ時の互換性確保 Providerごとに細かな改善・バグ修正が取り込まれている その他 MWAAの動作環境(PythonバージョンやAirflowバージョン)に合わせて、コードの微修正も行いました。 機密情報の管理やDAG配置場所の変更も事前に行っていたため、その部分のコードの微修正のみでDAG本体の移行作業自体はスムーズに完了しました。 移行によって得られた意外な効果 MWAAへの移行を進めた主目的は「インフラ管理の手間削減」でしたが、思わぬ性能改善という効果も得られました。 処理時間の改善 もともと日次バッチとして実行していたデータ連携処理では、1日あたり約14時間の処理時間がかかっていました。MWAAに移行した結果、約9時間で完了するようになり、4〜5時間ほど短縮されました。 詳細に見ていくと、ECS側では各タスクの開始間隔にも約30秒の遅延があり、日次バッチ全体では約500タスク × 30秒 = 約4.2時間の待機時間が発生していました。MWAAではこの待機時間がほぼなくなっており、これによって処理時間が改善されたと考えています。 原因の考察 さらに調査したところ、ECSの方ではExecuterがSequentialExecutor(逐次実行)になっていましたが、MWAAではデフォルトでCeleryExecutor(並列実行)が使用されていたためでした。 ECS時代はシンプルさを優先して SequentialExecutor を使用しており、タスクは1つずつ実行していました。一方、MWAAではCeleryExecutor(またはKubernetesExecutor)がデフォルトで、タスクが依存関係に応じて複数同時に実行される構成となっています。これにより、独立して動作可能なタスクは自動的に並列実行され、タスク間の待機時間も解消されたため、全体の処理時間が大幅に短縮されたと考えています。 なお、ECS時代でもExecutorの設定を変更すれば並列実行による改善は可能だったかもしれません。ただし、そうした調整やメンテナンスを自前で行うことなく、マネージド環境がデフォルトで最適な構成にしてくれるのも、MWAAを選んだ大きなメリットだと感じました。 影響範囲 タスクが並列実行されることによる影響がないか、以下の観点で確認しました。 元データベースへの影響について MWAAへの移行によって処理の並列化が進みましたが、ETLツールとしてメインで利用しているEmbulk自体は逐次的に実行されるようになっているため、元データベースへの負荷が並列実行で急増することはありませんでした。単純に待機時間が減ったのみで、移行後も元DBへの負荷増加を心配することなく、安定して運用できています。 並列実行によるタスク間の影響 同じテーブルや同じファイルへの出力などをDAGのタスク内で行なっておらず、タスクの依存関係(task1 >> task2)をDAG内で明示していたために同時実行がなされても問題にはなりませんでした。今後もExecutorに依存しない(並列実行されても問題ない)堅牢なDAG設計を継続していきます。 今後の改善点 1. DAGsフォルダ直下のファイル整理 現在、 dags フォルダ直下にDAGファイルだけでなく plugins/ , sql/ , common/ といった複数のフォルダが混在している状態です。 将来的には、DAGファイルと共通リソースをより分かりやすく整理し、管理・メンテナンスしやすい構成に改善したいと考えています。 2. Terraformによるインフラ構成管理 MWAA環境やSecrets Manager、S3バケットなどのAWSリソースをTerraformで管理することで、環境構築や変更の再現性を高め、運用負荷の軽減を図りたいです。 現状は手動で設定している部分も多いため、IaC化による標準化・自動化が望まれます。 おわりに Airflowの移行によって、運用負荷の軽減だけでなく、思わぬ性能改善も得ることができました。 今後も基盤全体の改善を進めながら、より安定したデータ連携基盤を目指していきます。 最後となりますが、弊社ではデータエンジニアを募集しています。上記で述べた課題以外にもBASEの分析基盤には多くの課題があって、とてもやりがいのある仕事かなと思っております。ご興味のある方は気軽にご応募ください! open.talentio.com
アバター
AWS SUMMIT JAPANにあった社名を書くボード はじめに BASE BANK Dept で Engineering Program Manager をしている大津です。 BASEでは多くのプロダクトでAWSを使用しており、BASE BANK Deptでもフルサイクルエンジニアの思想のもと、AWSに触れる機会が多いです。そのため、AWSのキャッチアップはとても重要です。 なぜフルサイクルエンジニアを目指すのか / FullCycleDeveloperNight#1 - Speaker Deck 今回はAWSの最新情報を得るため、2025年6月25日(水)〜26日(木)に開催されたAWS Summit Japan 2025に参加してきましたので、その様子をお届けします! ちなみに昨年の参加レポートブログもありますので、そちらもぜひご覧ください。 devblog.thebase.in 基調講演 基調講演は大盛況で、本会場はもちろん、サテライト会場もほぼ満員の状況でした! AWSやAWSを利用しているパートナー企業の発表に加え、AIに関してはAnthropic社のプレゼンテーションなど、魅力的なトピックが目白押しでした! サテライトだけどなんとか座れた! 基調講演聴講します✌️ #AWSSummit pic.twitter.com/nYXHUW1h2J — 02 (@cocoeyes02) 2025年6月25日 おお!anthropic 日本オフィス開設 #AWSSummit pic.twitter.com/COh5DFCeYM — 02 (@cocoeyes02) 2025年6月25日 ブース 会場には様々な種類のブースが設置されており、AWSについて詳しく知ることができる「AWS Expo」や、各社のAWS活用事例を詳しく学べる「Partner Solution Expo」などがありました! バーチャルデータセンターツアー面白かった! 実際のAWSデータセンターをVRで見れる!空調とか発電機とか諸々実物見れるの面白い #AWSSummit pic.twitter.com/k9jBQ2LvAh — 02 (@cocoeyes02) 2025年6月25日 去年もブースみたchaos kitty! なんとwebアプリ機能ができた他、7 月中には AWS Samplesで公開予定とのこと! 社内でやりたいなーーー #AWSSummit pic.twitter.com/QFS1snXt9h — 02 (@cocoeyes02) 2025年6月25日 ポーカーライクなゲームでAWSについて学べる#スマポ! 会場では自分のスマホでプレイできるよ! 体にパターンを叩き込む感じがあって反射でパターン出せるようになりそうで良い #AWSSummit pic.twitter.com/M1Qoldh7lK — 02 (@cocoeyes02) 2025年6月25日 ちいかわの隣にゴリゴリのAWSアーキテクチャ図あるのすき #AWSSummit pic.twitter.com/4W8Hh55fxh — 02 (@cocoeyes02) 2025年6月25日 GameDay ゲームのようにAWSを体験できるワークショップGameDayにも参加してきました! aws.amazon.com 今回のGame Dayのテーマはgenerative AIで、AWSが提供している様々なAIサービスを中心とした内容となっていました! あまりにもGameDay参加したい欲が強くて最前列取ってしまった #AWSSummit pic.twitter.com/RgryNMNEOO — 02 (@cocoeyes02) 2025年6月26日 GameDay参加していきます!! #AWSSummit pic.twitter.com/GnZR4ZGV0x — 02 (@cocoeyes02) 2025年6月26日 惜しくも上位入賞はなりませんでしたが、個人的にはあまりキャッチアップできていなかった分野だったため、とても勉強になりました! GameDay 8位/22チームでした!残念! #AWSSummit pic.twitter.com/IGk1mlgqno — 02 (@cocoeyes02) 2025年6月26日 もらった公式ノベルティ また、先着配布のクッションやAWS認定ステッカーなど、魅力的なノベルティグッズも多数いただきました! サテライトだけどなんとか座れた! 基調講演聴講します✌️ #AWSSummit pic.twitter.com/nYXHUW1h2J — 02 (@cocoeyes02) 2025年6月25日 そういえばまだもらってなかったからAWS認定ステッカーもろた #AWSSummit pic.twitter.com/rs2GBx3s9z — 02 (@cocoeyes02) 2025年6月25日 Flight Tagもろた! #AWSSummit pic.twitter.com/QdqKyHf2Pp — 02 (@cocoeyes02) 2025年6月25日 おわりに 他にもセッションに参加したり、コミュニティブースでのLTを聞いたりと、このブログで書ききれないほど様々なコンテンツを見て、学び、体験してきました! やはりAWS Summitは、AWSについてキャッチアップするのに最適なイベントだと感じます。来年もぜひ参加したいです! BASE BANK Deptでは、AWSにも触れるフルサイクルエンジニアを募集しています。 まずはカジュアル面談からどうぞ! open.talentio.com open.talentio.com binc.jp
アバター
はじめに BASE の ProductDev でエンジニアをしているTorataです。 2025年6月28日(土)に開催された「PHP Conference Japan 2025」にBASEのエンジニアが登壇 & ゴールドスポンサーとして協賛したのでその様子をお届けします! ちなみに今年は例年とは違いホットな夏開催でした! BASEのスポンサーブースの紹介について 先日のブログ でも紹介した通りBASEのスポンサーブースでは「教えて!PHPerの皆さん」というテーマでのアンケート形式の企画を実施しました! アンケートは3つのお題を用意しました PHPで成功した事 or 苦労した事を教えて! AIツールをどのように活用しているか教えて! お気に入りの関数 or フレームワーク教えて! また、アンケートに答えてもらった or 気に入ったものにシールを貼ってくれた人には BASE でもショップを開設されている COZY COFEE さんのコーヒーパックを配布しました このショップさんはいつも季節に合わせたブレンドを作ってくれる素敵なショップさんなので気になる方はショップ覗いてみてください!! 当日は想定していたよりもたくさんの方にアンケートに答えていただき、アンケートボードも埋まるくらいの大盛況でした。 中でもAIに関する質問には回答が集中していて、AIブームの盛り上がりを感じることができました! 登壇の紹介 Capi ( @ysssssss98 ) BASEでWebアプリケーションエンジニアをしているCapi(かぴ)です。 今回は趣味で触ってる FrankenPHP を使いWebアプリケーションを動かす方法をLTで紹介させていただきました。仕事に直接活きる内容ではありませんが、PHPを取り巻く新しい技術を紹介できてよかったです。PaaSを利用して公開まで行えたのも個人的によかったです。もっと低レイアを深ぼり、次は深い話しができたら幸いです。 久しぶりに社外で登壇をして緊張しました。 speakerdeck.com プログラミングをするパンダ ( @Panda_Program ) 今回は PHPerKaigi 2025 のモジュラーモノリス 、 TSkaigi 2025 のクリーンアーキテクチャ の発表に続くオブジェクト指向設計の発表でした。スライドの中で「クリーンなコードとは認知負荷の低いコード」「Entity と Value Object の違い」や「コマンドメソッド・クエリメソッド・モディファイアメソッドを分けて書こう」などオブジェクト指向でコードを書くにあたり大切なことをお伝えしました。コード例も交えて紹介できたので、ここで得た知識を活用して日々の開発に活かしてもらえれば幸いです。 スライド作りで工夫した点は、markdownファイルをGoogle Slidesに連携してスライドを作るOSSの deck を使ったことです。各スライドの文字コンテンツをGoogle Slidesに反映できたので、転記の作業が大幅に省力化できました。また、今回サンプルコードはmarkdownファイルをClaude Codeに読み込ませて生成させたものをチェックし、採用しました。微調整をするだけで十分紹介できるコードを最初から出力してくれました。本スライドの最後に「このスライドをAIに読み込ませたらコード生成できる」と書いているのは、実際に自分が手元で試してうまくいったからです。 PHP Conference での登壇は2回目でした。今回はプロポーザルの段階でstar数が17、トラック4の会場は満員で立ち見が出るほどで嬉しい驚きでした(ネットにはアップしないものの、写真撮れば良かったと後悔しました笑)。オブジェクト設計は多くの方が関心のある内容なのだと実感したのと同時に、たくさんの方にこの内容を届けられたことが嬉しいです。 スライドにも書きましたが、自分一人がクリーンなコードを書いてもチーム開発においては不十分です。みんなが「この時はこう書くよね」という共通認識がないと独りよがりになってしまいます。このため、多くの方にこの内容が届けられたことは意義があると思います。 一方、この発表の内容は私の独創ではありません。 オブジェクト設計スタイルガイド という良書を参照しています。本書を使った読書会の進め方は、以前 ブログに書いている のでこちらもぜひご覧いただければと思います。ぜひチームでこの本の読書会をして、みんなでクリーンなコードを書きましょう! speakerdeck.com 当日見たセッションの紹介 PHP 8.4の新機能「プロパティフック」から学ぶオブジェクト指向設計とリスコフの置換原則 PHP8.4 で追加されるプロパティフックの紹介と後半は型システムの話も入れながらのプロパティフックが入ることにより何が変わるかの紹介でした。 個人的にプロパティフックがあることで今までと何が変わるの?書き方楽になるだけ?getter, setter じゃだめなの?と思っていたのでこれから使っていくぞ!と思えるような発表でした。 自動販売機を使った例えばとてもわかりやすかったです。 speakerdeck.com イベントストーミング図からコードへの変換手順 昨今のAIエージェントでコード生成が楽になるというのは身をもって体感していましたが、このセッションでは自分たちエンジニアがコードを書かなくなったらその時間を何に使うべきなのかを感じさせられるセッションでした。 ポリシーや外部システムとの連携など様々なパターンでの例があったのでイメージもしやすかったです。 イベントストーミングに賭けたくなりますね speakerdeck.com おわりに ブースに来ていただいたみなさま誠にありがとうございました! また、登壇された方々やスタッフの方もカンファレンスを盛り上げるために尽力していただき本当にありがとうございます。 おかげでいつもカンファレンスを楽しむことができています。 BASEは今後もカンファレンスイベントへの参加や登壇を積極的に支援しています もしご興味ありましたら採用情報も確認してください! binc.jp
アバター
はじめに BASE BANK Dept で Engineering Program Manager をしている大津です。 今回は、4月にリリースした最速振込とそれまでの歴史について簡単に触れつつ、どのようにプロジェクトのリードをしたのか書きます! baseu.jp 振込申請の種類と歴史 最速振込は、BASEが提供する振込申請の一つの種類です。 振込申請とは、ショップオーナーさんがBASEでの売上金額を自身の銀行口座へ振り込むため申請する機能です。 BASEの振込申請には、様々な種類があります。表にまとめると下記のようになります。 種類 振込日目安 手数料 通常振込 10営業日後 振込手数料+事務手数料のみ お急ぎ振込 翌営業日または翌々営業日 振込手数料+事務手数料+振込申請金額の1.5% 定期振込 当月末までの売上金全額を翌月25日に自動で振り込む 振込手数料+事務手数料のみ 最速振込 最短10分(土日祝日含む) 振込手数料+事務手数料+振込申請金額の3.0% 1. 通常振込 BASEの基本的な振込方式として、当初から提供されている振込方法です。一般的な決済サービスでは月末締め翌月入金が多い中、10営業日での入金サイクルを実現し、早期入金を可能にしました。 手数料は、振込手数料+事務手数料のみになります。 2. お急ぎ振込の導入(2020年2月) 個人やスモールチームが多いBASEショップのニーズに応えるため、より迅速な入金サイクルを実現する「お急ぎ振込」が導入されました。翌営業日または翌々営業日での入金を可能にし、キャッシュフロー改善に貢献しています。 手数料は、振込手数料+事務手数料+振込申請金額の1.5%になります。 3. 定期振込の導入(2022年7月) 申請の手間を軽減するため、当月末までの売上金全額を翌月25日に自動で銀行口座へと振り込まれる「定期振込」が導入されました。 手数料は通常振込と同じで、定期振込の設定はいつでも解除することができます。 4. 最速振込の導入(2025年4月) さらなる入金スピードを求めるショップのニーズに応えるため、お急ぎ振込よりもさらに早く早期入金を実現する「最速振込」が導入されました。主な特徴は下記のとおりです。 最短10分での入金が可能 土日祝日を含む365日対応 モアタイムシステム対応の金融機関であれば、当日中の振込が可能 手数料は、振込手数料+事務手数料+振込申請金額の3.0%になります。 どのようにプロジェクトのリードをしていったか まず前提として、私はEngineering Program Manager(以下EPM)というプロダクトのデリバリーとクオリティに責任を持つロールについています。 devblog.thebase.in 最速振込のプロジェクトでは、主に下記のようなリードをしていました。 最速振込の設計(アーキテクチャやDB・API利用などの基本設計、バッチの詳細設計、運用設計など)、実装、QAや本番テストの方針策定と実施 プロダクトマネージャーと連携して契約推進および関連ステークホルダーとの調整MTGの実施 スプリントやレトロスペクティブなどのチームイベントの運営 API調査からリリースまでの全体スケジュールのハンドリング リリース後の安定運用を目指した改修と保守 私個人としては中規模プロジェクトのリードは初めてでしたが、マネージャーと相談しながらいくつかの工夫を重ねてプロジェクトのリードをしていきました。 ロードマップをベースに、目標を示し続けてスケジュールをすり合わせする プロジェクトのリードをする人は、聞かれたらいつでも答えられなければならないことがたくさんあります。 現在のプロジェクトが順調に進んでいるかどうか どのマイルストーンやリリースターゲットを目指しているのか どのタスクの優先順位が最も高いか、タスクの漏れはないか 想定されるリスクは何か スケジュールが遅延している場合に、どのような具体的なリカバリー方法があるか これらの質問に答えられるよう、FigJamでロードマップを作成し、進捗管理を行っていました。 FigJamで作成したロードマップの図 ロードマップに記載する内容は、次のようなものです。 タスクの内容 担当者 見積もり(工数感) 作業ステータス タスクの依存関係(クリティカルパスがどこか) タスク開始と終了目安 などです。 このロードマップはプロジェクトハンドリングの基礎になります。 プロジェクトがどのくらいタスクが終わっている/終わっていないのか、今の状況を把握できる 漏れているタスクがないか客観的にわかる どのタスクを最優先にすべきか、スケジュールが遅れている場合どうリカバリするか考えやすい メンバーとのスケジュールのすり合わせも、このロードマップをベースに行うとスムーズに進む 作成するタイミングとしては、理想は一番最初です。それが難しい場合でも、なるべく早い段階で作成すると良いでしょう。 また、このロードマップは何度でも作成し直しても構いません。重要なのは、現時点でプロジェクトメンバーとスケジュールを通して、(リリース)目標とそのプロセスを示し続けられるか、そしてスケジュールのすり合わせができているかということです。 フェーズごとの終了条件を明確にする 今回の最速振込は、銀行と連携する外部連携を必須とする開発でした。しかし、どのような外部連携であっても「API調査」「設計」「実装」「QA」「リリース」といったフェーズが必要など、基本的な流れは共通しています。 ただ、各フェーズの終了条件を明確にしておかないと、そのフェーズで無限に時間を消費してしまいます。手戻りを減らしながらも開発を進めていくバランスを考え、適切な終了条件を設定する必要があります。 最速振込では、API調査と設計について下記のような終了条件を設定していました。 API調査:仮説ベースで最速振込にまつわる業務フロー図をたたき台として作成し、それが実現できるかどうかを調査。実現可能性が確認できた段階で、API調査を終えて設計へ移る 設計:全体の基本設計ドキュメントをベースに、それぞれのバッチなどの詳細設計が迷わず実装に着手できる(あるいは実装しながら詰めていく)ようになったら、バッチなどの詳細設計へ移り実装を始める 実際に動くものを一番に信じる なるべく不確実性をなくすには、実際に動くものをベースに考える必要があります。 外部連携は動かしてみないと分からないものが多いので、いかに早く動かせるか?本番リリース前に確かめられるか?を考える必要があります。 外部連携先の開発環境で正常に動作するか 最速振込では、できるだけ早く開発環境を入手できるよう契約関連を最優先タスクに設定しました。 また、開発環境で検証できる事項をあらかじめ整理し、検証できない項目は本番環境でのテストで確認することにしました。 本番環境で期待通りに動作するか 最速振込では、本番環境での実際の銀行振込テストを実施しました。本番環境でないと分からないことを放置したままリリースするのは非常に危険だからです。 このテストは実際に銀行口座へ入金が発生するため、事前に社内での稟議手続きやテスト実施ショップの準備なども丁寧に行いました。 プロジェクトのリードをする人の腕の見せ所 プロジェクトのリードを実際に経験して、特に腕の見せ所だと感じた点をいくつか紹介します。 いかに自分がボトルネックにならないプロセスを考えられるか vs いかに自分がクオリティに責任を持てるか 「自分がすべてを確認しなければ進められない」という姿勢は非現実的であるため、適切に権限委譲していくことが求められます。 ただし、忙しさを理由に単なる丸投げをしてはいけません。移譲のプロセスやissueチケットの書き方などを工夫する必要があります。また、継続的にissueチケットを作成・管理する「筋力」も必要です。 一方で、できるだけ多くのレビューを行う姿勢も大切です。プロジェクトのリードする人は品質に責任を持つ立場であり、レビューを怠ることがPJの進捗を止めることにもつながります。 とはいえ前述の通り、「自分がすべてを確認しなければ進められない」という姿勢は非現実的です。状況によっては、期間限定でレビューを他のメンバーに委ね、タスク消化に集中するという判断が必要な場合もあります。 この権限委譲の適切なバランスを見極めることが重要です。 スケジュールが遅れそうなときのリカバリ案がいくつ出せるか プロジェクトの開発を進めていると、スケジュールが遅れている状況もありうるでしょう。そうなった時に、すぐに「納期を伸ばす!」ではなく、どうリカバリするか、リカバリ案はいくつあるかを考えることが重要です。 例えば以下のようなリカバリ案があります。あくまで一例であり、プロジェクトの状況によってはさらに多くの選択肢があるでしょう。 タスクをさらに分解して、並行で作業ができる状態にしたり、クリティカルパスのタスクを進めやすくする 先んじて(特にクリティカルパスの中で)依存関係が多いタスクをこなし、タスクが終わるまでプロジェクト全体の進捗が止まる状態を防ぐ 依存関係のないタスクを用意しておき、いざというとき人員追加した際のタスクとして活用する このリカバリ案を出す能力は、実際に経験を積み、その経験を振り返りながら徐々に上達していくことで身につけられるものです。 リカバリが困難な場合、プロジェクトマネジメントの基本である「スコープ/リソース/納期」のどれを調整できるかという検討が必要になります。ただし、これは前述のリカバリ案の検討と実施を一通り行った上での最終手段と考えるべきです。 リソース すぐにチーム外にヘルプを求められるよう、タスクが適切に整理されているか プロジェクトの知識を効率的にインプットできる資料は用意されているか(ただしプロジェクト後半になるほど難しくなる) スコープ リリースに必要な機能や優先順位が明確についているか 納期 デリバリーの遅延が事業計画にどの程度の数字的影響を与えるか ステークホルダーはどう受け止めるか 越境するための関係値づくりやコミュニケーション力が問われる プロジェクトで開発する機能と業務は密接に関わっています。業務は想像以上に多くのステークホルダーが関与しており、これらのステークホルダーを考慮せずに開発を進めると、簡単に手戻りが発生してしまいます。 プロジェクトの最初の段階でステークホルダーを洗い出し、早めに相談を持ちかけることが重要です。 また、コミュニケーションにおいては、場の設計、ファシリテーション、対話、ドキュメント作成など様々なスキルが求められます。これらのスキルも、先述のスケジュールリカバリ案と同様に、実践と振り返りを繰り返すことで徐々に磨かれていくものです。 おわりに プロジェクトのリードをしてみると、する前とした後で、見えてくる景色には大きな違いがあると感じました。今後も積極的に経験を積んで上達し、プロジェクトのリードを通じて事業貢献できるエンジニアになっていきたいです! BASE BANK Deptでは、プロジェクトの開発リードをする / したいエンジニアを募集しております。まずはカジュアル面談からお待ちしております! open.talentio.com binc.jp
アバター
はじめに BASE BANK Department で エンジニア をしている池田聖示です。 入社して1年が経ちましたが、この間、アラートやお問い合わせの対応に積極的に取り組んできました。 今回は、その理由や意識していたことを振り返ってみようと思います。 アラート対応、ユーザーからのお問い合わせ対応の価値 主語を大きくしたくないですが、多くのエンジニアにとってアラート対応などは敬遠されがちだと思います。 確かに、集中して取り組んでいるタスクを中断しなければならないこともあり、スイッチコストもかかります。 しかし、私はアラート対応やユーザーからのお問い合わせ対応の業務に大きな価値があると考えています。理由は、以下のような形で自分自身の成長にもチームへの貢献にもつながるからです。 キャッチアップにつながる 問題解決能力の向上 ユーザーの声に直接触れる貴重な機会 キャッチアップにつながる 私が所属しているチームでは、主に4つのプロダクトや機能を担当しています。 積極的に開発しているプロダクト以外は、なかなか普段のタスクでシステムの詳細を追うことが難しいです。 アラート対応やお問い合わせ対応を行うことで、データ構造や該当処理のコードを追うことができてシステムへの理解が深まります。 また、このエラーを出さないためにはどんな設計にすれば良いのか、どんなハンドリングが適切か、などを考えることができてエンジニアとして技術力を上げる機会になると思います。 実際に、エラーハンドリングの修正PRを上げることや、プロダクトのドキュメントに記述を追加するなどのアウトプットを行い、チームの資産にすることもできたと思います。 問題解決能力の向上 アラート対応やお問い合わせ対応などを行う際に、エンジニアだけに閉じず、他職種の方と連携して解決することが必要な場合があります。 例えばお問合せをもらった際に、「このような意図であっているか」、「更にこういった情報が欲しい」といった連携をしたり、 「システム的にこんな状態になっているのでユーザーに伝えたいがどんな風に伝えるのが適切か」などの相談をしたりと、コンテキストを共有することや、問題解決までの道のりを一緒に描くなどの職種を超えた連携の力を育むことができます。 ユーザーの声に直接触れる貴重な機会 ユーザーからのお問合せを受けることで、どのように機能を使っているか、どんなことで困っているのか、という情報に直接触れることができます。 ユーザーと向き合っている実感が持てる貴重な機会だなと思うと共に、 こんな風にヘルプ情報出したら良いかも、こんなUIにしたら分かりやすくなるかも、という考える機会になるためエンジニアとしての視野を広げることができると思います。 実際にどのような流れで行っているか 実際には概ね下記のような流れで行っています。 お問い合わせの場合 お問い合わせ文を見て回答すべきことを確認する 回答の根拠となる、情報を集めに行く 対象のソースコード、DB、ヘルプページ、ドキュメントなど 情報の整理を行い、回答する アラート対応の場合 アラートが発生したらSlackの通知が飛ぶので、そこからSentryを見に行く 該当ユーザーのデータを確認しつつ、リカバリー必要の有無を判断して実施する リカバリーが必要であればクエリを書いたりなどの対応を行う 根本原因を調査 根本原因への対策を検討 EPMやPdMとすり合わせて優先度付けを行う 意識していること お問い合わせの回答をする際に、どの情報を、どのように伝えれば過不足なく理解してもらえるか 根本原因への対策が運用手順書に書いてあったとしても、「なんでこの優先度の意思決定になったのか」などを追うことで、自分自身の成長に繋がるためissueを追って見たりします 進め方や解決策に関して積極的にフィードバックをもらいにいくことで、本当に良かったか、もっと良くするための方法を吸収していく 参照:EPMとは devblog.thebase.in 具体的な得 冒頭の結論で書いた 「キャッチアップにつながる」、「問題解決能力の向上」、「ユーザーの声に直接触れる貴重な機会」 でも記載した内容と重複するところもありますがまとめると下記の3点だと思います。 エンジニアとしての技術力の向上 仕事の進め方が良くなる 目の前の問題を解決するだけではなく、「もっとスムーズに解決するためには」、「そもそも起きないようにするためには」などのことを思考することで上記のような成長に繋がると思っています。 大変なこととその対処法 一時的にマルチタスクになると思うので忙しい、スイッチコストがかかるなどの負担があると思います。 ただ、EPMやマネージャーなどに適切にエスカレーションを上げることで、忙しいという面は解消できていますし、この相談も仕事の進め方能力向上につながると思っています。 具体的には、下記のような流れでEPMやマネージャーとコミュニケーションをとっています 目の前のアラート対応やお問合せ対応の緊急度を判断(既知の原因でのものか、機会損失になるか、今後のユーザーに影響が出るかなど) 目の前のアラート対応やお問合せ対応の概算の工数を見積もり、今の自分のタスクにどの程度影響が出るかを判断(30分程度で終わりそうであれば、その場で対応して終了) 必要があればissueを作成して重要度と緊急度なども含めて概要をまとめる 差し込みで対応するべきかバックログに積むかを検討してEPMやマネージャーと相談 差し込みでの対応なら見積もりなども踏まえて、差し込み前に対応していたissueの期限などを調整 意識していることは、アラートのスレッドや、お問合せのスレッドなど細かく現状の報告をするようにしています(調査開始時や、調査が長引きそうな時の中間報告など) 温度感や難易度などの情報をEPM・マネージャーと共有するために必要だと思っています。 補足: 私が所属しているチームのEPM・マネージャーがデイリーなどで、良しなに調整してくれているケースが多いので、私自身あまり差し込みで逼迫した経験がない前提ではあります。 まとめ アラート対応や、お問合せ対応は、大変な側面もありますが、個人的には得られる経験値は膨大であると思っています。 入社後のキャッチアップスピードを上げる。エンジニアとして技術力を上げる。仕事の良い進め方を身につける。など、意識次第で成長角度を上げることができるチャンスだと思います。 おわりに 今まで書いてきたことは私のチームが、メンバーの成長をサポートするという土壌が豊かであるという前提のものです。 アラート対応やお問合せ対応から成長するためには、適切なフィードバックやアドバイスが不可欠です。 BASE、BASE BANKでは一緒に働く仲間を募集していますので気になった方はぜひ下記リンクを見ていただけると嬉しいです。 binc.jp
アバター