NewsPicksにおけるモバイル開発でのAI活用

こんにちは、ソーシャル経済メディア「NewsPicks」でVP of Mobile Engineering をしております、石井です。

弊社のモバイル開発はFigma MCPを使ってUI構築をしたり、AIを使ってエンジニア以外でも環境構築せずにPRを作れるようにしています。今回はそんな話を書きます。

まず、前提として弊社モバイル開発では、主にClaude Codeを利用しています。他にもCopilotやCodexなど様々利用していますが、開発で利用しているメインは2025年12月現在はClaude Codeになります。

今回の例はAndroidになります。

モバイルエンジニアの場合

UIコンポーネント

Figmaを利用している場合は、今すぐにFigmaMCPと接続しましょう。

まずは、以下のコマンドでClaude Code に FigmaのMCP サーバーをHTTP 経由で登録して、figma という名前で使えるようにします。

$ claude mcp add --transport http figma https://mcp.figma.com/mcp

次にClaude Code上で、カスタムコマンドの /mcp を呼び出して、問題ないと判断した場合は、アクセス許可をしてください。

以下のように接続できているかを確認します。Connected になっているので接続されています。

✔ claude mcp get figma
figma:
  Scope: Local config (private to you in this project)
  Status: ✓ Connected
  Type: http
  URL: https://mcp.figma.com/mcp

To remove this server, run: claude mcp remove "figma" -s local

この状態でFigmaの右サイドバーにあるMCPの欄の「プロンプト例をコピー」して、Claude Codeに貼り付けます。

これでそれっぽいデザインのコードができるので、修正していくだけです。簡単ですね。ただし、paddingなどの細かい箇所がFigma通りになってないことがあります。また、アイコン画像などは自分でexportして配置しないといけません。

弊社では、デザイントークンをしっかり定義しており、また、CLAUDE.mdを用意して前提知識やコーディングルール、特に利用してほしいコンポーネントをClaude Codeに教えています。

CLAUDE.mdが無ければ、すぐにClaude Codeに書いて貰うのがよいでしょう。その後に修正を繰り返していくとよいです。

