はじめまして、プロダクト推進本部カイポケ開発部でエンジニアをしている木野と申します。 2025年1月に入社し、あっという間に1年が過ぎました。 入社して感じたこと、育児をしながら働いてみてどうだったかを中心に振り返っていこうと思います。 現在エス・エム・エスに興味をお持ちの方の参考になれば嬉しいです! ドメイン知識の習得と現場を知る大切さ 複雑な制度をシステムに落とし込む 私は介護事業者向け経営支援プラットフォーム「カイポケ」の障害福祉分野の開発に携わっています。 介護や障害福祉の事業所は、国が定めた制度に則って運営されています。 そのため私たちが開発する際も「行政から出される資料を読み解き、正しくシステムに反映すること」が何より重要になります。 制度、特に報酬算定(お金の計算)のルールは非常に複雑で、考慮すべきパターンや例外処理の難易度がとても高いです。 私は以前歯科向けの電子カルテ開発をしていた経験があり、厚生労働省の資料を読むことには多少慣れていました。ですが実際に障害福祉の分野に入ってみると、歯科とは考え方が異なる部分も多く、1年経った今も日々試行錯誤しています。 例えば歯科は「何をやったか(診療単位)」が基本ですが、介護や福祉は「誰が、どんなことを、何時間提供したか」といった要素の組み合わせで計算が変わります。 この「算定パターン」をどうシステムに落とし込むかを考えるのは、悩む場面が多いです。 ただこの難しさは同時に面白い部分でもあります。 制度の変更は現場のニーズや社会情勢が反映されたものです。資料を読み込み、落とし込んでいく作業を通じて、社会課題に向き合い、取り組んでいる実感が持てるのはこのドメインならではのやりがいだと感じています。 現場を知る 入社して早い段階で、実際の放課後等デイサービス事業所を訪問する機会をいただきました。 現場のスタッフの方々からお話を伺い、実際の忙しさや、業務上まだまだアナログが多い現状を直接目にすることができました。 本来の業務である「利用者への支援」に集中するため、事務作業を効率化する必要がある。 それを肌で感じたことで、自分が作っているシステムが解決すべき課題が明確になり、開発に向き合うモチベーションが高まりました。 実際の現場を見た後は、画面の入力方法を検討する際も「現場の入力負荷が増えないか?」「実際の業務フローとして不自然ではないか?」と、 解像度を上げて考えられるようになりました。 現場を知ることは、業務の解像度を高めるだけではなく、エンジニアとしての視点を広げるためにとても大切だと実感しています。 こうした事業所見学や体験を通じて現場を知る機会は社内に定期的にあり、 現場の「肌感覚」を大切にできる環境は非常にありがたいなと思っています。 「なぜやるのか」という文化 入社して一番驚いたのは皆さんのスキルの高さ、開発部全体に根付いている「なぜこれをやるのか」を考える意識の高さでした。 単に「どう実装するか」という技術的な話だけでなく、「なぜこれをやるのか」「なぜこの修正が必要なのか」「それによって誰がどう幸せになるのか」という問いかけをとても大切にしています。 もし自分の考えがぼんやりしていれば、納得いくまで前提から丁寧にすり合わせをしてくれます。 このおかげで、ブレることなく進められた場面が多くありました。 最初はレビューで「なぜこの実装にしたのか?」と問われても、言語化できずに固まってしまうこともありました。 チームのメンバーは、単に正しい書き方を教えるのではなく、「どういう理由でこの形にしたのか」という意図を根気強く引き出そうとしてくれました。 そのおかげで目先のコードの書き方だけではない、開発の根底にある「考え方」の大切さに気づくことができました。 この文化はコードレビューや設計の場だけでなく、チームの運営や方針を決める際にも徹底されていると感じます。 納得できないことがあればオープンに質問でき、それに対して「なぜこれを行うのか」を納得いくまで議論しています。 「なぜやるのか」を全員が徹底していることで、「誰のどんな助けになるのか」が明確になり、より誠実にプロダクトに向き合えているのだと感じています。 日々どうすればもっと良くなるかを考え抜いている皆さんをみて、1年経った今、私も自然と「なぜやるのか」を自問自答できるようになってきたと感じます。 今後は私もそんな風に、誰かの視界をクリアにできる存在を目指していきたいです。 モダンなツールとチームの支え 実際の開発業務では、本格的なJavaの開発は初めてで戸惑いもありました。 それでも、AIツールの活用やチームメンバーによる丁寧なレビューに助けられ、無事にいくつかの案件をリリースできています。 最近は、AIを日々の実務にうまく取り入れる流れが活発です。 個人としては、テストコードの作成やセルフレビュー、ドキュメント作成など日常的な作業の各所で活用しています。 チームとしても共通で使える各種設定を作成したりと、効率化がどんどん進んでいます。 先日もチーム間でAI活用の情報交換会が行われました。 「具体的なプロンプトをどう工夫しているか」といった現場ならではの共有が多く、非常に参考になりました。最新情報の共有もSlackなどで日常的に行われており、ツールを使いこなしながら、より本質的な設計や議論に時間を割こうとする自然な雰囲気があると感じています。 子育てとフルリモートワーク 「家族優先」が当たり前の空気感 私は現在、未就学児2人の育児中です。 入社直後は「急な欠勤や早退で迷惑をかけるのではないか」と心理的なハードルを高く感じていました。 その不安をオファー面談でお伝えしたところ、入社前に子育て中のエンジニアの方々とお話しする「座談会」を設けていただけました。 育児している時間が減るが、技術的なキャッチアップはどうしているか 急な休みはどう調整しているのか お迎えで1度抜けたり柔軟な勤務は可能か といったリアルな話をフランクな雰囲気で聞けたことが、入社を決める大きな安心材料になりました。 実際に働いてみると、開発部全体に「家族や自分の体調を最優先にする」空気が文化として根付いているのを実感します。 例えば、子供が急に発熱して中抜けや欠勤が必要になった際も、チームの皆さんが「お大事に!」「家族優先」と、当たり前のようにフォローし合える環境があります。 入社直後、メンバー数名体調不良で不在だった時期がありました。 その際も「お互い様だから無理せず休もう」という空気感が徹底されており、新入社員としての心理的なハードルがすっと下がったのを覚えています。 フルリモートで働くこと フルリモートと聞くと、コミュニケーションや情報のキャッチアップに不安を感じる方も多いかもしれません。 実際、社内には膨大なドキュメントやアウトプットがあるため、最初は情報の多さに圧倒されることもありました。 ただ、次第にすべてを完璧に追うのはやめて、esaの検索を工夫したりAIツールで要約したりと、自分なりのハンドリング術を模索するようになっています。 この情報の取捨選択スキルは、この1年で得た意外な収穫のひとつです。 Slackでのコミュニケーションも驚くほど活発です。 子育て中のメンバーが集まるチャンネルや趣味のチャンネルなど、業務外のつながりも多いため、リモート特有の孤独感を感じることはほとんどありません。 加えて、日々の業務における連携のオープンさも、大きな安心感につながっています。 例えば、メンションをつけていない独り言のような投稿に対しても、誰かがさっと解決策を提示してくれたり、類似案件を教えてくれたりすることがあります。 困ったときはすぐに「ハドル(音声通話)しようか」と声がかかるので、自宅で一人悩んで孤立することもありません。 程よい距離感の交流会もあり、オンライン越しでもチームのつながりをしっかりと感じられています。 終わりに 1年を振り返ってみました。 改めてエス・エム・エスに入社して良かったと感じています。 業務解像度が上がってきた今、新しいことにチャレンジをしながらさらに頑張っていきたいと思います。
こんにちは、エス・エム・エスでプロダクト推進本部人事をしている韓( @ssket0809 )です。 2026年3月20日〜22日に開催された PHPerKaigi 2026 に、エス・エム・エスがスポンサーとして参加しました。ブース出展もおこない、多くのエンジニアの方々と交流させていただきました。 phperkaigi.jp イベントスタッフの皆さん、参加された皆さん、そして弊社ブースでアンケートに答えてくださった皆さん、本当にありがとうございました。 この記事では、スポンサー参加の背景、ブースで取り組んだこと、当日の様子についてレポートします。 PHPerKaigi 2026とは PHPerKaigiは、PHPを愛するエンジニアたちが集まる年次カンファレンスです。2026年は中野セントラルパークカンファレンスにて開催され、44本のセッション、22本のLT(ライトニングトーク)があり、非常に密度の高い3日間でした。 エス・エム・エスとしてPHPerKaigiへの参加は2年ぶりです。今回のスポンサー参加では、PHPerKaigiを一緒に盛り上げたいのと同時に、弊社の キャリア事業 領域におけるプロダクト・技術の認知をエンジニアコミュニティに広げていきたい、という背景もありました。それもあり、そのプロダクト開発を担う 人材紹介開発グループ のメンバーが中心となってブースに立ち、PHPを使ったプロダクトの技術的な取り組みや、チームの開発スタイルについて来場者と直接対話しました。 ブースのコンセプト ブースには、Day0からDay2までエンジニア9名が参加しました。 Day1の集合写真 Day2の集合写真 弊社のキャリア事業のプロダクトは、PHPをはじめとする技術スタックで開発されています。ただ正直なところ、どういうチームでどういう開発をしているのか、外部への情報発信がまだあまりできていませんでした。そのため「エス・エム・エスにこういうプロダクトがある」「こんな技術課題に取り組んでいる」という認知が、エンジニアコミュニティにはほとんど届いていないのが現状でした。 今回のブースはキャリア事業の認知を変えていくための1つ目の施策でもあります。そこで、採用パンフレットを並べるのではなく、 アンケートパネルを用意して来場者と対話する という形をとりました。具体的には、アンケートパネルを用いて来場者にエンジニアとして大切にしているポイントを答えてもらいながら、自然な流れでエス・エム・エスのプロダクトや技術についてお伝えしていきました。 アンケート結果 当日盛り上がったアンケートの結果を振り返ってみます。 アンケートの回答で最も多かったのが、「 ビジネスと距離が近い 」という選択肢でした。ただ、会話をしていると「ビジネスと距離が近い」が意味するものは人によって少し違うのが面白くて、PdMをビジネスサイドと捉えてそことの距離感を指している人もいれば、営業やマーケ職などとの近さを指している人もいました。 生成AIが開発の現場で当たり前のように使われるようになった今、コーディングスキルだけではなくビジネスの文脈を理解して価値を生み出せるエンジニアが求められている、そういった変化を含め、来場者の生の声はいろいろと考えさせてくれるものでした。 また、会話の中で気づいたのが、「エス・エム・エス」という社名は知っていても、事業内容はほとんど知らないという方が多かったことです。医療・介護・ヘルスケア領域の人材紹介を手がけているとお伝えすると、「社会貢献性が高い事業ですね」「日本社会にとってとても重要ですね」という反応をいただくことが多く、改めて自分たちが取り組んでいる事業の意義を感じる場面でもありました。 こういった本音の声を直接聞ける場は、普段のオンライン面談では得られない貴重な機会だと感じています。 セッションの感想 どのセッションやLTも熱量が高く、弊社メンバーが参加したセッションの感想をいくつか紹介します。 接続—パフォーマンスチューニングの最後の一手 〜点と点を結ぶ、その一瞬のために〜 チューニングを「接続」という観点で体系的に捉え直すセッションでした。アプリケーション全体の構成を俯瞰し、どこでリクエストが発生してどこで処理されているかを把握することで、コードを書いている最中には意識しにくい「接続点」が見えてくる、そんな視点を改めて学ぶことができました。 肥大化したRepositoryクラスで責務分割で解決しようとした話 EC領域の注文情報を扱うRepositoryクラスがドメインの複雑さゆえに肥大化した問題を、「注文ステータスを更新する」といった動詞や、更新の起因(ユーザーによるものかシステムによるものか)に着目することでチーム内の共通認識を形成し、サービスクラスとして切り出すことに成功した話が印象的でした。 ビジネスがわかるエンジニアになろう:経営学とエンジニアリング、その共通点と活用法 日々のエンジニアリング業務にMBA的視点をもって臨むという話で、MBAの課題解決フレームワークが日々のエンジニアリング業務に使えるという視点で面白かったです。 参加を通じて感じたこと 人材紹介開発グループとしてカンファレンスにブース出展するのは今回が初めてでした。参加したメンバーからは「ブースを出してよかった」「来場者と直接話せて楽しかった」「自分たちの認知を広げることの大切さを実感できた」といったポジティブな感想が多く集まりました。同じグループ内でも普段は異なるチームで働いているメンバー同士が一緒にブースに立つ機会はなかなかないので、そういった意味でもお互いを知れる良い機会になったと思っています。 エンジニアとしてではなく採用・組織づくりの立場で参加していた私にとっても、「このプロダクトに関わりたい」「このチームで働きたい」と感じてもらえる組織であり続けることの大切さを、改めて実感する3日間でした。 まとめ 今回PHPerKaigiにスポンサーとして参加し、来場者の皆さんと直接対話できたことは、私たちにとって大きな収穫でした。エス・エム・エスでは引き続き、技術コミュニティへの貢献と、エンジニアとの接点づくりを大切にしていきたいと思っています。 最後に、素晴らしいイベントを作り上げてくださったイベントスタッフの皆さん、セッションやLTで場を盛り上げてくださった登壇者の皆さん、そして弊社ブースに足を運んでくださった皆さんに、心よりお礼申し上げます。ありがとうございました!
はじめに はじめまして。介護/障害福祉事業者向け経営支援「カイポケ」の事業部でCS職(カスタマーサクセス/サポート)をしているTSUNOです。カイポケに携わって10年以上になります。 エンジニアではありません。プログラミングの経験もありませんでした。 そんな私がAIを活用して業務自動化ツールを開発した結果、 月17.7時間の工数削減 と 購買判断の適正化 を実現しました。 この記事は、非エンジニアのCS職がAIで業務自動化を進めた実践記です。AIでここまでできるんだ、という実感を持ってもらえたら嬉しいです。 なぜやろうと思ったのか カイポケのCSでは、お客様からの問い合わせ対応だけでなく、カイポケを利用するうえでの事務手続きまで、お客様の業務を幅広く支えています。 2024年11月、業務体制の変更にともない、新たに業務を引き継ぐことになりました。 この業務は完了までに多くのステップがあります(下図)。引き継いだのはそのフェーズ2の部分でした。 複雑な作業を、ひたすら繰り返す。通常業務にこれらが上乗せされる状況では、とてもではないですが手が回りません。ちょうどその頃、無料版のChatGPTで簡単なGoogle Apps Script(GAS)を書く体験をしていました。もっと本格的にプログラムで業務を改善できるのではないか——そう考え始めたのが、すべての出発点です。 AI活用のステップアップ 最初から有料ツールを使っていたわけではありません。 無料ツールで小さく始めて、成果が出たら次のステップへ。その繰り返しで、気がつけば本格的な開発環境が整っていました。 大事なのは、 最初から大きな投資をする必要はない ということです。 時期 やったこと きっかけ 2024年1月〜 無償版ChatGPTでAI活用を開始 AI活用への興味 2024年11月〜 GASで業務自動化に着手 業務効率化の必要性が高まった 2025年1月頃 Google Workspace標準搭載のGeminiを活用 会社の環境変化 2025年11月 Claude Codeで本格的な開発へ AIツールの比較・検証を経て 2025年12月 Claude MAXプランへグレードアップ ROIを上司に提示して承認 ※ 各時期は筆者が知った・使い始めたタイミングであり、サービスのリリース時期とは異なります。 AI活用の情報収集は多方面から行いました。 X YouTube Google CloudユーザーコミュニティのJagu'e'r ※ Jagu'e'r (ジャガー) とは、Google Cloudユーザー企業が企業の垣根を超えて最新技術やノウハウを共有し合い、クラウド活用の変革を推進する公式コミュニティです。 特にJagu'e'rの無料ハンズオンセミナーでVertex AIに触れたことが、「APIを通じてAIを使う」というイメージを掴むきっかけになりました。この体験が後述するデータ移行支援ツールの技術選定につながりました。こうした外部の学びの場に加え、最近では社内エンジニア主催のClaude Code活用ナレッジ共有会にも参加しました。 よくわからなくても飛び込んでみると、新しい発見があるものです。 生成AIを使った3つの取り組み ここからは、AIを活用して取り組んだ3つの事例を紹介します。 # 事例 概要 1 GAS + 業務フローの見直し 6時間→2時間に圧縮 2 介護保険請求の事務手続きRPA※ 月17.7時間の工数削減 購買判断の適正化 3 AI駆動で開発中のデータ移行支援ツール 帳票の自動解析とデータ整形 ※ RPA(Robotic Process Automation):人がブラウザやアプリ上で行う操作をプログラムで自動化する技術 1.最初の成功体験 — GASで6時間の業務を2時間に AI活用で最初に取り組んだのは、GASによる業務自動化です。 コードは主にChatGPTで生成・修正しました。自分でゼロから書いたわけではなく、「こういう処理がしたい」とAIに伝えて、出てきたコードを実行し、うまくいかなければエラーメッセージをAIに貼って修正する——このサイクルを回すことで、コードは着実に動くものになっていきました。 結果、1日あたり約6時間かかっていた業務が約2時間に圧縮されました。ただし、これはGASによる自動化だけの効果ではなく、業務フロー全体の見直し(不要な手順の廃止や作業順序の組み替え)との合算です。GAS単体の削減効果として切り出せる数字ではありませんが、ツールを作ること自体が業務を棚卸しするきっかけになったという意味で、大きな一歩でした。 2.介護保険請求の事務手続きRPA — 業務自動化の本格展開 前述の業務見直しの過程で「GASでは解決できない業務」も浮き彫りになりました。業務の中には、介護保険の請求手続きに使う外部システム上で、ログイン・画面操作・帳票出力といったブラウザ操作を行う工程が含まれていました。 このシステムには外部からプログラムで連携するための仕組み(API)が提供されておらず、ブラウザを人の手で操作するしかありません。こうしたブラウザ操作はGASの守備範囲外であり、自動化するにはブラウザそのものを操作するRPAが必要でした。 なお、外部システムをRPAで操作するにあたっては、利用規約の確認や社内のリスクマネジメント部門への事前相談を行ったうえで開発を進めています(詳細は後述の「外部システムを操作する上での配慮」で触れます)。 介護事業所がカイポケを通じて介護保険を請求するには、このシステム上で各種手続きを行う必要があります。これらの作業は、全都道府県にわたる多数のアカウントに対して日々行われます。 以前にもこの業務を自動化するRPAツールが作られたことがありました。しかし、運用環境の変化に対応しきれなくなり、最終的に役割を終えていました。業務は再び手作業に戻っていたのです。 GASで積み重ねた成功体験が、「自分で作ろう。エラーが出ても、AIに聞きながら対処できる」という確信を支えていました。 成果①:月17.7時間の工数削減 RPAによる自動化で、月に17.7時間(稼働日20日/月換算で、1日あたり53分)の業務時間が削減されました。2026年1月時点の実績です。これらの業務はお客様の増加とともに件数が増える傾向にあり、今後さらに削減効果が拡大する見込みです。 数字には表れない変化もあります。以前はルーチン対応で手一杯でしたが、時間が生まれたことで、お客様への進捗報告をより適切な頻度で届けられるよう設計し直す余裕ができました。自動化の本当の価値は、 削減した時間そのものではなく、その時間で何ができるようになるか にあると感じています。 成果②:購買判断の適正化 工数削減以上にインパクトが大きかったのが、購買判断の適正化です。 従来の運用では、外部システムにログインして処理件数を一つひとつ確認する必要があり、全体の正確な把握が困難でした。そのため、実態より多めにアカウントを購入せざるを得ない状況が続いていました。 RPAがこのログインと件数取得を自動で行うようになったことで、実際の利用状況が正確に見えるようになり、不要なアカウント購入を回避してコスト適正化を実現しました。 こうした削減効果の見込みをROIとして上司に提示し、AIツールの上位プランの利用承認を得ました。承認後の実績データでもその効果が裏付けられています。「ツールの利用料に対して、これだけの時間が浮く」という説明は、社内で予算を取るうえで有効でした。 データが見えるようになると、正確な判断ができる と実感した出来事でした。 3.AI駆動で開発中のデータ移行支援ツール データ移行支援ツールは、RPAと並行して開発を進めてきたもう一つのプロジェクトです。現在は検証フェーズであり、RPAのような確定した成果はまだありません。ここでは「完成していなくても、非エンジニアがAIと一緒にここまで到達できる」という過程をお伝えします。 何を解決するツールか カイポケを導入いただく際、お客様がこれまで蓄積してきたデータを、カイポケに登録したいというニーズがあります。その際、帳票(PDF)を目視で読み取り、手作業で転記する。これは時間がかかるだけでなく、ミスが起きやすい作業です。 データ移行支援ツールは、この帳票をAI(Geminiをチャット画面ではなくAPI経由で利用)で自動解析し、カイポケに取り込める形式に変換する仕組みです。 Geminiアプリから始まり、Claude Codeで成長した 最初はGeminiアプリのチャット画面上で、1つのプログラムファイル(.py)にコードを書いていく形でスタートしました。「この帳票のこの項目を読み取って」「エラーが出たから直して」とやり取りしながら、少しずつコードを育てていきました。 しかし、コードが1,600行を超えたあたりで限界が来ました。チャットが一度に扱える文脈の範囲(コンテキスト)にコード全体が収まりきらなくなり、修正のたびに前後関係が途切れるようになったのです。 そこで切り替えたのが「Claude Code」という、テキスト入力で操作する開発ツールでした。プロジェクト全体のファイルを把握しながら、エージェントのように自律的にコードを編集・実行してくれます。 Claude Codeに切り替えてからは開発速度が大幅に上がり、1,600行の単一ファイルだったコードは、役割ごとにファイルを分けた9,300行超の構成にまで成長しています。 時点 規模 開発環境 初期 約1,600行・単一の.pyファイル Geminiアプリのチャット画面 現在 約9,300行 + テスト約1,800行・複数ファイル構成 Claude Code AIに任せる部分と、任せない部分 開発を進める中で、正確性の高いデータソースを優先する設計にたどり着きました。介護保険の請求データは、仕様書でCSV形式として定義されています。これらはCSVから確実に取得し、CSVでは得られない情報だけを帳票PDFからAIに読み取らせる「ハイブリッド方式」を採用しています。 CSV形式で確実に取得できるデータを、あえて精度にばらつきのあるAI読み取りに回す理由はありません。AIは帳票の読み取りで誤認識を起こすことがあるため、確実な手段があるならそちらを優先する。どのデータをどの方法で取得するかの線引きにも、ドメイン知識が活きています。 ※ 個人情報を含むデータのAI処理にあたっては、エンタープライズ向けのセキュアなサービスを利用しています。 現在地 開発環境での検証を経て、クラウド上で動くWebアプリとして構築し、ブラウザからアクセスできる状態にまで持ってきました。前述のハイブリッド方式は、実データを用いた検証でも一定の精度で動作することを確認しています。現在は様々なパターンのプロンプト(AIへの読み取り指示)を調整しながら、対応できる帳票の種類を増やしているところです。自分以外のメンバーが使える状態にすることは今後の課題です。 完成にはまだ時間がかかりますが、非エンジニアによる業務改善の新しい可能性を示せたと考えています。ここからは、3つの事例を通じて得た実践的な学びを共有します。 非エンジニアがAI駆動開発を進めるためのプラクティス 非エンジニアがAIを活用して成果を出すためには、具体的な手法の前に、まずベースとなる「心構え」からお伝えします。 まず押さえておきたい4つの心構え 1. プログラミング経験より、深い業務フロー理解 業務を深く理解し、常に改善点を模索すること。 2. 人間は「要件定義と判断」、AIは「実装担当」 「何を作るか」「どんなエラーが危険か」「どのデータをAIに任せてはいけないか」。こうした判断は人間の役割です。具体的な指示を出し、AIをコントロールすること。 3. AIの出力は「たたき台」として受け取る AIは自信満々に間違えることがあります。コードの中身をすべて理解するのは難しくても、「この修正で何が変わった?」「意図した設計になっている?」とAIに確認することはできます。複数のAIにクロスチェックさせるのも有効です。鵜呑みにせず、自分の言葉で問いかける習慣を持つこと。 4. 小さく始めて、成果を積み重ねる 小さな自動化の成功体験が、次の挑戦への自信と原動力になりました。まずは手を動かしてみること。 実践&組織で進めるための6つのプラクティス 心構えを土台として、私が実際にやってきた中で「これは他の人にも再現できる」と感じた具体的なアクションを6つにまとめました。 カテゴリ # プラクティス ひとことポイント 実践 1 AIへの指示は「業務の言葉」でいい 専門用語より「何を・なぜ・どうしたいか」 2 エラーは壁ではなく、手がかり エラーメッセージをAIに貼るだけで前に進める 3 テストもAIに書いてもらう ただし「業務的に正しいか」は人間が考える 4 環境構築は「AIに聞く → 裏取り → セキュリティ確認」 シャドーITを避ける手順を省かない 組織 5 成果を数字で見せて、リソースを得る ROIで上司の承認を得る 6 外部システムを操作する上での配慮 利用規約・社内承認・負荷配慮 1. AIへの指示は「業務の言葉」でいい プロンプトエンジニアリングだと身構える必要はありません。大事なのは、 業務の文脈を丁寧に伝えること です。データ移行支援ツールの開発初期に私がAIに伝えたのはこんな内容でした。 専門用語は一切使っていませんが、「何を・なぜ・どうしたいか」が明確なので、AIはセキュリティ設計、並列処理、エラーハンドリング、コスト表示まで一度に提案してくれました。「個人情報はログに出ないようにして」——こうした発想は、業務で日常的に個人情報を扱い、その重みを知っているからこそ生まれるものです。AIの出力品質を左右するのは、プログラミングの知識ではなく業務の知識です。 ただし、AIに任せきりでいい部分と、人間が厳密に設計しなければならない部分はあります。外部システムの仕様書を読み込み、帳票にどのような値が入ってくるのかを整理した上で読み取りのロジックを設計する——ここは業務を知っている人間が責任を持つ領域です。 2. エラーは壁ではなく、手がかり 非エンジニアにとって最大の壁は、エラーが出たときの対処です。でもやることは簡単で、 エラーメッセージをそのままAIに貼る だけです。実際の開発では、エラー対処を段階的にレベルアップさせていきました。 まず貼る — エラーメッセージをAIに貼って「これどうすればいい?」と聞く。大抵はこれで解決策が返ってくる 戦略を作る — エラーの種類ごとの対処方針をAIと一緒に設計する 仕組み化する — エラー発生時に画面キャプチャやHTML、処理ログを自動取得し、原因特定を容易にする ひとつ注意しておきたいのは、エラーは自分のコードだけから起きるわけではないという点です。Pythonのバージョンアップをしたところ、コードを一切変えていないのに、ライブラリが未対応でツールが動かなくなった経験もあります。「動いているものを維持する」難しさも学びでした。 3. テストもAIに書いてもらう 「このコードが正しく動くか確認するテストを書いて」とAIに頼めばテストコードは生成してくれます。ただし、AIが自動生成するのは「コードが技術的に正しいか」の確認です。 「業務的に正しいか」を確認するテストは人間が考える必要があります 。 たとえば「処理が中途半端な状態のまま放置されていないか」というテストシナリオは、実際の運用リスクを知っている人間にしか発想できません。AIに「こういうケースをテストしたい」と伝えれば、コード自体は書いてくれます。 4. 環境構築は「AIに聞く → ネットで裏取り → セキュリティ部門に確認」 必要なライブラリやセットアップ手順をAIに聞き、全体像を把握します。次にライセンス形態や開発元の信頼性をネットで裏取りします。その上で、社内のセキュリティ部門に「このツールを導入してよいか」確認します。 たとえばライブラリ導入時は、ライセンスが商用利用可能であること、開発元が信頼できることを確認した上で社内の専門部署に確認を取る——この手順を省かず、シャドーIT(会社の管理部門を通さずにツールを導入すること)を避けることが、長く使える仕組みにするための土台になります。 5. 成果を数字で見せて、リソースを得る 非エンジニアが業務時間を使って開発を進めるには、上司の理解が不可欠です。前述のとおり、削減効果を数字で示すことで上位プランの承認を得ました。 段階的にスケールし、各段階で成果を見せていくことで、次のチャレンジへの許可を得やすくなります。 6. 外部システムを操作する上での配慮 RPAの開発着手前に、以下の確認・配慮を行いました。 利用規約の確認 — RPAによる自動操作が明示的に禁止されていないことを確認 robots.txtの確認 — 対象システムにrobots.txt(RPAによるアクセス範囲を示すファイル)は設置されていないことを確認 社内承認 — リスクマネジメント部門に事前相談し、問題ないとの確認を取得 負荷への配慮 — 人間が操作するのと同等の速度で動作させ、未知のエラー発生時には自動停止する設計 おわりに — 属人化しない自動化を目指して 「あなたがいなくなったらどうなるの?」 ——避けられない問いです。実際、過去に社内で作られたRPAも引き継ぎがうまくいかず使われなくなった経緯があります。だからこそ、トラブルシューティングガイドや運用手順書といったドキュメントを整備するようにしています。そして何より、 AIがメンテナンスの「通訳」になれる 可能性に期待しています。コードを読めなくても、AIにエラーメッセージを貼れば対処法が返ってくる。作った人がいなくなっても回せる仕組みを作ること——その「属人化しない自動化」を目指して、今も試行錯誤を続けています。 データ移行支援ツールはまだ完成していません。模索中のことも多くあります。でも、非エンジニアだからこそ「使う側の目線」で作れる強みがある。業務を深く理解した人間にしか書けない要件定義がある。そしてAIが、その要件定義をコードに落とし込んでくれる。 自分で作るようになって、大きな気づきがありました。先述のPythonアップデートで動かなくなった経験を通じて、社内のエンジニアがフレームワークや基盤の更新に日々取り組む大変さを、身をもって理解できました。大規模なシステムを止めずに改善し続けるエンジニアの仕事に対する解像度が上がったことで、協業の質も変わったと感じています。非エンジニアが自分で作る経験は、エンジニアとの共通言語を増やすことにもつながるのです。 この記事を読んで、「自分もやってみよう」と思ってくれる方が一人でもいたら、書いた甲斐があります。最初の一歩は、「AIで何ができるか」を考えることではありません。「こんな作業が大変なんだよね」と、AIに壁打ちしてみること。そこに、活用のヒントがあるかもしれません。 追伸: 実はこの記事自体も、大部分をAIに書いてもらっています。構成案の作成、文章の推敲、さらには実際のプログラムと記事の内容に食い違いがないかの確認まで、AIと一緒に進めました。 ただし、「何を伝えたいか」「どんなストーリーで読者に届けるか」——その核となる設計は、自分の頭で考えました。AIは優秀な道具ですが、魂を込めるのは人間の仕事です。ツール開発もブログ執筆も、そこは変わらないと思います。
こんにちは!人材紹介開発グループでSRE活動をしている大上です。 私は2026年1月から、心機一転SRE領域に挑戦しています。SWEとして約7年のキャリアはありますが、AWSやインフラの世界ではまだ3か月目の初心者です。 そんな私が、人生初のオフラインイベント「JAWS DAYS 2026」に飛び込んできました。 本記事では、インフラ初心者かつイベント初参戦の私が、会場の熱気に揉まれながら何を感じ、どんな景色を見てきたのかを等身大でお伝えします。 参加に対する不安 正直なところ、参加が決まってから当日を迎えるまでは、期待よりも落ち着かない気持ちの方が大きかったように思います。SRE活動を始めてまだ日が浅い自分が、この大規模なイベントから何を持ち帰れるのか。その具体的なイメージを、当時は全く描けていなかったからです。 弊社ではこうしたイベントへの参加を業務の一環として認めてくれていて、交通費や宿泊費も会社がサポートしてくれます。とても恵まれた環境だなと感じる一方で、その手厚さから「しっかりと実務に役立つ成果を持ち帰らなければいけない」というプレッシャーがありました。 そんな中、周囲から「まずはイベントの雰囲気を知って、モチベーションを上げるだけでも十分価値があるよ」というアドバイスをもらって、少し気持ちが楽になりました。技術を身につけるのは時間がかかりますが、マインドは自分次第ですぐに切り替えることができます。今回はとにかく経験を積む場にしようと割り切ったことで、ようやく純粋な気持ちで会場に向かうことができました。 関心に沿ったセッション選び 当日は会場で迷子にならないように、「気になるセッションを片っ端から視聴する」というシンプルな作戦を立てました。タイムテーブルを見て事前に予定を組みましたが、その際に1つ自分の中で決めたルールがあります。それは、セッションの難易度を示すLevelを一切気にしない、ということでした。 SRE活動3か月目という状況から、高Levelのセッションは避けてしまうかもしれませんが、今回は今の自分自身の興味を優先しました。もちろん全てを完璧に理解できたわけではありません。しかし、SWEとして7年間システムを作ってきた経験があったからこそ、語られている設計思想や「なぜその構成にするのか」という論理的な部分は、自分なりのフィルターを通して解釈することができました。自分の関心に素直に従ったことで、最後まで集中力が途切れず、自分の引き出しにはなかった考え方を知るたび、視野が広がっていくような感覚がありました。 漠然としたAIへの不安 今、多くのエンジニアがそうであるように、私も「生成AIとどう向き合うべきか」という点には漠然とした不安を感じていました。特に新しい領域にチャレンジしている最中だと、「自分が今必死に覚えていることは、すぐにAIに取って代わられるんじゃないか」なんて考えてしまうこともあります。 しかし、今回のイベントを通じてその不安はかなり解消されました。第一線で活躍するSREの方々の見解に触れることで、SREとしての視点でAIをどう捉え、どう向き合うべきかという解像度が大幅に向上しました。特に印象に残ったのは、AIを「アンプ」に例えた考え方です。AIは人間の強みも弱点もそのまま増幅させてしまう性質があるため、ただ導入するだけではリスクも大きくなります。だからこそ、AIが踏み外さないための「ガードレール」や仕組みを整えるSREの役割は重要となってきます。 これまでは漠然とした不安を感じることもありましたが、今ではその輪郭がはっきりし、不安は期待へと書き換わっています。 会場の温度感 私は普段、福岡でフルリモート勤務をしています。リモートワークは集中できるし大好きな働き方ですが、今回のイベントで改めて「対面の温度感」の大切さを再認識しました。 参加前は、「堅苦しい講義」のようなものなのかなと考えていたのですが、現地で感じるお祭りのような空気感によって、一気に楽しいイベントへと上書きされていきました。情報はオンラインでも十分に手に入りますが、現場の空気はやっぱり別格でした。1000人以上ものエンジニアが同じ場所に集まって、同じ熱量で技術を語り合っている。そんな空間にただ身を置いているだけで、自分のモチベーションが内側からじわじわと底上げされていくのを感じました。 物理的な収穫も、オフラインならではの楽しみです。会場でいただいたノベルティは、作り込まれており、手に取るだけで嬉しくなるものばかりでした。こうした「モノ」としての思い出が手元に残ることも、デジタルな情報収集だけでは得られない、現地参加のご褒美のように感じます。 最後に 振り返ってみれば、参加前にあんなに悩んでいたのが嘘のように、前向きな気持ちでいっぱいです。 もし、今の私と同じようにイベント参加を迷っているという方がいたら、私は全力で参加してみることをおすすめします!経験年数や技術力は一旦置いておいて、その場の熱狂に身を任せてみることも大変貴重な経験となるはずです。 そして、最後になりますが、この素晴らしいイベントを企画・運営してくださった運営メンバーと当日スタッフの皆様、本当にありがとうございました!
こんにちは、プロダクト推進本部人事のふかしろ( @fkc_hr )です。 エス・エム・エスは先日開催されたJAWS DAYS 2026に協賛し、多くのメンバーとともに参加してきました! jawsdays2026.jaws-ug.jp イベントスタッフの皆さん、参加された皆さん、そして弊社ブースでアンケートに答えてくださった皆さん、本当にありがとうございました。 今回のブログでは、当日のブースの様子と、皆さんに協力いただいたアンケートの結果を共有したいと思います。 ブースのコンセプト 弊社は複数の事業やプロダクトを展開していて、エンジニアも様々なチームに所属しています。特にSREは各プロダクト開発チームの1チームとして所属していたり、全社横断して複数のプロダクトを見るというチームの形もあるため、今回のイベントには計3チームからメンバーが集まって参加することになっていました。 そこで「会社やプロダクトを紹介する」よりも「JAWS DAYS 2026というお祭りを一緒に盛り上げたい」「懇親会も含めて、参加者同士のコミュニケーションのきっかけになる場所を作りたい」と考え、以下の企画を用意しました。 アンケートパネル①:JAWSイベントの参加回数 × AWS経験年数 アンケートパネル②:「あなたの推しAIコーディングエージェントは?」 ノベルティ:AIエージェント名やロール、ちょっとしたネタを仕込んだ「缶バッジ」 缶バッジは自分の「推し」や「役割」を付けて歩くことでブース外でも会話のネタになればいいなと思って作ったのですが、AWS HEROの皆さんがたすきを止めるために活用してくださるという想定外な使われ方をしておりました。 アンケート結果 当日盛り上がったアンケートの結果を振り返ってみます。単なる利用率ではなく、タイトルの通り「推し」という表現にした結果以下のようになりました。 1. 全体傾向:3強の構図 ボードを俯瞰すると、Claude / OpenAI Codex / Kiroの3つに票が集まりました。 特にClaudeへの票の集まり方がすごかったですね。バックエンドやSRE層からの信頼が厚く「今のコード生成能力ならまずはClaude」という空気感がそのまま表れた結果になりました。一方では「インフラのようにカッチリした実装を行うのであれば余計な実装を行わないCodexも優秀」という声も聞くことができました。 「推し」という表現にしたことで頻繁に利用しているかどうかだけではなく、応援したいという思いや仕事では使えてないけど気に入っているという方もいらっしゃり、話のきっかけになりました。 ちなみにエス・エム・エスでは特定のAIツールのみを利用する方針ではなく、個人・チーム単位で利用してみることができます! 2. 職種別のこだわりが見える 職種ごとに見ていくと、面白い違いが見えてきました。 SRE / インフラ層:投票数が一番多く、参加割合の高さが伺えます。ClaudeとKiroが拮抗 バックエンド層:ほぼClaude一強 フロントエンド層:他の職種に比べてCursorへの投票が目立つ マネジメント層(EM/PdM等):特定のツールに偏らず、幅広く触っている印象 ChatGPTやClaudeのような「チャット型」だけでなく、エディタと深く連携して自律的にファイルを操作する「エージェント型」ツールを実戦投入しているエンジニアも多いのかと見受けられました。 また、個人的にはフロントエンドのエンジニアの数やその他ロールの方もいらっしゃって、色んな方が参加するイベントなのかと驚きました! 3. 参加者の属性 もう1つのボード(参加回数×AWS歴)を見ると、「AWS歴が長く、イベント参加回数も多い」という、いわゆるコミュニティのベテラン勢から初参加の方まで広く参加されていることがわかりました。 AWS歴3〜10年の中堅〜ベテラン層が最も厚いですが、イベント参加回数3〜10回のリピーター層も多く見えます。 中には20年以上の超ベテランや、参加回数100回超(!)のコア層も。20回以上の方は「もうわからないなあ」と言いながらシールを貼ってくれていました。 まとめ 振り返ってみて、アンケートの結果が想定以上に面白くて、こちらが一番楽しんでいたかもしれません。 弊社は色々なイベントに協賛していますが、今回のJAWS DAYS 2026はセッションの熱量もブースの数、そして何より参加者の皆さんの盛り上がりが凄まじくて1日中パワーをもらえるイベントでした。 改めて、運営の皆さん、素敵なイベントをありがとうございました! またどこかのコミュニティでお会いしましょう!! 撮影協力 臼井さん (株式会社エウレカ)
はじめに こんにちは、介護/障害福祉事業者向け経営支援「カイポケ」の介護レセチームでエンジニアをしている沖口です。 チームで管理しているテーブルに長年の運用によりデータ量が相当数まで増えてきたものがあり、idカラムの型をINT UNSIGNEDからBIGINTに変更する必要がありました。 先日、その対応をAurora MySQLの BlueGreenDeployment (以降では省略してBlueGreenDeploymentと記載)を用いて短時間のメンテナンスで実現できたため、その事例を紹介します。 背景 カイポケは2011年にリニューアルを行い、現在のカイポケとしての運用を開始しました。 当時作成された一部のテーブルでは2011年から現在までデータの蓄積が続いており、今回対応を行った利用者の請求明細に関するテーブルは、INT UNSIGNEDの上限である約42億レコードに近々到達することがわかっていました。 レコード数がこの上限に達してしまった場合、利用者請求に関連する業務上極めて重要な機能が停止します。 これを未然に防ぐため、大規模なレコードが存在するテーブルの型変更について、実現方法の検討を行うことから始めました。 実現方法の検討 まずidカラムの型変更を行う方法について、生成AIのDeepResearchにより取りうる選択肢を調査しました。 直接ALTER TABLEを実行する オンラインスキーマ変更ツール gh-ost (GitHub's Online Schema Transmogrifier/Translator/Transformer/Transfigurator) を利用する オンラインスキーマ変更ツール pt-online-schema-change を利用する BlueGreenDeployment によるデプロイを行う 選択肢と特徴について把握した後は、実際に私たちのテーブルに適用する場合の制約と照らし合わせてよりベストな方法を検討します。 そこからは、DeepResearchの調査文章を鵜呑みにするのではなく、DeepResearchが根拠資料として出力した公式資料を確認しながら詰めていきました。 以下では、それぞれの選択肢についての判断結果と、その理由を書いていきます。 (見送り) 直接ALTER TABLEを実行する MySQLはテーブルの型変更を行う場合、オンラインDDLによる顧客影響のない形でスキーマ変更を行うことはできません。 *1 もし本番環境でDDLを開始した場合はDDLが完了するまでの間 SHARED_UPGRADABLE ロックが取得されます。 ユーザーの視点に立つと、利用者請求の変更に関する操作を行うと処理が完了せず、タイムアウトすることになります。 それを防ぐためにはメンテナンスの時間をとってリリースを行うことになりますが、その妥当性を検討しておかなければなりません。 私たちのメンテナンスモード下でのリリースには以下の制約があります。 介護事業者は日中は常に重要な業務を行っています。ログアウトが発生するリリースは利用率が下がった19時以降に行う必要があります。 介護事業者の中には19時から24時近くまで業務を行っている方もいます。メンテナンスを行う場合はより短い時間で行う必要があります。 私たちのチームも継続可能な開発体制の一環として、休日深夜のリリースは極力避けるべきという考えがあります。 これらの制約を基に、この手法については「リリース作業が2、3時間程度で完了するか否か」を1つの判断基準として調査することにしました。 そこで、試しに本番環境のAurora MySQLインスタンスをコピーした疑似環境を用意し、実際に流したいDDLを実行しました。 結果として実行時間は7時間弱となり、判断基準とした時間より上回ったため、この選択肢は除外することになりました。 (見送り) gh-ost gh-ostはGitHubが提供する、オンラインでスキーマ変更を行うことができるツールです。(ツール自体の説明は割愛します) オンラインでスキーマ変更を行うことができるのであればメンテナンス時間も不要となり、サービスを止めることなく型の変更ができそうです。 しかし、実行するための 制約 を確認したところ、対象テーブルに外部キー制約がある場合はサポート外との記載があり、今回のケースとマッチしなかったため見送ることとなりました。 (見送り) pt-online-schema-change Perconaが提供する、MySQLのスキーマ変更をオンラインで実行するためのツールです。(こちらも、ツール自体の説明は割愛します) pt-online-schema-changeには、私たちに関係する部分としては以下の特徴があります。 トリガー作成に伴うデータコピー負荷の増加 負荷が大きいとツールが判断した場合の処理停止と再開 上記は注意事項ではありますが、これらによってpt-online-schema-changeの使用が不可能であるとの判断はしませんでした。 一方、懸念点としては以下がありました。 トリガー作成による負荷検証を検討・実施する必要がある。 pt-online-schema-changeによるリリースを開始した後、リリース完了となる時刻が不明であり体制を作りづらく、深夜待機に発展する可能性もある。 pt-online-schema-changeによるリリース実施経験がなく、リリース中断時に元の状況にロールバックする方法の検討/再検討の可能性がある。 上記の懸念点がBlueGreenDeploymentの場合は抑えられると判断し、結果としてpt-online-schema-changeは見送ることにしました。 (採用) BlueGreenDeployment BlueGreenDeploymentで対処する場合、以下の流れで作業することになります。 本番で稼働しているBlue環境を元にGreen環境を作成 Blue環境へのデータ変更は、binlogを用いてGreen環境に継続的にレプリケーションされる Green環境に対して変更を実施 Blue環境とGreen環境を入れ替えることで変更の適用完了 もし、BlueGreenDeploymentの制約が今回のテーブル変更に影響しない場合には、以下が言えます。 本番環境に影響しない形でリリースとは分離してDDLを事前実行できる Green環境へのDDL実行時間中には、本番環境への影響がないため体制を張る必要がない 予定より長時間となった場合もDDL実行日とリリース日の間にバッファをもうけておくことでリリースに影響を出さずに済む リリース可否の判断が明確。リリース可能と判断した後はBlue環境とGreen環境を入れ替えるだけであり問題が発生しにくい Green環境へのDDLが成功した場合はリリース可能 失敗した場合はリリース不可 メンテナンスはBlue環境とGreen環境を入れ替えるタイミングのみ必要であり、1時間もかからず完了できる見込み こういった変更の確実性の高さとリリースまでの予測の立てやすさから、この手法を最優先で検討することにしました。 BlueGreenDeploymentの調査 まずはBlueGreenDeploymentを用いる場合の制約について公式ドキュメントを確認します。 公式ドキュメントに記載されている内容の中で見落としがないよう、全て読みました。 ここでユースケースとしてスキーマ変更についての記載があると一気に実現の可能性が高まるのですが、公式ドキュメントではパッチや設定値変更についてのユースケースが勧められている程度でスキーマ変更については記載がありませんでした。 Amazon RDS ブルー/グリーンデプロイを使用する利点 Amazon RDS ブルー/グリーンデプロイを使用すると、セキュリティパッチを最新の状態に保ち、データベースのパフォーマンスを向上させ、短い予測可能なダウンタイムで新しいデータベース機能を導入できます。ブルー/グリーンデプロイでは、エンジンのメジャーバージョンまたはマイナーバージョンのアップグレードなど、データベース更新のリスクとダウンタイムが軽減されます。 しかし、 ブルー/グリーンデプロイの一般的なベストプラクティス には、制約事項の形で以下の文言がありました。 ブルー/グリーンデプロイを使用してスキーマの変更を実装する場合は、レプリケーション互換の変更のみを行ってください。 例えば、ブルーデプロイからグリーンデプロイへのレプリケーションを中断することなく、テーブルの最後に新しい列を追加することができます。ただし、列名の変更やテーブル名の変更などのスキーマの変更は、グリーンデプロイへのレプリケーションを中断させます。 レプリケーションと互換性のある変更の詳細については、MySQLドキュメントの「ソースとレプリカのテーブル定義が異なるレプリケーション」とPostgreSQL論理レプリケーションドキュメントの「制限」を参照してください。 この制約は裏を返せば「その変更がレプリケーション互換であればスキーマ変更に利用可能である」と解釈できます。 MySQLのドキュメントを見てみましょう。 17.5.1.9.2 データ型が異なるカラムのレプリケーション ソース上の対応するカラムと同じテーブルのレプリカコピーは、同じデータ型であることが理想的です。ただし、特定の条件が満たされているかぎり、これは必ずしも厳密には強制されません。 通常、特定のデータ型のカラムから、同じサイズまたは幅 (該当する場合) またはそれ以上の同じ型の別のカラムにレプリケートできます。 サポートされる変換.違うけれども似ているデータ型の間でサポートされる変換を次のリストに示します。 整数型TINYINT、SMALLINT、MEDIUMINT、INT、およびBIGINTのいずれかの間。 これには、これらの型の符号付きおよび符号なしバージョンの間の変換が含まれます。 不可逆変換は、ソース値をターゲットカラムで許可される最大値 (または最小値) に切り捨てることで行われます。符号なし型から符号付き型への変換時に非可逆変換を保証するには、ターゲットカラムがソースカラムの値の範囲を収容できる十分な大きさである必要があります。たとえば、TINYINT UNSIGNEDは、非不可逆にSMALLINTに降格できますが、TINYINTにはできません。 上記の内容から、カラム型のINT UNSIGNEDからBIGINTへの昇格はレプリケーション互換であることがわかったため、サポート対象と判断しました。 Amazon Aurora のブルー/グリーンデプロイの制限と考慮事項 にも今回のスキーマ変更に影響する制約はなかったため、ここまでの調査およびメリットの高さからBlueGreenDeploymentの採用を決めました。 本番環境でのリリース スケジュール BlueGreenDeploymentの本番環境適用とメンテナンス(本番リリース)は数日空けて計画しました。 このスケジュールでは、以下を考慮しています。 DDL実行時間が事前計測よりも長くかかる可能性への備え DDLが実行された後、Blue環境で実行されたクエリがGreen環境に後追いで適用されるレプリケーション処理時間への考慮 不測の事態が発生した場合のリカバリー時間 特に不測の事態への備えについては、BlueGreenDeploymentによるDDL実行について公開されている事例が少ないことから、何かエッジケースを踏む可能性があったので設定しました。 後続で書きますが、不測の事態が実際に発生しており、時間ギリギリでリカバリーに成功したためバッファを設けておいてよかったです。 実行時間 本番での実測値は以下の通りで、無事1時間のメンテナンスでリリースを完了することができました。 Aurora MySQL DBインスタンス: db.r6i.16xlarge 変更対象テーブルのレコード数: 2,574,439,006レコード DDLの実行時間 9時間30分 メンテナンス時のBlueとGreenの入れ替え作業 10分ほど(※正確な記録を取り忘れました) メンテナンス全体 1時間 以降は、本番環境で起きた不測の事態について書いていきます。 本番環境での不測の事態: データ不整合が発生しDDL実行後のレプリケーションが失敗する 起きたこと Green環境を作成し、Green環境へDDLの実行を行って無事完了したのですが、DDLの実行が完了した後に行われるレプリケーションでエラーが発生していました。 エラーメッセージ 2025-11-18T01:14:43.909892Z 7858 [ERROR] [MY-010584] [Repl] Replica SQL for channel '': Worker 1 failed executing transaction 'ANONYMOUS' at source log , end_log_pos 54575012; Could not execute Delete_rows event on table {テーブル名}; Can't find record in {テーブル名}, Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's source log mysql-bin-changelog.038641, end_log_pos 54575012, Error_code: MY-001032 これはBlue環境で実行されたdeleteクエリをGreen環境に適用しようとした際に、delete対象のレコードが無いぞと言っています。 エラーが発生している削除対象の該当行が存在するか、Green環境へSELECTクエリを実行したのですが、しっかりと存在するので不可解なエラーメッセージで困惑です😇 原因 以下はレプリケーションに利用されるbinlogから、DELETEに失敗したlogを抜粋したものです。 ### DELETE FROM `{テーブル名}` ### WHERE ### @1=-824762424 (3470204872) /* INT meta=0 nullable=0 is_null=0 */ ### @2=NULL /* DATE meta=0 nullable=1 is_null=1 */ ### @3=NULL /* TIME(0) meta=0 nullable=1 is_null=1 */ ### @4=NULL /* TIME(0) meta=0 nullable=1 is_null=1 */ ### @5='05' /* STRING(8) meta=65032 nullable=1 is_null=0 */ 「@X」の次にあるのは実際に入る値で、たとえば @5 、つまり5番目のカラムに入るのは '05' であることがわかります。 このうち、 @1 は今回型変更を行ったカラムです。Blue環境ではINT UNSIGNED、Green環境ではBIGINTというように型が異なります。 @1 の値として書かれている -824762424 (3470204872) は他と表記が異なりますが、以下のように読み取ることができます。 -824762424 : signed解釈の値 (3470204872) : unsigned解釈の値 INT UNSIGNEDのカラムに対してSQL上で使われるのはunsigned解釈の値なので delete from {テーブル名} where id = 3470204872 はHITします。 一方でGreen側はこのbinlogを用いてレプリケーションを実行していく際、 どうやら -824762424 が値として扱われるよう解釈してしまっているようでした。 つまり、Blue側は delete from {テーブル名} where id = 3470204872 を行っていましたが、情報を伝搬されたGreen側は delete from {テーブル名} where id = -824762424 を行っていました。しかしそのような行は存在しないため、レプリケーションエラーが発生していたのです。 調査の過程 今回は一度の実行が長時間となるDDLを用いたリリースであるということから、探索的に成功するまで実験を繰り返すような対処法の探し方はできず、限られた時間で確実性の高い対処法を探し出し、一度の成功でリカバリーをする必要がありました。 そのため、仮説を持って確実性の高い証拠・裏どりを探しに行く動きをとっています。 (仮説1)binlogを確認する前、「行は存在するのに削除対象が見つけられない」という状況から Green環境の型変換後のid: 1 (BIGINT) binlogレプリケーションにおけるクエリの履歴である delete from {テーブル名} where id = 1 (INT UNSIGNED) ともに値は 1 ではありますが、内部的に別物となり一致しない状態になっているのではないか?という仮説を持ちました。 (仮説2)仮説1を念頭にbinlogを確認したところ、id列に -824762424 と (3470204872) の2値が併記されており、本来扱うべきである 3470204872 ではなく -824762424 がwhere句で使われているのでは、と初期の仮説1から別仮説に一歩進展しました。 裏付け 仮説2をドキュメントで確認できれば確度が上がると考え、レプリケーション時の値の解釈についてMySQLの公式ドキュメントを再確認しました。 すると、 ソースとレプリカで異なるテーブル定義を使用したレプリケーション にて、以下のオプション記載を見つけました。 ALL_SIGNED 昇格される整数型を符号付き値として扱います (デフォルト動作)。 ALL_UNSIGNED 昇格される整数型を符号なし値として扱います。 整数型が昇格されるときに、符号ありか符号なしかは保持されません。デフォルトでは、レプリカはこのような値をすべて符号付きとして扱います。 これは、今回変更したカラムの値はデフォルトでは符号付き値 (-824762424) として扱われることを示しています。また、 ALL_UNSIGNED を指定することで符号なし値 (3470204872) として扱われるように設定できるともあります。 今回の場合はまさにこれが対処法となりそうで、「これだ!」と仮説が確信に変わりました。 ドキュメントの該当部分は事前に読んでいたのですが、このような事態につながる記載であるとは気付けませんでした。 さらなる裏付け id列がsigned解釈の値であるという場合、delete / updateをしようとすれば対象の行が見つからないエラーとなりますが、insertの場合はエラーなくマイナスの値でinsertされた行があるはずです。 実際に確認したところ、Green環境にはマイナス値のid列が多数作成されており、確証を得ることができました。 リカバリー リカバリーのためには ALL_UNSIGNED を付与したGreen環境で再度レプリケーションを実行する必要があり、以下のように全工程のやり直しを行いました。 Green環境の削除 Green環境の再作成 ALL_UNSIGNED パラメータの追加 DDLの再実行 幸いエラーが発生した当日に原因と対処法の特定ができたため、リリース実行日に間に合わせることができました。 終わりに 今回はBlueGreenDeploymentを活用したカラム型の変更と、その際に生じた予期せぬレプリケーションエラーについて記載しました。 予期せぬ事態は1件発生してしまいましたが、 顧客影響を出さず、実行時間を気にせずDDLを本番実行できる Green環境の型変更が正常に完了できればメンテナンスは不安なくリリースができる 短時間のメンテナンスにより介護事業者がアプリを利用できない時間を短時間としつつ、リリース関係者も無理なくリリースができる というBlueGreenDeploymentのメリットを活かしたリリースが行えたと思います。 この記事がこれからスキーマ変更を行う方の役に立つと嬉しいです。 読んでいただきありがとうございました。 *1 : オンラインDDL操作に関する公式ドキュメント: https://dev.mysql.com/doc/refman/8.0/ja/innodb-online-ddl-operations.html
はじめに こんにちは!カイポケコネクトの開発推進チームでエンジニアをしている @_kimuson です。 私たちのチームでは、開発体験の向上や今後の拡張に備えて大規模なフロントエンドアプリケーションのマイクロフロントエンド化を進めています。 アプリ分割については下記の記事で紹介していますので、よろしければ合わせてご参照ください。 アプリ分割の一環としてpnpm workspaceを使ったモノレポ構成を採用しているのですが、internal packageにおけるpeerDependenciesの扱いが課題になりました。 この記事では、pnpm workspaceにおけるpeerDependenciesの問題とその解決策について整理してみます。同じような構成で開発している方の参考になれば幸いです。 pnpm workspace と peerDependencies、何が問題なのか まずは問題の背景から説明します。 pnpm workspaceでは workspace:* プロトコルを使うことで、ローカルパッケージ間の依存をシンボリックリンクで解決してくれます。これがとても便利で、パッケージ内のファイルを編集すると即座に反映されますし、watchプロセスも不要なので開発環境が重くなりません。 典型的な構成はこんな感じです: // apps/main/package.json { " dependencies ": { " react ": " ^18.0.0 ", " shared-ui ": " workspace:* " } } // packages/shared-ui/package.json { " peerDependencies ": { " react ": " ^18.0.0 " } } apps/main が shared-ui に依存していて、 shared-ui はReactをpeerDependenciesとして宣言しています。ごく普通の構成ですね。 シンボリックリンクが引き起こす問題 UI Library等ではよくある普通の構造だと思いますが、workspaceでのinternalパッケージでは致命的な問題があります。 シンボリックリンクでパッケージを参照すると、Node.jsのモジュール解決の仕組み上、それぞれのパッケージが 異なるライブラリの実態を参照してしまう 、ということです。 シンボリックリンクにより shared-ui を参照していますが、それぞれが異なるreactインスタンスを参照してしまいます。 Node.jsはモジュールを解決するとき、呼び出し元のファイルから見て近いディレクトリから順番に node_modules を探していきます(参考: Node.js Documentation - Loading from node_modules folders )。 shared-ui のソースコードから import React from 'react' すると、まず packages/shared-ui/node_modules/react を見つけてしまうわけです。 peerDependenciesは本来「利用側と同じインスタンスを使ってね」という意図で宣言するものですが、シンボリックリンクだと期待通りの解決になりません。 実際に問題が起きるケース とはいえ、すべてのpeerDependenciesで問題が起きるわけではありません。問題が顕在化するのは、基本的にパッケージが グローバルな状態を持つ 場合です。 たとえば、わかりやすい例として単純なカウンターパッケージを考えてみます: // counter.ts let count = 0 ; export const addCount = () => { count++; } ; export const getCount = () => count; このパッケージが shared-ui にpeerDependenciesとして追加されていると仮定して、 shared-ui から addCount() を呼んでも、 apps/main から getCount() を呼ぶと0が返ってきます。別のインスタンスの別の変数を見ているからですね。 Reactも同様で、 useContext や useMemo などグローバルな状態に依存する機能を使うとエラーが発生します。一方、date-fnsやes-toolkitのような純粋な関数だけを提供するパッケージは、同じ実装が2箇所に存在するだけなので動作には問題ありません。 解決策 この問題に対するアプローチは大きく2つあります。いずれも peerDependencies を同じモジュールの実体に解決させる という方向性は同じです。 解決策1: バンドラーやテストフレームワークで依存解決をオーバーライドする 1つ目は、依存解決が行われる各ツールで、モジュールの解決先を上書きする方法です。 Jestの場合はこんな感じで設定します // jest.config.ts import { createRequire } from 'node:module' ; const require = createRequire(import.meta. url ); const reactPath = require.resolve( 'react' ); const jestConfig = { moduleNameMapper : { '^react$' : reactPath, } , } ; export default jestConfig; webpackを使うNext.jsやStorybookでも、同様に resolve.alias で上書きできます。Viteでも dedupe オプションが提供されています。 メリット: シンボリックリンクの利点(即座に反映、watch不要、軽量)を維持できる 必要な箇所だけパッチを当てられる デメリット: Next.js、Storybook、Jest/Vitestなど、依存解決を行うすべてのツールで設定が必要 新しいツールを追加するたびに設定を追加しないといけない 潜在的な問題は残る Ex. 実はグローバルな状態を持っていてロジックが壊れていることに後から気づく Ex. 同じコードが重複してバンドルに含まれてしまう 解決策2: pnpm の dependenciesMeta.*.injected を使う 2つ目は、pnpmが提供する injected オプションを使う方法です。 解決策1がパッチを充てるような対策だったことに対して、こちらは根本解決になります。 // apps/main/package.json { " dependencies ": { " react ": " ^18.0.0 ", " shared-ui ": " workspace:* " } , " dependenciesMeta ": { " shared-ui ": { " injected ": true } } } これを設定すると、pnpmは .pnpm ディレクトリ内に node_modules を持たないパッケージのクローン を作成します。 ディレクトリ構造は下記のようになります。 ./ ├── apps │ └── main │ └── node_modules │ ├── .pnpm │ │ └── <shared-ui-clone> │ │ ├── src (shared-ui のコピー) │ │ └── node_modules (空) │ └── @my-pkg │ └── shared-ui --> .pnpm/<shared-ui-clone> ├── packages │ └── shared-ui └── package.json apps/main からはこのクローンを参照するようになるので、 shared-ui のコードからReactをimportしても、クローン側の node_modules は空であるため親ディレクトリをたどり、 apps/main/node_modules/react へ解決されます。 つまり、 apps/main のコードと shared-ui のコードが同じreactインスタンスを参照するようになります。 見ての通り根本的な解決であり、理想的に見えますが開発体験が致命的に悪いという問題を含んでいます。 injected による開発体験の劣化と融和策 injected を使うと、 packages/shared-ui/src とそのクローンである apps/main/node_modules/.pnpm/<shared-ui-clone>/src は基本的にファイルごとにハードリンクで同期されます。 したがってファイルが追加されたり、削除されたりする場合には同期されません。 また、特定条件下でハードリンクではなく単なるコピーが行われるというUndocumentedな挙動があり、我々のプロジェクトではこの条件( shared-workspace-lockfile=false , postinstall あり)を満たすためコピーに寄って作成され、変更すら同期されないという状態でした。 起票したIssue: https://github.com/pnpm/pnpm/issues/9828 この問題を補完するために、 pnpm-sync-dependencies-meta-injected というツールがあります。これを使うと、開発中にソースコードの変更をwatchしてハードリンクを更新してくれるので、injectedを使いながらも快適な開発体験を維持できます。 ちなみにpnpm v10では syncInjectedDepsAfterScripts という公式オプションも追加されています。任意のスクリプト実行後にハードリンクを再同期してくれるもので、将来的にはこちらを使う選択肢もありそうです。 ただこれで全部解決だよね!ということでもなく「node_modulesを削除してpnpm iしなおさないと更新されない状態に定期的に陥る」といった問題が実際に発生しており、開発体験としては非常に悪い状態が残っています。 結局どちらを採用すればよいのか 少なくとも現在(2025年12月)ではどちらかが完璧な解決策にはなっておらず、トレードオフを考慮して選ぶ必要があります。 観点 解決策1(オーバーライド) 解決策2(injected) 開発体験 ◎ △ 設定の煩雑さ・手間 × ◎ 根本解決 × ◎ バンドルサイズ △(重複の可能性) ◎(重複なし) 可能であれば根本解決であるinjectedに寄せていきたい気持ちはありつつ、開発体験が悪すぎるので現状はオーバーライドに寄せています。 overrides 方式では解決できない問題もある 基本開発体験を優先してoverridesに寄せていますが、一部の共通パッケージではoverridesで解決できない問題があり、injectedも利用しています。 具体的には型解決の問題です。 型解決についてはpeerDependenciesの実態が異なるものに解決されていたとしてもバージョンさえ揃っていれば構造的部分型で型チェックされるため基本的には問題は起きません。 import { User } from 'peer-dep-pkg' import { getUser } from '@my-pkg/dep' const user: User /* node_modules/peer-dep-pkg */ = getUser() /* packages/dep/node_modules/peer-dep-pkg */ のように実態が異なっていても構造は同一であるため、型エラーにはなりえません。 弊プロダクトの場合はpnpm catalogを使って依存を管理しているため、バージョンは固定する運用をしているのでバージョン違いも起きません。 https://pnpm.io/ja/catalogs 一方、TypeScriptでも「classを使っておりprivateプロパティを持つ場合」では例外的に総称型で型チェックされるケースが存在し、そういった型が使われているライブラリがpeerDependenciesに存在すると型チェックは適切に行えません。 // ライブライ側のコード例 class ApiClient { private cache : unknown ; // ... } import { ApiClient } from '@my-pkg/peerDep' import { createApiClient } from '@my-pkg/dep' const apiClient: ApiClient /* node_modules/peer-dep-pkg */ = createApiClient() /* packages/dep/node_modules/peer-dep-pkg */ ; // => 実態が異なるため総称型でチェックされ型エラー この問題は解決のワークアラウンド的に回避も難しいので、一部のパッケージでは開発体験の劣化を許容してinjectedを採用しています。 終わりに pnpm workspaceにおけるpeerDependenciesの問題と解決策について整理しました。 シンボリックリンクによるモジュール解決の仕組み上、peerDependenciesが異なるインスタンスを参照してしまう問題がある グローバルな状態を持つパッケージ(Reactなど)や総称型になる型を公開するパッケージで問題が顕在化する 解決策としては「各ツールでオーバーライド」か「injectedオプション」の2つ 正直、overridesも設定が煩雑すぎるしワークアラウンドであること、injectedも体験が悪くてしっくりは来ていないのですが背景理解と方針検討にも苦労したので、同じようなworkspace化等に取り組んでいる方の参考になれば幸いです! また、pnpmのリポジトリでのこの問題は議論されているので、injected(根本解決)ベースでより開発体験も維持できるソリューションが出てくると良いなと思っています。 https://github.com/orgs/pnpm/discussions/3938
はじめに こんにちは!カイポケコネクトの開発推進チームでエンジニアをしている @_kimuson です。主にフロントエンドを中心に開発生産性の向上に取り組んでいます。 今回は、カイポケコネクトのフロントエンドを単一のNext.js構成からマイクロフロントエンド化した話を紹介します。 スパンで言うと提案をしてから9か月ほど経っているのですが、ようやく形になってきたので方針や試行錯誤した知見を共有できればと思います。 背景・元々のアーキテクチャ まず、元々の構成を簡単に説明しておきます。 カイポケコネクトのフロントエンドは、GraphQL Federation *1 を行うBFF *2 Serverに対して巨大なフロントエンドが建っている構造です。 Next.jsを使っていますが、SSR *3 は行わず静的な構成です。Pages RouterでStatic Buildした成果物をS3でホスティングするだけのシンプルな形ですね。 組織構造としては、ストリームアラインドチーム *4 がNext.js内のページで区切られた小さいアプリケーションごとにオーナーシップを持っています。 例えば図のapp1のチームは主に src/pages/app1 , src/services/app1 のオーナーシップを持つような形です。 分割のモチベーション もともとはミニマムに単一のNext.jsで開始していたこのプロダクトですが、組織拡大・時間経過とともに肥大化を続けており、ペインが出てきている状況でした。 課題1: 各チームごとにバリューストリームを持ちたい まずそれぞれのアプリケーションの開発はチームが分かれているので、当然それぞれのチームでバリューストリームを持ち、リリースをしていきたいのですがビルドが一括になる都合上個別でのデプロイを行うことができませんでした。 結果、2週間毎にまとめて足並みをそろえてリリースを行う「リリーストレイン」を長らく実施していましたが もっと高頻度にリリースをしていきたい アプリ単位でQAやリリースを行って行きたい と言った需要が大きくなっていきました。 課題2: CI やローカル環境の肥大化 本来自チームとは関係ない・全チームのソースコードが含まれているパッケージになってしまっているので 変更に関係ない対象のCI(test, build, lint, 型チェック)を動かす必要がある ローカルで全部入りのNext.js Dev Serverを立てる必要がある と言った状態でした。 今後もアプリの小グループやコードベースも増えていくので今の構成のまま進んで大丈夫か?という懸念が出つつありました。 マイクロフロントエンドで解決を目指す これらの課題に対して、Verticalにフロントエンドを分割する構成に移行することで解決を目指しました。 アプリごとに独立したNext.jsアプリケーションを持てるようにします。 これにより ローカル環境で自分が触らないアプリは共有環境のリソースに接続できる CI/CDも分割され、アプリ単位で必要なCIに絞って回すことができるようになる アプリのデプロイ単位を分割できるため、チームごとに自分のアプリだけデプロイすることが可能になる という形でペインが解消されていく構想で開始しました。 実現方法 分割の実施には複数のアプローチを検討しましたが、分割すること自体が非常に大きな取り組みでありスコープを極力絞ったミニマムな方針で分割を行いました。 例えばアプリごとにサブドメインを分ける等も考えられましたが アプリのパスは変えない( /app1 ならapp1のNext.jsが動くだけ、という構造) パスを変えないので旧パス・新パスのリダイレクト等も不要 これまで同様単一のs3バケットにデプロイする形を維持 とすることで、パッケージを分割する以外の関心をあまり気にせず進められるようにしました。 basePath を活用したインフラ構成がほぼ変わらない方法 Next.jsには basePath オプション が存在しており、サブパスにおいて配信する構成に対応しています。 これを使ってそれぞれのアプリを basePath ありでビルドし、成果物を結合してS3にアップロードします。 # 各アプリのビルド成果物 apps/ ├── app1/out/ # basePath: /app1 でビルド │ ├── _next/ │ └── index.html ├── app2/out/ # basePath: /app2 でビルド │ ├── _next/ │ └── index.html └── app3/out/ # basePath: /app3 でビルド ├── _next/ └── index.html ↓ cp -r で結合 # S3にアップロードする成果物 dist/ ├── app1-path/ │ ├── _next/ │ └── index.html ├── app2-path/ │ ├── _next/ │ └── index.html └── app3-path/ ├── _next/ └── index.html 静的ホスティングでの Dynamic routes 対応 上記で基本的には期待通り動くのですが、Dynamic routesの解決に関しては追加の対応が必要です。 そもそも分割関係なく一般的にNext.jsの静的ホスティングではDynamic Routesが動作しないのでワークアラウンドを行う必要があることが知られています。 詳細な方法はインフラ等にも寄るのでまちまちですが、概ねこういう対応が必要です。 インフラ側: /posts/10 のようなアセットが存在しないパスへのリクエストでも /404.html 等を返すようにする フロントエンド側: /404 等受けたFE側で window.location.pathname ( /posts/10 ) を確認し、存在するルートあれば router.replace してフォールバックする アプリ分割すると当然アプリごとの /404 からしかソフトナビゲーションで正規のパスにフォールバックできませんから、個別の /404 に流す必要があります。 我々の場合は、CloudFront Functionsで下記のような対応を入れることでDynamic Routesに上手く対応しています。 静的アセットは正規表現でマッチさせてそのまま帰す それ以外はCloudFront Functionsが各アプリのパスを知っており、 /app1-path → /app1-path/404.html を返す、というような処理を生やす これにより、分割して結合したビルド成果物をs3に配信する形でDynamic Routes含め正常に動かすことができるようになりました。 モノレポの管理 続いて、ローカルやCIでのパッケージ管理についてです。 モノレポ管理はpnpm workspace + Turborepoの構成を採用しています。 pnpm workspaceは他のパッケージマネージャーと比較してもワークスペース周りの機能が充実しています。 基本的にはワークスペースプロトコルを使用し、内部パッケージ間の依存を解決しています。ワークスペースプロトコルを使用すると依存元のnode_modules/pkg-name部分がパッケージの実態へのシンボリックリンクになるため、ホットリロード等がほぼ同一パッケージ内で依存していた場合と変わらないような体験で利用できます。 ./ ├── packages/ │ └── shared/ # 実際のパッケージの実体 │ ├── package.json │ └── src/ │ └── index.ts │ └── apps/ └── app1/ ├── package.json # "shared": "workspace:*" と記述 └── node_modules/ └── shared/ # → ../../packages/shared へのシンボリックリンク また、パッケージを跨ぐスクリプトの管理にTurborepoを採用しています。 Turborepoでは --affected というオプションが提供されており、例えば turbo run build --affected と実行するとgitのdiffから依存関係を含めて実行する必要があるパッケージを計算し、実行してくれます。 また、我々はまだそういう構成が必要になっていないので利用していませんが、「ビルドを実行するには依存するパッケージがビルドされている必要がある」というような依存関係も定義できるのでここういった実行すべきタスクの管理がお任せできて便利です。 internal package における TypeScript の型解決 internalでないパッケージではビルドを行い d.ts と .js を公開して利用させる構造が一般的です。 // 一般的な npm package の公開方法 { "type": "module", "exports": { ".": { "types": "./dist/index.d.ts", "require": "./dist/index.cjs", "import": "./dist/index.mjs" } } } ただしinternal packageでは一々共通パッケージでビルドしていると開発体験が悪いので、 .ts ファイルを直接公開し、実際にトランスパイルを行うのはアプリ側にしています。 // TypeScript ファイルを直接公開する { "type": "module", "exports": { ".": "./src/index.ts" } } 基本この形で開発者体験を維持して依存解決をしていますが、一部ビルドをしたいパッケージもワークスペース内に存在しているのでそちらについてはcustom conditionを使って内部でのみ .ts に解決させたりもしています。 この辺りは以前記事を書いているのでよければあわせてご参照ください。 直接 .ts を公開するために気をつけること 体験が圧倒的に良いので .ts の直接公開がおすすめですが、いくつか気をつけておくべきポイントがあります。 まずは、 .ts を公開するということは複数のパッケージから公開されたtsファイルの型チェックが行われるということです。 そのため、極力パッケージ間の型チェックに関するtsconfigのオプションを統一しておくことが望ましいです。我々の場合は共通のtsconfigを packages/tsconfig として用意し、これをextendsして必要な箇所だけ上書きする構造にしています。 { "extends": "@my-pkg/tsconfig/base.json", "compilerOptions": { // ... 上書きする設定 } } 次に同様の理由でパッケージのバージョンを揃えておくことが望ましいです。 アプリごとのTypeScript本体のバージョンが異なっていたり、依存のバージョンが異なっていると一方では通る型チェックがもう一方では通らないと言ったことがありえます。 pnpmではCatalogsというワークスペース内で利用するバージョンを揃える機能が提供されているのでこれを使うと統一を簡単に実現できます。 # pnpm-workspace.yaml packages : - apps/** - packages/** catalog : 'react' : 19.0.0 catalogMode : strict cleanupUnusedCatalogs : true // package.json { " dependencies ": { " react ": " catalog: " } } 共通のアプリケーションコードをどうするか問題 app1とapp2で「共通で利用しているコード」は、パッケージに切り出す必要があります。いわゆるcommonやutilsという名前がつきがちなコード郡ですね。 まず理想形を言うとちゃんと責務ごとにパッケージを分けていくのが良いと思います。 一方、現実的にはリファクタコストが大きくて分割のコストが大きくなってしまうため、どかっとまとめて単一のsharedなパッケージとして切り出すことにしました。 これはパッケージ間の循環参照を許容しないためです。 例えば auth パッケージと test パッケージを用意して、testではauthにある型が必要、authではテストするのにtestパッケージのユーテリティが必要となると相互依存の関係になってしまうことになります。これを許容してしまうとビルド等の依存関係を正しく解決できますか?とか、型やパッケージ自体の依存解決は問題ないか?等と考えることが増えるため許容しないことにしています。 上記を基本方針としながら まずは単一のNext.jsアプリがワークスペースの中で動く構成 命名からcommonのようにわかりやすく共通部分となっている箇所を切り出し、1のアプリがそこに依存する状態を作る 小さい・変更の少ないアプリから実際に移行しながら必要な箇所を特定して共通パッケージに切り出す という流れで共通コードを分離しながら分割を進めていきました。 結果 この記事を書いている2026年1月現在ですべてのアプリ分割は終わっていませんが、残すことあと1アプリとなりました。 現時点での結果をまとめようと思います。 開発環境で必要なアプリだけ起動できるようになった ビルド単位が別れたことで触るアプリケーションの next dev のみ立てれば良い形になりました。他のアプリに関しては共有環境のbuildをそのまま受け取るだけで良いので開発マシンにも優しいですし、他アプリ起因のトラブルが起きづらく成りました。 CI は turborepo --affected で必要な依存だけ実行 冒頭で紹介した通りTurborepoには --affected オプションがあり、変更に影響があるスクリプトだけ実行することができます。 CIの構築も手軽で、CI用のワークフローを用意して --affected でテスト等を実行するだけで必要なパッケージに絞ったテスト等が実行されるようになります。 ライブラリの段階移行がしやすくなった 副次的に狙っていたことではありますが、ライブラリのアップデートをアプリ単位で進められるようになりました。 コードベースが大きいので、密に依存しているライブラリのMajorアップデートや別ライブラリへの移行等は大変になりがちです。例えばJestはESM Support周りが辛いのでVitestへ移行をしているのですが、こういう話をアプリごとで実施できるようになりました。 ちなみに、前述した通り我々はパッケージのバージョンはすべてpnpm catalogで一元管理していますが、named catalogsを使って複数バージョンの共存も可能になっています。 # pnpm-workspace.yaml # 通常のカタログ catalog : react : 17.0.2 react-dom : 17.0.2 # Named Catalog catalogs : react17 : react : 17.0.2 react-dom : 17.0.2 react18 : react : 18.2.0 react-dom : 18.2.0 これでバージョンを一元管理しつつも、特定のパッケージだけMajorバージョンアップさせると言った対応が可能になっています。 https://pnpm.io/catalogs#named-catalogs 残っている課題:shared 肥大化問題 分割後に課題もいくつか残っているのですが、特に重要なので「sharedの肥大化問題」です。 まず、アプリケーションの共通部分を切り出したsharedのパッケージの変更ではホットリロードが効かないという問題があります。 これはpeerDependenciesを持つパッケージを workspace:* プロトコルで解決する際に起こってしまう問題であり、事情が複雑なのでこれ自体で記事を書いています。 また、ホットリロードの問題を置いておいてもsharedがファットだと結局変更が他チームに影響することが増えます。調整ごとの時間が増えてしまうので、組織的にも良くないと思っています。 対策としてsharedを減らしていく方向で進めています。 そもそも移行を優先してどかっと持ってきてしまったので デザインシステムとして昇華されていないが、ドメインの事情を持たないUI Patternはデザインシステムに持っていけないか? アプリを跨ぐ共通のUIは本当に共通にしないとダメなものか?コピーの方が望ましくないか? 等を検討し、ちゃんと用途ごとのinternal packageに分離してsharedを縮小していきたいと思っています。 まとめ 巨大なNext.jsアプリケーションをマイクロフロントエンド化した話を紹介しました。 ページパスやインフラ構成への影響を最小限に抑えたことで、現実的に分割を進められました。 おかげでCIや開発環境、依存ライブラリの段階的アップデートなどアプリケーション単位で実施できることが増えました。 まだ課題が残っているのは書いたとおりなので、引き続き改善を続けていきたいと思っています。 *1 : 別途のグラフを持つ複数のGraphQL Serverを束ねるGateway Serverを用意し、クライアントから統合された1つのグラフに対してリクエストを行うことができるアプローチ。 *2 : Backend For Frontend の略。フロントエンドとバックエンドの中間に配置されるサーバーで、フロントエンドから見て複雑なバックエンド呼び出しを隠蔽する等の責務を持ちます。 *3 : Server-Side Rendering の略。意味が揺れがちですが、ここでは「リクエストごとにサーバー側でHTMLを組み立てて返す構成」の意味で使用しています。 *4 : 書籍チームトポロジーにて紹介されているチーム分類の1つです。基盤を提供したり高度な専門領域を扱うチームと対比してビジネスドメインに沿ってプロダクトの開発を進めるチームを指します。
はじめに こんにちは。カイポケコネクトの開発推進チームでエンジニアをしている @_kimuson です。 開発推進チームではエンジニアの生産性向上をミッションに掲げているため、最近では積極的にAI活用を推進しています。 上記エントリでは、タスクごとの協業レベルを定義しより低い協業レベル(=できるだけLLMに移譲しきる)を実現するための方針を紹介しました。 このエントリではより具体的に、Claude Codeをフル活用してこういったワークフローの設計を組織に適用する際の知見をまとめてみようと思います。 設計するワークフローの協業レベルを意識する 前回のエントリでは、ワークフローを設計するに当たって協業レベル、つまりどの程度LLMに権限移譲するか、をデリゲーションポーカーの分類を借りて整理しました。 よくあるLLMの利活用シーンと対応する移譲レベルは下記のように対応します: 流れ 協業レベル 主体 ChatGPTに設計について相談し、自分で実装 Consult 人間 Copilot や Cursor の補完を使いながら、自分で実装 Consult 人間 細かい指示を出しながらエージェントが実装。Driver がエージェントなモブプロ Agree 人間 & LLM LLM にチケットを渡してPRまで作ってもらう Inquire LLM LLM にチケットを渡してPRを作ってもらい、LLMによるレビューでマージまで完結 Delegate LLM 広く「AI活用」といっても、目的ややりたいこと次第で設計すべきワークフローの協業レベルは変わってきます AgreeやConsultレベルで、エンジニアとAIが協業しながら出せるアウトプットの質を高めようという話なのか Inquireレベルに持っていくことで、責務を移譲しデザイナーが簡単なFE実装をできるようにしたり、QAの人が自動テストを書きやすくしたりといった職能の拡張をしたいのか Inquireレベルに持っていくことで、エンジニアの作業時間をブロックせずに小さいタスクをゴリゴリ進めてもらおうとしているのか これらはすべてAI活用ですが、ワークフロー設計の考え方が大きく変わってきます。 なので最初に明確に意識しておくのが良いと思っています。 エージェントはコンテキストがすべて エージェント設計でもっとも重要なことはコンテキスト管理だと思っています。 イメージしてみてください。われわれ人間が開発をするうえでも 設計をしているときは、要件・非機能要件を満たせるか、対応できないEdgeケースがないかをワーキングメモリに置きながら考えるし フロントエンド開発をするときはTypeScriptの型システムやReactの思想を意識しながらコーディングするし 同じフロントエンド開発でもユニットテストを書くときは仕様の漏れや境界値など検証すべき内容を意識しているし と言った形でワーキングメモリに置いていることが全く違います。 人間はこういうコンテキストの切り替えを自然にできるんですが、LLMはこれができません。 したがって工夫をしないと、エージェントはこれらすべての視点をすべてワーキングメモリに載せた注意散漫な状態で様々な作業を行う羽目になります。これではいくらモデル性能があがっても質の高いアウトプットは出しづらいです。 → つまり、 コンテキストを最適化すること、それを実現するためのプロンプトがすべて なので、そこに投資をするのが大事になってきます。 コンテキストをどうやって分離するのか このコンテキスト分離の答えの1つがマルチエージェントです。 単一のエージェント・会話セッションでやりたいことを全部載せると指示も会話ログが非常に長くなってしまうので、それぞれの個別の責務を持つエージェントが協業することでコンテキストを分離しようという考え方です。 この領域ではGoogleが発表されている A2A プロトコル 等もありますが、普及しているコーディングエージェントのCLIツールで利用できるわけではないのでとっつきづらさがあります。 Claude Codeではやや制約もある *1 もののタスクツール・サブエージェントが組み込まれているので、手軽にこれを実現できます。 例として、実装を丸投げしようと思ってオーケストレーションなしでワークフローを組んでみます。チケット確認→設計→API Spec決定→BE実装→FE実装→型エラー・テスト対応→報告、という流れです。 この場合、すべてのステップの注意事項やガイドラインを含むと、プロンプトが数百行にもなります。こういうのを作ってみるとわかりますが、 それぞれのステップで重要な観点を担保できない どこかのステップで詰まると解決できない・長引くと型エラー対応などのステップがスキップされる といったことが多くなります。 一方、これをオーケストレーション前提で組んでみると、メインセッションの責務はオーケストレーションだけになります。各ステップの状況を追っていって、サブエージェント(サブタスク)を呼び出して内容は移譲する。これだけです。 こうするとサブエージェントには単一責任なプロンプトを持たせた上で起動できるので、「設計において重要なこと」「BE実装のガイドライン」などそれぞれの責務で必要なプロンプト のみ を渡した上で各ステップを実行できるようになります。 オーケストレーションなしだと他のステップの会話ログも全部N回投げつけることになるのに対して、コンテキストは適時破棄されるのでトークン効率も良いです。 オーケストレーションのトレードオフ という感じでオーケストレーションは良いことづくめに見えますが、すべてのケースで適用すべきというものでもありません。 実際に使ってみると弱い点もあります 理論上解ける問題の範囲を広げやすいが、現実にはオーケストレーターと各サブエージェントの関わり方の設計の難易度が高い。 対話を重ねることによって成果物をブラッシュアップすることにも向きません。 ブラッシュアップに向かないのがなぜかというと、オーケストレーションではサブエージェントの実装のコンテキストを知ることができません(むしろそれを目的に分離している)。 したがって、ユーザーとメインセッションの会話はいわば伝言ゲーム状態であり、メインセッションも実装の詳細を知らないため、詳しくない者同士が対話している状態になります。 ということで協業レベルを意識することが大事になるわけです。 Agreeレベルで一緒に作っていきたい内容はオーケストレーションの採用を限定的にした方が良いですし、逆にInquire以上のレベルでまるっと移譲したいタスクは積極的にオーケストレーションしていくと良いです。 また、0/100ではなく部分的に使う案はバランスが良くAgreeレベルでも採用しやすく私は好んで使っています。 メインセッションの責務は「実装 & オーケストレーション」にする メインセッションは実装に集中しつつ、設計やコードレビュー・動作確認などは自分で行わずサブエージェントへ移譲する これだと「もうちょいここ直さないとでしょ〜」みたいなフィードバックを柔軟に受けつつ、各ステップの品質を安定させやすくなります。 サブエージェント vs Skill vs コマンド エージェントに適切なコンテキストを付与する手段としてClaude Codeは複数の手段を提供していて、特に効果的に活用しようと思うと使い分けの判断が難しいのでは?と思ってます。 Slash Command Subagents Agent Skills CLAUDE.md ここでは私なりにそれぞれが得意とする観点や用途を整理しようと思います。 Progressive Disclosure Progressive Disclosureは、最近よく主張されているタスクごとに必要なコンテキストだけを段階的に読み込ませるプラクティスです。 Claude Skillsの公式のプラクティス で推奨されている概念で、LLMのコンテキストウィンドウを効率的に使うための重要な考え方です。 例えばCLAUDE.mdやMCPはすべてのセッションで例外無く読まれます。10%のセッションでしか使わない知識を入れると無駄になってしまいます。 一方、Skillやコマンド、サブエージェントは必要なセッションでだけプロンプトを読み込む仕組みです。「限られた場面でしか使わない専門的な知識」を置く場所として優れています。 良い面ばかり言われるのでネガティブな面にもフォーカスすると、段階的にSkillを使えれば理想なんですが、自動で適切に適用していくのは現実的に難しいと感じています。 Must always be enabled when writing/reviewing React code のような強めのdescriptionを入れておいてもReactを触るときに必ず使ってくれるわけではない サブエージェントもLLMが自律的に使うかを決めますが、プロンプトなしでReactを書くときにReact agentへ移譲するとは限りません ですので、もちろん重要な仕組みではあるのですが、Skillやサブエージェントを増やし続けても人間のように自然なコンテキストスイッチをして実装してくれるわけではありません。 とはいえ考え方自体は非常に重要なので、すべてのコンテキストに読まれてしまうCLAUDE.mdは以下のような方針で最小限にしています。 いかに育てるかではなく、いかに情報を落とすかこそが大事。 むやみに増やさない 80%以上のタスクで必要になるか、プロジェクト概要など解像度を上げるため必要なむしろ抽象的な情報を中心にする 情報そのものよりProgressiveにDisclosureするための起点となる情報(例えばトラブルシュートについてはこのドキュメントにまとまっているよ、など)を記載する また、MCPについてはSkillsの登場の背景としてMCPがProgressiveにDisclosureできないことから説明されていたのでネガティブな印象を受けがちですが、Claude Codeでは段階的な読み込みがサポートされており有効にすればProgressive Disclosure面での不利はもうないので、用途にあわせてSkillsと適切に選択できると良いと思います。 Command vs Skills vs Agent CLAUDE.mdはProgressive Disclosureの文脈でむやみに育てるべきではないので、代わりにコマンド・スキル・サブエージェントを育てていくのが良いと思います。 これらの使い分けについては悩みがちだと思うので私なりの整理を書いておこうと思います。 Command vs Skill は本来の用途に寄せる まず機能面の話をすると、コマンドについては実はシステムコンテキストとしてコマンドとスキルはもうほぼ同一視されているので境界はユーザーのわかりやすさ程度しかありません。 ユーザーも「 /<skill名> 」でスキルをコマンドのように呼び出せますし、エージェントも「 Skill(skill=<コマンド名>) 」の形でコマンドを有効化できます。エージェントに「スキルの一覧教えて」等と問いかけると当たり前にスラッシュコマンドを含むリストを区別なく返す状態なので、我々利用側も同一のものと考えてしまって良いと思います。 ですので、あとはわれわれのわかりやすさで使い分ければ良い範囲ですが、個人的にコマンドとスキルは設計思想が異なるので「人が直接実行するのを主な目的とするか」で区別して使い分けています。 コマンド 人が直接実行する 知識というより手順を載せ、エージェントの動き方を制御したい スキル 人が直接実行することもあるが、サブエージェントで指定されたりProgressive Disclosureで知識を補完するのがメイン 全体の作業手順はあまり書かない(複数のスキルを有効にしたとき、指示矛盾が起きやすい) Skill vs Agent で重要なのは複数利用したいか サブエージェントについては @<agent-name> でサブエージェントを指定できるようになってはいますが、コマンド的にメインセッションにモデルやプロンプトを適用することはできません。 Skill vs Agentで重要なのは1セッションに対して複数利用できるかという観点で、例えばReact skill × TypeScript skillはできますが、React agent × TypeScript agentはできません。 なので再利用可能な知識の単位としてSkillを分離し、サブエージェントに読み込むスキルを指定することが望ましいと思っています。 name: frontend-engineer description: フロントエンドの実装を行う skills: - typescript - react --- < prompt > 責務分解点 責務、つまりサブエージェントをどう切るか。いろいろなパターンがあるかなとは思うのですが、私がよく切るパターンを紹介します。 これらすべてを使うわけではなく、タスクの難易度だったりで部分的に使ったりする前提です。 コンテキスト収集プロセス カイポケリニューアルのプロジェクトのフロントエンドでは開発時のガイドラインなどがかなりちゃんとガイドライン化されています。 逆にそれがゆえにすべてのドキュメントを読み込ませてしまうとコンテキストが膨れてしまうので、今回のタスクに関連するガイドラインのみを抽出して渡すようなプロセスが効果的です。 今回必要なガイドラインのみ集める・LLM向けに不要な情報を削り、LLM向けの整理されたコンテキストを用意することが責務ですね。 計画・設計プロセス これはよくあるパターンなので改めて書くことはそれほどないですが、設計において重要な観点などをプロンプトに含めておき設計に集中させます。 Tipsとして非常に重要なステップなのでSonnetを普段使いしていてもここだけOpusにしたり、また少し大変ですがこういうステップはOpenAI系のモデルのほうが得意なのでそちらに流すのもオススメです。 LiteLLM やBashツールでCodex CLIを使うことでこういうステップのみAnthropic以外のモデルに任せることもできます。 参考: https://code.claude.com/docs/en/common-workflows#use-extended-thinking https://docs.litellm.ai/docs/tutorials/claude_responses_api コードレビュー コードレビューも切り出すと効果的です。 体感「Aをしてはいけません」というルールを守らせながらコードを書かせる精度は出づらいように感じており、実装側には否定形ではなく例など用いて「こんな風に書いてください」を書くことが多いです。 逆にレビューステップだと否定形をかなり上手く扱って指摘できるので、特にレビューステップ用のプロンプトではやらないでほしいことを書くことが多いですね。 また、レビューはミュータブルでないタスクなので並列化しやすく、かつ毎回異なるフィードバックが返ってくるので質を上げたければN並列で依頼するのも効果的です。 QA アプリケーション次第ですが、例えばローカル環境を用意しやすいWebアプリケーションであれば開発サーバーを起動してE2Eで試したり、API開発であればcurlで叩いてみたりします。 プロンプトを書くメタプロンプト ここまで書いてきたように ワークフローをまず丁寧に設計すること そのワークフロー通りに動かせるようにプロンプトを書くこと が重要ですが、こういった知見はあっても守った状態で大量のプロンプトを書くのは非常に大変なのでプロンプトを書く用のコマンドを用意しておくのがオススメです。 参考までに私が使っているコマンドを貼っておきます: このコマンドは私が言語化したプロンプトのプラクティスに沿ってプロンプトを書き、サブタスクを使ったレビュープロセスを行うことである程度期待に沿ったプロンプトを書いてくれるコマンドです。 私が確認する前段である程度問題を検出して修正できますが、とはいえ意図と異なる結果になることも多いので、丸投げはできず全体をちゃんと確認しています。 私はまだそれほど質で困っていないので使っていませんが、 DSPy などプロンプトの評価プロセス自体を持つ仕組みを使うことで質を挙げていくことも有用だと思います。 まとめ Claude Codeを使ったAI活用のワークフロー設計について、私なりの知見をまとめてみました。 協業レベル・責任境界を意識してワークフローを丁寧に設計する ワークフローは協業レベルが低ければオーケストレーション要素を強化し、自律的に動かせるようにする。逆に高密度で協業するのであればレビューやデバッグなど本来の目的と異なる副次的な作業をサブセッションで分ける程度に留める、といった設計が大事 CLAUDE.mdを育てない・Skillを再利用単位として適切な粒度で育てる。エントリーポイントとしてコマンドやサブエージェントを構成 プロンプトの品質向上には時間がかかりますが、言語化・体系化する機会にもなるので、プロンプトを書くためのプロンプトを用意しておくと良い 皆さんのAI活用の参考になれば幸いです! *1 : サードパーティのLLM APIのProxy等で複雑な構成を組まない限りAnthropic以外のモデルを選択することができません。またサブエージェントはサブエージェントを呼び出すこともできません。一方、制約はこれくらいで以前はチャットの再開が不可能である問題等もありましたが対応され、極端に大規模なマルチエージェント協業が必要でなければ十分な機能を持っています。
はじめに カイポケコネクトの開発推進チームでエンジニアをしている @_kimuson です。 チームで「リファインメント文字起こしからLLMにチケット詳細を自動でメンテナンスしてもらう」という活用を試したところ非常に感触が良かったので紹介しようと思います! 課題 まず前提としてカイポケリニューアルではLeSS *1 を採用しており、スプリントを回す各チームが協業することでプロダクトを前に進めています。 われわれのチームは主にフロントエンドの開発生産性向上をミッションに置き、メンバー2人で一通りのスクラムイベントを実施しています。 その中でリファインメントを実施して、プロダクトバックログアイテムをReadyな状態(Acceptance Criteria(以降、ACと略します)が合意されており、Storypointが振られている)に持っていけるようにしています。 リファインメントで合意した内容は極力チケットに記載するようにはしてはいたんですが、気をつけていてもどうしても漏れは出てしまうのと、チケットに議論した内容をできるだけもれなく記載していくのもコストが掛かってしまっていました。特に2人チームということもあり、議論に参加していない暇な人が書くといったこともしづらいので議事録を丁寧に取っていると議論のスピードが落ちやすく、省力化して運用できると良いなーと思っていました。 結果、「どこかで会話したはずだけどチケットには残ってない」といった内容もたまに発生していました。 解決策 思いつきでリファインメントの文字起こしをそのまま食わせてMCP(Model Context Protocol)を介してJiraチケットにこういった情報を書くのを丸投げしちゃえば良いんじゃね?という話になりました。 文章をサマライズするのは、文字起こしの不安定さを考慮してもLLMにやらせるタスクとしては十分難易度が低いですし、コンテキストサイズも過度に枯渇する内容ではないので行けそうだよねとなり実施しました。 議事録(サマリー)ではなく文字起こしを使う われわれはSlackのhuddleでリファインメントを実施しているのでhuddleを使っていますが、huddleに限らずだいたいのMTGツールの議事録機能には 人が読んで読みやすいように良い感じにサマライズしてまとめられる議事録 正確な情報を追うためにサマライズされていないプレーンな文字起こし の2つが付いていることが多いと思います。 議事録はさっと見るには嬉しいですが かなり情報が削がれてしまっている 言ってない内容でサマライズされていることが多く信頼性に欠ける(huddle議事録に対する個人的な印象) といった点で文字起こしの方がおすすめです。 Atlassian MCPとの連携 文字起こしはコピペして食わせるだけなので、あとはその文字起こしの内容からチケットを更新できる必要があります。 われわれはプロダクトバックログの管理にJiraを利用しているため、Atlassianから提供されている公式のRemote MCPを利用しています。 OAuthに対応しているのでAPI Keyなどの発行も不要で使いやすいです。 { " mcpServers ": { " type ": " sse ", " url ": " https://mcp.atlassian.com/v1/sse " } } これを繋いでOAuthの承認だけ行えばClaude CodeでJiraチケットを探したりアップデートしたりができるようになります。 コマンド化 道具は揃ったのでコマンド化して再利用できるようにします。 以下の内容を .claude/commands/update-jira-from-minutes.md として保存します。 --- description: '議事録からJiraチケットを自動検出し、内容を要約してチケット情報を更新する' allowed-tools: mcp __ atlassian __ searchJiraIssuesUsingJql, mcp __ atlassian __ getJiraIssue, mcp __ atlassian __ editJiraIssue, AskUserQuestion --- You will analyze meeting minutes provided by the user, automatically detect Jira tickets mentioned in the text, and update those tickets with relevant information from the minutes. ## Process ### 1. Extract Jira Ticket References Scan the meeting minutes text for < PROJECT > ticket references in the format: - ` <PROJECT>-XXX ` (direct mention) - URLs containing ` /browse/<PROJECT>-XXX ` - Any other patterns that clearly reference < PROJECT > tickets Create a comprehensive list of all unique ticket IDs found. ### 2. Retrieve Current Ticket Information For each detected ticket: - Use ` mcp__atlassian__getJiraIssue ` with cloudId: ` https://<domain>.atlassian.net ` to fetch current ticket details - Retrieve: summary, description, status, issuetype, parent (epic), and subtasks if any - If a ticket has subtasks, also retrieve their information ### 3. Analyze Meeting Minutes Content For each ticket found: - Extract all relevant information from the minutes that relates to this ticket - Identify: - Technical decisions made - Implementation approaches discussed - Concerns or blockers mentioned - Dependencies on other tickets - Timeline or priority changes - Any acceptance criteria or requirements clarified ### 4. Generate Update Proposal For each ticket, prepare: - **Updated Description**: Enhance the existing description with information from the minutes - Preserve existing content structure (Why, Acceptance Criteria, Note sections) - Add new sections if needed (Implementation Plan, Technical Background, Dependencies, etc.) - Use markdown formatting - Write in Japanese - **Epic Assignment**: If the discussion indicates this ticket should belong to an epic, identify the epic ID ### 5. Present Updates for Confirmation Use ` AskUserQuestion ` to present all proposed updates: - Show ticket ID and summary - Display both the current description and proposed description in full - Show epic assignment changes if any - Ask user to confirm which tickets should be updated Format the question clearly: \`\`\` 以下のチケットを更新します。内容を確認してください: [Ticket ID]-[Summary] 現在のDescription: ... 更新後のDescription: ... Epic:[現在]→[更新後] 更新を実行しますか? \`\`\` Provide options: - "すべて更新" (Update all) - "選択して更新" (Select which to update) - "キャンセル" (Cancel) ### 6. Execute Updates Based on user confirmation: - Use ` mcp__atlassian__editJiraIssue ` to update each approved ticket - Update the ` description ` field with the enhanced content - If epic assignment is needed, update the ` parent ` field with the epic ID - Confirm successful updates ## Important Notes - **Cloud ID**: Always use ` https://<domain>.atlassian.net ` as the cloudId - **Project**: Only process < PROJECT > tickets - **Language**: Write all descriptions in Japanese - **Preserve Information**: Never remove existing information; only enhance and add - **Structure**: Maintain markdown formatting and section structure - **Accuracy**: Only include information that is clearly stated in the minutes - **Parent/Epic Format**: When setting parent/epic, use the format: ` {"key": "<PROJECT>-XXX"} ` ## Error Handling If any ticket cannot be retrieved or updated: - Note the error - Continue processing other tickets - Report all errors at the end 一応更新前に承認を行ってから反映するようにしています。 結果 このワークフローを使い始めてから非常に運用が楽になりました。 リファインメントではACの合意は大事なのでリアルタイムに会話し記載をします。それ以外の情報は基本書いてませんが、リファインメント直後に上記のコマンドを実行して文字起こしの全文を渡します。あとは承認だけして終わりです。 Claude CodeがACだけでなく どういう議論をしてそういう結論になったのか 気をつけるべきポイントはどこか 実装時に考慮すべきポイントはどこか といったリファインメントで議論された情報がちゃんと書かれています。 しかも、書かれた情報を読み返してみても議論した内容がかなり正確に整理されて記載されており、違和感のある内容や嘘が書かれていることがほぼほぼないので非常に上手くワークしていると感じます。 リファインメントを実施したら必ず実行する形で定着しているので、今後可能であれば自動で上記のワークフローが実行されるようにできると良いなと思っています。 まとめ リファインメント議事録を元にClaude Codeを使ってコストをかけずにJiraチケットをちゃんとメンテナンスする手法を紹介しました。 特にわれわれはメンバーが2人なのでかっちりと決め切るより緩く運用している側面もあり、そこにすごく刺さりました。少人数チームだとこういった雑務に割く時間のコスパも悪いので省力化してチケットの質もあがって良いことづくめでした。 皆さんのチームでも良ければお試しください!めっちゃおすすめです。 *1 : Large-Scale Scrum。スクラムを拡張したフレームワークで、単一のプロジェクトについて複数のスクラムチームが連携して協業します。
こんにちは!カイポケリニューアルのケア領域でPO *1 を務めている岩下です。 育休から復帰し、仕事と家事・育児の両立に奮闘する中で、「AIの活用」はもはや必須の仕事術となりました。 この記事では、そんな私がAIを仕事でどのように活用しているのか、具体例を交えてご紹介します。基本的な活用法が中心ですが、もしかしたら皆さんの日々の業務のヒントになるかもしれない――そんな思いで書いてみたので、ぜひ、最後までお付き合いください! プロダクトマネージャーはAIをどう使っている? 私のAI活用はまだ手探り状態ではありますが、実践例として特に以下の5つの方法を紹介します。 1. PRD(プロダクト要求定義)の叩き台作成 PRD(プロダクト要求定義)とは、「何のために、どのようなプロダクト(機能)を作るのか」を開発チームやビジネス関係者に共有するための設計図となる文書です。これから開発する機能のWhyやWhat、Howを言語化していくものです。 私は Gemini をPRDの叩き台作成に活用しています。 具体的には、社内で使用しているesa *2 のテンプレート(14項目)を直接貼り付けてインプットし、そのフォーマットに沿ってPRDの初稿を作成してもらいます。特に便利なのは、 会社のGoogleドライブを情報源としてPRDを作成してくれる 点です。 例えば、情報ソースの取得元として【既存のプロダクトについてのVoC(Voice of Customer)をまとめたスプレッドシートURL】や【介護保険制度についての最新情報を集約している共有フォルダ】をプロンプトに入れておきます。これにより、社内の既存ドキュメントや最新情報を参照した、より精度の高いPRDを迅速に作成できます。 これを叩き台に、詳細を追記、あるいは内容に誤りがあれば修正していくことで、短時間で80点くらいのPRDができあがります。 ちなみに、出来上がったPRDは社内の運用ルールとしてリスマネ観点でもレビューをしており、こちらもAIによるチェックができるようになっています。 ※ Geminiの「Deep Research」機能は社内で活用が推進されているものではありますが、ソースが一般的なWeb情報になるため、会社のGoogleドライブに格納された情報の信頼性の方が高く、私の業務ではあまり使用していませんでした。が、2025/11から「Deep Research」機能がアップデートされ、Gmailやドライブ(ドキュメント、スライド、スプレッドシート、PDF等)、Google Chatを情報ソースとして直接指定できるようになりました。今後は「Deep Research」も活用していくようになると思います! 2. 開発チェックリストの作成 開発者とのコミュニケーションを円滑に進めるため、 Gemini で開発のチェックリストを作成しています。例えば、新規のスマホ対応機能についてエンジニアと話す前にGeminiへ依頼して「スマホ向けの開発で考慮が必要なこと」のチェック項目をリストアップしてもらったことがありました。これにより、自身の知識レベルを上げ、より質の高い議論の準備ができます。 ▼具体例)「スマホ向け開発」での考慮ポイントのチェックリスト(経験者には当たり前のことかもしれませんが、”非機能要件”の洗い出し等、自分が経験したことがない分野についての開発前にはとても助かりました) 生成されたチェックリスト 3. 優先度判断のための議論深化 プロダクト開発における優先度判断は常に難しい課題です。そんなシーンではGeminiへのプロンプトを工夫し、議論を深めています。詳細なシナリオと登場人物の設定を与えて討論させることで、単なる質疑応答を超えた、思考のシミュレーションツールとして活用するイメージです!複数の選択肢やトレードオフについてGeminiの結論を参考にすることで、より客観的かつ多角的な視点から優先度を判断できるようになります。(あくまで最終的な判断をするのは自分です) 具体的には、議論を深める役割としてプロダクトマネジメントトライアングル的に3者(顧客・開発者・ビジネス)を設定し、それぞれの観点を用いて議論を展開するようにプロンプトを書き、話を深めてもらっています。(また、これはまだやったことはありませんが、役割に加えて「警戒派」「楽観派」「現実派」といったスタンスを与えることでも検討内容は深まるようです。) ▼具体例)訪問記録の開発ロードマップについて「思考モード」を使って3者の立場から議論を深めてもらいました プロンプトの入力例 この時には、上のようにプロンプトを入力するとそれぞれの立場からの意見と議論が展開された後、以下のようにMSP *3 の構成が提案されました。更に、これを元にしたユーザーストーリーやロードマップの提案も続けて行われました。 Geminiからの返答(一部抜粋) 意思決定からくる行動・アクションは「やる・やらない」の2択であるにも関わらず、プロセス(HOWや登り方)は基本的にはグラデーションになっているので、優先度判断には多角的に判断軸(私がしているように3者の観点を踏まえるなど)を持って思考することが求められます。上記の「討論させてみる」手法は、そのためのインプットとして使えると思います! 4. 議事録のポッドキャスト化と情報収集 情報量が多く、内容が複雑な会議の議事録は、後から読み返すのが大変ですよね。私はこの課題を NotebookLM で解決しています。 議事録を読み込ませて音声化するプロセス NotebookLMの魅力は、読み込ませたドキュメントを基に、その内容を要約したり、質問に答えたり、そして「音声」として再生できる点です。 資料の用意とアップロード: 普段利用しているesaや議事録をPDFやGoogleドキュメントとして用意し、NotebookLMのソースとして読み込ませます。 音声生成と再生: 読み込み後、NotebookLMの機能(「音声解説」ボタン一つで実行)を使って、平文のドキュメントをポッドキャスト風の音声に変換します。 音声化のメリット:対話形式で情報がスッと入る この機能のすごいところは、ただテキストを機械的に読み上げるだけでなく、対話形式やストーリー形式で音声を作成してくれる点です。 通勤中の「ながら」学習:生成された音声をラジオのようにイヤホンで聞くことで、通勤中や家事の合間など、移動時間やスキマ時間を有効活用できます。 理解度の向上:単調なテキストを読むよりも、対話形式の音声の方が頭に入ってきやすく、内容のキャッチアップ効率が格段に上がりました。 現在はmiroやesaの情報をPDF化してNotebookLMに読み込ませる工程に少し時間がかかるのが課題ですが、この「ながら学習」のメリットがそれを補って余りあると感じています。 5. Vercel v0によるUXの不確実性削減への挑戦 最近、Vercelのv0というAIコーディングツールの活用を始めました。 v0は、「シンプルなログインフォーム」「和風デザインのランディングページ」といった自然言語でのプロンプトを入力するだけで、 WebページのUIデザインやコード(React/Next.js/Tailwind CSSベース)を自動で生成 してくれるツールです。Webデザインやプログラミングの知識がなくても、 数秒でデザインの叩き台やプロトタイプを作れる ため、アイディアを素早く可視化できます。 PRDで言語化された要求定義だけでは、しばしばUX(ユーザー体験)の部分の不確実性が残りがちです。v0で簡単なプロトタイプやUIコンポーネントを素早く作成し、それをベースにチームと会話することで、開発に入る前の早い段階で認識のズレを解消し、不確実性を減らせると期待しています。まだ試行段階ですが、他チームのPOの間でも活用が広がっていて、私自身もその効果を楽しみにしています! ▼具体例)「スマホの訪問記録向け開発」で、画面左側にある吹き出しで「ここをこうして欲しい」のコメントをすると、右側にあるような画面が秒で出来上がります。 v0で生成されたプロトタイプの例 まとめ プロダクトマネージャー業に携わる人がAIを業務に取り入れると、手軽に周辺領域の知識を習得できるようになったり、より質の良い意思決定ができるようになるため、数々の業務を効率的かつスムーズに進めていけるようになります。また更に一歩踏み込んで、v0のようなツールを通じてUXの早期検証を行えば、業務領域を広げる形でアウトプットの質を高めることも可能です!今回ご紹介した事例が、皆さんの日々の業務に少しでも役立てば幸いです。 皆さんはどのようなAI活用術をお持ちですか?ぜひ教えてください! *1 : プロダクトオーナー;プロダクトマネージャーの役割の一部として、プロダクトの価値を最大化する責任を負うポジションです *2 : チーム・組織内の情報共有のためのドキュメントサービスです *3 : Minimum Sellable Product;販売可能な価値を持つ最小限のプロダクトのこと
これは 株式会社エス・エム・エス Advent Calendar 2025 の12月25日の記事です。 カイポケリニューアルプロジェクトでエンジニアリングマネージャーをしている荒巻( @hotpepsi )です。 今年の11月に LeSS' Yoaké 2025 というカンファレンスに参加したり、 認定LeSS実践者研修 を受けてきました。これらのイベントや研修では、学習の重要性や、調整役を置かないことの意義が語られていて印象に残ったので、それについて書いてみます。 スクラムとLeSSの関係 以下の話の前提として、LeSSについて少し補足します。 LeSS (Large-Scale Scrum) は大規模スクラムを謳うフレームワークで、単一のバックログと一人のプロダクトオーナー、複数のチームからなります。 LeSSはスクラムである と宣言しており、基本的にはスクラムの原則がそのまま適用されます。各チームは小さく、クロスファンクショナルなフィーチャーチームであることが望ましいです。 ※ 用語について クロスファンクショナル 一般的には、チーム内に複数の職能の人たちがいる状態。LeSSの文脈では、チームに求められるスキルを持っているか、習得可能であること フィーチャーチーム 顧客中心の視点を持ち、価値のある機能(フィーチャー)を届けるための全ての工程に関わり、完成させることに責任を持つチーム。必然的にクロスファンクショナルであることが求められる。対義語は、特定領域を担当する「コンポーネントチーム」 LeSSでの学習とは LeSSは、人は学習可能であるという前提に立ち、実験・学習・考察に振り切ったフレームワークとなっています。 研修では、繰り返し学習の重要性が語られました。ここでの学習は、チームの能力を高める全ての活動のことです。技術領域を広げたり業務ドメインを理解するなどの開発業務に関わる学習だけでなく、顧客インタビューや価値検証のような、要求分析の領域なども含まれます。すなわちLeSSが想定する組織学習とは、学習して影響範囲を広げていくことで、全体に対してオーナーシップを発揮して価値提供していくというものになります。 スクラムと全体最適 スクラムガイド ではスクラムの外の世界についてあまり語られていません。一方、「 大規模スクラム Large-Scale Scrum(LeSS) 」によると、LeSSでは「プロダクトが使われる現場」と「プロダクトが開発される現場」の2つの現場があるとしていて、チームの外側にも明確に意識が向いています。 一般に、プロダクトが成長して人が増えるとチームも増えていき、役割分担が生まれて境界ができます。そして次第に守備範囲が狭くなり、徐々に「プロダクトが使われる現場」から遠ざかり局所最適化されていきます。これに対してLeSSでは個人の学習能力に期待することで、自然な力学に逆らい、全体最適を目指します。ここで顧客価値とは「プロダクトが使われる現場」の価値であって、スクラムが注力することそのものです。なので全体最適に向かうというLeSSの原則は、スクラムと矛盾するものではなく、スクラムの明確化の一形態として解釈できるのかなと思いました。 LeSSそのものを学ぶ 開発者が学習の重要性を意識するためには、土台となる原則の理解が必要になります。研修ではいくつかのワークショップがあり、それを通じて、原則の理解や共感というのは、スクラムマスターがただ内容を紹介するだけで身につくものではなさそうだという感覚も得られました。 システム思考など実験・分析・改善活動などを通じて、開発者自身が議論し思考し、原則がどのように作用するのかを実感し記憶することで、原則とプラクティスが相互に結びつくと感じました。 調整役を置かないこと LeSSではなるべく調整役を置かないことも推奨されています。ここでの調整役は、プロダクトオーナーやフィーチャーチーム以外の様々な役割のことです。例えば設計を専門的に行う人やチームが存在すると、調整コストや待ちの要因となります。そうした依存関係は仕事のパイプライン化を生み出し、スプリント内で作業を完結させることを困難にします。また、チームから見ると調整役が学習機会を奪っていることにもなります。そのためLeSSでは、チームの外部に存在する役割=調整役がいないのが理想的です。 LeSSを導入してからの現在地 ここからは我々のLeSSの状況についてお伝えしたいと思います。カイポケリニューアルプロジェクトでは、チーム数が徐々に増え、複数のプロダクトオーナーと複数の職能別チームが存在する状況で、昨年LeSSを導入しました。 そこから徐々に、職能別チームからフィーチャーチームへ再編成し、少しずつLeSSの形に近づいている状況です。LeSS導入の少し前には、プロジェクトリードというチーム間のハブとなる役割を廃止したことがありましたが、これはまさに調整役を減らす活動だったのだと意義が再認識できました。 このあたりの導入による変化については、プロダクトオーナーやチームメンバーの声を座談会形式で記事化しています。 私自身はLeSSのマネージャーとしても活動しています。調整役にならないようにしたいなと思っています。 現在地としては、全体の半分くらいのチームがLeSSを実践しており、それ以外にも特定領域を担当するチームがいくつか存在します。またLeSS内部でも、プロダクトバックログ全体を管理するプロダクトオーナーの他に、特定ドメインのプロダクトバックログアイテムに責任を持つプロダクトマネージャーもいます。そうした状況で、このままLeSSを拡大していくのか、それともLeSS Hugeに向かうのか、などの議論も生まれたりしています。今後も、業務ドメインが複雑であるというプロダクトの特性を考慮しながら、どのようなLeSSに向かうのかを議論し実験していきたいと思っています。 LeSSの実践に興味のある方は、ぜひカジュアル面談でお話しましょう。以下のリンクからお気軽にお申し込みください。
はじめに こんにちは!カイポケコネクトの開発推進チームでエンジニアをしている @_kimuson です。 私たちのチームは、ストリームアラインドチーム *1 の生産性向上をミッションに持つチームで、その文脈で生成AIの活用にも取り組んでいます。 LLMを使った開発が当たり前になってきて、実際に生産性が上がる側面を実感している一方で、できることが多すぎるが故に夢が広がりつつも、現実では壁も多くて難しいポイントが多いのも事実です。人間の作業がボトルネックになってしまい、思ったほど生産性が上がらないという課題にもぶつかります。 このエントリでは、生産性向上をゴールに、AIをどう活用していくのが良いかの整理と、私たちのチームで実際にどういうコンセプトでAI活用を進めているのかを紹介したいと思います。 LLMへの移譲レベルを定義する AIエージェントを活用して仕事をするということは、仕事の一部をLLMに権限移譲するということです。 したがってLLMとの責務の境界を明確に意識しておくと良いだろうなと思っています。 ここでは、チーム開発でよく使われる Delegation Poker *2 の移譲レベルの分類を借りて、人間とAIエージェント間の責務の移譲レベルを分類してみます。 よくあるLLMの利活用シーンと対応する移譲レベルは下記のように対応します: 流れ 移譲レベル 主体 ChatGPTに設計について相談し、自分で実装 Consult 人間 Copilotの補完を使いながら、自分で実装 Consult 人間 細かい指示を出しながらエージェントが実装。Driver がエージェントなモブプロ Agree 人間 & LLM LLM にチケットを渡してPRまで作ってもらう Inquire LLM LLM にチケットを渡してPRを作ってもらい、LLMによるレビューでマージまで完結 Delegate LLM ConsultレベルではあくまでLLMに相談をするだけなので主体は常にわれわれ人間です。AgreeレベルになることでLLMも共同で責務を持ちますが、われわれ人間も一緒に作業をすることになります。 この辺りまでの活用が現実的に多く行われている・採用されやすい移譲レベルだと思います。 そこからさらに移譲レベルを上げていくと 最終レビューはするけどタスクの主体はLLMに移譲されているInquireレベル さらにはわれわれ人間による承認さえ不要なDelegateレベル に到達することなります。 移譲レベルがなぜ重要か まず大前提として、コーディングを初めとしてタスクの作業時間はわれわれ人間よりLLMの方が圧倒的に早いです。物理的な速度もそうですし、LLMは並列で作業を進めることも可能です。 生産性を上げるには、ボトルネックを解消していくことが大切であり、作業がLLMのほうが高速だからこそ移譲レベルを上げていくことでボトルネックが解消し、移り変わっていきます。 Consult / Agree レベル : 人間の作業時間がボトルネック 人間が必ずつきっきりで作業する必要があるため Inquire レベル : 人間の認知負荷がボトルネック 人間が変更内容を認知し、責任を持ってマージする必要があるため Delegate レベル : 人間のチケット生成速度がボトルネック 理論上すべてがDelegateなら、お金が許す限り24時間開発を進められるが、チケットの方が足りなくなるはず つまり、生産性を上げるには、LLMへの移譲レベルをいかに上げていくかがポイントになりそうです。 移譲レベルをどう上げていくか アウトプット(アウトカムではない)の生産性だけを考えた場合、理想論で言うと、人間はボトルネックにしかならないのですべてのタスクをDelegateレベルで進めるのがベストです。 とはいえ、現実的には クオリティコントロール 方向性の維持 アウトカムにならない といった側面を考えると、すべてを丸投げするのは無理があります(できたらシンギュラリティですね)。 現実的には、 開発タスクの中で移譲レベルを上げやすいタスクを移譲していき、手離れさせた時間でエンジニアがより難しい問題にAgree/Consultレベルで協業することで生産性を高める のが良いと思っています。 より具体的には 主要なエンジニアのタスクを分類する 丸投げビリティ *3 を評価し、どのタスクをどの移譲レベルに持っていけるか評価する DelegateやInquireレベルに移せるタスクを移譲していく という流れで方針を作っています。 丸投げビリティという指標 LLMに丸投げしやすいタスクを定性的にでも評価できないと、どのタスクを移譲すべきか判断しづらいです。 個人的には、以下のような観点で評価できそうだと考えています。 最悪壊れても良いか ワークフロー設計でアウトプットを安定させるのは前提としても、LLMなので(まあ人間でも同じですが)一定のミスは許容せざるを得ません。それがどの程度許容できるかという観点です。 例えば、CIの設定ならまあ壊れるときもあるよね、という許容度があると思います。一方で、本番機能のコアロジックだとそうはいきません。 LLMでどれだけ期待値ラインに近いアウトプットを出せるか ふわっとしていますが、そもそもある程度見て「よし!」となるアウトプットが出づらいなら最初からAgreeでやれば良い、という話です。 個人的にLLMが解けるかはコンテキストがすべてだと思っています。暗黙知でコンテキストに含められない、デカすぎて含められない、といった制約がなければ、情報の集め方やワークフロー設計を適切にチューニングすればある程度どうとでもなる気はします。 チーム内での相対的な指標としては Storypoint が使えるかもしれません。ただし、Storypointはチーム固有の基準なので、丸投げビリティの評価には定性的な観点も併せて考慮する必要があります。 その作業内容が自動化されることでどれだけ嬉しいか 一般的な自動化と同じ観点です。例えば年1でしか発生しないタスクに適用していきますか?という話ですね。コマンドの整備などにもコストがかかりますから。 私たちはこの考え方で評価をしていますが、「どういうタスクがLLMに丸投げできるか」の評価が行えていれば手段はなんでも良いと思っています。 例えば下記の記事では「生成されたコードを自分が読んでいない割合」が基準になるという考え方が紹介されています。読んでない=すでに移譲されている、ということなので丸投げできるよね、という話で、こういったシンプルな考え方もアリだなと思います。 移譲レベルの上げ方 タスクごとの移譲レベルの評価ができたら、あとは実際にLLMの責務を増やしていく必要があるので少し具体に踏み込んで、実際にどうやって移譲レベルを上げていくのかを紹介します。 Agree から Inquire へ LLMへの移譲レベルを上げる=LLMに移譲する責務を増やす= コンテキスト分解が必須 、というのがAgreeからInquireへの移行のキモだと思っています。 コンテキストウィンドウの物理的なサイズももちろんありますが、それ以上に複数のことをやらせるとわかりやすく性能が落ちます。 つまり、 LLMでも単一責任の原則が重要 であり、複数の責務を持たせるならオーケストレーションが前提になります。 エージェントが別のプロンプト(=責務)を持つエージェントを呼び出せる必要があります。Claude CodeはTaskツールとサブエージェントによってこれをサポートしているので、サブエージェントとコマンドを作成してみました。 作業イメージとしてはこんな感じです: エンジニア: /inquire_xxx <チケットURL> の実装をして Claude Code(Orchestrator) use: オーケストレーションスキル Claude Code(context-collector): 情報収集 Claude Code(architect): 設計 Claude Code(engineer): TDD実装 Claude Code(reviewer): レビュー×N Claude Code(pr-creator): PR作成 & CIチェック Claude Code(QA): 動作検証 → レポート 単一の責務を持つエージェントが協業することで質の高いアウトプットは出やすくなりますが、手離れする以上、期待と異なる場合に止めることができないので渡せる難易度に限界はあります。 Inquire から Delegate へ Inquire時点で実装面は移譲されているので、Delegateへの壁は大きく2つあります。 GitHubにおけるマージブロックをどう適切なタスクでのみ回避するのか AIレビューでどう品質保証するか 前者は、Delegateレベルで移譲できる対象のソースコードに対してCODEOWNERSでオーナーをもたせることでエージェントによるレビュー及び承認・マージを行うことができます。 後者は、「エンジニアがコードレビューで担保している内容」を言語化する必要があります。加えてタスクごとに観点が異なるはず(機能実装とCIの管理では観点ぜんぜん違いますよね)なので、タスクごとに個別で考える必要があります。 例: Renovate の Delegate 化 直近ありがたみが大きそうで取り組んでいるのがRenovateの手離れです。 下記は実際には運用されていない叩きですが、例えば1例としてこういった確認及びLLMによるオートマージが考えられます。 0.x以外のpatchバージョンは変更内容をざっと読んで問題なければカジュアルにApprove minor updateや0.xアップデートはClaude CodeにBreaking Changesを中心に影響範囲を調査してもらい、影響がないかを確認 影響なし → Approve 影響あり → Inquireレベルで修正を行ってもらい、エンジニアのレビューにフォールバック Majorなどでもパッケージごとのルールで制御 Majorはデフォルトでは慎重に扱う 例えば開発環境で使うパッケージはpnpm buildが通ればOKとか、グループごとに確認すべき内容を言語化。通っていればマージまでOK アプリで使うパッケージでも、例えば副作用のないdate-fnsやes-toolkit等はCI通過を持って問題なしとできそう こんな感じの確認がClaude Codeによって行われれば、Approve & マージして良いのではないか、という考え方です。 ここはチームでの合意形成がタスクごとに必要となります。例えばRenovateは上記のようなガイドラインを持ってマージOKとしてよいか、といった議論ですね。 並列で Inquire 以上のタスクを行う仕組み Inquireレベルでゴリゴリのタスクを進めるのには一定の仕組みが必要です。 現状は私の開発マシンで1つのworktreeをClaude Code用に割り当て、手前味噌ですが私が作っている d-kimuson/claude-code-viewer *4 のスケジューラ機能(cron式にマッチする時間で自動でメッセージ送信)を使うことで完全に手離れしたところで軽いタスクを実行しています。 LLM タスクのリファインメント 上記で挙げた丸投げビリティ(定量的にはStorypoint、定性的にはACの充実度や内容)を言語化し、LLM自身に「やるべきタスク」「やらないべきタスク」を分類させる Claude Codeに実施させるべきかの最終チェックは一応したいので分類された情報をみて、承認したチケットをQueueに積む 自動実行 Queueから定期的にチケットを取り出してinquireレベルでClaude Codeを実行 まとめ LLMへの移譲レベルを整理し、私たちが現在取り組んでいるLLMによる開発生産性向上の考え方を紹介しました。 移譲レベル(Consult / Agree / Inquire / Delegate)を意識的に設計することで、エンジニアは本当に難しい問題・楽しめる問題に集中できるはずです。 実際に判断基準をより正確に言語化したり、一部のタスクをDelegateに移していくところはまだまだ私たちも取り組んでいる最中であり、チームでの合意形成を大事にしながら進めていきたいと思っています。 *1 : チームトポロジーで紹介されているチームの分類の1つで、ドメインに沿って継続的にプロダクト開発を行うチームがこれに該当します。 *2 : Management 3.0 で紹介されている管理者からチームへ権限移譲をするためのゲームです。権限を7つのレベルに分類し、移譲レベルの期待値をすり合わせます。この記事では人間からAIへの権限移譲の度合いを分類するために利用しています。 *3 : タスクをLLMに移譲しやすいかどうかを評価する指標。造語です *4 : Claude CodeのGUIクライアント
こんにちは、カイポケの開発組織責任者をしている酒井です。 今日は私の大切な仕事の1つである「エンジニア採用」について書きます。この記事は 株式会社エス・エム・エス Advent Calendar 2025 の23日目の記事です。 「意思決定をスケールするエンジニア」がなぜ重要なのか エス・エム・エスの事業領域は、制度・業務・環境が複雑に絡み合う変化の大きい「社会課題」という不確実性の高い領域です。プロダクト開発において重要なのは、こうした不確実性と向き合いながら、試行錯誤を通じてソフトウェア設計へと落とし込み続けられるかどうかだと考えています。 事前に立てた計画どおりに進めれば問題が解決するわけではなく、絶対的な正解が存在しない中で、状況に応じた判断を積み重ねながら物事を前に進めていく力が求められます。そのためには、特定の個人の力量に依存するのではなく、組織としてスキルやマインドセットをバランスよく身につけていく必要があります。 私たちが採用したいエンジニアは、単に経験が豊富な人という意味での「強い個人」ではありません。実装が速いことや難しい技術に詳しいことは前提条件の一部にすぎず、本当に重視しているのは、判断を引き受け、学習をチームに広げ、不確実性の中でも組織として前に進められる状態をつくれるかどうかです。 プロダクトや組織が成長するにつれ、意思決定は一部の人に集中しやすくなり、結果としてスピードを失ってしまうことがあります。そのボトルネックを解消するためには、強い個人を増やすこと以上に、判断と学習が分散する構造をつくることが重要だと考えています。 このような「意思決定をスケールするエンジニア」に対して、私たちは何を大切にし、採用の現場ではどのような点を見ているのかについて以降で整理していきます。 何のための「技術力」か 私たちの採用プロセスでも、他の多くの企業と同様に、ソフトウェアエンジニアの選考において「技術面接」を行っています。ここでは、過去のご経験を伺いながら現実の問題やビジネス上の課題をどのように捉え、ソフトウェアとしてどのように設計してきたのか、その難易度やスケール感などを理解させていただいています。 技術面接の結果は、能力を把握するうえで非常に重要な情報ではありますが、それだけで採用を決める十分条件とはしていません。特により高い期待役割を担っていただくポジションになるほど、技術的な正しさだけで問題を閉じてしまわず、周囲の思考を広げ、チーム全体の学習速度を高める関わり方ができるかどうかも含めて見ていきたいと考えています。 問題解決の能力 前述のとおり、私たちが向き合っている事業領域には常に高い不確実性が存在します。ときには、機能を開発する意味(WHY)そのものが明確に定義されていない状態で向き合うこともあります。 そのような状況において私たちが期待しているのは、「これはプロダクトオーナーが決めること」と線を引くことではなく、必要なコンテキストを集め、自分ごととして課題設定に関わりながら少しずつソフトウェア設計の材料をつくっていく姿勢です。 表層的に現れている問題だけを塞ぐのではなく、なぜその問題が起きているのかを考え、アーキテクチャや組織、プロセスといった複数の観点を行き来しながら構造的に課題を捉え直していくことが重要であり、そのための手段として「技術」を使っているエンジニアと一緒に仕事をしたいと私たちは考えています。 面接では「設計」の経験について多く伺いますが、一般論としての設計ではなく、向き合ったドメイン固有の不確実性に対してどのような設計判断を行ったのか、その設計が時間の経過とともにどのように変化していったのか、複数の選択肢の中からなぜその判断を選んだのか、何を守り、何を捨てたのかといった「判断の背景」を重視しています。 リーダーシップのあり方 技術力と同様に、採用においてはエンジニアとしての「リーダーシップのあり方」も大切にしています。 私自身は、強いリーダーシップに必ずしも肩書きは必要ないと考えています。権限の有無に関わらず、状況を理解し根本的な課題を設定しながら物事を前に進めていく力や、意見の対立を恐れずに状況を整理し、挑戦の道筋を描いていく力こそが重要だと考えています。 これまで多くの面接を担当してきた中で、複雑な問題解決を経験してきたエンジニアの多くは、再現性のある「技術以外の能力」を併せ持っていると感じることが多くありました。特に、社会的背景や業界特性、ビジネス上の文脈といったコンテキストを理解しようとする姿勢が強く、「なぜ(WHY)、このタイミングで(WHEN)、誰のために(WHO)、この問題を(WHAT)、解く必要があるのか」といった点について、解像度の高い説明をしていただけることが多い印象です。 また、そのようなリーダーシップを発揮する方ほど、他者や状況からのフィードバックに対しても柔軟であるように感じます。他者からの指摘や、判断の結果としてユーザーから寄せられた意見に対して、防御的になるのではなく自分の前提を疑い問題を捉え直そうとする姿勢を持っているかどうかを大切に見ています。 面接の場では、私自身が理解しきれなかった点や違和感を覚えた点については率直に質問するようにしています。もちろん、意図的に揚げ足を取るような聞き方をすることはありませんが、お互いの考えをすり合わせるための対話として、その背景や判断理由を丁寧に伺うようにしています。 制約が強い環境であること 問題解決力やリーダーシップに加えて、外部環境による制約と向き合いながらエンジニアリングを行ってきた経験があるかどうかも、大切な観点の1つです。 法制度や業界特有の商習慣、リソースや時間の制約、大規模で複雑なソフトウェアといった前提条件の中で、理想を理解しつつも現実的な着地点を見出してきた経験やその中で「将来変えられるもの」と「変えられないもの」をどのように切り分けて考えてきたのかは、必ず伺うようにしています。 介護業界においては、複雑な法制度が顧客業務にとって大きな制約となり、同時にソフトウェア設計にも強く影響します。これらを無視することはできない中で、何を選び、何を捨てるのかという判断を積み重ねてきた経験は、私たちが特に大切にしたいポイントです。 頭数で解決しない採用 私たちは、複雑で不確実性の高い社会課題に向き合いながらソフトウェア開発を行っています。もちろん、ここまでに書いたすべての能力や経験を一人のエンジニアに求めているわけではありません。 採用において私が大切にしているのは、人数を目標にして「強い個人」を集めることではなく、未来の「強いチーム」をつくるために必要な視点や役割を持った方と出会うことです。 選考の場で多くのエンジニアの方と対話する中で、私自身も日々多くの学びを得ています。これまでエス・エム・エスの採用に関わってくださったすべての方に感謝しつつ、これからも、組織の未来を一緒につくっていける方との出会いを大切にしていきたいと考えています。 引き続き、カジュアル面談や選考へのご応募をお待ちしています。
この記事は 株式会社エス・エム・エス Advent Calendar 2025 の22日目の記事です。 はじめに こんにちは! ウェルミージョブ 、 シカトル 、 カイゴジョブアカデミー でエンジニアリングマネージャーとプロダクトマネージャーを担当している 豊濱 です。 自己紹介は先日の記事をご覧ください。 tech.bm-sms.co.jp 今回は「作らない技術」についてお話します。 ものづくりに関わるコストや時間が大きく減らせる時代になったからこそ、こういった視点を持って取り組むことで本質的な課題に取り組めるのでは、と考えています。 いつもやっていること プロダクト開発に関わっている方は、細かい違いはあれど概ね以下の流れで進めていることが多いのではと思います。 現状や市場、顧客の分析 達成したい目的はなにか 提供できる価値はなにか プロダクトとして提供すべきものはなにか 設計、開発、テスト、リリース 検証 1〜3番あたりに戻り、発展させる ものづくりをするために、感覚や定性ではなく、目的や価値を明確にして、チーム全体で同じ目線を持って取り組むのはとてもいいことです。 ただそれを検証するために「なにかものを作らないといけない」という流れが当然になっていないでしょうか。 なにかを作るには人件費やインフラ・アプリケーションの構築、リリースをするのであれば運用やメンテナンス・顧客対応、そしてそれらをこなすための「時間」など、投資が必ず必要になってきます。そこへ至る前にまだやれることがたくさんあるのでは、と考えています。 作らないための工夫 いまあるものの組み合わせや見直しでどうにかする 社内ツールの使いづらさを解消したい リードタイムを短くしたい 人的リソースを最適化したい 複雑なフローをなくしたい こういった目的や成果をもって進めることはよくあります。 新しいプロダクトで価値提供するのが適切な場合もありますが、いまあるフローをガラッと変えるのも大きなコストと時間がかかってしまいます。 いまの複雑なフローを全く新しいシンプルなものにする →いまのフローのなかで、待ちが発生している部分を並列化する 複数ある管理画面を1つに集約する →複数の管理画面は変えず、まずはデータの連携を人手(コピペ)でやっている部分を自動化する といったところから入るのも次に進める大きな一歩だと考えています。 現状の理解や可視化に時間がかかってしまうのでは、という見方もありますが、なぜそれが存在しているのか?を確認することは新しくプロダクトを作るにしても必要なプロセスなので、全く無駄になるとはあまり考えていません。 そのプロダクト・業務をなくしたらどうなるのか もはや、作らないどころか作ってあるものをなくす話になっていますが、いまあるものが本当に必要なのか、という検証もやっていくべきです。 なくすことで失われる価値はなんなのか 維持していくための投資を鑑みるとどうなるのか 新しくプロダクトを作って移行させるコストとのトレードオフはどうなのか 実はなくすだけで、目的が達成できるのではないか もちろん、単なる投資対効果やトレードオフだけで判断できるわけではありませんが、発想として「なくしてみる」も考えていくのが大事だなと思います。 まとめ さまざまな技術ソリューション・近年の生成AI・IDEに代表されるツールによって、10年前に比べて作るハードルは圧倒的に下がり、作りながら試行していいものに発展させていく、というのがスタンダードな時代になってきました。 そんな時代だからこそ、「いかに作らずに成果を出せるか」みたいな視点を持っておくのも1つの「技術」なんじゃないかなと考えて、こんなタイトルをつけてみました。
この記事は 株式会社エス・エム・エス Advent Calendar 2025 の19日目の記事です。 こんにちは。エス・エム・エスの人材紹介開発グループでマネージャーをしている @kenjiszk です。今回はカジュアルな私の悩みについて書いてみたいと思います。 コードを書かないマネージャー 業務でコードを書くかどうかはマネジメントしている領域や組織規模に寄ると思いますが、私は現在、業務において「コードを書かないマネージャー」というスタイルをとっています。コードを書くことが嫌いではないですし、実際にコードを書くことで手触り感を持ってプロダクトを扱うことは非常に好きです。ただし、マネジメントという観点において以下の理由でコードを書くことをしていません。 マネジメント業務に関わらず、仕事はレバレッジが効くポイントに力を割くことが良いと考えている 残念ながらスーパーエンジニアではない私は自分がコードを書くことで効かせられるレバレッジよりも、マネジメント業務によって事業に与えられるレバレッジの方が大きいと感じている むしろ、今の状態で中途半端にコードを書き始めると2種類のボトルネックを発生させる 1つ目は、兼務としてコードを書くので、おそらく実装速度やクオリティは高くない、大きなissueは扱えない 2つ目は、コードを書くことに時間を使うことで、本来するべき意思決定や戦略づくりなどに時間が割けなくなる ということで、意図的にコードを書いていないし、それが良いと思っています。 生成AIの登場 ただ、この状況は自分が過去にコードを書いたことがあるから成立しているとも言えます。また、SREやらマイクロサービスの運用やらもやっていた経験があるのでシステム全体を通してある程度理解できるという前提があり成立していそうです。 そんなこんなでまあなんとかやっているわけですが、最近はこんな事をよく口にしているなあと思いました。 「その辺はAIに書かせちゃっても大丈夫そうですね」 「この処理はAIが得意そうなんで書かせちゃいましょうか」 「AIでコード書くの当たり前になってきてますねー」 そして気づきました、はて、私はAIを活用してコードを書いたことあったっけ?、と。 コードを書かないマネージャーはどこでAIを使ってコードを書く? やったことがないならやってみればいいのですが、私はコードを書く業務をしていないのでAIを活用したコーディングを試す場所がありません、どうしよう。 無理やり業務の中にコーディングのタスクをねじ込んでも、前述のように自分がボトルネックになることは目に見えています。じっくり腰を据えて取り組めば良いのでしょうが、色々な仕込みをしている最中でもあって、そっちはそっちで時間を割かないといけない状況でした。 であればもう個人開発しかなさそうです。 以前は個人開発をしていたこともあったのですが、なかなか継続的にコードを書く時間が確保できるわけでもないのでここ数年は断念していました。AIがコードを書いてくれるなら時間をそこまで使わなくても何か作れそうなので個人開発を再開してみることにしました。 このブログで伝えたいことの主題ではないのでアプリの機能や中身については触れませんが、Flutter + Firebaseという構成でシンプルなiOSアプリを作ってみました。デザインも含めて実装していて、なんとなくの雰囲気は以下のようなものになります。 やって良かったvibe coding AIによるコーディングについてはあらゆるところでその効果が語られていますので改めてここでまとめるつもりはないですが、実際に手を動かしてやってみたことは価値があったなと思います。 まず当たり前の話ですが、圧倒的に便利でした(笑)。 first commitが2025/11/6ですが、そこから週に数時間空いた時間を使う程度で約1か月で概ねの機能を作り終えることができました。シンプルな構成とはいえ、Firebaseによる認証周り、Firestoreへのデータ保存、トップページから複数ページへの遷移など、一通りの機能を持つアプリです。これらが予想外に簡単に作れてしまいました。 個人的に特に便利だと感じたのは、実現したい機能の概要を伝えると、それに適したライブラリの選定から提案してくれる点です。最新の言語・フレームワーク事情をそこまでキャッチアップできていない身としては、この辺りの調査の時間を大幅にショートカットできるのは非常に助かりました。 AI開発は領域によって、能力のスケールアウトをしてくれる場合とスケールアップをしてくれる場合があるということもわかりました(スケールアウト/スケールアップは本来インフラ用語で、それぞれ「台数を増やして処理能力を上げる」「単体の性能を上げる」という意味です。ここでは「自分と同じ能力を持つ分身を増やす」「自分にない専門能力を獲得する」という意味で使っています)。 自分が得意な領域や実現方法を詳しく知っている箇所では能力をスケールアウトしてくれる感覚になります。私の場合は、Flutter + Firebaseという構成でアプリを作ることは何度か経験があるので、この部分は自分が出来ることを代わり単に高速でコーディングをしてくれているという感覚でした。自分がもう一人いる感覚です。 一方で、デザインだったりアプリのアイコンの作成というところでは、私は専門家ではないのでなんとなくのイメージを伝えるだけで、それなりのクオリティのものを作り出してくれました。ここは確実に能力のスケールアップがされている実感があり、AIを使っていて一番テンションが上がるポイントでした。これは自分がもう一人いるというよりは、専門家が自分のために働いてくれているという感覚でした。 別の観点として、自分で手を動かすにはちょっとテンションが上がらないけどやらないといけないタスクは全部AIがやってくれるのはとても良く、私の場合は、ストアにアプリを出すための設定やストアに表示する魅力的な文言作成は全然やる気が出ないのでこの辺りを全部任せられるのはとてもありがたいなと思いました。これは文句を言わない秘書的な感覚です。 ちなみに全く新規の言語やフレームワークだときつそうだなというのも同時に感じました。少なくとも私が扱うと、言語やフレームワークの特徴や設計方針などを理解していない状態でAIに任せると結構酷いものが出来上がってきそうです。 また、実装についてはマルっと任せると冗長で適当なただ動くだけの巨大なコードを出してくるので、必然的に意味のある最小単位の指示をAIに出すことになり、細かい修正を少しずつ積んでいくというスタイルに自然となりました。 最後に AIによるコーディングでアプリ開発をするという実績を解除しましたので、今後は自信を持って「これ系の処理はAIが得意そうだからAIに書かせましょう」とか「AIで開発するとレビュー大変ですよね」と声高に言っていこうと思います! 冒頭で触れた、「コードを書かないマネージャー」という選択も今後変わってくるかもしれません。今回はAIをコーディングに活用する部分だけに触れていますが、あらゆる業務でAIの活用は積極的にしていきたいと考えています。 AIの登場によりどんなことでも色々と触って試してみるコストが大幅に下がったと思うので、積極的に新しいことを取り入れチャレンジする組織を目指していきます。
はじめに この記事は 株式会社エス・エム・エス Advent Calendar 2025 の18日目の記事です。 はじめまして。エス・エム・エス プロダクト推進本部 採用・組織開発支援グループの韓です。 今年の8月に入社したばかりですが、なぜ私がエス・エム・エスに入社したのか、今やっていること、そして今後やっていきたいことを紹介します。 今までの経歴 前職はデジタルマーケティングSaaSを提供する企業に所属していました。2018年にエンジニアとして入社し、約5年間開発に携わりました。開発業務だけでなく、チームリードとしてのマネジメントや外部登壇など、様々な経験をさせてもらいました。 チームで開発したプロダクトがスピーディーに形になり、ユーザーから嬉しいフィードバックが届く瞬間こそ開発の醍醐味だと感じ、エンジニアとして楽しく仕事に向き合っていました。 転機が訪れたのは、エンジニア採用が芳しくなく、誰かエンジニア採用を牽引する必要が出てきたときでした。エンジニアバックグラウンドがあり、コミュニケーションが比較的得意だった私に白羽の矢が立ち、2023年7月からエンジニア採用責任者としてのキャリアが始まりました。 面接官以外の採用業務は未経験でしたが、周囲の協力もあり、大変ながらも期待に応える成果を出すことができました。エンジニア時代に感じた、チームで開発したプロダクトがスピーディーに形になる体験において、優秀なチームメンバーが存在したことが1つの要因であると感じています。そのチームメンバーがいたのも当時の採用があったからこそであり、会社・組織・チームにとっては採用が重要であるのを身をもって感じました。また、組織やプロダクトの課題と候補者のキャリアに深く入り込むことで、なぜその候補者に入社してもらいたいのかのストーリーを作り、結果として候補者に熱量高く入社してもらえたときの嬉しさはかけがえのないものでした。そういった成功体験を通じて、採用をはじめとした「人・組織」に向き合う楽しさ、そして優秀なメンバーを採用することのインパクトの大きさを肌で感じました。 エス・エム・エスに入社した理由 前職での人事の仕事も楽しかったのですが、人事へのジョブチェンジから2年、在籍期間も6年半が経ち、「他にどのような環境があるのか」と外の世界にも興味を持ち始めました。 そんな中、現在のグループ長である @emfurupon777 とカジュアル面談をする機会があり、エス・エム・エスについて詳しく聞きました。特に刺さったのは、企業理念やミッション・バリューにあるように「続」を重視している点です。つまり、「長期を見据えて価値を出し続けること」を大事にしているという文化です。 エス・エム・エスが向き合う日本の高齢社会の課題は非常に壮大です。1年やそこらで解決できるものではなく、10年、20年というスパンで考えなければなりません。そのためには長期視点で思考し、継続的にアクションを取り続けることが重要になります。 私自身、そこまで長期で思考した経験はありませんでしたが、「将来組織を牽引する人材になるには、長期的な視座が必要だ」という課題感を持っていました。また、この壮大な課題に向き合う組織を作ることは非常にチャレンジングだと感じ、強く惹かれました。 選考過程で、技術責任者の @sunaot 、人材紹介開発部EMの @kenjiszk 、人事の @fkc_hr ともお話ししましたが、皆さんが優秀であることはもちろん、「エス・エム・エスを通じて社会を良くしたい」という熱い思いがひしひしと伝わってきました。そのパッションに感化され、次のチャレンジの場としてエス・エム・エスを選び、今年8月に入社しました。 今エス・エム・エスでやっていること 現在は、プロダクト推進本部のエンジニア採用をメインで進めています。 採用業務は多岐に渡りますが、時間的にも比重が大きいのは「カジュアル面談」と「候補者の選考フロー構築」の2つです。 カジュアル面談について 前職での経験から、「カジュアル面談でどれだけ自分たちに高い関心を持ってもらえるか」が候補者の意思決定における重要な要素だと考えています。また、入社時に期待されていたことの1つが、今までのエス・エム・エスにはない「私ならではの熱量・アプローチ」でした。そのため、自分の言葉でエス・エム・エスの魅力を語れるようになる必要がありました。 組織や事業のキャッチアップが落ち着いた入社1か月半頃から、まずは田辺さんやEM陣の面談に同席して見学。次に私が作成した資料を使ってメインで話し、 @sunaot や @emfurupon777 に同席してもらってフィードバックをもらう……というサイクルでブラッシュアップしていきました。皆さんとても協力的で、しっかりフィードバックをもらえる環境は本当にありがたいです! 採用チームでは今年9月以降、ダイレクトリクルーティングや紹介会社連携の強化により母集団形成がうまくいっており、私の9月から12月現在のカジュアル面談担当数も70件を超えました。 まだ精度を上げる余地はありますが、短期間で多くの機会をもらえたおかげで、候補者の方から「韓さんとの面談が有意義でした」といったポジティブな感想をいただけることも増えました。また、私が担当した候補者の方がオファーや内定承諾に至るケースも出てきています。 カジュアル面談で話すたびに、エス・エム・エスの向き合う課題の壮大さと、やるべきことの多さを再認識します。私が魅力を感じたときのように、候補者の方にも「今とこれからのエス・エム・エス」の魅力を感じてもらえるよう、今後も力を入れていきたいです。 選考フローの構築 入社して驚いたことの1つが、「候補者への向き合い」に相当な力を入れている点です。 現在は毎朝、採用チームでパイプラインを確認しています。各候補者の方にどのような選考フローを組むべきか、この場で決められない場合は誰に相談するかを話し合います。エス・エム・エスの選考は画一的なフローではなく、候補者ごとに柔軟にカスタマイズするため、しっかりとした議論が必要です。 当初は「ここまで時間をかけて決めるのか」と驚きましたが、エンジニア採用の難易度が年々高まる中、候補者一人ひとりに深く入り込む重要性を再認識しています。(もちろん、ただ時間をかければ良いわけではないので、効率化できる部分は工夫も必要ですが) 採用は人を巻き込む業務が多いですが、エス・エム・エスのメンバーはコミュニケーションが非常に円滑で、建設的な議論ができる方ばかりです。だからこそ、候補者に合わせた最適な選考フローが提供できているのだと思います。 これからやっていきたいこと 入社して5か月になりますが、今のところとても楽しく働いています。 私は、仕事を長く続けるには「その仕事が面白いか」が最も大事だと思っています。「面白い仕事」の条件は、「向き合っている課題が挑戦的であること」そして「一緒に働く仲間が優秀で良いメンバーであること」です。 重要なので繰り返しますが、エス・エム・エスの取り組んでいる課題は壮大で、一筋縄ではいきません。そのため、初めて会う候補者の方に一言で説明するのは難しいです。しかし、だからこそあらゆる切り口での魅力があり、候補者の入り口となる人事は、事業・プロダクト・組織・人に深く入り込み、広く知る必要があります。 まだ理解が浅い領域もありますが、その分、飽きずにやれることがたくさんあると感じています。そして、一緒に取り組む心強い仲間もいます。 つまり、腰を据えて長期であらゆることに取り組めそうだと思っています! まずは採用を軸にしつつ、人事として組織・人の観点で「今後どうあるべきか」を考え、日頃から問いを立ててアクションしていきたいです。 そして、エス・エム・エスではあらゆるポジションのエンジニア、デザイナー、PdMを募集しています。ぜひ私や現場のメンバーのカジュアル面談でお話しましょう。お待ちしています!
この記事は「株式会社エス・エム・エス Advent Calendar 2025」の12/17の記事です。 qiita.com はじめに 介護/障害福祉事業者向け経営支援サービス「カイポケ」でQAを担当している中村です。気づけば入社して4年が経ちました。現在は複数のQAチームに横断的に関わりつつ、チームのサポートや改善活動の推進、組織マネジメントなど幅広い業務を担当しています。 エス・エム・エスでは全社員が生成AIを業務に活用できる環境が整っており、私たちQAエンジニアもテスト活動や業務効率化に活用を進めています。しかし、現状は個人レベルでの活用がメインとなっており、組織的な仕組み化やナレッジの横展開という面では、まだまだ生成AIを活かしきれていないというのが実情です。 こうした課題に対し、今回の記事では生成AIを品質活動に取り入れようとしている具体的なチャレンジ事例について2つ紹介します。まだ充分な成果が出ているフェーズではなく、あくまで試行錯誤している内容として、率直に記載していますのでご了承ください。 事例1. 不具合分析を生成AIで効率化 導入の背景 カイポケでは、不具合データに複数の分類を持たせて、定量的に分析する仕組みを取り入れています。詳細は過去に私が執筆した記事をご参照ください。 tech.bm-sms.co.jp 不具合分析は主に以下のプロセスで進めていますが、生成AIを取り入れたのは「3.JIRAのデータを元に分析する」フェーズです。 不具合をJIRAチケットに起票 JIRAのデータをスプレッドシートで集計・可視化 JIRAのデータを元に分析する ※AI活用ポイント この「分析する」のフェーズは、分析経験・プロダクト理解・そして熟練者の勘所も必要であり、属人化しやすく時間が掛かってしまうという課題を抱えていました。そこで、構造化された不具合データを生成AIと連携させ、分析の作業効率化とプロセスの標準化を目指すことで、この課題を打破できると考えました。 どう実現しているか? 使用する生成AIはGeminiです。まず、JIRAに蓄積されている分析対象の「不具合データ」を用意し、インプットとしてAIに渡します。次に分析の目的や期待するアウトプットの形式といった具体的な分析指示をプロンプトで入力し、不具合分析を実施していきます。不具合データやプロンプトの詳細は後述します。 不具合データ 不具合データは、普段から集計・活用しているJIRAチケットの情報がベースです。このデータは、不具合の発生状況だけでなく、品質改善に向けた深掘り分析を可能にするため、複数の「分類軸」を持たせてています。 不具合データが持っている主要な情報は以下の通りです。 項目名 説明 基本情報 要約、再現手順、期待値など、不具合の概要情報 テストフェーズ 不具合を検出したテストフェーズ (例:DEVテスト、STGテスト など) 不具合種別 不具合の種別 (例:新規、既存 など) 検出種別 検出した不具合の内容 (例:機能不備、レイアウト不備 など) 検出分類 不具合を検出した経路 (例:QAテストケース、QAテストケース外など) 原因分類 不具合が混入した原因 (例:仕様理解不足、コード実装不備 など) プロンプト 分析の品質を均一化、誰でも悩まずに効率的にアウトプットが得られるよう、「標準プロンプト」を設計しました。この標準プロンプトは生成AIを特定の専門家として機能させるための要素を含んでいます。 標準プロンプトを構成する主な要素は以下の通りです。 構成要素 目的と具体的な指示 役割 ペルソナを設定し、出力のトーンと視点を設定する 背景 分析やテストの目的など、データでは分からない文脈を設定する ルール 具体的な分析作業を指示、分析軸の指定やアウトプットの構成要素を設定する ※プロンプト例 役割 ・経験豊富なQAチームリーダーの視点で分析してください 背景 ・分析目的:プロジェクトの品質傾向を把握したい ・プロジェクト名:XXX機能の追加 ・テスト目的:追加したXXX機能が正しく動作すること、関連する既存機能に影響がないことを確認する) ルール ・「検出種別 × 原因分類」の軸で分析をしてください ・不具合から品質傾向を客観的な視点でレポートしてください ・全体を通して「である調」で記述してください ・結論から先に述べる構成にしてください 今後に向けて 生成AIが最初に出してくるアウトプットはあくまで「下書きレベル」であるため、人間によるレビューやAIとの対話が多く必要になっています。今後は、チーム全体での積極的な活用とフィードバックを通じて分析精度の向上を図り、レビューのコストを削減できればと考えています。また、データ集計から言語化までのプロセスをより効率化するため、スプレッドシートのAI関数なども活用し、シームレスな連携を実現できるよう改善を進めていくことも検討していきます。 事例2. 不具合情報を持ったチャットボットの活用 導入の背景 テスト設計において、過去の不具合情報やドメイン知識は重要な参考情報ですが、情報が膨大ゆえに探索コストが高く情報が漏れてしまうというリスクがありました。生成AIはこれらの課題解決に加え、テスト観点の提案やレビュー効果も期待できるため、対話式のチャットボット作成を目指すことにしました。 どう実現しているか? GeminiのGem機能 を使い、「カスタム指示」と「知識」に必要な情報を設定することで専用のチャットボットを作成しました。プロンプトは入力に迷わないようにいくつかサンプルを作成して公開しています。運用イメージは下記図をご参照ください。 カスタム指示 ドメイン知識を持ったQA専門のアシスタントとして機能するように設定しています。カスタム指示には、AIが回答の際に参照すべき「役割」「ドメイン」「ルール」を詳細に定義しています。 カスタム指示に設定した内容は以下の通りです。 構成要素 目的と具体的な指示 役割 ペルソナを設定し、出力のトーンと視点を設定する (例:あなたは過去不具合とドメイン知識に精通したQAアシスタントです) ドメイン サービスの業界、業務領域、技術的・制度的な制約といった、背景知識を設定する ルール 行動指針(情報検索方法、事実に基づいた回答の徹底)と、アウトプットの構成要素を設定する 知識 知識には事例1で紹介した不具合データを設定します。 チャットボットとの対話例 実際にチャットボットとやりとしている内容の例を紹介します。最終的な判断は人が行う必要がありますが、叩きとしては充分な内容で高速で出力されることもあり非常に効率的です。 目的 プロンプト例 回答概要 1. リスク分析と観点抽出 ログイン機能に変更が入るので、過去の不具合から見て注意すべき観点を教えて 過去の不具合事例に基づき、 認証・セッション安定性 、 セキュリティ(権限昇格) 、 連携機能への影響 など、最もリスクの高い重点観点を提示 2. テストケースの提案 勤怠管理の改修が入るので、具体的なテストケースを提案して 過去事例を反映し、 境界値テスト や 機能連携テスト など、具体的な操作手順を含むテストケースの例を提案 3. 不具合発生時の対応支援 特定のデータで画面が真っ白になったけど、過去に似た事象はある? 類似する 過去の不具合事例 や 想定される原因 を特定し、調査の方向性を提示 4. ドメイン知識の問合せ 請求情報と勤怠情報の連携で、過去にどんな問題が起きた? 特定の機能連携に関して、過去に発生した データ不整合のリスク や、それに対する 現在のシステム対応状況 を説明 今後に向けて 実運用はまだQAチームに閉じていますが、今後は広く展開し不具合データだけでなく、膨大なドメイン情報や社内の知見も取り込み、QAや品質に関するあらゆる「困りごと」の相談相手となるAIアシスタントに育てていきたいと考えています。 さいごに 本記事では、カイポケQAチームの生成AIを使った具体的な取り組み事例を紹介させていただきました。技術の進化を「絵に描いた餅」で終わらせず、品質活動に積極的に取り入れるモチベーションを持って日々業務に取り組んでいます。その他、GitHub CopilotやClaude Codeを使って、プロダクトコードやPRの情報からテスト観点を効率的に抽出する活動もトライしています。 私たちQAエンジニアは単にバグを見つけるだけでなく、プロセスのデザインやチームの知識を構造化したり、最新のテクノロジーを活用してプロダクト全体の品質を高める役割を担っていると考えています。そういった新しい技術を品質活動に取り入れることにワクワクし、試行錯誤できるモチベーションがある方を積極募集中ですし、一緒に仕事をしたいと思っています。 興味がある方は、ぜひカジュアル面談でお話ししましょう!!
この記事は株式会社エス・エム・エスAdvent Calendar 2025の12月11日の記事です。 qiita.com こんにちは、介護/障害福祉事業者向け経営支援サービス「カイポケ」のリニューアルプロジェクトでSREを担当 していた 加我 ( @TAKA_0411 ) です。 私事ではありますが、9月にSREチームからプロダクト開発チームへ異動しました。現在はEmbedded SREではなく、開発者としてKotlinを用いたバックエンド開発を主に担当しています。 これまでの私のキャリアはQA → インフラ → SREという流れで、アプリケーション開発の経験はほとんどありませんでした。そのため、自分のスキルを広げたいという思いから挑戦させてもらっています。 当初はIntelliJのセットアップやDDDの理解などに苦戦しましたが、チームメンバーの多大なサポートもあり、ようやく少しずつ慣れてきたと感じています。 前のチームでの私は「どのようにオブザーバビリティを実現・高めていくか」ということに注力していたのですが、実際に開発チームで動いているうちにオブザーバビリティに関する考え方や取り組みに関して新しい視点が芽生えてきたと感じているので紹介します。 きっかけはいつもカンファレンス まず、私にとってひとつの転機となったイベントを紹介します。2025年10月27日に開催されたObservability Conference Tokyo 2025です。 o11ycon.jp このカンファレンスはオブザーバビリティという技術領域にフォーカスしたイベントで、ロール・文化・運用・OpenTelemetryなど幅広いテーマが扱われていました。弊社もロゴスポンサーとして協賛しています。 中でも特に印象に残ったのは、LINEヤフー株式会社のToshiya Katoさんによる「オブザーバビリティが育む開発者のシステム理解と好奇心」というセッションです。アーカイブ動画も公開されているので、ぜひご覧ください。 o11ycon.jp youtu.be このセッションは「オブザーバビリティツール、本当に使われていますか?」という問いかけから始まります。 サービスのテレメトリーデータを一通り揃えている しかし、テレメトリーデータが実際に活用されるシチュエーションはリリース時や問題発生時であった 問題発生時にはオブザーバビリティツールを用いたものではなくベテランによる解決というケースが起こっていた テレメトリーデータやオブザーバビリティツールが日常的に利用されているとは言えない状況 つまり、システムを理解するためのオブザーバビリティではなく、オブザーバビリティツールを導入してモニタリングしていただけでは?という状況であると整理されています。 このようなプロダクトやチームの状況をふまえ、メンタルモデルという切り口から下記のように課題を整理していました。 私たちはドキュメントやコード、ダッシュボードなどを通じてシステムの姿を思い描いている(≒メンタルモデル) メンタルモデルとシステムがズレると仕様の誤解や障害が発生する 担当しているサービスでは障害が少なかった反面、メンタルモデルのズレの修正を行う機会を得ることができなかった 開発者とSREとではメンタルモデルが異なっており、開発者はコードやドキュメントから、SREはダッシュボードなどのテレメトリーデータから構築している 上記のメンタルモデルの違いはDevOpsのサイクルと一致しているようである オブザーバビリティツールはDevOpsの "Ops" のサイクルで拡充されがちで、開発者にとっては使い慣れないツールになってしまう "Dev" のサイクルでオブザーバビリティツールを使うことでシステムの理解と好奇心を育てることができるのではないか DevOpsサイクル ( https://www.pagerduty.co.jp/blog/devsecops-cultural-transformation ) 上記の課題を解決するため、"Dev" のサイクルで本番同等の観測ができる環境と負荷が必要と考え、GitHubのPRごとのPreview環境、そしてカジュアルに実施できる負荷試験のシステムを整備した取り組みを紹介していました。 ここまでの発表内容から自分の取り組みを振り返ってみると、SREとしての私が注力してきたのは "Ops" のサイクルでのテレメトリーデータ拡充にすぎず、それこそ "オブザーバビリティツールでモニタリングをしているだけ" という状況に陥っているということに気付きました。これからの自分に必要なのは "Ops" のサイクルで得られた学びやフィードバックを適切に "Dev" のサイクルに取り込み、オブザーバビリティツールを活用してシステム理解を深め、問題をより迅速に解決できる環境を整えることだと強く認識しました。 このセッションが自分にとって大きな転換点となったこと、そして貴重な発表をしていただいたことを改めてToshiya Katoさんに感謝したいと思います。 オンコール対応から見えてきた課題 カンファレンスを経て意識が変化した直後の11月末、珍しくオンコール対応が必要なアラートを検知しました。私も開発者としてトラブルシューティングに参加しました。 DatadogのAPMを見つつエラーの箇所を追っていくと、DatadogのGitHub Integrationが役立ち、問題箇所と原因を早い段階で把握できました。しかし、実際にどのようなリクエストが送られているのか、なぜそのようなリクエストが送られてしまったのかといった調査にとても手間取ってしまいました。 また、Slackに通知されたアラートメッセージが抽象的だったこともあり、そのアラートを見て我々がどのようなアクションが必要なのかという点で初動の遅れに繋がってしまいました。 12月3日の記事 にあるとおり、私たちが開発しているカイポケのシステムは分散システムとなっています。WebフロントエンドからAPIのGatewayを経由するデータや、コンポーネント間の通信データもあります。そのため、オブザーバビリティの考え方としては問題を引き起こしたデータがどこから来たのか、その中身が何であったのかを収集しておいてすぐに確認できる状態であるべきでした。 システム概要図 また、私を含め開発者がトラブルシューティングのためのDatadogの利用に不慣れであったり、オンコール対応のためのRunbookがまだ整備されていないという状況でした。最終的には開発経験が長く詳しい人にデータを調査をお願いし、事なきを得てひとまず落ち着きました。これはつまり下記の状況です。 問題発生時にはオブザーバビリティツールを用いたものではなくベテランによる解決 システムを理解するためのオブザーバビリティではなくツールを導入してモニタリングしていただけ 開発者にとっては使い慣れないオブザーバビリティツール このような状況を踏まえ、同じチームの同僚と簡易的なポストモーテムを実施し、現状の課題を整理しつつ迅速なオンコール対応を可能にするための改善を進めています。プロダクト開発チームに所属することで私に当事者意識が芽生えたのでしょうか、チーム全体での "開発者が自分たちの手で観測・理解できる環境づくり" への意欲が高まっています。"Dev" のサイクルでオブザーバビリティツールを使うこと、それに慣れること、そしてシステムの理解を深めることの重要さを痛感しました。 まとめ 今回のチーム異動とObservability Conference Tokyo 2025への参加を通じて、オブザーバビリティへの理解が大きく変化しました。 今後はより開発サイクルに密着した実践的なオブザーバビリティ改善を進めていきたいと思います。 社内で「オブザーバビリティ・エンジニアリング」の輪読会を開くなど、私の所属チーム以外でもオブザーバビリティへの関心が広がりつつあります。 今回の改善でどのような成果が見られたのかについては、結果が出次第またブログや登壇で共有する予定です。今後の報告もぜひご期待ください。
この記事は 株式会社エス・エム・エス Advent Calendar 2025 の12月9日の記事です。 はじめに ちょうど1年ぶりのテックブログへの登場となりました。BPR推進部EA推進グループでエンジニアをしている、おうえ @kotaoue です。 この記事は「エス・エム・エスに入社してから、楽しく仕事をするためにおうえがやってきたこと」を振り返ってみようという、個人的な想いドリブンで書いています。 ※ 同時に「BPR推進部ってどんなチーム?」や「エス・エム・エスのBPR推進部でエンジニアとして働く楽しさ」みたいなものを、もしかして将来一緒にチームとして仕事をすることになる誰かに伝わると本当に最高だなという期待も結構込めています! 具体的なTechの話というよりは、開発フローやカルチャーに関するポエムです。 簡単な自己紹介 まずは、おうえの略歴を簡単に書いておきます。 これから「エス・エム・エスのBPR推進部でエンジニアとして働く楽しさ」に触れますが、それは「ただしこんな感じで仕事をしてきた人にとって」という前提が付く話にはなるので略歴を書いておきます。 20年以上前に就職してから、ゲームプランナー → 起業試みて失敗 → Slerでプログラマ → 事業会社の社内SE → ゲーム会社のサーバーエンジニア → SaaSスタートアップのエンジニア といった感じで仕事をしてきています。 ちょっと変則的なキャリアプランで参考にならないよと思われるかもですが… 「Slerのプログラマ」「個人事業主」「スタートアップのメンバー」のような何個かの視点から語っていると感じていただけると幸いです。 BPRって何? EA推進グループって何? エス・エム・エスには「プロダクト開発部」とは別に「BPR推進部」という組織も存在します。 そこで、 昨年の記事 と同様に、所属している部署の紹介を記載しておきます。 まず、BPR推進部ですが、BPR(Business Process Re-engineering)の略称です。 とても簡単に言うと「部署を横断して会社全体の業務プロセスを改善していくこと」が目標のチームとなっています。 ちなみに、EA推進グループは、EA(Enterprise Architecture)の略称で、ここにも「ビジネス戦略とITを統合してシナジーを最大化していこう」といった想いが入ったチーム名となっています。 「プロダクト開発部」と「BPR推進部」では、お互いに「マーケット(市場・業界)へ向けて」価値を届けるという方向性は同じですが、そこへ至るアプローチとして、主に以下のような役割分担をしています。 プロダクト開発部⇒マーケットに向けて直接価値提供するサービスの開発・提供 BPR推進部⇒マーケットへのサービスデリバリーまでを含めた社内の業務プロセス改善/業務システム構築 もちろん、この役割分担も固定的なものではなく、お互いにやるべきと思ったことをオーバーラップしたり協業したりしながら組織横断的に成果に向かって動いています。 ※ このTechBlogも、プロダクト開発部とBPR推進部の両方のメンバーがエントリーを書いて運営しています。 テーマとしていた働き方の発表 規模としては多くの従業員数が所属するいわゆるエンタープライズ企業ということで、エンタープライズ企業ならではの働き方が必要だと入社前から少し身構えていました。 例えば、組織として守るべきルールや、登場人物が多いことによる調整の難しさや独特のスピード感については、前職のスタートアップとは大きく異なると想像していました。 そんな組織の中で、自分として楽しく仕事をする&組織に価値を還元できるように、「とりあえずやってみる」を自分のテーマにしてきました。 ※ 裏テーマは「誰かに怒られるまではやってみる」でした。 それは、これまで主に「Slerのプログラマ」「個人事業主」「スタートアップのメンバー」として働いてきた人間が「エンタープライズ企業」でプレゼンスを示すためには、ちょっと違った視点ややり方が大事だと思って作成したテーマです。 その一例として「自分の好きな仕事」について部全体に共有会を実施することになった件を紹介します。 「自分の好きな仕事」について部全体に共有会を開催することになった件 おうえはポストモーテムが大好きです!色々ある仕事の中で一番好きだと言っても過言では無いです。 そして「楽しく仕事をしたい」し「とりあえずやってみる」「誰かに怒られるまではやってみる」がテーマの一年だったので、「よし、ポストモーテムの魅力を伝える共有会をみんなに向けて開催しよう」と動いてみた結果の振り返りです。 開催までの流れ 共有会を開催したいなと思う 「ポストモーテムが大好きなので、ポストモーテムの魅力を伝える会を開催したいです!参加者募集です」とSlackのBPR全体チャンネルに投稿 実際のメッセージのスクリーンショットは↓ 部長から「何より楽しいっていうところが良いですね!」というコメントを貰って喜ぶ 開催 という感じでした。 入社前に身構えていたエンタープライズ企業的な難しさもなく、「やりたい」→「いいね」→「やる」という軽いフットワークで開催することができました。 また、個人の思いつきが起点となった共有会ですが「一緒に内容ブラッシュアップしよう」とマネージャーも前のめりで協力してくれるなど、とても動きやすい環境でした。 この時点で「BPRという組織は、入社前に想像していたよりも数倍〜数十倍の裁量範囲がある」ということを感じ、それは「誰かに怒られるまではやってみる」という限界を攻めるのも難しいなという、大きな驚きになっていました。 開催した結果 結果として、共有会の冒頭に表示されるスライドで「好きだから」を全面に押し出すような、個人的な想いが満載の共有会を開催することになりました。 反応も上々で 共有会を聞いて、3秒後にesaでポストモーテムを仕組み化、チームのドキュメントとしてシェアしました! さっそくチームでポストモーテムやってみました!再発防止策はみんなで考えようぜ!という意識で議論できたのは良かったと思います! 経営管理本部とか他部署のメンバーにも共有したいなぁと思うんですけど、エス・エム・エス全体に広げちゃってもいいですか? といった感じで、BPRの中で反応するだけではなくて他部署にも波及するという、当初抱いていたエンタープライズ企業という想像を打ち砕くような軽やかな結果となりました。 ポストモーテムが好きな理由の補足 今回の記事は「楽しく仕事をするためにテーマとしていたことの振り返り」なので、ポストモーテムについては深堀りしないようにしようと思いましたが、やはり好きなのでちょっとだけ語らせてください。 ポストモーテムが好きな理由は「 ポストモーテムを楽しめるメンバーの集まったチームが好きだから 」です。 そしてその理由を細分化すると ポストモーテムが好きってことは、失敗しても批判されないし、失敗からポジティブな学びを得るチーム 失敗からポジティブな学びを得るってことは、新しいことにチャレンジできるチーム 新しいことにチャレンジできるってことは、もっと良いチームになる可能性が高いチーム もっと良いチームになる可能性が高いチームってのは、参加していて楽しいチーム! という感じです。 そして、共有会を開催するまでの流れで「 自分が参加しているチームはもっと良いチームになる可能性が高いと感じることができた 」というのが最高のフィードバックでした。 まとめ 入社前にはエンタープライズ企業だからと身構えていましたが…実際には「やってみたいな」と自分からアクションを起こせば、やってみたい仕事にチャレンジできる機会がある、拍子抜けするくらい軽いフットワークで色々なことができる組織でした。 「はじめてのポストモーテム」だけではなく「LT大会やってみませんか」「輪読会やってみませんか」「プロダクト開発で実施しているボードゲーム会に参加して良いですか?」といったチームカルチャーにまつわる相談にはもちろん「やってみよう」という反応で進行することになりました。 また「ダッシュボード作りましょう」や「AIエージェント使ってみたいです」や「次はJavaじゃなくてGoでPoCやりたいです」といった技術的な希望や「ITGCの統制対象となっているシステムの開発フローだがやりづらい部分があるので変更したい」といった開発フローやIT全般統制に関わるようなややこしい要望であっても、一度も「NG」と言われることがない組織でした。 他にも「ちょっと1on1したいです」とSlackで声をかければ、技術責任者の田辺さん( @sunaot )とも1on1実施できるという、スタートアップのようなとても距離の近いコミュニケーションも可能な組織でした。 もちろん「とりあえずやってみよう」ではなくて「それをやるためには情報を整理して然るべきルートで承認申請してから」といった進め方になることはあります。 それでも「じゃあどうすれば実現できるか」という視点で動けるのが、BPR(Business Process Re-engineering)という言葉が入った組織の強みであり、エス・エム・エスという会社の社風なんだなと感じたのが、一年を振り返った率直な感想です。 さいごに アドベントカレンダーの中ではありますが…BPR推進部では一緒にエス・エム・エスのBPRに取り組んでくれるメンバーを募集中です。 BPR推進・コーポレート エンジニア職種一覧 としてまとめております。 もちろん「とりあえず、1回話をしてみたいなー」というカジュアル面談も大歓迎なので、↓にあるカジュアル面談のリンクをクリックしてみてください。 また、BPRについてもう少し知りたい方向けへの記事もリンクしておきます。 規模はエンタープライズですが、スタートアップ的な速度感で動くことのできる組織なので、「チャレンジしがいのある大きなissue」がたくさんありますし、ぜひ一緒にチャレンジしたいと思っていますという想いを伝えて筆を置きます。 もうすこしBPRについて知りたい方向けへの記事 組織のやっていることを知りたい方へ 多様なビジネスモデルを展開している成長企業のBPR組織のミッション BPRらしさの詰まったビジネスアーキテクトという職種について知りたい方へ ビジネスアーキテクト × Salesforce:改善だけで終わらない、戦略推進と戦術実行を追求する その他、BPRメンバーの書いた記事は こちら