コネヒト開発者ブログ

コネヒト開発者ブログ

コネヒトのウェブアクセシビリティに関する取り組み

この記事は コネヒトAdvent Calendar 2025、08日目の記事です。

コネヒトで働く人たちがお届けするアドベントカレンダーです。

コネヒトは「あなたの家族像が実現し続けられる社会へ」をビジョンに掲げ、「ママリ」などの家族向けプロダクトや事業を展開しています。

過去2年のアドベントカレンダー

adventar.org


こんにちは、コネヒトAndroidエンジニアの中島(id:nacatl)です。 今までAndroidに関する記事ばかり書いていた自分ですが、今回はちょっと違う分野としてアクセシビリティをテーマにした取り組みを紹介します。

背景

コネヒトはKDDIグループウェブアクセシビリティ方針に基づき、アクセシビリティの確保に取り組んでまいります。

connehito.com

www.kddi.com

というわけで、コネヒトでは会社としてアクセシビリティの確保に向けて活動を開始しています。 推進委員会的なメンバーが3名おり、その末席に自分がいるという形です。

しかし、一口にアクセシビリティと言ってもさまざまな項目があります。 今まで普段の作業の中で気にしていたメンバーも少なく、推進と言ってもどこから手をつければいいか五里霧中でした。

この記事では、どうやってメンバーにアクセシビリティを推進しているか、実際に行なった取り組みの一つである社内ワークショップの内容を紹介します。

基礎知識としてのアクセシビリティ

はじめに少し、予備知識としてアクセシビリティとは何かについて、自己解釈も含めて軽く触れておきます。 有識者の方は、この節は読み飛ばしていただいて構いません。

アクセシビリティとは

アクセシビリティはよくユーザビリティと比較されます。 どちらもユーザーフレンドリーにするという意味では同じですが、アプローチは真逆です。 その違いについて、筆者は下記の資料の8pにある表現が最もしっくり来ているので、ここで引用させていただきます。

ユーザビリティは山の頂点を高める活動

特定のユーザー(状況)に響く

アクセシビリティは山の裾野を広げる活動

幅広い層の人々にとって使える

speakerdeck.com

アクセシブルなコンテンツ

言葉遊びのようですが、「アクセシビリティを確保する」とは、「コンテンツをアクセシブルにする」ことです。 ここでは「アクセシブルなコンテンツ」とは何かを軽く解説します。

ユーザーがコンテンツを利用する際には、時と場合によりさまざまな障壁が立ちはだかります。 ここでいう障壁とは、いわゆる障がい者の方々についてのものだけではありません。 高齢者や他言語利用者、怪我をしていたり手が塞がっていたりするシーン等の、一時的なものも含まれます。

  • 身体的なもの
    • 目が見えない
    • 耳が聞こえない
    • 老眼 / 遠視 / 色弱など
    • 手指が使えない(怪我なども含む)
  • 状況的なもの
    • 乗り物が揺れて小さい文字が読めない
    • 旅行先などで言葉が通じない / 文字が読めない
  • デバイス的なもの
    • タッチパネルじゃない(スマホアプリだと忘れがち)
  • etc......

こういった状況下にあるすべての人に対して場所やシーンによらず、どのような状況でもサービスの価値を提供できる状態が、完璧な「アクセシブルなコンテンツ」と言えるでしょう。 (もちろん、完璧に対応するには相応の努力が必要になりますし、現実的にはかなり難しいと思います)

「アクセシビリティの確保を推進する」とは、「アクセシブルなコンテンツ」としての完成度を上げていく活動と言えます。

カーブカット効果

「アクセシブルなコンテンツ」になることで恩恵を受けるのは、障壁があるユーザーだけに限りません。

車椅子の移動のために歩道の縁石に簡素なスロープを作ったことにより、車椅子利用者だけでなくベビーカーや台車、スーツケースなどの利用にも恩恵がもたらされた現象があります。

このことから、裾野を広げることで一般的にも恩恵がある、という概念はカーブカット効果(Curb Cut Effect)と呼ばれています。

ssir-j.org

readspeaker.jp

WCAG

Web Content Accessibility Guidelines の略で、 World Wide Web Consortium(W3C) の下部組織が打ち出している、Webコンテンツ用のアクセシビリティガイドラインです。

waic.jp

www.w3.org

WCAGでは以下の4大原則が掲げられています。 ここでは紹介に留めますがより詳しいことが知りたければ、検索すればもっと詳しい記事が見つかると思いますので、そちらを参照していただければと思います。

  1. 知覚可能
    • 情報及びユーザインタフェース コンポーネントは、利用者が知覚できる方法で利用者に提示可能でなければならない。

    • 視覚 / 聴覚 / 色覚 など、それぞれ一つだけに依存した提示でないことが求められます。
  2. 操作可能
    • ユーザインタフェース コンポーネント及びナビゲーションは操作可能でなければならない。

    • タッチパネルやマウスに依存せず、キーボードだけなどの入力デバイスでも操作ができることが求められます。
  3. 理解可能
    • 情報及びユーザインタフェースの操作は理解可能でなければならない。

    • 知覚したものに対して、例えば「それが何をするボタンであるのか」などを理解できる必要があります。
  4. 堅牢
    • コンテンツは、支援技術を含む様々なユーザエージェントが確実に解釈できるように十分に堅牢 (robust) でなければならない。

    • 表示するブラウザや端末に左右されないことが求められます。

また、WCAGでは項目ごとに対応レベルが設定されており、以下のような定義となっています。

  • A(最低レベル)
  • AA
  • AAA(最高レベル)

コネヒトでは執筆時の最新である WCAG 2.2 に基づき、AAレベル の項目までの対応を目標としています。

コネヒトでの取り組み -社内ワークショップ-

先にも述べたように、アクセシビリティ確保と言ってもまず何をすればいいのか、という段階から始まるのがほとんどかと思います。 正直な話、人間、ただ「やれ」と言われても普通は身が入りません。自分もそうです。 なぜ何をやるのか、やって何が良くなるのかを知り、納得を得ることが、当人のパフォーマンスを十全に発揮する近道だと自分は考えています。

ですので、まずは「なぜ必要なのか」「何をやるのか」を知ること、情報と知識の社内浸透が必要かと考えました。

