エクセル設計書とソースコードを差分比較する仕組みを考えてみた

記事タイトルとURLをコピーする

目次

  1. はじめに
  2. 概要
  3. Excel設計書のtxt変換
  4. 設計書とソースコードの差分レビュー
  5. 実行結果
  6. 活用例
  7. まとめ

はじめに

こんにちは、佐々木です。

皆さんはプログラムの設計書をどの形式で作成していますか? Markdown形式が増えてきたものの、まだまだExcel設計書を使うことも多いのではないでしょうか。

私も先日、Excelで設計書を書いていたら、こんなことがありました。

  1. Excelで設計書を作成
  2. コーディングを実施
  3. コーディング中の仕様変更がExcel設計書に反映されず、ソースコードとの間に差分が発生

これは開発プロジェクトあるあるではないでしょうか。 最後に総チェックする方法もありますが、連携が多いシステム等では、設計書の反映漏れが大きな手戻りにつながることもあります。 設計書とソースコードの整合性は常に保たれている状態が理想です。

そこで、ソースコードとExcel設計書を随時比較してくれる仕組みを作ってみました。

概要

GitHubのプルリクエスト作成時に、AIがソースコードとExcel設計書を自動比較します。

仕組みは以下の通りです。

  1. Amazon S3にExcel設計書を格納
  2. AWS LambdaでExcelをテキストに自動変換
  3. GitHubでプルリクエスト作成時に、GitHubActionsにより、Amazon Bedrockがソースコードと設計書を比較してレビュー
  4. レビュー結果をプルリクエストにコメント投稿

Excel設計書のtxt変換

以下の流れでExcelファイルをテキストに変換します。

  1. S3バケットのexcel/フォルダに.xlsxファイルをアップロードすると、EventBridgeがイベントを検知
  2. Lambda関数が自動起動し、openpyxlでExcelファイルを読み込み、全シート・全セルの内容をタブ区切りテキストに変換
  3. 変換結果をtxt/フォルダに保存

技術スタック

AWS SAM / Amazon S3 / Amazon EventBridge / AWS Lambda (Python 3.12) / openpyxl

フォルダ構成

├── template.yaml              # SAMテンプレート
└── functions/
    ├── app.py                 # Lambda関数(Excel→txt変換)
    └── requirements.txt       # Python依存関係

template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Excel to Text converter using S3, EventBridge, and Lambda

Resources:
  S3ExcelReviewTestBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 's3-excelreview-test-${AWS::AccountId}'
      NotificationConfiguration:
        EventBridgeConfiguration:
          EventBridgeEnabled: true

  LambdaExcelReviewTestProcessor:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: lambda-excelreview-test-processor
      Runtime: python3.12
      Handler: app.lambda_handler
      CodeUri: functions/
      Timeout: 300
      MemorySize: 512
      Policies:
        - S3ReadPolicy:
            BucketName: !Sub 's3-excelreview-test-${AWS::AccountId}'
        - S3WritePolicy:
            BucketName: !Sub 's3-excelreview-test-${AWS::AccountId}'
      Events:
        EventBridgeExcelReviewTestRule:
          Type: EventBridgeRule
          Properties:
            Pattern:
              source:
                - aws.s3
              detail-type:
                - Object Created
              detail:
                bucket:
                  name:
                    - !Sub 's3-excelreview-test-${AWS::AccountId}'
                object:
                  key:
                    - prefix: excel/
                    - suffix: .xlsx

requirements.txt

openpyxl

app.py

import json
import boto3
import openpyxl
from io import BytesIO

s3 = boto3.client('s3')

def lambda_handler(event, context):
    bucket = event['detail']['bucket']['name']
    key = event['detail']['object']['key']
    
    # Excelファイルをダウンロード
    response = s3.get_object(Bucket=bucket, Key=key)
    excel_data = response['Body'].read()
    
    # ワークブックを読み込み
    wb = openpyxl.load_workbook(BytesIO(excel_data), data_only=True)
    
    # 全セルの内容を抽出
    output = []
    for sheet_name in wb.sheetnames:
        sheet = wb[sheet_name]
        output.append(f"=== Sheet: {sheet_name} ===\n")
        
        for row in sheet.iter_rows(values_only=True):
            row_text = '\t'.join(str(cell) if cell is not None else '' for cell in row)
            output.append(row_text + '\n')
        output.append('\n')
    
    # txtフォルダにアップロード
    txt_key = key.replace('excel/', 'txt/').rsplit('.', 1)[0] + '.txt'
    s3.put_object(Bucket=bucket, Key=txt_key, Body=''.join(output))
    
    return {'statusCode': 200, 'body': json.dumps(f'Processed {key}')}

設計書とソースコードの差分レビュー

以下の流れで GitHubActionsによりプルリクエストを自動レビューします。

  1. リポジトリのsrc/ディレクトリ内の変更ファイル一覧を取得
  2. S3バケットから変換済みのテキスト設計書をダウンロードして1ファイルに結合
  3. 各変更ファイルのdiffと設計書をBedrockのコンテキストに設定して、整合性チェック
  4. レビュー結果をPRにコメントとして自動投稿

