TECH PLAY

Findy/ファインディ

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

181

こんにちは。 ファインディ株式会社でテックリードマネージャーをやらせてもらってる戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 弊社でも例に漏れず、生成AIを活用して開発効率の向上に取り組んでいます。その中でFindy Team+で開発組織の生産性をチェックしていたところ、Pull requestの質が落ちているのでは?という仮説が浮かび上がりました。 今回は仮説が浮かんできた経緯と、その対策として導入したセルフレビューの仕組みについて紹介します。 それでは見ていきましょう! 思っていたよりPull requestの数が増えていなかった 理解しないままレビュー依頼を出していた AIでセルフレビューを支援する仕組みを導入 まとめ 思っていたよりPull requestの数が増えていなかった 稼働人数は昨年比で1.5倍程度増えており、それと比例する形でPull requestの作成数も単純に1.5倍に増えていました。この図から、人数の増加とPull request作成数が概ね比例していることが分かります。 しかし、1人あたりのPull requestの作成数は、昨年とほぼ変わらずでした。この図を見ると、人数が増えても1人あたりのPull request作成数はほぼフラットであることが分かります。 生成AIにPull requestを作成してもらうのであれば、1人あたりの作成数も伸びて、増えた人数以上に総数も伸びるはずでは?ここが疑問ポイントでした。 Pull requestの数が多ければ必ずしも良いわけではありませんが、AIを導入しても1人あたりの数値が伸びていないということは、どこかしらに問題があるはずです。 Pull requestの作成数だけでは判断することが出来ないので、他の数値に目を向けてみました。すると、各種リードタイムが昨年比で悪化していることがわかりました。 その中でも私が特に目を付けたのが「レビューからApproveまでの平均時間」です。この数値が昨年比で平均約20分近くも伸びていたのです。 更に「平均コメント数」と「平均レビュー数」にも目を付けました。こちらも昨年比で30%近くも増えていたのです。 これらの数値の変化から、1つの仮説が浮かび上がりました。それは「レビューで指摘された内容の対応で各種リードタイムが伸びており、マージまでの時間が伸びて結果的にPull requestの作成数が伸びていないのでは?」ということです。 この仮説を一言で言うと、「作成されているPull requestの質が落ちているのでは?」と言い換えることもできます。仮説を整理できたので、その仮説が正しいのかどうかを検証することにしました。 理解しないままレビュー依頼を出していた AIが作成したPull requestを幾つか確認してみたところ、確かにセルフレビューである程度防げるような指摘が多く見受けられました。 例えばAIが次のようなテストコードを追加しているシーンがありました。 import { render, screen } from '@testing-library/react' ; it ( 'should render with isHiddenTitle' , () => { render(< HogeComponent isHiddenTitle />); expect ( screen .queryByText( "Title" )).not.toBeInTheDocument(); } ); 一見特に問題なさそうなテストコードですが、仮にテキストが常に非表示になっている状態だった場合、このテストコードは常に成功してしまいます。つまり、テストコードとしての意味を成していないのです。 特定の条件下で「表示されないこと」を守りたいのあれば、その条件下以外で「表示される」ことも同時に守る必要があります。この変更に対してはリードクラスのエンジニアからレビューで指摘が入り、次のようなテストコードになりました。 import { render, screen } from '@testing-library/react' ; it ( 'should render' , () => { render(< HogeComponent />); expect ( screen .getByText( "Title" )).toBeInTheDocument(); } ); it ( 'should render with isHiddenTitle' , () => { render(< HogeComponent isHiddenTitle />); expect ( screen .queryByText( "Title" )).not.toBeInTheDocument(); } ); このテストコードで文言が表示されること、特定の条件下のみで表示されないことの両方を守ることができるようになりました。 このように、AIが出力したコードを依頼主が理解しないままレビュー依頼を出しているケースが少なからず見受けられました。そしてそれらをレビューするリードクラスのエンジニアのレビュー負担が上がっており、結果的にマージまでのリードタイムが伸びている。という状態に陥っていたのです。 これらの多くは難しい問題点ではなく、セルフレビューの時点で気づくことが出来るような内容が大半でした。 AIが出力したコードの責任は人間にあります。 レビュー依頼を出す前に、まずセルフレビューをして、早い段階で問題点に気付けるように仕組みを作ることにしました。 AIでセルフレビューを支援する仕組みを導入 自動でレビューをしてくれるサービスも利用したのですが、汎用的な内容でのレビューなのでドメイン知識や個人の癖などを考慮出来ておらず、指摘内容としても薄いものが多く、レビュー依頼する前のセルフチェックという意味合いでは不十分でした。 そこで、自分自身にカスタマイズされたセルフレビューのチェックリストを作成する仕組みを内製することにしました。 流れとしてはこうです。 まず直近数カ月で自分が作ったPull requestの一覧を取得します。そのPull requestに対して作成されたレビューコメントを全て取得します。それらレビューコメントの全てをLLMに渡して、どういう内容や傾向で自分自身が指摘されているのかを分析後にチェックリストを作成します。 作成されたチェックリストに沿って、Claude Codeにセルフレビューしてもらいます。 一連の流れはこのようになります。 このシーケンス図から、チェックリストの生成からセルフレビュー、修正の反映までが一連のフローとして自動化されていることが読み取れます。 この一連の流れを全て自動で行うカスタムコマンドを作成し、Pluginsに入れて社内に展開しました。 チェックリストを更新するカスタムコマンドと、そのチェックリストを使ってセルフレビューを実行するカスタムコマンドは分けています。チェックリストは定期的に更新すれば良いので、セルフレビューの度に更新する必要はないからです。 まずチェックリストを作成するコマンドを実行して、次のようなファイルが出力されます。 # Self-Review Checklist for hoge このチェックリストは、過去3ヶ月間(2025年9月30日〜2025年11月26日)にマージされたPRとレビューコメントを分析して作成されました。 ## 🧪 テストコード ### アサーションの品質 - [ ] ` toEqual ` の代わりに ` toStrictEqual ` を使用しているか - より厳密な型チェックのため - [ ] テストケースは実装の意図を正確に検証しているか - [ ] スナップショットテストは適切に使用されているか ### テストの網羅性 - [ ] 主要な機能パスはすべてカバーされているか - [ ] エラーハンドリングのテストは含まれているか - [ ] エッジケースを考慮しているか ## 🎨 UI/UX 設計 ### アクセシビリティ - [ ] aria-label は適切に設定されているか - [ ] キーボード操作に対応しているか - [ ] カラーコントラストは十分か ## 🎯 コミットメッセージ ### Conventional Commits - [ ] プロジェクトのコミットメッセージ規約に従っているか - [ ] 適切な type を使用しているか(feat, fix, refactor, chore, etc.) - [ ] scope は正しく指定されているか --- **最終更新日**: 2025-11-28 **分析期間**: 2025-09-30 〜 2025-11-26 次にセルフレビューのコマンドを実行します。出力されたチェックリストの内容に沿って、変更箇所をレビューしてもらいます。実際の出力例は次のようになります。 > 変更箇所に対して、`self-review-check-list.md` の内容を元にレビューしてください ⏺ 変更箇所をレビューするために、まず self-review-check-list.md の内容を確認します。 ⏺ Search(pattern: "**/self-review-check-list.md") ⎿ Found 1 file (ctrl+o to expand) ⏺ Read(self-review-check-list.md) ⎿ Read 33 lines ⏺ Read(packages/feature-server/src/clients/github/github-client.spec.ts) ⎿ Read 863 lines ⏺ self-review-check-list.md の内容に基づいて、変更ファイルのレビューを実施しました。 レビュー結果 ✅ コード品質 命名の明確さ - 関数名や変数名が実際の動作を正確に表現しています - ドメイン用語(GitHub API関連)を正しく使用しています ✅ テストコード テストの網羅性 - 各関数に対して以下のテストケースを網羅しています: - すべてのパラメータを指定した成功ケース - 必須パラメータのみの成功ケース - エラーケース - toStrictEqual を使用してオブジェクト全体の検証を適切に行っています テスト依存関係 - 不要なテスト依存関係は追加されていません - プロジェクト標準のテストライブラリのみを使用しています ✅ プロジェクト固有のルール - TypeScript Deep Dive のスタイルガイドに従っています - ファイル名がケバブケース(github-client.spec.ts)になっています ⚠️ 改善提案 テストアサーションの統一性 packages/feature-server/src/clients/github/github-client.spec.ts:307 expect(response.data).toEqual(mockData); 他のテストケースでは toStrictEqual を使用していますが、ここだけ toEqual を使用しています。toStrictEqual に変更することを推奨します: expect(response.data).toStrictEqual(mockData); toStrictEqual は toEqual よりも厳密なチェック(undefined プロパティも検証)を行うため、より堅牢なテストになります。 --- 全体的に非常に高品質なテストコードです。上記の1点のみ修正すれば、チェックリストのすべての項目を満たしま す。 テストコードを変更した場合のセルフレビュー例ですが、コード品質やテストコード、プロジェクト固有のルールに関しては基本的にクリアしていましたが、改善提案として1点のみ指摘がありました。 このレビュー結果を元に、修正も自動で行ってもらいましょう。続いてプロンプトを実行します。 > レビュー結果を元に、変更箇所を修正してください ⏺ レビュー結果に基づいて修正します。 ⏺ Update(packages/feature-server/src/clients/github/github-client.spec.ts) ⎿ Updated packages/feature-server/src/clients/github/github-client.spec.ts with 1 addition and 1 removal 304 } 305 ); 306 expect(response.status).toBe(HttpStatusCode.OK); 307 - expect(response.data).toEqual(mockData); 307 + expect(response.data).toStrictEqual(mockData); 308 }); 309 310 it('fetch data with only required params', async () => { ⏺ 修正が完了しました。 修正内容 packages/feature-server/src/clients/github/github-client.spec.ts:307 変更前: expect(response.data).toEqual(mockData); 変更後: expect(response.data).toStrictEqual(mockData); この修正により、テストアサーションが統一され、すべてのテストケースで toStrictEqual を使用するようになりました。toStrictEqual は toEqual よりも厳密なチェック(undefined プロパティも検証)を行うため、より堅牢なテストになります。 これで self-review-check-list.md のすべての項目を満たすコードになりました。 この仕組みにより、定期的にチェックリストのファイルを更新することによって、セルフレビューの精度を上げ続けることが可能となります。 まとめ 今回はジュニアエンジニアがAIを使ってPull requestを作成した場合に、セルフレビューでのチェックが甘くなり、レビュワーの負担が上がっているといったケースでした。 「AIに使われる」のではなく、「AIを使う」ためにも、AIが出力したコードを理解することが必要不可欠です。AIが出力したコードの責任は人間にあります。自分自身の責任を果たす意味でも、生成AI時代のセルフレビューが持つ意味合いは、これまで以上に重要になってくるでしょう。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは。 ファインディ株式会社でFindy AI+の開発をしているdanです。 Findy AI+ではLLMを活用した分析機能を提供しています。 分析対象は個人・チーム・組織と幅広く、データ量に応じて分析に時間がかかることがあります。分析が完了するまで画面に何も表示されないと、ユーザーは処理が進んでいるのか分からず、待ち時間が長く感じられてしまいます。 この課題を解消するため、LLM分析結果の表示にストリーミング出力を導入しました。 今回は、実装内容とどの程度待ち時間が改善されたのかについてお話しします。 Findy AI+とは ストリーミング対応前は何が問題だった? 当初の設計 分析結果を見るのにどのくらいの時間を要していたのか どのように対応を進めたか ストリーミング対応の設計 肝となる実装の全体像 LangChainの astream() メソッド FastAPIでのストリーミング実装 ストリーミングレスポンスの生成 SSE(Server-Sent Events)の仕組み フロントエンドでの受信処理 ストリーミング対応後に得られた効果 おわりに Findy AI+とは Findy AI+ は、GitHub連携やプロンプト指示を通じて生成AIアクティビティを可視化し、生成AIの利活用向上を支援するサービスです。 人と生成AIの協働を後押しし、開発組織の変革をサポートします。 Claude Code、GitHub Copilot、Codex、Devinなど様々なAIツールの利活用を横断的に分析しており、分析基盤にはLangChainを採用しています。また、日報やチーム分析などの機能でもLLMを活用しています。 LLM分析に使用するプロンプト調整についても記事を公開していますので、よかったらご覧ください。 tech.findy.co.jp ストリーミング対応前は何が問題だった? 当初の設計 分析結果を見るのにどのくらいの時間を要していたのか 冒頭で述べた通り、Findy AI+では個人・チーム・組織と幅広いデータを分析対象としています。 分析に必要なデータ作成のAPIを例にあげます。 @ router.post ( "/api/v1/hoge" ) def create_hoge ( request: CreateHogeRequest, db: Session = Depends(get_db), ): # 1. データ取得 hoge = get_hoge(db, request.hoge_id) # 2. LLM呼び出し(全レスポンス待ち) client = Anthropic(api_key= "xxx" ) message = client.messages.create( model= "claude-sonnet-4-20250514" , max_tokens= 4096 , messages=[{ "role" : "user" , "content" : f "分析して: {hoge.content}" }], ) analysis_result = message.content[ 0 ].text # 3. 分析結果保存 save_analysis(db, hoge.id, analysis_result) # 4. レスポンス返却 return { "id" : hoge.id, "analysis" : analysis_result} やっていることは次の2つです。 LLM分析を行い完了後に分析結果を保存 フロントへデータを返す APIを呼び出してみると平均して30~40秒ほど時間がかかっていることが分かりました。 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 7341 100 6673 100 668 193 19 0:00:35 0:00:34 0:00:01 2059 実行してから分析結果を見るのに30~40秒程度かかるほど、遅すぎて使いものにならない状態でした。 どのように対応を進めたか ストリーミング対応の設計 新たに作成したストリーミングのAPIは下記の通りです。 肝となる実装の全体像 ストリーミング対応したサンプルコードは下記になります。 @ router.post ( "/api/v1/hoge/analysis/streaming" ) async def create_hoge_analysis_streaming ( request: AnalysisRequest, db: Session = Depends(get_db), ): # 1. データ取得 hoge = get_hoge(db, request.hoge_id) # 2. LangChainエージェント作成 agent = ChatAnthropic( model= "claude-sonnet-4-20250514" , anthropic_api_key= "xxx" , max_tokens= 4096 , ) # 3. StreamingResponse返却 return StreamingResponse( generate_streaming_response(agent, hoge, db), media_type= "text/event-stream" , ) async def generate_streaming_response ( agent: ChatAnthropic, hoge: Hoge, db: Session, ) -> AsyncGenerator[ str , None ]: """SSE形式でストリーミングレスポンスを生成""" accumulated_content = "" messages = [HumanMessage(content=f "分析して: {hoge.content}" )] # チャンクごとに送信 async for chunk in agent.astream(messages): if chunk.content: accumulated_content += chunk.content data = json.dumps({ "type" : "content" , "content" : chunk.content}) yield f "data: {data} \n\n " # 完了後にDB保存 save_analysis(db, hoge.id, accumulated_content) # 完了イベント送信 data = json.dumps({ "type" : "complete" , "content" : accumulated_content}) yield f "data: {data} \n\n " やっていることは次の2つです。 分析結果がチャンクで返ってくるので、そのままフロントに渡す 分析完了後に分析結果を保存・フロントに返す どのように分析結果をチャンク(断片したテキスト)形式で受け取るのかについて説明します。 これは、LangChainのストリーミングメソッドを使用することで実現可能です。 LangChainの astream() メソッド async for chunk in agent.astream(messages): print (chunk.content) # "Find" → "y AI+" → "AI利活用" のように少しずつ届く astream() は非同期ジェネレータを返し、LLM APIからのレスポンスをチャンク単位で受信できます。 通常の invoke() との違いは全文が返らないことです。 # invoke(): 全文が返るまで待つ result = agent.invoke(messages) # 数秒〜数十秒ブロック # astream(): チャンクごとに即座に処理できる async for chunk in agent.astream(messages): # 即座に開始 process(chunk.content) FastAPIでのストリーミング実装 @ router.post ( "/api/v1/hoge/analysis/streaming" ) async def create_hoge_analysis_streaming (request: AnalysisRequest): hoge = get_hoge(request.hoge_id) agent = ChatAnthropic(model= "claude-sonnet-4-20250514" , ...) return StreamingResponse( generate_streaming_response(agent, hoge), media_type= "text/event-stream" , ) StreamingResponse に非同期ジェネレータを渡すことで、yield するたびにクライアントへデータが送信されます。 ストリーミングレスポンスの生成 async def generate_streaming_response (agent, hoge) -> AsyncGenerator[ str , None ]: accumulated_content = "" messages = [HumanMessage(content=f "分析して: {hoge.content}" )] # チャンクごとにフロントへ送信 async for chunk in agent.astream(messages): if chunk.content: accumulated_content += chunk.content data = json.dumps({ "type" : "content" , "content" : chunk.content}) yield f "data: {data} \n\n " # 完了後にDB保存 & 完了イベント送信 save_analysis(hoge.id, accumulated_content) data = json.dumps({ "type" : "complete" , "content" : accumulated_content}) yield f "data: {data} \n\n " accumulated_content で全文を蓄積しDB保存の準備を行います yield f"data: {data}\n\n" でSSE形式でフロントへ送信することでストリーミング対応を行います SSE(Server-Sent Events)の仕組み StreamingResponse で media_type="text/event-stream" を指定することで、SSE形式でデータを送信できます。 SSEでは data: {JSON}\n\n という形式でイベントを送信します。クライアントはこのイベントを受信するたびに画面を更新できるため、LLMの出力をリアルタイムで表示できます。 data: {"type": "content", "content": "Findy "}\n\n data: {"type": "content", "content": "AI+では"}\n\n data: {"type": "content", "content": "..."}\n\n data: {"type": "complete", "content": "Findy AI+では..."}\n\n フロントエンドでの受信処理 フロントエンドでは fetch の ReadableStream を使ってストリーミングデータを受信します。 const response = await fetch ( '/api/v1/hoge/analysis/streaming' , { method : 'POST' , body : JSON . stringify ( { hoge_id : 123 } ), } ); const reader = response. body .getReader(); const decoder = new TextDecoder (); while ( true ) { const { done , value } = await reader.read(); if (done) break ; const chunk = decoder. decode (value); // "data: {...}\n\n" 形式のイベントをパース const events = chunk. split ( ' \n\n ' ). filter ( e => e. startsWith ( 'data: ' )); for ( const event of events) { const data = JSON . parse (event. replace ( 'data: ' , '' )); if (data. type === 'content' ) { // チャンクを画面に追加表示 appendText(data.content); } else if (data. type === 'complete' ) { // 完了処理 } } } このように、サーバー側でチャンクを yield するたびにフロントエンドで受信・表示することで、ユーザーは分析結果をリアルタイムで確認できます。 ストリーミング対応後に得られた効果 画面遷移から3秒程度で読み始めることができるので非常に使い勝手が良くなりました。 おわりに ストリーミング対応をしたことで分析に使用するデータ量が多くても逐一分析結果が表示されるようになりました。 LangChainを使用したストリーミング対応について少しでも参考になれば幸いです。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらからご応募ください。 herp.careers
アバター
こんにちは、Findy Freelanceでフロントエンドエンジニアをしている主計(かずえ)です。 この記事は、 ファインディエンジニア #3 Advent Calendar 2025 の25日目の記事です。 adventar.org Dependabotが作成するPRの対応、皆さんはどのように運用していますか?依存パッケージの更新は地味ながら継続的に発生する作業で、特に少人数チームでは対応工数の比率が無視できません。 この記事では、私たちのチームがDependabot PR対応を手動運用からDevin、そしてClaude Code Actionへと段階的に改善してきた過程を紹介します。それぞれのアプローチで得られた知見と、最終的にClaude Code Actionに落ち着いた理由をお伝えします。 Dependabot PRの対応フローを効率化したい方、AIツールを活用したコードレビューの自動化に興味がある方の参考になれば幸いです。2025年の変遷を書いているのでDependabot PRのAIレビューをこれから実施したい場合はClaude Code Actionのセクションを中心に見ていただければと思います。 手動時代 フロー 課題 Devinへ移行 Playbookとは SlackからPlaybookを呼び出して実行 承認時 非承認時 良かった点 運用していく中で見えてきたこと Claude Code Actionへ移行 bot作成PRでは動作しないためClaude Code Base Actionを利用 allowed_botsでClaude Code Actionへ移行 各CI完了後にレビューを実施 現在のフロー 承認時 非承認時 効果 注意点 ANTHROPIC_API_KEYはDependabot用のSecretに設定 WebFetchの不安定さ まとめ 手動時代 フロー Dependabot PRへの対応は、次のような流れで行っていました。 Dependabotが作成したPRを確認する CIの実行結果を待ち、成功・失敗を確認する 更新されたパッケージのリリースノートを確認し、Breaking Changesがないか調べる CIが失敗している場合は原因を調査し、必要に応じてコードを修正する 問題がなければレビューを行う マージする 一見シンプルなフローですが、実際に運用してみると様々な課題があります。 課題 まず、コンテキストスイッチのコストが大きいという問題がありました。Dependabot PRを順番にマージしていくと、他のPRとコンフリクトが発生してrebaseが必要になります。CIの実行を待っている間に別の作業を始め、CIが完了したら戻ってきて次のPRを処理する、という流れで作業が細切れになりがちでした。 リリースノートの確認も手間のかかる作業でした。Breaking Changesは基本的にCIが失敗するので気付けますが、稀にruntimeで問題が発覚することがあります。そのため、念のためリリースノートを確認してからマージするようにしていました。 また、人によってマージの判断基準にズレがあるという問題もありました。あるメンバーはCIが通っていればすぐにマージし、別のメンバーはリリースノートを細かく確認してからマージするといった具合です。リリースノートを確認するというルールは作れば防げますが、どれくらい詳細に確認するかなど個人の感覚に依存してしまいます。 少人数チームでは、こうした定型作業の工数比率が相対的に高くなります。週に数時間をDependabot PR対応に費やしていると、本来注力すべき開発作業に割ける時間が減ってしまいます。 Devinへ移行 こうした課題を解決するため、導入済みだったDevinのPlaybookをDependabot PRのレビューに活用してみることにしました。 Playbookとは DevinにはPlaybookという機能があります。これは繰り返し行うタスクの手順を定義しておき、再利用できる仕組みです。「Dependabot PRをレビューする」というPlaybookを作成しておけば、毎回同じ手順でレビューを実行できます。 次のような形でPlaybookに記載して繰り返し利用しておりました。 SlackからPlaybookを呼び出して実行 DevinはSlackと連携できるため、Slackから直接Playbookを呼び出すことができます。 「@Devin playbook:!hoge」とメンションするだけで、定義したPlaybookが実行される仕組みです。 レビューが実施されると各PRにコメントを残してくれます。 承認時 非承認時 良かった点 Devinを導入して良かった点は、1つのアクションで各PRのレビュー依頼が完結することでした。Slackでメンションするだけでレビューが始まるため、Devinの作業が完了した後は、各PRについたレビューを確認し、マージするだけで済むようになりました。 運用していく中で見えてきたこと 複数のDependabot PRが同時に作成された場合、一部のPRが漏れてしまうケースがありました。また、すでにレビュー済みのPRを再度レビューしてしまうこともありました。 これらはDevin自体の問題ではなく、1回の依頼で複数PRをまとめて処理させていた運用方法に起因する課題でした。DevinにはAPIが提供されているため、GitHub ActionsからPRごとにDevin APIを呼び出す仕組みを作れば解決できる課題と考えました。 Claude Code Actionへ移行 GitHub ActionsからDevin APIを呼び出す仕組みの構築を検討していたところ、Claude Code Actionがリリースされました。 Claude Code Actionは、名前の通りGitHub Actions上でClaude Codeを実行できるActionです。PRの作成やコメントをトリガーにして、自動でコードレビューやタスクの実行ができます。 PRごとにワークフローが実行されるため、「このPRに対してレビューを行う」というスコープが明確になります。公式のGitHub Actionとして提供されていることと、AIモデルを選択できることが決め手となり、Claude Code Actionへ移行することとしました。 bot作成PRでは動作しないためClaude Code Base Actionを利用 導入当初、Claude Code ActionにはDependabotのようなbotが作成したPRでは実行できないという制約がありました。 この制約を回避するため、Claude Code Base Actionを利用することにしました。Base Actionはbot作成のPRでも動作させることができ、機能的にもClaude Code Actionと同等のことができます。 allowed_botsでClaude Code Actionへ移行 その後、Claude Code Actionに allowed_bots オプションが追加されました。これにより、Dependabotが作成したPRでもClaude Code Actionを実行できるようになりました。 Claude Code Base Actionからの移行を行った理由は、機能的な差はほとんどないものの、他のCIワークフローとの一貫性を保つためでした。チーム内で複数のActionを使い分けるよりも、統一した方がメンテナンス性が高くなります。 各CI完了後にレビューを実施 Claude Code Base Actionのワークフローはlint、test、typecheckなどのCIジョブが完了した後にClaude Code Base Actionを実行するようにしました。そうすることで、CIの結果を踏まえたレビューができます。 CIの流れは次のようなイメージです。 jobs: test: ...(省略)... lint: ...(省略)... typecheck: ...(省略)... claude-review-for-dependabot-pr: name: Claude Review for Dependabot PR # `always()`を指定しCIが失敗しても実行 if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' && always() }} # 各CIの結果が欲しいので終了してから実行 needs: [test, lint, typecheck] ...(省略)... steps: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Claude Review for Dependabot PR uses: anthropics/claude-code-action@f0c8eb29807907de7f5412d04afceb5e24817127 # v1.0.23 with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} github_token: ${{ github.token }} show_full_output: false #デバッグしたいときはshow_full_outputをtrueにして確認 allowed_bots: dependabot claude_args: | --allowedTools "View,GlobTool,GrepTool,BatchTool,Bash(gh auth status),Bash(gh pr view:*),Bash(gh run list:*),Bash(gh pr comment:*),Bash(gh pr review:*),Bash(gh pr diff:*),Bash(gh pr checks:*),Bash(gh run view:*),Bash(gh release view:*),Bash(git log:*),Bash(git status:*),Bash(git diff:*)" --model claude-opus-4-5-20251101 prompt: | (プロンプト例は下記に記載) プロンプト例 ## 命令 CI実行中のDependabotのプルリクエスト #${{ github.event.pull_request.number }} を評価しマージして問題ないか判断してください ## 手順 1. プルリクエストを確認(gh pr view ${{ github.event.pull_request.number }}) 2. package.jsonとpackage-lock.jsonの差分を確認 3. バージョン差分から公式リリースノートとGitHubのリリースを確認しライブラリの変更内容を把握(gh release view) 4. test, lint, typecheckの実行結果を確認(gh pr checks ${{ github.event.pull_request.number }}) 5. test, lint, typecheckが失敗していた場合、ログを確認(gh run view) 6. 既存コードや他ライブラリのバージョンとの整合性を確認 7. 変更内容を評価しフォーマットに沿ってプルリクエストにレビューコメント(日本語)を1件投稿 ## フォーマット ``` # {ライブラリ名} x.x.x -> x.x.x ## 評価結果 ✅ 承認 / ⚠️ 確認が必要 / ❌ 要対応 / etc... ## ライブラリの変更内容 - 変更内容1 - 変更内容2 ## リスク、注意事項 - リスク1 - リスク2 ## 必要な対応 - 対応1 - 対応2 ``` ## 注意事項 - 承認する場合:`gh pr review {プルリクエスト番号} --approve --body "{BODY}"` - 承認しない場合:`gh pr comment {プルリクエスト番号} --body "{BODY}"` - 実行時に足りない権限があった場合はコメント ## 追加確認項目 - Breaking Changesの有無 - セキュリティ脆弱性の修正状況 - 他の依存関係への影響 他のCIジョブの完了を待ってからActionを実行することで、CIが失敗している場合は「なぜ失敗したか」の分析をさせることができます。失敗ログから原因を特定し、次に取るべきアクションをPRコメントとして残すことができます。 対応すべきことがわかれば対応時の工数感がわかりすぐ取り掛かるかタスクとして積んでおくかの判断がしやすいです。 現在のフロー DependabotがPRを作成する lint、test、typecheckのCIジョブが実行される CIジョブ完了後、Claude Code Actionが実行される Claude Code Actionが更新内容の要約、リリースノートの重要ポイント、CI失敗時の原因分析と修正提案をPRコメントとして残す 人間がコメントを確認し、最終判断を行う 問題なければマージする 人間が行う作業は「Claude Code Actionのコメントを確認して最終判断する」ことに集中できるようになりました。 承認時 非承認時 効果 この改善により、Dependabot PR対応にかかる工数が週あたり約30分〜1時間削減されました。 削減される主な内訳としては、リリース内容の確認と対応要否の調査にかかる時間です。 必要な対応が出力されるのですぐ対応するかタスクとして積むかの判断がしやすくなったのは良かったと感じます。 また、レビューの観点がプロンプトで統一されているため、属人性が低下しました。誰が対応しても同じ基準でレビューが行われます。 コンテキストスイッチのコストも低下しました。コンフリクトしたPRは自動でrebaseと再レビューがされるため、自分の切りがいいタイミングでマージするだけで済むようになりました。 注意点 ANTHROPIC_API_KEYはDependabot用のSecretに設定 ANTHROPIC_API_KEY はGitHub ActionsのSecretsだけでなく、Dependabot側のSecretsにも設定する必要があります。Dependabotが作成したPRでは、通常のRepository Secretsにアクセスできないためです。 設定場所は https://github.com/{Org}/{Repo}/settings/secrets/dependabot です。これを忘れると、Dependabot PRでClaude Code Actionが動作しません。 WebFetchの不安定さ 当初、リリースノートの取得にWebFetch機能を使っていましたが、フリーズすることがありました。(2025年11月ごろ) 対策として、外部情報の取得は gh コマンドを使う方針に変更しました。GitHub CLIを使ってリリース情報を取得する方が安定性と再現性が高く、トラブルが減りました。 Claude Code側でWebFetchがフリーズするissueがいくつかあります。 show_full_output を有効化してもログが表示されないため直接的な原因は掴めていませんが、現状では gh コマンドで必要な情報は取得できているので allowedTools から WebFetch は一時的に除外しています。 github.com まとめ Dependabot PR対応を手動運用からDevin、そしてClaude Code Actionへと改善してきた過程を紹介しました。 定期的に発生する作業は自動化すると効果が大きいです。特にDependabot PRのような「PRごとに自動でトリガーされる」タイプのタスクには、GitHub Actionsと連携するClaude Code Actionが適していました。 今後の課題としては、Claude Code ActionがApproveしたPRを自動マージする仕組みの導入を検討しています。現在nxを利用したモノレポで運用しており、ユニットテストやVRTは各アプリで整備できています。ただし、管理画面など一部のアプリではE2Eテストが未整備のため、まだ自動マージには踏み切れていません。E2Eテストを拡充し、自動マージしても安全という確信を持てる体制を整えていきたいと考えています。 上記のように、AIのガードレール整備が重要なのでテスト等をしっかりやっていくことは今後さらに重要になってくると再認識しました。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
この記事は「 ファインディエンジニア #1 Advent Calendar 2025 」の24日目の記事です。 沢山のアドベントカレンダー記事が執筆されていますので、年末のお供に是非読んでみてください。 adventar.org はじめに ソフトウェアエンジニアの 土屋(@shunsock) です。私の所属するデータソリューションチームでは、ファインディ全体のデータ活用を推進するためのデータ基盤を構築しています。 今回、我々はデータ基盤のRDSとBigQueryのテーブル同期システム (EL Pipeline) のリプレースを行い、 DuckDBを本番導入 しました。本稿では、活用に至った経緯と実際に組みこむにあたる課題、および成果を紹介します。 はじめに ファインディにおけるテーブル同期システムの立ち位置 リプレイスの背景 補足 技術選定 Datastream DuckDB Datastream, DuckDB両採用の理由 システム設計 概要 CLIを挟む理由 GitHub Actionsからの起動にした理由 複数のRDSを転送する 開発運用と成果 開発・運用してみた感想 可読性と拡張性が高い とはいえまだまだ新興のソフトウェア まとめ ファインディにおけるテーブル同期システムの立ち位置 ファインディでは、ウェブアプリケーションをAWS上のECSとRDS、データ基盤をGoogle CloudのBigQueryで作成しています。 このような構成を取っているため、AWSのRDSとGoogle CloudのBigQueryを同期してテーブルを最新にする必要があります。 次の図は、Findy Tools事業部における、現在のデータフローの概念図です。AWS上に存在するRDSのデータをBigQueryに転送していることが分かります。 リプレイスの背景 弊社では従来、OSSのEL(Extract Load) ツール  Embulk  をECSに載せて長期間運用していました。弊社で利用しているRDBMSやデータウェアハウスに対応している他、社内に知見を持った方が在籍しているためです。 しかし、近年では、 Embulkのエコシステムのレガシー化や 長期的なメンテナが不足 が課題 となっています。特に、 将来のメンテナンスが不透明な点は、セキュリティインシデントに繋がりかねない ため危惧していました。 また、 Embulkの起動の遅さも課題 にしていました。我々はBigQueryプラグインなどを利用していたため、JVM上でさらにJRuby VMを立ちあげます。このような構成は テーブル同期の遅さに繋がり、ECSの課金額を増やす要因 となっていました。 このように、システムを堅牢にすることと処理スピード向上による料金のコストダウンが今回のプロジェクトの目的でした。 補足 Embulkのメンテナーの方も 「オープンソース・プロジェクトのたたみ方」 というブログ記事で脆弱性について次のように述べています。 おそらくいくつかの攻撃は既に成功していて、私たちのソフトウェア・サプライチェーンには、悪意のあるコードがとっくに入り込んでいる、と認識しておくべきでしょう。 技術選定 Datastream, Spark, その他 ELTツールなど、複数の移行先候補がありました。その中で、データ規模に応じて次の2つから選定することにしました。 Datastream: ニアリアルタイムでの更新が欲しい場合や大規模データの場合 DuckDB: 小規模データの場合 Datastream Datastream は Google Cloudが提供するサーバーレスのCDC (Change Data Capture), Replicationツールです。 CDCは、あるソースのシステムを監視し、そのシステムに対する操作をニアリアルタイムで、ターゲットとなるシステムに反映する仕組みのことです。これによりAWSのRDSに対する変更を即座にBigQueryに反映可能です。 DuckDB DuckDB は高速なアナリティカルデータベースです。s3などのストレージサービスに出力されたログ分析やファイルフォーマットの変換、wasmによるフロントエンドでの活用など広い用途で活用されています。 接続先や出力フォーマットが非常に豊富な他、C++製のマルチスレッドランタイムにより、高速に動作する点が魅力です。 次の写真はDuckDBのPoC時に行なったベンチマークです。小さなテーブルで転送を試したところ、 1.5倍程度の高速でした 。 ソフトウェア名称 平均 標準偏差 最速 最遅 Embulk 253秒 8秒 242秒 261秒 DuckBD 176秒 30秒 137秒 209秒 補足: 実際にパフォーマンステストを行ったときの様子 Datastream, DuckDB両採用の理由 今回のリプレイスでは、コスト最適化を軸に Datastream と DuckDB の2種類のアプローチを使い分ける構成を採用しました。 DatastreamはフルマネージドでサーバーレスなCDCサービスと強力です。一方で、ニアリアルタイム性が不要な小規模データに対しては機能過多となり、費用面でも割高になります。そこで、リアルタイム性を求めない領域では、より軽量でシンプルに扱えるDuckDBを使って同期を行う方針を取りました。 本記事の以降では、上記のうち、DuckDBによってどのようにテーブル同期システムを構築したか、開発運用で見えた知見を説明します。 システム設計 概要 次の画像は我々のDuckDBによるテーブル同期システムの概念図です。 次のように各種ソフトウェアが起動します。 GitHub Actionsの on_schedule でワークフローが起動 ワークフローがECS Fartate Taskを起動 Fargate Taskがコンテナランタイムを起動 コンテナランタイムの中でCLIアプリケーションが起動 CLIアプリケーションが引数と設定ファイルからSQLを生成 CLIアプリケーションがDuckDBでSQLを実行 CLIを挟む理由 DuckDBを直接起動しない理由は、1回の実行で1テーブルずつ送信できるようにするためと、SQLを直接書かずに設定ファイルをインターフェースにするためです。 実際のユーザーの入力インターフェースは次のようなYAMLです。 dataset_id : lake... table_name : table_name select_statement : "hoge, fuga, ..." GitHub Actionsからの起動にした理由 元々のワークフローはEventBridge Schedulerだったのですが、システム障害時にEventBridgeのcronを変更するなど運用負荷が重い状態でした。 DispatcherをGitHub Actionsにすることでボタン操作だけで検証可能にしました。 また、1テーブルずつの送信にしたので、ステージング環境での動作検証も簡単かつ軽量です。ユーザーは次のようなWorkflow Dispatchを起動するだけで動作検証が完了します。 複数のRDSを転送する 現在のFindy Tools事業部のワークフローを見ると分かる通り、複数のRDSを転送する必要がありました。そこで開発用スクリプトを汎用化して動的なビルドやawsコマンドの発火をしています。 開発運用と成果 開発は、私1人で1か月弱でしました。最初の1プロジェクトこそ時間がかかったものの、モノレポ構成にしたおかげで 従来1か月かかった新規データソースの追加が1週間程度になりました。 処理速度については、直列稼動から並列稼動へ変更となったため単純な比較は難しいのですが、 1テーブルあたり約30秒から約10秒に短縮 できました。 すでに他のメンバーからもプルリクエストが届いており、社内でも手応えのある反応を得ています。 開発・運用してみた感想 可読性と拡張性が高い 今回作成したCLIでは次のようなSQLを生成しています。高い拡張性や可読性が良いと改めて感じました。 INSTALL mysql; LOAD mysql; ATTACH '' AS mysqldb ( TYPE mysql); -- 環境変数から取ってくる CREATE TABLE users AS SELECT * FROM mysqldb.table_name; INSTALL bigquery FROM community; LOAD bigquery; ATTACH '' as bq ( TYPE bigquery); DROP TABLE IF EXISTS bq.lake__system_name.table_name; CREATE TABLE bq.lake__system_name.table_name AS SELECT * FROM table_name; DROP TABLE table_name; 拡張についても、次のCore Extensionsの他にCommunity Extensionsがあります。DB以外にもSpreadSheetなど幅広いツールが対応しているので、興味を持った方は確認してみると良いと思います。 duckdb.org とはいえまだまだ新興のソフトウェア DuckDBは新興のソフトウェアということもあり、普通にバグがあったりします。例えば次のIssueは、私がDuckDBのMySQLのプラグインのATTACH句に存在したバグを報告したものです。(既に解決済みです) github.com また、拡張によっては、サポートしているOSが限られていることがあります。私が作成した時期では、BigQuery拡張でarm64 linuxがサポートされておらず、Fargateをamd64で立てていました。なお、こちらも現在は対応しているようです。 github.com まとめ 今回の取り組みで、我々の テーブル同期システムはより高速、堅牢になりました。 さらに、ユーザーインターフェースが洗練され、 チームメンバーの利用しやすいソフトウェアとなりました。 データソリューションチームでは一緒に事業部横断データ基盤を作る仲間を募集しています。気になる方は是非次のフォームからカジュアル面談に応募してみてください!! herp.careers
アバター
こんにちは。 ファインディ株式会社でFindy AI+の開発をしているdanです。 今回は、プロンプトにどのようなデータや指示内容を与えるとLLMが誤った出力をしやすいのかについてお話しします。 プロンプトには何を書くべきで、何を書かないべきなのか。また、LLMに渡すデータはどのような形であるべきなのか。私自身が経験した実際の例をあげて解消までのアプローチ方法をご紹介します。 分析の精度をあげるにはここで紹介する内容では不十分ですが、入門編として参考になれば幸いです。 この記事はファインディエンジニア #3 Advent Calendar 2025 23日目の記事です。今月から、たくさんのアドベントカレンダー記事が執筆される予定ですので、ぜひ読んでみてください。 adventar.org Findy AI+とは 誤解していたプロンプト調整 良くない手法1: システムプロンプトにUTCから日本時間に変換する指示を与える 良くない手法2: 分析に使用するデータを加工する指示をシステムプロンプトに与える あるべき手法 システムプロンプトはどのような振る舞いで分析をしてほしいのかを書く 分析に使用するデータを加工してからLLMに渡す おわりに Findy AI+とは Findy AI+ は、GitHub連携やプロンプト指示を通じて生成AIアクティビティを可視化し、生成AIの利活用向上を支援するサービスです。 人と生成AIの協働を後押しし、開発組織の変革をサポートします。 Claude Code、GitHub Copilot、Codex、Devinなど様々なAIツールの利活用を横断的に分析しており、分析基盤にはLangChainを採用しています。また、日報やチーム分析などの機能でもLLMを活用しています。 こうした特性から、Findy AI+ では「何をどう分析するか」を定義するためのプロンプトが、サービスの価値を左右する重要な要素となります。 誤解していたプロンプト調整 良くない手法1: システムプロンプトにUTCから日本時間に変換する指示を与える 初期のシステムプロンプトは次の通りです。 # System Prompt ## Overview You are expert of developer experience and developer productivity. Your Timezone is Asia/Tokyo (UTC+9). Your Language is Japanese. The Timezone for the creation datetime of the Pull request is UTC. 上記はすごくシンプルなシステムプロンプトです。 このコードでは次のことを書いています。 LLMがどのような役割を担うのか タイムゾーンはどこを使用するのか どの言語で出力するのか プルリクエストの作成日時がUTCであること このシステムプロンプトを使用してプロダクトから分析ツールを実行すると次のような出力結果になりました。 システムプロンプトには使用してほしいタイムゾーンがUTC+9(日本時間)であることと、LLM分析に使用するデータはUTCであることを明記しています。 その結果、LLMは分析中に与えられたUTCのデータをJSTに変換する推論処理を行う必要があり、意図しない日付のズレが発生しました。 良くない手法2: 分析に使用するデータを加工する指示をシステムプロンプトに与える ユーザーからの自由入力による追加分析を行うと実際とは異なる日時が分析結果として返ってきました。 そのため次のようにシステムプロンプトを調整しました。 # System Prompt ## Overview You are expert of developer experience and developer productivity. ## Current Date Today's date is {current _ date} (YYYY-MM-DD format in UTC timezone). When you see dates in the data provided, interpret them according to this current date. For example, if today is 2025-10-08 and the data shows "2025-10-06 to 2025-10-12", this is the current week, not a future or past week. Your Timezone is Asia/Tokyo (UTC+9). Your Language is Japanese. The Timezone for the creation datetime of the Pull request is UTC. このコードでは次のことを書いています。 LLMがどのような役割を担うのか 現在日時の明記 現在日時は明記されたものを使用し過去を参照しないこと タイムゾーンはどこを使用するのか どの言語で出力するのか プルリクエストの作成日時がUTCであること このシステムプロンプトを使用してPRの分析を行った後、「日曜日に稼働したりしてないよね?」と追加で質問しました。LLMはGitの活動ログから曜日を判定して回答しますが、次のような出力結果になりました。 実際の曜日とLLMが出力した曜日を比較すると、2025年11月17日は月曜日ですが日曜日で出力されてしまっていることが分かります。 システムプロンプトに現在日時の明記と過去を参照しない旨を明記しています。 また期間指定の範囲についても具体的に指示しています。 その結果LLMは現実と過去について言及されている部分で混乱し、誤った推論による出力ミスが起きてしまいました。 あるべき手法 システムプロンプトはどのような振る舞いで分析をしてほしいのかを書く システムプロンプトにデータの加工、時間変換など処理の具体的な内容を書いてしまうと上記で紹介したような誤った推論を誘発してしまう可能性が高いです。 そのため、役割・言語・フォーマットなどシンプルな内容で最低限のみ書くのが良いです。 最終的には次のようなシンプルなシステムプロンプトになりました。 # System Prompt ## Overview You are expert of developer experience and developer productivity. ## Current DateTime Current datetime is {current _ datetime _ jst} ## Important Rules - When data includes weekday information (e.g., "月曜日", "火曜日"), use it as-is. Do NOT recalculate weekdays yourself. Your Language is Japanese. このコードでは次のことを書いています。 LLMがどのような役割を担うのか 現在日時は変換済みのJSTで渡す 渡されたデータをそのまま使うよう指示する どの言語で出力するのか 分析に使用するデータを加工してからLLMに渡す 分析に使用するデータは、システムプロンプトへ渡す前に加工済みのものを用意した方が良いです。 システムプロンプトにUTCからUTC+9(日本時間)の変換をするように書くべきではありません。 LLMに渡すデータは変換済みのデータにしておきましょう。 例えば、PRのデータをLLMに渡す場合を見てみましょう。 GitHubのPR情報をAPIから取得する場合、日時に関するレスポンスはUTCで返ってきます。 次の手順で、LLMに渡すデータを変換し分析を行います。 ・GitHubのAPIから取得したPR作成日時をUTCからUTC+9(日本時間)に変換する def format_datetime_jst (pr_utc_datetime: str ) -> str : # UTCの日時文字列をJSTに変換 utc_dt = datetime.fromisoformat(pr_utc_datetime.replace( "Z" , "+00:00" )) jst_dt = utc_dt.astimezone(JST) # 曜日も付与してフォーマット weekday_jp = WEEKDAYS_JP[jst_dt.weekday()] return jst_dt.strftime(f "%Y/%m/%d ({weekday_jp}) %H:%M:%S UTC+9" ) # 実行例 format_datetime_jst( "2025-11-17T08:53:32Z" ) # => "2025/11/17 (月曜日) 17:53:32 UTC+9" ・変換したデータを分析コンテンツに格納する analysis_content = f """ # Pull Request Analysis - PR1 Created: {format_datetime_jst(pr1.get("created_at", ""))} - PR2 Created: {format_datetime_jst(pr2.get("created_at", ""))} - PR3 Created: {format_datetime_jst(pr3.get("created_at", ""))} """ ・分析コンテンツを使用してLLMに分析を依頼する llm.invoke([ # 「システムプロンプトはどのような振る舞いで分析をしてほしいのかを書く」で紹介したシステムプロンプト { "role" : "system" , "content" : system_prompt}, { "role" : "user" , "content" : analysis_content} ]) このように変換済みのデータをLLMに渡すことで、LLMが日時の計算や曜日の判定を行う必要がなくなり、誤った出力を防ぐことができます。 おわりに 今回は、LLMにデータ加工や時間変換を任せると誤った推論を誘発しやすいことをご紹介しました。システムプロンプトには役割や出力形式などシンプルな指示のみを書き、データはあらかじめ加工してから渡すことで、分析精度を向上させることができます。 プロンプトの書き方ひとつでLLMの出力は大きく変わります。この記事が、皆さんのLLM活用の参考になれば幸いです。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらからご応募ください。 herp.careers
アバター
こんにちは。 2025 年 9 月にファインディに入社し、 Platform 開発チームで SRE を担当している富田( @Cooking_ENG )です。 この記事は、 ファインディエンジニア #2 Advent Calendar 2025 の 23 日目の記事になります。 adventar.org 今回は、ファインディのサービスの1つである「 Findy Conference 」の インフラ環境の運用トイル を改善した話を紹介します。 Findy Conference とは Findy Conference とは、テックカンファレンスに特化したプラットフォームサービスです。 国内外のカンファレンスに関する情報・体験を一元化し、主催者・参加者・スポンサーをつなぐことで、テックカンファレンスの体験を最大化することを目指します。 参加者は関心のあるイベント情報や CFP(発表募集)、イベントのタイムテーブルを見逃さずに把握でき、主催者は集客や受付管理、データ活用といった運営にかかるコスト・工数を最小化できるようになります。 conference.findy-code.io Findy Conference のトラフィックの特徴 Findy Conference のトラフィックには、一般的な Web サービスとは異なる、カンファレンス特有の 瞬間的なスパイク が多く発生するという特徴があります。 特にスパイクが起こりやすいタイミングは次の 2 点でした。 受付が始まったタイミング セッションの始まりと終わりのタイミング このうち、特に負荷が高かったのが セッションの始まりと終わりのタイミング です。 原因は次のような、 オンライン配信におけるカンファレンス参加者の方々の動き によって起こるものでした。 セッション中は参加者の方々は配信セッションを視聴しているため、Findy Conference のポータルサイトなどにアクセスすることは少ない。 セッションが終了するタイミングで、次のセッションの配信場所やチャンネル切り替えを行うため、セッションを視聴していた方々が一斉に Findy Conference のポータルサイトにアクセス。 その結果、一気にアクセスが集中し、スパイクが発生! この一連の流れにより、インフラに瞬間的な高負荷がかかっていました。 オートスケールが発動しない Findy Conference の環境は Amazon ECS と AWS Fargate (以降 ECS/Fargate) を使って構築しています。 ECS/Fargate であれば、オートスケールが発動するのではないか?という疑問を持つ方もいらっしゃると思います。実際に、Findy Conference の環境でも、CPU 使用率が設定している閾値を超えたらオートスケールが発動するように設定していました。 しかし、実際の運用では CPU 使用率が設定している閾値を超えてもオートスケールが発動せず、高負荷時にユーザー体験を維持できないリスクが生じていました。 オートスケールが発動しなかった原因は「アクセス集中が瞬間的すぎる」という点にありました。 短時間の高トラフィック・スパイクにより、オートスケールが発動に必要な時間を満たせず、新しいコンテナが立ち上がる前に CPU 使用率が下がってしまう Fargate の起動が少し遅いという特性も影響 結果として、カンファレンス中に上記のような瞬間的な高負荷がかかっても、 コンテナ数はスケールせず終わってしまう という状況でした。 (参考までに、こちらは過去のオブザーバビリティカンファレンスでの CPU グラフです。同時刻にオートスケールが発動していないことがわかります。) これまでのカンファレンス開催時の SRE の対応 上記の問題を回避するため、以前は「カンファレンス開催前に、Platform 開発チーム SRE メンバー(以降、SRE チーム)が AWS の Production 環境に入り、手動でコンテナ数を増やし、カンファレンス終了後にコンテナ数を元に戻す」という対応をしていました。 スパイク時の対策としては、当時はコンテナ台数を増やす以外に現実的な選択肢がなく、人手によるスケール対応に頼らざるを得ない状況でした。 この手動オペレーションは、次のようなトイルを生み出していました。 カンファレンス運営の方との連携が必須: カンファレンスが開催される日程共有の段階でコミュニケーションミスが発生した場合、急いで対応する必要がある。 ペアオペ作業のため 2 人分の工数が発生する: Production 環境で作業をするセンシティブな作業のため、ペアオペが必須となり、2 人分の時間が取られる。 複数環境の調整: フロントエンドとバックエンドなど、複数の環境で調整が必要なため、作業量、作業時間が多くなる。 オペレーション・リスク: そもそも Production 環境を手作業で触るので、作業ミスが発生するリスクがある。 実際、最近開催されたアーキテクチャカンファレンスでは、関連する複数環境のコンテナ調整に 2 時間近く要してしまいました。 カンファレンスが開催されるたびに、この手動作業の負荷が大きいと考え、トイルを抜本的に改善する必要があると判断しました。 GitHub Actions の workflow と AWS CLI で自動化 このトイルを撲滅すべく SRE 以外でも素早くコンテナ調整をできるようにするために、今回は AWS CLI と GitHub Actions の workflow_dispatch を組み合わせて、Production のマネジメントコンソールに入らなくても GitHub 上からコンテナ数を調整できるようにしました。 これにより、必要な権限を持ったユーザーが、安全かつ簡単にコンテナ調整を行えるようになりました。 コードの全体像 以下が、コンテナ数をスケールさせるための GitHub Actions のワークフロー全体像です。 scale-containers.yml name : Scale Containers run-name : Conference Scale Containers to ${{ github.event.inputs.container_count }} in ${{ github.event.inputs.environment }} on : workflow_dispatch : inputs : environment : type : environment required : true default : staging container_count : description : "containers_count" type : choice required : true options : - xx - yy - zz permissions : id-token : write contents : read jobs : scale-containers : runs-on : ubuntu-slim environment : ${{ github.event.inputs.environment }} steps : - uses : actions/checkout@v5 with : fetch-depth : 0 token : ${{ secrets.GITHUB_TOKEN }} - name : Configure AWS credentials uses : aws-actions/configure-aws-credentials@v5 with : role-to-assume : ${{ secrets.AWS_ROLE_ARN }} aws-region : ap-northeast-1 - name : Scale Backend ECS containers run : | CLUSTER_NAME="backend-${{ github.event.inputs.environment }} " SERVICE_NAME=" backend-${{ github.event.inputs.environment }} " echo "🔄 Scaling Backend containers to ${{ github.event.inputs.container_count }}" # 1. ECSサービスのDesired Countを更新 aws ecs update-service \ --cluster "$CLUSTER_NAME" \ --service "$SERVICE_NAME" \ --desired-count ${{ github.event.inputs.container_count }} # 2. オートスケールの最小キャパシティもワークフローでの設定値に合わせる aws application-autoscaling register-scalable-target \ --service-namespace ecs \ --scalable-dimension ecs:service:DesiredCount \ --resource-id "service/$CLUSTER_NAME/$SERVICE_NAME" \ --min-capacity ${{ github.event.inputs.container_count }} \ --max-capacity [ xx ] echo "✅ Backend containers scaled successfully" - name : Scale Frontend ECS containers run : | CLUSTER_NAME="frontend-${{ github.event.inputs.environment }} " SERVICE_NAME=" frontend-${{ github.event.inputs.environment }} " echo "🔄 Scaling Frontend containers to ${{ github.event.inputs.container_count }}" aws ecs update-service \ --cluster "$CLUSTER_NAME" \ --service "$SERVICE_NAME" \ --desired-count ${{ github.event.inputs.container_count }} aws application-autoscaling register-scalable-target \ --service-namespace ecs \ --scalable-dimension ecs:service:DesiredCount \ --resource-id "service/$CLUSTER_NAME/$SERVICE_NAME" \ --min-capacity ${{ github.event.inputs.container_count }} \ --max-capacity [ xx ] echo "✅ Frontend containers scaled successfully" ※実際のワークフローの画面です。 ワークフローの実装ポイント workflow_dispatch による手動実行 inputs で environment(環境名)と container_count(コンテナ数)を入力値として受け付けます。 container_count は choice にすることで、設定可能な値に制限を設け、誤入力を防いでいます。 コンテナ数と同時に最小コンテナ数の設定値も合わせる aws application-autoscaling register-scalable-target を実行し、オートスケールの --min-capacity もワークフローでの設定値に合わせるようにしています。この設定はコンテナ数を増やしても、オートスケールが最小キャパシティまでコンテナ数を減らしてしまう可能性を防ぐためです。 本ワークフローの導入により、Findy Conference のコンテナ調整は、誰でも GitHub Actions の画面から数クリックで実行できるようになり、SRE チームの負荷が軽減されました。また、既にカンファレンス開催に関わる複数の環境全てに横展開を完了しています。 この改善によって、SRE チームが約 2 時間かけて行っていたペアオペ作業は解消されました。 加えて、手動オペレーションのリスクも排除され、 必要な権限を持った開発者やカンファレンス担当者が安全にコンテナ調整を行える運用体制 を整えることができました。 おわりに 今回は Findy Conference のスパイクの起こりやすいトラフィック課題に対して、GitHub Actions と AWS CLI を用いて運用オペレーションを自動化・トイル削減した事例をご紹介しました。 トイル削減は SRE の永遠のテーマですが、エンジニアが気持ちよく開発に取り組める環境づくりや、安心して運用できる体制に繋がるため、これからも積極的に進めていきたいと思います。 最後までお読みいただきありがとうございました! ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。ファインディのTeam+開発部でエンジニアをしている古田(ryu-furuta)です。 この記事は、 ファインディエンジニア #2 Advent Calendar 2025 の22日目の記事です。 はじめに 2025年下期、私は「DevとOpsを融合する」というミッションを掲げ、問い合わせやアラートといった運用業務の改善にAIをいくつか活用していきました。 この記事では、Claude Code GitHub ActionsやNotion MCPを使った運用業務改善の具体的な実装方法を紹介します。 また、効率化を実現した先に見えてきた「次にやるべきこと」についても共有します。 AIを活用した運用改善を検討している方や、改善施策を打っても成果が出ないと悩んでいる方に読んでいただけると幸いです。 はじめに 問い合わせやアラートに生じていた課題 Claude Code GitHub Actionsでアラートの初期調査コストを削減 Notionのデータベースで問い合わせのチケット管理とデータ蓄積 Notion MCPを使って過去事例の検索と自動調査 取り組みの成果 今後の取り組み:根本原因の特定と改善の仕組みづくり まとめ 問い合わせやアラートに生じていた課題 私が携わる Findy Team+ はエンジニア増加による開発チームの細分化・多数の機能リリース・連携するサービスの増加といった変化の中にあります。これにより、問い合わせやアラートなどの機能開発以外の運用業務でも複数の課題が生じていました。 問い合わせ/アラートの数が増加して機能開発のボトルネックになっている 問い合わせ/アラートに関連した機能・実装のコンテキストを知らないため調査コストが高い 問い合わせのやりとりは Slack のスレッドで行っているためステータスが分かりにくい 問い合わせのデータが蓄積されないため対策や将来の改善に活かせない こういった課題を解消すべくAIやツールを活用した改善をこの2025年下期で取り組みました。 Claude Code GitHub Actionsでアラートの初期調査コストを削減 アラート通知はこのようにSentryを経由してSlackへ通知されます。 これだけを見てもどういったエラーでどこで発生したのか分かりません。 そのため従来はSentryのイシュー詳細に遷移し、スタックトレースを確認したり、そこからエディタで関連コードを調査したり、まず 状況把握をするための初期調査コストが高い という問題がありました。 この問題の改善に用いたのが Claude Code GitHub Actions です。 Claude Code GitHub Actionsは、GitHub ActionsのワークフローからClaude Codeを呼び出せる機能です。 SentryからGitHubのイシューを作成したら自動で次のようなプロンプトのコメントをClaudeにメンションします。 このissueのdescriptionに当リポジトリで発生したエラーが記述されています。 このissueのdescriptionにはSentryのissueのIDが記載されています。 mcp__sentry__get_sentry_issueで記載されたIDのissueの詳細情報を取得してください。 mcp__sentry__get_sentry_issueで取得した結果やエラー発生箇所・周辺ファイルを閲覧し、エラーの発生原因の調査結果をissueのコメントに記載してください。 可能であれば修正対応のプルリクエストを作成してください。 プルリクエストを作成する際は次の3ステップで実行してください: - エラーに対する初期の対応案(ドラフト)を作成してください。 - そのドラフトに対して、どこが良くてどこが改善できるかをレビューしてください。 - レビュー結果をふまえて、より良い最終的な対応案を提示してください。 これによってClaude Code GitHub Actionsが起動し、自動でエラー発生箇所の周辺調査や状況整理、うまく噛み合えばClaudeが作ったプルリクエストをマージするだけで対応が完了する時もあります。 ▼実際にClaudeが作成したコメント例 この取り組みによって アラート発生時の初期調査コストを削減 することができました。ケースによっては数時間かかっていた調査が数分で状況把握できるようになり、調査開始までの心理的ハードルも下がっています。 Notionのデータベースで問い合わせのチケット管理とデータ蓄積 前述したようにFindy Team+では数年間に渡ってSlackワークフローでの問い合わせ起票を行ってきました。 問い合わせのコミュニケーションに関してはSlackで過不足無いのですが、複数問い合わせが並行するとやりとりを追うのが大変だったり、現在のタスクの状況が分からなくなる問題が度々発生していました。 また問い合わせはプロダクトの改善に繋がる貴重な情報なのにそのデータが蓄積されずフィードバックループを回すことが出来ない、というのも大きな課題でした。 これを一気に解消したのが Notion のデータベースです。 Slackのワークフローでの問い合わせ起票を全て Notion Form に移行し、フォーム送信と同時に問い合わせの情報がデータベースに蓄積されるようになりました。 またデータベースでもチケット管理を行うようにしました。 対応期限のカラムやいわゆる「To Do」「In Progress」「Done」といった値を持ったステータスのカラムを用意し、 Zapier を使ってリマインドの機構を設けました。 例えば対応期限を超過してもステータスが「Done」になっていない場合、Slackで担当者へリマインド通知を飛ばすといった自動化も行いました。 ▼対応期限超過のリマインドメッセージ Notionのデータベースを用いることでステータス管理や情報の蓄積が可能になり、問い合わせが抱えていた複数の課題を一気に解消することができました。 また、データが蓄積されることで次に紹介する取り組みにも繋がりました。 Notion MCPを使って過去事例の検索と自動調査 問い合わせ起票時には起票するメンバーに問い合わせに関連した「画面機能」「連携サービス」「メトリクス」といった情報をデータベースに入力してもらうようにしています。 さらに問い合わせの対応が完了したらLLMに問い合わせのやりとりを要約してもらい、その内容もデータベースに保存しています。 これにより半自動的に問い合わせについての情報を拡充していくことができています。 そしてアプリケーションのリポジトリに次の内容のClaude Codeのスラッシュコマンドを作成しました。 --- description : Notion上の問い合わせDBから類似の問い合わせを検索し、原因を調査する --- - $ARGUMENTSは `collection://***` の問い合わせデータベースの中の問い合わせ(ページ)です。 - notion-fetchを使って $ARGUMENTS の問い合わせ内容を確認してください。 - $ARGUMENTS の問い合わせと類似の過去の問い合わせを `collection://***` のデータベースから検索してください。 - 検索の際は`summary`,`detail`,`tag`の各プロパティから類似の問い合わせを検索してください。 - この検索結果から $ARGUMENTS の問い合わせを当リポジトリのコードから調査してください。 - 最終的に次の結果を出力してください。 1. 類似の問い合わせが見つかったかどうか 2. 類似の問い合わせが見つかった場合、その問い合わせIDと概要(summary) 3. $ARGUMENTS の問い合わせの原因調査結果 このスラッシュコマンドは内部で Notion MCP のtoolを利用しています。 これにより過去の問い合わせ情報というコンテキストを持ちながらClaude Codeがより詳細にコード情報を調査することを可能にしています。 出力サンプルを本記事に掲載したいところですが、あまりにも詳細に情報を出力しすぎてしまうため残念ながらここでの掲載は控えさせていただきます。 ただ私自身何度かこのスラッシュコマンドを問い合わせに実行してみて過去に類似問い合わせがあると問い合わせの要因等をかなり詳細に調査してくれることを確認しています。 また過去に類似問い合わせが無いとしても、問い合わせに関連した周辺処理の概況を説明してくれるので全くコンテキストを把握していない機能の問い合わせの調査コストを軽減できていると感じています。 取り組みの成果 今回紹介した取り組みにより、次のような成果を得ることができました。 問い合わせやアラートの状況が可視化され、分析可能な基盤が整った AIによる初期調査で調査の効率化が実現し、状況把握までの時間を大幅に短縮できた チケット管理によりステータスが明確になり、対応漏れを防げるようになった 一方で、可視化や効率化を行うだけでは問い合わせやアラートの件数自体は減少しませんでした。 機能開発が進み、利用者数も増加している中での自然な傾向でもあります。 可視化や効率化は部分的に対応コストを下げるものであり、それだけでは件数を減らす根本的な解決にはなりません。 今後の取り組み:根本原因の特定と改善の仕組みづくり 蓄積された問い合わせデータやアラート傾向を分析し、頻出する問題の根本原因を特定していきます。 暫定対処ではなく恒久対応を行うことで、問い合わせやアラートの件数自体を減らすことを目指します。 たとえば、問い合わせデータを「画面機能」や「連携サービス」ごとに集計し、特定の領域に問い合わせが集中していないかを可視化します。 集中している領域があればUIの改善やドキュメントの拡充、場合によっては機能自体の見直しを検討します。 また、これまでは改善活動に対する明確な行動指針がなく、暫定対処に留まりがちでした。 今後はインセンティブの設計をしっかり行い、改善活動が継続して実施される仕組みを作ります。 具体的には、来期から私も機能開発チームに合流し、改善対応もミッションの一部として進めていきます。 運用業務の当事者として改善に取り組むことで、フィードバックループを確実に回していきます。 まとめ 2025年下期開始当初、自分は昨今のAIの潮流もあって「AIがあれば運用業務の全てを改善できる!」と意気込んでいました。 実際に取り組んだ結果、AIやツールを活用していくらかの問い合わせやアラート対応の「可視化」と「効率化」を実現しました。 しかしこれらは対応を効率化するものであり、件数を減らす根本解決ではありません。今後は蓄積したデータを活用して恒久対応に繋げ、問い合わせやアラートの根本原因を取り除いていきます。 引き続きAIを活用しつつ、改善活動が継続する仕組みを作りながら本質的な改善に挑戦していきます! ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
この記事は、 ファインディエンジニア #3 Advent Calendar 2025 の22日目の記事です。 adventar.org はじめに こんにちは、ファインディのPlatform開発チームでSREを担当している原( こうじゅん )です。 2025年12月に、アメリカ・ラスベガスで開催されたAWS re:Inventに参加してきました。 re:Inventは毎年ラスベガスで開催されるAWSの世界最大のカンファレンスで、世界中からエンジニアが集まります。 この期間中、ラスベガスの街全体がre:Inventの会場となり、最新のAWSアップデート情報のリリースや技術セッションの他、EXPO、re:Playパーティー、5K Raceなど様々なアクティビティが用意されています。 本記事では、技術セッションの内容よりも、会場の雰囲気やサブイベント、現地での過ごし方を中心にお伝えします。 技術セッションの内容を中心とした内容は先日投稿した AWS re:Invent 2025 参加レポート - 参加して感じた、AIOpsの本格的な到来 に記載しているので、ぜひこちらも合わせて御覧ください。 はじめに re:Inventの規模感 - ラスベガスの街が会場に 会場は6つの施設に分散 シャトルバスとモノレールで会場間を移動 多数あるセッションカテゴリ 会場の様子 フリードリンクと軽食 Meal会場でのビュッフェ 厳重なセキュリティチェック EXPO会場 SWAG SPORTS FORUM セッション以外のサブイベント 5K Fun Run re:Play おわりに re:Inventの規模感 - ラスベガスの街が会場に 会場は6つの施設に分散 re:Inventの会場は次の6つに分散しており、それぞれが巨大な施設です。 Encore Wynn The Venetian (メイン会場) Caesars Forum MGM Grand Mandalay Bay 上の地図を見ても縮尺がわかりにくいですが、実際に現地で歩いてみると想像以上の距離があります。 メイン会場であるThe VenetianからMGM Grand付近まで実際に歩いてみると約1時間ほどかかりました。 さらに、各会場内も広大で、イベント全体を通じてかなりの距離を歩くことになります。 シャトルバスとモノレールで会場間を移動 会場間の移動手段は、シャトルバスかモノレールが基本です。 シャトルバスもひっきりなしに運行されており、私は期間中ずっとシャトルバスを利用していました。 街中やホテル内の至るところでre:Inventのバッジを付けた参加者とすれ違います。 まさに「ラスベガスの街全体がre:Invent」という雰囲気でした。 多数あるセッションカテゴリ この複数ある巨大な会場の中で、様々なセッションが同時並行で行われます。セッションの種類は次の通りです。 Keynote : 基調講演 Breakout Session : 技術・事例セッション Workshop : ハンズオン形式 Chalk Talk : 小規模なディスカッション形式 Game Day : チーム対抗の技術チャレンジ セッション数が膨大なため、見たいセッションを探すだけでも一苦労です。 また、移動時間込みでセッションスケジュールを考える必要があります。 re:Invent 2025 MCP Server というイベント情報を調査できるMCPもあり、私はこれを利用してスケジュールを組んでいました。 builder.aws.com Keynoteで発表された新サービスのアップデートに関するセッションは[NEW LAUNCH]という形で新しく登場してきます。 そのため、気になるアップデートがあれば、事前に組んでいたスケジュールから変更したり、柔軟にスケジュールを変えていく必要があります。 私の参加したスケジュールは次の通りです。その他の時間は、会場移動やEXPOへの参加などしていました。 今回は、Keynoteで発表されたDevOpsエージェント関連のワークショップを運よく予約できたこともあり、ObservabilityやAIOps系のセッションが多めの構成になりました。 Scaling observability with generative AI (ARC311) Behind the scenes: How AWS drives operational excellence & reliability (COP415) Amazon ECS observability patterns and design decisions (CNS351-R) Opening Keynote with Matt Garman (KEY001) A deep dive on IAM policy evaluation (SEC402-R1) Best practices for cost optimization with AWS Backup (STG328-R) The Future of Agentic AI is Here (KEY002) Unveiling Amazon ECS workloads with AWS observability and agentic AI (CNS413) [NEW LAUNCH] Resolve and prevent future operational issues with AWS DevOps Agent (DVT337-R1) Infrastructure Innovations (KEY004) A Special Closing Keynote with Dr. Werner Vogels (KEY005) 技術セッションの感想を中心とした内容は先日投稿した AWS re:Invent 2025 参加レポート - 参加して感じた、AIOpsの本格的な到来 に記載しているので、こちらもよろしければ御覧ください。 会場の様子 ここからは、セッション以外の会場の様子やサブイベントについての体験談を書いていきたいと思います。 フリードリンクと軽食 各会場の廊下には、コーヒー、ドリンク、サンドイッチ、ドーナツ、バナナなどの軽食がおいてあり、自由に飲食できます。 特に制限もないため、私はここで簡単に朝食を済ませたり、セッション後にコーヒーを入れてホテルに持ち帰ったりしていました。 Meal会場でのビュッフェ Meal会場ではビュッフェ形式の食事が提供されています。 イベント期間中は軽食とMeal会場の食事が用意されているため、イベント時間中は会場だけで出費なしで食事を賄うことは可能です。 会場や日にちによって出る料理が異なったりしてますが、注意点としてはLunchの時間が11:00 AM ~ 1:00 PMなど食事できる時間が限られていることです。セッションの時間と様子を見てLunchの時間を確保する必要があります。 厳重なセキュリティチェック 各会場の入口には、セキュリティゲートが設置されており、持ち物検査を受ける必要があります。 麻薬検知犬も多く見受けられ、日本のカンファレンスでは体験できない海外イベントならではの厳重さを感じました。 シャトルバスで会場間を移動した際も、別会場の入口でセキュリティチェックを受ける必要があります。 EXPO会場 企業ブース出展会場のEXPOも圧巻の広さでした。 多数の企業が出展しており、Datadogの滑り台やKiroのお化け屋敷など、ユニークな展示もありました。 また、アメリカらしいと感じたのは、ドネーション(寄付)コーナーが設置されているブースで、日本にない文化を感じました。 SWAG EXPO会場や各ブースでSWAG(ノベルティグッズ)が配られており、Tシャツ、ステッカー、ボトルなど様々なグッズを集めることができます。 SWAGもサプライズ的に配布されたりすることがあり、Xで「〇〇でXXが配られた!」などの情報をみて初めて知るものもありました。 SPORTS FORUM SPORTS FORUMは、スポーツとテクノロジーを組み合わせたエンタメエリアです。 F1のタイヤ交換ゲーム、バスケのゲーム、VRなど、多彩なアクティビティが用意されていました。 散策しているだけでも楽しめます。 セッション以外のサブイベント ここからは、re:Inventのサブイベントをご紹介します。 5K Fun Run イベント期間中に開催される5Kmのマラソンイベントです。 参加して完走すればメダルがもらえます。 6:00 AMから開始され朝早いイベントですが、ラスベガスの道路を走れる貴重な機会なので、体力に余裕があればぜひ参加してみてください。 re:Play re:Invent後半、クロージングKeynoteの後に開催される公式パーティーがre:Playです。 DJによるライブパフォーマンスが行われ、会場の雰囲気はもはやカンファレンスというより野外フェスそのもの。 40フィート走や、巨大なロボットアームで廃車を持ち上げて落とすという、ユニークなアクティビティも用意されており、締めのエンジョイできる時間でした。 おわりに 技術セッションで最新のAWSサービスを学べたのはもちろんですが、会場の規模感やサブイベントの充実度、そして海外のエンジニアとの交流が、このイベントの大きな魅力だと感じました。 ワークショップで英語を使って会話したり、海外のエンジニアからファインディについてフィードバックをもらったりと、コミュニケーションを取ろうとした経験は貴重なものでした。 もっと技術的なディスカッションができるようになりたいという想いも強くなり、継続して英語を学習していきたいと思っています。 来年以降re:Inventへの参加を検討している方の参考になれば幸いです。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
この記事は、 ファインディエンジニア #1 Advent Calendar 2025 の21日目の記事です。 adventar.org はじめに こんにちは、ファインディのPlatform開発チームでSREを担当している原( こうじゅん )です。 2025年12月、ラスベガスで開催されたAWS re:Inventに参加してきました。re:InventはAWSが毎年開催する世界最大級のクラウドカンファレンスです。 今年は特にAI Agentを中心とした大きな変化を感じるイベントとなりました。 本記事では、私の体験したセッションを通じて見えてきたインフラ・運用の変化について、AIOps領域に焦点を当てて振り返りを書いていこうと思います。 会場の様子やセッション以外のイベントについてはまた別記事で書いていきます。 はじめに re:Invent 2025 今年の主要テーマの1つであるFrontier Agents AWS DevOps Agentとは ワークショップでの体験 その他の運用・インフラ領域で参考になるセッション Observability × AI 運用の文化とプラクティス インフラ基盤の進化 IAMポリシーの深掘り エンジニアに求められる姿勢 おわりに re:Invent 2025 re:Inventは、ラスベガスの街全体が会場となる巨大なイベントです。 reinvent.awsevents.com 6つの会場で数多くのセッションが同時並行で開催され、世界中のエンジニアが集まります。 会場間の移動だけでも場所によれば徒歩だと約1時間かかることもあり、シャトルバスやモノレールで移動しながら1週間を過ごすことになります。 セッション以外にもEXPO、re:Playと呼ばれるパーティイベント、5k Raceなど様々なアクティビティが用意されており、まさにAWSの祭典という雰囲気でした。 今年の主要テーマの1つであるFrontier Agents 2025年のre:Inventで印象的だったのは、Frontier Agentsと呼ばれるAIエージェントにまつわる発表です。 Keynoteでは、Kiro Autonomous Agent、AWS DevOps Agent、AWS Security Agent、など、フロンティアエージェントと呼ばれるインフラ・運用領域に直接関わるAIエージェントが次々と発表されました。 これらは単なる「補助ツール」ではなく、「チームメイトとして成果を出すことを期待される存在」として位置づけられています。 その中の1つである私が体験してきたAWS DevOps Agentについて軽く触れていきたいと思います。 AWS DevOps Agentとは AWS DevOps Agentは、運用チームの「チームメイト」として次のような役割を担います。 Team Player : アラートやチケットに対応し、Slackなどのコラボレーションチャネルで知見を共有 Telemetry Expert : メトリクス・ログ・トレースを横断的に分析。DatadogやNew Relicとも連携可能 Pipeline Pro : GitHubやGitLabと連携して障害につながる変更を特定し、パイプライン改善を提案 Application Context : アプリ構成やRunbookを理解した上で判断 aws.amazon.com ワークショップでの体験 実際にDevOps Agentを使ったワークショップである [NEW LAUNCH] Resolve and prevent future operational issues with AWS DevOps Agent に参加し、次のような操作を体験しました。 障害発生中のAWSリソースを解析して根本原因を特定 Dynatraceと連携させてオブザーバビリティデータを統合 インシデント対応レポートと改善計画の自動生成 エージェントが「インシデントの根本原因を教えてくれる」だけでなく、「改善計画」まで説明してくれる点は、まさにチームメイトのような動きでした。 まだプレビュー版ではありますが、弊社でオブザーバビリティツールとして使用しているDatadogとの連携もできるのでぜひ取り入れていきたいと思いました。 その他の運用・インフラ領域で参考になるセッション DevOps Agent以外にも、AIOpsに関連する運用・インフラ領域で参考になるセッションがいくつかありました。 Observability × AI Scaling observability with generative AI (ARC311) では、Kiro CLI Agentを用いた自然言語操作によるオブザーバビリティの自動化が紹介されました。 障害が発生している環境に対して、Kiroがカスタムエージェントで解析した内容をもとにLambdaのコードを書き換えたり、リソース設定を変更したりするデモが印象的でした。 Unveiling Amazon ECS workloads with AWS observability and agentic AI (CNS413) では、ECSワークロードに対して生成AIを活用し、オブザーバビリティデータを自動分析するアプローチが紹介されました。 毎週30億タスクが実行され、新規コンテナ顧客の65%がECSを利用しているという事実を紹介してから、AWSのオブザーバビリティツール全体を整理した上で、ECS上でAIOpsエージェントを構築する際のベストプラクティスが紹介されました。 運用の文化とプラクティス Behind the scenes: How AWS drives operational excellence & reliability (COP415) では、AWSがグローバル規模で運用をどのように行っているのかが解説されました。 特に印象的だったのは、次のサイクルを継続的に回している点です。 Readiness : 障害が起きる前の状態づくり(アラーム、ダッシュボード、Runbook、オンコール体制の整備) Observability : ログ・メトリクス・トレースでの計測、SLOドリブンなモニタリング Incident Response : SOP(標準作業手順書)に従った対応、AIOpsによる障害分析 Reviews : 定期的なダッシュボードレビューと改善活動 これらはSREのプラクティスと大きくは変わらないなと思いつつ、改めて運用フローを整理・定義していく重要性を認識しました。 インフラ基盤の進化 Infrastructure Innovations (KEY004) では、Graviton5やLambda Managed Instances、Amazon ConnectのAI対応など、AWSのインフラ技術の進化が語られました。 セキュリティ、可用性、弾力性、コスト、俊敏性といった軸で、どのような思想で設計・進化してきたのかが示されており、基盤レイヤの理解を深めることができました。 IAMポリシーの深掘り A deep dive on IAM policy evaluation (SEC402-R1) では、IAMポリシーの評価ロジックが詳細に解説されました。 権限評価は単一のポリシーだけで決まるのではなく、Organization → Account → Role → Boundary → Session という複数レイヤをすべて通過して決まります。 また、すべてのPrincipalを対象にしたDenyに条件を付けることで、特定のロールだけを例外として許可するIAMポリシーの書き方なども紹介されており、セキュリティ設計の参考になりました。 AIがインフラ領域に組み込まれている中、ガードレールとしてのポリシーの整備も必要だと感じました。 エンジニアに求められる姿勢 また、クロージングKeynoteで、AWS CTOのWerner Vogels氏が語った言葉が印象に残っています。 「AIは自分の仕事を奪うのか?」という問いに対して、CTOは「多分ね……」と答えつつも、本質的な問いはそこではなく、「AIがあなたを時代遅れにするのか?」であると強調していました。 そして、その答えは、「あなたが進化し続ける限り、断じてノーだ」と。 私たちは今、AIによって時代が大きく動いている震源地に立っています。その中で重要なのは、次の姿勢です。 Be Curious: 好奇心を持ち続けること Think in Systems: 複雑なシステム全体を捉える力 Communicate: 良いアイデアを明確に伝える力 Owner: 成果物に対して自ら責任を持つこと Polymath: 多才であり、学び続けること AIはあくまでツールであり、仕事の主体は常に「あなた自身」である。 The work is yours, not the tool's YOUR CURIOSITY + YOUR SKILLS = WORLD-CHANGING このメッセージは、re:Inventの締めとしてとても印象に残りました。 おわりに 4日間のイベントを通して、技術的な知見が広がり、刺激的で濃い時間を過ごすことができました。 2026年は、AIOpsが本格的に実務に組み込まれていく年になると感じ、ファインディのPlatform開発チームでもよりAIOpsを組み込んでいく体制づくりを行っていければと思います。 ファインディでは一緒に働くメンバーを募集中です! よかったら覗いてみてください。 herp.careers
アバター
こんにちは。 ファインディ株式会社でテックリードマネージャーをやらせてもらっている戸田です。 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど、生成AIを活用した開発支援ツールが次々と登場し、日常的なワークフローに組み込まれつつあります。 そんな中で先日、弊社主催でAI Engineering Summit Tokyo 2025が開催され、「Findy AI+の開発、運用におけるMCP活用事例」と題しまして登壇してきました。 ai-engineering-summit-tokyo.findy-tools.io そこで今回は、登壇資料を元に、Findy AI+の開発でどのようにMCPを活用したか、その選択の背景と効果を振り返っていきます。特に、MVPでのリモートMCPサーバー活用と、Admin機能でのMCPサーバー実装という2つの事例から、MCPの実践的な活用パターンをお伝えします。 それでは見ていきましょう! MCPとは Findy AI+ アルファ版: リモートMCPサーバーでの提供 ベータ版: チャットUIとMCP活用のAdmin機能 まとめ MCPとは MCP(Model Context Protocol)は、アプリケーションが大規模言語モデル(LLM)に情報やツールへのアクセス方法を提供する、新しいオープンプロトコルです。 USB-Cが様々なデバイスを標準的な方法で接続するように、MCPはAIモデルを多様なデータソースやツールへつなぐための、標準化された方法を提供します。 詳しくは次の公式ドキュメントをご覧ください。 modelcontextprotocol.io また先日、 MCPがLinux Foundation傘下に新設されたAgentic AI Foundation (AAIF)に寄贈される というニュースが発表されました。 www.anthropic.com これにより、 ベンダーに依存しない中立的な技術として管理される ことになります、また、 長期的な安定性と互換性が保証 され、より安全に採用できる技術となるでしょう。まさに 業界にとって不可欠な共有インフラとしての地位を確立しようとしている と言えるでしょう。 Findy AI+ Findy AI+はGitHub連携・プロンプト指示で生成AIアクティビティを可視化し、生成AIの利活用向上を支援するサービスです。 生成AIやAIエージェントを活用するうえでの組織、個人の課題を解決するために開発されました。 jp.ai-plus.findy.io アルファ版: リモートMCPサーバーでの提供 まずこのプロダクトのニーズが一定以上あるかどうか検証するためにMVPでアルファ版の開発を行いました。 この時、アルファ版ではリモートMCPサーバーでのサービス提供を実現しています。 リモートMCPサーバーで提供することで、画面を実装する工数をカットすることが出来た上、分析や解析をクライアント側のLLMに任せることが出来たため、エンジニア2人で1ヶ月程度での開発を実現することに成功しました。 リモートMCPサーバーの役割は、必要な情報を外部APIから取得して、LLMが分析しやすい形に加工して返すこと です。 分析そのものはクライアントから接続しているLLMに任せます。 そのため、実行するプロンプトによって出力結果にバラつきが出ることを防ぐために、MCPサーバーからプロンプトを動的に生成して返す機能までを実装しました。 リモートMCPサーバーの詳細は別記事を参照すると、より理解が深まるかと思います。 tech.findy.co.jp ベータ版: チャットUIとMCP活用のAdmin機能 アルファ版の提供により一定以上のニーズを確認出来たため、次にベータ版として画面UIからのチャット形式のインターフェースを提供することになりました。 更にサービス全体を管理するためのAdmin機能が必要となりました。そこで Admin機能を画面UIではなく、ローカルMCPサーバーとして実装する ことにしました。Admin機能は管理者のみが使用し、利用頻度も高くないため、画面UIを作るよりもMCPで柔軟に操作できる方が効率的と判断しました。 MCPサーバーのtoolからバックエンドのサーバーのAdmin機能用のREST APIを実行してデータを取得して返すだけのシンプルな構成です。また、Admin機能用のAPIとユーザー側の機能用のAPIのendpointと認証を分けることで、セキュリティ面も考慮しています。 結果的に、画面ベースで開発した場合の見積もりが約1ヶ月程度の工数であったのに対し、MCPサーバーとして実装したことで約1週間程度の工数で実装が完了しました。 Admin機能を提供するMCPサーバーについては別記事を参照すると、より理解が深まるかと思います。 tech.findy.co.jp まとめ MCPの登場により、開発効率を上げるだけではなくデータへのアクセス手段の選択肢が広がりました。 今回のFindy AI+の事例では、MVP開発でリモートMCPサーバーを活用することで開発期間を大幅に短縮し、Admin機能ではMCPサーバーとして実装することで画面UIの開発工数を削減できました。それにより、価値提供の方法も変わってきています。 また、LLMや生成AIツールが変わっても、MCPはLLMや生成AIツールを選ばずに接続が出来ます。これにより長く使える知識、技術となっています。 ファインディは早期にMCPの検証を開始して、積み重ねを継続して、実用化にたどり着くことができました。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
はじめに みなさんこんにちは。Platform 開発チーム SREでサブマネージャーの安達( @adachin0817 )です。この記事は、 ファインディエンジニア Advent Calendar 2025 の18日目の記事です。今回はECS Express Modeをスピーディーに試してみたので、使ってみて分かったメリット・デメリットを中心にまとめていきたいと思います。 adventar.org はじめに ECS Express Modeとは Terraform terraform.tf iam.tf ecs.tf variables.tf Deploy 削除の挙動と懸念点について まとめ ECS Express Modeとは https://aws.amazon.com/jp/blogs/news/build-production-ready-applications-without-infrastructure-complexity-using-amazon-ecs-express-mode/ 従来のECSを用いたインフラ構築では、ECSクラスターやタスク定義、サービスだけでなく、ロードバランサー、ターゲットグループ、セキュリティグループ、オートスケーリングなど、多数のリソースを個別に定義・管理する手間がありました。 公式ドキュメントによるとECS Express ModeはAPIを通じて、インフラのセットアップを全て、自動化できるようになりました。これにより、アプリケーション開発に集中できる環境を実現し、Amazon ECSを含む各リソースを設定できるため、必須項目はコンテナイメージのみで、シンプルさとスピードを飛躍的に向上させています。 https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/ecs_express_gateway_service Terraformではaws_ecs_express_gateway_serviceリソースが提供されているため、こちらを使って一連の流れを実装していきます。 Terraform terraform.tf ECS Express Modeは、Terraform AWS Providerのバージョン 6.23 から利用できるようになります。 terraform { required_version = ">= 1.14.2" required_providers { aws = { source = "hashicorp/aws" version = ">= 6.26.0" } } cloud { organization = "hoge" workspaces { name = "hoge-ecs" } } } iam.tf ECS Express Modeでは、主に2つのIAM ロールが必要になります。Task Execution Roleは、コンテナイメージのpullやCloudWatch Logsへの書き込みに使用され、Infrastructure Roleは、ECS Express Modeが各種リソースを作成・管理するために使用されます。 resource "aws_iam_role" "ecs_task_execution_role" { name = "test-service-task-execution-role" assume_role_policy = jsonencode ( { Version = "2012-10-17" Statement = [{ Effect = "Allow" Principal = { Service = "ecs-tasks.amazonaws.com" } Action = "sts:AssumeRole" }] } ) } resource "aws_iam_role_policy_attachment" "ecs_task_execution_role_policy" { role = aws_iam_role.ecs_task_execution_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy" } resource "aws_iam_role" "ecs_infrastructure_role" { name = "test-service-infrastructure-role" assume_role_policy = jsonencode ( { Version = "2012-10-17" Statement = [{ Sid = "AllowAccessInfrastructureForECSExpressServices" Effect = "Allow" Principal = { Service = "ecs.amazonaws.com" } Action = "sts:AssumeRole" }] } ) } resource "aws_iam_role_policy_attachment" "ecs_infrastructure_role_policy" { role = aws_iam_role.ecs_infrastructure_role.name policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRoleforExpressGatewayServices" } ecs.tf ECS Express Modeでは、中心となるリソースであるaws_ecs_express_gateway_serviceを通じて各種設定を制御します。ECSクラスター自体は別途定義する必要がありますが、サービス側ではコンテナイメージ指定(今回はNginx)、ログ設定、事前に作成したIAM ロール、ネットワーク、CPU・メモリ、スケーリング設定などをまとめて指定します。 ロードバランサーについては ALBとターゲットグループが自動的に作成・管理され、ACM証明書も自動発行される仕様となっていました。また、セキュリティグループもExpress Mode側で自動生成・管理されるため、Terraform側では差分検知を防ぐために、ignore_changesを指定する必要がありました。 ※ネットワークはデフォルトVPCを参照しています。 resource "aws_ecs_cluster" "main" { name = var.cluster_name } resource "aws_ecs_express_gateway_service" "main" { cluster = var.cluster_name service_name = var.service_name primary_container { image = var.container_image container_port = var.container_port command = var.command aws_logs_configuration { log_group = aws_cloudwatch_log_group.ecs_service.name log_stream_prefix = var.service_name } } execution_role_arn = aws_iam_role.ecs_task_execution_role.arn infrastructure_role_arn = aws_iam_role.ecs_infrastructure_role.arn network_configuration { subnets = toset ( [ "subnet-xxxxxx" , "subnet-xxxxxx" ] ) security_groups = toset ( [ aws_security_group.tests_service.id ] ) } cpu = tostring (var.cpu) memory = tostring (var.memory) scaling_target { min_task_count = var.min_capacity max_task_count = var.max_capacity auto_scaling_metric = "AVERAGE_CPU" auto_scaling_target_value = 60 } health_check_path = var.health_check_path lifecycle { ignore_changes = [ network_configuration [ 0 ] .security_groups ] } } variables.tf variable "cluster_name" { type = string description = "The name of the ECS cluster" default = "hoge-cluster" } variable "service_name" { type = string description = "The name of the service" default = "hoge-service" } variable "log_group" { type = string description = "The name of the CloudWatch log group" default = "/ecs/hoge-service" } variable "container_image" { type = string description = "The container image to use for the service" default = "nginx:latest" } variable "container_port" { type = number description = "The port that the container listens on" default = 80 } variable "command" { type = list ( string ) description = "The command to run in the container" default = [ "nginx" , "-g" , "daemon off;" ] } variable "cpu" { type = number description = "The number of CPU units to allocate" default = 256 } variable "memory" { type = number description = "The amount of memory (in MiB) to allocate" default = 512 } variable "min_capacity" { type = number description = "Minimum number of tasks" default = 1 } variable "max_capacity" { type = number description = "Maximum number of tasks" default = 10 } variable "health_check_path" { type = string description = "The path for health checks" default = "/" } Deploy デプロイはECSビルトインデプロイであるカナリアデプロイとなっており、アプリケーションURLにHTTPSでアクセスできるようになりました。 ❯❯ curl -I https://xxx.ecs.ap-northeast-1.on.aws HTTP/2 200 server: nginx date: Tue, 16 Dec 2025 02:30:25 GMT content-type: text/html; charset=utf-8 content-length: 14 x-powered-by: Express 削除の挙動と懸念点について https://docs.aws.amazon.com/AmazonECS/latest/developerguide/express-service-delete-task.html The Amazon ECS cluster (if no other services are running) The Amazon ECS service, task definition, and any running tasks Service security group CloudWatch log group Metric alarm ACM Certificate The Application Load Balancer (if no other services are configured), target group, security group, listener, and listener rule Amazon EC2 Auto Scaling policy, scalable target 削除の挙動については、Terraformでdestroyを実行すればExpress Mode管理下のリソースがすべて削除される想定でした。しかし、実際にはALBやターゲットグループ、ACMが残存し、その後に手動削除と再apply を行った結果、同一サービス名のECSサービスがDraining 状態のままとなり、再作成できない問題に直面しました。 ╷ │ Error: creating ECS (Elastic Container) Express Gateway Service │ │ with aws_ecs_express_gateway_service.main, │ on ecs.tf line 5 , in resource "aws_ecs_express_gateway_service" "main" : │ 5 : resource "aws_ecs_express_gateway_service" "main" { │ │ ID: "hoge-service" │ Cause: operation error ECS: CreateExpressGatewayService, , │ InvalidParameterException: Unable to Start a service that is still Draining. " クラスター名を変更して再度applyし直したところ、applyは完了するものの、ロードバランサーが作成されない状態となりました。その結果、存在しないセキュリティグループを参照したままサービスが起動できず、結果としてサービスがデプロイされないままタイムアウトしない事象が発生しました。この挙動から、Terraformでの削除・再作成は、現時点で課題が残っていると感じています。 まとめ ECS Express Modeは、App Runnerと比べても、インフラ構築の複雑さを大きく減らし、アプリケーションエンジニアでも素早く環境を立ち上げ、開発に集中できる体験を提供してくれる仕組みだと感じました。一方で、Terraformを前提とした運用ではまだ課題が残る印象もありますが、Platform SRE チームがこれまで整備してきた汎用モジュールの一部を、将来的に置き換えられる可能性も感じています。 今後はAWSサポートとも連携しながら挙動の整理を進め、どのユースケースで安全に使えるのかを見極めつつ、実運用に耐えうる形へ落とし込んでいく予定です。 最後まで、読んでいただきありがとうございました! herp.careers
アバター
こんにちは。 Findy Freelanceの開発チームでEMをしている中坪です。 この記事は、 ファインディエンジニア Advent Calendar 2025 の18日目の記事になります。 adventar.org 日々進化するAIや関連ツールをキャッチアップし、実務に活用することに苦労しているエンジニアの方も多いのではないでしょうか。 私たちは、チームでAIツールのキャッチアップを行う取り組みとして「10分勉強会」を実施しています。 本記事では、その取り組み内容について紹介します。 10分勉強会とは 発表内容の例 1. Sentry MCPとLog Analyzer with MCPを使った不具合調査 2. Gemini Canvasを使ったUIモックの作成と社内共有 3. Git Worktree Runnerの紹介 持続するための工夫 発表のスキップを許容する 発表資料は任意 厳密ではないテーマ設定 チーム内で開催する 開催時間を短くする 効果と反響 チームメンバーの声 チームAI活用率 メリット アウトプットによる知識の定着 AIのキャッチアップをチームで取り組める 聞いた内容をすぐに試せる デメリット 余談と「うちのAIがやらかしまして」の紹介 おわりに 10分勉強会とは 発表者が5分間で学んだことを発表し、残り5分で質疑応答を行う形式の勉強会です。 この勉強会の目的は次の3つです。 メンバーが学んだことをチームメンバーに共有する機会を作る 発表からその人の仕事、興味、課題などを知り、相互理解を深める アウトプットのハードルを下げ、アウトプットの習慣をつける Findy Freelance開発チームでは、週に2回、10分勉強会を実施しています。 1回につき1名が発表し、ローテーションで全員が発表する形をとっています。 2024年の2月頃に開始し、継続しています。 2025年1月以降は、基本テーマを「生成AI活用」に設定し、変化の激しいAIツールのキャッチアップに焦点を当てています。 過去の発表内容の一部です。 発表内容の例 過去の発表内容の例をいくつか簡単に紹介します。 1. Sentry MCPとLog Analyzer with MCPを使った不具合調査 AWSが提供する Log Analyzer with MCP を使った不具合調査の方法を紹介しました。 このMCPはCloudWatch Logsの検索と分析を行うことができ、 Sentry MCP と組み合わせることで、エラーの概要と詳細なログを横断的に調査できます。 Sentryでエラーの概要を把握し、CloudWatch Logsで詳細なログを確認することで、Claude Code上で一貫した調査が可能になり、エラーの根本原因を効率的に特定できた事例が紹介されました。 2. Gemini Canvasを使ったUIモックの作成と社内共有 仕様検討時にUIイメージを共有する方法として、Gemini Canvasの活用事例が紹介されました。 Geminiのチャット欄でCanvas機能を有効化し、既存画面のキャプチャと簡単なプロンプトを渡すだけで、動きのあるUIモックを作成できます。 生成されたHTMLをGoogle Apps Scriptにデプロイし、公開範囲を組織内に限定することで、社内のGoogleアカウントを持つメンバーだけがアクセスできるURLとして共有できます。 静的なキャプチャでは伝わりにくいインタラクションも、実際に動かせるモックを使うことで、仕様の認識合わせを効率的に進められた事例が紹介されました。 V0のような専用ツールと比べて、ファインディの社内で導入されている標準ツールで利用できる点が利点です。 3. Git Worktree Runnerの紹介 CodeRabbitが公開している Git Worktree Runner (GTR) を使った開発効率化の事例が紹介されました。 このツールは、Git worktreeの作成と管理を簡単にし、AIツールとの連携をスムーズにします。 コマンド一つでworktreeとブランチを同時に作成でき、エディター(VS CodeやCursorなど)やAI CLIツール(Claude Codeなど)の起動も自動化できます。 フック機能により、worktree作成時にnpm ciなどの初期化コマンドを自動実行できるため、ブランチを切り替えてすぐに開発を始められる環境が整います。 git worktreeの導入ハードルを下げ、複数のタスクを並行して進めやすくするツールとして活用事例が共有されました。 持続するための工夫 10分勉強会がメインとなる開発業務の妨げにならず、継続的に実施するために、次のような工夫をしています。 発表のスキップを許容する 業務が忙しい時期や準備が間に合わない場合は、当日開催前までに周知すればスキップできるようにしています。 基本的には開発業務を優先し、発表者が自身の負荷状況を考慮して調整できる運用にすることで、無理なく続けられる仕組みにしています。 発表資料は任意 発表資料の作成は必須ではありません。 Notionに簡単にまとめるだけでも良いですし、実際の操作を画面共有しながら説明する形でも、誰かの書いたブログ記事を紹介する形でもOKにしています。 資料作成のハードルを下げることで、発表しやすい環境を作っています。 厳密ではないテーマ設定 基本テーマは設けつつ、テーマ以外の内容でも発表可能にしています。 業務での取り組み、ドメイン知識の共有、最近読んだ技術書の紹介など、特にチームに共有したいことなどがあれば、テーマ外でも発表可能です。 チーム内で開催する ファインディのエンジニア組織全体ではなく、Findy Freelance 開発チーム内で開催しています。 チーム内であれば、Findy Freelance固有のプロダクトや事業やドメイン知識に関する内容も共有しやすく、実務に直結した内容を扱いやすいです。 全体開催に比べると、対象者が限定されており、一定の前提知識も揃っているため、発表者もテーマ設定や内容を考えやすいと考えています。 開催時間を短くする オープン、クローズを含めて15分程度で会が終わるようにしています。 チームメンバー全員参加であっても、15分程度であれば業務の時間を大きく割くことなく参加しやすいと考えています。 効果と反響 チームメンバーの声 チームメンバーにアンケートを実施したところ、次のような声がありました。 AIキャッチアップの助けになっていたり、発表内容が実務に役に立っていることがわかりました。 良かった点: 色々MCPを知ることができたこと。Claude Codeの使い方を知ることができたこと。 AIのキャッチアップは大変なので知らなかった変更や知見を知れた CloudWatch Logsの検索mcpはかなりの頻度で利用しています 自身が仕様検討する機会が多く、認識合わせのためのUIモックが必要だと感じている中でGemini Canvasを用いた画面モックの発表があり、すぐに仕様のすり合わせで活用することができた。 また、5段階評価で「生成AIのキャッチアップに役立ちましたか?」という質問に対しては、平均4.4点という高評価を得られました。 チームAI活用率 勉強会だけの効果とは言い切れませんが、Findy Freelance開発チームではAIツールの活用率は高い値を維持しています。 Findy Team+ のAI活用レポートをみると、2025/09/16 - 2025/12/15の期間のAI利用者率は100%、AI利用プルリクの割合も70%を超えています。 単月でみると、最も高い月で10月のAI利用プルリク割合は約90%に達しています。 アンケートの反応なども合わせて考えると、10分勉強会がAI活用の促進に一定寄与していると捉えています。 メリット アウトプットによる知識の定着 人に説明することで、自分の理解が深まり、知識が定着しやすくなります。 自分ではわかっているつもりが、発表しようとすると、理解が不十分な部分に気づくことがあります。 そこを調べたり、説明の仕方を考えたりすることで、より深い理解につながります。 この勉強会において、一番恩恵を受けるのは発表者自身だと感じています。 AIのキャッチアップをチームで取り組める AIや関連ツールは日々進化しており、個人でキャッチアップするのは大変です。 一方で、新しいものがでてきたときに、少し触ってみる、試してみるということも重要だと考えています。 触ってみないと実際にそのツールがどのように役立つかを理解するのは難しいからです。 勉強会を通じて、他のメンバーが試したツールや活用事例を知ることで、個人のキャッチアップの負荷を軽減することができると感じています。 週2回という頻度も、変化の激しいAIツールのキャッチアップには適していると考えています。 聞いた内容をすぐに試せる 前述の通り、チーム内で実施しているため、発表内容が実務に直結しやすいです。 また、導入されているツールや対象とするシステムや環境が共通していることも多いため、発表を聞いた後にすぐに試してみることができます。 例えば、普段開発しているリポジトリにClaude Codeのカスタムコマンドを導入したという発表があった場合、他のメンバーにとっても普段さわっているリポジトリになるため、すぐに試してみることができます。 環境構築の手間も少なく、マージ済みであれば、勉強会を聞きながらその場で試すことすら容易です。 デメリット 体系的に学びたい場合や、基礎を固めたい場合には向いていないと考えています。 テーマは発表者が自由に選べるため、どんな内容が発表されるかは事前にはわかりません。 特定のトピックスに偏る可能性もありえます。また、深い内容を扱うには5分では時間がたりません。 Findy Freelance開発チームでは、現状ではミドル以上のエンジニアが中心の構成になっているため、自主性に一定の期待ができることもあり、この形式が機能していると考えています。 余談と「うちのAIがやらかしまして」の紹介 余談になりますが、10分勉強会では、試してみたけどうまくいかなかった事例も共有されることがあります。 また、AIの進化が早すぎて、発表した内容が古くなってしまったり、バージョンアップにより使えなくなったりすることもありました。 この記事を読んでくれている方の中にも、AIがうまく動いてくれなかった経験がある方がいると思います。 現在、Findyでは「うちのAIがやらかしまして」というAIを使ったときのちょっと笑えるやらかし体験をシェアする期間限定企画を実施中です。 ちなみにですが、私はこの投稿が好きです。 実際に体験がある方はぜひシェアいただけると嬉しいです! 他の方の投稿をみるだけでも面白いと思いますので、ぜひのぞいてみてください! おわりに Findy Freelance開発チームでは、10分勉強会を通じて、変化の激しいAIツールのキャッチアップをチームで取り組んでいます。 2025年は生成AI活用に焦点を当てて取り組んでおり、チームメンバーからも好評を得ています。 これは今のチーム構成や文化に合っているからこそ機能している面もあると考えています。 継続することが目的ではなく、チームの構成や人数や課題に応じて、勉強会の形式や実施するかどうか振り返ることも重要です。 ただ、どのような形式であれ、変化の激しいAIの進化をチームで協力しつつ、楽しみながらキャッチアップすることは継続していきたいと考えています。 ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。 興味を持っていただいた方はこちらのページからご応募お願いします。 herp.careers
アバター
こんにちは。 ファインディ株式会社でテックリードマネージャーをやらせてもらってる戸田です。 この記事は、 ファインディエンジニア #1 Advent Calendar 2025 の17日目の記事です。 adventar.org 現在のソフトウェア開発の世界は、生成AIの登場により大きな転換点を迎えています。 GitHub CopilotやClaude Codeなど生成AIを活用した開発支援ツールが次々と登場し、開発者の日常的なワークフローに組み込まれつつあります。 そんな中で先日、Claude Codeの新機能であるPluginsが公開されました。 そこで今回は、Pluginsの紹介と解説、作り方と利用方法を紹介したいと思います。 それでは見ていきましょう! Pluginsとは 作り方 利用方法 まとめ Pluginsとは PluginsはCustom slash commands, Subagents, Hooks, Agent Skills、MCPサーバーを使用してClaude Codeを拡張できる便利な機能となっています。 また、marketplacesからPluginsをインストールして、事前に構築されたCustom slash commands, Subagents, Hooks, Agent Skills、MCPサーバーを利用できるようにもなります。 code.claude.com 一言で言うと、Claude Codeの各種設定や機能をPluginsとして事前に用意しておき、それらを簡単に横展開できるようにした仕組みです。 開発組織やチーム間で、開発手法やワークフローを標準化するのに非常に役立ちます。 作り方 必要なファイルと、展開したい各種Claude Codeの設定ファイルなどを用意するだけでPluginsを作成できます。 まずPluginsを管理するための新しいリポジトリをGitHub上に作成します。作成したリポジトリをLocal環境にcloneしましょう。今回は TestOrg/DevPlugins というリポジトリを作成したとします。 次にリポジトリのrootに .claude-plugin というディレクトリを作成し、その中に marketplace.json というファイルを新規で作成します。 { "name": "DevPlugins", "owner": { "name": "TestOrg Inc." }, "plugins": [ { "name": "development-plugin", "source": "./development-plugin", "description": "Development plugin for TestOrg Inc." } ] } 次にリポジトリのrootに development-plugin/.claude-plugin というディレクトリを作成し、その中に plugin.json というファイルを新規で作成します。 { "name": "development-plugins", "description": "Development plugins for TestOrg", "version": "0.0.1", "author": { "name": "TestOrg Inc." } } これで DevPlugins というmarketplaceに development-plugin というPluginsが作成されました。 ここまで用意できれば、あとは展開したい各種Claude Codeの設定ファイルを development-plugin ディレクトリ以下に配置していくだけです。今回はCustom slash commandsを追加します。 --- description: Greet the user with a personalized message --- # Hello Command Greet the user warmly and ask how you can help them today. Make the greeting personal and encouraging. 全体の最小構成は次のようになります。 DevPlugins/ ├── .claude-plugin/ │ └── marketplace.json └── development-plugin/ ├── .claude-plugin/ │ └── plugin.json └── commands/ └── hello.md 作成したファイルをGitHubのデフォルトブランチに push すれば Plugins の作成と展開は完了です。marketplace と Plugins の設定ファイルを作成し、展開したい各種Claude Codeの設定ファイルを配置するだけでシンプルに構築できることが分かると思います。 利用方法 作成したPluginsを利用する方法を説明します。 まずPluginsの登録先を追加します。Claudeのコンソールに入って、次のコマンドを実行します。 > /plugin marketplace add TestOrg/DevPlugins このコマンドにより、GitHub上のリポジトリをmarketplaceとして登録します。 次に、作成したPluginsを実際にインストールします。続いて次のコマンドを実行します。 > /plugin install development-plugin@DevPlugins 実行すると次のような出力が表示されるので Install now を選択します。 ╭────────────────────────────────────────────────────────────╮ │ Plugin Details │ │ │ │ development-plugin │ │ │ │ Development plugin for TestOrg Inc. │ │ │ │ Will install: │ │ • Components will be discovered at installation │ │ │ │ > Install now │ │ Back to plugin list │ ╰────────────────────────────────────────────────────────────╯ インストールが成功すると ✓ Installed development-plugin. Restart Claude Code to load new plugins. と表示されるので、Claude Codeを再起動します。 再起動すると、インストールしたPluginsが利用可能になります。実際に利用するには、次のようにコマンドを実行します。 > /development-plugin:hello 実行すると次のような出力が表示されました。Pluginsを正しくインストール出来たことが確認できます。 ⏺ Hello! 👋 Welcome to DevPlugins I'm Claude Code, and I'm here to help you with anything related to this project. Whether you need to: - 🚀 Set up the development environment - 🔧 Build new features or fix bugs - 🧪 Write or run tests - 📊 Work with the database or migrations - 🤖 Integrate with Claude AI or GitHub APIs - 📝 Review code or create pull requests I'm ready to assist! I have full context of the project structure, authentication patterns, service architecture, and best practices for this codebase. What would you like to work on today? まとめ Pluginsを利用することで、開発組織やチーム間で開発手法やワークフローを簡単に標準化できるようになります。 弊社ではClaude Codeの共通の設定を自動で設定するCustom slash commandsや、Pull requestを作成するAgent Skillsなどを作成して開発組織全体に展開し、開発効率の向上に役立てています。実際に作成した Plugins の具体例紹介は、別の機会で改めてまとめたいと思います。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらから ↓ herp.careers
アバター
こんにちは、CTO室データソリューションチームでマネージャーをしている 開(hiracky16) です。 この記事は、 ファインディエンジニア #1 Advent Calendar 2025 の14日目の記事です。 adventar.org 先日、チームで半日ほど時間をとってワークショップ(オフサイトミーティング)を実施しました。今回は、そのプロセスの中で「生成AI(Gemini)をファシリテーター兼、壁打ち役として参加させる」という試みを行った話と、そこで決まった私たちの新しいミッション・ビジョンについて書きたいと思います。 データソリューションチームについて紹介 我々のチーム、データソリューションチームについて少し紹介すると現在は職能で言うとデータエンジニアのみが所属するチームで、現チーム体制になって約1年半が経過しました。横断組織でもあるため特定の事業の仕事に取り組むのではなく全事業のデータ活用に関する依頼に対応しながらデータ基盤を作っています。もともとはデータサイエンティストと一緒のチームでしたが、組織変更を経て、データサイエンティストやデータアナリストは事業部の方に所属となり今の形となりました。ファインディのエンジニアチームの構成は次のような形です。 ワークショップ開催の経緯 日々の業務としては、各部署のデータアナリストやサイエンティストの支援をしたり、データ活用の悩みを解決したり、全社横断の検索エージェント基盤を作ったり様々です。しかし、1年半走ってくる中で、マネージャーである私自身の中に、ある種の「モヤモヤ」が溜まっていました。 優先順位の悩ましさ ファインディでは4事業を展開している中で、事業ごとにデータ関連の仕事の相談を受けます。横断組織として複数の事業に関わる一方で、限られた人数の中で取り組むテーマに優先順位をつけながら進めています。さらに新規事業やプロダクトも控えており、今後は関わる事業やプロダクト、仕事の幅が広がる中で、より丁寧な判断が求められる場面も増えていくと考えています。 「具体的な」データ・AI戦略の言語化 優先順位に迷いながらでも現場は回っている状況ではある中で、中長期的な指針がより明確になることで、チームが同じ目的をこれまで以上に共有しやすくなると考えています。また普段は単一の事業やチームに最適な取り組みをするとよいことが多いですが、「ファインディとして」どうあるべきか?という全社視点をあらためて意識することの重要性も感じています。 データエンジニアの役割変化 生成AIの台頭により、これまでの「基盤を作って終わり」というスタイルに加えて、よりビジネス価値に踏み込んだ関わり方が求められるようになってきました。ファインディ主催のカンファレンス 「Data Engineering Summit 2025」 でも他社の事例を見聞きする中で、データエンジニアやデータ基盤の役割が変わりつつあることを改めて実感しました。自分がモデレーターを務めた「サイロ化解消のその先へ。ビジネス/データ、それぞれの視点で語るRevOps」というセッションでも、RevOpsという領域におけるデータエンジニアの新しい役割やキャリアについて話すことができました。 そんな危機感を感じ、チーム全員で一度立ち止まり、自分たちのミッションやビジョンを見直すタイミングだと思いました。ただ、私ひとりが悩んで決めたトップダウンの指針では十分ではありません。メンバー全員が腹落ちし、意欲的に働くための指針を作ること──それが今回のワークショップの目的でした。 準備 ワークショップを企画するにあたり、今回はGeminiを活用しました。 私自身過去ワークショップに参加したことはありましたが、主催するのは初めてです。準備や進行の面でうまくできるか不安がありました。また当時、課題感は言語化できていない曖昧な状態でした。 そこで、今回は次のようなフローで準備を進めました。 音声入力でひたすら喋る:現状の課題、チームの歴史、私の悩みなどを、脈絡なく音声入力でテキスト化 Geminiに投げ込む:その長文テキストをGeminiに渡し、「これらのコンテキストを踏まえて、半日のワークショップのアジェンダと、各パートの狙いを設計して」と依頼 壁打ちしてブラッシュアップ:Geminiから返ってきた案に対し、「ここはもっと発散させたい」「ここは収束させたい」と対話し、スライドの骨子を作成 結果、課題の言語化にも成功しましたし、ワークショップの準備も比較的時間をかけずに終えられたと思います。 実施 当日は、会議室を半日貸し切って付箋を使いながらワークを行いました。 1. 情報のインプット 役職や社歴に問わず文脈を共有した上でワークに入れるように情報のインプットパートを設けました。まずは開催に至った経緯を丁寧にメンバーに説明し、私が抱いた悩みをメンバーも感じているのかの確認やメンバー間で違和感や課題感を揃えるところから始めました。また入社時期もバラバラで、直近だと3ヶ月前に入社したメンバーもいたのでチームの成り立ちから現状に至るまでの歴史を振り返りました。次に会社や部署の指針やミッションをスライドに記述することで会社から求められていることを意識して話し合いできるようにしました。 「生成AIの進化によるデータエンジニアやデータ基盤に求められる役割」をDeep Researchでまとめてもらい、それらを斜め読みする時間も設けました。社内の仕事だけしていると個社最適なスキルになりがちなので、世の中一般的なデータエンジニアリングのスキルと比較しながら議論しました。以下Deep Researchの結果を簡単にまとめてもらったものです。 2. 存在意義のワーク:「もし自分たちが1年いなかったら?」 まず取り組んだのが、「もし私たちのチームが存在しなくて、過去1年間不在だったら会社はどうなるか?」という思考実験です。 「データ連携が止まって、数字がズレる」や「誰もデータ基盤のメンテナンスをしなくなって、コストが爆増やセキュリティへの対応が遅れる」といったリアルな痛みから、「ツールが統一できずに情報やノウハウが分断される」といった機会損失まで様々なことが考えられました。このワークを通して我々のチームが会社や他のチームから求められていること、つまりミッションを考える上での重要な要素を洗い出すことができました。 3. Will/Can/Mustでビジョンを描く 次に、3年後の未来像を「Will/Can/Must」のフレームワークで言語化しました。メンバー個々人のキャリア上のWillと会社のビジョンである「挑戦するエンジニアのプラットフォームをつくる。」とが重なる部分を見出してチームのビジョンにしたいと思いこのワークを実施しました。 以下私が書いたことを例です。 - Can(できること) - データエンジニアリングと Google Cloud チョットデキル - 採用活動 - Must(すべきこと) - A事業部のデータ基盤開発、運用 - マネージャーとしての調整業務 - Will(やりたいこと) - 全社のデータ活用を伴走し売上に貢献できるデータエンジニアになる 他のメンバーにも同じように書いてもらい、まずはメンバー間で一緒にできそうなことはないか探りました。そうすると「価値のあるデータ」や「売上に貢献できる」というエッセンスが得られました。 4. ミッション・ビジョンを考える 最終的に決まったミッションとバリューがこちらです。 Mission: 「データとエンジニアリングの力で、ファインディの知恵を結集し、意思決定を加速させる」 Vision: 「事業成長に並走できるデータxAI基盤を作る」 1~3のステップで得られた意見を元にチームでミッション・ビジョンを考えました。内容をGoogleスライドに書き込みながら進めていたためGeminiにそのまま添付し、ミッション・ビジョンの案を3つずつ考えてもらいました。あらかじめ4つの基準を考えており、「情熱が持てるか?」「会社のミッションと関連性はあるか?」「他のチームと比べてオリジナリティがあるか?」「シンプルで覚えやすいか?」をメンバーの主観で点数化しながら最終的に1つに決めました。 最後に言葉選びを我々のチームやファインディっぽく変更しました。例えば、会社のバリューに関連するワード「加速(スピード)」や「並走(チームワーク)」を使いました。「集結させる」のか「結集させる」のかで悩んだ際に「結集」には「力を合わせる」という意味合いがあるらしく採用しました。 振り返りとこれからの話 ワークショップを通じて、認識が揃ったことはもちろんですが、Geminiを議論に混ぜることで、より客観的にミッションやバリューを作る上で機能したことの気づきがありました。ある程度コンテキストを与えていたところはありますが、Geminiはより深い事情を知っているチームメンバーよりもいい意味で違った視点の意見を出してくれることが多かったです。またDeep Researchの結果を使って現代のデータエンジニア像をインプットできたのは客観的な視点で情報をまとめてくれたおかげです。 もちろん、Geminiは優秀な壁打ち相手でしたが、AIに頼り切るだけでは「メンバー全員が腹落ちし、意欲的に働くための指針を作る」という部分は達成できなかったように思います。最後に自分たちの手で細かい微調整をし、想いを込めていくプロセスこそが、今回のワークショップで必要だった作業だとわかりました。結果として、会社から求められていること(Mission)と、チームが成し遂げたいこと(Vision)が繋がり、「自分たちの言葉で決めた」という強い納得感のある指針が生まれました。 私たちデータソリューションチームはこの新しいミッション・ビジョンのもと、生成AI時代の新しいデータ基盤づくりに挑戦していきます。ファインディやデータソリューションチームのミッションに共感し、一緒にビジョンを叶えたい方、や我々チームの取り組みに興味を持ってくださった方はぜひ一度カジュアル面談でお話ししましょう! herp.careers
アバター
こんにちは、ファインディでソフトウェアエンジニアをしているnipe0324です。 この記事は、 ファインディエンジニア #1 Advent Calendar 2025 の13日目の記事です。 adventar.org コーディングエージェントを使う中で、 実装は早くなる一方CIが遅いと思うことはないでしょうか? かくいう私も、Claude Codeを使って並列にプルリクエストを作る中で「CI遅いなー」と思うことがよくありました。 CIの実行時間を短くしたいという気持ちはありつつ、メインの開発があるのでなかなか改善に手をだせませんでした。 しかし、2025年はAIエージェント元年。 せっかくなら、「Claude Codeに任せられるだけ任せてみよう!」と思い、CIのテスト実行時間の削減を任せてみました。 Claude Codeに「方針検討」「対応・効果測定」を任せ、私は意思決定とレビューに注力することで、 メインのタスクがありながらも、CIのテスト実行時間を約2分短縮 できました。 この記事では、具体的な内容を交えながら、Claude CodeにCI速度改善の方針検討と対応・効果測定を任せた事例をご紹介します。 CIのテスト実行時間が7分から5分に短縮 Claude CodeによるCI高速化の改善結果は次のとおりです。 CIでのテスト実行時間が7分から5分になり、 約2分短縮 できました。 対応前 対応後 改善 7分01秒 5分05秒 -116秒 (-28%) たかが2分の短縮と思うかもしれませんが、1日50-60回ぐらい実行されているので1日2時間、月の営業日を20日とすると月40時間になるので、 月5営業日分の待ち時間が削減 できました。 今回Claude Codeに実施してもらった改善は次の4つです。 並列マシンへのテスト割当をファイルサイズベースから実行時間ベースに変更(60秒短縮) テストファイルごとの実行時間の偏りが大きかったので平準化 不要なジョブを削除(27秒短縮) 影響のないジョブがクリティカルパスに存在していたので削除 aptでインストールしているライブラリのキャッシュ(25秒短縮) 毎回インストールして30秒ぐらいかかっていたのをキャッシュすることで2-3秒に短縮 テスト用のDBダンプのキャッシュ(55秒短縮) 並列実行のためDBスキーマ作成とシードデータ登録に1分弱かかっていたが、キャッシュ化で20秒前後に削減 Claude CodeにCIの高速化を任せていく CIのテスト実行時間の短縮のため、Claude Codeに「調査依頼」、「改善案の実施と効果測定」、「結果のとりまとめ」をそれぞれ任せていきました。 ファインディでは、CI/CDにGitHub Actionsを使っています。 GitHub Actionsでは、CIのワークフローの詳細な実行時間やログがあり、また、ghコマンドでそれらの情報が取得できるため、AIエージェントが自律的に改善・効果測定をできる環境が整っていました。 結果として、CI高速化はAIエージェントにとても任せやすいタスクだと感じました。 調査依頼 調査依頼では次のようなプロンプトで調査依頼をしました。 # プロンプトイメージ CIが7分と遅いので、5分以内にしたい。改善案を検討してください。 CIの実行結果: https://github.com/Findy/Xxxxx/actions/runs/1234567890 CIの実行結果を確認し、現状分析と改善提案をしてくれました。 Claude Codeの調査結果イメージ(一部省略) これまでもCI高速化を何度かしてきて改善余地が少なくなっている中でも、改善効果がありそうな改善案を6つほど提案してくれました。 クリティカルパスを利用した分析や削減効果と対応工数による優先度付けなど基本を押さえた分析と提案をするのですごいな!と思いました。 実際Claude Codeに改善案を対応してもらう中で一部想定と違うこともありましたが、適宜結果を確認して方向を微修正することで結果として実行時間短縮につながりました。 改善と効果測定 アイデアとして有望そうに見えますが、実際に試して効果を測定するまでわかりません。 そのため、Claude Codeに改善と効果測定を実施してもらいました。 # プロンプトイメージ https://github.com/Findy/Xxxxxx/issues/12345 の 「parallel_tests実行時間ベース分配」の対応を実施してください。 PR作成後にCIの実行時間を確認し、PRボディに見込みと実績を表形式で記載する。 Claude Codeが作成したPRイメージ Claude Codeがghコマンドを使うことで、GitHub Actionsの各ジョブやステップの実行時間や状況を知ることができるため、自律的に改善を任せることができました。 また、必要に応じてプロンプトに「CIが失敗したら成功するまで対応する」「改善結果が見込みに届かない場合、原因分析して追加改善をする」などの指示を追加して自律性を高めました。 結果の取りまとめ CIのテスト実行時間を短縮できたため、結果の取りまとめもClaude Codeに依頼しました。 # プロンプトイメージ https://github.com/Findy/Xxxxx/issues/12345 の対応が 一通り終わったので結果をとりまとめたい - 対応前後でのCIのテストの実行時間の比較 - 表形式で、サンプル数、中央値、平均値をだす - 対応前は 2025-12-05 と 対応後は 2025-12-10 のデータを集計 - 1分以内のタスクはテストがスキップされているので除外する - やったことの概要 - 箇条書きでシンプルに記載 - 結果をシンプルにまとめ、イシューにコメントをする Claude Codeのイシュー対応結果のまとめイメージ 数字があっているのか若干気になりましたが、確認してみると細部は少し怪しいものの、実際にCIの実行履歴を目検で眺めてみると概ねあってそうでした。 まとめ 今回は、Claude CodeにCIのテスト実行時間の改善を丸っと任せることができました。 その結果として、 自分はメインのタスクをしながらも、テスト実行時間を7分から5分に短縮 できました。 個人的にClaude Codeにうまく任せることができたポイントとしては、 「Claude Code自身がPDCAを実施したこと」 と 「影響範囲や制約が少ない領域だったこと」 だと考えています。 ゴールが明確で、エージェント自身がPDCAを実施 CIの実行時間を7分から5分に削減とゴール明確で測定可能 エージェントが直接CIの実行時間やログを確認できるため、改善後の効果測定や原因分析が自律的にできる 影響範囲や制約が少ない領域 改善に失敗しても、CIのテストが失敗するだけで影響範囲が限定的 制約もワークフローの実行時間、保守性、コスト、セキュリティぐらいで少ない 以上、参考になったら嬉しいです。 CIの実行時間が気になる方は、ぜひAIエージェントに任せてみてはいかがでしょうか。 最後に、現在Findyでは「うちのAIがやらかしまして」というAIとの試行錯誤の結果をシェアする期間限定企画をやっています。 「AIエージェント活用しているぞ!」という方は、ぜひのぞいてみてください。 findy-code.io
アバター
はじめに こんにちは!ファインディのTeam+開発部でエンジニアをしている澁谷( TENTEN11055 )です。 この記事は、 ファインディエンジニア Advent Calendar 2025 の11日目の記事です。 今年11月、AWS が主催する AI-DLC Unicorn Gym に参加しました。 AWS主催 Unicorn Gym 最終日の成果プレゼンの様子 このプログラムの開発プロセスはAIと共に歩む仕様駆動開発。 部分的なAI活用から一歩進んだ開発体験を得ることができ、同時に「今後はより読解力が求められる」と感じました。 この記事では読書習慣がなぜスキルになるのか、自分の体験をもとに書いています。 はじめに AI-DLC(AI駆動開発ライフサイクル)とは AI-DLCにおけるレビュー負荷 読書を始めてみた 理解力がある人の特徴 「読む」と「理解」は別 人間が監視する時代、読書がどう活きるか まとめ AI-DLC(AI駆動開発ライフサイクル)とは これまで開発の一部にAIを用いるケースが多く、その真価を発揮しきれないなどの課題がありました。 AI-DLCでは要件、ユーザーストーリー、設計、開発の全てをAIベースで行います。 そして 人間の役割は監視、つまりレビューです 。 作業の一切をAIに任せ、人間はそれを監視して品質を担保しながら素早く成果物を提供できるというものです。 AI 駆動開発ライフサイクル:ソフトウェアエンジニアリングの再構築 AI-DLCにおけるレビュー負荷 AI-DLCでは実装前に多くのドキュメントを作成します。 そのため最も時間を使ったのは「文章を読み、AIの意図を正しく理解すること」 でした。 AIの文章は論理的ですが、人間が読みやすいかどうかでは最適化されていません。 ときには矛盾を見抜き、ときには曖昧な記述を解釈して補う必要があります。 AI-DLCではこのドキュメントレビューの質がそのまま品質に影響します。 こうした経験から、「読む力」を鍛える必要性を強く感じました。 読書を始めてみた というのも、自身も普段の仕事で読解力に課題を感じており、対策として半年前から読書習慣を続けてきた背景があったからです。 文章の理解に時間がかかる 一行戻って読み直す回数が多い 説明を聞き返すことが増えた こうしたものを少しでも解消したくて、「読む力」を鍛える目的で始めました。 理解力がある人の特徴 読書を続ける中で、「理解力の高い人とは何が違うのか?」を意識して観察するようになりました。 理解力の高い人は、次の点が際立っています。 説明の意図を素早く理解できる 情報の本質を捉えられる そのため発言や判断が的確になる そしてこうした人たちは例外なく読書量が多い印象です。 「読む」と「理解」は別 こうして観察と実体験を重ねるうちに、読む行為と理解する行為は別の能力だと改めて実感しました 「それはそう」と言われてしまいそうですが、これを同時に行うトレーニングをできるのが読書のすごいところ。 以前に比べて本を読むのが早くなり、それは先に読んだ文章を理解しながら次の文章を読み進めているからだと気づきました。 また、文章全体を読みながら「重要な部分だけ自然と拾える感覚」も少しずつ身についてきました。 人間が監視する時代、読書がどう活きるか ここで話を AI-DLC に戻すと、この手法は前述の通り多くのドキュメントを作成します。 つまり「読む力」「本質をつかむ力」がそのまま成果物の質に跳ね返ってきます。 今回のワークショップで実施したドキュメント数は次の通り。 Inception(要件、ストーリー整理、 ユニット変換) 12ドキュメント Construction(ドメインモデル設計、フェーズの定義など、そして開発) 3ユニット、計18ドキュメント 合計30のドキュメントをレビュー後、コード生成に入るのです(そしてコードレビューへ...)。 そんな丸一日ドキュメントを眺める際に重要だったのは次の点です。 文章を短時間で理解できる力 AIが生成した成果物の意図や本質を汲み取る力 論理を追う集中力 これらは全て読書で鍛えることができます。 私も本当にまだまだですが、ワーク中「読書しててよかった〜」と思いました。 まとめ AIに何かを生成してもらうのはもはや当たり前の時代になりました。 人間の価値は「作業」から「確認と意思決定」に比重が移りつつあるように感じます。 AI は体系的に詳細な作業計画を作成し、積極的に意図のすり合わせとガイダンスを求め、重要な決定は人間に委ねます。これが重要なのは人間だけが情報に基づいた選択を行うために必要なビジネス要件の文脈的理解と知識を持つからです。 (AI 駆動開発ライフサイクル:ソフトウェアエンジニアリングの再構築 より) 読書はそんな時代においても開発の手助けとなり、基礎体力になります。 で、どんな本がおすすめかというと何でもいいと思います。 技術書、ビジネス書、小説でも十分トレーニングになります。 私は最近 ザ・ロイヤルファミリー という競馬が舞台の小説を読んでいました。 おすすめです。ドラマもおすすめ。 AI時代は基礎知識や読解力など、アナログ(?)なスキルが求められているかもしれませんね。 ファインディでは一緒に働くメンバーを募集中です! よかったら覗いてみてください。 herp.careers
アバター
はじめに こんにちは、GenAI Enablementチームです。 この記事はファインディエンジニア #3 Advent Calendar 2025の9日目の記事です。 今年1月に「GenAI Enablementチーム」を立ち上げてから現在までの約1年間における活動を総括します。 チーム組成から今日に至るまで、どのような課題に直面し、それらをどう解決して成果に繋げてきたのか。その過程で得られた「理想と現実」のギャップや、具体的な成果・反省点について詳述します。 今後、自社でのGenAI活用推進を担う方々にとって、実践的なヒントとなれば幸いです。 今月から、沢山のアドベントカレンダー記事が執筆される予定ですので、年末のお供に是非読んでみてください。 adventar.org GenAI Enablementチームって? まず簡単に、チームのご紹介から。 ファインディにはプロダクトマネジメント室直下にGenAI Enablementチームという、その名の通り 全社のデータ生成AIを含む広義のAI活用を推進し実装する、データサイエンティスト の専門部隊が存在します。 今でこそメンバー5名体制(兼務を含む)になりましたが、立ち上げ当初(2025年1月)はマネージャーと、入社したばかりのメンバー1名、計2名からのスタートでした。 チーム誕生の背景 会社として、2024年を通じて自社の事業やプロダクトに生成AIを組み込むことは、もはや『あったらいいな』ではなく、企業の生存確率を高めるための『必然』であるという確信に変わったからです。 プロダクトマネジメント室という部署にこのチームが置かれたのも、単なる業務効率化だけでなく、 プロダクトの競争力強化 に直結させるため。 そんなミッションを背負い、チームが発足しました。 【社内活用】プロダクト使い方Botが生んだ「意識の180度転換」 まず着手したのは、社内のAI偏差値の断絶を埋めることでした。CTOや一部のエンジニアを筆頭に、生成AIを活用する動きは社内でも出始めていたものの、まだまだ当時全社的に「生成AI?便利だって聞くし使いたいけど業務が忙しいのと、どう使っていいのかわからない…」のような空気感が漂っていました。 このままではイネーブルメントはできないと考え、はじめに生成AIアプリツール「 Dify 」を導入しました。Difyは、Slackと連携して便利なチャットボットを簡単に生み出すことができるため、これを活用し、最初のユースケースとして「 Findy Team+の使い方Bot 」を作成して全社展開してみました。 Findy Team+使い方Botの雰囲気 「便利やん!」から始まった変化 とはいえ正直、最初は「まあ使ってもらえれば御の字か」くらいに思ってました。 しかし、蓋を開けてみれば想定以上の反響。「これ便利すぎ!」「こんな用途で、似たようなBotを作成したい!」と、社内は一種の熱狂に包まれました。 社内の声① 社内の声② 社内の声③ この「Findy Team+の使い方Bot」は、Findy Team+の機能に関する説明や社内で蓄積されたドキュメント等々をナレッジとしたBotであり、これまで事業運営によって培ってきたものが結果として生成AIを強化する武器となってくれています。 しかし、このBot施策の本当の成果は使われたことそのものではありません。 Botを使っているうちに、社員みんながある事に気付いたこと。これこそが最大の成果です。 AIに適切なコンテキスト(データ)を渡し、そのデータを活用する役割を与えれば、強力なパートナーに変貌する ということです。今までは、 「データ入力?次の予定までに済ませなくちゃいけない準備が優先だから…」 となりがちだった業務の後処理が、 「ここに入力しておけば、AIが賢くなって後で自分が楽できる!きちんと入力しよう!」 という意識に変わった事が、当初想定していなかった一番のインパクトでした。 すなわち、 データをきちんと入力・整備することの重要性 への意識が、180度変わったんです。 長年事業を積み重ねてきたデータ資産の価値が再定義され、全社の目線が揃った瞬間でした。 社内の声④ 【事業貢献】Findy Insightsの立ち上げとα版リリース GenAI Enablementチームの業務は、社内の便利ツール作りだけではありません。 今年9月に提供開始された Findy Insights という 生成AIを中心に据えた新規プロダクトの立ち上げとα版リリース にもPoCから実装まで関わりました。 プロダクトの簡単な概要をご紹介すると、「Findy Insights」は、 日々集まる膨大な「顧客の声」や「市場データ」を生成AIが分析し、「次にどんな機能を作るべきか(プロダクトディスカバリー)」を支援するサービス です。 今までPMが泥臭く読み込んでいた議事録などのテキストデータを、AIが分析して「こういうニーズが増えている」と提案してくれます。勘と経験だけに頼らない、 データドリブンな意思決定を加速させるツール となります。 プロダクトオーナー(PO)の起案からPoCの着手を2月に開始し、約3ヶ月の検証期間を経てから5月のプロダクト開発開始。9月のα版公開と顧客提供開始というスピード感あふれるタイムスケジュールで駆け抜けることができました。 本来であれば1年はかかる規模の新規プロダクト開発でしたが、半年足らずで顧客への提供開始まで漕ぎ着けることができました。その背景には、 提供予定の機能のPoCを、POと連携しながら常に最前線で取り組み続けたこと PoCにより確定した仕様をアプリケーションエンジニアと連携し、実装にも加わりつつレビューにも入り込み、密な連携を取り続けたこと などと振り返っています。 もちろん、GenAI Enablementチームだけではなく、このプロダクトの開発に関わった全員の尽力に寄るところは言うまでもありません。 提供開始後まもなくではありますが、既に 数十社以上との商談やトライアル開始 などで引き合いを頂けている状況であります。 また、今後も様々な機能の開発とアップデートを予定していますので、どこかの機会でご紹介できればと思います。 取り組みの成果と社内評価 たった2名体制ながら、社内活用向けのBot開発と、事業貢献につながる新規プロダクト立ち上げの両輪で取り組みを進めました。その結果、半期に一度の全社表彰で受賞とノミネートの評価を得ることができました。 表彰トロフィーと表彰状 【知見共有】データサイエンティストがいなくても実装できる体制へ 成果が出れば出るほど、ぶつかった壁が「リソース不足」でした。 ML(機械学習)やLLMの実装は、一定部分をデータサイエンティストに依存してきた背景がありました。 社内活用や事業貢献の取り組みを通じて同時に取り組んだのが、 エンジニアリングの冗長化 です。 ML/LLMを伴う機能開発の概念フロー(Before) これまでデータサイエンティストだけで完結させていた実装ノウハウを、プロジェクトを通じて社内のエンジニアや他組織に積極的に展開しました。 その結果、今では実装面においてデータサイエンティストの手が空いてなくても、社内エンジニアに頼ればOKという状態になりつつあります。 ML/LLMを伴う機能開発の概念フロー(After) 実装工数が理由でお断りせざるを得なかった依頼も、レビュー/レビュワーの関係になりながらエンジニアチームと連携しながら進めることができるようになったことは、非常に大きな一歩だったと振り返っています。 やりきれなかったこと ここまで良い取り組みを書いてきましたが、その裏側には、思うように前に進められなかったことも少なくありませんでした。 お断りの連続 問い合わせや相談は急増しましたが、リソースには限りがあり、新規開発や業務改善の多くを先送りせざるを得ない状況が続きました。 生成AIフレンドリーなデータ整備 新しい取り組みを進めようとするほど、その実現に必要なデータが不足していたり、整備が十分でない場面に直面しました。 「業務改善のために Team+ の使い方Botのような仕組みが欲しい」という声も多くいただきましたが、前提となるデータが不足していたり、そもそも存在しないケースもありました。 データ活用、新規開発、Ops改善の推進に向けて、これらの課題を来年にかけて解決する必要があります。来期は、計画的に取り組みを進めていきます。 まとめ この1年の取り組みを経て、データ活用への意識やモメンタムを産むには、論より証拠。まずは作って示すことが効果的な方法の1つである事を学びました。 新規プロダクトをスピード感を持って立ち上げるには、データサイエンティストが常にPoC先頭に立って絶え間なく行い続けることができる体制を整える事が大切である事を学びました。 最後に GenAI Enablementチームではデータ・AI活用を用いて一緒に事業貢献に取り組んでいく仲間を募集しています。興味のある方はぜひカジュアル面談等々でお話ししましょう! herp.careers
アバター
こんにちは、ファインディのみっきー @mikiko_bridge です。 12月6日(土)に池袋で開催された Developers Boost 2025 の「Hello, new world! ~技術とキャリアを次のステージへ~」というテーマのLT枠で登壇しました。 翔泳社さんのイベントで登壇するのは2回目です。昨年、 Women Developers Summit 2024 でLTをさせていただき、再び登壇の機会をいただけて本当に嬉しいです! 本記事では、私のLTの内容と、登壇準備を通じて得た気づきについてお伝えします。 ファインディと生成AI ジュニアエンジニアはどう生きるか? 伸び悩むわたし 5ヶ月間、何をやったか テストの追加 コードドキュメントの追加 結果 現在とこれから 登壇資料 おわりに ファインディと生成AI ファインディでは、生成AIの活用を推進しています。 AI推進チームが設立され、エンジニアが開発に集中できる環境が整っています。AI推進チームがAIのキャッチアップや活用をサポートしてくれるため、最新技術を取り入れやすい環境です。 AI活用事例については、次のブログをご覧ください。 https://tech.findy.co.jp/archive/category/GenAI%E3%83%BBLLM https://tech.findy.co.jp/archive/category/Claude https://tech.findy.co.jp/archive/category/Devin https://tech.findy.co.jp/archive/category/MCP https://tech.findy.co.jp/archive/category/GitHub%20Copilot ジュニアエンジニアはどう生きるか? 生成AIが当たり前になった今、ジュニアエンジニアとしてどう成長していくべきでしょうか。これまでは、good first issue やテストコードの追加といった小さなタスクから始めて、徐々にスキルを身につけていくのが一般的でした。 しかし、生成AIの登場により、コードの自動生成やデバッグの支援が簡単にできるようになり、ジュニアエンジニアが直面する課題も変わってきています。 伸び悩むわたし ファインディに転職してから、チーム目標である1日4件のプルリクエスト作成をほぼ達成できない日々が続いていました。 コードを書いても思うようにいかず、レビューで指摘される箇所も多く、「なんとなくうまくいかないな」という感覚が続きました。 同期入社のエンジニアたちが次々と新しい機能を実装していく中で、自分だけが取り残されているような焦りと不安を感じていました。 そんな状況を見かねて、テックリードの方がメンターとなり、毎日1on1をすることになりました。テックリードに声をかけられることはなかったので、1on1の予定が入った時はめちゃくちゃビビっていました。1on1の当日、怒られると思っていたのですが、そうではなく、今後どうやって成長していくべきかを真剣に話し合いました。 そして、5ヶ月間の修行が始まりました。私は、「あえて生成AIという便利なツールに頼ることなく、まずはエンジニアとしての基礎をしっかりと固める」という方針を選びました。 5ヶ月間、何をやったか 2024年12月から2025年4月までの約5ヶ月間、私はテストのリファクタリングとコードドキュメントの追加という地道な作業に集中的に取り組みました。テックリードの方がメンターとなり、毎日1on1を行い、進捗や課題について相談しました。 テストの追加 ファインディはテストカバレッジが90%超えを維持していますが、さらに堅牢なテストにするためのリファクタリングを行いました。 具体的には、ソート機能に関するテストを強化しました。 境界値や閾値を意識したテストデータを用意する ソート順が正しく機能していることを検証するため、ID順とは異なる順序でデータを配置し、意図した並び順になっていることを確認する 条件に該当しないデータ(対象外となるケース)も含めることで、フィルタリングロジックが正しく動作していることを保証する 例えば、次のようなテストコードを書きました。 # ソート機能のテストの例 describe ' ソート機能のテスト ' do let!( :user1 ) { create( :user , name : ' Charlie ' , created_at : 1 .day.ago, is_active : true ) } let!( :user2 ) { create( :user , name : ' Alice ' , created_at : 3 .days.ago, is_active : true ) } let!( :user3 ) { create( :user , name : ' Bob ' , created_at : 2 .days.ago, is_active : true ) } let!( :inactive_user ) { create( :user , name : ' Dave ' , created_at : 4 .days.ago, is_active : false ) } it ' 名前順でソートされること ' do result = User .active.order_by_name expect(result.map(& :name )).to eq([ ' Alice ' , ' Bob ' , ' Charlie ' ]) end it ' 作成日順でソートされること ' do result = User .active.order_by_created_at expect(result.map(& :name )).to eq([ ' Charlie ' , ' Bob ' , ' Alice ' ]) end it ' 非アクティブなユーザーが除外されること ' do result = User .active expect(result).not_to include (inactive_user) expect(result.count).to eq( 3 ) end end 初めはテストデータの作成ミスがあったり、想定以上に時間がかかったりしていました。レビューコメントをもらう数も多く、なかなか思うように修正が進まないこともありました。 しかし、徐々にフィードバックを活かして改善を重ねていくうちに、最終的にはテストケースの漏れを自分で見つけられるようになりました。 コードドキュメントの追加 テストの追加が進む中で、コードドキュメントの整備が課題として浮上しました。特に、内部実装の共通処理に関するドキュメントが不足していたため、こちらの整備に注力しました。 コードドキュメントの追加を始めた当初は、例外処理の仕様や実際の使用方法の理解に苦労し、作成に時間がかかることも多くありました。 具体的には、次のようなYARD形式のドキュメントを追加しました。 まず、コメントドキュメントがない状態のコードを見てみましょう。 class UpdateUserInteractor include Interactor delegate :user_id , :name , :is_active , :roles , :options , to : :context , private : true def call update_user context.user = user rescue ActiveRecord :: RecordInvalid => e Logger .error_exception(e, message : ' Failed to update user ' ) context.fail!( message : ' Failed to update user ' ) end private def update_user # 実装 end end このコードを見ただけでは、 roles には何が入るのか、 options にはどんなパラメータを渡せばいいのか、よくわからないですよね? そこで、YARD形式のコメントドキュメントを追加してみました。 # Interactorのコメントドキュメントの例 # # @attr user_id Integer ユーザーID # @attr name String 名前 # @attr is_active Boolean アクティブかどうか # @attr roles Array<Role> 権限一覧 # @attr options Hash { # ids: Array<Integer> IDのリスト。 # mode: String[Optional]("include") 選択モード # is_verified: Boolean (false) trueの場合、検証済みとして扱う # }[Optional] オプション設定 # # @example # UpdateUserInteractor.call( # user_id: 1, # name: 'John Doe', # is_active: true, # roles: [Role.first], # options: { ids: [1, 2, 3], mode: 'include', is_verified: true } # ) # class UpdateUserInteractor include Interactor delegate :user_id , :name , :is_active , :roles , :options , to : :context , private : true # Interactor実行 # # @return Interactor::Context { # user: User 更新後のユーザーデータ # message: String エラーメッセージ # } コンテキスト def call update_user context.user = user rescue ActiveRecord :: RecordInvalid => e Logger .error_exception(e, message : ' Failed to update user ' ) context.fail!( message : ' Failed to update user ' ) end private def update_user # 実装 end end いかがでしょうか?コメントがあると、各パラメータの型や意味、使用例が明確になって、格段にわかりやすくなりましたよね! こうしたコメントドキュメントを追加したことで、自分自身がコードを読み返すときにも理解しやすくなりました。 後から参加する新メンバーにとっても助けになるし、生成AIにコードを解析してもらうときにも正確な情報を渡せるので、AI活用の場面でも役立っています! 対応が進むにつれて作業の質が上がり、自力も少しずつ付いてきたため、最終的にはテストケースの漏れを自分で見つけられるようになりました。 ファインディでは日報・週報の文化があり、テックリードからは「周りではなく過去の自分と比較しましょう」と言われてきました。過去の日報や週報を読み返してみると、2025年4月の週報に「修正が必要な箇所を見極める力がついてきた」という記述がありました。 自分の成長を客観的に実感できた瞬間でした。 結果 取り組みを始めた当初は、プルリクエストの作成が週に7.2件程度というペースで、レビューの数も多い状態でした。 2024/07/01〜2024/11/30までの1週間あたりにPR作成数 しかし、作業を続けていくうちに、徐々にコードの書き方やテストの構造に慣れてきて、最終的には1日あたり18件のプルリクエストを作成できるようになりました。 2024/12/01〜2025/04/30までの1週間あたりにPR作成数 現在とこれから 5ヶ月間の修行を通して、生成AIや目新しい技術の前に、まず基礎を固めることが大切だと実感しました。これからは、基礎力upをベースに生成AIを適切に活用しながら、より品質を高めていきたいと考えています。 現在は、生成AIをピンポイントで利用しています。以前と違って、出力結果を鵜呑みにはしていません。コードリーディングの補助や、命名の提案など、具体的なタスクに対して活用しています。 登壇資料 Speaker Deckで資料を公開しました。 「生成AIを"おあずけ"された私〜自力で書く力がついた半年間〜」 speakerdeck.com おわりに 今回のLTでは、生成AIが当たり前になった時代において、ジュニアエンジニアとしてどう成長していくべきかについて、私自身の経験をもとにお話ししました。 生成AIは非常に強力で便利なツールですが、それを本当の意味で使いこなし適切に活用していくためには、基礎的な技術力やプログラミングの根本的な理解が不可欠だと感じています。 私はまだまだ成長途中ですが、この5ヶ月間の修行を通じて、焦らず地道に基礎を固めることの大切さを実感しました。同じようにキャリアをスタートした皆さんにとって、私の実践と学びが技術とキャリアを次のステージへ進めるヒントになれば幸いです。 最後に、このような貴重な機会をくださった翔泳社の皆さま、そして当日ご参加いただいた皆さまに心より感謝申し上げます。ありがとうございました! ファインディでは共に働く仲間を募集中です! 興味がある方はこちらから↓ herp.careers
アバター
こんにちは!ファインディのTeam+開発部の甲斐( @karukan013L23 )です。この記事は 🎄ファインディエンジニア #1 Advent Calendar 2025 7日目の投稿です。 adventar.org 去年まで1度も登壇したことがなかったのですが、今年は次の3つのイベントに登壇しました。 2025/6/25: Mita.ts #6 2025/8/20: すごくすごい。フロントエンドミートアップ 〜複雑GUI・アーキテクチャ設計を語ろう 〜 2025/11/23: TSKaigi Hokuriku 2025 今回は、登壇経験のなかった私が登壇に挑戦したきっかけや、各イベントの登壇内容、そして登壇を通して得られた学びについて紹介します。 登壇のきっかけ Mita.ts 登壇内容 登壇してみて すごくすごい。フロントエンドミートアップ 〜複雑GUI・アーキテクチャ設計を語ろう 〜 登壇内容 登壇してみて TSKaigi Hokuriku 2025 登壇内容 登壇してみて 登壇準備でやってよかったこと 1. 登壇内容の壁打ち 2. 話したいことをとにかく書き出す 3. 登壇時に話す内容を全てスピーカーノートに書き出す、発表練習を繰り返してブラッシュアップ 4. 登壇資料のレビュー依頼 まとめ 登壇のきっかけ きっかけは、TSKaigi 2025の懇親会でした。来年のTSKaigiはプロポーザル出して登壇してみたいねと懇親会の参加者の方と一緒に話していました。私はまだ登壇したことがなかったのでそのことを話すと、「じゃあ1回登壇してみようよ」と直近登壇できそうなLTイベントを探してくださり、私はそのLTイベントに登壇枠で申し込みました。これが最初の登壇への一歩でした。 Mita.ts イベントリンク: https://mitats.connpass.com/event/353424/ 登壇タイトル: 「tsgoを触ってみて得た学び」 登壇資料 speakerdeck.com 登壇内容 Announcing TypeScript Native Previews でTypeScriptのGo言語実装によるコンパイラのプレビュー版の公開が発表されました。これにより、tsgoコマンドを使用することでGo言語実装版でのtypecheckが実行可能になりました。 そこで、typecheck実行時にコード量の異なるプロジェクトでどのようなパフォーマンス差が出るのかを検証しました。 実際に計測してみると、コード量が多いプロジェクトでは 8.47倍、少ないプロジェクトでも 3.14倍 の高速化を確認できました。 特にコード量が多いプロジェクトほど、Go言語による並列処理の恩恵を受けやすく、高いパフォーマンス改善効果が見られました。 調査過程で現在のTypeScriptから変わる部分や今後の動きを学ぶことができ、「調べるだけでなく実際に手を動かすことの大切さ」を実感しました。 登壇してみて 初めての登壇ということもあり、多くの反省点がありました。 特に時間管理が課題で、心の中で読むのと実際に声に出して発表するのとでは、所要時間に大きな差があることを痛感しました。大まかなメモだけで話そうとしてしまったため、想定以上に時間がかかってしまいました。 また、内容についても「とりあえず触ってみた」という域を出ず、聞き手にとっての学びやメッセージ性が弱かった点も反省です。 登壇自体は反省点が多かったですが、登壇準備はTypeScriptについて理解を深める良い機会になりました。 LT会はワイワイした雰囲気で、多くの人との交流を楽しむことができました。初めて登壇する場として、とても良かったと思います。 すごくすごい。フロントエンドミートアップ 〜複雑GUI・アーキテクチャ設計を語ろう 〜 弊社が会場スポンサーを務めるイベントで、「登壇してみないか?」と社内で声をかけていただきました。 1度登壇したことで登壇に対する心理的ハードルが下がっていたこともあり、せっかくの機会なので挑戦することにしました。 イベントリンク: https://formx.connpass.com/event/364158/ 登壇タイトル: 「AI疲れに効く、フロントエンドのワークフロー整備」 登壇資料 speakerdeck.com 登壇内容 生成AIによるコーディングが普及する一方で、AIが生成したコードのレビューや手直しによる「AI疲れ」という新たな課題も生まれています。そこで、AIと安全に協業しつつ開発速度を維持するための「守り」と「高速化」のワークフロー整備について紹介しました。 具体的には、「守り」としてTypeScriptやESLintによる静的解析、Nxによるモジュール境界の強制、Vitestを用いた自動テスト、フィーチャーフラグの導入などを行っています。 また、「守りの高速化」のアプローチとして、Nxの変更検知とキャッシュ機能を活用し、影響範囲のあるプロジェクトのみをCI対象に絞り込んでいます。さらに、GitHub ActionsのRunnerスペックを負荷に合わせて最適化することで、CIの実行時間を短縮しています。 これらの仕組みは元々開発効率と品質のために構築したものですが、結果としてAI時代においても強固な土台として機能しています。 登壇してみて 今回は弊社のフロントエンドテックリードに壁打ちをお願いし、方向性をしっかりと固めてから準備に入りました。「フロントエンドのワークフロー整備」という範囲が広いテーマでしたが、「AIに好き勝手させないための守りと高速化」という軸が決まっていたので、話す内容の取捨選択がしやすかったです。 当日は緊張しましたが、スピーカーノートをしっかり準備して練習していたおかげで、落ち着いて話すことができました。 TSKaigi Hokuriku 2025 弊社がGoldスポンサーとして協賛していたイベントです。 一般公募のプロポーザルは残念ながら不採択だったのですが、スポンサーLT枠として登壇の機会をいただきました。 イベントリンク: https://hokuriku.tskaigi.org/ 登壇タイトル: 「Nxはいいぞ!monorepoプロジェクトにおける差分検知を活用した型チェック最適化」 登壇資料 speakerdeck.com 登壇内容 プロジェクトのコード量増加に伴い、CI実行の実行時間が増加する課題に対して、Nxの差分検知とキャッシュを活用したCI高速化の手法を紹介しました。 Nxは、モノレポやアプリケーションのビルド、テスト実行、コード生成などの機能を備えた統合的なツールです。ファインディの多くのフロントエンドでも採用されています。主な特徴として、タスク実行の並列化、変更検知、キャッシュ活用によるCI実行の効率化があります。 Nxは変更があったプロジェクトと、それに依存関係のあるプロジェクトのみを対象にコマンドを実行します。これにより、typecheckなどのタスクの不要な実行をスキップでき、依存関係が小さい変更ほどCIが早く終わるようになります。 Nxの恩恵を最大限受けるためにはプロジェクトの依存関係を適切に整理することが重要です。コード量の増加によるCI実行時間の増加や開発体験の低下に課題を感じたら、ぜひNxのことを思い出してください! 登壇してみて 元々プロポーザルを出していた内容だったため、ターゲット(モノレポ構成やCI時間に課題を感じている層)と伝えたいメッセージを明確にできており、登壇準備を進めやすかったです。 4分間のLT枠だったため、短い時間の中で「何を伝えればNxの良さが響くか」を意識して構成を考えました。結果、制限時間ギリギリではありましたが、伝えたいポイントはしっかり届けられたと感じています。 ちなみに、TSKaigi Hokuriku 2025については、同日参加したメンバーも記事を投稿していますので、イベントの雰囲気が気になる方はぜひ併せてご覧ください! tech.findy.co.jp note.com 登壇準備でやってよかったこと これら3回の登壇を通して、特にやってよかったなと思った取り組みを紹介します。 1. 登壇内容の壁打ち 登壇内容の方向性、軸を決めるためにテックリードや他の登壇予定の方と壁打ちをすることです。 自分だけで登壇内容を考えると、何か足りないと感じたり範囲が広すぎて軸を定められないなど迷うことがあります。 必ずしもひとりで考えきる必要はありません。迷いがあったら壁打ちをお願いしてみることをおすすめします。 2. 話したいことをとにかく書き出す 「話したいこと」をとにかく書き出しました。 一度書き出すことで、自分自身の理解の曖昧な部分が浮き彫りになり、調査をして理解を深めるきっかけになりました。 調査の過程がそのまま学びの機会になるため、おすすめです。 3. 登壇時に話す内容を全てスピーカーノートに書き出す、発表練習を繰り返してブラッシュアップ いわゆる「台本」を作ることです。 話す内容を全て文字に起こすことで、説明の言い回しや構成に違和感がないかを確認できます。 また、実際に声に出して読んでみると「この表現は伝わりにくい」「ここは順序を入れ替えたほうがいい」といった気づきが得られます。 発表練習を繰り返してスピーカーノートを直し、時間配分を調整することをひたすら繰り返すことで、本番で落ち着いて話すことができるようになります。 4. 登壇資料のレビュー依頼 資料ができたら、テックリードや社内のエンジニアにレビューをお願いしました。 作り手視点だけでは気づけない「説明の誤り」や「わかりにくい表現」を指摘していただき、勉強になりました。 また、会場が大きいので、文字が小さいと後ろの席から見えないから限界まで文字サイズを大きくした方が良いといった、登壇経験者ならではの実践的なアドバイスもいただき勉強になりました。 まとめ 登壇に挑戦することで、技術の理解を深めるよい学びの機会となりました。 聞き手にわかりやすく説明するためには、自分自身がその技術を深く、体系的に理解している必要があります。曖昧だった知識を補完し、学び直すプロセスそのものが、エンジニアとしての成長に繋がったと感じています。 これからも、登壇やブログ執筆といったアウトプットの機会を大切にし、自分自身の学びの場として活かしていきたいと思います。 ファインディでは一緒に働くメンバーを募集しています! 興味がある方はこちらから ↓ herp.careers
アバター
キャリアプロダクト開発部の森 @jiskanulo です。 この記事は、 ファインディエンジニア Advent Calendar 2025 の6日目の記事です。 adventar.org 現在Findyにて「うちのAIがやらかしまして」という企画ページを期間限定で公開しております。 https://findy-code.io/ai-yarakashi findy-code.io 「うちのAIがやらかしまして」はAIとの協働で生まれた“試行錯誤のエピソード”を投稿してもらう参加型企画です。 AIのやらかし・すれ違いをシェアし、皆さんの前向きな学びにつなげていく場を提供いたします。 今回は私のAIやらかし事例を紹介しつつ、同じやらかしを再度起こさないようにするため心がけることをご紹介します。 私のやらかし事例はいずれもClaude Codeの利用で起きたものですが、他のAIエージェントを活用されている方にも参考になれば幸いです。 AIやらかし事例の紹介 コードレビューに意図してないコメントを残された Pull Requestに関係ないファイルがコミットされていた 同じやらかしを繰り返さないために おわり AIやらかし事例の紹介 コードレビューに意図してないコメントを残された GitHubのコードレビュー内容を確認して、と指示を出したら対応するつもりのない内容をコメントとして残されてしまい慌てて訂正した findy-code.io このやらかしの原因は、私の指示が曖昧だったことです。 「コードレビューを確認して」と書いたつもりでしたが、「コードレビューを確認して 対応して 」と指示してしまったため、Claude Codeはそのレビューに返信コメントを投稿してしまったわけです。 コンソールを眺めていたらgh issue commentコマンドを発行しているのに気づき、慌てて訂正しました。短期間に正反対のコメントを連投しレビュアーに迷惑をかけてしまったやらかしです。 Pull Requestに関係ないファイルがコミットされていた 作業指示を出し、Pull Requestを作成してもらった。Pull Requestを確認すると作業指示に入っていないファイルもコミットされていた findy-code.io コミットされていたファイルは別のタスクでCLAUDE.mdの記述調整を依頼した際に作成された一時的なファイルでした。 Claude Codeが git add -A で全ファイルをコミット対象に追加し、そのままコミットを作成してしまったのです。 同じやらかしを繰り返さないために これら2つのやらかしを踏まえ、同じミスを繰り返さないための対策を整理します。 曖昧な指示が来た時に、Claude Codeに指示の内容を確認するようCLAUDE.mdに記載を追加しました。 これで思いがけない行動を取ってしまうことが減りました。 指示に不明な点や曖昧な点がある場合、作業を進めずに質問を返してください。 次に、指示が終わった後に意図しない挙動を示した場合、どうしてそうなったのか質問をし、回答を求めます。 以下は私が対話した内容の抜粋です。 私: 先ほど不要なファイルのcommitが混ざってしまった事象について、どうして起きてしまったのか、どうすれば再発を防ぐことができるか検討して提案して Claude: ⏺ CLAUDE.md.backupファイルが誤ってコミットされた原因と再発防止策を分析しました 原因分析 何が起きたか 1. PR #51 (docs-restructure-claude-md) でCLAUDE.mdのバックアップを作成 # 当時の作業 cp CLAUDE.md CLAUDE.md.backup 2. PR #51マージ後、mainから新ブランチを作成 3. git add -A で全変更をステージング 4. CLAUDE.md.backupがワーキングディレクトリに残っていたため、意図せずコミットに含まれた 根本原因 - ✅ バックアップファイルを作業後に削除しなかった - ✅ git add -A が全ファイルを無条件に追加した - ✅ コミット前のステージング内容確認を怠った 再発防止策 … これ以降、対話を続けて方針を定めました。 対話してまとめた内容をCLAUDE.mdに記載させ、次回以降同じことを起こさないようにしました。 内容が冗長だったり逆に限定的で不足している部分もありますが都度調整していきます。 最終的にCLAUDE.mdに追加した内容は次の2点です。 コミット前にステージングされているファイルを確認すること 意図していないファイルが含まれていないことを確認すること #### コミット前の確認 ```bash # ステージングエリアの確認 git status # 意図していないファイルが含まれていないことを確認 git diff --cached --name-only ``` おわり AIエージェントは最初から100%期待に沿う行動をしてくれるわけではありません。 いい加減な指示を出すと思いがけないふるまいをやらかしてしまいます。 時にはやらかしつつ、やらかしを再発防止策を考えて対策し、共に成長していくパートナーとして触れ合っていきましょう。 現在、ファインディでは一緒に働くメンバーを募集中です。 興味がある方はこちらからからご応募ください。 herp.careers
アバター