コネヒトでは普段の仕事から少し離れた視点で考える取り組みとして、マンスリーでワークショップを開いています。

connehito.com

その場を借りてアクセシビリティに関するワークを全社員メンバーに行なってもらい、まずは触れてもらおう、知ってもらおうと考えました。

第1回「スクリーンリーダー体験会」

2025年02月、第1回を開催しました。

目的

目的は「今まで知らなかった世界のママリを知ってもらう」としました。 まず具体的な内容より前に、普段と違うものがあることを知ってもらう狙いです。

内容

内容は「スクリーンリーダーを用いてママリアプリを触ってみる」です。

Androidユーザーには TalkBack、iOSユーザーには VoiceOverをそれぞれオンにして、その状態でママリアプリを触ってもらいました。 自由にアプリを触ってもらい、使おうと思ってできなかった機能や、こうだったらわかりやすい / やりやすいと思ったことを書き出すまでをワークとしました。

工夫点

スクリーンリーダーはスマホの操作方法が完全に変わるため、動かし方がわからないなどのトラブルが多く起こることを想定しました。 そのため、対応策を事前に考え以下のような対策を取りました。

  • 先に少数メンバーを集めて要望を聞く
  • オフラインで開催し、推進委員会メンバーがトラブル対応のために待機する
  • スクリーンリーダーの基本動作を先に説明、マニュアルも紙で作成して配る

結果 / 改善点

事前準備を厚めにしたことで、基本的には大きなトラブルはなく終えられました。 ほとんどのメンバーが初めて触れたこともあり、知らない世界に触れてもらうという意味では成功したと言えるでしょう。

ただやはりスクリーンリーダーは難しかったとの意見は多く、ワーク内容の操作指示などをより細かく指定した方が良かったかもしれません。

第2回「アクセシビリティを満たさないウェブサイトを触る会」

2025年11月、第2回を開催しました。

目的

今度の目的は「具体的な対応項目の例を知ってもらう」としました。

コネヒトではアクセシビリティの対応をする際、「サービスとしてまず優先して対応する予定の項目」を10項目ほど定めています。 それらを具体的に体験することで対応内容のイメージを掴んでもらうことが狙いです。

以下、優先対応予定とした項目の一例を抜粋します。

- 自動で動くものは全て一時停止を可能にする
- キーボードトラップ(キーボード操作で抜け出せなくなるUI)を作らない
- 画像の代替テキストを適切に追加する
- 色だけで情報を伝えない
- コントラスト比を十分に確保する
- etc......

内容

内容は「アクセシビリティの項目をわざと満たさずに作成された悪い例のWebサイトを触ってみる」としました。

今回はママリではなく、 駒瑠市〜アクセシビリティ上の問題の体験サイト〜 というWebサイトを用いて、ある項目が満たされなかった場合に何が問題なのかを考えてもらいました。 前述の対応すべき項目を先に提示し、各項目について満たされないことで何が問題なのかを書き出してもらうワークとしました。

a11yc.com

工夫点

今回はオフライン / オンライン混合で開催されることが先に決まっており、スクリーンリーダーの時のような対面でのサポートは全員にできないことが想定されました。 また、対応すべき項目の中にキーボードトラップ排除などがあることもあり、キーボードが使える環境でのワークを考える必要がありました。外部キーボードでスマホアプリを触ってもらうといった形では、Bluetooth接続機器などの所持を全員に求めることになってしまいます。 そのため、全員が使える機器でできることを念頭に置き、普段から業務で利用しているPCで触れるWebサイトでワークすることを決めました。

結果 / 改善点

ワーク終了後、参加者にアンケートで「アクセシビリティのために、サービスにどのようなことが必要かイメージすることはできましたか?」について答えてもらいました。回答は、「1(全くイメージできなかった)」から「5(イメージできた!)」までの5段階としました。

質問「アクセシビリティのために、サービスにどのようなことが必要かイメージすることはできましたか?」の結果の棒グラフ。内訳は続く表の通り
アンケート結果

回答 回答者数 %
5 (イメージできた!) 11人 40.7%
4 13人 48.1%
3 2人 7.4%
2 1人 3.7%
1 (全くイメージできなかった) 0人 0%

アンケート結果では対応内容がイメージできたという返答が多く、目的は達成できたかなと思います。

改善点としては、前回に続き「難しい」「スパルタ」といった感想をいただいてしまったことです。 これに関しては明らかに失念していたことがあって、駒琉市には「全て対応した困らない市」のリンクもあることを伝え忘れていました……

最初から「対応済みがあるからこれと比較もしてみるとよさそう」と伝えていれば、もう少し難易度が下がっていたかもしれません。

おわりに

今回の記事では、コネヒトにおけるアクセシビリティの確保推進について、社内での取り組みを紹介しました。 筆者もこの分野では知見が浅く、計画もまだまだ途上の段階なので、何が正解なのか今も手探りな状態です。

この記事が、同じようにアクセシビリティの確保や社内への浸透を考えている方々の一助となれば幸いです。

「現状起点の最適化」に夢中になっていた私

こんにちは!エンジニアのaboyです。これは自戒であり私の学びです。

コネヒト Advent Calendarの他の記事もお楽しみください。

私が携わったとある施策がありました。その施策はできるだけすぐに実現したかったので、当時思いつく仕組みで作りました。また、その後も不定期的に発生することが分かっていたので運用フローを定めました。

AIエージェントやツールによる段階的な自動化

その運用フローがこちらです。

  1. 👤 営業)Google Sheetsに指定項目を記入して、開発チームに連絡する
  2. 👤 開発)情報集約用のGitHub Issueを作成し依頼内容をまとめる
  3. 👤 開発)Issueの内容をもとに2つのリポジトリで実装する
  4. 👤 開発)Pull Requestをレビュー → マージ → デプロイする
  5. 👤 開発)担当者に完了連絡をする

最初に大枠の仕組みを作っておいたので、手順3で必要な実装というのは、2つのGitHubリポジトリ内に保持している定数を変更・追記するだけでOK。実装内容は数行程度なのでラクチンです。

