TECH PLAY

Findy/ファインディ

Findy/ファインディ の技術ブログ

182

こんにちは。Findy Tech Blog編集長の高橋( @Taka-bow )です。 「要件がまた変わった」「会議ばかりで開発時間がない」「あの人に聞かないと進められない」──こんな悩みを抱えていませんか? 前回の記事 では、アジャイル実践者の59.6%が開発生産性に前向きだという意外な事実をご紹介しました。しかし、前向きでも実際の取り組み率は47.8%に留まっています。 今回は、798名の調査から明らかになった 開発生産性を阻害する要因 と、その改善への道筋を探ります。特に、技術的な問題よりも深刻かもしれない「組織の3大課題」がどのように連鎖し、どこから手をつければ効果的なのかを考察します。 【調査概要】 調査対象: ソフトウェア開発(組み込み開発を含む)に直接関わるエンジニア、プロダクトマネージャー、プロジェクトマネージャー、エンジニアリングマネージャー、開発責任者など 調査方法: インターネット調査 調査期間: 2025年4月2日(水)~2025年5月21日(水) 調査主体: ファインディ株式会社 実査委託先: GMOリサーチ&AI株式会社 有効回答数: 798名(95%信頼区間±3.5%) 統計的検定力: 80%以上(中程度の効果量d=0.5を検出) 調査内容: 開発生産性に対する認識 開発生産性に関する指標の活用状況 開発生産性に関する取り組み 開発環境・プロセス評価 組織文化と生産性 調査結果から、開発生産性を阻害する要因には明確な優先順位が存在することが判明しました。ここで注目したいのは、上位3つの課題がいずれも技術的な問題ではなく、組織運営やプロセスに関する点だということです。 上位3つは技術的な要因ではなかった 課題1 - 「不明確な要件」(53.5%) 半数以上が直面する根本的問題 要件が不明確になる3つの側面 ▼ 第一の側面 - 文書化・情報伝達の問題 ▼ 第二の側面 - ソフトウェア開発の本質的な不確実性 ▼ 第三の側面 - 優先順位と価値の曖昧さ 要件定義を阻害する組織的構造問題 「不明確な要件」への改善アプローチ ▼ 第1段階 - 文書化・情報伝達の改善 ▼ 第2段階 - 不確実性への適応力向上 ▼ 第3段階 - 組織文化の変革 課題2 - 「会議が多い」(38.7%) 開発時間を奪う会議の実態 会議が減らない本質的な理由 「会議が多い」への改善アプローチ ▼ 第1段階 - 会議の目的別再設計 ▼ 第2段階 - 組織構造の見直し ▼ 第3段階 - 会議依存からの脱却 課題3 - 「コミュニケーションの問題」(33.6%) 曖昧な「コミュニケーションの問題」が示すもの Flow Stateから見える「見えない中断」 「見えない中断」の正体 「コミュニケーションの問題」への改善アプローチ ▼ 「見えない中断」を減らすための具体策 まとめ - 共通認識から始まる改善 問題の連鎖構造 改善への第一歩 次回予告 上位3つは技術的な要因ではなかった 開発生産性を阻害する要因について尋ねたところ、次の結果が明らかになりました。 開発生産性の主要な阻害要因(複数回答) 順位 阻害要因 回答率 回答者数 分類 1位 不明確な要件 53.5% 427人 組織プロセス 2位 会議が多い 38.7% 309人 組織プロセス 3位 コミュニケーションの問題 33.6% 268人 組織プロセス 4位 技術的負債 30.5% 243人 技術的要因 5位 開発環境の制約 19.2% 153人 技術的要因 6位 その他(具体的に) 2.8% 22人 - (N=798、複数回答可) また、上位3つの阻害要因はいずれも組織プロセスに関連しており、技術的負債(30.5%)を上回っています。 この結果は、技術的な改善だけでは開発生産性の問題を解決できないことを示唆しています。むしろ、組織の仕組みやプロセスの見直しこそが、生産性向上の鍵となるのです。 それでは、これらの3大課題について、順に詳しく見ていきましょう。 課題1 - 「不明確な要件」(53.5%) 半数以上が直面する根本的問題 回答者の53.5%が指摘するこの課題は、上流工程における要件定義の品質に関わる根本的な問題です。 不明確な要件は、手戻りや追加開発を引き起こし、プロジェクトの効率性と開発チームの生産性を著しく低下させる要因となっています。 要件が不明確になる3つの側面 この問題には大きく3つの側面があると考えられます。 ▼ 第一の側面 - 文書化・情報伝達の問題 要件自体は顧客や関係者の頭の中では具体的になっているものの、それを適切に言語化・文書化できていない可能性があります。 この問題の本質を理解するため、要求仕様化の専門家の知見を参考にしてみましょう。 私の恩師である清水吉男氏は、要求の仕様化手法「USDM(Universal Specification Describing Manner)」を開発し、著書『[改訂第2版] [入門+実践]要求を仕様化する技術・表現する技術 -仕様が書けていますか?』でその手法を体系化したコンサルタントでした。 [改訂第2版] [入門+実践]要求を仕様化する技術・表現する技術 -仕様が書けていますか? 作者: 清水 吉男 技術評論社 Amazon 長年の実践を通じて日本のソフトウェア開発現場を見てきた清水氏は生前、「なぜ仕様が書かれないのか」について、次の3つの問題を指摘していました。 問題点 詳細 "要求"が表現されていない そもそも実現したいことが明確に表現されていないため、その要求を満たすための仕様を拾いきれない 要求と要求仕様の関係性の理解不足 要求と要求仕様の関係や違いを認識していないため、両者が混同される "機能仕様書"への偏り 機能面ばかりに注目することで、品質要求などの非機能要件が漏れてしまう これらの問題に加え、日本語の曖昧性も状況を複雑にしています。清水氏は「要求」「要件」「仕様」といった用語の混同についても警鐘を鳴らしていました。これらは英語と照らし合わせることで、それぞれの意味がより明確になります。 用語 英語 意味 要求 Requirement 実現したい(Require)ことが書かれたもの 仕様 Specification 特定(Specify)できた状態で表現されているもの そして、清水氏が特に強調していたのは、 要求には必ず「理由(Why)」が存在する という点です。 すべての要求には、それが存在する背景や理由があります。この「理由(Why)」を明確にすることが、適切な仕様を導き出すための重要な鍵となります。 要求の背後にある理由を探ることで、顧客が本当に実現したいことを正しい位置に誘導でき、仕様を外さない開発が可能になります。 理由が曖昧なままでは、要求の範囲を正しく認識できず、開発の方向性を見誤る可能性があります。 また、理由を理解することで、要求の変化の方向を予測し、将来の変更に備えた柔軟な設計が可能になります。 この「理由(Why)」への配慮が、最終的には保守性、パフォーマンス、機能拡張性、操作性、メモリー使用効率など、システム全体の品質に大きな差をもたらすのです。 このような概念の混同や、要求の背景にある「理由(Why)」への配慮不足が、文書化の質を低下させ、結果として「不明確な要件」という問題を生み出している可能性があります。 ▼ 第二の側面 - ソフトウェア開発の本質的な不確実性 より根本的な問題として、そもそもプロジェクト初期段階ですべての要件を確定できるという前提自体が非現実的である可能性があります。 書籍『アジャイルサムライ』では、この現実を端的に示しています。 ソフトウェア開発の3つの真実 1. プロジェクトの開始時点にすべての要求を集めることはできない 2. 集めたところで、要求はどれも必ずといっていいほど変わる 3. やるべきことはいつだって、与えられた時間と資金よりも多い 出典:Rasmusson, J. (2011).『アジャイルサムライ──達人開発者への道』(西村直人・角谷信太郎・近藤修平・角掛拓未 訳). オーム社. (原著出版年:2010) アジャイルサムライ−達人開発者への道− 作者: Jonathan Rasmusson オーム社 Amazon これらの「3つの真実」は、多くの開発現場で日々体感されている現実ではないでしょうか。 要件の変更に振り回され、限られたリソースで山のようなタスクに向き合う。そんな経験は、きっと多くの読者の皆様にも共感いただけるはずです。 重要なのは、 この不確実性を前提として受け入れ 、それに対応できる柔軟な体制を構築することなのだと思います。 ▼ 第三の側面 - 優先順位と価値の曖昧さ 多くの開発現場では「やりたいことはたくさんある」状態です。 しかし、 どれから着手すべきか、なぜそれが重要なのか が曖昧なまま、要件リストだけが膨張していきます。 さらに深刻なのは、関係者同士が「合意が取れている」と思い込んでいる状況です。 会議では皆頷いていても、実際には各人が異なる成果物をイメージしており、後になって「思っていたものと違う」という事態が発生します。 出典:Jeff Patton "Glad we all agree" - https://jpattonassociates.com/glad-we-all-agree-2/ そして最も本質的な問題は、 顧客にとっての価値(アウトカム)が不明確 であることです。 「何を作るか」ばかりに注目し、「なぜ作るのか」「それによって顧客がどう変わるのか」という視点が欠如していると、要件自体が迷走してしまいます。 これらの問題に対する有効な解決策の1つが「ユーザーストーリーマッピング」です。 ユーザーストーリーマッピング 作者: ジェフ・パットン , 川口恭伸 , 長尾高弘 オライリージャパン Amazon ユーザーの行動を時系列で可視化することで、全体像と優先順位が明確になり、関係者全員が同じ地図を見ながら議論できます。 また、ユーザーの体験に焦点を当てることで、自然とアウトカムを意識した要件定義が可能になるのです。 要件定義を阻害する組織的構造問題 これらの3つの側面(文書化の問題、不確実性への対応、優先順位と価値の曖昧さ)がなぜ改善されないのでしょうか。 そこには、次のような組織的な構造問題が潜んでいると考えられます。 阻害要因のカテゴリー 具体的な問題 影響 文書化・情報伝達の阻害 決定権限や責任の所在が不明確 誰が最終決定権を持つのか曖昧なため、要求の「理由」を確認する相手が特定できない ステークホルダー間での認識の不一致 要求の背景や優先度について、関係者間で共通理解が形成されていない 不確実性への対応の阻害 完璧主義的な組織文化 「最初から完全な要件定義ができるはず」という非現実的な期待が根強い 変更を失敗と捉える風土 要件変更を「計画の失敗」と見なし、柔軟な対応を躊躇する 実際、調査では開発フレームワークについて「よくわからない」が18.2%、「ウォーターフォール」が36.8%と、合わせて過半数(55.0%)が変化への柔軟な対応を前提としていない、または開発手法自体を明確に理解していない状況でした。 この結果から、 不確実性への対処方法が組織的に確立されていない 可能性が高いことが見て取れます。ただし、ウォーターフォール型開発であっても、適切なリスクマネジメントが実施されていれば、ある程度は対処可能だと考えられます。 「不明確な要件」への改善アプローチ これまで見てきた問題構造を踏まえ、要件定義の改善には段階的なアプローチが有効と考えられます。 ▼ 第1段階 - 文書化・情報伝達の改善 清水吉男氏が指摘した「要求の理由」を明確にすることから始めましょう。 清水氏が開発したUSDM(Universal Specification Describing Manner)は、まさにこの問題を解決するための手法です。USDMの特徴は、要求と仕様を階層的に整理し、それぞれに「理由」を明記する点にあります。 USDMの基本構造 要求 :「〜したい」という形で記述し、必ず「理由」を併記 仕様 :要求を実現するための具体的な振る舞いを「〜する/〜である」と記述 階層化 :要求を段階的に詳細化し、抜け漏れを防ぐ 例えば「ログイン機能が欲しい」という要求に対して、 理由 :セキュリティを確保し、ユーザーごとにカスタマイズされた体験を提供するため 仕様 :3回ログインに失敗したらアカウントをロックする、パスワードは8文字以上とする、など このように構造化することで、「なぜ」が明確になり、手戻りが激減します。 ユーザーストーリーカードという選択肢 アジャイル開発では「ユーザーストーリーカード」も有効な手法です。これは要求を次の形式で記述します。 「 〜として (Who:誰が)、 〜したい (What:何を)、 なぜなら〜だから (Why:理由)」 例 Who:「ECサイトの利用者として」 What:「過去の購入履歴を簡単に確認したい」 Why:「なぜなら、リピート購入を素早く行いたいから」 ユーザーストーリーカードの利点は次の通りです。 視点が明確 :誰のための要求かが一目瞭然 価値が明確 :「なぜなら」で理由と価値を必ず記述 対話を促進 :カードを使って関係者と議論しやすい 受け入れ条件 :裏面に具体的な仕様(受け入れ条件)を記載 USDMとユーザーストーリーカードは、どちらも「理由(Why)」を重視する点で共通しています。組織の文化や開発スタイルに合わせて選択するとよいでしょう。 実践的な改善策 要求テンプレートの導入 :USDMやユーザーストーリー形式を活用し、要求記述時に必ず「理由・背景」欄を設ける ステークホルダーマッピング :各要求の提案者と承認者を明確化し、決定権限の所在を可視化 共通言語の確立 :要求・要件・仕様の違いを組織内で統一し、認識のズレを防止 ▼ 第2段階 - 不確実性への適応力向上 アジャイルサムライの「3つの真実」を受け入れ、変化を前提とした体制を構築します。 段階的な要件確定(Progressive Elaboration) :初期はMVPレベルで要件を定義し、フィードバックを受けながら詳細化 ユーザーストーリーマッピングの導入 :ユーザーの行動を時系列で可視化し、全体像を共有しながら優先順位を決定。Jeff Patton氏が提唱したこの手法は、要求の「理由」と「文脈」を自然に表現でき、ステークホルダー間の認識を合わせる強力なツールとなります 変更管理プロセスの確立 :要件変更を「失敗」ではなく「学習」と捉え、影響分析と承認フローを明確化 プロトタイピングの活用 :動くモックアップで早期に認識を合わせ、手戻りを最小化 ▼ 第3段階 - 組織文化の変革 過半数を占める「ウォーターフォール」「よくわからない」層への働きかけが重要です。 段階的な移行戦略 :いきなり全面的なアジャイル化ではなく、小規模プロジェクトから試行 教育・研修の充実 :開発手法の理解促進と、変化への対応力向上 成功体験の共有 :柔軟な要件対応で成功したプロジェクトの事例を組織内で展開 課題2 - 「会議が多い」(38.7%) 開発時間を奪う会議の実態 回答者の38.7%が指摘するこの問題は、開発に集中する時間を大幅に削減する要因となっています。 会議は必要な情報共有の場である一方、過剰な会議は開発者のフロー状態を妨げ、集中して作業できる時間を奪っています。 さらに深刻なのは、会議の連鎖的発生です。 隙間がないカレンダーは要注意 明確な結論が出ない会議は、確認のための追加会議を必要とし、さらにその調整のための会議が発生するという悪循環に陥ります。 本来、効率化のための議論であっても、会議自体が目的化してしまうと、開発時間の確保という本来の目的から離れてしまう恐れがあります。 会議が減らない本質的な理由 会議が増殖し続ける最大の要因は、 異なる目的の会議が混在してしまうこと にあります。 会議には、次の4つの目的があると言われています。 会議の目的 会議の例 ディスカッションの種類 報告や情報共有を行い、次の活動に活かす 日常の進捗報告 情報交換型 多くの視点から、新しいアイデアを生み出す 新企画の洗い出し 洗い出し型 事実を論理的に組み立て、因果関係を整理する 現状課題の共有と整理 分析・考察型 ゴールを実現するために判断し、結論を出す 新企画の決定 意思決定型 しかし現実には、これらの異なる目的が1つの会議に混在し、「情報共有のつもりが議論になり、結論も出ないまま時間切れ」という状況が頻発します。 この問題は、課題1で見た「要件の不明確さ」と密接に関連しています。 要件の不明確さと組織構造の問題が複合的に作用し、会議を増やす負の連鎖が生まれています。 問題の種類 具体的な事象 結果 要件の不明確さ 要求の「理由」が共有されていない 同じ説明を何度も繰り返す 決定権限が不明確 意思決定型の会議なのに決定できない 目的が曖昧 「とりあえず集まって話そう」という会議が増える 組織構造 権限委譲の不足 同一部門内で多階層が参加(上司も部下も全員) 「全員参加」の誤解 議論には4-5名が理想なのに大人数を集める 責任回避の文化 「みんなで決めた」形にして個人の責任を曖昧化 実際、5人以上の会議になると「私1人ぐらい参加しなくても」という心理が働き、居眠りや内職、発言しない人が出てきます。 これは参加者個人の問題ではなく、会議設計の失敗なのです。 興味深いことに、アジャイル開発を導入した組織でも会議過多の課題は残っています。 デイリースクラム、スプリントプランニング、レトロスペクティブなど、本来は目的が明確なはずのセレモニーが、形骸化してしまうケースも見受けられます。 この問題は、物理出社でもリモートワークでも共通して発生しています。 むしろリモートワークの普及により、「とりあえずオンラインで集まる」ハードルが下がり、会議数が増加する傾向も見られます。 場所を問わず、会議の本質的な設計と運用の見直しが必要なのです。 「会議が多い」への改善アプローチ 会議の問題を解決するには、まず「会議の目的を明確に分離する」ことから始める必要があります。 ▼ 第1段階 - 会議の目的別再設計 前述の4種類の会議それぞれに適した運営ルールを設定します。 ディスカッションの種類 運営ルール 情報交換型 タイムボックス設定、資料事前配布、質疑は最小限 洗い出し型 参加者を4-5名に限定、個人思考時間を確保 分析・考察型 分析手法を事前に決め、全員が手順を理解してから開始 意思決定型 決定権者を明確化、判断基準と選択肢を事前準備 ▼ 第2段階 - 組織構造の見直し 会議過多の根本原因である組織構造にメスを入れます。 権限委譲の推進 :同一部門内の多階層参加を避け、適切なレベルに決定権を委譲 参加者の最適化 :議論は4-5名、情報共有以外は必要最小限のメンバーに限定 権限レベルの明確化 :デリゲーションポーカーなどを活用し、各メンバーがどのレベルで意思決定に関わるかを明確にする デリゲーションポーカーはManagement 3.0で開発されたプラクティスです ▼ 第3段階 - 会議依存からの脱却 すべてを会議で解決しようとする文化から脱却します。 ドキュメント文化の構築 :議事録・決定事項を確実に文書化し、共有する仕組みを確立 非同期ツールの活用 :SlackやTeamsのスレッドで議論を進め、会議は意思決定のみに 時間制限の厳格化 :すべての会議に明確な終了時間を設定し、延長を原則禁止 課題3 - 「コミュニケーションの問題」(33.6%) 曖昧な「コミュニケーションの問題」が示すもの 回答者の33.6%が「コミュニケーションの問題」を生産性低下の要因として挙げています。しかし、この「コミュニケーションの問題」が具体的に何を指しているのかは、統計的な分析を行っても特定できませんでした。 興味深いのは、「会議が多い」(38.7%)とは別項目として挙げられている点です。会議もコミュニケーションの一形態であるにもかかわらず、別の問題として認識されているということは、ここで言う「コミュニケーションの問題」は会議以外の何か別の問題を指していると考えられます。 Flow Stateから見える「見えない中断」 この問題を理解するには、DevEx(Developer Experience)の観点、特に Flow State(フロー状態) の概念が有効かもしれません。 開発者が「フローに入る」「ゾーンに入る」という状態は、完全に集中し、生産性が最大化される状態を指します。研究によれば、この状態を頻繁に経験する開発者は、より高いパフォーマンスを発揮し、質の高い製品を生み出します。 フロー状態を妨げる主要な要因は 中断や遅延 です。会議は「見える中断」として明確に認識されますが、「コミュニケーションの問題」は 「見えない中断」 を生み出している可能性があります。 「見えない中断」の正体 会議とは異なる形で開発者のフロー状態を阻害する要因として、次のようなものが考えられます。 中断の種類 具体的な問題 開発者への影響 非同期コミュニケーション Slackやメールの返答待ち 作業が停滞、待機時間が発生 チャットツールの頻繁な通知 集中が途切れ、再集中に時間がかかる 複数の会話を並行処理 思考が分散し、効率が低下 情報探索 ドキュメントがどこにあるか不明 探し回る時間で開発が中断 Wiki、チャット、メール等に情報が分散 情報収集に時間を取られる 「あの人に聞かないと分からない」 属人化により作業がブロック チーム間連携 他チームの作業完了時期が不明 依存関係で作業が止まる 決定権者が不明確 承認待ちで進捗が遅延 仕様の詳細が曖昧 何度も確認が必要になる 生成AI活用 AIの高速な生成に人間の判断が追いつかない レビュー待ちが常態化、判断疲れ 複数のAIタスクを並行して依頼 自己マルチタスク化で集中力が分散 AIの処理待ち時間に別タスクを開始 コンテキストスイッチが頻発 これらの「見えない中断」は、一つ一つは小さくても、累積すると開発者が集中できる時間を大幅に削減します。研究によれば、中断から再び集中状態に戻るまでに平均15〜30分かかるとされており、頻繁な「見えない中断」は生産性に深刻な影響を与えます。 特に生成AI活用においては、AIの処理速度と人間の判断速度のミスマッチが新たな中断を生み出しています。AIが瞬時に生成するコードや文書を適切にレビューするには時間がかかり、その間にAIに別のタスクを依頼することで、結果的に人間側が複数のコンテキストを同時に管理する「自己誘発的マルチタスク」状態に陥るのです。 「コミュニケーションの問題」への改善アプローチ もし「コミュニケーションの問題」が上記のような「見えない中断」を含んでいるとすれば、Flow Stateを守るための対策が効果的でしょう。 ▼ 「見えない中断」を減らすための具体策 改善カテゴリ 具体的な施策 非同期コミュニケーション • 返答の期待値を明確にする(今日中、明日中など) • 通知のルールを設定し、集中時間帯を確保 • 非同期で解決できることと同期が必要なことを区別 情報の構造化 • ドキュメントの一元管理と検索性の向上 • 技術的な意思決定の理由と経緯を文書化して残す • FAQやナレッジベースの整備 チーム間連携 • API仕様の文書化とバージョン管理 • 依存関係の可視化とタイムラインの共有 • ブロッキングポイントの事前特定と対策 AI活用の最適化 • AIタスクを順次処理する(並列依頼を避ける) • AIの出力をバッファリングし、まとめてレビュー • AIとの協働時間を時間枠で区切る これらの施策は、「会議を減らす」という目に見える対策とは異なり、日常的な開発作業の中で発生する「見えない中断」を減らし、開発者がフロー状態を維持できる環境を整えることを目指しています。 まとめ - 共通認識から始まる改善 調査で浮かび上がった3つの阻害要因──「不明確な要件(53.5%)」「会議が多い(38.7%)」「コミュニケーションの問題(33.6%)」は、実は互いに連鎖する1つの問題群です。 問題の連鎖構造 プロジェクト開始時に「なぜ」「何を」「どう進めるか」の共有が不足すると、次の連鎖が起きます。 要件が不明確になる理由 会議が増える理由 コミュニケーションの質が低下する理由 プロジェクトの目的や背景(理由)が共有されていない 共通認識がないため、都度確認が必要になる 前提となる情報が共有されていないため、毎回説明が必要 成功基準やトレードオフの優先順位が定まっていない 会議の目的も不明確になり、4種類の会議が混在する 判断基準が不明確なため、議論が収束しない 結果として、要求の「理由」が分からず、仕様が定まらない 決定権限が不明確なため、全員参加の非効率な会議が増える 情報が構造化されず、属人化してしまう これらすべての根本にあるのは「プロジェクト開始時の共通認識の欠如」です。 改善への第一歩 形式は問いません。インセプションデッキでも、1ページのキックオフノートでも十分です。最低限、次の4点だけはチームで明文化してから開発を始めましょう。 なぜやるのか (目的・期待する価値・成功指標) 何をつくるのか (スコープと優先順位・トレードオフ) どう進めるのか (進め方・意思決定権限・変更の扱い) 誰が決めるのか (責任と承認フロー) 共通認識の形成は一度きりの作業ではありません。しかし、スタート時点で最低限の合意がなければ、その後の適応的な変更も迷走してしまいます。技術的な改善以前に、まず「なぜ」「何を」「どう」「誰が」を明確にすることこそが、変化に強いチームづくりの第一歩なのです。 次回予告 第4回は「 AI時代の技術格差 ── Visual SourceSafe 15.8%が示す変革への壁 」をお届けします。 Visual SourceSafeがまだ現役?レガシーツールから脱却できない組織の本音に迫ります。 第1回、日本の開発現場の「リアル」を数字で見る ── 798名の声から浮かび上がる衝撃の実態 調査全体について 第2回、開発生産性への意外な好印象 ── アジャイル実践者59.6%が前向きな理由 開発手法による意識の違いの本質 第3回、開発生産性を阻む「組織の3大課題」 ── 要件定義、会議、コミュニケーションの問題 取り組みが失敗する本当の理由 第4回、AI時代の技術格差 ── Visual SourceSafe 15.8%が示す変革への壁 なぜ従来型ツールから移行できないのか 第5回、なぜDevExは日本で知られていないのか ── 認知度4.9%が語る未開拓領域 日本の開発者が本当に求めているもの ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で先日、弊社から新サービスのFindy AI+がリリースされました。 Findy AI+のα版はリモートMCPサーバーで提供しており、以前の記事でも紹介させていただきました。 tech.findy.co.jp 一般的なWebサービスでは、ユーザー側のアプリケーションの他に、管理者用のアプリケーションを用意することが多くあります。 Findy AI+でも管理者用のアプリケーションを用意しましたが、今回は管理者用のMCPサーバーとして実装することで、専用の画面を必要とせず、自然言語で管理機能を実行できるようにしました。 そこで今回は、この管理者用のMCPサーバーについて深堀って解説していきます。 それでは見ていきましょう! Findy AI+とは Local MCP Server for Administrator アーキテクチャ 認証 利用方法の統一 Elicitation まとめ Findy AI+とは Findy AI+はGitHub連携・プロンプト指示で生成AIアクティビティを可視化し、生成AIの利活用向上を支援するサービスです。人と生成AIの協働を後押しして、開発組織の変革をサポートします。 GitHub Copilot / Claude Code / Devin / Codexに対応しており、生成AIアクティビティを可視化し、生成AI利活用のボトルネック発見・利活用推進をサポートします。 また、ユーザーがプロンプトで指示して、Findy AI+のMCPサーバー経由で生成AIの利活用状況を定量・定性両面から自動取得します。 Local MCP Server for Administrator サービスやプロダクトを提供する場合、ユーザー向けの機能だけではなく、サービスの管理者側の機能も必要になることがあります。 このような場合、管理者用の画面を用意するのが一般的です。しかしFindy AI+では管理画面を作らず、Local MCP Serverを介して管理者用のAPIを実行出来るように環境構築を行いました。 昨今のWebフロントエンドの画面は、デザインからHTML/CSS、認証やデータ通信など、1画面を作るために必要な要素が多岐に渡るため、想定以上に時間とコストが掛かることがあります。 しかし、この仕組みにすることで管理者用の画面のデザインや実装をする必要がなく、最低限のAPIとMCPサーバーの実装をするだけで管理機能を用意できるようになりました。 アーキテクチャ アーキテクチャは非常にシンプルです。 まずFindy AI+の利用者がRemote MCP Serverに接続して、そこからFindy AI+や、GitHub、Devinなどといった外部APIを実行します。 Findy AI+の管理機能は画面やRemote MCP Serverではなく、運営メンバーのPCにLocal MCP Serverを用意して提供します。Local MCP ServerからFindy AI+のAPIを実行します。 この時、利用者側と管理者側のAPIはエンドポイントレベルで分けており、利用者側から管理者用のAPIを実行出来ないようになっています。 この仕組みを実現することで、管理機能を実装するコストがAPIの実装とLocal MCP Serverの実装コストだけになり、開発コストを大幅に削減しました。 認証 管理者向けのLocal MCP Serverの認証も非常にシンプルです。 運営メンバーのPCで動くため、MCPサーバーの起動時に管理者用APIの実行権限を持たせたアクセストークンを環境変数に付与します。また、APIの実行先を開発用とそれ以外で切り替えできるようにもします。 { " inputs ": [ { " type ": " promptString ", " id ": " ACCESS_TOKEN ", " description ": " MCP Access Token for Findy AI+ Admin ", " password ": true } , { " type ": " promptString ", " id ": " ENV ", " description ": " production or staging or local ", " password ": false } ] , " servers ": { " admin ": { " command ": " node ", " args ": [ " /User/hoge/dist/apps/admin/main.js " ] , " env ": { " ACCESS_TOKEN ": " ${input:ACCESS_TOKEN} ", " ENV ": " ${input:ENV} " } } } } MCPサーバーから管理者用のAPIを実行する際に、そのアクセストークンをhttp headerに付与し、API側で認証を確認します。 import * as https from 'https' ; import createFetchClient from 'openapi-fetch' ; import type { paths } from './__generated__/schema.js' ; const adminApiEnv = process .env[ 'ENV' ] || 'local' ; const baseUrl = adminApiEnv === 'production' ? 'https://production.hoge.com' : adminApiEnv === 'staging' ? 'https://stg.hoge.com' : 'https://localhost:8000' ; const apiClient = createFetchClient< paths >( { baseUrl , credentials : 'include' , } ); const httpsAgent = new https.Agent( { rejectUnauthorized : false } ); await apiClient.POST( '/api/admin/hoge' , { params : { header : { Authorization : `Bearer ${ process .env[ 'ACCESS_TOKEN' ] } ` , } , } , body : { text : 'test' } , httpsAgent , } ); このように、APIの実行先の切り替えとアクセストークンを、運営メンバーのローカル環境の環境変数に持たせることで、安全に管理運営できるように整備しました。 利用方法の統一 自然言語を利用して、MCPサーバー経由で管理機能を利用することになりますが、ここで1つ問題が出てきます。 MCPサーバーを実行する際に、運営メンバーが意図した挙動をするプロンプトを入力出来ないケースが想定されます。 この問題を解決するために、MCPサーバーのPromptsを活用することにしました。Promptsを利用することで、定型文を使って動的にプロンプトを作成することが可能になります。 modelcontextprotocol.io 例えば、新しく契約して頂いた企業情報を追加するとします。その場合、次のようなコードでプロンプトそのものを動的に作成できます。 import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' ; import { z } from 'zod' ; const mcpServer = new McpServer( { name : 'Findy AI+ Admin MCP Server' , version : '0.0.1' , } ); mcpServer. prompt ( 'add_organization' , 'Add organization to Findy AI+' , { last_name : z.string().describe( 'Last Name(Family Name)' ), first_name : z.string().describe( 'First Name' ), email : z.string().email().describe( 'Email address' ), org_name : z.string().describe( 'Organization name' ), } , async ( { last_name , first_name , email , org_name } ) => { return { messages : [ { role : 'user' , content : { type : 'text' , text : `Findy AI+に組織を追加してください。 パラメータ: - 管理者名: ${ last_name } ${ first_name } - 管理者メールアドレス: ${ email } - 組織名: ${ org_name } ` , } , } , ] , } ; } ); 実際に実行すると、プロンプトを作るために必要な情報を聞かれます。 指示に従って内容を入力していくと、最終的に動的なプロンプトが作成されます。 あとはそのまま実行するだけで、誰が実行しても同じ結果になります。 Elicitation MCPサーバーで管理機能を実現するうえで避けて通れない問題がもう1つあります。基本的にMCPサーバーとのやり取りは一方通行だということです。 MCPサーバーとのやり取りの基本的なシーケンス図はこうなります。 このシーケンス図から分かる通り、リクエストを投げたらレスポンスが返ってくるといった、一般的な流れです。 しかし入力した企業名を間違っていたままプロンプトを実行してしまった場合、間違った情報のままでAPIが実行されてしまうのを止める手段がありません。 そこで活躍するのが、以前に他の記事でも紹介したMCPのElicitationという機能です。 tech.findy.co.jp Elicitationを利用することで、MCPサーバーとのやり取りのシーケンス図は次のように変わります。 confirmとapproveのフローが増えているのが分かるかと思います。MCPサーバーとMCPクライアントの通信中に、ユーザーに追加情報を要求できるようになるのです。 Elicitationを使った確認フローの実装例は次のようになります。 import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js' ; import { apiClient } from '@admin/api-client' ; import * as https from 'https' ; import { z } from 'zod' ; const mcpServer = new McpServer( { name : 'Findy AI+ Admin MCP Server' , version : '0.0.1' , } ); mcpServer.tool( 'create_org' , 'Create a new organization' , { org_name : z.string().describe( 'Organization name' ), email : z.string().email().describe( 'Email address' ), last_name : z.string().describe( 'Last name(Family name)' ), first_name : z.string().describe( 'First name' ), } , { title : 'Create Organization Tool' , } , async ( { org_name , email , last_name , first_name } ) => { const confirmation = await mcpServer.server.elicitInput( { message : `組織 " ${ org_name } " を作成しますか? \n 管理者: ${ last_name } ${ first_name } ( ${ email } )` , requestedSchema : { type : 'object' , properties : { confirm : { type : 'string' , title : '確認' , description : 'Type "yes" to confirm or "no" to cancel' , enum : [ 'yes' , 'no' ] , } , } , required : [ 'confirm' ] , } , } , { timeout : 30000 } ); if ( confirmation. action !== 'accept' || confirmation.content?. [ 'confirm' ] !== 'yes' ) { return { content : [ { type : 'text' , text : 'Organization creation cancelled by user.' , } , ] , } ; } const httpsAgent = new https.Agent( { rejectUnauthorized : false } ); const { response , data } = await apiClient.POST( '/api/admin/hoge' , { params : { header : { Authorization : `Bearer ${ process .env[ 'ACCESS_TOKEN' ] } ` , } , } , body : { org_name , email , last_name , first_name , } , httpsAgent , } ); if (response. status !== 201 || !data) { return { content : [ { type : 'text' , text : `Error: Unexpected response status ${ response. status} ` , } , ] , } ; } const { id , name , user_id , user_first_name , user_last_name , user_email } = data; return { content : [ { type : 'text' , text : `Organization created successfully: - ID: ${ id } - Name: ${ name } - User ID: ${ user_id } - User Name: ${ user_last_name } ${ user_first_name } - User Email: ${ user_email } ` , } , ] , } ; } ); 実際にGitHub Copilot ChatでElicitationを実行した様子を見てみましょう。 まずは先程紹介したプロンプトを実行します。Toolの実行許可を尋ねられるので許可しましょう。 すると、次のような確認ステップが出力されます。 このRespondボタンを押下すると、次のような確認モーダルが表示されます。 今回のケースだとyesを選択するとAPIが実行され、noを選択するとそこで処理が終了となります。 このように、MCPサーバーとの通信中にユーザーに選択肢を要求して処理を分岐したい時にElicitationは大きな威力を発揮します。 まとめ いかがでしたでしょうか? 今回の内容は先日開催した Findy AI Meetup in Fukuoka #2 でも紹介させてもらいました。 こちらがその時の資料となります。是非参考にしてみてください。 ファインディではMCPの有用性にいち早く気づき、検証を続けてきました。 その結果、開発効率を上げるだけではなく、今回紹介したようにサービスに埋め込んだり、プロダクトの作り方、提供の仕方までもが大きく変わりました。 MCPの可能性はどんどん広がっています。是非みなさんのMCP活用法も教えてください。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で先日、Findy AI Meetupの第2回を福岡で開催しましたので、今回はそのイベントの様子や内容を紹介します。 findy-inc.connpass.com 当日参加くださったみなさま、ありがとうございました! Findy AI Meetupとは? 登壇内容 実践!カスタムインストラクション&スラッシュコマンド ファインディ株式会社におけるMCP活用とサービス開発 懇親会 まとめ Findy AI Meetupとは? ファインディ株式会社のエンジニアが主催する技術系のオフラインイベントです。 ファインディ株式会社では、生成AIやAIエージェントの活用を通じて開発生産性の向上を目指す取り組みを行っています。このイベントでは、ファインディのエンジニアが社内での実践事例を紹介するとともに、エンジニア同士がつながり、知見の共有や交流を目的としています。 今回のMeetupは2回目の開催となっており、前回開催にも参加くださった方々が3割ほど、初参加の方々が7割ほどの割合でした。まだ参加したことがない読者の方も次回開催には是非ご参加ください。 登壇内容 実践!カスタムインストラクション&スラッシュコマンド 最初にフロントエンドテックリードの新福が、「実践!カスタムインストラクション&スラッシュコマンド」と題して、ファインディでGitHub CopilotやClaude Codeの機能をどのように活用しているかを紹介しました。 カスタムインストラクションは、生成AIのコンテキストとして渡す文章です。生成AIの特性に合わせた書き方を工夫することで出力の精度を高められます。 実践の例として、今回はコミットメッセージ生成のカスタムインストラクションの設定方法を紹介しました。 // .vscode.settings.json { " github.copilot.chat.commitMessageGeneration.instructions ": [ { " file ": " .github/instructions/commit-message.instructions.md " } ] , } commit-message.instructions.md の例を次に示します。 --- applyTo: '**' description: 'コミットメッセージの生成' --- コミットメッセージは [Conventional Commits](https://www.conventionalcommits.org/ja/v1.0.0/) に従って記述する。 ## フォーマット <type>[optional scope]: <description> [optional body] [optional footer(s)] ### type(必須) - `feat`: 新機能や既存機能の変更 - `fix`: バグ修正 - `docs`: ドキュメントのみの変更 - `*.md` を追加、変更した場合 - `test`: テスト追加・修正 - `*.spec.*` `*.spec.*.snap` を追加、変更した場合 <!-- (中略) --> ### scope(任意) - ディレクトリ名が `package.json` または `package-lock.json` の時 `deps` - ディレクトリ名が `.github/**` の時 `github` - ディレクトリ名が `apps/frontend/**` の時 `frontend` - ディレクトリ名が `libs/frontend/feature-xxx/**` の時 `frontend-feature-xxx` - ディレクトリ名が `libs/ui/**` の時 `ui` <!-- (中略) --> ## コミットメッセージの例 - feat(frontend-feature-xxx): add social login - feat(ui): add button component - fix(frontend-feature-xxx): fix validation - docs(*): update README.md - refactor(frontend-feature-xxx): refactor form logic <!-- (中略) --> GitHub Copilotのカスタムインストラクションは applyTo というプロパティを持っており、ファイル拡張子でコンテキストを絞り込めるのが特徴です。 ファインディのフロントエンドでは、慣習的に 拡張子によってモジュールの責務を分離していた ため applyTo と相性が良いという発見が得られました。これまでやってきた開発の工夫が生成AIの活用に繋がった好例と言えるでしょう。 スラッシュコマンドについては、Gitコマンドを実行する例を示しつつ、プロンプトを書くコツを紹介しました。 プロンプトのコツ さらに実践的な内容として、 Nx のマイグレーションやClaude Codeの通知設定といった例を示しつつ、プロンプトの二重管理を防ぐ工夫を紹介しました。 プロンプト二重管理防止の工夫 スライドは↓から参照できます。時間の都合で割愛した他のサンプルも掲載しております。 ファインディでは生成AIツールの活用を進めつつ、生成AI時代に向けた新しいサービスを開発中です。 findy.co.jp 冒頭に紹介しました調査結果は、次のURLから全文をダウンロードできます(Findyのユーザー登録が必要です)。 findy-code.io ファインディ株式会社におけるMCP活用とサービス開発 次にテックリードの戸田が、「ファインディ株式会社におけるMCP活用とサービス開発」と題しまして、弊社の開発シーンでもMCP(Model Context Protocol)の活用方法と、MCPを埋め込んだプロダクト開発について紹介しました。 まず、弊社でのMCPの活用事例を紹介しました。 TypeScriptのSDKを使用して社内MCPサーバーを開発できるように環境を整備したことを紹介しました。以前にも、このテックブログで紹介しています。 tech.findy.co.jp Nxのgenerator機能を利用して、 ワンコマンドでMCPサーバーの雛形を作成できる ようにしています。さらにNxで管理しているため、複数のMCPサーバーをmonorepoで管理できるようにしており、MCPサーバーの社内エコシステムを実現しています。 このような環境を整備したことにより、3日間で10個のMCPサーバー、30個のtoolを実装して、社内のエンジニアに配布することを実現しました。 次に、他社のMCPと連携して効率化した事例を紹介しました。 GitHubのMCPを利用して、メンティーが受け取ったレビューコメントを取得し、社内MCPサーバーから解析用のプロンプトを動的に返すようにして、 レビューコメントの傾向をLLMが解析する 仕組みを作りました。 また、GitHubのメトリクスを取得してきて MCPサーバー内でmermaid記法のmarkdownに落とし込み、それをクライアント側でグラフ表示する といった仕組みも作りました。 このように、 LLMとMCP、MCPクライアントとMCPサーバーの責務を分けて考えることがMCP活用のコツ です。 最後に、弊社からリリースされた新サービスのFindy AI+について紹介させてもらいました。 Findy AI+は、GitHub連携・プロンプト指示で生成AIアクティビティを可視化し生成AIの利活用向上を支援するサービスです。人と生成AIの協働を後押しして、開発組織の変革をサポートします 当日はFindy AI+のアーキテクチャや設計などについても解説したのですが、これはまた別の機会で紹介できればと思います。お楽しみに! 今回の登壇と資料が皆さんの参考になると幸いです。 懇親会 登壇発表後は参加者の皆さんと懇親会を開催しました。 懇親会では「パックマンルール」をお願いしています。懇親会で誰かと話すときは新しい人が会話に入れるように、一人分のスペースを空けて話しましょう。というルールです。 生成AI活用における悩みや知見を意見交換して、楽しんでいただけたようです。 まとめ いかがでしたでしょうか? 当日、イベントに足を運んでくださった参加者のみなさん、本当にありがとうございました。頂いたアンケート結果を、次回開催の参考とさせていただきます。 次回開催は11月前後を予定しております。残念ながら今回のイベントに参加出来なかったみなさんも、次回イベント開催時には是非ご参加ください! 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
ファインディでソフトウェアエンジニアをやっている土屋です。今回は、先日大好評だった企画、「エンジニアの人生を変えたイベント」のPart2をお届けします。 tech.findy.co.jp 前回に引き続き、弊社エンジニア達が過去に参加したイベントの中で、特に印象に残っているイベントを紹介していきます。 それでは見ていきましょう! YAPC (Yet Another Perl Conference) はじめての外部登壇 同世代エンジニアとの出会い キャリアの転機 まとめ HackBowl【次世代エンジニアの登竜門】 めぐろLT / TechBrew まとめ YAPC (Yet Another Perl Conference) CTO室データソリューションチームの土屋です。私はYAPC::Kyoto 2023とYAPC::Hiroshima 2024で人生が変わりました。 yapcjapan.org yapcjapan.org はじめての外部登壇 YAPC::Kyoto 2023では、初めて大きな舞台でLTに挑戦しました。イベントのトリとして全参加者の前に立つ緊張感は今でも鮮明に覚えています。 私は当時流行り出していた「ChatGPT」に自分の仕事で利用していた技術、「文字コード」を分析させる内容で登壇し、ベストLTをいただきました。 ChatGPTと文字コード.YAPC::Kyoto2023 LT.土屋俊介 (2023)) from stsuchiyabusiness さくらインターネットさんからいただいた賞状はいまでも家に飾っています。 このイベントを契機に、積極的に勉強会やカンファレンスで登壇するようになりました。外部登壇で培った伝える力は、職場での設計議論やプロジェクトの合意形成に貢献しています。 同世代エンジニアとの出会い また、このイベントを通じて知り合った仲間とは、今も一緒にコミュニティ活動を続けています。 「 若手ふんわり勉強会 」という若手エンジニア向け勉強会の運営をさせていただいているのですが、運営メンバーの @uutan1108 さん や @azukibar_D さん と出会ったのもこのイベントです。 同世代のエンジニアとのイベントは単に楽しみに留まらず、自分の実力を客観視する機会になっています。 キャリアの転機 YAPCは現職と関わるきっかけでもあります。YAPCのスポンサーとして来ていたファインディのチームと懇親会に行き親睦を深めました。和気藹々として楽しそうな会社だなと思ったのを今でも覚えています。また、当時の内定者に友人がいたので、CTOの佐藤さんと2ショットをtimesに送り驚かせたりしました (笑) その後、転職を考えはじめたときにファインディを想起し、ご縁があり就職しました。YAPCは私の人生を変えたと確信しています。 まとめ YAPCは私にとって、自分の可能性を広げ、新たな出会いとキャリアの転機を与えてくれる場所でした。そんな、YAPCは2025年11月14日、15日に福岡で開催されます。 blog.yapcjapan.org エンジニアとしての成長や仲間との出会い、人生を変えるきっかけが、そこにあります。カンファレンス初心者の方も、ぜひ一歩踏み出して参加してみてください!! HackBowl【次世代エンジニアの登竜門】 Findyの転職サービス を開発しているみっきーです。 大学2年生の時にHackBowlというTechTrainが主催するハッカソンイベントに参加しました。 このイベントがきっかけで、エンジニアとしてのキャリアの選択肢ができました。 prtimes.jp note.com 大学生の頃、エンジニアになるという目標があったわけではなく、ただ「みんなとご飯を食べにいく時間が楽しみ」という、ごくカジュアルな理由でプログラミングサークルに参加していました。 当時の私は、サークルに集まる情報系の学生や、Kaggle、AtCoderといった競技プログラミングで優秀な成績を収める先輩たちを見て、「そういった特別な人たちだけがエンジニアになれるのだ」と思い込んでいました。(私は情報系の学部の出身ではありません。) サークルに参加をし始めて、半年ほど経った頃にハッカソンへの誘いを受けました。 その時の誘い文句は、「人数合わせだから座っているだけでいい」「東京にも行けるよ(当時、大阪住み)」というものでした。 参加を迷っていましたが、メンターに相談できるハッカソンであり、初心者でも参加しやすそうだと感じたため、参加を決意しました。 結局、開発未経験の中で苦しい思いをしながら徹夜で開発に参加することにはなりましたが、ハッカソン後の懇親会で目の当たりにした光景が、私のエンジニアに対する固定観念を完全に打ち破りました。 様々なバックグラウンドを持つ学生たちが、楽しそうにエンジニアリングを語り合っていたのです。 この光景は、私にとって大きな刺激となり、「情報系の学生や競技プログラミングで優秀な人だけがエンジニアになれる」という、それまでの思い込みが完全に覆されました。 この時、心の底から「自分ももっと本気でやりたい!」という強い思いが芽生えました。 まさに、この瞬間が私の人生を変えるターニングポイントとなったのです。 このハッカソンでの経験が、私のエンジニアとしての道を本格的に歩み始めるきっかけとなりました。 また、学生時代に多くの出会いと助けを受け、支えられてきた経験から、「今度は自分がコミュニティに貢献したい」という気持ちが強く芽生えました。 サークルに所属して1年が経つ頃には、思いがけず代表を任されることになりました。 これを機に、学生向けハッカソンや勉強会の主催、エンジニアインターンへの挑戦など、本格的にエンジニアリングの道へと足を踏み入れました。 社会人になった今も、技術コミュニティへの関心は尽きません。 TechBull の運営に携わったり、Rubyコミュニティの活動に参加しています。 最近では、RubyKaigi 2024でLTに挑戦する機会をいただき、TechBullでも登壇させていただくなど、コミュニティに貢献しながら自身の技術を磨いています。 techbull.connpass.com 偶然の誘いから始まった1つのハッカソンが、私のエンジニアとしてのキャリア、そして人生観そのものを大きく変えました。 あの日の経験が、エンジニアリングへの情熱を燃やし、私自身の可能性を広げてくれたことに、深く感謝しています。 めぐろLT / TechBrew Findy Team+を開発している、おおいし( @bicstone )です。 私がエンジニアキャリアの転機として挙げたいイベントは、人生で初めて登壇した「 めぐろLT 」(2023年5月)と「 TechBrew 」(2023年6月)という2つのイベントです。 raksul.connpass.com findy.connpass.com これまでブログ執筆やイベントに参加する中で、登壇者の発表に刺激を受けるたび、いつしか「情報を受け取る側」から「情報を伝える側」へ回ってみたいという憧れを抱くようになりました。そして、思い切ってLT(ライトニングトーク)に挑戦したのがこの2つのイベントです。 当日は、業務で取り組んでいた チームでの合意形成を促す投票手法 について発表しました。 とはいえ、登壇には高いハードルを感じる方も多いかもしれません。私もその一人でした。もちろん、最初は「緊張せずにうまく話せるだろうか」「的外れなことを言って攻撃されないか」といった不安がつきまといます。 しかし、そんな心配とは裏腹に両コミュニティとも初心者や登壇者を温かく迎え入れてくれる雰囲気があり、運営の方や参加者の皆さんの温かい空気が、そういった不安を和らげてくれたのです。 TechBrewにて著者が登壇している様子(2023年6月) この初登壇での成功体験は、その後の継続的なアウトプットへの大きな自信と原動力になります。私自身、今では2ヶ月に1回以上のペースで登壇を続けており、 アウトプットを続けることのメリット を日々実感しています。あの時、勇気を出して一歩を踏み出した経験が、現在の活動の大きな糧となっています。 社外での登壇がもたらす最大のメリットは、全世界からフィードバックが得られることです。参加者としてイベントに参加するのとは異なり、発表に対してフィードバックや質問が寄せられます。これにより、チーム内だけでは得られない新たな視点に気づかされるのです。まさに、「発信した人のもとに、さらに質の高い情報が集まる」という好循環が生まれます。 この記事を読んで、少しでも学びを共有し成長したいと感じた方は、ぜひ身近なコミュニティのLTイベントに挑戦してみてください。きっと、温かい拍手で迎えてくれるはずです。 もし最初の一歩を踏み出す場所に迷ったら、私たち ファインディが開催しているイベント のLT公募登壇枠も、ぜひ選択肢に入れてみてください。挑戦するエンジニアを応援するこの場所で、皆さんの挑戦をお待ちしています。 まとめ いかがでしたでしょうか? 3名とも初めての登壇が人生を変えたという共通点があり、最初の一歩を踏み出すことが大切なのだと改めて感じました。本記事が登壇の切っ掛けになれば幸いです。 そんな登壇者が集まるファインディでは一緒に働くメンバーを募集中です!! 詳細は次のリンクからご確認ください。 herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で先日、Findy AI Meetupの記念すべき第1回を、2025年8月4日(月)に福岡にて開催致しました! tech.findy.co.jp そのイベントで ファインディ株式会社における生成AI活用までの軌跡 と題しまして登壇しました。 そこで今回は、イベントに参加出来なかった方向けに、登壇資料をなぞりながら弊社が生成AIを活用できるようになるまでの道のりを紹介します。 ファインディの開発文化 生成AI活用のための事前準備 生成AI時代のファインディの開発現場 テックブログの壁打ち 小さいタスクはDevinにお任せ AI Agentで自律的かつ並列に開発 Model Context Protocol カスタムスラッシュコマンド まとめ ファインディの開発文化 まずは弊社の開発組織の文化を紹介します。 以前紹介したタスク分解。これは 弊社にJOINしてくれたエンジニアが最初に覚えるスキル です。 tech.findy.co.jp また、以前紹介したPull requestの粒度も重要です。適切な粒度でPull requestを作成することで、レビュワー、レビュイーの両者に対して優しいPull requestとなり、開発リズムを整えることが出来ます。 適切な粒度を知るためにも、タスク分解のスキルは必須となっています。 tech.findy.co.jp テストコードとCI/CDを整備することも重要です。 テストコードがあることで、実装コードを変更した際に、既存の振る舞いに影響がないことを保証することが出来ます。また、テストコードを読むことで、そのアプリケーションの正しい振る舞いを知ることが出来ます。 tech.findy.co.jp CI/CDは特に速度と自動化に拘っています。 Pull requestの粒度が比較的細かいため、作成数が多くなります。作成数が多い中でCIが遅い場合、CIの速度がボトルネックとなり、開発スピード全体が遅くなってしまいます。そこで弊社では、キャッシュや並列実行などを駆使してCIの高速化を図っています。 tech.findy.co.jp 統一されたコード規約と設計、ドキュメンテーションも重要です。弊社では「新しいメンバーがJOIN初日にPull requestを作成することが出来る」ということを目指してREADMEの整備を行っており、都度内容の見直しをしています。 このようにファインディの開発文化は、 開発に着手する前の事前準備を重要としている ことが分かるかと思います。 1つ1つはとても小さなことです。しかし、それらをこの5年間でしっかりとやり切ってきました。それらの積み重ねが開発組織の文化となっています。 僕もテックリードとなり、弊社の開発組織も5年前は10人も満たなかったのが、今では50人を超える規模となっています。 この規模になると、僕の目が行き届いていないチームも出てきています。 しかし、彼らは僕のいないところでも、今回紹介した 「開発に着手する前の準備」を怠っておらず、新メンバーに開発文化の継承を継続する ことが出来ています。 着実に積み重ねたものは強い ということを皆が証明してくれました。 生成AI活用のための事前準備 さて、ここからが本題ですが、ここまで読んでくださった読者のみなさんの中には既に勘付いている方もいるかと思います。 そうです。 ここまで紹介した内容はどれも、生成AIを活用するために必要なこと なのです! タスク分解は生成AIに明示的に指示を出す時に特に重要 です。Issueやプロンプトに階層構造で明確なステップを記述することで、生成AIが理解しやすいタスクを作成できます。 適切な粒度のPull requestを生成AIに例として提示することで、 余計な内容を学習することなく同じような修正を任せる ことが出来ます。 テストコードとCI/CDは生成AI時代に重要度が更に増しています。 生成AIが修正内容の方向性を外れないためのガードレールとなるからです。 生成AIがコードを修正した後に、その内容が合っているのか、間違っているのかを生成AI自身が判断するための基準となる のです。 統一されたコード規約と設計、ドキュメンテーションは、生成AIがコンテキストを理解するうえで最も重要なリソースの1つです。これらの内容がバラついてしまうと、生成AIが正解を導くことが難しくなってしまいます。 ファインディではこれらのことを、生成AI活用が開発の現場に広まる前から取り組んでいました。 生成AIを開発に足したのではなく、生成AIが今までの開発フローに乗っかってきた。というイメージが近いかもしれません。 生成AIを活用するために新しく何かをした。ということではなく、 人が開発しやすくなるように整備を進めていた結果、生成AIフレンドリーな環境、文化になっていた ということです。 もちろん、全ての内容を完璧に整えられているわけではありません。まだ道半ばの箇所もあります。しかし、それらに対して 時間やコストを掛けて整備を進めることが当たり前という考えを、開発組織だけではなく経営陣含めて全社で共通認識として持っている ことが、弊社の文化だと言えるでしょう。 生成AI時代のファインディの開発現場 ここまでで、弊社が生成AIを活用出来ている理由を説明しました。 ここからは、実際にどんなシーンで活用しているかを紹介します。 テックブログの壁打ち 執筆やアウトプットの経験がないメンバーが、いきなりテックブログの記事を執筆するのはハードルが高いものです。 そこで弊社CTOが作ったのが壁打ちbotです。Slackのメッセージでbotとインタラクティブにやり取りして、執筆内容を壁打ちをしてくれます。 書きたい、伝えたい内容をbotと壁打ちしていくと、最終的にテックブログの記事の草案を出力してくれます。草案を元に記事を執筆できる環境を整えることで、テックブログの執筆に対するハードルを下げることに成功しました。 大事なこととして、AIで書かれた文章をそのままブログ記事にしてしまうと本人の持つ「味」が損なわれてしまいます。そのため、あくまで骨子を作ることまでに限定し、自分の手で書いてもらうことが望ましいです。 また、テックブログの記事を書き終わってタイトルに悩まされる経験をした読者の方もいると思います。そういったケースの場合、ChatGPTとタイトル案の壁打ちを行うこともあります。 この場合、生成AIに執筆内容を渡して、タイトル案を複数個出してもらうと良いです。 その中で気になるキーワードが出てきたら、そのキーワードを使うという条件を追加して新たにタイトル案を複数出してもらいます。この作業を繰り返すと、最終的に良い感じのタイトルが出てきます。テックブログの記事のタイトルに悩んだ時に試してみてください。 小さいタスクはDevinにお任せ 一括置換や軽微なリファクタといったタスクはDevinにお任せしています。 実際にDevinに依頼してPull requestを自動作成する仕組みを作ったことで、 個人のアウトプットが1.5倍 になったという実例もあります。 tech.findy.co.jp また、DevinでTerraformのコードを変更してPull requestを作成する仕組みも用意しています。 Slackのワークフローを用意して、Devinへの依頼を定型化します。そこからAWSのリソースへの権限追加や、構成変更などをDevinが自動でPull requestを作成します。 作成されたPull requestをSREチームがレビューし、問題なければmergeしてTerraformのapplyが実行されるようになっています。 Slackのワークフローを変更依頼のスタート地点としており、人間が介入するのはレビューとmergeのタイミングだけとなっています。このようにワークフローを定型化できる作業はDevinに任せています。 この話はまた別のタイミングで出来たらと思います。お楽しみに! AI Agentで自律的かつ並列に開発 弊社では主にClaude Code ActionやGitHub Copilot Coding Agentを活用しています。 GitHubのIssueに要件とタスクを記載して、それをAI Agentに渡してPull requestの作成まで自動化しています。 そしてここでも タスク分解のスキルが大いに生きます。 AI Agentに依頼するタスクは明確なステップ階層で渡すと精度が上がります。 実際にClaude CodeやKiroが自身でタスクを出すときも、明確なステップ階層で出してきます。タスク分解に慣れていない方は、まずClaude CodeやKiroにタスクを出してもらい、そこから修正して正しいタスク出しを経験していくと良いと思います。 Model Context Protocol 弊社ではMCP(Model Context Protocol)の有用性に一早く気づき、検証を進めてきました。 tech.findy.co.jp tech.findy.co.jp MCPを内製で作成できるように環境を整備した他、業務効率化だけに留まらず、 新規プロダクトでの導入 も行っています。 後述にはなりますが、 次回開催するイベントで私がMCPをテーマに登壇する予定 です。福岡でのオフラインイベントになりますが、気になる方は是非ご参加ください。 カスタムスラッシュコマンド Claude Codeの機能で、頻繁に使うプロンプトを定義できます。 Nxのmigrateを自動で実行するものや、GitHubのIssueを取得して、タスク分解から実装、Pull requestまで自動化するものなど、多岐に渡って用意しています。 特に有用だと感じたのは、ローカル環境の環境構築を自動化するカスタムコマンドです。今まではREADMEの内容を元に各自実行して環境構築をしていましたが、カスタムコマンドで自動化することで、環境構築に対するハードルが落ちました。 次の例は、Pythonのプロジェクトの環境構築をするカスタムコマンドの例です。 # Local環境の環境構築 - brew install uv - mise install - brew install mkcert - mkcert -install - mkcert -cert-file localhost.pem -key-file localhost-key.pem localhost 0.0.0.0 - uv sync --frozen - cp .env.sample .env.local - docker compose up -d db mailpit - python -m alembic upgrade head - python -m pytest 今まではREADMEに環境構築の手順を書いていましたが、メンテナンスが行き届いていなかったり、意図しない場面で詰まることがありました。 ですが、Claude Codeのカスタムコマンドで環境構築することで、 意図しない場面で詰まっても、Claude Codeが原因を突き止めて、軌道修正しながら環境構築を完了する ことが出来ます。 まとめ いかがでしたでしょうか? 長年の小さな改善の積み重ねが、現在の開発組織の文化を作りあげました。 その結果、生成AIと自然に協働できる AIフレンドリーな組織文化 となっていたのです。 生成AIとの協働は1日にして成らず。 事前準備や環境、ガードレールの整備など、 小さな積み重ねを続けることが重要 です。 人が開発しやすくすることは、結果的に生成AIのガードレール整備に繋がる のです。 生成AIを使ってみたけど、思っていた結果が出ないと感じているのであれば、まずは目の前の小さなことや、足元の整理に着手することをオススメします。 登壇資料の方も是非ご覧になってください。 最後になりますが、このたび 2025年9月8日(月)にFindy AI Meetup in Fukuoka #2の開催が決定 しました! findy-inc.connpass.com 会場へのアクセスは天神駅から徒歩3分となっています。また、TVCM公開記念ノベルティや、イベント後半には懇親タイムもご用意しています。 僕も運営、登壇者として参加予定です。是非イベントに足を運んでいただき、懇親会でAI談義に花を咲かせましょう。 申込みの先着順となっておりますので、気になっている方は早めにお申し込みいただくことをおすすめします。生成AIの活用事例に興味のある方は奮ってご参加ください! みなさんにお会いできることを楽しみにしています! 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
はじめに こんにちは。CTO室 Platform開発チーム SREの原( @kouzyunJa )です。 ファインディでは日々サービスが爆速で開発されており、新しいプロダクトも次々と生まれています。それらのインフラ構築を、私たちのチームが支えています。 インフラ構築にもスピード感が求められるため、効率的かつ安全に進める仕組みが欠かせません。 今回は、そのスピード感あるインフラ構築を支えるTerraform Testの取り組みについてご紹介します。 はじめに Terraform Testの導入背景 Terraform Testの書き方紹介 UnitテストとIntegrationテスト ディレクトリ構成 mock providorとUnitテスト 複数モジュールを組み合わせたIntegrationテスト CIワークフローでの活用 まとめ Terraform Testの導入背景 developer.hashicorp.com Terraform TestはTerraform 公式のテストフレームワークで、Terraform v1.6.0から利用可能です。 モジュール更新による破壊的変更を事前に検証でき、テストは新規にリソースが構築され、その後自動的に削除されます。既存のインフラ環境やstateへの影響はありません。 弊社ではIaCとしてTerraformを導入しており、HCP Terraformにてstateの情報を管理しています。 スピード感のあるインフラ構築を実現するため、ファインディのプロダクトでよく利用するリソースをモジュール化しています。 これらのモジュールを、私たちは「汎用モジュール」と呼んでいます。 AWSの新規インフラ環境構築時にはこの汎用モジュールを活用する取り組みを推進しています。 しかし、汎用モジュールから環境を構築する際にTerraform Planは通るものの、Terraform Applyで失敗するケースがあり、その結果、構築スピードが低下するという課題がありました。 この課題を解決するため、Terraform Testを導入しました。 Terraform Testの書き方紹介 Terraform Test は専用のテストファイルに記述します。 .tftest.hcl または .tftest.json の拡張子のファイルにテストコードを記載していきます。 イメージが付きやすいように、S3バケットを構築するシンプルな例を使って説明します。 # main.tf provider " aws " { region = " ap-northeast-1 " } variable " bucket_prefix " { type = string } resource " aws_s3_bucket " " example " { bucket = " ${var.bucket_prefix}-bucket " } このS3バケットの名前が想定通りで構築されているかのテストを書いてみますと次のようになります。 # main.tftest.hcl variables { bucket_prefix = " test " } run " valid_string_concat " { command = plan assert { condition = aws_s3_bucket.bucket.bucket == " test-bucket " error_message = " S3 bucket name did not match expected " } } runブロック内でテストを記述しており、assertで条件式を定義し、期待する値と一致するかを検証します。 このように作成するリソースの値が正常に設定されているかを確認できます。 UnitテストとIntegrationテスト ファインディではTerraform Testにおいて、独自にUnitテストとIntegrationテストの2種類のテストカテゴリを設けています。 Unitテスト: Terraform Planに相当し、リソースを作らず論理的に検証する Integrationテスト: 実際にリソースをApplyして作成し検証、その後は自動的にリソースのDestroy行われる この2つを組み合わせることで、インフラ環境のテストを行っています。 使い分けはrunブロック内のcommandの指定によって決まります。 command = plan を指定すればUnitテストを実行する command = apply を指定すればIntegrationテストを実行する よって、さきほどの例は command = plan を指定しているのでunitテストとしています。Integrationテストでも、assertでの値の確認は同様に行うことができます。 ディレクトリ構成 テストのコードは、各モジュール配下のtestsディレクトリに配置しています。 UnitテストとIntegrationテストをディレクトリで分けており、対象のテストだけを個別に実行できます。 # Terraform モジュール と テスト構成例 modules/ <module-name>/ ├── main.tf ├── variables.tf ├── outputs.tf └── tests/ ├── unit/ │ └── main.tftest.hcl └── integration/ └── main.tftest.hcl テストを実施したい場合は、 terraform test コマンドを使用します。 また、 -test-directory オプションを指定することで、Unitテスト用のディレクトリや Integrationテスト用のディレクトリを切り替えて実行できます。 $ terraform test -test-directory=./tests/unit 実行結果は次のように表示されます。 runブロックごとにテスト名と結果が表示され、成功(pass)か失敗(fail)かを確認できます。 tests/unit/main.tftest.hcl... in progress run "test1"... pass run "test2"... pass run "test3"... pass run "test4"... pass run "test5"... pass tests/unit/main.tftest.hcl... tearing down tests/unit/main.tftest.hcl... pass Success! 5 passed, 0 failed mock providorとUnitテスト Unitテストではcommand = planを利用して実リソースを作らず論理的に検証します。 テストを行うモジュールの外部にあるリソース情報(例: 既存のIAM RoleのARNや、外モジュールのS3バケットのARN)を参照する場合、 mock providerを活用すると、外部リソースを実際に参照せずにテストを実行できます。 # main.tftest.hcl mock_provider " aws " { mock_data " aws_iam_role " { defaults = { arn = " arn:aws:iam::111122223333:role/mock-role " } } } run " check_role_arn " { command = plan assert { condition = data.aws_iam_role.example.arn == " arn:aws:iam::111122223333:role/mock-role " error_message = " IAM Role ARN does not match expected value " } } このようにmock providorを活用することで、モジュール外部のリソースを実際に参照せずともUnitテストを行うことができます。 複数モジュールを組み合わせたIntegrationテスト ファインディでは汎用モジュールを「Network」「Container」など機能単位でモジュールを分けて作成しています。 このため、例えばContainerモジュールを単体でIntegrationテストしようとしても、Networkモジュールで作成しているVPCやSubnetが存在しないためApplyに失敗します。 そこで依存するNetworkモジュールを先にApply → その出力値をContainerモジュールに渡す、という流れを取り入れました。 これにより、依存関係を含めた最小構成を再現しながら Integrationテストを実行できます。 # main.tftest.hcl run " network_module_apply " { command = apply # Call the Network module module { source = " ./../../../network " } variables { vpc_cidr_block = " XX.XX.XX.XX/XX " subnet_public_1a_cidr_block = " XX.XX.XX.XX/XX " subnet_public_1c_cidr_block = " XX.XX.XX.XX/XX " subnet_public_1d_cidr_block = " XX.XX.XX.XX/XX " subnet_private_1a_cidr_block = " XX.XX.XX.XX/XX " subnet_private_1c_cidr_block = " XX.XX.XX.XX/XX " subnet_private_1d_cidr_block = " XX.XX.XX.XX/XX " } } run " container_module_apply " { command = apply # Call the container module module { source = " ./../../../container " } variables { vpc_id = run.network_module_apply.vpc_id private_subnets = [ run.network_module_apply.subnet_private_1a_id, run.network_module_apply.subnet_private_1c_id, run.network_module_apply.subnet_private_1d_id ] public_subnets = [ run.network_module_apply.subnet_public_1a_id, run.network_module_apply.subnet_public_1c_id, run.network_module_apply.subnet_public_1d_id ] } } CIワークフローでの活用 ここからはGitHub ActionsのCIに組み込んだTerraform Test活用方法について紹介します。 Terraform TestはCI ワークフローに組み込んで自動実行しています。 CIに組み込む際のポイントとしてUnitテストとIntegrationテストは使い分けています。 Unitテスト: PR作成時に実行 Integrationテスト: Mainブランチへマージ後、HCP Terraformへリリースする前に実行 使い分けている理由として、Integrationテストはリソースの構築から削除までを伴うため、完了まで時間がかかります。 例えばAuroraの場合、構築から削除完了まで長時間のテストを待つ必要があり、PRのレビュー速度に影響するため、マージ後に実行する設計としています。 Unitテストは論理的に検証するため、PR作成時に実行してスピーディーな確認ができます。 サンプルコードは次のようになります。 name: PR - Terraform Test (Unit) on: pull_request: paths: - "**.tf" - "**.hcl" jobs: unit-tests: runs-on: ubuntu-XX.XX steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: X.XX - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ap-northeast-1 role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} role-duration-seconds: 1200 - name: Terraform init run: terraform init - name: Terraform validate run: terraform validate -no-color - name: Terraform test (unit) run: terraform test -test-directory=tests/unit PRのUnitテストで問題ないと判断したら、mainブランチへマージを行いIntegrationテストを実行します。 AWSのSandbox環境で apply → assert → destroy を行い、リソースがApplyに失敗せず正しく作成できるかを検証します。 Integrationテストがパスされれば汎用モジュールのstateを管理しているHCP Terraformへリリースされます。 サンプルコードはこちらになりますが、ほとんどUnitテストと変わりません。 name: Release - Terraform Test (Integration) on: push: branches: - main jobs: integration-tests: runs-on: ubuntu-XX.XX steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Terraform uses: hashicorp/setup-terraform@v3 with: terraform_version: X.XX - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: aws-region: ap-northeast-1 role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} role-duration-seconds: 1200 - name: Terraform init run: terraform init - name: Terraform validate run: terraform validate -no-color - name: Terraform test (integration) run: terraform test -test-directory=tests/integration このようにCIのワークフローにTerraform Testを組み込むことで、PR時にUnitテストで素早いフィードバックを得られ、マージ後にはIntegrationテストで実際の構築検証を行うという二段構えが実現できました。 結果として、より信頼性の高い汎用モジュールを安全に開発できるようになっています。 まとめ 以上がTerraform TestとCIワークフローへの組み込みの紹介となります。 テストを汎用モジュールに組み込むことで、事前にApply失敗を検知できる仕組みを整え、信頼性を高めつつスピード感のあるインフラ構築を進められるようになりました。 一方で、Integration TestはSandbox環境に実際のリソースを構築するため実行時間が長くなるという課題もあります。今後はテストスピードの改善や効率化の仕組みを検討していく予定です。 皆さんのTerraform活用のヒントになれば幸いです。 ファインディでは一緒に会社を盛り上げてくれるSREメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で先日、Findy AI Meetupの記念すべき第1回を、2025年8月4日(月)に福岡にて開催致しました! tech.findy.co.jp イベント終了後には参加者の皆さんにアンケートを回答いただき、運営メンバー全員で全ての回答に目を通しました。 どの回答からもイベントを楽しんで頂けたこと、そして学びのきっかけを届けることが出来たことが伝わってきました。参加者の皆様、改めてお礼申し上げます。ありがとうございました。 Findy AI Meetup in Fukuoka #2 開催決定! Findy AI Meetupとは? 登壇予定 実践!カスタムインストラクション&スラッシュコマンド ファインディ株式会社におけるMCP活用とサービス開発 まとめ Findy AI Meetup in Fukuoka #2 開催決定! 前回開催から日は浅いですが、皆さんの熱量の高さに触れ、このたび2025年9月8日(月)にFindy AI Meetup in Fukuoka #2の開催が決定しました! findy-inc.connpass.com そこで今回は、イベント開催の告知と、予定している内容を紹介したいと思います。 Findy AI Meetupとは? ファインディ株式会社のエンジニアが主催する技術系のオフラインイベントです。 ファインディ株式会社では、生成AIやAIエージェントの活用を通じて開発生産性の向上を目指す取り組みを行っています。このイベントでは、ファインディのエンジニアが社内での実践事例を紹介するとともに、エンジニア同士がつながり、知見の共有や交流を目的としています。 今回は前回の開催から1ヶ月という短いスパンでの開催とはなりますが、皆さんの熱量のおかげで2回目の開催がすぐに決定しました!本当にありがとうございます! 登壇予定 実践!カスタムインストラクション&スラッシュコマンド GitHub CopilotやClaude等のAIツールを用いたソフトウェア開発は、今や当たり前のものとなっています。 この発表では、ファインディで用いられているカスタムインストラクションやスラッシュコマンドについて紹介します。 tech.findy.co.jp tech.findy.co.jp スラッシュコマンドについては、以前のテックブログで取り上げられたものの他にも、 Gitリポジトリの掃除 Claude Codeの通知設定 Nxのマイグレーション実行 といったものを紹介する予定です。 また、ツールの整備を通して得られた、コーディングスタイルと生成AIとの関係についても共有できればと思います。 ファインディ株式会社におけるMCP活用とサービス開発 「ファインディ株式会社におけるMCP活用とサービス開発」と題しまして、弊社のMCP活用の実例をいくつか紹介します。 まずMCP(Model Context Protocol)と、それを使った弊社のサービスについて紹介します。 tech.findy.co.jp tech.findy.co.jp 次に、MCPを日々の開発にどのように入れ込んでいるのか、弊社の事例をいくつか紹介します。 MCPとは何なのか?そして具体的にどう活用すればいいのかヒントを得たい方に是非聞いていただきたいセッションとなっています。 まとめ いかがでしたでしょうか? 会場へのアクセスは天神駅から徒歩3分となっています。また、TVCM公開記念ノベルティや、イベント後半には懇親タイムもご用意しています。 申込みの先着順となっておりますので、気になっている方は早めにお申し込みいただくことをおすすめします。生成AIの活用事例に興味のある方は奮ってご参加ください! イベント参加申し込みはこちらから ↓ findy-inc.connpass.com みなさんにお会いできることを楽しみにしています!
アバター
こんにちは!ファインディのTeam+開発部でEMをしている奥村です。 チームや組織が大きくなるにつれ、横の繋がりが薄くなった気がする…そんな課題を感じたことはありませんか? 私たちファインディのTeam+開発部は多くのメンバーを迎え入れながら拡大を続けています。 現在26名(業務委託除く、正社員のみ)が所属しており、そのうちここ一年でジョインしたメンバーが11名にのぼります。 一方で横軸のコミュニティ構築とメンバーの主体性の促進が組織の課題として挙がっていました。 そこでOpen Space Technology(以下OST)というワークショップを実施したので、今回はワークショップの紹介と実施レポートを報告します。 なぜOST? まず前提として私たちは、Team+開発部を 「チーム横断での協働・協力等の相互支援を活性化し、Findy Team+開発のあるべきを主体的に思い描き、建設的な議論を行いながら自走できる組織」 にしたいと考えています。 冒頭で述べた通り、私たちTeam+開発部は多くのメンバーを迎え入れて拡大をしています。 人数増加に伴いチームも6チームに分かれていますが、正直なところ、 かつてのような横軸のつながりが薄くなってきている と感じています。 また、組織課題に触れる機会も断片的・限定的になりがちで、他のチームの状況や各メンバーがどんなことを考えているのかを知る機会が減ってきています。 何かしら課題を感じても「周囲の考えが分からない」「どんな活動が進められているか見えない」といった具合に主体的な行動が抑制されかねないと感じています。 実際、属人化や対応偏り、知見や活動の共有の不足などを聞くこともありました。 そこで、次のような目的を持ってOSTを実施することにしました。 横軸のコミュニティを再構築し、課題解決に向けた協働文化や成長の相互支援を活性化する Team+開発の未来のあるべきを主体的に思い描き、建設的な議論を行いながら自走できる組織にする もう少し具体的に言うと、次の狙いです。 信頼関係・相互理解:チームを超えた交流の促進 自己組織化:主体的にあるべき姿を考える文化の醸成 自立性:自立して学び、行動する文化の促進 OSTってなに? 「OST」というワークショップをご存知でしょうか? OSTは、参加者が自分で「これを話したい!」というテーマを持ち寄って、自由に議論するスタイルのワークショップです。 セッションテーマの提案からタイムテーブルの作成、セッションの進行までを参加者自身が主体的に行うことが特徴です。 セッションテーマは誰でも提案可能で、アジェンダもその場で決まります。 参加するセッションも参加者が自身の興味関心に合わせて自由に選べます。また、セッションの途中で他のセッションへの移動も可能です。 「対話」をメインの目的としており、明確なネクストアクションを決めるようなことはありません。 対話を通して、テーマに対する理解の深化や知見の共有、アイデア創出など行うワークショップになります。 OSTには"4つの原則"があります。これらの原則は参加者の主体性を促すOSTの鍵となります。 ここにやってきた人は、誰もが適任者である 何が起ころうと、それが起こるべき唯一のことである いつ始まろうと、始まった時が適切なときである いつ終わろうと、終わった時が終わりのときである なお、他にも"蝶と蜂"や"移動性の法則"といった特徴がありますが、私たちの人数規模では詳細に説明する必要がないと判断して省略をしました。 似たワークショップにワールドカフェがあります。 ワールドカフェは設定されたテーマに対してメンバーを変えながら議論を深めていきます。 これに対して、OSTはテーマが複数並行して進行し、参加者が自由に選べる点で異なります。 当日の流れ 全体タイムテーブル 10:00 ~ 10:15: 準備 10:15 ~ 10:30 アイスブレイク 10:30 ~ 11:00 概要説明、タイムテーブル作成 11:00 ~ 15:00 セッション 11:00 ~ 11:40 セッション① 11:50 ~ 12:30 セッション② 12:30 ~ 13:30 お昼(お弁当) 13:30 ~ 14:10 セッション③ 14:20 ~ 15:00 セッション④ 15:00 ~ 15:10 クロージング、片付け 弊社オフィス内のイベントスペースで実施をし、フルリモートのメンバーもオフィスに集まってもらい23名が参加をしました。 アイスブレイクでは、テーブルごとに他己紹介を行なってもらい、各メンバーのパーソナルな部分を知る時間を設けました。 フルリモートのメンバーやチーム外のメンバーの意外な一面を知り、本題のセッションに入る前の心理的なハードルを下げることができたと思います。 各セッションは40分+10分のバッファで設定していました。 セッションタイムテーブル 大枠のテーマとして 「Team+の今後を考えるとき今話したいこと」 を置いて、各セッションのテーマはその場で各メンバーから自由に提案してもらいました。 念の為、テーマが挙がらなければマネージャー陣がファーストペンギンに…と裏で話していましたが、 全くの杞憂でした。 AIの話から、開発の進め方、品質、コミュニケーションなどなど、様々なテーマが挙がりました。 重複するものはマージし、類似するテーマは別時間にズラすなどの調整をして、最終的にはこのようなタイムテーブルとなりました。 セッション一部紹介 実際のセッションを一部紹介します。 ・チームを超えた交流の方法について ・どうやって考えている?(プロセス・手法) やってみてどうだったか? 実施後アンケートから、非常にポジティブな結果が得られました。 対話と発散を意図していたため業務への活用はあまり期待していませんでしたが、「ある程度活用できる」が60%、「積極的に活用できる」が40%と、全員が何かしらの活用を考えることができたようです。 実際に、OST実施後に改善へ向けたアクションを起こしたメンバーもいました。 自由記入の感想では次のような回答がありました。 なかなか話す機会ないトピックについて話ができた チーム外のメンバーがどう課題感を持っているか、どういう考えを持っているのかを広く知れる機会になった 普段感じている課題感や難しさを共有できた マネージャーからメンバーまで、役職関係なくさまざまな視点からの意見が聞けた 今回のOSTを通して、各メンバーが何かしらに興味関心を持ち、何かしらに課題感を持っていることを再確認できました。 また、それらを発散・共有するだけでも組織の一員としての意識が高まることを実感しました。 目的が達成されたのかは今後のアクション次第ではありますが、少なくとも重要で大きな一歩目を踏み出せたと感じています。 コミュニケーションにおいても、普段フルリモートのメンバーやチーム外のメンバーなど幅広く交流ができ、通常の業務で会話する際のハードルを下げられたと考えられます。 次回以降の改善点として、他セッションでの議論を知る時間を設けることやエンジニア以外のメンバーを巻き込むことなどを考えています。 まとめ Team+開発にとってははじめてのOSTでしたが、単なる交流会ではなく、 組織を強くするための大きな一歩になったと確信しています。 交流を深められた・課題感を共有できた・アイデアを出し合えた等ポジティブな感想が多く、実施後に多くのメンバーから「定期的にやってください」と直接言われるほどでした。 反省点もあるものの、それを活かして今後も引き続き、組織の強化・文化の醸成に向き合っていきます。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。Findy Tech Blog編集長の高橋( @Taka-bow )です。 前回の記事 では、全体の44.3%が開発生産性に前向きという結果をご紹介しました。今回は開発手法別に深掘りすると、予想外の事実が浮かび上がってきました。 開発生産性への印象は多様 ── 約半数が中立的立場も抵抗感は少数派 意外な結果 ── アジャイル実践者の59.6%が開発生産性に前向き なぜアジャイル実践者は開発生産性に前向きなのか アジャイルの価値観と生産性改善の親和性 Kent Beck氏が語る測定の本質 ── 「測定が目標になると、システムは歪む」 アジャイル実践者の「前向きさ」に潜む3つの勘違い 何を測るべきか ── Kent Beck氏が示す価値創造の道筋 測定を「コントロール」ではなく「認識」のツールとして ── Kent Beck氏の4つの提言 次回予告 【調査概要】 調査対象: ソフトウェア開発(組み込み開発を含む)に直接関わるエンジニア、プロダクトマネージャー、プロジェクトマネージャー、エンジニアリングマネージャー、開発責任者など 調査方法: インターネット調査 調査期間: 2025年4月2日(水)~2025年5月21日(水) 調査主体: ファインディ株式会社 実査委託先: GMOリサーチ&AI株式会社 有効回答数: 798名(95%信頼区間±3.5%) 統計的検定力: 80%以上(中程度の効果量d=0.5を検出) 調査内容: 開発生産性に対する認識 開発生産性に関する指標の活用状況 開発生産性に関する取り組み 開発環境・プロセス評価 組織文化と生産性 開発生産性への印象は多様 ── 約半数が中立的立場も抵抗感は少数派 あらためて、「開発生産性」という言葉に対する印象を見てみましょう。 開発生産性への印象に関する回答分布 選択肢 回答者数 割合 詳細内訳 どちらでもない 384人 48.1% – ポジティブ 354人 44.3% とてもポジティブ + どちらかというとポジティブ ネガティブ 61人 7.6% とてもネガティブ + どちらかというとネガティブ 合計 798人 100.0% – 「開発生産性」という言葉に対してネガティブな印象を持つ人は わずか7.6% (61人)。一方で、 44.3%がポジティブ (354人)な印象を持っており、 約半数(48.1%)が中立的 (384人)な立場を取っています。 この結果から、多くのエンジニアが生産性向上に対して前向き、あるいは少なくとも抵抗感を持っていないことが分かります。これは、日本の開発現場が変化を受け入れる準備ができていることを示唆しています。 意外な結果 ── アジャイル実践者の59.6%が開発生産性に前向き 私がこれまで出会ったアジャイルコーチの多くは、口を揃えて「生産性は測れない」「生産性に意味はない」と言っていました。そのため、アジャイル実践者ほど開発生産性という概念に抵抗を示すのではないかと予想していました。 しかし、調査結果は意外でした。 開発手法別の開発生産性に対するポジティブ印象の比較 フレームワーク 対象者数 ポジティブ印象者数 ポジティブ率 アジャイル系 245名 146名 59.6% ウォーターフォール 294名 116名 39.5% 差 – – 20.1ポイント アジャイル実践者の約6割(59.6%)が開発生産性に前向きという結果は、ウォーターフォール開発者(39.5%)と比べて20.1ポイントも高い数値でした。 さらに、実際の取り組み状況を見てみましょう。 開発手法別の開発生産性向上への取り組み状況の比較 フレームワーク 対象者数 取り組み実施者数 取り組み率 アジャイル系 245名 117名 47.8% ウォーターフォール 294名 105名 35.7% 差 – – 12.1ポイント アジャイル系では47.8%が実際に取り組みを実施しているのに対し、ウォーターフォールでは35.7%にとどまっています。しかし、ポジティブ印象の差(20.1ポイント)に比べて、実際の取り組み率の差(12.1ポイント)は小さいことが分かります。 つまり、アジャイル実践者は「開発生産性」に対して前向きな印象を持っているものの、実際の取り組みに落とし込めていない人が多いということです。ポジティブな印象を持つ59.6%のうち、実際に取り組んでいるのは47.8%。この差は何を意味するのでしょうか? 前回の記事で指摘した「測定指標の混乱」を考慮すると、このギャップの原因が見えてきます。実際、組織が重視する指標は千差万別です。 コード行数、バグ数、残業時間、機能数、ストーリーポイント──組織によって測定する指標はバラバラで、業界全体で「何を測るべきか」の共通認識が欠けています。DORA指標(デプロイ頻度、リードタイム、MTTR、変更失敗率)の認知度がわずか4.3%という事実も、この混乱を裏付けています。 アジャイル実践者の多くは開発生産性の重要性は理解しているものの、「何を測るべきか」「どう測るべきか」が分からず、結果として行動に移せていない可能性があるのです。 なぜアジャイル実践者は開発生産性に前向きなのか アジャイルの価値観と生産性改善の親和性 なぜアジャイル実践者の方が前向きなのでしょうか。私の経験から考えると、アジャイルの実践と生産性改善の考え方には、次のような共通点があるのかもしれません。 1. 継続的な改善が文化として根付いている スプリントやイテレーション(短期間の開発サイクル)ごとにレトロスペクティブで定期的に振り返り、改善を繰り返す。この習慣により、「生産性を向上させる」という考え方が自然に受け入れられています。 2. 測定と可視化が日常的な実践 ベロシティ、バーンダウンチャート、イテレーション完了率など、アジャイルチームは様々な指標を日常的に活用しています。そのため、「測定する」ことへの心理的抵抗が少ない。 3. 変化への適応力 「変化を歓迎する」というアジャイルの原則により、開発生産性という概念も「改善の機会」として前向きに捉えられます。 4. チームの自律性と当事者意識 アジャイルでは、チームが自ら課題を発見し解決策を考えます。開発生産性も「上から押し付けられる」ものではなく、「自分たちが主体的に改善する」ものとして受け止められています。 Kent Beck氏が語る測定の本質 ── 「測定が目標になると、システムは歪む」 しかし、アジャイル実践者の59.6%が前向きだという事実は、彼らが「正しく」生産性を理解していることを意味するのでしょうか? 実は、この問題について、アジャイル界のレジェンドであるKent Beck氏が重要な示唆を与えています。19年ぶりに来日し、開発生産性Conference 2025で登壇した彼は、測定と生産性の本質的な問題について警鐘を鳴らしました。 Kent Beck 氏(開発生産性Conference 2025にて) Kent Beck氏は「グッドハートの法則」を引用しながら、こう語りました。 "When a measure becomes a target, it ceases to be a good measure. If we exert pressure on that system, the regularity will disappear. It's worse than that. If we exert pressure on that regularity to make things better, we will destroy the system that created that regularity in the first place." 「測定が目標になると、それは良い測定ではなくなります。システムにプレッシャーをかけると、規則性は消えます。それよりも悪いことに、物事を良くするためにその規則性にプレッシャーをかけると、最初にその規則性を作り出したシステムを破壊してしまうのです」 プルリクエストの例を挙げて、具体的に説明しています。 "I'm going to take my pull request that made some sense and I'm just going to slice it up. Their less readable leads to less cooperation leads to more waste leads to fewer pull requests. So by applying pressure to the software development process to make it better, we have made it worse." 「理にかなった1つのプルリクエストを細かく分割します。読みにくくなり、協力が減り、無駄が増え、プルリクエストが減ります。ソフトウェア開発プロセスにプレッシャーをかけて改善しようとすることで、悪化させてしまったのです」 このような単一メトリクスの問題に対して、「では複数のメトリクスでバランスを取ればよいのでは?」という反論が予想されます。Kent Beck氏は、この点についても次のように警告しています。 "People say well you need a balanced set of metrics. That doesn't solve the problem. Every metric that you introduce is going to distort the system that you're working in in ways that aren't what you want it to be." 「『バランスの取れたメトリクスのセットが必要だ』と言う人もいます。しかし、それでは問題は解決しません。導入するすべてのメトリクスは、望ましくない方法で作業しているシステムを歪めます」 つまり、メトリクスを増やしても、歪みが複雑化するだけで根本的な解決にはならないということです。これは、日本の組織でよく見られる「各チームが異なるKPIを追求する」状況と重なります。 ただし、Kent Beck氏自身も 「測定自体は極めて価値がある」 と強調しています。 "I've been measuring my own software development process as long as I've been developing and I find it extremely valuable to turn what I'm doing into numbers that I can analyze and interpret." 「私は開発している限り、自分のソフトウェア開発プロセスを測定してきました。私がしていることを分析し解釈できる数字に変えることは非常に価値があると思います」 つまり、問題は測定そのものではなく、 何を測るか と どう使うか なのです。 アジャイル実践者の「前向きさ」に潜む3つの勘違い Kent Beck氏の警告を踏まえると、アジャイル実践者の「前向きさ」には次のような勘違いが潜んでいる可能性があります。 1. ベロシティ=生産性という誤解 ベロシティが上がると「生産性が向上した」と感じてしまいがちです。しかし、ベロシティはあくまでもチーム内での前イテレーションとの相対比較でしかなく、チーム間の比較や組織全体の生産性を示す指標ではありません。さらに、ストーリーポイントのインフレーション(見積もりの甘さ)や、価値の低いタスクの量産でも数字は上がります。Kent Beck氏が指摘するように、これはまさに「測定が目標になった」状態です。 2. プロセスの遵守をアウトカムと混同 アジャイルの「儀式」を正しく実行していることと、実際に価値を生み出していることは別物です。毎日スタンドアップをやり、レトロスペクティブを欠かさず、バーンダウンチャートが美しい右肩下がりを描いていても、それは「プロセスを守っている」だけかもしれません。顧客が本当に必要としている機能を届けているか、ビジネスアウトカムにつながっているか、技術的負債を積み上げていないか──これらの本質的な問いを忘れ、「アジャイルをちゃんとやっている」ことに満足してしまうリスクがあります。 3. 複数メトリクスの罠 ── なぜ全体最適が失われるのか 日本の組織では、各チームが自分たちの領域で完璧を追求する傾向があります。開発チームはベロシティを上げ、QAチームはバグ検出率を誇り、運用チームは安定性を守る。それぞれが「うちのチームは生産性が高い」と思っています。しかし、これはまさにKent Beck氏が警告する「バランスの取れたメトリクス」の問題です。各チームが異なるメトリクスを最適化することで、システム全体に複雑な歪みが生じます。開発が早くても、QAで長時間滞留し、運用への引き渡しで調整に時間がかかり、結局顧客に価値が届くまでのリードタイムは改善されない。 Kent Beck氏が指摘するように、「システムを歪めるメトリクスが多いほど、理解しにくく影響を与えにくくなる」のです。各チームの「優秀さ」が、かえって全体のボトルネックを見えなくし、誰も全体像を把握できない状況を生み出しています。 つまり、アジャイル実践者が「前向き」なのは、 自分たちの測定方法や改善活動が正しいと信じているから かもしれないのです。 何を測るべきか ── Kent Beck氏が示す価値創造の道筋 本調査から明らかになったのは、どの開発手法でも「何を測るべきか」の共通認識が欠けていることです。この根本的な問題について、Kent Beck氏は価値創造の道筋を次のように説明しています。 Kent Beck 氏(開発生産性Conference 2025にて) "We start out with effort... That's effort. We can measure it in time... Now we have some output... But we still haven't created value until the customer does something, behaves in some new kind of way... And finally the value that we created... comes back to the company in terms of increase in revenue, increase in customer satisfaction." (*下図を示しながら)「まず努力(Effort)から始まります。これを時間で測定できます。次に何らかの成果物(Output)が生まれます。しかし、顧客が新しい行動を取るアウトカム(Outcome)が生まれるまでは、まだ価値は生まれていません。そして最終的に、創出された価値が収益増加や顧客満足度向上という影響(Impact)として会社に還元されます。」 Kent Beck 氏のプレゼン資料から引用 (p.8) そして、この価値の道筋における測定の難しさと歪みの関係について、次のように述べています。 "The further over here we are towards effort the easier things are to measure. But also the more likely that measurement is to distort the system... The further over here you are... the harder it is to attribute value to any one person or one team but the less prone that measurement is to distorting the system." 「投入した努力(作業時間など)に近い指標ほど測定は容易ですが、同時にその測定がシステムを歪めるリスクも高まります。一方、創出された価値(ビジネスアウトカム)に近い指標ほど、そのアウトカムを特定の個人やチームに帰属させることは困難になりますが、測定によるシステムの歪みは生じにくくなります」 測定を「コントロール」ではなく「認識」のツールとして ── Kent Beck氏の4つの提言 では、どうすればこの問題から抜け出せるのでしょうか。Kent Beck氏は講演の結論で、4つのアプローチを提示しています。 Kent Beck 氏のプレゼン資料から引用 (p.11) 1. Observe later(後で観察する) 価値連鎖の早い段階(努力やコード量)ではなく、後の段階(アウトカムや影響)を観察することを推奨しています。「開発者1人あたりの利益を見てください」と彼は例を挙げています。 2. Encourage awareness(認識を促す) 「システムを高速化する最良のテクニックの1つは、システムがどれだけ速いかをグラフ化することです」と述べ、可視化によって自然な改善を促すことを提案しています。 3. Avoid pressure(プレッシャーを避ける) 「リーダーとしてプレッシャーをかけないことは最も難しいことです。しかし、プレッシャーをかけると、システムの歪みが生じます」と警告しています。 4. Instill purpose(目的を植え付ける) 「今のような頻度で本番環境のインシデントが発生しない世界は素晴らしいと思いませんか?」という形で、プレッシャーではなく共通の目標として提示することの重要性を語っています。 この観点から見ると、 DORA指標 (デプロイ頻度、リードタイム、MTTR、変更失敗率)も実は「Output」レベルの測定です。これらは「コード行数」のような純粋な努力(Effort)レベルよりは価値に近いものの、依然として「どれだけ速く・頻繁にリリースしたか」を測っているに過ぎません。顧客の行動変化(Outcome)やビジネスへの影響(Impact)を直接測定しているわけではないのです。 それでも、DORA指標には意味があります。なぜなら、これらの指標を プレッシャーツールとしてではなく、チームの健全性を把握し、改善の機会を見つけるための認識ツール として使うことができるからです。 重要なのは、 どんな指標であっても、それを目標化してプレッシャーをかけるのではなく、現状を理解し、チーム自身が改善方法を考えるためのツールとして活用すること です。 アジャイル実践者への提案 ベロシティだけでなく、顧客価値の提供速度を測る チームの指標とビジネス指標を接続する DORA指標やDevExの考え方を取り入れる ウォーターフォール開発者への提案 現在の指標(バグ数、納期)を維持しつつ、先行指標を追加 小さな改善サイクルを導入して効果を検証 リスクを最小化しながら段階的に変化を進める 次回予告 第3回は「 開発生産性を阻む『日本の3大悪習』── 要件定義、会議、コミュニケーションの罠 」をお届けします。 日本の開発現場が抱える構造的な課題と、その改善への道筋を探ります。 第1回、日本の開発現場の「リアル」を数字で見る ── 798名の声から浮かび上がる衝撃の実態 調査全体について 第2回、開発生産性への意外な好印象 ── アジャイル実践者59.6%が前向きな理由 開発手法による意識の違いの本質 第3回、開発生産性を阻む「組織の3大課題」 ── 要件定義、会議、コミュニケーションの問題 取り組みが失敗する本当の理由 第4回、AI時代の技術格差 ── Visual SourceSafe 15.8%が示す変革への壁 なぜ従来型ツールから移行できないのか 第5回、なぜDevExは日本で知られていないのか ── 認知度4.9%が語る未開拓領域 日本の開発者が本当に求めているもの また、ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 Findy で Tech Lead をやらせてもらってる戸田です。 突然ですが皆さんは、イベントに参加することはありますか? コロナ禍を経てオンラインイベントも増えましたし、最近はオフラインイベントも少しずつ戻ってきてるように感じています。 そこで今回は エンジニアの人生を変えたイベント と題して、弊社エンジニア達が過去に参加したイベントの中で、特に印象に残っているイベントを紹介していきます。 それでは見ていきましょう! Hiyoko Developer Meeting TDD Boot Camp 2020 Online #1 RubyKaigi 2022 まとめ Hiyoko Developer Meeting Tech Lead をやらせてもらってる戸田です。 僕が今まで参加して一番印象に残っているのは、Hiyoko Developer Meetingと呼ばれるイベントです。 hiyoko-dev.connpass.com 当時の自分は20代中盤くらいで、会社には先輩しかいない状況でした。同年代のエンジニアとの比較が出来ない状況が長く続き、自分自身のエンジニアとしての立ち位置、そして市場価値を測ることが難しかったのを覚えています。 そんな中、このイベントが開催されました。同年代のエンジニアと交流できるとのことで、すぐに参加申請を押したのを覚えています。 実際に参加して、同年代のエンジニアのみんなと交流して、自分自身の立ち位置と市場価値の現在位置を大まかに把握できましたし、自分のキャリアの方向性の答え合わせが出来ました。 その中でも強烈に覚えているのは、「エンジニアの友人」が出来たことです。 社外の横の繋がりは、転職によって会社が変わっても消えることはありません。当時は違う会社で働いていましたが、今ではファインディで一緒に働いている友人もいます。 彼らと初めて出会うきっかけをくれたこのイベントを、僕は一生忘れないでしょう。 ファインディでも先日、若手エンジニア限定のイベントを開催しました。 findy.connpass.com このイベントに参加してくださった若手エンジニアのみなさんがXのアカウント交換をしている姿を見て、10年前の自分と友人の姿を重ねました。 当時の僕と同じ境遇の若手エンジニアの読者のみなさんも、是非イベントに参加してみてください。 そしてまずは顔見知りを作るところから始めてみてください。その出会いが友人となり、気づいたら同僚となり、戦友と呼べるような関係になるかもしれません。そのきっかけと出会いを作るのに必要なものは、あなたが持つであろう小さな勇気だけです。 TDD Boot Camp 2020 Online #1 Findy Team+を開発しているEND( @aiandrox )です。 私が一番印象に残っているイベントは、「TDD Boot Camp 2020 Online #1」というイベントです。コロナ禍で配信のみのイベントがほとんどの中で、初めて参加した「見るだけではないイベント」でした。 tddbc.connpass.com 当時、私はプログラミングスクールを卒業して、エンジニアとして就職活動をしていた頃です。テストについては興味があるが、チーム開発の経験もなく「良いテスト」がどういったものなのか肌で理解できていませんでした。そんな中で、TDDを実践できるイベントがあるということを知り、勇気を出して参加しました。 実際に参加してみると、想像していた以上に濃い体験が待っていました。 t_wadaさんによる基調講演のライブコーディングでは、FizzBuzzのテストと実装をここまで細かく繰り返すのかと衝撃を受けました。仕様のTODOリストを作成する、まずは落ちるテストから書く、利用者の視点でテストを書く、など、すべてが新しい発見でした。 初めてのモブプロでは、わからないことだらけではあったものの、現役エンジニアの方と話しながらテスト駆動開発を進めることができました。同じコードを見ながらちゃんと会話ができたのと、どう進めていくか相談をして自分の意見が取り入れられた経験が自信にもなりました。 このイベントをきっかけに、私はテストの目的や良さについて自分の言葉で話せるようになりました。それは今も開発スタイルの根源にあります。 振り返ると、あのとき「まだエンジニアでもない自分には無理かもしれない」とひよってしまうのではなく、思い切って参加して本当によかったです。 RubyKaigi 2022 Findy IDを開発しているsontixyou( @sontixyou )です。 私にとっては「RubyKaigi 2022」への参加でした。 rubykaigi.org 当時、私はベンチャー企業でエンジニアとして働いており、Ruby歴は2年でした。 RubyKaigi 2022への参加は、私にとって初めてのテックカンファレンス体験。行きの道中は、参加が楽しみであるのとワクワク感でいっぱいでした。 参加の目的はつぎのものです。 セッションを通じて、Rubyが好きな理由を言語化したい Rubyistのつながりをつくりたい RubyKaigi 2022の3日間、毎セクション何かしらの発表を聞きました。 分からない用語もたくさんありましたし、当時の自分の実力でもなんとか分かる内容もありました。 カンファレンス終了後、私はRubyが好きでプライベートでも仕事でもRubyを使い続けたいと思いました。 しかし、同時に課題も見つかりました。「Rubyの具体的にどんな点が好きなのか」を自分の言葉で説明できなかったのです。Ruby良いよなという感情はあるのに、それを論理的に語る知識と経験が不足していました。 この気づきから、自分のスキルアップのための取り組み方を大きく変えました。 Rubyの動的型付けの柔軟性を客観視できるように静的型付け言語のRustに挑戦 gemの開発を通じて、Rubyの深い知識を身につける 地域のRubyコミュニティに定期的に参加してRubyistと交流することで、自分の考えを深める これらを通じて、ただ「Rubyが好き」から「Rubyのこの部分がこういう理由で素晴らしい」と語れるようになりました。技術的な実力向上はもちろん、自分のキャリアの方向性も明確になったと感じています。 技術カンファレンスは、新しい知識を得る場としてだけでなく、自分の現在地を知り、自分の伸びしろを見つけるチャンスだと思います。 「分からないことがあっても大丈夫」という気持ちで、ぜひ積極的に参加してみてください。きっと、予想もしない成長のきっかけや出会いが見つかるはずです。 最後に、RubyKaigi 2022でスポンサーしていたファインディで現在働いているのはなにかの縁かもしれません。 まとめ いかがでしたでしょうか? 1回のイベントに参加するだけで、学びだけではなく、エンジニアとしてのキャリアや人生に対して大きなヒントを得ることが出来るかもしれません。ぜひ皆さんの思い出のイベントも教えてください。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは。Findy Tech Blog編集長の高橋( @Taka-bow )です。 皆さんは「開発生産性」という言葉を聞いて、何を感じますか? これまで、エンジニアの「開発生産性」という概念に対する理解度や、その活用状況を体系的に調査した事例はほとんどありません。 そこで2025年、ファインディは ソフトウェア開発における「開発生産性」に関する実態調査 を実施し、日本のIT従事者798名にこのテーマを真正面から問いかけました。 【調査概要】 調査対象: ソフトウェア開発(組み込み開発を含む)に直接関わるエンジニア、プロダクトマネージャー、プロジェクトマネージャー、エンジニアリングマネージャー、開発責任者など 調査方法: インターネット調査 調査期間: 2025年4月2日(水)~2025年5月21日(水) 調査主体: ファインディ株式会社 実査委託先: GMOリサーチ&AI株式会社 有効回答数: 798名(95%信頼区間±3.5%) 統計的検定力: 80%以上(中程度の効果量d=0.5を検出) 調査内容: 開発生産性に対する認識 開発生産性に関する指標の活用状況 開発生産性に関する取り組み 開発環境・プロセス評価 組織文化と生産性 その結果は、私たちの想定を大きく覆すものでした。これまで「日本は海外に比べてアジャイルやDevOpsの浸透が遅れている」といった一面的な見方がされがちでした。 しかし、実際に見えてきたのはそれだけではありません。日本の開発現場には、品質へのこだわりやチームワークといった確かな強みがある一方で、それを十分に活かしきれない構造的な課題が浮き彫りになったのです。 まずは今回の調査から見えてきた全体像をお伝えし、その後はシリーズでテーマごとに深掘りしていきたいと思います。 第1回、日本の開発現場の「リアル」を数字で見る ── 798名の声から浮かび上がる衝撃の実態 調査全体について 第2回、開発生産性への意外な好印象 ── アジャイル実践者59.6%が前向きな理由 開発手法による意識の違いの本質 第3回、開発生産性を阻む「組織の3大課題」 ── 要件定義、会議、コミュニケーションの問題 取り組みが失敗する本当の理由 第4回、AI時代の技術格差 ── Visual SourceSafe 15.8%が示す変革への壁 なぜ従来型ツールから移行できないのか 第5回、なぜDevExは日本で知られていないのか ── 認知度4.9%が語る未開拓領域 日本の開発者が本当に求めているもの それでは、第2回以降で深掘りしていく各テーマに入る前に、まずは調査全体を象徴するいくつかの結果をご紹介します。 開発生産性への認識は前向き、でも実践にはギャップが 組織運営の課題が技術的課題を上回る現実 従来型ツールがAI時代の足かせに Developer Experience(DevEx)の低い認知と見えてきた課題 測定指標の混乱 ── 業界全体で「何を測るべきか」が不明確 なぜ変われないのか ── ケイパビリティと体験のギャップ 数字だけでは動けない現場 必要なのは「体験から学ぶ」ステップ 日本の強みを活かしながら 開発生産性への認識は前向き、でも実践にはギャップが 興味深い発見のひとつは、IT従事者の開発生産性に対する認識が予想以上に前向きだったことです。 「開発生産性」という言葉に対してネガティブな印象を持つ人は わずか7.6% 。多くのエンジニアが、生産性向上に対して前向きな姿勢を示していました。 特に注目すべきは、開発手法による意識の差です。 アジャイル実践者の59.6% がポジティブな印象 ウォーターフォール開発者は39.5% に留まる 私は「アジャイル実践者」のほうが、よりネガティブに捉えているのではと予想していたので、これは意外な結果でした。 また、開発生産性向上への取り組みは「実施36.6%」「未実施37.8%」と拮抗している一方で、25.6%が自組織の状況を把握していないという結果が浮かび上がりました。これは、生産性への関心は高いにもかかわらず、取り組みが十分に浸透しておらず、組織内の情報共有やコミュニケーションに課題が残っていることを示しています。 組織運営の課題が技術的課題を上回る現実 開発生産性を阻害する要因を尋ねたところ、技術的な問題よりも組織運営の課題が上位を占めました。 最大の障壁は 「不明確な要件」(53.5%) です。半数以上のIT従事者が、プロジェクトの上流工程に大きな問題を感じています。続いて以下の通りです。 会議が多い 38.7% コミュニケーションの問題 33.6% これらはいずれも組織運営に深く関わる問題であり、しかも長年にわたり繰り返し指摘されてきた課題です。 その根本原因は「やり方を変えないこと」にあるのではないでしょうか。どれほど最新のツールやフレームワークを導入しても、こうした本質的な課題に向き合わない限り、生産性の大幅な向上は望めません。 日本の開発現場は、技術力そのものは十分に備えているにもかかわらず、それを最大限に活かせる土壌が整っていない──そんな実態を映し出しているのかもしれません。 従来型ツールがAI時代の足かせに ソースコード管理ツールの利用状況を見ると、技術格差の深刻さが明らかになりました。 GitHub 30.5% Visual SourceSafe 15.8% Subversion 13.7% GitHubがトップあることは驚きませんでしたが、2012年にサポートが終了したVisual SourceSafeが2位という事実は衝撃的でした。さらにSubversionも含めると、約3割の組織が従来型のバージョン管理システムを使用していました。 これは単なる「古いツールを使っている」という話では済みません。 GitHub CopilotやAmazon CodeWhispererなど、最新のAI開発支援ツールはGitベースのワークフローを前提としています。従来型ツールに縛られている組織は、AI活用による生産性向上の波に乗り遅れるリスクが高いのです。 つまり、現在の技術格差が、将来的にはさらに大きな生産性格差へと発展する可能性があるということです。 Developer Experience(DevEx)の低い認知と見えてきた課題 日本において「Developer Experience(DevEx)」という概念は、まだ広く浸透していません。今回の調査でも、DevExという言葉を知っていると答えたエンジニアはわずか 4.9% にとどまりました。 同じ調査では、DevExの要素であることを伏せたうえで、基盤的な要素の満足度も尋ねました。その結果、以下のようにきわめて低い数値が明らかになっています。 CI/CDパイプライン 満足度14.2% ドキュメント管理システム 満足度17.5% 開発環境整備 満足度24.7% これらの結果は、日本の開発現場におけるインフラ整備の遅れを如実に物語っています。特にCI/CDパイプラインの満足度が14.2%にとどまっているのは深刻です。継続的インテグレーション/デリバリーは現代のソフトウェア開発の基本であるにもかかわらず、8割を超えるエンジニアが不満を抱えたまま日々の開発を続けているのです。 こうした環境の不備は、エンジニアのモチベーション低下を招くだけでなく、生産性そのものにも直結します。ビルド待ち時間、手動デプロイによるミス、ドキュメント不足による知識共有の停滞 ── これらの問題が開発現場を日常的に妨げているのです。 測定指標の混乱 ── 業界全体で「何を測るべきか」が不明確 最後に、最も根本的な問題があります。業界全体で「何を測るべきか」という共通認識が欠けているのです。 実際、組織によって重視する指標は大きく異なります。ある企業はコード行数を追い、別の企業はバグ数を数え、さらに別の企業は残業時間を管理しています。しかし、これらの指標が本当に開発生産性を正しく示しているのか、確信を持てている人はほとんどいません。 世界的に注目されているDORA指標(デプロイ頻度、リードタイム、平均復旧時間、変更失敗率)の認知度がわずか 4.3% にとどまっているという事実も、この混乱を裏付けています。 測定基準が曖昧なまま「生産性を上げろ」と求められても、現場は困惑するばかりです。まるでゴールの見えないマラソンを走らされているようなものです。 なぜ変われないのか ── ケイパビリティと体験のギャップ 調査では、44.3%が「開発生産性を高めたい」と前向きに答えました。 しかし、実際に自社で具体的な取り組みをしていると答えたのは36.6%にとどまります。 ここで重要なのは、この36.6%が必ずしも「正しい指標に基づいて取り組んでいる」とは限らないという点です。測定基準が不明確なままでは、努力が空回りしてしまう危険があるのです。 その背景には、“知識として知っていること”と“実際に体験していること”の間に横たわる、大きなギャップがあります。 数字だけでは動けない現場 たとえば、DORA指標の認知度はわずか4.3%。「デプロイ頻度を上げよう」「リードタイムを短縮しよう」といった施策を伝えても、それがもたらす真の価値──素早いフィードバック、リスク低減、チームの自信向上──を実感したことがなければ、単なる数字遊びにしか見えません。 同じことはCI/CDの整備にも言えます。満足度14.2%という結果は、自動化がまだ十分に根付いていないことを示しています。ビルドやテストが自動化されていれば「コードを書いたらすぐに安心できる」「金曜の夕方でもデプロイできる」──そんな開発体験が得られます。しかし、体験がなければその価値を想像することすら難しいのです。 必要なのは「体験から学ぶ」ステップ 本当に必要なのは、生産性の高い組織が備えている ケイパビリティ(組織能力) を理解し、実際に体験することです。 疎結合なアーキテクチャ :チームが独立して素早く動ける 自動テスト :安心してリファクタリングできる モダンなバージョン管理 :PR・レビュー・CI/CDが可能になる ただし、これらのケイパビリティは一足飛びには身につきません。段階を踏んで育てていくしかないのです。 Visual SourceSafeを利用している組織は15.8%、Subversionを利用している組織は13.7%に上り、両者を合わせると全体の約3割を占めます。つまり、GitHub(30.5%)とほぼ同じ規模で、いまだにレガシー寄りの環境が現場に残っているのです。こうした環境では、PRやコードレビュー、CI/CDパイプラインといったモダンな仕組みを前提とした開発体験を実現するのは難しく、「デプロイを自動化しましょう」と言われても、その基盤自体が存在しません。 だからこそ、小さな一歩から始める必要があります。新しいツールの価値を「頭で理解する」のではなく、まずは「体験する」こと。その実感が、次のステップに進む原動力となります。こうした積み重ねが、最終的に組織全体の変革を実現していくのです。 日本の強みを活かしながら 日本の開発文化が培ってきた 品質へのこだわり や チームワーク は、決して手放す必要はありません。むしろそれを土台にしながら、新しいケイパビリティを段階的に身につけていく。そのプロセスこそが現実的な改善への道筋です。 あなたの組織は今、どの段階にいますか? そして明日から、何を始めますか? この問いへの答えを探るために、次回以降は7回にわたり調査結果をテーマ別に深掘りしていきます。 第2回は「開発生産性への意外な好印象 ── アジャイル実践者59.6%が前向きな理由」を取り上げます。 また、ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で先日、Findy AI Meetupの記念すべき第1回を福岡で開催しましたので、今回はそのイベントの様子や内容を紹介します。 findy-inc.connpass.com 福岡でのイベント開催は実に2年ぶりとなっており、我々も参加者の皆さんにお会い出来ることを楽しみにしていました。 ありがたいことにキャンセル待ちが出るほどに参加申し込みをしていただきました。当日参加くださったみなさま、ありがとうございました! Findy AI Meetupとは? 登壇内容 Nx × AI によるモノレポ活用 ~ コードジェネレーター編 Findy Freelance利用シーン別AI活用例 ファインディ株式会社における生成AI活用までの軌跡 懇親会 まとめ Findy AI Meetupとは? ファインディ株式会社のエンジニアが主催する技術系のオフラインイベントです。 ファインディ株式会社では、生成AIやAIエージェントの活用を通じて開発生産性の向上を目指す取り組みを行っています。このイベントでは、ファインディのエンジニアが社内での実践事例を紹介するとともに、エンジニア同士がつながり、知見の共有や交流を目的としています。 今回のMeetupは初めての開催となっており、登壇者は全員弊社のエンジニアとなっています。 登壇内容 Nx × AI によるモノレポ活用 ~ コードジェネレーター編 まず弊社のフロントエンド テックリードの新福が登壇しました。 弊社のフロントエンドの多くにはNxが採用されています。今回はNxを採用してきたことが、生成AIの時代にマッチしていたというお話をしました。 tech.findy.co.jp これまで弊社では、NxのGeneratorを用いて開発効率の向上に取り組んできました。NxのGeneratorは強力な機能を持つ反面、覚えることも多く、初心者がとっつきにくいというのが課題でした。 tech.findy.co.jp 最近のNxは生成AIとの連携が強化されており、中でもNx MCPの登場によって、モノレポ内の情報を生成AIのコンテキストとして利用できるようになりました。 Nx MCPの素晴らしい点は、モノレポ内のプロジェクトやNxのGeneratorを自然言語で操作できることにあります。これにより、複雑なコードを書かなくても柔軟で対話的なコード生成の業務フローが実現可能になりました。 例として今回は、CopilotやClaude CodeのスラッシュコマンドからNx MCP + Nx Generatorを起動させる方法を紹介しています。 生成AI時代の業務標準化は、もうすぐそこに来ているのかもしれません。 今回はNxのGeneratorに焦点を当ててお話しましたが、Nx公式のCIサービスである「Nx Cloud」にもAI機能が続々と追加されているので、いつかご紹介できればと思います。 Findy Freelance利用シーン別AI活用例 次にフロントエンドエンジニアの主計が、Findy Freelanceチームのコーディング以外でのAI活用事例をいくつか紹介しました。 1つ目は、不具合調査時の Ask Devin の活用です。 不具合報告があった際に、不具合内容をAsk Devinに調査を依頼しています。 対象となるリポジトリを複数選択できるため、原因箇所の特定や切り分けが素早くできるようになっています。 専門領域に関わらず一次調査ができるのもありがたいです。 2つ目は、dependabotのAIレビューです。 最初はDevinのPlaybookを利用して週1でまとめてレビューを依頼していましたが、 Claude Code Base Actionを利用して随時自動で行うように改善しました。 精度も上がり、日々の作業の負担が軽減されています。 3つ目は、AI によるリファインメントの実施です。 PdMとエンジニアで行っているリファインメントの文字起こしデータをNotebookLMに追加して、 リファインメントの観点を洗い出しプロンプト化しています。 ラベル付与をトリガーとすることで、PdMメンバーが任意のタイミングでAIリファインメントを実施できるようになり、リファインメントの負担を軽減できています。 アウトプットに関しては文量が多かったり、肯定的なフィードバックになりがちだったりと課題があるので、引き続きプロンプトを調整しています。 チームでAI活用を進めるため、10分勉強会(5分LTを正社員メンバーで持ち回り)で実施しています。 継続することを優先し、スキップ可や記事紹介可などハードルを下げて取り組んでいます。詳細はこちらの記事をご覧ください。 findy-code.io 普段の業務にAIを活用するために、AIのキャッチアップと同時に、どの業務にどうAIを活用するか日々チーム全体で考えることが大事だと考えています。 引き続きAIを積極活用していくので、良い事例があれば紹介していきたいと思います。 ファインディ株式会社における生成AI活用までの軌跡 最後に、テックリードの戸田が、「ファインディ株式会社における生成AI活用までの軌跡」と題しまして、弊社が生成AIで結果を出せるようになるまでの軌跡を紹介しました。 まず弊社の開発組織の開発文化を支えている考え方やテクニックをいくつか紹介しました。以前にこのテックブログでも紹介した内容もあります。 特にタスク分解とPull requestの粒度は重要です。 tech.findy.co.jp tech.findy.co.jp また、統一されたコーディング規約や設計、ドキュメントを整備することも文化として根付いています。特にドキュメント整備は重要で、弊社ではJOIN初日にPull requestを出せるようにしています。 このように、弊社の開発文化を支えているテクニックはコードを書く前の事前準備を重要としており、また、環境や自動化、スピードに拘りを持っています。 これは小さなことをコツコツと積み重ねることでしか実現できませんが、それをしっかりやり切ってきた歴史があり、その積み重ねこそが開発組織の文化となっています。着実に積み重ねたものは強いのです。 次に、弊社が生成AIを活用するために取り組んだ内容を紹介しました。 既存コードの最適化や不要なコードの削除、テストコードの整備やドキュメンテーションなど、生成AIのガードレールとなる要素の整備に関して紹介しました。 また、生成AIに命令を投げる際は、可能な限りスコープを限定的にして、具体的な内容を段階的に渡すのが良いとされています。そのため、弊社で取り組んでいたタスク分解のスキルが重要となるシーンが増えました。 ここまで読んだ読者なら気付いた方もいるかもしれません。そうです。弊社の開発組織の開発文化は、生成AIが流行するずっと前から生成AIフレンドリーな文化となっていたのです。 今までの開発組織に生成AIを足した。ということではなく、今までやってきたことの延長線上に生成AIが乗っかってきた。という表現が近いかもしれません。そのため、生成AIを導入したことで一時的に生産性が落ちた。といった光景は、弊社ではほとんど見られなかったのです。 今までの積み重ねが、結果的に生成AIとの協業を可能としていました。もちろんガードレール整備がまだ行き届いていない箇所もあります。しかしながら、そこの整備に対して投資をするという意思決定が当たり前となっている開発文化でもあります。 このあと、生成AI時代の弊社の開発現場の様子をいくつか紹介させてもらいましたが、これはまた別の記事でも紹介できればと思います。 懇親会 登壇発表後は参加者の皆さんと懇親会を開催しました。 懇親会では「パックマンルール」をお願いしました。懇親会で誰かと話すときは新しい人が会話に入れるように、一人分のスペースを空けて話しましょう。というルールです。 生成AI活用における悩みや知見を意見交換して、楽しんでいただけたようです。 まとめ いかがでしたでしょうか? 当日、イベントに足を運んでくださった参加者のみなさん、本当にありがとうございました。頂いたアンケート結果を、次回開催の参考とさせていただきます。 次回開催は9月前後を予定しております。残念ながら今回のイベントに参加出来なかったみなさんも、次回イベント開催時には是非ご参加ください! 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中でこのたび、Findy AI Meetupの記念すべき第1回を、2025年8月4日(月)に福岡にて開催することとなりました! findy-inc.connpass.com 今回は、このイベントの紹介をしたいと思います。それでは見ていきましょう! Findy AI Meetupとは? 登壇予定 Nx × AI によるモノレポ活用 ~ コードジェネレーター編 Findy Freelance利用シーン別AI活用例 ファインディ株式会社における生成AI活用までの軌跡 まとめ Findy AI Meetupとは? ファインディ株式会社のエンジニアが主催する技術系のオフラインイベントです。 ファインディ株式会社では、生成AIやAIエージェントの活用を通じて開発生産性の向上を目指す取り組みを行っています。このイベントでは、ファインディのエンジニアが社内での実践事例を紹介するとともに、エンジニア同士がつながり、知見の共有や交流を目的としています。 福岡でのイベント開催は実に2年振りとなっており、我々も参加者の皆さんにお会い出来ることを楽しみにしています。 登壇予定 Nx × AI によるモノレポ活用 ~ コードジェネレーター編 弊社では、ほぼ全てのフロントエンドでNxによるモノレポ管理が採用されています。 tech.findy.co.jp tech.findy.co.jp 最近のNxは生成AIとの連携が強化されており、中でもNx MCPはモノレポ内の情報を生成AIのコンテキストとして利用できるなど非常に便利です。 今回は、NxのGeneratorをより柔軟かつ対話的に利用できるよう、Nx MCPや プロンプトファイル を組み合わせ、生成AI時代の業務の標準化を目指したお話を紹介します。 Findy Freelance利用シーン別AI活用例 Findy Freelanceの開発ではコーディング時の生成AI活用はもちろんのこと、 コーディング以外の開発関連業務のなかでも生成AIを活用し業務効率化を図っています。 特長の異なる生成AIをどのように使い分けているか、利用シーン別にご紹介します。 ファインディ株式会社における生成AI活用までの軌跡 「ファインディ株式会社における生成AI活用までの軌跡」と題しまして、弊社が生成AIで結果を出せるようになるまでの軌跡を紹介します。 まず弊社の開発組織の開発文化を支えている考え方やテクニックをいくつか紹介します。 tech.findy.co.jp tech.findy.co.jp その開発文化の上で、どのように生成AI活用を推し進めたのか、現在はどのような開発現場になっているのかを紹介します。 まとめ いかがでしたでしょうか? 会場へのアクセスは天神駅から徒歩3分となっています。また、TVCM公開記念ノベルティや、イベント後半には懇親タイムもご用意しています。 申込みの先着順となっており、ありがたいことに参加枠も残りわずかとなっております。生成AIの活用事例に興味のある方は奮ってご参加ください! イベント参加申し込みはこちらから ↓ findy-inc.connpass.com みなさんにお会いできることを楽しみにしています!
アバター
こんにちは。ファインディでソフトウェアエンジニアをしている千田( @_c0909 )です。 2025年3月末頃からファインディに導入されたClaude Codeは、私たちの開発フローに大きな変化をもたらしました。特に私が注目し活用を進めてきたのが、カスタムスラッシュコマンドの機能です。 Claude Codeを初めて触った時は、 CLAUDE.md に長文で汎用的な指示を書いてコードを生成していました。しかし、全てのプロンプトを網羅するには限界があり、より効率的な活用方法を模索していました。そんな中で出会ったのが、このカスタムスラッシュコマンド機能です。 この機能は、日々のGit操作やコーディング作業の自動化を後押ししてくれます。本記事では、私が実際にどのようなカスタムスラッシュコマンドを作成し、どのように開発業務に役立てているのかを具体的な事例と共にご紹介します。 Claude Codeのカスタムスラッシュコマンドとは 実際に作成したカスタムスラッシュコマンド ブランチを作成 commitメッセージを作成 Pull Requestを作成 ブランチ, commit, PRの全てを一度に作成 頻出するコードを自動生成 まとめ Claude Codeのカスタムスラッシュコマンドとは Claude Codeでは、 .claude/commands/ ディレクトリにMarkdownファイルを配置することで、個人またはチーム独自のコマンドを作成できます。例えば /create-branch のようなコマンドを実行すると、事前に定義したルールに従ってClaude Codeが作業を進めてくれます。 docs.anthropic.com 実際に作成したカスタムスラッシュコマンド まずはGitのコマンド実行です。Gitの操作は同じ内容を CLAUDE.md にも書いていて、コードを書いてPR作成までの流れを一貫して依頼することもあります。ただ、コーディングとGit操作の工程を分けて、その間に人がチェックした方が手戻りが少ないため、敢えてカスタムスラッシュコマンドとして用意しています。 ブランチ命名やメッセージの作成などは、次のように自動化しています。 ブランチを作成 .claude/commands/git-create-branch.md ## branchを作成 - ブランチ名は [ Conventional Branch ]( https://conventional-branch.github.io/ ) に従う - feature/[FeatureName]-[実装した機能名] 例: feature/admin-user-role-edit-invite-form 毎回悩みがちなブランチ名の命名。Conventional Branchに従っていても、命名するタイミングで手が止まってしまうこともありますよね。このコマンドのおかげでブランチ名を考える手間がなくなり、開発がスムーズになりました。 次の画像は、コマンドを実行した時の結果です。 commitメッセージを作成 .claude/commands/create-commit.md # commitメッセージを作成 ## 実行手順 1. Read @~/.claude/commands/guideline-read-code.md 2. 違反があれば作業を中断 4. ` git status ` でファイルを確認 5. [ Conventional Commits ]( https://www.conventionalcommits.org/en/v1.0.0/ )に従ってコミットを実行 ## 形式の指定 - type(scope): subject の形式に従う - タイトルは50文字以内、本文は72文字程度で改行 - 動詞は原形を使用(add, fix, updateなど) - scope は原則記述するが、適切なものがない場合は省略可 - コミットメッセージは小文字で始める ## 実装とテストが含まれる場合の優先ルール - 実装とテストコードが含まれている場合、typeはtestよりもfeat/fixを優先する このコマンドの特徴は、コミット前に必ずコーディングガイドラインをチェックすることです。手順1の Read @~/.claude/commands/guideline-read-code.md の部分で読み込ませてます。 例えば、Reactのテストコードでhooksの関数を作成した場合、そのテストとしてコールバック関数がパラメータ付きで実行されることなどを確認しますが、実行回数やエラー時のコールバック関数が実行されていないことを必ずセットで検証します。このような内容をガイドラインとして盛り込んでいます。 機械的にできるレビューは、Commit前にClaude Codeが事前チェックすることで、レビューの負荷を下げます。 なお、弊社のテストコードの考え方については Findyの爆速開発を支える「システムを守るテストコード」の実例3選 - Findy Tech Blog で紹介しています。 Pull Requestを作成 .claude/commands/git-create-pr.md # PRを作成 - Read @.github/PULL _ REQUEST _ TEMPLATE.md に従うこと - Draftで作成すること - push時は ` git push -u origin <branch_name> ` のように ` --set-upstream ` を指定すること - コマンドの例: ` gh pr create --draft --title "title" --body "body" ` PRのテンプレートに詳細な情報が記載されているため、ファイルを参照するだけのシンプルな構成です。エディターでもセルフレビューをしますが、GitHubのdiffの方が見やすいため、PRは必ずDraftの状態で作成してセルフレビューを実施するフローを標準化しています。 また、 PULL_REQUEST_TEMPLATE.md には「動作確認」の項目を用意しています。これはブラウザ上で目視で動作確認する目的で、Claude Codeに内容を列挙して貰っています。 一部抜粋すると次のイメージです。 ## 動作確認 - [ ] レスポンシブ対応が正しく動作すること(スマートフォン、タブレット、デスクトップ) - [ ] Xのシェアボタンが正しく表示されること - [ ] 背景色がブレークポイントに応じて適切に変更されること この対応により、特にフロントエンドの実装時はレビュー前にブラウザで動作確認をする時のチェック観点として、PRのレビュアーにも共有しています。 ブランチ, commit, PRの全てを一度に作成 .claude/commands/git-create-branch-commit-pr.md # branch & commit & pr を作成 ## 実行手順 1. Read @~/.claude/commands/create-branch.md を実行 2. Read @~/.claude/commands/create-commit.md を実行 3. Read @~/.claude/commands/create-pr.md を実行 ブランチ作成からPR作成までの一連の作業は、開発サイクルの中で何度も繰り返されます。この定型的なプロセスを自動化するコマンドを作成しています。 開発プロセスの中で事前にタスクを分解し、その粒度に沿ってPRを作成しています。そのため、PRの粒度が小さく、1つのPRに対してコミットは1件が多いです。これにより、ブランチ作成からPR作成までの自動化が容易に実現できています。 タスク分解の詳細は Findyの爆速開発を支えるタスク分解 - Findy Tech Blog で紹介しています。 頻出するコードを自動生成 カスタムスラッシュコマンドは、Git操作だけでなく、具体的なコーディング作業の自動化にも威力を発揮します。私の経験則ではIssueに作成したタスクリストに基づき、小さな単位で具体的なコードを指示すると期待した結果が得られやすいと感じます。 そのため、定型化できる実装はカスタムスラッシュコマンドで対応してもらいます。例えば、フロントエンドの実装では、次のよく使うコードはカスタムスラッシュコマンドで対応しています。 保存ボタンの連打防止の実装 テキスト入力の必須バリデーションの実装 フォーム入力中の離脱防止の実装 .claude/commands/[Repository name]-coding-is-saving.md ## 保存ボタンの連打防止を実装 作業対象のフィーチャー: $ARGUMENTS ### 参考情報 - PRの確認にghコマンドを使うこと - https://github.com/Findy/[リポジトリ名]/pull/111 ### 実装コードの例 < Button priority= "primary" size = "large" disabled = {isSaving} type = "submit" > 保存 </ Button > ### テストコードの例 describe('isSaving', () => { it('should disable save button when isSaving is true', () => { // Arrange setup({ isSaving: true, }); // Act & Assert expect(screen.getByRole('button', { name: '保存する' })).toBeDisabled(); }); it('should enable save button when isSaving is false', () => { // Arrange setup({ isSaving: false, }); // Act & Assert expect(screen.getByRole('button', { name: '保存する' })).toBeEnabled(); }); }); コーディングにおいてカスタムスラッシュコマンドを作成する基準は次の通りです。 3回以上同じような実装に遭遇した プロダクトコードとテストコードを1セットでPRを作成できる 実装内容が分かり切っている このようにClaude Codeに小さな粒度でコードを書いてPRを出して貰いつつ、その間に私は別の作業をします。 Claude CodeのHooksの設定により、コーディングなどの作業が完了したら通知音を鳴らしているため、スムーズに切り替えることができます。 まとめ 本記事では、私が実践しているClaude Codeのカスタムスラッシュコマンド活用術をご紹介しました。Git操作の自動化から、具体的なコーディング作業の効率化まで、多岐にわたる場面でClaude Codeが開発をサポートしてくれています。 カスタムスラッシュコマンドは汎用的な指示よりも、具体的で小さなタスクに特化させて作成することで、その効果を最大限に発揮すると感じています。機械的な作業をClaude Codeに任せることで、私たちはより本質的な開発業務に集中できるように今後も試行錯誤していきたいです。 この記事が、皆さんの開発現場におけるAI活用のヒントになれば幸いです。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そのような状況の中で、MCP(Model Context Protocol)の新バージョンが公開され、いくつかの機能が追加されました。 modelcontextprotocol.io そこで今回は、その中でも特に注目すべき3つの機能について紹介したいと思います。 それでは見ていきましょう! toolの表示名の項目追加 MCPサーバーからの出力データの構造化 Elicitation まとめ toolの表示名の項目追加 MCPサーバーにtoolやpromptを登録する際に、 title を設定することが出来るようになりました。 github.com 今までのMCPサーバーでのtoolの登録は次のようなコードで実行されていました。 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ; import { z } from "zod" ; const mcpServer = new McpServer( { name : "Sample MCP Server" , version : "0.0.1" } ); mcpServer.registerTool( "addition" , { description : "足し算をする" , inputSchema : { a : z.number(), b : z.number() } } , ( { a , b } ) => { return { content : [{ type : "text" , text : String (a + b) }] } ; } ); MCPクライアントからtoolの情報を確認すると、次のような出力になります。 ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │ Tools for sample (1 tools) │ │ │ │ ❯ 1. addition │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │ addition (sample) │ │ │ │ Tool name: addition │ │ Full name: mcp__sample__addition │ │ │ │ Description: │ │ 足し算をする │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ Tool nameに addition が、Full nameに mcp__sample__addition が設定されているのがわかります。 同じMCPクライアントで複数のMCPサーバーに接続した場合、tool名が重複してしまうケースが有り得ます。そのため、Tool nameとは別にFull nameが用意されており、MCPサーバー名とtool名を組み合わせた一意な名前が用意されています。 しかしここで重要な問題が起こります。MCPクライアントによっては、Full nameに文字数制限が存在しており、制限を越えてしまうとMCPサーバーの実行に影響が出ることがあります。とはいえ、tool名はLLMが実行対象を決めるための判断材料となっているため、短縮しすぎることはできません。 そこで今回追加された title の出番です。 title を次のように設定します。 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ; import { z } from "zod" ; const mcpServer = new McpServer( { name : "Sample MCP Server" , version : "0.0.1" } ); mcpServer.registerTool( "addition" , { description : "足し算をする" , inputSchema : { a : z.number(), b : z.number() } , annotations : { title : "add two numbers" , } } , ( { a , b } ) => { return { content : [{ type : "text" , text : String (a + b) }] } ; } ); MCPクライアントでtool情報を再確認すると、次のような出力に変化します。 ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │ Tools for sample (1 tools) │ │ │ │ ❯ 1. add two numbers │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │ add two numbers (sample) │ │ │ │ Tool name: addition │ │ Full name: mcp__sample__addition │ │ │ │ Description: │ │ 足し算をする │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ title を活用することで、Full nameの文字数制限を気にすることなく、よりわかりやすい名前をMCPクライアントに提供できるようになります。 MCPサーバーからの出力データの構造化 MCPサーバーにtool等を登録する際に inputSchema を設定することは以前から可能でしたが、今回のバージョンアップから outputSchema を設定できるようになりました。 modelcontextprotocol.io outputSchema を定義して、MCPサーバーからのresponseに、 content とは別に structuredContent を設定することで、MCPクライアントは構造化されたデータを受け取ることができるようになります。 実際に outputSchema を設定したMCPサーバーのtoolを見てみましょう。 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ; import { z } from "zod" ; const mcpServer = new McpServer( { name : "Sample MCP Server" , version : "0.0.1" } ); mcpServer.registerTool( "addition" , { description : "足し算をする" , inputSchema : { a : z.number(), b : z.number() } , outputSchema : { result : z.number().describe( "Sum of the two numbers" ) } , } , ( { a , b } ) => { const result = a + b; return { content : [{ type : "text" , text : JSON . stringify ( { result } ) }] , structuredContent : { result } } ; } ); toolを登録する際に、 inputSchema だけではなく outputSchema も設定しています。更にtoolのresponseには content に加えて structuredContent を追加しています。 後方互換性を持たせるために、 content には structuredContent をJSON文字列に変換して返します。 これらの設定により、MCPクライアントはtoolの実行結果をより構造化された形で受け取ることができます。 今回の outputSchema と structuredContent の追加により、MCPクライアントとLLMがMCPサーバーからのresponseをより適切に解析して利用できるようになることを期待できます。 Elicitation 最後になりますが、今回のMCPの新バージョンで追加された機能の中でも特に注目すべき機能が Elicitation です。 modelcontextprotocol.io Elicitation を活用することで、MCPサーバーとMCPクライアントの通信中に、ユーザーに追加情報を要求できるようになります。 今まで紹介したMCPの機能とは一線を画しているのでイメージしづらいと思いますので、実際のコードと具体例で説明していきます。 import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js" ; const mcpServer = new McpServer( { name : "Sample MCP Server" , version : "0.0.1" } ); mcpServer.registerTool( "validate_username" , {} , async () => { const elicitInputResponse = await mcpServer.server.elicitInput( { message : "Input your username." , requestedSchema : { type : "object" , properties : { username : { type : "string" , title : "your username" , description : "input your username." } } , required : [ "username" ] } } ); if (elicitInputResponse. action !== 'accept' ) { throw new Error ( "username is required." ); } const userName = elicitInputResponse.content?. [ 'username' ] as string ; if (userName. length > 12 ) { throw new Error ( "username must be less than 12 characters." ); } return { content : [{ type : "text" , text : ` ${ userName } is valid.` }] , } ; } ); elicitInput を呼び出すことで、ユーザーに追加情報を要求できます。GitHub Copilotで実行した場合、次のような表示になります。 usernameを入力するように要求されているので、次のように入力してみます。 追加要求が成功した場合、ユーザーの入力内容を取得でき、その内容を元に処理を続行できます。 今回は入力されたユーザー名の長さをチェックして、12文字以下であれば有効なユーザー名として処理を続行しています。 今回は12文字以内で入力して送信したため、次のような結果になりました。 また、 elicitInput は文字列の入力だけではなく、enumを使って選択式にするといったことも可能です。選択式にすることにより、入力内容からの分岐をより明確にできます。 mcpServer.server.elicitInput( { message : "select period" , requestedSchema : { type : "object" , properties : { period : { type : "string" , title : "Period" , description : "Select the period" , enum : [ "today" , "yesterday" , "this_week" ] , enumNames : [ "Today" , "Yesterday" , "This week" ] } } , required : [ "period" ] } } ); このように Elicitation を活用することで、MCPサーバーからの追加要求を通じて、ユーザーとのインタラクションをより柔軟に行うことが可能になります。MCPサーバーの使い方、作り方、提供内容がより多様化し、ユーザーにとっても使いやすいツールを提供できるようになることが期待されます。 まとめ いかがでしたでしょうか? 今回紹介したMCPの新バージョンでは、 title 、 outputSchema と structuredContent 、そして Elicitation といった重要な機能が追加されました。 これらの機能は、MCPサーバーとMCPクライアントの連携をより強化し、ユーザーにとって使いやすいツールを提供することが期待できます。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは。Developer Productivity Engineer(DPE)兼 Findy Tech Blog編集長の高橋( @Taka-bow )です。 おかげさまで、Findy Tech Blogは2年目に突入しました。 この1年で、私たちのブログは多くのエンジニアやIT業界関係者の皆さんにご愛読いただき、記事の内容もますます多様化・充実してきたと感じています。 日々の開発現場で役立つノウハウや、最新技術のトレンド、エンジニアの日常など、さまざまなテーマを取り上げてきました。 「現場で本当に使える知見がほしい」「他社のエンジニアはどんな工夫をしているのか知りたい」「自分の成長のヒントを探したい」――そんな方々にとって、少しでもヒントや刺激となる記事をお届けできていれば幸いです。 今回は、2025年上半期に特に多くの反響をいただいた記事を、ランキング形式でご紹介します。 技術のトレンドから生産性向上テクニックまで、見逃していた記事が見つかるかもしれませんよ! それでは、2025年上半期のFindy Tech Blogを一緒にふりかえっていきましょう! 2025年上半期トピックス 「テックブログ運営 井戸端会議〜2025年を走り切るために〜」というLT大会を開催 【2025年上半期(1月〜6月)】PV数ランキングTop3 第3位 第2位 第1位 【2025年上半期(1月〜6月)】はてなブックマーク数Top3 第3位 第2位 第1位 おわりに 2025年上半期トピックス 「テックブログ運営 井戸端会議〜2025年を走り切るために〜」というLT大会を開催 年明け早々に「テックブログ運営」という、ありそうでないテーマでLT大会を開催しました。 はじまった〜📝 #techbrew_findy https://t.co/uFBws89kch pic.twitter.com/ERWbz5ZcT2 — ゆーだい@Findy Team+ (@dai___you) 2025年1月27日 LT大会では、株式会社ログラスの粟田さん、株式会社Goalsの今村さん、株式会社リブセンスの鈴木さん、フューチャーアーキテクト株式会社の伊藤さん、株式会社タイミーの吉野さん、ウェルスナビ株式会社の長さんという豪華なメンバーにご登壇いただきました。 テックブログと一口に言っても、その目的や運営の悩みは本当にさまざまであることを、あらためて実感しました。 当日の雰囲気や盛り上がりは、Xのまとめからも感じていただけると思います。 posfie.com ファインディからは、戸田さんが Findy Tech Blog の誕生秘話や立ち上げ時のターニングポイントについて、私(高橋)は運営における定量的な測定目標の考え方や、普段どんな点を意識しているかについてお話ししました。これらは今も変わっていません。資料もぜひご覧ください! speakerdeck.com speakerdeck.com 【2025年上半期(1月〜6月)】PV数ランキングTop3 2025年上半期、Findy Tech Blogには数多くの注目記事が登場しましたが、ここからは、上半期で一番アクセス(PV)のあった記事を紹介します! 第3位 \ 第3位 /13,710 PV ファインディのエンジニアたちが自身の成長に影響を与えた一冊を語る人気シリーズ「エンジニア達の人生を変えた一冊 Part4」がランキング。 記事では、『コンピュータの構成と設計』(通称「パタ&ヘネ」)や『体系的に学ぶ 安全なWebアプリケーションの作り方』、そして『現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法』といった名著が取り上げられており、それぞれがどのようにエンジニアたちの視点やスキルに変化をもたらしたのかが語られています。 とても実直なラインナップでしたが、多くの方に読まれました。ぜひチェックしてみてください! 第2位 \ 第2位 /14,012 PV 2位は、こちらも人気シリーズの「エンジニア達の自慢の作業環境を大公開 Part6」でした! 第6弾となるこの記事では、ファインディエンジニアの安達さん、土屋 (しゅんそく)さん、秋田さんの3名それぞれが、生産性向上と快適性を追求した作業環境を詳しく紹介しています。単なるガジェット紹介にとどまらず、各エンジニアがどのような思想で作業環境を構築しているかが詳しく語られています。生産性向上、身体への配慮、空間の美しさやコストパフォーマンスなど、それぞれ異なる優先順位で環境を整えており、エンジニアの多様な働き方スタイルが見えてくる内容となっています。 第1位 \ 第1位 /14,743 PV 2025年上半期、最も多くの方に読まれた記事は「【エンジニアの日常】これが私の推しツール!〜日々の開発を豊かにするおすすめツール〜 Part2」でした。 エンジニアの日常シリーズの人気企画「推しツール」第2弾。Findyのエンジニアたちが日々の開発で愛用しているツールやOSSを紹介し、Neovimやlazygit、Raycastなど、業務効率化に役立つツールの活用法やおすすめポイントを詳しく解説しています。他のエンジニアの工夫やツール選びを知りたい方におすすめの記事です。 2025年上半期のトップ3は、いずれも【エンジニアの日常】シリーズからのランクインとなりました。 【2025年上半期(1月〜6月)】はてなブックマーク数Top3 続いては、はてなブックマーク(はてブ)の数が多かった記事のランキングをご紹介します。 PVランキングとはまた違った切り口で、読者の皆さんが「あとでじっくり読み返したい」「何度も参考にしたい」と思った記事が上位に並びました。 日々の業務や学びの中で役立つと感じていただけた記事が多くランクインしているのではないでしょうか。 それでは、はてブ数Top3を見ていきましょう! 第3位 \ 第3位 /131 users Findyの爆速開発シリーズの一環として、生成AI活用の実践編を紹介しています。MCPサーバーの作成を通じて、実際の開発現場でどのようにAIを活用しているか、具体的な実装方法や効果について詳しく解説しています。AI技術を活用した開発効率化に関心のあるエンジニアにおすすめの記事です。 第2位 \ 第2位 /136 users PVランキングでも3位に入った人気シリーズ「エンジニア達の人生を変えた一冊 Part4」が、はてブランキングでも2位にランクイン! 第1位 \ 第1位 /190 users 2025年上半期、最も多くのはてブが付いた記事は「Findyの爆速開発を支えるタスク分解」でした! ファインディの開発チームが実践している効率的なタスク分解手法について詳しく解説。複雑な機能開発を小さな単位に分割し、段階的に実装していくことで、開発速度と品質を両立させる方法を紹介しています。開発生産性向上に関心のあるエンジニアやマネージャーに特に人気の記事となっています。 おわりに 2025年上半期のトピックスや、公開した35本の記事の中から注目の内容をランキング形式でご紹介しました。ここでご紹介しきれなかった記事もたくさんありますので、ぜひ他の記事もあわせてご覧いただければと思います。 今後も新しい技術への挑戦や、ファインディならではの開発の取り組みについて、積極的に発信していきます。 また、読者の皆さんからのコメントやSNSでの反応は、私たち編集部にとって大きな励みです。 これからも「面白い!」「参考になった!」と思っていただける記事をお届けできるよう、ファインディエンジニア一同取り組んでまいります。 引き続きFindy Tech Blogをよろしくお願いいたします。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募ください。 herp.careers
アバター
こんにちは。データエンジニアの田頭( tagasyksk )です。 本記事では、MCPとAIエージェントを活用して、複数CRMの顧客情報を横断的に検索できるようにした事例をご紹介します。 背景 システム構成図 技術選定 エージェント間連携の簡易さ Google Cloud統合 MCP Toolbox for Databasesによる簡単なBigQuery接続 工夫した点 オーケストレーションの設計 ツールを搭載したサブエージェントの呼び出しについて Slack統合 導入後の効果 今後の展望 終わりに 背景 ファインディでは、エンジニア組織をあらゆる場面で支援するため、複数のプロダクトを展開しています。 事業成長に伴う課題として、お客様の大切な情報がプロダクト毎にサイロ化してしまう状況が起きました。 そこで、この課題を解消し、一社でも多くのお客様にファインディの価値を届けるため、CRMに蓄積されていた顧客情報をBigQueryに集約し、部門横断で利用できる「共通企業マスタ」を構築しました。 これにより、全部門が常に同じ最新の顧客情報を参照できるようになり、スムーズな連携が可能な体制を整えました。 しかし、この共通企業マスタをどのようにセールスチームやCSチームに届けるかが新たな課題となりました。 全員にSQLを書かせるのは現実的でなく、新しい分析インターフェースを作るのも工数がかかります。そこで、MCPとAIエージェントを活用したSlack上での企業検索システムの構築に取り組みました。 システム構成図 Slackとソケットモードを利用して疎通するAIエージェントサーバーと、後述するBigQueryのMCPサーバーをCloud Runのマルチコンテナ構成を利用してホスティングしています。 技術選定 AIエージェントのフレームワークには、GoogleからリリースされているAgent Development Kit(ADK)を採用しました。 google.github.io ADKを選定した理由は次の通りです。 エージェント間連携の簡易さ Google Cloud統合 MCP Toolbox for Databasesによる簡単なBigQuery接続 エージェント間連携の簡易さ ADKでは、次のようにシンプルなコードでエージェント間でのオーケストレーションを実装できます。 今回のケースでは、企業の業務情報や従業員数をWEBから取得したいユースケースがあったので、Google検索ができるエージェントをサブエージェントとして実装しています。 # Google検索で企業の情報を取得するエージェント google_search_agent = LlmAgent( model= "gemini-2.5-flash" , name= "google_search_agent" , description= "A helpful AI assistant that can search company information from google." , instruction=GOOGLE_SEARCH_AGENT_INSTR, tools=[google_search], ) root_agent = LlmAgent( model= "gemini-2.5-pro" , name= "company_master_agent" , description= "A helpful AI assistant that can search company." , instruction=ROOT_AGENT_INSTR, sub_agents=[google_search_agent] #Google検索エージェントをサブエージェントとして追加 ) タスクごとに細かくサブエージェントを立てられるため、非常に見通しの良いエージェントシステムが構築できます。 Google Cloud統合 データ基盤をBigQueryで構築しており、Geminiも活用している弊社にとって、権限やホスティングに必要な知識を新しくキャッチアップする必要がないのはかなり大きかったです。 MCP Toolbox for Databasesによる簡単なBigQuery接続 MCP Toolbox for Databasesでは、次のようなyamlファイルを定義するだけで簡単にBigQueryへの接続情報をMCP化できます。 my-bigquery-source : kind : bigquery project : ${your_project} location : asia-northeast1 toolsets : search_company : - search-company-by-name tools : search-company-by-name : kind : bigquery-sql source : my-bigquery-source description : 企業情報を企業名から検索する。 parameters : - name : company_name type : string description : 企業名 statement : SELECT * FROM `${your_dataset}.companies` WHERE company_name LIKE CONCAT('%', @company_name,'%'); MCPサーバーは、次のようなコマンドで簡単に起動できます。 containers: - image: us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest name: toolbox args: - "toolbox" - "--tools-file" - "/app/tools.yml" - "--address" - "0.0.0.0" - "--port" - "5001" エージェントからは次のように参照させると、yaml上で登録したtool(今回は search-company-by-name )を使えるようになります。 from toolbox_core import ToolboxSyncClient toolbox = ToolboxSyncClient( "http://localhost:5001" ) search_company_tools = toolbox.load_toolset( "search_company" ) agent = LlmAgent( model= "gemini-2.5-pro" , name= "company_search_agent" , description= "A helpful AI assistant that can search company in BigQuery" , tools=search_company_tools ) このように事前にBigQueryとの接続を定義しておくことで、意図したSQLを使ってデータにアクセスさせる事ができ、不要なデータベースの参照や誤ったコマンドを防ぐことができました。 工夫した点 オーケストレーションの設計 メインエージェントのInstructionはサブエージェントのユースケースのみを記載し、BigQueryやGoogle検索の具体的な利用方法はサブエージェントのInstructionに記載しています。 これにより、メインエージェントは全体のオーケストレーションに集中し、各サブエージェントは専門的なタスクに特化できるような設計と なっています。 ツールを搭載したサブエージェントの呼び出しについて 2025年7月現在、ビルトインツールやPythonの関数で定義したツールを搭載したエージェントを2つ以上同時にサブエージェントとして呼び出すことができません。 github.com エラー回避策として、エージェントをToolとして呼び出すAgentToolというラッパーを使っています。 # toolを持ったサブエージェントを定義 google_search_agent = LlmAgent( ~~~, tools=[google_search], ) bigquery_search_agent = LlmAgent( ~~~, tools=[bigquery_search], ) # AgentToolでラップ google_search_agent_tool = AgentTool(agent=google_search_agent) bigquery_search_agent_tool = AgentTool(agent=bigquery_search_agent) # メインエージェントからはツールとして参照 root_agent = LlmAgent( ~~~, tools = [google_search_agent_tool, bigquery_search_agent_tool], ) Slack統合 新しいツールを導入することで利用者の負担を増やすことを避けるため、既に社内で日常的に使用されているSlack上でやりとりできるシステムを構築しました。 ソケットモードで送信されてきたメッセージでエージェントを起動し、返答をSlackに返却するMCPクライアントを実装しています。 class SlackToADKClient : """Slack メッセージを ADK エージェントに橋渡しする MCP クライアント""" def __init__ (self): self.slack_app = AsyncApp(token=SLACK_BOT_TOKEN) self.session_service = InMemorySessionService() async def handle_slack_message (self, event, say): """Slackメッセージイベントを処理""" user_id = event.get( "user" ) message_text = event.get( "text" , "" ) # エージェントに問い合わせ response = await self.query_adk_agent(message_text, user_id) await say(text=response) async def query_adk_agent (self, message: str , user_id: str ): """エージェントにクエリを送信""" # セッション管理 session = await self.session_service.get_or_create_session(~~~) runner = Runner( agent=self.company_agent, session_service=self.session_service, ) # エージェントの実行 events = runner.run_async(~~~) # ~~~応答処理~~~ return response_text Slack側からは、Slack Botにメンションする形で簡単に企業情報を検索できるようにしました。 企業名で検索すると共通企業マスタの内容を回答してくれ、かつ事業内容などの企業マスタに含まれない情報はGoogle検索をベースにして回答してくれるようになっています。 導入後の効果 運用開始から1ヶ月で、インサイドセールスやカスタマーサクセスのメンバーの40%近くに利用されています。 ユーザーからは次のような声をいただきました。 各サービスごとの社内担当者がすぐわかるようになり、社内連携が迅速になった Slackで情報の確認ができるため、展示会やイベントの会場からスマホで企業の情報を得られるようになった 一方で、検索機能については次のフィードバックもいただいています。 全角アルファベットで検索したら、共通企業マスタ上では半角で登録されていて検索できなかった 同一会社名で重複しているレコードが表示され、どちらが正しいかわからない この課題については情報源である共通企業マスタの品質向上によって解決していけるものです。データ品質のテストをより厚くしたり、各CRMの担当者と協力してデータクレンジングを進めることで改善を進めています。 今後の展望 現在の検索機能をベースに、さらなる機能拡張を計画しています。 例えば、現在は企業名に基づいた検索のみ実装していますが、企業マスタに存在する様々なカラムから検索フィルタをエージェントが自動で作成し、営業リストとして提供する機能などを考えています。 終わりに いかがでしたでしょうか?今回は弊社でのMCPとAIエージェントの活用について書きました。 AIエージェントの活用は、単純な検索だけでなく、将来的にはより高度な顧客分析や提案機能へと発展させることができる可能性を秘めています。今回の事例が、同様の課題を抱える組織の参考になれば幸いです。 弊社ではデータ基盤を共に育てていくメンバーや、AIエージェントなどのデータ利活用を推進するメンバーを募集しています。少しでも興味が湧いた方はカジュアル面談お待ちしております! herp.careers herp.careers
アバター
こんにちは。こんばんは。 開発生産性の可視化・分析をサポートする Findy Team+ 開発のフロントエンドリードをしている @shoota です。 ファインディのフロントエンドでは多くのプロダクトで Nx を用いたモノレポを構築しています。 tech.findy.co.jp Findy Team+ のフロントエンドもNxを採用し、各パッケージ間の依存関係の管理やライブラリのマイグレーションなどの恩恵を受けています。 なかでも強力なキャッシュ機構をベースとしたCIの高速化はなくてはならない存在となっています。 以下は、このブログの執筆時点での Findy Team+ のフロントエンドリポジトリが実行するCIの統計情報です。 Team+ の CI実行 直近30日間でCIの実行回数は2500回、平均時間は7分です。 そしてNxの機能によって 削減された実行時間はなんと167日分(約4000時間) にもなります(キャッシュはネットワークで共有されるので開発者のローカルでも有効です)。 しかし我々はこのような強力かつ高速なCIの環境を常に維持し続けていたわけではありません! 過去には平均のCI実行時間が13分以上かかっており、開発速度に大きな影響を及ぼしていました。 そこで今回はNxでのキャッシュ率を高め、CI時間を短縮するためのNxをベースとしたリアーキテクチャの実例についてご紹介したいと思います。 CI高速化のためのリアーキテクチャ ページレイアウトモジュールの分離、ライブラリ化 共有モジュールの分割 翻訳アーキテクチャの刷新 UI コンポーネントのモジュール分割 コードベースとCI時間の比較 まとめ CI高速化のためのリアーキテクチャ 2024年のはじめ頃から、Team+のフロントエンドのCI時間は伸び続ける傾向が見え始めてきました。 プロダクトの肥大化と複雑化、そして開発メンバー数の急増によって、コードベースの増加速度も急成長をしていました。 「開発速度が上がるほどCI時間が伸びる」というアンチパターンを打開すべく、1年以上をかけてモノレポの内部構造の再設計をしました。 ページレイアウトモジュールの分離、ライブラリ化 共有モジュールの分割 翻訳アーキテクチャの刷新 UI コンポーネントのモジュール分割 今回はこの内容を紹介していきたいと思います。 ページレイアウトモジュールの分離、ライブラリ化 まず初めに目をつけたのがページレイアウトに関連するモジュールでした。Team+のサイドナビゲーションやヘッダーUIなどのページ全体のレイアウトに関わるコードです。 これらはモノレポの共有モジュールの中に配置されていましたが、その役割ゆえにほぼすべての画面で利用します。 レイアウトを変更することは稀ですが、共有モジュール内にレイアウトが所属することでモジュール全体に依存関係を持ちます。このときレイアウト以外のコードを変更をすると、レイアウトを利用しているものすべてが依存関係にあるため、全画面のテストが発生してしまいます。 そこでレイアウト関連のコードを別モジュールに分離して、依存関係が集中しないようにしました。 図1. レイアウトモジュール分離 共有モジュールの分割 次にレイアウトを分離した後の共有モジュールを更に分割し、変更の影響範囲を効率化しました。 共有モジュールの中には古くからあり、成熟しており、そしてテストの重いものがいくつかありました。このような古参モジュールは多くの機能で利用します。一方で、最近の開発ドメインに向けて作られた新米モジュールも共有モジュールに存在します。 両者が同居していると日々のコード変更頻度と重いテストが複合し、全体効率を下げる要因になっていたため、別居計画を進めました。 図2. 共有モジュールの別居 変更頻度の低い古参モジュールを分離することで、開発を進めているドメインに関連した比較的軽いテストのみがよく回るような構造にできました。 翻訳アーキテクチャの刷新 これまでは通常のモノレポ構造の再設計でしたが、CI時間に最も影響を及ぼしていたのはここで紹介する翻訳システムでした。 Findy Team+ は日本語・英語・韓国語の3言語に対応していますが、これらの翻訳は1つのモジュールで集約管理していました。 しかし機能開発の高速化・大規模化に伴って、翻訳対象の文言も急増し、さらに韓国語対応を追加したことで爆発的な依存関係の連鎖が生まれ、CI時間を圧迫してしまいました。 図3. 翻訳辞書の一元管理 画面が追加されるごとに翻訳辞書が増え、かつ翻訳モジュールの変更が発生するので、全画面のテストが実行されます。 次の画面が追加されるとその前に追加された画面もテスト対象になり、さらに実行時間が伸びます。この繰り返しによってCI時間が指数的に長くなっていきました。 そこで画面個別の辞書を画面モジュールに分散し、それぞれの画面の開発で発生するコード変更が画面モジュールのなかで閉じるようにしました。分散した辞書は画面表示前に動的に読み込んで表示できるような修正も行いました。 図4. 翻訳辞書の分散 画面がどんどん追加されても全画面のテストが起きなくなり、開発速度・並行数が上がってもCI時間が伸びない構造に生まれかわることができました。 共有モジュールの分割とは異なり、依存関係は変更せずにコード変更の発生箇所を移動することで、平均の実行時間を大きく縮めることができました。 UI コンポーネントのモジュール分割 上記の3点の改善によってCI時間は概ね安定して短縮できていましたが、更にTeam+を構成するUI コンポーネントの分離を進めました。 ボタンやフォームなどのプリミティブなUI(HTMLに近いもの)とTeam+特有のセマンティックなUIに分類し、依存の親子関係となるように分けました。 これも先述のようにボタンコンポーネントやフォームなどのプリミティブなUIは変更頻度が少なく、かつ依存度が高いことを見据えた分離です。 UI分離 変更頻度の高いモジュールとそれに依存したモジュールのテストが実行されるので、Nxのキャッシュ率を向上させることができました。 コードベースとCI時間の比較 CI高速化のためのリアーキテクチャの内容をご紹介してきましたが、タイトルの「60万行」にも触れたいと思います。 今回のリアーキテクチャを開始した時点では、Team+のコード量は次のようになっていました。 Language files blank comment code TypeScript 5422 42462 13430 353578 JSON 349 0 0 51694 以下略 SUM: 6212 46170 17230 419602 TypeScriptのコードとして約35万行、翻訳辞書を定義しているJSONを合わせると約41万行です。 これらのコードの 平均のCI実行時間が13分以上 かかっていました。 そして冒頭にも記載したとおり、現在では 平均のCI実行時間が7分程度 になっています。この改善の間にも多くの機能リリースをしてきました。 こちらが現在のTeam+のコード量です。 Language files blank comment code TypeScript 9171 68280 22279 552539 JSON 672 6 0 66888 以下略 SUM: 10453 69658 22424 635517 TypeScriptのコードとして約55万行、翻訳辞書を定義しているJSONを合わせると約62万行です。 つまりコードベースとして約1.5倍の成長をしながら、CI時間を53%程度まで削減できたのです!! まとめ ここまで拝読いただきありがとうございます。 今回は Findy Team+ の開発を支えるCIとその改善内容についてご紹介いたしました。内容を以下3点にまとめてます。 Nxベースのモノレポアーキテクチャを再設計することで変更に依存しない高速なCI環境をつくることができる。 モノレポ間の依存関係と、開発現場のコード変更の傾向をつかむことがCI速度改善のカギになる。 CI速度の改善は規模の大きなコード、組織にとって不可欠な改善のひとつと言える。 なお今回のリアーキテクチャでいちばん大変だったのは、変更対象のCI時間が基本的に長いことでした。 CI時間が長いモジュールを修正し続けているので当然なのですが、効果がでるまでの我慢期間が長かったことは胸に刻みたいと思います。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから herp.careers
アバター
こんにちは。 ファインディ株式会社 で Tech Lead をやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやCursorなど、生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そこで今回は、弊社のGitHub Copilotの活用方法について紹介します。 それでは見ていきましょう! カスタムインストラクション MCP Agent mode Coding Agent まとめ カスタムインストラクション GitHub Copilotを始めとする生成AIツールを効果的に活用するためには、まず最初にカスタムインストラクションの設定が必要不可欠です。 docs.github.com カスタムインストラクションに関しては以前の記事で紹介しておりますので、併せてご覧ください。 tech.findy.co.jp tech.findy.co.jp カスタムインストラクションを設定することで、生成AIがプロジェクトのコンテキストを理解し、より適切な提案を行うことが可能になります。 GitHub Copilotの場合は .github/copilot-instructions.md というファイルをリポジトリに配置するだけで利用することが出来ます。 他にも、実装コード、テストコード、コミットメッセージなど、目的別にカスタムインストラクションのファイルを分けることができるようになっています。 code.visualstudio.com 弊社の場合、ファイルや変数の命名規約に留まらず、コミットメッセージやテストコードについてもカスタムインストラクションに記載しています。 コミットメッセージにSemanticVersionを採用しているケースがあり、リリース時にコミットメッセージを元にリリースノートを自動生成しています。 そのため、コミットメッセージが持つ意味合いが重要となっており、誤ったSemanticVersionになっていた場合はレビュー時に修正依頼を出すこともあります。 しかし、Copilotが作業を行いコミットまで自動で行うケースの場合、AIが生成したコミットメッセージが誤っているケースが出てきました。 そこでカスタムインストラクションに次のようなコミットメッセージのルールを記載することで、Copilotが作成するコミットメッセージに適切なSemanticVersionが設定されるようにしています。 ## コミットメッセージ規約 ### 1. 基本構造 < semantic version > - < type > : < message > ### 2. 例 - major-feat: remove user field from api params - minor-feat: add api for get user list - patch-docs: fix typo in README ### 3. 各要素の説明 #### semantic version https://semver.org/ - major - 互換性のないAPIの変更 - 既存のフィールドの削除 - 既存のフィールドの型の変更 - 必須パラメータの追加 - エンドポイントの削除や名前変更 - minor - 互換性のあるAPIの変更 - 新しいフィールドの追加 - 新しいエンドポイントの追加 - 任意パラメータの追加 - 既存の機能を拡張するが後方互換性を維持する変更 - patch - リファクタリング - ドキュメントの追加、変更 - CI/CDの追加、変更 - コードの意味に影響を与えない変更 #### type - test - テストの追加、修正 - feat - 新機能の追加 - fix - バグ修正 - chore - ビルドプロセスや補助ツールの変更 - docs - ドキュメントの変更 - refactor - リファクタリング - style - コードの意味に影響を与えない変更 - ci - CIに関連する変更 - perf - パフォーマンスを向上させるコードの変更 #### message - 変更内容を要約した72文字以内の英語のメッセージ - 技術用語は英語のままにする カスタムインストラクションには事実のみを簡潔に書くのがポイントです。 複雑で長いルールを適用させたい場合は、具体例を示すと良いでしょう。今回紹介したコミットメッセージのカスタムインストラクションにも具体例を記載しています。 また、カスタムインストラクションは最初に1度作成して完成するようなものではなく、徐々に加筆修正して精度を上げていきましょう。 このように、ドメイン知識やプロジェクトのルールをカスタムインストラクションに記載することで、AIがより適切で自分たちの開発ルールに沿った提案を行ってくれるようになります。 MCP GitHub Copilotや各種AIツールを効果的に活用するためには、MCPの活用も非常に重要になってきます。 tech.findy.co.jp カスタムインストラクションに加え、MCPを活用することで、Copilotが扱う情報の範囲を広げ、より適切な提案やタスクの実行を行うことが可能になります。 例えばGitHubのMCPを利用する場合、次のような記述で設定します。 { " servers ": { " github ": { " command ": " docker ", " args ": [ " run ", " -i ", " --rm ", " -e ", " GITHUB_PERSONAL_ACCESS_TOKEN ", " ghcr.io/github/github-mcp-server " ] , " env ": { " GITHUB_PERSONAL_ACCESS_TOKEN ": " <YOUR_GITHUB_PERSONAL_ACCESS_TOKEN>> " } } } } GitHubのMCPの設定を行い、対象のIssueの情報を取得して、その内容をそのままCopilotに渡すことが出来ます。 Issueに要件やタスクの内容を記載しておくことで、Copilotがその内容を理解し、適切なコードの提案やタスクの実行を行うことが可能になります。 SentryのMCPも同様に活用することが出来ます。次のような記述で設定します。 { " servers ": { " sentry ": { " command ": " uvx ", " args ": [ " mcp-server-sentry ", " --auth-token ", " <YOUR_SENTRY_AUTH_TOKEN> " ] } } } Sentryで障害を検知した際、MCP経由でSentryのIssueの情報を取得して、その内容をそのままCopilotに渡すことが出来ます。その情報を元に、Copilotに原因を特定してもらい、Copilotにコードを修正してもらうことが可能です。 このように、MCPを活用することで、Copilotがプロジェクトやリポジトリ、さらにそれらに関連する情報を取得して、より適切な提案やタスクの実行を行うことが可能になります。 Agent mode GitHub CopilotのAgent modeを利用することで、Copilotが自律的にタスクを実行し、コードの修正や新機能の追加などを行うことが可能になります。 docs.github.com その際にカスタムインストラクションやMCPの設定が非常に重要な役割を果たします。 また、Agent modeを実行する際に、コンテキストを絞ることも非常に有効です。 特定のファイルや、コンテキストを指定することで、Copilotが参照する範囲を絞り込むことに繋がり、結果的に生成AIの提案の精度を向上させることができます。 例えば次のような実装コードとテストコードがあるとします。単純な描画を行うコンポーネントと、それに対するテストコードです。 export const TestComponent = () => { return ( <> < h1 > Test </ h1 > < div > < div > < span > Test Text </ span > </ div > </ div > </> ); } ; import { render } from '@testing-library/react' ; import { TestComponent } from './test.component' ; describe ( 'TestComponent' , () => { const setup = () => { const utils = render( < TestComponent /> ); return { ...utils, } as const ; } ; describe ( 'render' , () => { it ( 'render snapshot' , () => { const { asFragment } = setup(); expect (asFragment()).toMatchSnapshot(); } ); } ); } ); 一見問題ないように見えますが、弊社で開発しているFindy Team+は複数言語での表示に対応しています。そのため、表示されるテキストに翻訳処理を追加する必要があります。 翻訳処理を追加して、それに伴ってテストコードも修正するのは手間がかかりますが、ルールさえ覚えれば単純作業になります。こういったケースはAIエージェントの得意分野です。 翻訳処理を一気に追加したい場合、まずカスタムインストラクションに次のような記述を追加します。 # 翻訳処理 - 辞書データを定義する - json 形式のファイルで定義する ```json:libs/feature-hoge/src/lib/locales/ja.json { "component": { "hogeLabel": "ほげ", "hogeButtonText": "ほげボタンテキスト" } } ``` - Component 内 で ` useTranslation ` を利用する - ` keyPrefix ` に ` component ` を指定する ```tsx import { Trans, useTranslation } from 'react-i18next'; export const HogeComponent = () => { const { t } = useTranslation('hoge', { keyPrefix: 'component', }); return ( <> <span>{t('hogeLabel')}</span> <button type="button">{t('hogeButtonText')}</button> </> ); }; ``` - Component のテストコードで ` I18nextTestProvider ` と ` translateResources ` を利用する - ` translateResources ` は ` libs/feature-hoge/src/lib/locales ` を相対パスで import する ```tsx import { render } from '@testing-library/react'; import { I18nextTestProvider } from '@provider/i18n'; import { translateResources } from '../../locales'; import { HogeComponent } from './hoge.component'; const setup = () => { const utils = render( <I18nextTestProvider resources={{ ja: { hoge: translateResources.ja }, }} > <HogeComponent /> </I18nextTestProvider> ); return { ...utils, }; }; describe('HogeComponent', () => { it('should render', () => { const { asFragment } = setup({}); expect(asFragment()).toMatchSnapshot(); }); }); ``` そして次のようなプロンプトをAgent modeで実行します。 あなたは優秀なフロントエンドエンジニアです。 次の指示に従って作業を行ってください。 ## 対象ディレクトリ - ` libs/feature-test ` ## 辞書データ - ` libs/feature-test/src/lib/locales/ja.json ` ## 1. 辞書データのファイルに書き込みを行う ### 作業内容 - 対象ファイルに合致する既存ファイルの実装コードから文字列を抽出する - 抽出した文字列の中で辞書データのファイルに定義されていない文字列のみを、辞書データのファイルに追加する ### 対象ファイル - Component - **/*.component.tsx ## 2. 翻訳処理を追加する ### 作業内容 - 対象ファイルに合致する既存ファイル全てに翻訳処理を追加する - 辞書データに記述されているテキストを翻訳処理に利用する ### 対象ファイル - Component - **/*.component.tsx ## 3. テストコードを修正する ### 作業内容 - 対象ファイルに合致する既存のファイル全てに翻訳処理を追加する ### 対象ファイル - Component - **/*.component.spec.tsx ## 4. snapshotを更新する ### 作業内容 - 対象ファイルに合致する既存のファイル全てのsnapshotを更新する - MCPのWallabyを使用して、変更したテストコードの実行とsnapshotの更新を行う カスタムインストラクションとMCPをAgent modeで活用することで、次のようなコードへの変更が自動で実行されます。 実装コードに useTranslation での翻訳処理が追加され、テストコードには I18nextTestProvider と translateResources を利用した翻訳処理が追加されていることがわかります。 import { useTranslation } from 'react-i18next' ; export const TestComponent = () => { const { t } = useTranslation( 'test' , { keyPrefix : 'component' , } ); return ( <> < h1 > { t( 'testTitle' ) } </ h1 > < div > < div > < span > { t( 'testText' ) } </ span > </ div > </ div > </> ); } ; import { render } from '@testing-library/react' ; import { I18nextTestProvider } from '@provider/i18n' ; import { translateResources } from '../../../locales' ; import { TestComponent } from './test.component' ; describe ( 'TestComponent' , () => { const setup = () => { const utils = render( < I18nextTestProvider resources = { { ja: { test : translateResources.ja } , }} > < TestComponent /> </ I18nextTestProvider > ); return { ...utils, } as const ; } ; describe ( 'render' , () => { it ( 'render snapshot' , () => { const { asFragment } = setup(); expect (asFragment()).toMatchSnapshot(); } ); } ); } ); このように、カスタムインストラクションを使ってリポジトリのルールやドメイン知識をCopilotに提供することで、Agent modeの精度を向上させることができます。 またMCPを使うことで、Copilotが参照するリソースを増やしたり、実行できるタスクの幅を広げることができます。 Coding Agent Coding Agentを利用することで、Copilotをバックグラウンドで独立して動作させて、人間の開発者と同じようにタスクを実行できます。 docs.github.com 使い方はとても簡単です。タスクに対するIssueを作成して、Issueの担当者にCopilotを指定するだけです。その後、Copilotが自動でPull requestを作成して、GitHub Actions上でタスクが実行されます。タスクが完了した段階で、依頼者がレビュワーに設定されます。 また、Copilotが作成した変更に対してレビューコメントを書くことが出来ます。そのレビューコメントに対する修正もCopilotが自動で行ってくれます。 Coding Agentで作成されたPull requestに対してレビューコメントを書く場合、 Add single comment で一個ずつコメントを追加するのではなく、 Start a review から複数のコメントを追加した後にまとめて送信することをオススメします。全てのコメントを一括で送信すると、Copilotは個々のコメントを個別に処理するのではなく、レビュー全体を対象に処理を開始します。 docs.github.com また、ここでもカスタムインストラクションは効果を発揮します。 Copilotが作成するPull requestの内容やコミットメッセージ、コードのスタイルなどをカスタムインストラクションに記載しておくことで、より自分たちの開発ルールに沿った内容でPull requestを作成してくれます。 Coding AgentはMCPの利用も簡単に設定することが出来ます。リポジトリの設定でMCPの設定ファイルを記述することで簡単に設定可能です。 docs.github.com また、Coding AgentがGitHub Actions上でタスクを実行する前に事前に実行しておきたい処理を設定することも可能です。 .github/workflows/copilot-setup-steps.yml というファイルを作成して、GitHub Actionsのworkflowを定義することで、事前に必要な処理を実行しておくことができます。 次の例は、Pythonのプロジェクトで必要なライブラリのインストールと、テスト用のデータベースを事前に起動しておくための copilot-setup-steps.yml です。この設定をしておくことで、Coding Agentがファイルを修正してテストを実行する時に、必要なライブラリがインストールされており、テスト用のデータベースも起動している状態でタスクを実行できます。 name : "Copilot Setup Steps" on : workflow_dispatch jobs : copilot-setup-steps : runs-on : ubuntu-latest permissions : contents : read steps : - uses : actions/checkout@v3 - name : Set up Python uses : actions/setup-python@v4 with : python-version : '3.13' - name : Start database with Docker Compose run : docker compose up -d db --wait - name : Install dependencies run : | pip install ".[test]" - name : Run migrations run : | python -m alembic upgrade head Coding Agentが作成するPull requestの内容の精度は、次の要素に大きく左右されます。 カスタムインストラクションの内容 Issueに記載されているタスクの内容 既存実装の内容 特にIssueに記載されているタスクの内容は非常に重要です。タスクは具体的に且つ簡潔に記載することが重要です。そこで重要になってくるスキルがタスク分解です。 tech.findy.co.jp Issueのタスクを細分化して箇条書きにすると良いでしょう。大きなタスクをIssueに起票する際は、まず親Issueとして大きなIssueを作成することをオススメします。この親Issueに対してはCoding Agentを利用しません。 次に、親Issueに対して子Issueとして複数のSub Issueを作成します。このSub Issueに対してCoding Agentを利用します。Sub Issueの内容は具体的に且つ簡潔に箇条書きで記載しましょう。 このように簡潔で単純なタスクの集合体であるSub Issueを幾つも作成し、それに対してCopilotを担当者として指定することで、Copilotが自律的にタスクを実行し、Pull requestを作成してくれます。 Issueを作ってCopilotを担当者に設定するだけでPull requestが作成されるので、並行して複数のPull requestを作成してもらえることも強みの1つです。エンジニアはIssueを作って、担当者にCopilotを指定して、作成されたPull requestをレビューするだけです。 Coding AgentがPull requestを作成している間に、自分はローカル環境で別の作業をやっているのは、今では当たり前の光景になってきています。 まとめ いかがでしたでしょうか? 今回紹介した機能はGitHub Copilotの機能のほんの一部であり、今回は特に重要な機能に絞って紹介しました。 カスタムインストラクションを整備しつつ、MCPを活用することが、GitHub Copilotを始めとする生成AIを効率的に活用するための最初の一歩です。 その上で、Agent modeやCoding Agentを活用することで、より自律的にタスクを実行してもらい、開発の効率化を図ることが可能になり、エンジニア自身は他の作業に集中することが出来るようになります。 生成AIを活用した開発フローに変化していく上で、生成AIが出力したコードが正しいかどうかを判断するスキルが非常に重要になってきました。 この判断するスキルは基礎と経験によって培われるものであり、今まで以上に基礎力が重要になってきていると感じています。弊社でもエンジニアとしての基礎力を重要視しており、これを強化するための取り組みも幾つか行っていますが、それはまた別の機会で紹介したいと思います。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから herp.careers
アバター
こんにちは! Findy Team+ 開発チームでEMをしている ham です。 Findy Team+のバックエンドはRuby on Railsで開発しており、Rubyの静的解析ツールとして広く知られているRubocopをTeam+の開発でも積極的に活用しています。 ファインディでは「爆速開発」を掲げており、開発速度に直結するCI(継続的インテグレーション)の実行時間を非常に重視しています。具体的には、CIの実行時間は遅くとも10分以内、理想としては5分以内に完了することを目標にしています。 CIの実行時間短縮に向けた取り組みについては、以前公開した次の記事で詳しくご紹介していますので、ぜひご覧ください。 tech.findy.co.jp 今回、バックエンドのCIの実行時間を見直したところ、Rubocopの実行時間が5分以上かかっていることに気づきました。これは改善の余地があると感じ、実行時間短縮に取り組むことを決めました。 また、CIではRubocopの他にRSpecでテストを実行しているのですが、RSpecの実行時間の方がRubocopよりも圧倒的に長いためそちらの改善ばかりに気を取られて、Rubocopの実行時間は見過ごされていました。 なお、この時もテストは7分ほどかかっておりRubocopより長かったですが、こちらは並列実行と実行環境のスペックアップを駆使することで3分程度まで短縮できました。 そこで、今回はRubocopの実行時間短縮に取り組むことを決意し、その結果、5分以上かかっていた実行時間を1分未満に短縮できました! なぜRubocopの実行時間が長かったのか? CIにおけるRubocopの実行は、基本的に全てのRubyファイルに対して無条件に実行されていました。 そのため、プロジェクトの規模が拡大するにつれて、解析対象となるファイル数も増加し、比例して実行時間も伸びていったのが主な原因です。 改善内容 実行時間短縮のために、次の3つの変更を加えました。 無条件で全ファイル解析していたが、編集したファイルだけ対象とする Gitの差分情報を用いて、変更があったファイルのみをRubocopの解析対象とするようにしました。これにより、CIの実行ごとに解析するファイル数を大幅に削減できました。 ファインディではGitHub Actionsを使ってCIを実行しているため変更したファイルを取得できる tj-actions/changed-files を活用して対象ファイルを取得しました。 設定ファイルやGemがアップデートされたときは全て解析 前述の変更により通常時は変更ファイルのみを対象としますが、Rubocopの設定ファイル(.rubocop.ymlなど)やRubocop本体や関連Gemのバージョンがアップデートされた場合は全てのファイルを解析するようにしました。 これは、設定変更やバージョンアップによって、これまで問題なかった箇所が新たに指摘される可能性があるため、CIの信頼性を保つ上で重要な対応です。 ファイル指定だと除外設定が無視されたので無視されないように変更 Rubocopには、コマンド引数に対象ファイルを明示的に指定すると、.rubocop.ymlで指定されている除外設定(Exclude)が無視されるという仕様があり、本来は解析対象外のファイルまで解析されてしまうという問題が発生しました。 これを解決するため、 --force-exclusion オプションを利用できることがわかりました。こちらのオプションを指定することで対象ファイルを明示的に指定した場合でも除外設定が反映されるようになります。 bundle exec rubocop -f github --force-exclusion ${{ all_changed_files }} 結果 これらの改善を適用した結果、5分以上かかっていたRubocopの実行時間は1分未満にまで劇的に短縮されました! これにより、CI全体の実行時間が短縮され、開発者はより素早くフィードバックを得られるようになりました。Rubocopの指摘への対応も迅速に行えるようになり、コードの品質維持にも貢献しています。 まとめ CIにおける静的解析の実行時間は、テスト実行時間に比べると見過ごされがちですが、積み重なると開発体験を損なう要因となります。 今回のRubocopの実行時間短縮で行った次の対応は、実装難易度も低く簡単にできるものでしたが、大きな効果をもたらしてくれました。 無条件で全ファイル解析していたが、編集したファイルだけ対象とする 設定ファイルやGemがアップデートされたときは全て解析 ファイル指定だと除外設定が無視されたので無視されないように変更 もしあなたのプロジェクトでもCIのRubocop実行時間が長いと感じているのであれば、本ブログで紹介した内容が少しでも参考になれば幸いです。変更ファイルのみを対象とする工夫は、他の静的解析ツールにも応用できる可能性がありますので、ぜひ検討してみてください。 ファインディでは一緒に働くメンバーも絶賛募集中です。興味がある方はぜひこちらから ↓ herp.careers
アバター