また、CLAUDE.mdは、分割する方がメリットが多そうです。
たとえば、次のように分割します。

  • ルート直下の CLAUDE.mdは、.claude/rules/xxx.md へのインデックス集にします.
    • .claude/rules/xxx.mdに詳細なコーディング規約、全体のアーキテクチャ、共通のビルド・テストコマンドなどをそれぞれ別ファイルで書きます。
      これで必要な時に必要なファイルだけを読み込むようになります。
    • .claude/rules/xxx.mdで、paths: を先頭に書く方法が便利です。
      たとえば、以下のようにcomposeパッケージのファイルを触る時だけ読み込まれるようにするルールを書きます。「@Previewを必ず用意する」「Modifier の記述順」「remember の使い方」など、Compose 実装に特化した細かい規約を書くなどなどです。
        ---
        paths:
          - ui/src/main/kotlin/**/compose/*.kt
          - ui-common/src/main/kotlin/**/compose/*.kt
        ---    
        * コンポーザブルは必ず @Preview を用意する
      
  • 各モジュール配下に小さめの CLAUDE.md そのモジュール固有の責務・依存関係・使用禁止事項を簡潔に書きます。
    たとえば、UI関連のモジュールでは、共通コンポーネントの一覧や依存関係のざっくりした説明を書くとよさそうです

UIコンポーネント以外

最近のClaude Codeはだいぶ進化しており、しっかりとしたCLAUDE.mdとサンプルとなる実装があれば、それっぽいコードを生成してくれます。
なので、ちゃんとしたアーキテクチャで理想的な綺麗なコードを用意して、CLAUDE.mdにそれらのルールを書くことに集中しましょう。それで、大体の基本的なコードはできます。

モバイルエンジニア以外の場合

では、モバイルの知識がない方々はどうでしょう。上に書いた方法だとAndroid Studioを用意して、ビルドして....などなどモバイルエンジニア以外にはハードルが高いでしょう。
特にWeb系のデザイナーにとっては環境を作るのもハードルが高く難しいと感じるかもしれません。

そこで弊社では簡単な修正であれば、誰でもPRができるような仕組みをAmazon Bedrockを利用して作っています。

フロー

PRが作られるフローは以下です。

  1. コードを変更したい人間が、GitHub Issueに変更したい内容を記述
  2. コードを変更したい人間が、そのissueに「issue-to-plan」ラベルを付ける
  3. Github Actionが起動し、Bedrockがissueの内容を見て実行計画をたて、issueのコメントに実行計画を記述
  4. 変更したい人間がその内容を見て
    • よさそうなら、「issue-plan-to-pr」ラベルをつける。するとBedrockがPRを作成してくれる
    • よくなければ、実行計画を人間が編集したり、実行計画を参考にissueそのものの文言を変更し、再度、2をする
    • ここで実行計画の意味がわからなかったら、そのままにする(モバイル知識があるメンバーが気づいたら修正する)
      • 簡単な修正だったら、そのままPRを作ってもほとんど問題なし
  5. PRができたら、Codemagicが動き、Deploygateにそのアプリが作成される
  6. 人間は、Deploygateで動作確認する
  7. 人間は、PRが期待通りでなければ、PR上にレビューをして、Bedrockに直して貰う

これにより、モバイルエンジニアの介在が最小限、場合によってはゼロでモバイルの変更ができます。

他に必要なこと

現在は、すごく簡単な修正(ジュニアメンバーが1時間程度でできるタスク)であれば、10個試して4個マージできるレベルです。
ただ、まだ完璧に運用できる状態ではないです。モバイルの知識がなくともできますが、視覚的な画面の論理名がわからないとissueに書くのが難しいし、周りくどくissueに書かずにコンポーネントを変えたい、ディープリンクなど決まりきった機能を追加したいなどなど、課題があります。

そのため、以下のことを今後進めていき、精度を上げていこうと考えています。

  • 画面名を統一をし、その名前と実際のクラス名、関数名のマッピングをClaudeに覚えさせる
  • 画面のカタログを用意し、視覚的に関数名をわかるようにして、その名前を指定できるようにする
  • 決まりきった機能のClaudeのカスタムコマンドを用意しておく

これにより、たとえば、デザイナーがこのコンポーネントのテキストサイズを変えたい、paddingを変えたい。などもissueに書きやすくなるはずです。

コード

最後にこの仕組みのポイントはGitHub Actionのworkflowです。 実際のコードとは違いますが、以下のような書き方をしてissueからplanを作成してます。

name: Issue to Plan

permissions:
  contents: write
  pull-requests: write
  issues: write
  id-token: write

on:
  issues:
    types: [ labeled ]

jobs:
  issue-to-pr:
    if: github.event.label.name == 'issue-to-plan'
    runs-on: ubuntu-latest
    env:
      AWS_REGION: ap-northeast-1
    steps:
      - name: Checkout repository
        uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

      - name: Generate GitHub App token
        id: app-token
        uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
        with:
          app-id: ${{ vars.MY_APP_ID }}
          private-key: ${{ secrets.MY_APP_PRIVATE_KEY }}

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0
        with:
          role-to-assume: ${{ vars.MY_AWS_ROLE_TO_ASSUME }}
          aws-region: ap-northeast-1

      - name: Generate code from issue using Claude
        uses: anthropics/claude-code-action@a3ff61d47aa5118a43b33ae44c4087d9eb51111a # v1.0.6
        timeout-minutes: 60
        env:
          SYSTEM_PROMPT: |
            - GitHubに書き込む際は、必ず日本語で書いて下さい。
        with:
          github_token: ${{ steps.app-token.outputs.token }}
          use_bedrock: "true"
          trigger_phrase: "issue-to-plan"
          label_trigger: "issue-to-plan"
          claude_args: |
            --allowedTools "Bash(git checkout:*),Bash(gh pr:*),Bash(gh issue:*),Read,Write,Edit,Glob,Grep"
            --disallowedTools "Bash(git branch -d),Bash(git branch -D),Bash(git push --delete),Bash(git rebase),Bash(gh pr close --delete-branch),Bash(gh pr update-branch --rebase)"            
            --model ${{ vars.MY_CLAUDE_CODE_MODEL }}
            --system-prompt "${{ env.SYSTEM_PROMPT }}"
          prompt: |
            以下のIssue内容や要件を読んで、必要な実装の計画を立ててください。
            その計画を該当のissue #${{ github.event.issue.number }}に書き込んでください。
            ${{ github.event.issue.body }}

planからPRを作成するのも同じような仕組みにしており、気にするのは権限ぐらいです。

            --allowedTools "Bash(git checkout:*),Bash(git add:*),Bash(git commit:*),Bash(git push:*),Bash(gh pr:*),Bash(gh issue:*),Read,Write,Edit,Glob,Grep"
            --disallowedTools "Bash(git branch -d),Bash(git branch -D),Bash(git push --delete),Bash(git rebase),Bash(gh pr close --delete-branch),Bash(gh pr update-branch --rebase)"

この仕組みの応用

この仕組みを応用して、いくつか便利な運用ができます。

ライブラリの更新

この仕組みを使ってライブラリ更新の課題を解決できます。弊社では、ライブラリの更新は毎週水曜日に5個ずつアップデートしています。
仕組みは、Renovateを使ってます。Renovateが動くとビルドして、DeploygateのリンクがRenovateのPRのコメントができます。ここで動作確認をしてマージしてます。
このとき「動作確認をする際にライブラリのリリースノートを確認」してます。
この「動作確認をする際にライブラリのリリースノートを確認」の部分をBedrockに任せます。

仕組みは、renovateが作るブランチをrenovate/**にして、このブランチのPRができた場合にBedrockがそのライブラリのリリースノートを確認して、テスト観点をPRのコメントに書いて貰うだけです。

ログ仕様書からPR

弊社では、ログ仕様書をTypeScriptでできており、そこから、Kotlinのクラスを自動生成しています。このjarをAndroidのプロジェクトで利用してます。
ここで、この仕組みを応用すると一気通貫でPRができます。

ログのjarができたら、モバイルのレポジトリに専用のラベル付きでissueを作成したら、PRを作成してくれます。 この話は、他のモバイルメンバーが別ブログで書くそうなので、そちらを楽しみにしてください。

終わりに

この仕組みは、エンジニアのコスト削減にも繋がりますが、それ以上に以下のメリットがあります。

  • 気になるけど頼むほどでもない(と思っている)修正がプロダクトに反映される
  • モバイル開発のとっかかり。「モバイルは怖い」が減り、手を出しやすくなる
  • これを進めていくためにモバイルの内部品質を良くしていく気運が高まる
  • 完全なるAI時代への布石の一歩になる

そして、どんどん生産性が上がっていく!

Page top