数回繰り返すうちに、よくやるし対応方法も決まっているし簡単なので、手順3をラクにするためにAIエージェントに実装をさせるようにしました。その運用フローがこちらです。

  1. 👤 営業)Google Sheetsに指定項目を記入する
  2. 🤖 Zapier)1日1回、対応すべきものを検知してSlackに通知する
  3. 👤 開発)情報集約用のGitHub Issueと実装用のsub-issueを作成する
  4. 🤖 GHA※)sub-issueの対応をDevinに指示する(※GitHub Actions)
  5. 🤖 Devin)sub-issueの分だけDevinが起動し実装する
  6. 👤 開発)Pull Requestをレビュー → マージ → デプロイする
  7. 👤 開発)担当者に完了連絡をする

コネヒトのママリ事業部では、要求管理用のGitHubリポジトリにIssueを立てて、細かいタスクはシステム毎のリポジトリにIssueを立てるという方法がよく取られます。GitHubにはsub-issueという仕組みがあるので、Issueに紐づいているsub-issueの対応を一括でDevinに依頼できるワークフローを作りました。Devinのような自律型AIエージェントは、複数のリポジトリでの作業が必要なIssueに対して、それぞれのリポジトリごとに独立したセッションで仕事を進めてくれるのでとても便利です。

実装内容がシンプルということもあり、Devinは毎回完璧に実装してくれました。これで、営業メンバーが開発メンバーに連絡する手間と、開発メンバーが複数リポジトリで実装してPull Requestを出す手間が削減できました。

この運用で数回繰り返すうちに、今度GitHub Issueを人間が作成する手順3が無駄に思えてきます。どんなIssueを作るかというパターンは決まっています。この手順をGoogle Apps Scriptを用いて自動化した運用フローがこちらです。

  1. 👤 営業)Google Sheetsに指定項目を記入する
  2. 🤖 GAS)1日1回、対応すべきものを検知してGitHub Issueとsub-issueを作成する
  3. 🤖 GHA)sub-issueの対応をDevinに指示する
  4. 🤖 Devin)sub-issuesの分だけDevinが起動し、Pull Requestを開発チームに出す
  5. 👤 開発)Pull Requestをレビュー → マージ → デプロイする
  6. 👤 開発)担当者に完了連絡をする

以前の手順2,3をGASに置き換えました。Zapierだとsub-issueを作成する標準アクションが無かったため、どうせAPIリクエストを組み立てないといけないのであればこのタイミングでコネヒトで全員が使えるGeminiから直接コード生成ができるGASに変えました。地味にアクセストークンの管理などで考えなきゃいけないことがあったため、この過程でGASから自社のGitHubを操作するための簡単な仕組みも用意して、社内に展開しました。

さて、ここまででできた運用フローと、一番最初の運用フローを比べてみると、人間が行う作業は確実に減りました。

  1. 👤 営業)Google Sheetsに指定項目を記入して、開発チームに連絡する
  2. 👤 開発)情報集約用のGitHub Issueを作成し依頼内容をまとめる
  3. 👤 開発)Issueの内容をもとに2つのリポジトリで実装する
  4. 👤 開発)Pull Requestをレビュー → マージ → デプロイする
  5. 👤 開発)担当者に完了連絡をする

  1. 👤 営業)Google Sheetsに指定項目を記入する
  2. 🤖 GAS)1日1回、対応すべきものを検知してGitHub Issueとsub-issueを作成する
  3. 🤖 GHA)sub-issueの対応をDevinに指示する
  4. 🤖 Devin)sub-issueの分だけDevinが起動し、Pull Requestを開発チームに出す
  5. 👤 開発)Pull Requestをレビュー → マージ → デプロイする
  6. 👤 開発)担当者に完了連絡をする

営業メンバーが入稿し、機械が実装し、開発メンバーがデリバリーするという運用フローになりました。やったね。

ある日、チームメンバーから「これって管理画面でできたほうがいいんですかね」という意見を貰いました。

現状の最適化か、あるべき姿の実現か

「た、たしかに〜」と思い、”管理画面から設定できる”をゴールに設定し、そのゴールをどうすれば実現できるかという観点で色々と見直してみました。

見直した結果、管理画面から設定できるようにするには、データストアも含めた5つのシステムに関連する改修が必要だろうということが分かりました。

やることは多いけど「できる」ということが分かりました。

もちろん、できるはできるが、果たして今やるべきことなのかどうかは判断しないといけません。ただこうして一歩引いて考えられたことは良いことでした。

管理画面からできるようにすることが本当にやるべきことなのか、というのも考えないといけません。管理画面からできるようにした後の運用フローというのは、この施策が世の中に価値を提供するまでの流れの中の開発メンバーの介入にしか影響しておらず、まだ営業メンバーの介入が残っています。

  1. 👤 営業)管理画面から入稿する

そもそも、この施策は誰にどんな価値を提供したかったのか。当時はイージーな方法で実現しましたが、改めてこの問いについて考えてみると、全然違う言葉のほうがこの施策を適切に表しているんじゃないかと思ったりしてきます。何十回と行われ、今後も行われるため、持続可能性の向上も考慮する必要があります。

未来を見据えて適切に課題を設定し、それに伴う変化をリードすることこそが私がすることだったのに、当時の意思決定から地続きの現状起点で考えていて、いつしか近視眼的になっていました。

ゴールを決めるとそのゴールに向けた方法がたくさん思い浮かんできます。「XXという作業を自動化する」というゴールを決めた場合、生成AIの普及も手伝って自動化する方法は本当にたくさんあります。今ある業務を効率化するという観点では便利なツールがたくさん存在しますが、仕事における「誰にどんな価値を提供するのか」「なぜこれを課題に設定したのか」そういったコンテキストを操作する思考を忘れたくないな〜という自戒でした。

コネヒトの開発組織にみられる「+αの改善を肯定しフォローする」文化

こんにちは!エンジニアのaboyですԅ( ˘ω˘ԅ)

今回はコネヒトの開発組織の文化の一つ、「+αの改善を肯定しフォローする」ことについてサクっと紹介します。組織の文化というのは組織にいる人間が当たり前のように持っている価値観だったり前提のようなものです。

形式的に説明すると、誰かの主体的に加えられた付加価値に対して、他の人がまずその意図と行動を肯定し、その後の目的達成を支援することを意味します。

+αの改善というものについては、以前ボーイスカウト・ルールについて記事にしました。この記事でも「コネヒトにはボーイスカウト・ルールを当たり前のように実践できる人がたくさんいる」と書きましたが、ボーイスカウト・ルールに限らずこの文化は適用されます。 sizu.me

