TECH PLAY

Findy/ファインディ

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

199

ファインディでソフトウェアエンジニアをやっている土屋です。今回は、先日大好評だった企画、「エンジニアの人生を変えたイベント」の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
こんにちは、ファインディでソフトウェアエンジニアをしている nipe0324 です。 先日、AWSさんの Coding Agent at Loft #2 〜 AI コーディング活用事例 Night - 効果的な組織導入と実践〜 (第2回目) で登壇させていただき、登壇内容を記事として書き起こしました。 この記事では、Devinと協働して 「個人のアウトプットを1.5倍にした実践3ステップ」 をご紹介します。 Devinと協働して個人のアウトプットは1.5倍に増加 2025年5月末時点では、Copilot Coding Agent、Codex、Jules などのリリースが続々とされており、自律型のコーディングエージェントが盛り上がってきています。 Devinに特化せず他のコーディングエージェントでも使える内容になっていますので、 自律型のコーディングエージェントの利活用に興味ある方 はご一読くださいませ。 ちなみに、生成AI界隈は動きが早いので、数ヶ月後はどうなるかわかりません。また、現時点での業務で試した結果の1事例として参考にしてください。 はじめに Devinと協働してアウトプットを1.5倍にした3ステップ ステップ1. Devinに教える 1-1. 小さなタスクから始める 1-2. Devinに開発のルールを教えていく ステップ2. Devinに慣れる 2-1. Devinのドキュメントを読む 2-2. 試行錯誤して勘所を掴む 2-3. Knowledgeを洗練させる 2-4. AI Friendlyな環境を整備する ステップ3. Devinと協働する 3-1. Devinに定型作業を任せる 3-2. Devinと一緒にタスクを進める 3-3. Devinにサブタスクを任せる おまけ: Devinの活用Tips Tips1. GitHub/AWSアカウント管理のワークフローを自動化 Tips2. 口調を変えるKnowledgeで親しみやすくする Tips3. PMが仕様把握のためにDevin Searchを利用 Tips4. AI駆動な仮実装 Devinに対する所感や協働して変わってきたこと まとめ はじめに Microsoftさんの最近の研究では、組織がAIトランスフォーメーションをしていくためには、次の3つのフェーズがあるようです。 Phase 1 Human with assistant :AIがアシスタントする Phase 2 Human-agent teams :エージェントがチームにジョインして、同僚として一緒に働く Phase 3 Human-led, agent-operated :人間がディレクションをして、エージェントが業務を遂行する。必要があれば人がチェックする AI Transformationの3段階(引用元: https://www.microsoft.com/en-us/worklab/work-trend-index/2025-the-year-the-frontier-firm-is-born ) その中で、今回の話はこの 「Phase2 エージェントと一緒に働く」 をトライしている話になります。 Devinと協働してアウトプットを1.5倍にした3ステップ ステップとしては次の3ステップで進めていきました。期間はDevinの導入から大体3ヶ月ぐらいかけて実施していきました。 ステップ1. Devinに「教える」 ステップ2. Devinに「慣れる」 ステップ3. Devinと「協働する」 個人的なポイントとしては、ステップ3までいくと、 コーディングエージェントの良さを感じ、日々のアウトプットをスケールしていけるという実感 をもてました。 ステップ1. Devinに教える 最初のステップは「Devinに教える」です。 Devinに小さなタスクを依頼しながら基本的な開発ルールを教えていくことで、 Devinが軽微な修正をそつなくこなせる ようになります。 1-1. 小さなタスクから始める まずは、文言変更や軽微なタスクを依頼してDevinの動きを知ります。 実際にDevinが開発している画面をみながら、Devinの開発環境・作業手順・やりとり方法などを押さえることで今後のDevinとのやりとりの土台をつくれます。 DevinとやりとりするWeb画面 アンチパターンとして、エージェントへの期待値が高すぎることで、最初から「急ぎのタスク」や「大きめなタスク」を依頼し精度がでなく幻滅してしまうことがあります。 人と同じで小さなタスクから開発に慣れてもらうことが大切です。Devinはチームに入った新人だと思い、焦らずまずは文言変更やドキュメント修正など小さなタスクから依頼していくことをオススメします。 1-2. Devinに開発のルールを教えていく 開発のルールは、会社やプロジェクトごとに違います。そのため、Devinに小さなタスクをお願いしながら開発ルールを教えていきます。 Devinには Knowledge という機能があります。Devinとの会話からルールをほぼ自動的に学び、Knowledgeとして保存することで、次回以降のタスク精度が高まります。 以下は、実際にDevinが学んだ開発ルールのKnowledgeの一部です。 ブランチ作成、PR作成、コミット作成、テスト実行など基本的な開発ルールをKnowledgeとしてDevinに学んでもらいました。 実際に学んだ開発ルールのKnowledge(抜粋) ステップ2. Devinに慣れる 次のステップとして、「Devinに慣れる」です。 Devinのドキュメントを読みながら、試行錯誤して依頼の勘所を掴みます。また、Knowledgeを洗練させ、AI Friendlyな環境を整えることで、 Devinがよくあるタスクで90点以上のタスク精度を実現できる ようになります。 2-1. Devinのドキュメントを読む Devin の Documentationの Essential Guidelines は必読です。Devinにうまく依頼するための重要なプラクティスが記載されています。 例えば、次のような内容が記載されています。 Devinは「ジュニアエンジニア」として扱うのが最適です。明確で十分な指示があれば、インターンや新人エンジニアが対応可能なタスクを任せることができます。 ベストプラクティス: 小さなタスクを並行して実行 :朝の始まりに複数の小さなタスクをDevinに割り当て、昼食時にレビューを行うと効率的です。 Slackでの迅速な対応 :Devinは30分程度で完了するタスクに適しており、長期間放置されがちなバックログの解消に役立ちます。 明確な成功基準のあるタスクに集中 :CIのパス確認や自動デプロイのテストなど、結果が明確に確認できるタスクが理想的です。 小さく始める :Devinの性能は長時間のセッション(≒10 ACU以上)で低下する可能性があるため、小規模なタスクから始めることを推奨します。 引用元: https://docs.devin.ai/essential-guidelines/when-to-use-devin の英語を翻訳 2-2. 試行錯誤して勘所を掴む Devinに様々なタスクを依頼しながら、依頼内容、依頼方法、タスク粒度の勘所を掴んでいきます。また、Devinのドキュメントを読んで学んだことを試しながら、より良い協働方法を模索していきます。 例えば、変数で指示をすることで汎用的なプロンプトを作成する、どの程度までの抽象的な指示ならタスクを遂行してもらえるか確認するなど試してみました。 そして、試行錯誤した結果、Linter対応や横展開系の対応、FeatureFlagの追加・削除、管理画面の軽微な改修、簡易なSentryのアラート対応などの定型作業は、ほぼ90点以上の精度でプルリクエストを作成できました。 Tipsとして、Devinの作成したプルリクエストの精度がいまいちなときは、Devinの設定画面で「Devinは承認を待たずに進める」のチェックをオフにするがおすすめです。複雑なタスクの場合、Devinの作業計画を承認してから作業を進めることができるので、作業計画段階で早めに方向性のすり合わせができ、「プルリクエストが出来上がった後のこれじゃない感」を大幅に減らせます。 「Devinは承認を待たずに進める」のチェックをオフにする 2-3. Knowledgeを洗練させる Devinとの試行錯誤を通しながら、DevinのKnowledgeのバリエーションを増やしていきます。 例えば、テーブルを扱う変更やビジネスロジックの作成、APIの実装、ドキュメンテーションの追加など、さまざまなケースのKnowledgeが溜まっていきます。 これにより、より多くのタスクを精度よく任せられるようになります。 しかし、KnowledgeがあってもDevinがその内容通りに動かないこともあります。 そのような場合は、うまくいかなかったやりとりをもとに「今回のやりとりを次回以降で活かすためにKnowledgeを更新して」と伝え根気強くKnowledgeを更新します。 それでも駄目なら、初期の依頼プロンプトに内容を盛り込んだり、現状のLLMの限界として諦めています。 2-4. AI Friendlyな環境を整備する 単純にDevinに頑張ってもらうだけでなく、AIが開発をしやすいコードベースや開発環境を整備することも大事です。 個人的に、AI Friendlyな環境として以下3つは特に重要だと考えています。 自動テスト、Linter、CIは必須 :Devin自身でフィードバックループが回せなくなるので作業の精度が下がります。また、レビュアーのレビュー時のガードレールにもなるので必須です。 コードの統一や暗黙のルールを明文化 :既存の実装を踏襲してもらうとDevinのタスク精度が高くなります。コードベース上で同じ目的のためにいろんな実装方式があるとDevinが迷ってしまうので、コードの統一感を高めています。また、暗黙知も明文化してKnowledgeとして教えます。 場合によっては開発ルールを変更する :Devinに何度伝えてもうまく対応できないことがあったので、ルールを変更しました。具体的には、コミットメッセージの文字数のルールを守れなかったため、開発ルールとしての制限を緩めることで対応しました。 ステップ3. Devinと協働する ここまででDevinへの依頼に慣れて、ある程度の難易度のタスクならほぼ満足できるようになってきます。 最後のステップでは、Devinに定型作業を任せたり、一緒にタスクを進めたりすることで、 個人のアウトプットを増加 させていきます。 3-1. Devinに定型作業を任せる 「これは9割以上の精度でDevinに任せられる」というタスクはDevinに任せていきます。定型作業のようなものは、ほぼ完璧にプルリクエストを仕上げてくれます。 最近では、個人のAIエージェントとの協働を通じてマインドも変化してきました。ある程度定型化されたタスクは「Devinに任せれば良さそう」いう考えになってきています。 例えば、軽微な修正やFeatureFlagの追加・削除、モデル作成、マイグレーションファイル作成、管理画面の簡易な対応などはDevinに任せて、その間に自分はDevinができない作業を進めることが多くなりました。 3-2. Devinと一緒にタスクを進める Devinは、CursorやClineなどローカルマシンで実行するエージェントに比べて相対的に作業時間は長くなります。しかし、タスクを分担して連携して開発できれば、大きな問題にはならないと考えています。 私がよく実施する「Devinと一緒にタスクを進める方法」は主に2つです。 よくあるDevinと一緒にタスクを進める方法 パターン①:タスクを分解し、Devinがメインで開発を担当し、難しい部分やレビューを自分が行う パターン②:横展開系のタスクで、最初の実装イメージは自分が作成し、その後の横展開はDevinに並列で実装を任せ、レビューを自分が行う 3-3. Devinにサブタスクを任せる たまに、メインでないサブタスクを裏でDevinに丸っと依頼して作ってもらうことをします。 Devinの公開APIを利用した自前ワークフローツール(※Roo Codeの Boomerang Tasks の簡易版のようなもの)を作成し、一連の依存関係のあるタスクリストをワークフローツールで実行しています。 これにより、1〜2時間ほどで一通りの対応(5〜8プルリクエスト)をDevinに実装してもらうことが可能になりました。 タスクの定義例。依存関係にそってタスクを実行してくれる 課題としては、個々のタスク精度にはまだ伸びしろがあります。また、メインタスクとサブタスクを頻繁に切り替える必要もでてくるため、かなり疲れることもあります。 改善案として、レビューの一部をエージェント化したり、ワークフローのオーケストレーターやタスク出しをエージェント化したりすることで、より丸ごと任せられるか試してみたいと考えています。 おまけ: Devinの活用Tips 最後におまけとして、Devinの活用Tipsをいくつかご紹介します。 Tips1. GitHub/AWSアカウント管理のワークフローを自動化 SREチームでは、SlackワークフローとDevinを組み合わせてGitHubとAWSのアカウント管理をほぼ自動化しています。 SlackワークフローでDevinに依頼 流れとしては次のとおりです。 前提として、Terraformでアカウント管理をしている。 Slackのワークフローで依頼をすると、@Devinメンションでワークフロー内容が記載される。 Devinが反応してアカウント管理(追加・更新・削除)のプルリクエストを作る。 SREがプルリクエストをレビューをする。修正がある場合プルリクエスト上でコメントをするとDevinが修正してくれる。 SREがプルリクエストをマージすると、Terraformによりアカウントが追加・更新・削除される。 SREの方に効果を聞いたところ、月末月初などユーザー申請の対応が五月雨にあり地味に時間がかかっていた工数が 感覚値で1日程度削減 できたようです。 Devinには、Slackからタスクを依頼をできる機能があるので、Slackのワークフローとの接続がとても簡単にできるところはいいところだと思っています。 Tips2. 口調を変えるKnowledgeで親しみやすくする DevinのKnowledgeで口調を指定することで、エンジニアがDevinに親しみを感じやすくしています。 Devinはデフォルトだと割とかしこまった感じの口調なのですが、Knowledgeを指定することで砕けた感じの会話ができるようになり、チームとDevinの親近感が醸成されました。(たぶん...) Devinの口調を変えるKnowledgeとDevinとのやりとり 実用的な観点ではDevinが Knowledge をどのぐらい理解して作業をするかを日々検証できるというメリットもあると思っています。 Tips3. PMが仕様把握のためにDevin Searchを利用 Devinには、コーディングだけでなくDevin Searchという自然言語で質問をして回答を得られる機能があります。現在はβ板なので無料で利用できます。 Devin Searchで仕様を確認 実際にPMからメール送信の条件に対する質問をされ、Devin Searchで検索したら100点の回答が得られました。 そのため、PMにDevinのアカウントを発行して、詳細の仕様が気になる場合はDevinに聞いてもらうという取り組みをしました。 Tips4. AI駆動な仮実装 まだ試行錯誤段階ですが、Devinをフル活用して、仮実装を感覚値で2~3日想定が1日で完了しました。また、仮実装を通して設計やコードの解像度が高まり、「実現性の検証」や「改善点の発見」を短期間で実現できました。 仮実装の流れは次のように進めました。 Devin Wikiで新しいリポジトリの主要機能や設計を把握 Devin Searchで影響範囲を設計とコードレベルで把握 Devin に大きめなタスクを渡して仮実装 Cursorを使いながら仮実装の細部を修正して動くようにする ある程度頭の中に設計イメージがあり、そのイメージをDevinに伝えて設計をしてもらい、仮実装を進めていくことで素早く検証を進めることができました。(※もちろん仮実装のコードは捨てて、本実装時に細部も含めてちゃんと作り込みます) Devinに対する所感や協働して変わってきたこと Devinとうまく協働することで、いままではチームのエンジニアが5~6名ぐらいだったのが、3名前後でも同程度のアウトプットをだせるようになっていきそうな感覚を受けています。 しかし、足元少しずつ顕在化しはじめているのですが、より少人数のチームでプルリクエストの数が増えているのでチームのレビュー負荷が高まっています。 具体的な解決策のアイデアはまだないですが、レビューのあり方をよりAI駆動によせていく必要があると思っています。 また、Devinと協働する中で個人の動きも少しずつ変わっています。 ミーティングが多くなってしまった日でも、Devinに実装をお願いすることで想定の進捗どおりに開発できた 一部のプロダクトマネジメント業務やデータ分析など業務の幅が広がった 生成AIの進歩は早いですが、新しい技術に一喜一憂しながら、楽しんでいこうと思っています。 まとめ 今回の記事では、 「Devinと3ヶ月協働して個人のアウトプットを1.5倍にした3ステップ」 についてご紹介しました。 Devinと協働する3ステップは次のとおりです。 ステップ1. Devinに教える :小さなタスクからはじめ、開発ルールを教える。 ステップ2. Devinに慣れる :Devinのドキュメントを読みながら試行錯誤をする。また、Knowledge拡充やAI Friendlyな環境を整備する。 ステップ3. Devinと協働する :Devinに定型作業を任せる。Devinと一緒にタスクを進める。Devinにサブタスクを全て任せる。 今後は次のようなことにトライしていきたいと考えています。 個人のアウトプット向上から、チームや組織のアウトプット増加につなげていきたい Devinに任せられる範囲を増やし、AI駆動開発をより推進したい また、セキュリティなどには気をつけつつも、DevinにとらわれずCopilot Coding Agent, Claude Code + GitHub Actionsなどいろいろと試しながら、より開発組織のスピードと品質を向上させていきたいと考えています。 ファインディでは生成AIやAIエージェントを試して開発生産性を高めることで、ユーザーにより価値を届けることを推進しています。 こうした新しい技術の利活用に興味がある方は、ぜひカジュアル面談にお越しくださいませ。 herp.careers
はじめに 皆さんこんにちは。ファインディに転職してまもなく1年を迎える、CTO室/SREチームの安達( @adachin0817 )です。今回は複数のWordPressサイトをShifterへ移行しましたので、その取り組みについてご紹介します。 Shifterとは ja.getshifter.io Shifterは、WordPressサイトを静的に変換・ホスティングできるマネージドサービスです。動的に動作するWordPressをShifterがビルドし、生成されたHTML/CSS/JavaScriptの静的ファイルをCDN経由で配信する構成となっています。主なメリットは次のとおりです。 セキュリティ強化:PHP実行環境を持たないため、WordPress本体やプラグインの脆弱性リスクが激減。 運用負荷の軽減:インフラやWordPressのバージョンアップ管理が不要。 表示速度の高速化:静的ファイルをCDN 経由で高速配信できるため、ユーザー体験の向上が期待。 自動バックアップ・簡単ロールバック:管理画面から任意のタイミングで復元可能。 Shifterに移行する背景 旧構成図 元々はAmazon Lightsail上の単一サーバーで複数のサイトを運用しており、画像ファイルやデータベースもすべて同一のインスタンス上で管理されていました。コーポレートサイト以外はPHPやプラグインのバージョン管理が行われておらず、明確な運用者もいなかったため、誰がメンテナンスしているのか分からない状況が続いていました。 また、コーポレートサイトに関しては情報システムチームが毎週のようにセキュリティアップデートを対応する必要があり、テーマのデプロイも自動化されておらず手動で行っていたため、運用負担が大きいという課題を抱えていました。 こうした背景に加え、会社全体でも定期的なバージョンアップ対応やセキュリティ強化に十分なリソースを確保することが難しく、改善が急務となっていました。そのような中、2024年に全社的な信頼性向上を目的として横断SREチームが発足しました。SREチームでは属人化していたWordPress環境を集約・統制することで、信頼性の向上を目指す取り組みが始まりました。 その解決策としてマネージドサービスへの移行を検討し、上記のメリットとコストが比較的安価のため、最終的にShifterを採用しました。次は、ローカル開発環境についてご紹介していきます。 開発環境の構築 ローカル開発環境では、コーポレートサイト以外の開発環境が整っていなかったため、Dockerを使って1から構築し直すことにしました。リポジトリ構成としては、WordPress本体をwordpress-coreリポジトリ(仮)で一元管理し、各サービスのテーマは個別のリポジトリで管理する方式を採用しました。これは、すべてを単一リポジトリに集約すると容量の肥大化や管理の複雑さを招くためです。 ※以下仮としています compose.yml ❯❯ cat docker-compose.yml volumes: php-fpm-sock: services: wp-nginx: container_name: wp-nginx build: docker/dev/nginx/ image: wp-nginx ports: - '80:80' - '443:443' volumes: - ./wordpress-core:/var/www/wp:delegated - ./site-corporate:/var/www/wp/corporate/wp-content/themes/site-corporate:delegated - ./site-enterprise01:/var/www/wp/enterprise01/wp-content/themes/site-enterprise01:delegated - ./site-enterprise02:/var/www/wp/enterprise02/enterprise/wp-content/themes/site-enterprise02:delegated - ./site-blog:/var/www/wp/blog/wp-content/themes/site-blog:delegated - php-fpm-sock:/var/run/php-fpm tty: true depends_on: - wp-app wp-app: container_name: wp-app build: docker/dev/app image: wp-app volumes: - ./wordpress-core:/var/www/wp:delegated - ./site-corporate:/var/www/wp/corporate/wp-content/themes/site-corporate:delegated - ./site-enterprise01:/var/www/wp/enterprise01/wp-content/themes/site-enterprise01:delegated - ./site-enterprise02:/var/www/wp/enterprise02/enterprise/wp-content/themes/site-enterprise02:delegated - ./site-blog:/var/www/wp/blog/wp-content/themes/site-blog:delegated - php-fpm-sock:/var/run/php-fpm tty: true depends_on: - wp-db wp-db: container_name: wp-db build: docker/dev/mysql image: wp-db command: --default-authentication-plugin=mysql_native_password ports: - '33066:3306' volumes: - ./mysql/db_data:/var/lib/mysql - ./mysql/init.sql:/docker-entrypoint-initdb.d/init.sql ShifterがPHP 8.1に対応していることから、Appコンテナ・Nginxコンテナ・MySQLコンテナも同じバージョンに揃えて構成しました。WordPressのバージョンや依存パッケージに差異があると、静的化後に想定外の動作になる恐れがあるためです。Shifterでは開発用のDocker環境も用意されていますが、できる限り本番と同等の構成になるよう意識して環境を整備しました。 さらに、Justfileを導入することで、hosts登録やmkcertによる自己署名SSL証明書発行、S3からのDBダンプ取得などのセットアップを自動化しました。複雑だった開発環境の構築手順が、今では just all コマンドを実行すれば素早く構築できるようになりました。ただ、運用していく中で、開発環境自体のバージョンアップもしなければなりませんが、今後GitHub Actionsで自動化していきたいと思っています。 Justfile 開発用ドメイン設定 リポジトリのclone mkcertの実行 wp-config.phpのコピー Docker Composeの起動から停止 DBのリストア setup-hosts: for hosts in "127.0.0.1 dev.site.co.jp" "127.0.0.1 dev.site.co.com" "127.0.0.1 dev-site2.com" "127.0.0.1 dev-site3.com"; do \ if ! grep -q "$hosts" /etc/hosts; then \ sudo bash -c "echo '$hosts' >> /etc/hosts"; \ fi; \ done setup-mkcert: cd ~/www/wordpress-core && \ brew install mkcert && \ mkcert -install && \ mkdir -p docker/dev/nginx/cert && \ cd docker/dev/nginx/cert && \ mkcert "*.hoge.co.jp" clone-repos: @echo "Cloning repositories..." repos="site-corporate site-blog site-enterprise01 site-enterprise02"; \ for repo in $repos; do \ dir="$HOME/www/$repo"; \ url="git@github.com:hoge/$repo.git"; \ if [ ! -d "$dir" ]; then \ git clone --depth 1 "$url" "$dir"; \ echo "Cloned $repo repository."; \ else \ echo "$repo repository already exists. Pulling latest changes."; \ cd "$dir" && git pull origin main; \ fi; \ done copy-wp-config: for dir in "corporate" "site-blog/blog" "site-enterprise01/enterprise01" "site-enterprise02/enterprise02"; do \ cd ~/www/wordpress-core/$dir && cp wp-config-dev.php wp-config.php; \ done start-docker: docker-compose up -d stop-docker: docker-compose stop down-docker: docker-compose down restore-db profile: rm -rf ./db_dumps aws --profile={{profile}} s3 cp s3://hoge/dev/MySQL/ ./db_dumps --recursive --exclude "*" --include "*.sql" for file in ./db_dumps/*.sql; do \ db_name=$(basename "$file" .sql); \ echo "Copying $file to wp-db container"; \ docker cp "$file" wp-db:/tmp/$(basename "$file"); \ echo "Dropping and creating $db_name"; \ docker exec wp-db mysql -u root -e "DROP DATABASE IF EXISTS \`$db_name\`; CREATE DATABASE \`$db_name\`;"; \ echo "Restoring $db_name from /tmp/$(basename "$file")"; \ docker exec wp-db sh -c "mysql -u root $db_name < /tmp/$(basename "$file")"; \ echo "Cleaning up /tmp/$(basename "$file") from wp-db container"; \ docker exec wp-db rm "/tmp/$(basename "$file")"; \ done rm -rf ./db_dumps all profile: just setup-hosts just clone-repos just copy-wp-config just start-docker just restore-db {{profile}} Shifter移行とトラブルシューティング Shifterへの移行にあたっては、公式ドキュメントにも記載されているとおり、All-in-One WP Migrationプラグインを使ったエクスポート・インポート方式が推奨されています。この方法を使えば、WordPressサイトを簡単に丸ごと移行できるのが大きなメリットです。実際に試してみたところ、基本的な移行作業はスムーズに完了しましたが、いくつか想定外の不具合も発生しました。以下にその内容を共有します。 独自テーマのページネーションが正しく動作しない コーポレートサイトのページネーションが正しく機能しないという事象が発生しました。Shifterでは、静的サイトを生成する際にWordPress REST API を通じて対象のURL一覧(JSON形式)を取得し、それをもとに静的化を行います。しかしながら、WordPressのアーカイブページのページネーションはデフォルト設定のままだと検出されず、静的化の対象から漏れてしまうことがあります。この問題に対しては、Shifterが提供する ShifterURLS::AppendURLtoAll を使うことで、手動で静的化対象のURLを追加が可能です。次のようにfunctions.phpに追加し、ページネーションURLを明示的に含めることで対応しました。 function.php function my_append_urls( $urls ) { $limit = get_option('posts_per_page'); $args = array( 'post_type' = > 'post', 'post_status' = > 'publish', 'posts_per_page' = > -1, 'fields' = > 'ids', 'no_found_rows' = > true, ); $the_query = new WP_Query($args); if ($the_query- > have_posts()) { $last_page = ceil(count($the_query- > posts) / $limit); for ($i = 2; $i <= $last_page; $i++) { $urls[] = home_url('/news/page/' . $i . '/' ); } } return $urls; } add_action( 'init' , function(){ add_filter( 'ShifterURLS::AppendURLtoAll' , 'my_append_urls' ); } ); 一部画像が表示されない All-in-One WP Migrationを使った移行ではスムーズに進みましたが、日本語ファイル名の画像が表示されないという問題が発生しました。Shifterへの移行後、原因を調査したところ、画像ファイル名が日本語の場合に限って読み込めないというバグを確認できました。数枚ほどだったので、対象のファイルを手動でリネームし、再アップロードをする必要がありました。 サブディレクトリでシェアボタンがShifterの仮ドメインになってしまう 既にCloudFrontにカスタムドメインが設定されている場合、Shifter 側のCDNに同じカスタムドメインを適用できません。このようなケースでは、Shifterで生成された静的コンテンツのみを対象に、CloudFront経由でカスタムドメイン配下のサブディレクトリに公開する必要があります。 /blog のようにサブディレクトリでの公開が必要な場合、 shifter-cli を使って --no-shifter-cdn オプションを指定することで、ShifterのCDN配信を無効化し、自前のCloudFront経由でのホスティングが可能になります。 CloudFrontのオリジンドメインにShifterが提供するCloudFront URLを指定し、キャッシュポリシーを無効化に設定することで、Shifterで生成された静的サイトをそのまま公開できます。最後にShifterでデプロイを実行することで、シェアボタンやOGPのリンク先にShifterの仮ドメインが含まれることはなくなりました。 ドメイン紐づけ $ npm install -g @shifter/cli $ shifter domain:attach --username hoge --password hoge --site-id hoge --domain hoge.com --no-shifter-cdn terraform/cloudfront.tf data "aws_cloudfront_cache_policy" "caching_disabled" { name = "Managed-CachingDisabled" } resource "aws_cloudfront_distribution" "hoge" { provider = aws.us-east-1 origin { domain_name = "hoge.cloudfront.net" origin_id = "blog" origin_path = "" custom_origin_config { http_port = 80 https_port = 443 origin_protocol_policy = "https-only" origin_ssl_protocols = [ "TLSv1.2" ] } ordered_cache_behavior { allowed_methods = [ "DELETE" , "GET" , "HEAD" , "OPTIONS" , "PATCH" , "POST" , "PUT" ] cache_policy_id = data.aws_cloudfront_cache_policy.caching_disabled.id cached_methods = [ "GET" , "HEAD" ] compress = true path_pattern = "blog/*" target_origin_id = "blog" viewer_protocol_policy = "https-only" } ordered_cache_behavior { allowed_methods = [ "DELETE" , "GET" , "HEAD" , "OPTIONS" , "PATCH" , "POST" , "PUT" ] cache_policy_id = data.aws_cloudfront_cache_policy.caching_disabled.id cached_methods = [ "GET" , "HEAD" ] compress = true path_pattern = "blog/" target_origin_id = "blog" viewer_protocol_policy = "https-only" } } これらトラブルシューティングを解決したことにより、次はテーマのデプロイ方法について説明したいと思います。 Shifter Github Plugin/Theme Installedでのテーマデプロイ https://github.com/getshifter/shifter-github ShifterではGitHub経由でテーマをデプロイするための公式プラグイン「Shifter GitHub Plugin/Theme Installed」が提供されています。このプラグインを利用することで、次の手順でテーマの更新が可能になります。 テーマをgit tagでバージョン付け git pushでタグを反映 テーマ一式を .zip に圧縮し、GitHubの Releases にアップロード Shifter側で該当リリースの.zip を取得し、テーマを最新化 もともとは複数のテーマをモノレポで管理しようとしていましたが、Shifterの仕様上、1テーマ、1プロジェクト(単一リポジトリ)が前提となります。さらに、GitHub Actionsを活用してリリースの自動化も実装しており、手動作業を減らして運用効率を向上させました。 github/workflows/release.yaml name : Tag and Release on : push : branches : [ main ] jobs : tag-and-release : name : Tag and Release runs-on : ubuntu-latest permissions : contents : write defaults : run : working-directory : "./" steps : - uses : actions/checkout@v4 - name : Fetch tags run : git fetch --tags - name : Get latest tag id : get_latest_tag run : | TAG=$(git tag --sort=-v:refname | head -n 1 || echo "0.0.0" ) echo "Latest tag: $TAG" echo "latest_tag=$TAG" >> $GITHUB_ENV - name : Calculate next tag id : calculate_next_tag run : | IFS='.' read -r MAJOR MINOR PATCH <<< "${{ env.latest_tag }}" NEXT_TAG="$MAJOR.$MINOR.$((PATCH+1))" echo "Next tag: $NEXT_TAG" echo "next_tag=$NEXT_TAG" >> $GITHUB_ENV - name : Create new tag run : | git tag ${{ env.next_tag }} git push origin ${{ env.next_tag }} - name : create archive env : PACKAGE_NAME : "hoge-theme" FILES_TO_ARCHIVE : "*" run : | sed -i -e "s/{release version}/${{ env.next_tag }}/g" ./style.css zip -r ${PACKAGE_NAME}.zip ${FILES_TO_ARCHIVE} - name : Upload to GitHub Release env : PACKAGE_NAME : "hoge-theme" GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }} GOPATH : /home/runner/go run : | go install github.com/tcnksm/ghr@latest ${GOPATH}/bin/ghr \ -b "Release ${{ env.next_tag }}" \ -replace \ "${{ env.next_tag }}" \ "${PACKAGE_NAME}.zip" style.css Version: { release version } 現在の運用体制について Shifterのアカウント管理は情報システムチームが担当し、テーマの修正はエンジニアやSREチームが対応しています。また、記事の公開やコンテンツの更新は広報チームやマーケティングチームが行っており、各チームの役割が明確に分担されるようになりました。 移行してみて Shifter導入によって、SREチームだけでなく非エンジニアのメンバーでも運用できる環境が整いました。Shifterのダッシュボードはシンプルで直感的に操作でき、バックアップの復元も簡単です。また、静的ファイル化によりPHPの脆弱性リスクが排除され、HTMLとCSSのみで構成されることでセキュリティ面でも安心できるようになりました。さらに、CDNが標準で組み込まれているため、パフォーマンスの向上も実感しています。一方で気になったところは記事をリリースするまで、毎回Shifter側で静的化デプロイをしなければならないので、反映までに時間がかかるといったところです。 さらに、1つのShifterアカウントで複数のサイトを一元管理できる点も大きなメリットです。以前はサイトごとにユーザーアカウントを発行していたため管理が煩雑でしたが、現在は運用効率が大幅に向上し、ユーザー棚卸しも簡単になりました。また、デジタルキューブ様の導入事例でも紹介していただきましたので、ぜひご覧ください。 ja.getshifter.io まとめ 長らく技術的負債となっていたWordPress環境でしたが、SREチームを中心にShifterへの移行を進めたことで、信頼性の向上と一元管理を実現できました。自分自身、初めてShifterを導入するにあたり、静的化に伴う挙動の違いなど、試行錯誤する場面も多く苦労しました。しかし、今では導入して本当に良かったと感じています。今後は新たなメディアを立ち上げる際もShifterを利用し、SREチームを通じた管理フローを社内で徹底していきたいと思っています。 最後まで読んでいただきありがとうございました。SREチームは絶賛募集しているので、カジュアル面談ぜひお待ちしております!🙏 herp.careers 最後に aws.amazon.com AWS Summit Japan 2025で登壇することになりました!Security LakeとAIの活用についてお話します!6/26(木) 12:40~行いますので、ご都合合う方はぜひご参加をお待ちしております!
こんにちは。Findy Tech Blog編集長の高橋(@Taka_bow)です。 本記事は「 エンジニア達の人生を変えた一冊 」シリーズの第4弾となります。エンジニアとしてのキャリアや技術的な視点に大きな影響を与えた一冊とは?それぞれの思い入れのある本から、技術への向き合い方や成長の軌跡が垣間見えるかもしれません。 今回は佐藤さん、中村さん、甲斐さんの3名のエンジニアに、人生を変えた一冊を紹介していただきます。 まずはファインディのテクノロジーを統括するCTO佐藤さんからです!幅広い知見を持つ佐藤さんが、エンジニアとしての原点となった一冊とは?大学時代に出会った運命の本が、その後のキャリアをどう形作ったのでしょうか。 ■ 佐藤将高さん / CTO ■ ファインディ株式会社のCTOを務めています。トップバッターを務めさせていただきます! コンピュータの構成と設計 コンピュータの構成と設計 MIPS Edition 第6版 上 作者: David Patterson , John Hennessy 日経BP Amazon コンピュータの構成と設計 MIPS Editoin 第6版 下 作者: David Patterson , John Hennessy 日経BP Amazon コンピュータの構成と設計 作者: デイビッド・A・パターソン、ジョン・L・ヘネシー 出版社: 日経BP Amazon: 第6版 上 、 第6版 下 私が紹介する「コンピュータの構成と設計」は、コンピュータアーキテクチャの基礎から応用までを体系的に解説した書籍です。通称「パタ&ヘネ」として知られており、著者の両名はチューリング賞も受賞している著名な研究者です。 この本を読んだきっかけ 私が大学時代、恥ずかしながら「コンピュータについて何もわからない」状態で授業を受けていました。その後、大学院受験をするタイミングで試験内容にコンピュータアーキテクチャのセクションがあり、この本を何度も読み返し勉強を進めてきました。命令セットやプロセッサの種類を詳しく知ることが自分にとってどれほど重要なのか理解できていませんでしたが、この本との出会いが私のコンピュータに対する理解を大きく変えることになりました。私にとっては革命的な本です。 本の内容 この本は世界中の大学でコンピュータアーキテクチャの教科書として使われている名著で、もしかしたら大学で勉強したことがある方がいるかもしれませんね。 コンピュータアーキテクチャの内容をわかりやすく解説しており、コンピュータの歴史を踏まえながら命令やプロセッサなどの概念を理解しやすく説明しています。1996年の初版以来、私が読んだ時点の第5版ではMIPSアーキテクチャが中心でしたが、現在の6版では最新のアーキテクチャやトレンドも反映されています。 この本から影響を受けた点/学んだ点 この本を読んだことで、コンピュータの動作が頭の中でだんだんイメージできるようになりました。特に、Webサービスを提供する上では、クライアントと記憶媒体間のデータのやり取りを考慮しながらプログラムを組む必要があることを理解できました。サービスをより大規模に展開しようとすると、ハードウェアについての知識がますます重要になってくることを実感しました。また、I/Oやメモリに関する知識が深まったことで、プロダクトの課題発見に今でも役立てています。 特に印象に残った部分 世の中にある技術書は難解なものが多いと感じていましたが、この本は特に読みやすく、当時学生だった私にとってアーキテクチャの基礎を掴むのにとても役立ちました。 表面的なプログラミングだけでなく、その下層で何が起きているかを理解することで、より良いシステム設計ができるようになりました。例えば、CPU内部の論理設計から、メモリ階層・I/O・並列計算機までのコンピュータの動作原理を広く理解することは、エンジニアとしてのキャリアを積む中で常に私の基盤となっています。 全体的に図が多く、内部の動作をイメージしやすい良書です。 このような方におすすめ ソフトウェア以外にも、コンピュータサイエンス全般を幅広く学びたい方にお勧めの一冊です。特に、Webサービスやアプリケーション開発に携わるエンジニアの方々には、パフォーマンスチューニングやシステム設計の基礎知識として役立つでしょう。また、コンピュータサイエンスを学び始めたばかりの学生の方にも、その読みやすさから入門書として最適です。 また、理解が進んだ方には「上パタ&ヘネ」と言われる「Computer Architecture: A Quantitative Approach」という本もありますので、物足りない方はこちらもおすすめです。 佐藤さんの原点は「パタ&ヘネ」にあったんですね。大学時代に出会ったこの一冊が、現在CTOとして活躍する佐藤さんのコンピュータに対する深い理解の礎となったことがよく伝わってきます。技術書との出会いが、その後のキャリアを大きく左右することを実感させられます。 次は、Findy Team+のフロントエンド開発を担当する中村さんです!中村さんが選んだ一冊は、実際の開発現場で直面した課題から見つけ出した救世主のような本。Webセキュリティの世界への扉を開いた体験とは? ■ 中村大輝さん / フロントエンドエンジニア ■ こんにちは、 Findy Team+ の開発をしている 中村 です。 体系的に学ぶ 安全なWebアプリケーションの作り方 体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践 作者: 徳丸 浩 SBクリエイティブ Amazon 体系的に学ぶ 安全なWebアプリケーションの作り方 作者: 徳丸 浩 出版社: SBクリエイティブ 私が紹介する「体系的に学ぶ 安全なWebアプリケーションの作り方」は、Webアプリケーションのセキュリティを体系的に解説した書籍です。通称「徳丸本」として知られています。 この本を読んだきっかけ エンジニアとして働き始めた1〜2年目の頃、当時私が担当していたWebサービスで脆弱性診断を受ける機会がありました。その結果、XSSやCSRFといった複数の脆弱性が指摘され、修正を求められる事態となりました。 1つ具体的な例を挙げると、そのWebサービスにはユーザーがレビューのようなものを投稿できる機能がありました。しかし、その入力欄に悪意あるスクリプトが埋め込まれ、他のユーザーがそのレビューを閲覧すると、JavaScriptが実行されるXSS(クロスサイトスクリプティング)が発生しました。この脆弱性により、ユーザーのクッキー情報が盗まれたり、不正な操作が実行されたりする可能性があり、非常に危険でした。これらの修正事項を解決するため、Webセキュリティに関する知識が必要となり、何をどう対策すれば良いのか悩んでいたときに出会ったのが「体系的に学ぶ 安全なWebアプリケーションの作り方」でした。 本の内容 この本は、Webアプリケーションの脆弱性を体系的に解説し、その対策方法を具体的に示しています。特に、XSSやCSRF、SQLインジェクションなど、代表的な脆弱性ごとにその仕組みと対策をわかりやすく解説しており、Webセキュリティに関する理解を深めることができます。また2011年の初版から、HTML5の普及に伴う改定などいくつかの改訂が重ねられた第2版まで現在出版されています。 この本から影響を受けた点/学んだ点 この本を読むことで、脆弱性とは単なる「エラー」ではなく、悪意ある攻撃者によって悪用される可能性があるとても重大なリスクであることを理解しました。また、脆弱性の種類ごとにどのような攻撃が行われるかを学び、実際のコードにどう対策を実装すればよいかを具体的に理解できました。 特に印象に残った部分 特に印象に残ったのは、XSS(クロスサイトスクリプティング)の項目です。当時私が担当したWebサービスでもXSSが報告され、その危険性を初めて実感しました。本書の例をもとに、エスケープ処理やCSP(コンテンツセキュリティポリシー)を適用することで安全性を高める方法を学び、実際の修正にも役立ちました。 このような方におすすめ Webアプリケーション開発に関わるすべてのエンジニアにお勧めです。特に、開発経験が浅く、Webセキュリティに自信がない方には非常に助けになる一冊です。 中村さんの「徳丸本」との出会いは、まさに現場のピンチを救った実践的な体験でしたね。エンジニアとして直面した実際の脆弱性問題が、セキュリティへの深い理解につながった瞬間が印象的です。技術書は時に、現場の課題を解決する強力な味方になるのですね。 最後は、2025年3月に入社したばかりの甲斐さんです!同じくFindy Team+のフロントエンド開発を担当する甲斐さんが選んだのは、コードの「変更しやすさ」という永遠のテーマに挑んだ一冊。大規模開発の現場で見つけた設計の知恵とは? ■ 甲斐和基さん / フロントエンドエンジニア ■ こんにちは、 甲斐 です! 2025年3月にファインディへ入社、フロントエンドエンジニアとして Findy Team+ の開発をしています。 現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法 現場で役立つシステム設計の原則 ~変更を楽で安全にするオブジェクト指向の実践技法 作者: 増田 亨 技術評論社 Amazon 現場で役立つシステム設計の原則 変更を楽で安全にするオブジェクト指向の実践技法 作者: 増田 亨 出版社: 技術評論社 この本を読んだきっかけ エンジニアとして働き始めて2年目の頃、初めて大規模なコードベースのアプリケーションを担当することになりました。コードベースが巨大かつ複雑で影響範囲を調査するだけでも数時間かかるような状況に課題感を感じ、変更しやすいコード・設計に興味を持ったことがきっかけでこの本を手に取りました。 本の内容 システム設計について、ドメイン駆動設計とオブジェクト指向プログラミングを中心に、変更に強いコードを書くための設計・手法について具体的なコードを例に挙げて解説しています。ベースの話はオブジェクト指向に沿ったものですが、変更に強い構造を作るための手法や考え方は他のプログラミングパラダイムでも活用できるものになっています。 この本から影響を受けた点/学んだこと この本を読んだことで、高凝集・疎結合であることで変更しやすい構造になるということを知識としてだけではなく、具体的に実践するための手法・考え方をベースに設計を考えるようになりました。この考え方は直接的にではないですが、フロントエンド開発に主軸を移してもからもコンポーネント設計や共通ロジックの切り出しなどを検討する際に活かされています。 特に印象に残った部分 全体を通して「変更を楽にするため」の手法について触れていたことが印象に残っています。特にドメインオブジェクト(ドメインに紐づくデータとロジックを扱うことに特化したオブジェクト)を使用した関心ごとの分離について言及しており、コードの整理だけでなく業務ドメインに対する理解を深めることが良い設計をする上でも重要であることを学びました。 例として取り上げるサンプルコードの題材が発注システムなど実践的なものだったので、よくあるサンプルコードのような「定義はわかるけど実際にどう扱うのか?」がイメージしづらいようなことはなく読みやすかったです。 このような方におすすめ プログラミングを始めて、コードの書き方はわかったけど設計ってどうすればいいのか?現場のコードベースが変更しづらいけどなぜだろう?など設計・オブジェクト指向について具体的なユースケースを見つつ学びたい方におすすめです。 おわりに 今回ご紹介した3名のエンジニアたちが人生を変えた一冊は、それぞれの専門分野や関心領域を反映した多様な選択でした。コンピューターの基礎原理からWebセキュリティ、そしてシステム設計まで、エンジニアとしての成長過程で出会った本が、その後のキャリアや技術的視点に大きな影響を与えていることがわかります。 技術書との出会いは、単なる知識の獲得だけでなく、問題解決の糸口や新たな視点をもたらしてくれるものです。皆さんも、自分の技術的な課題や興味に合わせた一冊を見つけ、エンジニアとしての視野を広げてみてはいかがでしょうか。 ファインディでは、さまざまなバックグラウンドを持つエンジニアが活躍しています。技術にこだわり、より良いものを追求する仲間とともに働いてみませんか? 現在、ファインディでは新しいメンバーを募集中です。 興味のある方は、ぜひこちらからチェックしてみてください!