技術スタック

GitHub Actions / AWS CLI / Amazon Bedrock (Claude Sonnet 4.5)

excel-review.yml

name: Excel Review with Bedrock

# PRがオープンまたは更新された時に実行
on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - 'src/**' 

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

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      # リポジトリをチェックアウト
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      # AWS認証(OIDC)
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      # srcディレクトリ内の変更ファイルを取得
      - name: Get changed files in src
        id: changed-files
        run: |
          git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '^src/' > changed_files.txt || true
          echo "files<<EOF" >> $GITHUB_OUTPUT
          cat changed_files.txt >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      # S3から設計書をダウンロードして結合
      - name: Get design documents from S3
        run: |
          BUCKET="s3-excelreview-test-${{ secrets.AWS_ACCOUNT_ID }}"
          mkdir -p /tmp/design_docs
          aws s3 sync "s3://${BUCKET}/txt/" /tmp/design_docs/
          
          # 設計書を結合してファイルに保存
          echo "" > /tmp/design_docs_combined.txt
          for doc in /tmp/design_docs/*.txt; do
            if [ -f "$doc" ]; then
              echo "" >> /tmp/design_docs_combined.txt
              echo "### $(basename "$doc")" >> /tmp/design_docs_combined.txt
              cat "$doc" >> /tmp/design_docs_combined.txt
            fi
          done

      # Bedrockでコード変更をレビュー
      - name: Review code changes with Bedrock
        if: steps.changed-files.outputs.files != ''
        env:
          PR_NUMBER: ${{ github.event.pull_request.number }}
          REPO: ${{ github.repository }}
          GH_TOKEN: ${{ github.token }}
        run: |
          COMMENT="## Code Review Results\n\n"
          
          # 変更ファイルごとにレビュー実行
          while IFS= read -r file; do
            if [ -z "$file" ]; then continue; fi
            
            # ファイルのdiffを取得
            DIFF=$(git diff origin/${{ github.base_ref }}...HEAD -- "$file")
            
            # Bedrock用メッセージJSON作成
            jq -n \
              --arg file "$file" \
              --arg diff "$DIFF" \
              --rawfile design /tmp/design_docs_combined.txt \
              '[{
                role: "user",
                content: [{
                  text: (
                    "以下のコード変更をレビューしてください。\n\n" +
                    "ファイル: \($file)\n\n" +
                    "変更内容:\n```\n\($diff)\n```\n\n" +
                    "設計書:\n\($design)\n\n" +
                    "以下の観点でレビューし、それぞれについて箇条書きで回答してください。各指摘は1~2行で示してください:\n" +
                    "- ソースプログラムと機能定義書との整合性\n" +
                    "- ソースプログラムとテーブル定義書との整合性\n" 
                  )
                }]
              }]' > /tmp/messages.json

            # Bedrock Converse APIを呼び出し
            echo "Calling Bedrock API for $file..."
            aws bedrock-runtime converse \
              --model-id jp.anthropic.claude-sonnet-4-5-20250929-v1:0 \
              --messages file:///tmp/messages.json \
              --output json > /tmp/response.json
            
            # レビュー結果を抽出
            REVIEW=$(jq -r '.output.message.content[0].text' /tmp/response.json 2>/dev/null || echo "レビュー生成に失敗しました")
            
            COMMENT="${COMMENT}### \`${file}\`\n${REVIEW}\n\n"
          done < changed_files.txt
          
          # PRにコメント投稿
          echo -e "$COMMENT" > /tmp/comment.txt
          gh pr comment $PR_NUMBER --body-file /tmp/comment.txt

実行結果

設計書とプログラム(今回はストアドプロシージャ)の間に意図的に10か所の差分を作り、プルリクエストを作成してみました。

結果は以下の通りです。

  • 検出率: 10件中10件すべての誤りを検出
  • レビュー時間: 約30秒で完了
  • コスト: 1回あたり数円程度

PRには以下のようなレビューコメントが自動投稿されました。

所感

良かった点:

  • 高精度で設計書とソースコードの差分を検出することができた。
  • 設計書の量にもよるが、1回あたり数円程度と低コストであった。

課題点:

  • 設計書を全て読み込むというやや乱暴な方法のため、Bedrockのトークン制限に注意が必要。
  • 大規模プロジェクトでは、設計書をディレクトリ分割して一部のみ読み込むなどの工夫が必要。

まとめ

今回、GitHub Actions、Amazon Bedrockを組み合わせて、Excel設計書とソースコードの自動レビューシステムを構築しました。

開発プロジェクトにおける「設計書とソースの乖離」という課題に対して、生成AIを活用した実用的な解決策の案を提示できたのではないかと思います。

今後も、開発現場の課題をAWSサービスと生成AIで解決していきたいと思います。

佐々木 悠貴 (記事一覧)

クロスインダストリー第1部 クラウドモダナイズ課

役に立つちょんプロを作るのが好き