いくつかの事例を紹介すると、例えば、多くのリポジトリのデフォルトブランチがmasterになっているのを全てmainにしようと呼びかると、チームを超えてたくさんの協力者が集まり、あっという間にmainブランチへのリネームをやりきりました。

デフォルトブランチのリネームをシュッとやりきった

他には、必要であればチーム外の人間が課題設定をしてパフォーマンス改善策を実行したりしても受け入れられます。このあと、さらなるパフォーマンス改善がチーム内で実行されました。

チーム関係なく課題解決

あとは、生成AIについてのもくもく会や勉強会を始めると、みんなでワイワイできたり、フィードバックが集まったり。

生成AIもくもく会

こういった活動というのは、一人目のあとに続くフォロワーの存在も重要です。フォロワーが出てくるからこそ言い出しっぺが独りにならないし、物事が進んでいきます。失敗を必要以上に恐れずに主体的に考えた行動をしやすくなり、リーダーシップの発揮がしやすい風土になります。

とはいえ、このような組織文化を再現性をもって維持するには仕組みと仕掛けが重要だと思っていますが、その点でコネヒトには課題もあります。Mission/Vision達成のために必要な組織文化を属人化させず、意図的に作れるよう、開発組織全体で取り組んでいきます。

この記事で、開発組織の雰囲気を知っていただけたなら幸いです!

DroidKaigi 2025に参加しました!

こんにちは、コネヒトAndroidエンジニアの中島(id:nacatl)です。 コネヒトは、さる2025/09/10~2025/09/12の3日間に開催されましたDroidKaigi2025にサポータースポンサーとして協賛しておりました。

2025.droidkaigi.jp

このブログを読まれている方の中にも、現地参加された方がいらっしゃるかと思います。 中島もセッションの2日間に現地に赴き、色々学びを得られました。

今回は、自分が聴講した中でも特に印象深かったセッションを3つほど、感想を交えながらご紹介したいと思います。 今年はセッション動画も上がるのが早く、すでにほぼ全てYoutubeにて視聴できるようです。運営の方々の努力には頭が上がりません。

基礎から学ぶ大画面対応 〜「Large screen differentiated」認定アプリの開発知見〜

2025.droidkaigi.jp

tomoya0x00さんによる、アプリの大画面対応についてのセッションです。 ママリでは、実はつい最近ようやくEdge-to-edgeの対応をしました。 しかし時の流れは早く、世の中ではすでにSDK37の対応についての話がなされています。 技術的な注意点だけでなく、実装する画面の優先付などについても、実体験からくる説明で納得感がありました。

Deep dive into Kotlin Flow

2025.droidkaigi.jp

Jumpei Matsudaさんによる、Kotlin Flowの実装を深掘りするセッションです。 StateFlowの扱いに関してはLiveDataからの移行で実装レベルでは把握しているのですが、ChannelFlowなど普段実装で使えておらず、そういった知見が欲しくて聴講しました。 様々なFlowについて、普段の実装だけでは気にしない、気付けない点など改めて知ることのできたセッションでした。

スマホ新法って何?12月施行?アプリビジネスに影響あるの?

2025.droidkaigi.jp

公正取引委員会の鈴木健太さんによる、今年12月18日に施行される「スマートフォンにおいて利用される特定ソフトウェアに係る競争の促進に関わる法律」、スマホ新法に関する招待公演です。 正直なところ、情けなくもスマホ新法と言われても内容まで詳しく知らなかった身としては、詳しく知る場としてとてもありがたかったです。 現実的な問題としてこれが施行されたからと言って急に世界が変わるとまでは言えないでしょうが、「安全弁を整備する」という面で言えば重要なことなのかなといった認識を持ちました。 ただそれはそれとして、こういう機会は国民側への展開としてめちゃくちゃ重要なのではと思いました。

まとめ

運営の方々、またスピーカーの方々、素晴らしいカンファレンスをありがとうございました。 紹介しきれなかったセッションも素晴らしいものばかりで、これからも開発でしたいことがどんどん増えていくのを実感しています。 セッション外でも、すっかりお馴染みになったバリスタコーヒーコーナーが、混雑回避のための整理券制になっていたりと進化を感じます。

自分もコネヒトも進歩の足を止めず、負けじと日々成長していきたいと思いました。

コネヒトはiOSDC Japan 2025に協賛いたします!

こんにちは、iOSエンジニアのyoshitakaです!

本日は、iOSアプリ開発者の祭典iOSDC Japan 2025に協賛するお知らせです。

コネヒトはiOSDC Japan 2025に協賛いたします!

iOSDC Japan 2025に、シルバースポンサーとして協賛いたします。

iosdc.jp

スポンサーするにあたって、コネヒトは「Connehito Tech Vision」として「Run with Tech」を戦略として掲げており、世の中のテクノロジーの成長と共にコネヒトも成長し、新たな価値を生み出すことを目指しています。技術コミュニティについても同様に、サポートして一緒に盛り上げていくことができたら、と思っております。

イベント概要

  • 開催 2025年9月19日(金)〜 9月21日(日)
  • 場所 有明セントラルタワーホール&カンファレンス+ニコニコ生放送
  • 対象 iOS関連技術およびすべてのソフトウェア技術者
  • タイムテーブル https://fortee.jp/iosdc-japan-2025/timetable
  • 主催 iOSDC Japan 2025 実行委員会(実行委員長 長谷川智希)

iOSDCトークンはこちら!

#mamari-iOS

これはiOSDCチャレンジで使うトークンです!

技術者同士のつながりや知識の共有が広がることにワクワクしています。皆さん、楽しみましょう!

今年は私もday1に以下の内容で登壇予定です!お時間ある方ぜひ聞きに来てください!

fortee.jp

Devin x GitHub ActionsでRenovateのPR対応を自動化する実践ノウハウ

こんにちは!Androidエンジニアの関根です。

今回は、RenovateのPR対応を自動化する取り組みについてご紹介します。

はじめに

皆さんの職場では、Renovateを使いこなせていますか?依存関係を最新に保つ上で、本当に頼もしい存在ですよね。 弊社のAndroidチームではRenovateのPullRequestを定例で確認し、マージの判断をする運用は行っていますが、だんだんとPullRequestが溜まってしまっていました。

影響の少ないアップデートならその場で判断し、マージできますが、調査が必要な場合に、先送りしてしまうということが起きていました。 「影響範囲の調査が必要だな…」「後でやろう…」 そう思っているうちに、PRはどんどん溜まっていき、上限数に達してしまうということが定常化していました。

この記事では、そんな「調査待ちRenovate PR」の渋滞を、今話題のAIエージェントDevinを使って解消する実践的なノウハウをご紹介します。

Part 1:実現したこと

まずは、この仕組みを導入したことで、私たちのチームにどんな変化があったかをお見せします。 これまで先送りしがちだった「調査が必要なPR」。ここにDevinが介在することで、人間は「Devinからの調査報告をレビューするだけ」 になりました。

システムの流れ

この自動化システムは、以下のような流れで動作します:

  1. Renovateが依存関係の更新を検知し、PullRequestを作成
  2. GitHub ActionsがPRの作成を検知し、Devin APIにリクエストを送信
  3. DevinがPlaybookを読み取り、以下のレビューを実施

この一連の流れでのレビューには、以下のような情報が含まれます:

  • ライブラリ変更点の概要

    • バージョン間の主要な変更点
    • 破壊的変更の有無
    • 新機能や非推奨機能の情報
  • コードへの影響と対応案

    • 影響を受ける箇所の特定
    • 推奨される修正方法
    • テストが必要な範囲

具体的なサンプルをお見せすると、以下の通りです。こちらは実際のレビュー内容を生成AIでマスキングしたものです。

ライブラリ変更点の概要

### com.example.library:core 2.1.0 → 2.2.0

**リリース日**: 2024年3月15日

**変更内容**:
- **バグ修正**: 特定の条件下でメモリリークが発生する問題を修正
- **パフォーマンス改善**: データ処理の最適化により、処理速度が約20%向上

**詳細**:
- 公式ドキュメント: https://example.com/library/docs/releases/2.2.0
- メモリリークの修正により、長時間の運用時の安定性が向上
- 破壊的変更はありません

**影響レベル**: 中(バグ修正とパフォーマンス改善)

## コードへの影響と対応案

### 影響範囲の調査結果

ライブラリの使用箇所を調査した結果:

**使用箇所**: 
- `src/main/java/com/example/app/ImageProcessor.kt` のみ

**現在の使用方法**:
val processor = HogeProcessor()
val data = processor.getData(source)

コードへの影響と対応案

✅ **影響なし**: 
- 現在のコードは基本的なメタデータ読み取りのみを行っており、修正対象の機能は使用していません
- 高度な機能(今回修正された部分)は使用していないため、影響はありません
- 既存の実装は基本的な機能のみを使用しており、安全です

### 対応案

**推奨対応**: 
- ✅ **コード修正不要** - このアップデートは安全に適用可能です
- ✅ **テスト実行** - 念のため既存のテストを実行して動作確認を行うことを推奨します
- ✅ **マージ可能** - 破壊的変更がないため、レビュー後にマージして問題ありません

**理由**:
1. バグ修正のみで新機能や仕様変更はありません
2. 修正対象の高度な機能は使用していません
3. 既存の基本的な機能に影響はありません

このアップデートにより、将来的に高度な機能を使用する際の安全性が向上します。

このように、人間が行っていた調査作業をDevinが自動化することで、レビュアーは「調査結果の確認と判断」に集中できるようになりました。

Part 2:実践!自動化システムの作り方

今回はDevinとGitHubActionsの機能のシンプルな組み合わせで実装しており、以下の2つの実装で完結します。

  1. DevinにPlaybookを設定する
  2. GitHubActionsからDevin APIにリクエストを送信

まずは比較的DevinのPlaybookを採用した理由から解説をさせていただきます。

Devin Playbook docs.devin.ai

Playbookを選んだ理由

DevinのPlaybookを採用した理由は、RenovateのPR対応が以下のような定型的な作業の繰り返しになるためです:

  1. 更新内容の確認

    • ライブラリの変更履歴やリリースノートの確認
    • 破壊的変更の有無の確認
  2. コードベースへの影響調査

    • 更新対象のライブラリを使用している箇所の特定
    • 影響範囲の特定と評価
  3. 必要に応じた修正作業

    • 破壊的変更への対応
    • 互換性の確保

このような明確な手順繰り返しの作業は、まさにDevinのPlaybookの得意分野だと考えたためです。Playbookは以下の内容で定義しています。

## 概要
Renovateによって自動生成されたプルリクエスト(PR)をレビューし、ライブラリのアップデートに伴う変更点の調査、コードへの影響評価、および必要な修正作業を実施します。

## ユーザーに必要なもの
- レビュー対象のRenovateのプルリクエストのURL
- (もしあれば) 対象ライブラリに関する特記事項や注意点

## 手順
1.  指定されたRenovateのプルリクエストを開き、Renovateがどのライブラリをどのバージョンからどのバージョンへアップデートしようとしているかを確認します。
2.  アップデート対象となった各ライブラリの公式ドキュメント、リリースノート、変更履歴(changelog)などを参照し、バージョン間の主要な変更点(新機能、非推奨機能、破壊的変更、バグ修正など)を特定します。
3.  特定したライブラリの変更点を、元のRenovateのプルリクエストにGitHubのコメント機能を使用して、「ライブラリ変更点の概要」として記載します。破壊的変更や対応が必須と思われる項目については特に明記してください。
4.  ライブラリの変更点を踏まえ、リポジトリ内の既存コード(アプリケーションコード、テストコード等)への影響範囲を調査します。具体的には、以下のような点を確認します。
    * 廃止されたAPIや変更されたAPIの使用箇所
    * 仕様変更に伴い、修正が必要となるロジック
    * アップデートによる潜在的なバグやパフォーマンスへの影響
5.  調査したコードへの影響範囲と、推奨される修正対応について、元のRenovateのプルリクエストにGitHubのコメント機能を使用して、「コードへの影響と対応案」として記載します。
6.  コードの修正が必要だと判断された場合、Renovateのプルリクエストのブランチ(例: `renovate/ライブラリ名-2.x`)をベースブランチとして、`fix/renovate-対応内容` の命名規則で新しい作業ブランチを作成します。
7.  作成した作業ブランチで、ステップ5で特定した影響箇所に必要なコード修正作業、および関連するテストコードの修正や追加を行います。
8.  全ての修正作業とテストが完了したら、作業ブランチから元のRenovateのプルリクエストのブランチに向けて、新しいプルリクエストを作成します。
    * 新しいプルリクエストのタイトルには、例:「Fix: Renovateによる[ライブラリ名] vX.Y.Zへのアップデート対応」のように、内容がわかるように記載します。
    * 新しいプルリクエストの説明文には、元のRenovateのプルリクエストへのリンク、実施した修正内容の概要、およびレビューしてほしいポイントを明記します。

## 仕様
1.  RenovateのPRには、「ライブラリ変更点の概要」と「コードへの影響と対応案」がコメントとして記載されていること。
2.  必要な修正作業が完了した場合、適切なターゲットブランチに対して新しいプルリクエストが作成されていること。
3.  新しいプルリクエストは、レビュアーによる確認と承認が行われるまではマージされない状態であること。

## アドバイスとポイント
1.  ライブラリの変更点を調査する際は、公式ドキュメントやリリースノートを最優先の情報源としてください。フォーラムやIssue Trackerの情報は補助的に使用してください。
2.  コードへの影響調査は、直接的な利用箇所だけでなく、間接的な影響や全体的な動作への影響も考慮に入れてください。
3.  GitHubへのコメントやプルリクエストの説明文は、他の開発者が変更の意図と内容を迅速に理解できるよう、明確かつ簡潔に記述してください。
4.  作業ブランチ名は、そのブランチの目的が容易に理解できるような命名規則に従ってください。
5.  大規模な変更や判断に迷う場合は、途中で状況を報告し、指示を仰いでください。

## 禁止事項
1.  **Renovateが自動生成したプルリクエスト、および自身が作成した作業プルリクエストを、レビュアーの承認なしに勝手にマージしないでください。**
2.  ライブラリの公式ドキュメントを確認せずに、変更点や影響範囲を憶測で判断しないでください。
3.  元のRenovate PRのブランチに直接コミットを追加しないでください

Step 1:DevinのPlaybook準備編

さて、ここからは具体的な実装方法です。 この自動化システムの心臓部となるのが、Devinに与える指示、つまりPlaybook(プロンプト)です。

「Devinへの最適な指示なんて、どうやって作ればいいんだ…」と悩みますよね。 ご安心ください。私は、AI(Gemini)に作ってもらいました!

具体的には、Devinの公式サイトにあるPlaybookのサンプルと、今回Devinに「やりたいこと」を箇条書きにしたものをGeminiに渡し、Playbookの形式に合うようにプロンプトを生成してもらったのです。

使用したDevin Playbookサンプル docs.devin.ai

Geminiに渡したプロンプト

以下が、実際に私がGeminiに渡したプロンプトの全文です。 構造としては、「Geminiへの指示」「Devinにやってほしいこと」「出力形式のサンプル」の3つを伝えています。

# あなたへの指示
生成AIへのプロンプトを考えてください。
「やりたいこと」を達成するための指示を「サンプル」を参考に生成してください。

# やりたいこと
- PRで変更されたライブラリの更新内容について調査する
- ライブラリの更新内容が明確になったら、コード内変更への影響を調査する
- 必要に応じて、修正作業を行う

# サンプル

## 概要
Rマークダウンノートブックを使用してデータサイエンスのチュートリアルを作成します。

### ユーザーからの必要事項
- データセットへのリンク(CSVファイルの添付またはKaggleリンク)
- データサイエンスチュートリアルを作成するための具体的なタスク

### 手順
1.  ユーザーから提供されたデータセットをダウンロードします。
    - 必要に応じて、Kaggle CLIを使用してデータセットをダウンロードします。これには認証情報は必要ありません。
2.  `data_science_tutorial.Rmd` というタイトルのRマークダウンノートブックを作成します。
3.  中間コードを記述および保存するために `tmp.Rmd` ファイルを作成します。
4.  `data_science_tutorial.Rmd` ファイル内に5つの主要なセクションを作成し、`tmp.Rmd` ファイルから以下の内容を含むコードを追加します。
    - **データセットの統計**: データセットの統計的要約を生成します。
    - **EDA(探索的データ分析)**: 提供されたデータに対して棒グラフと散布図を作成します。
    - **訓練データとテストデータの分割**: データを80:20の比率で分割します。訓練データとテストデータを保存します。
    - **機械学習モデルの訓練**: 訓練が完了したらモデルを保存します。
    - **保存されたモデルでの推論**: 保存されたモデルをロードし、ユーザーが指定した評価指標を使用してテストセットでのパフォーマンスを評価します。
5.  コードの記述が完了したら、各セクションに簡単な説明を追加します。
6.  RマークダウンノートブックをHTML形式に変換します。
7.  最終的なRマークダウンノートブック、HTMLファイル、保存されたモデル、およびテストデータをユーザーに送信します。

### 仕様
1.  RマークダウンノートブックとHTMLファイルをユーザーに送信してください。
2.  保存されたモデルとテストデータをユーザーに送信してください。

### アドバイスとヒント
1.  パッケージがすでにインストールされている場合は、再インストールしないでください。
2.  このタスクを完了するためにRStudioへのサインインは必要ありません。
3.  各セクションのコードを追加した後、ノートブック全体を実行してください。

### 禁止事項
1.  `data_science_tutorial.Rmd` ファイルを上書きしないでください。

このように、「正解の形」を具体的にサンプルとして見せてあげることで、AIは期待するアウトプットを非常に高い精度で生成してくれます。ぜひ皆さんも試してみてください。✨

Step 2:GitHub Actions連携編

次に、DevinとGitHub Actionsを連携させる具体的な実装方法について説明します。

ワークフローの概要

まず、RenovateのPRが作成されたときに自動的にDevinにレビューを依頼するワークフローを実装しました。 このワークフローは以下のような特徴を持っています:

  • Renovateアカウントがdevelopブランチに対してPRを作成したときのみ実行
  • 他のPRや他のブランチでは実行されない
  • PRのURLをPlaybookのマクロと共に送信

実際の内容

name: Review by Devin on Renovate PR

on:
  # `develop`ブランチへのPRのみ
  pull_request:
    types: [opened]
    branches:
      - develop

jobs:
  review-by-devin:
    # RenovateアカウントがPRを作成したときのみ実行
    if: github.actor == 'renovate[bot]'
    runs-on: ubuntu-latest
    env:
      DEVIN_API_KEY: ${{ secrets.DEVIN_API_KEY }}
      PR_URL: ${{ github.event.pull_request.html_url }}
    steps:
      - name: Review by Devin API
          # /v1/sessionsにリクエストし、Devinセッションを作成
          # PRのURLをPlaybookのマクロと共に送信
          # Bearer認証を使用。API KeyはGitHub Secretsで管理
        run: |
          JSON_PAYLOAD=$(cat <<EOF
            {
              "prompt": "!renovatepullrequest ${PR_URL}"
            }
            EOF
          )
          curl -X POST "https://api.devin.ai/v1/sessions" \
               -H "Authorization: Bearer $DEVIN_API_KEY" \
               -H "Content-Type: application/json" \
               -d "$JSON_PAYLOAD"

こちらのGitHubActionsがトリガーとなり、Devinのレビューが開始される流れとなります。 ※現在は、他のチームと共有で使えるReusable Workflowが整備されたことで、このワークフローはそちらの呼び出しに置き換えています

Devin APIの連携

DevinのAPI連携で直面した問題と解決策について共有します。

API Keyの作成画面に表示されるサンプルコードでは、playbook_idをパラメータとして渡す方法が案内されています。しかし、この方法を試したところ、私の環境ではDevinがPlaybookを参照してくれないという問題が発生しました。

試行錯誤の結果、プロンプト内にPlaybookのマクロ(例: !your-playbook-macro)を直接記述する方法で、無事にPlaybookを読み込ませることができました。

この件についてDevinのサポートに問い合わせたところ、本来はどちらの方法でも動作することを意図しており、playbook_idパラメータが機能しない問題は修正するとの回答を得ました。

Thank you so much for the kind words, and we're thrilled to hear Devin is helping advance your development—means a lot to the team!

Also, really appreciate you flagging this. We do intend for both methods—passing playbook_id as a parameter and using a Playbook macro in the prompt—to work seamlessly. I'll check in with the team about why the first method isn't working as expected and get it fixed.

Thanks again for taking the time to share this!

Best regards,

もし同じ現象に遭遇した場合は、プロンプトに直接マクロを埋め込む方法を試してみてください。

Part 3: 上手くいったこと/上手くいかないこと/困ってること

ここまで、DevinとGitHub Actionsを連携させてRenovateのPRを自動レビューする仕組みの実装方法について説明してきました。しかし、実際に運用を始めてみると、予想外の効果や課題が見えてきました。このPart 3では、実際の運用で得られた知見や、より良い運用のために気をつけるべきポイントを共有します。

上手くいったこと

アップデートのマージ判断がスムーズになった

Devinが調査と対策を検討してくれるため、人間がやることは内容の正誤判断のみになりました。 このことで、「後で調査しよう」というステップがなくなり、定例を待たずにマージ判断を行えるようになってきました。

加えて、Devinが提示してくれた作業内容を、Devinに追加でお願いすることも試行しているところです。 これにより、調査から実装までを一気通貫で自動化できる可能性が見えてきました。

副次的な効果としてCI失敗も調査してくれる

当初の目的は「Renovate PRの影響範囲調査」でしたが、副次的な効果として嬉しい発見がありました。 それは、CIが失敗したPRに対しても、Devinが自動でエラー内容を読み解き、「〇〇が原因でテストが落ちています。□□を修正すれば通るはずです」といった具体的な対策まで提示してくれたことです。 このおかげで、失敗原因の調査という、また別の面倒な作業まで効率化できました。

特にAndroidではAndroid Gradle Pluginの更新が必要なものなどの、依存関係の更新が原因でビルドが失敗するケースが多々あります。このような場合に具体的な解決策を提案してくれます。

Devinの提案内容:

## ビルドエラーの詳細

### 1. Android Gradle Plugin バージョン不足
- 要求: Android Gradle Plugin 8.x.x以上
- 現在: 8.y.y
- 影響ライブラリ:
  - androidx.navigation:navigation-compose-android:x.y.z
  - androidx.lifecycle:lifecycle-viewmodel-compose-android:x.y.z
  - androidx.lifecycle:lifecycle-runtime-compose-android:x.y.z

### 2. Compile SDK バージョン不足
- 要求: compileSdk xx以上
- 現在: compileSdk yy
- 影響: 上記と同じライブラリ群

## 必要な追加更新
このNavigation x.y.zアップデートを適用するには、以下の追加更新が必要です:

Android Gradle Plugin: 8.x.x → 8.y.y以上
Compile SDK: xx → yy
関連するlifecycleライブラリも同時にx.x.xxに更新される

## 推奨対応

### オプション1: 段階的アップデート
1. 先にAGPとcompileSdkを更新
2. その後でNavigation x.x.xを適用

### オプション2: 一括アップデート
- AGP、compileSdk、Navigation、Lifecycleを同時に更新

### オプション3: アップデート延期
- より安定したタイミングでの一括更新を検討

この作業はPlaybookで指示をしていないため、毎回必ず実行してくれるわけではないため、プロンプトの改善を考えています。

上手くいかないこと

指示した範囲外の判断は人間の役割

Devinは指示した範囲でしか作業をしてくれません。 ライブラリAのレビューをお願いした場合、ライブラリAとライブラリBに依存関係で問題が起きた場合、本来であればライブラリBの更新が望ましいという判断はDevinにはできないため、ライブラリAの更新で解決する提案になります。 具体例として、ライブラリBを更新することで必要なくなるはずの、「競合する設定をライブラリAからオプトアウトする」といったような変更が提案されました。

ここは人間が想像力を働かせて、より本質的な判断をする必要がある部分だと感じています。

困ってること

チームでの可視性に課題

普段はDevinにはSlackから指示を出しています。今回のようにDevinAPI経由で開始すると、WebUIから操作する必要があり、チームでの可視化に課題があります。 ここはCognition Support Teamに共有し、要望として伝えさせてもらいました。

まとめ

本記事では、AIエージェントDevinとGitHub Actionsを用いて、これまで手作業で行っていたRenovateのPR対応を自動化する具体的な方法をご紹介しました。 このアプローチによって、面倒な調査作業から解放され、より本質的な開発業務に集中できる時間が生まれます。 皆さんの日々の業務の中にも、きっと応用できる場面があるはずです。ぜひ、この記事を参考に、身の回りの小さな課題から自動化を試してみてはいかがでしょうか。 もし、もっと良い方法や面白いアイデアがあれば、ぜひSNSなどで教えていただけると嬉しいです。一緒にベストプラクティスを見つけていきましょう!

GitHub Copilot Agent による Go製バッチのAWS Lambda移行(Claude 3.7 Sonnet)

こんにちは。CTOの永井 (id:shnagai) です。 今回は GitHub Copilot Agent (Claude 3.7 Sonnet) を活用し、Go製バッチをAWS Lambdaへ移行した際の開発体験と学びをご紹介します。

TL;DR

  • ゴール: Go製バッチを Copilot Agent (Claude 3.7 Sonnet) 支援のもと、AWS Lambda + EventBridge (SAM利用) へ移行
  • 効果: 簡単なプロンプトでSAMテンプレートやLambda雛形を高速生成。開発効率が劇的に向上
  • 注意点: クラウド設定(特に新しいランタイム等)にはハルシネーションが見られるため、人間によるレビューと修正が必須
  • Tips:
    • .github/copilot-instructions.mdでAI生成精度を向上
    • プロンプトは具体的であれば構造化不要
    • 生成されたインフラ設定は必ず公式ドキュメントで確認

背景・課題

毎月実行しているGo製データ処理バッチの手動実行を、AWS Lambda と EventBridge によって自動化したいと考えていました。Lambda化、SAMテンプレート作成、EventBridge設定など多くの作業が必要なため着手できていませんでしたが、GitHub Copilot Agent (Claude 3.7 Sonnet) の実力を試す好機と捉え、移行に取り組みました。

Copilot Agent との対話プロセス

VS Code の Copilot Chat (Claude 3.7 Sonnet) に、以下のようなシンプルなプロンプトで依頼しました。

Goで手元でビルドして動いているコードをLambda+EventBridgeを使ってAWS環境で自動実行できるようにしたい。
デプロイにはAWS SAMを利用するので、必要なファイルの準備も合わせてお願いします。

このシンプルなプロンプトだけで、的確な SAM テンプレート (template.yaml) や Lambda 関数 (main.go) の雛形が迅速に生成されました。また、リポジトリルートに .github/copilot-instructions.md を配置し、プロジェクト固有の情報を提供することで生成精度が向上することも確認できました(このファイル自体も Copilot に生成を依頼できます)。

発生した課題と手直し

Copilot Agent は非常に強力なアシスタントですが、万能ではありません。特に AWS のような急速に進化するクラウドサービスの構成においては、いくつかの点で手直しが必要でした。

Lambda ランタイム指定のハルシネーション

  • 事象: Copilot が生成した template.yaml では、Go の Lambda ランタイムとして古い Go1.x が指定されていました。このランタイムは現在 AWS では非推奨となっており、このままデプロイするとエラーとなります。
  • 対応: 同僚からランタイム指定が古いと指摘を受け、現在推奨されているカスタムランタイム provided.al2023 に修正しました。クラウドサービスの仕様は頻繁に更新されるため、AI の生成内容を鵜呑みにせず、公式ドキュメントで最新情報を確認することの重要性を再認識しました。

認証情報の取り扱い

  • 事象: 当初生成されたコードでは、外部サービス(Google Cloud)への認証キーが適切に扱われていませんでした。
  • 対応: セキュリティ強化のため、認証情報を AWS Systems Manager (SSM) パラメータストアに SecureString として保存し、Lambda 実行時に取得・復号する方式に変更するよう Copilot に指示しました。具体的なパラメータ命名規則(/service-name/GOOGLE_APPLICATION_CREDENTIALS_PARAM 形式)や、ローカル開発環境との互換性確保などの要件を伝えることで、セキュアで実用的なコードに改善できました。

SAM ビルド時のパス依存問題

  • 事象: sam build コマンドを実行するディレクトリによっては、ビルドプロセスが期待通りに動作しないケースがありました。
  • 対応: SAM CLI の挙動や Makefile のパス指定を調整することで解決しました。

環境固有の設定

SAM がデプロイパッケージをアップロードするための中間 S3 バケットとして、組織内で共通利用している特定のバケット名を指定するなど、環境固有の調整も必要でした。

これらの修正作業は必要でしたが、ゼロからすべてのコードや設定ファイルを作成する労力と比べれば、はるかに少ない時間で済みました。Copilot Agent が「ドライバー」としてコーディングの大部分を担い、人間は「ナビゲーター」として設計判断やコード品質の確認、最終調整を行うという、新しい開発スタイルを体験できました。

学び

  • Copilot Agent (Claude 3.7 Sonnet) の強力さ: 定型コードや雛形作成で生産性が飛躍的に向上します。簡単な指示で形にしてくれる体験は、開発の未来を感じさせます。
  • ハルシネーションへの対処: 特に変化の速いクラウド技術では、生成内容の検証(公式ドキュメント確認)と修正が必須です。
  • 人間の知識とレビューの価値: 最新情報の反映や品質担保には、人間の経験やチームレビューが依然として重要です。
  • 効果的なプロンプトとコンテキスト: 指示の仕方や事前情報の与え方で成果が大きく変わります。.github/copilot-instructions.md などの活用が効果的です。
  • 時間制約の克服: まとまった時間が取れないことを理由に先延ばしにしていたタスクも、AI の支援によりスキマ時間を活用して効率的に進められるようになりました。

まとめ

GitHub Copilot Agent (Claude 3.7) は開発効率を大幅に向上させる強力なツールだと感じました。現時点ではAIによるドメイン理解や把握の難しさだったり最新の技術を利用しようとすると、生成内容の検証と手直しが必要なのはたしかですが、これはコンテキストをしっかりと与えていくこととさらなる技術革新で徐々に和らいでいくのではないかと感じています。それよりも、AI と人間が協調する開発スタイルは今後ますます重要になるでしょうし、まずは手を動かしてガンガン使いこなしこの波のど真ん中で楽しんでいきたいと思います。