
ドメイン駆動
イベント

マガジン
技術ブログ
この記事は、”Reimagine your mainframe applications with Agentic AI and AWS Transform” を翻訳したものです。 本ブログでは、reimagine パターンによってメインフレームのレガシーアプリケーションをモダナイズする AWS のアプローチの概要を説明し、組織がレガシー COBOL アプリケーションをモダンなクラウドネイティブアーキテクチャに変換する方法を紹介します。 人材不足、コスト増加、ビジネスアジリティの制約により、組織はレガシーメインフレームアプリケーションをモダナイズする喫緊の課題に直面しています。 AWS は、メインフレームアプリケーションをモダナイズするための複数のアプローチをサポートしています。Reimagine パターンにより、組織はカスタマーエクスペリエンスを再構想 (reimagine) し、ビジネスプロセスフローを最適化し、新機能を導入することで、モダンなアプリケーションに機能的な変化をもたらすことができます。このプロセスで、メインフレームアプリケーションをモダナイズすることができます。この過程は、モダンなアーキテクチャとテクノロジースタックを使った、アーキテクチャの再設計 (rearchitecting) と、アプリケーションのリライト (rewriting) を伴います。トランスフォーメーションジャーニーを加速させるため、エージェンティック AI を活用したツール一式によって、メインフレームのモダナイゼーションの reimagine パターンがサポートされています。 メインフレームアプリケーションを再構想するときの戦略的課題 AWS は、メインフレームモダナイゼーションの特効薬が無いことを認識しています。戦術的アプローチは既存システムの拡張と維持に重点を置いていますが、戦略的モダナイゼーションには リプラットフォーム (replatform)、リファクタリング (refactor)、リプレース (replace)、reimagine という明確な道筋があります。Reimagine は最も変革的なアプローチを代表しており、組織はマイクロサービスやバッチプロセスからリアルタイム機能への移行などのモダンなパターンを使って、アプリケーションアーキテクチャを全面的に見直します。 ほとんどのお客様は、reimagine 戦略を検討する際に 80:20 の原則に従います。Reimagine は、ビジネスでアプリケーションの機能強化が必要な場合に適しています。お客様は、メインフレームワークロードの一部だけがこのカテゴリに該当すると予想しています。このような状況では、モダンな UI、リアルタイム機能、またはより高速なバッチ処理が望まれている可能性があります。また、現行のモノリス化したアプリケーションをプロダクトに合わせたビジネス機能に分割したいという目標をお客様が持っている場合もあります。お客様は、自社のメインフレームアプリケーションの 20% が技術的な制約のせいでビジネスレベルの変更から真に恩恵を受けられない一方で、残り 80% は機能変更を必要としていないことに気付くかもしれません。ただし、一部の組織では、短期的な移行効率よりも長期的なビジネス変革を優先しており、パターンの選択は機能変更を必要とするアプリケーションの割合だけではなく、戦略的目標にも依存していることが実証されています。この洞察は AWS のマルチパターン戦略を推進する要素の 1 つです。AWS は複数の移行パターンをサポートしているので、お客様は各ワークロードに最適なモダナイゼーションアプローチを選択できるようになっています。 参考 5 AWS の reimagine 戦略の中心にあるのが AWS Transform for mainframe です。これは、エージェンティック AI を活用して、メインフレームアプリケーションのモダナイゼーションを加速するサービスです。このサービスにより、お客様は COBOL などの言語で記述されたモノリシックアプリケーションを、マイクロサービスのような、よりモダンなアーキテクチャスタイルに変換できます。AWS の reimagine 戦略の中心は、「Human in the Loop」原則に基づく検証です。この原則では、AI が生成したアプリケーション仕様とコードは、各分野の専門家によって継続的に検証される必要があります。AWS Transform for mainframe は強力なリバースエンジニアリングを提供し、Kiro はマイクロサービス仕様を生成します。ただし、プロセス全体を通して、人間の専門知識は依然として不可欠です。ビジネスロジックの解釈を検証し、アーキテクチャの境界を確認し、アプリケーションがすべての要件を満たしていることを検証するには、専門家が必要です。AI の機能と人間の判断によるこの協調的なアプローチは、AI を活用したモダナイゼーションのスピード上の利点を維持しながら、トランスフォーメーションのリスクを大幅に軽減します。 Strangler fig パターン: 進歩的なモダナイゼーションを可能にする手法 企業のお客様が、すべてのアプリケーションをメインフレームから同時に一括移行するようなビッグバンアプローチの大規模なモダナイゼーションを追求することはめったにないと認識されています。Strangler Fig アプリケーションパターンは、漸次的なモダナイゼーションの手法として実証済の選択肢です。このパターンは、トランスフォーメーション、共存、排除という 3 つの段階を経て、メインフレームアプリケーションをモダナイズするための安全なアプローチとなります。 Strangler fig パターンは、漸次的なモダナイゼーションアプローチです。これにより、組織は元のアプリケーションを実行したまま、モノリシックアプリケーションを徐々にマイクロサービスに置き換えることができます。このアプローチは、モノリスから機能を段階的に抽出することで機能します。抽出された機能は、既存のシステムを中心とした新しいマイクロサービスに変換されます。その後、統合パターンにより、新しいマイクロサービスとレガシーアプリケーションの間の接続が可能になります。 共存フェーズでは、メインフレームと AWS 上の新しいシステムの両方が同時に動作し、システム間の連携が行われます。連携パターンは、アプリケーション間の連携、アプリケーションからデータに対する連携、データ間の連携の 3 種類の統合をサポートします。 参考 4 このような連携アーキテクチャを構築し、共存に適した統合パターンを選択するには、お客様はハイブリッド環境全体におけるデータの一貫性、トランザクション管理、パフォーマンスに特に注意を払う必要があります。 メインフレームモダナイゼーションのためのマイクロサービスアーキテクチャの理解 マイクロサービスアーキテクチャーでは、従来のメインフレームのモノリシックなアーキテクチャーとは対照的に、システムを独立した小さなサービスに分割し、個別に開発、デプロイ、拡張できるようにすることを重視しています。メインフレームモダナイゼーションという文脈において、マイクロサービスには、明確なコンテキスト、独立したデプロイ、テクノロジーの多様性、スケーラビリティなど、重要な価値ある特徴があります。 マイクロサービスとイベント駆動型アーキテクチャを組み合わせると、バッチ処理からリアルタイム処理に移行する際に特に強力になり、変更に対してシステムが非同期で反応できるようになります。 マイクロサービスには大きなメリットがありますが、普遍的に最適なソリューションというわけではありません。データの一貫性やトランザクション性が必要な場合は、モジュラーモノリスやマクロサービスなどの代替アプローチの方が適している場合があります。重要なのは、現在のニーズと将来の願望の両方に適合するアーキテクチャを選択することです。 Reimagine パターンにおける 3 フェーズのモダナイゼーションアプローチ Reimagine パターンでは、3 フェーズの方法論を通じて、現行のメインフレームアプリケーションをクラウドネイティブなマイクロサービスに変換します。 リバースエンジニアリング : AWS Transform for mainframe を使用してリバースエンジニアリングを行い、既存の COBOL / JCL コードからビジネスロジックとルールを抽出します フォワードエンジニアリング : AI エージェント / Kiro を使ってマイクロサービス仕様とソースコードの両方を生成します デプロイとテスト : 生成されたマイクロサービスを Infrastructure as Code (IaC) を使って AWS にデプロイしてテストし、モダナイズしたアプリケーションの機能をテストします Reimagine パターンにおける 3 フェーズのモダナイゼーションアプローチ フェーズ 1: リバースエンジニアリング AWS Transform for mainframe を使ったリバースエンジニアリングのスコープを以下の図に示します。 AWS Transform を使ったリバースエンジニアリング モダナイゼーションを成功させるための基礎は、レガシーアプリケーションを深く理解することから始まります。AWS Transform は、メインフレームのソースコードと運用データ (スケジューラープラン、モニタリングデータ) など、複数のソースからの情報を組み合わせて分析します。このフェーズでは、次のような重要なアウトプットが得られます。 技術文書 : AWS Transform はソースコードを自動的に分析して、アプリケーションプログラムの詳細な文書を作成します。このドキュメントには、レガシーシステム内のプログラムロジック、フロー、連携、依存関係についての説明が含まれています。レガシーシステムに関する重要な知識を維持することで、退職するメインフレーム専門家への依存を減らすのに役立ちます。また、これまで分析や計画に費やされていたプロジェクト時間も短縮されます。 ビジネスロジックの抽出 : ビジネスロジックの抽出は、複雑なモノリシックアプリケーションをその構成要素であるビジネス機能に分解する、メインフレームのモダナイゼーションにおいて不可欠な機能です。AWS Transform は COBOL ソースコードを自動的に分析します。この分析は、レガシーアプリケーションに組み込まれているプロセスフローやビジネスロジックなど、重要なビジネス要素を特定して文書化するのに役立ちます。この分解プロセスは、モノリス化したメインフレームアプリケーションをより小さく、より管理しやすいビジネス機能に分解するための基本です。これらの機能は、reimagine の取り組みにおける後半の工程でマイクロサービスのスコープと境界を特定するための基礎となります。この機能は、技術ユーザーとビジネスユーザーの両方が理解できるエクスポート可能な自然言語で仕様を提供することで、モダナイゼーションの取り組みにおける複数のステークホルダーに役立ちます。 メインフレームデータモデル : AWS Transform には、データリネージ分析やデータディクショナリの自動生成など、メインフレームのモダナイゼーションを成功させるために不可欠な高度なデータ分析機能が備わっています。これらの機能が連携して、メインフレームデータの「場所」(使用法と関係) に付随する「内容」(構造と意味) を定義します。組織はデータ環境を完全に可視化できるようになり、情報に基づいたモダナイゼーションの意思決定が可能になります。技術チームは、重要なビジネスロジックとデータ間の関連性を維持しながら、自信を持ってデータアーキテクチャを再設計できます。 稼働分析 : システム管理機能 (SMF) を介してメインフレームから収集された実行時データによって、静的コード分析を補完することができます。SMF は z/OS サブシステム上のアクティビティデータを収集するための中心的なメカニズムです。これらの記録に含まれる情報は、モダナイゼーションの計画、優先順位付け、実行に不可欠です。AWS Transform は SMF データ (バッチ処理ではレコードタイプ 30、CICS トランザクションではレコードタイプ 110) を分析して、アクティブなバッチジョブと CICS トランザクションを識別できます。使用済み/未使用のトランザクション/バッチを検出し、トランザクション/バッチの MIPS 使用量を測定することで、組織は未使用のプログラムと消費量の多いリソースを特定できます。これにより、何を移行し、何を廃止するかについてデータ主導の意思決定が可能になり、メインフレームのリソース使用率をかつてないほど可視化できます。 フェーズ 2: フォワードエンジニアリング フォワードエンジニアリングは、抽出されたビジネスロジックをマクロサービス/マイクロサービスのアーキテクチャに変換することを目的としています。 AWS は、お客様組織内の多様なニーズを認識し、パートナー主導型およびお客様主導型の柔軟なコード生成アプローチを採用しています。AWS は、既存の開発者ツールと競合するのではなく、リバースエンジニアリングで得られた豊富な理解を 促進 することに重点を置いています。これにより、既存のコードを複数の方法でモダンなアプリケーションに正確に変換できるようになります。 Kiro やその他のコーディングアシスタントなどの好みの開発ツールを使用した、お客様主導またはパートナー主導の開発 AI を活用したコーディングアシスタントとしての Kiro や AI エージェントの活用 AWS Transform は Kiro のような AI を活用したコーディングアシスタントと連携して、仕様駆動型の開発をサポートします。これらのツールは互いに補完し合っています。AWS Transform が提供するアウトプットは、Kiro がマイクロサービス仕様とソースコードの両方を生成するためのインプットになります。 Kiro と AI エージェントのアプローチについて詳しく見ていきましょう。このアプローチは 3 つの異なるステップで構成されており、正しさと品質を Human in the Loop で 検証 します。 以下の図は、 Kiro または AI エージェントを使ったフォワードエンジニアリングのスコープを示しています。 Kiro / AI エージェントを使ったフォワードエンジニアリング ステップ 1: マイクロサービス仕様の生成 このステップでは、ビジネスロジックの抽出を入力として、AI エージェントまたは Kiro を使い、各マイクロサービスの詳細な仕様を作成します。Kiro の仕様駆動型のアプローチにより、アーキテクトはマイクロサービスを設計して正式な仕様を作成し、実装を開始する前に、アプリケーションの対象分野の専門家が各仕様を確認して改良することができます。プロジェクト固有のステアリング文書を作成することで、Kiro はインプット (ビジネスロジック、データ分析、非機能要件など) と要件についての理解を深めることができます。このステップでは、トレーサビリティとビジネスルールの包括的な適用範囲を検証する必要があります。これにより、特定されたすべてのビジネスロジックが適切に分析され、関連するマイクロサービス仕様に組み込まれたかどうかを追跡できます。 Kiro にマイクロサービス仕様の生成を依頼するステアリングファイルのサンプルを次に示します。 マイクロサービス仕様を生成するためのステアリングファイルのサンプル 【参考】日本語訳 ## Role: あなたはソフトウェア設計、特にドメイン駆動設計、マイクロサービスアーキテクチャ、システムモダナイゼーションの分野で 20 年以上の経験を持つシニアソフトウェアアーキテクトです。エンタープライズアプリケーションのモノリスからマイクロサービスへのトランスフォーメーションを何十回も成功させてきました。あなたは、境界コンテキストの特定、クリーンなドメインモデルの設計、効果的なサービス境界の構築に関する専門家です。ソフトウェア設計パターン、API 設計、イベント駆動型アーキテクチャ、フロントエンド統合戦略に関する深い知識を有します。 ## Action: … `input/bre_output` フォルダーとサブフォルダー内の提供された HTML ファイルと JSON ファイルを分析して、現在のビジネスロジック、データ構造、および暗黙的なドメインモデルを理解してください。追加のコンテキストが必要な場合のみ、`input/source-code` フォルダーとサブフォルダーのソースコードを参照してください。 `input/bre_output` フォルダーとサブフォルダー内の HTML ファイルと JSON ファイルにあるビジネスロジックに基づいて、主要なビジネスドメイン、サブドメイン、潜在的な境界コンテキストを特定します。追加のコンテキストが必要な場合のみ、`input/source-code` フォルダーとサブフォルダーのソースコードを参照してください。 ドメイン駆動設計の原則を適用して、独自のユビキタス言語、集合ルート、エンティティ、バリューオブジェクト、ドメインイベントを使用して明確な境界のあるコンテキストを定義します。 特定された境界コンテキストに基づいてマイクロサービスアーキテクチャを設計し、各マイクロサービスが単一の責務を担い、独自のデータを管理するようにします。 ステップ 2: ターゲットデータベースの生成 データベースのモダナイゼーションは、メインフレームトランスフォーメーションプロジェクトにおける極めて重要な課題です。レガシーメインフレームデータベースは、IMS/DB や IDMS などの階層型データベースやネットワーク型データベース、または Db2 などのリレーショナルデータベースを使って構成されています。これらのデータベースには、ビジネス上の重要なデータが何十年にもわたって蓄積されていますが、今となっては時代遅れのデータモデルに従って構造化されているものもあります。ターゲットデータベースの生成フェーズでは、これらのレガシーデータ構造を、データの整合性とビジネスルールを維持しながらマイクロサービスアーキテクチャをサポートするモダンなクラウドネイティブなデータベーススキーマに変換します。AWS Transform のデータ分析機能により、レガシーデータベース構造を包括的に理解できます。Kiro は、このデータ分析結果をターゲットアプリケーションの仕様と組み合わせてインプットとして使用し、ターゲットのモダナイズされたデータベースを作成します。 ステップ 3: ソースコード生成と Infrastructure as Code の生成 仕様を検証した後、Kiro は実装フェーズに移行し、本番環境ですぐに使えるマイクロサービスコードと Infrastructure as Code を生成します。実装プロセスは、要件定義、設計、実装タスクという Kiro の 3 フェーズのワークフローに従います。このフェーズでは、Kiro は実装タスクを自律的に実行できます。一方、開発者は生成されたコードのレビュー、フィードバックの提供、要件に対する実装の検証に集中できます。このプロセスにはステアリングファイルが不可欠です。これによって Kiro はプロジェクトの規約、ライブラリ、標準に関する永続的な知識を得ることができ、確立されたアーキテクチャガイドラインやコーディング標準に準拠することができます。この構造化されたアプローチにより、チームは実装戦略を見直し、改良することができます。また、品質保証活動のための包括的なテストケースとテストデータの生成にも役立ちます。 Kiro にマイクロサービスのターゲットソースコードの生成を依頼するステアリングファイルのサンプルを次に示します。 ターゲットソースコードの生成のためのステアリングファイルの例 【参考】日本語訳 ## Action: まず microservices-specs フォルダーから提供されたマイクロサービス仕様を分析し、必要な各マイクロサービス、その責務、データモデル、連携ポイントを特定します。 以下を含む customer-management-service マイクロサービスシステムの全体的なアーキテクチャを設計します。 サービスの境界と責任 データの所有権と共有のアプローチ 通信パターン (同期 vs 非同期) 各コンポーネントの AWS サービスの選択 仕様書に記載されている customer-service マイクロサービスの場合: 適切な Maven/Gradle 構成で Spring Boot プロジェクト構造を作成する データモデルフォルダの下にある顧客の DynamoDB テーブル定義をマッピングするデータモデルを実装する REST のベストプラクティスに従って RESTful API コントローラーを開発する サービス層のビジネスロジックを指定どおりに実装する 適切な例外処理、検証、ロギングを追加する AWS サービスインテグレーション (必要に応じて DynamoDB、SQS、SNS など) を設定する サービスのユニットテストを書く 以下は、マイクロサービスを実装するためのプロンプトとステアリングファイルから Kiro によって生成されたタスクファイルのサンプルです。 マイクロサービスを実装するタスクファイルの例 【参考】日本語訳 [x] 1. 顧客管理サービスのプロジェクト構造を設定する Maven のディレクトリ構成で Spring Boot プロジェクトを作成する マルチモジュールプロジェクト構造 (domain, application, infrastructure, web) を設定する さまざまな環境 (dev, staging, prod) に合わせてアプリケーションプロパティを設定する 重要な依存関係 (Spring Boot, Spring Data, AWS SDK, validation, testing) を追加する _要件: 1.1、2.1_ [x] 2. コアドメインモデルとバリューオブジェクトを実装する [x] 2.1 ドメインロジックによる顧客集約ルートを作成する すべての必須フィールドとビジネスメソッドを含む Customer エンティティを実装する バージョンフィールドによるオプティミスティックロックを追加する ドメイン検証ルールを実装する _必要条件:5.1、5.5_ [x] 2.2 データの一貫性を実現するためのバリューオブジェクトを実装する ID が 9 文字であることのチェックも含めて CustomerID バリューオブジェクトを実装する フォーマット検証と暗号化をサポートする SSN バリューオブジェクトを作成する 電話番号のフォーマット (XXX-XXX-XXXX) のチェックを含む PhoneNumber バリューオブジェクトを作成する 値の範囲が 300 ~ 850 になるチェックを含む FICoScore バリューオブジェクトを作成する _必要条件:5.3_ フェーズ 3: デプロイとテスト 最後のフェーズでは、生成されたマイクロサービスを、さまざまなコンピューティングオプションとストレージオプションを使用して AWS クラウドネイティブアーキテクチャにデプロイします。お客様は、コンピューティングサービスとして Amazon Elastic Container Service (ECS)、Amazon Elastic Kubernetes Service (EKS)、AWS Lambda、AWS Fargate の中から選択できます。データベースオプションには、NoSQL ワークロード用の Amazon DynamoDB、リレーショナルデータベース用の Amazon Aurora、またはその他の AWS データベースサービスが含まれます。デプロイでは、AWS CloudFormation、AWS Cloud Development Kit (CDK)、Terraform などの Infrastructure as Code ツールを使って AWS リソースのモデル化とプロビジョニングを行います。 以下は、AWS CloudFormation テンプレートを使って新しいマイクロサービスアーキテクチャを AWS クラウドにデプロイするように生成された Infrastructure as Code のサンプルです。 生成された Infrastructure-as-Code の例 再構想 (reimagine) された新しいアプリケーションは、この新しい AWS クラウドネイティブアーキテクチャでテストされ、すべてのコンポーネントが期待どおりに動作することを検証します。 以下の図は、新しく作り直されたアプリケーションをデプロイするための一般的な AWS クラウドネイティブアーキテクチャを示しています。 新しく reimagine されたアプリケーションのデプロイとテスト Reimagine パターンのための AI 駆動アプローチの主な利点 ディスカバリーと分析の加速 AWS Transform の AI エージェントは、複雑な COBOL コードベースを数時間または数日で分析し、アプリケーションドメインとビジネスロジックパターンを自動的に識別できます。組織はメインフレーム環境全体を分析するか、もしくは、特定のビジネスプロセスを対象として分析するか、選択することができます。 インテリジェントなマイクロサービス設計 AI を活用したアプローチでは、ドメイン駆動設計 (Domain-Driven Design: DDD) の原則を適用して、レガシーアプリケーション内の自然な境界のあるコンテキストを識別します。DDD は、中核となるビジネスドメインの理解、技術チームとビジネスチームの間に共通のユビキタス言語の構築、複雑なドメインを明確に境界付けられたコンテキストに分割することに重点を置いています。 高品質なコード生成 Kiro は、適切な階層型アーキテクチャ、REST API 設計、クラウドネイティブパターンなど、最新の開発標準に従った、本番環境に対応したマイクロサービスを生成します。 Infrastructure as Code このアプローチでは、アプリケーションコードと、マイクロサービスを AWS クラウドにデプロイして実行するために必要なインフラストラクチャ全体の両方が生成されます。さらに、この Infrastructure as Code アプローチは AWS Well-Architected Framework の原則に沿ったものであり、自動化され繰り返し可能なデプロイによって運用上の卓越性を促進し、生成されたすべてのインフラストラクチャコンポーネントにセキュリティ、信頼性、パフォーマンス効率、コスト最適化、ベストプラクティスを一貫して適用できるようにしています。 AWS メインフレームモダナイゼーションの専門知識とパートナーエコシステム メインフレームアプリケーションを reimagine するための AWS のアプローチは、AWS の AI 駆動の機能を活用し、パートナーの専門知識とスケールを補完するものです。AWS は、Global System Integrators (GSI) と専門技術パートナーの専門知識を組み合わせて、メインフレームモダナイゼーションプロジェクトに内在する複雑さに対処する強固なパートナーエコシステムを構築しました。 GSI パートナーは、さまざまな業界の大規模なメインフレームモダナイゼーションで成功を収めていることが実証済です。 AWS の戦略は、データ移行ユーティリティ、テストフレームワーク、言語変換ツールなどの AWS ネイティブ機能を補完する専用のモダナイゼーションツールを提供するテクノロジーパートナーに依存しています。 このような協業アプローチにより、お客様は AWS のクラウドネイティブ機能を活用しながら、複雑なモダナイゼーションの課題に対応する専門知識と実証済の方法論を活用できます。 まとめ AWS がメインフレームモダナイゼーションを再構想 (reimagine) するために進めているのは、お客様のトランスフォーメーションジャーニーを加速させる包括的な AI 駆動のアプローチです。AWS Transform は、レガシーソースコードに対する深い理解と柔軟なコード生成を組み合わせることで、組織がリスクを最小限に抑え、ビジネス価値を最大化しながらメインフレームアプリケーションを変革できるようにします。 メインフレーム向けの AWS Transform と Kiro に関するその他の参考情報 インタラクティブデモを試す AWS Transform for mainframe の詳細 入門ガイドを読む メインフレームから AWS への移行途中の過渡期に於ける両環境併存のための連携アーキテクチャ メインフレームアプリケーションのモダナイゼーションに関する包括的な視点と配置戦略 著者 Yann Kindelberger Yann Kindelberger は、Amazon Web Services の Principal Solution Architect です。Yann は 23 年以上メインフレームに携わり、IBM で 20 年以上メインフレームアーキテクトとして勤務しました。彼はメインフレームの AWS クラウドへの移行とモダナイゼーションに取り組んでいるワールドワイドなチームの一員です。彼は 2021 年に AWS に入社し、ソリューションアーキテクトとして、お客様のメインフレームの移行とモダナイゼーションを支援し、助言し、サポートしています。 Cheryl du Preez Cheryl du Preez は、メインフレームとレガシーモダナイゼーションに関する AWS の World Wide Senior Specialist Solutions Architect です。Cheryl は、世界中のお客様を対象としたメインフレームのモダナイゼーションとトランスフォーメーションの取り組みにおいて、20 年以上にわたって技術的リーダーシップを発揮してきました。現在の役職では、AWS 独自の方法で生成 AI を活用したメインフレームのモダナイゼーションについて、お客様やパートナーに対して助言を提供しています。 Chris Poole Chris は Senior Partner Solutions Architect であり、メインフレームモダナイゼーションが大好きです! 彼は現在、EMEA 地域の AWS メインフレームパートナー戦略を推進していますが、以前はエッジコンピューティングテクノロジーに取り組む Principal Engineer の称号を持っていました。当時は、コミュニティや開発者支援の取り組みをリードし、クラウドセキュリティ製品のソリューションアーキテクトチームを率いたり、高スループットの金融取引処理システムにおける非同期 API を設計/開発したりしてきました。彼は理論物理学の博士号を取得しています。余暇には、香取神道流の武道やカリ (Kali) 等の格闘技を楽しんでいます。 Rao Panchomarthi グローバルのメインフレームモダナイゼーション組織のリーダー。Rao は、IBM メインフレーム、分散システム、クラウドテクノロジーにまたがる 20 年以上の経験を持つ経験豊富な IT プロフェッショナルです。Rao は大規模なビジネストランスフォーメーションをリードし、メインフレームアプリケーションのクラウドテクノロジーへの移行や、モダナイズするための戦略を策定しています。AWS に入社する前は、JPMorgan Chase のクレジットカード事業でアーキテクチャ責任者を務め、複数のトランスフォーメーションプロジェクトをリードしていました。 Souma Suvra Ghosh Souma は AWS でメインフレームモダナイゼーションを担当する Senior Specialist Solutions Architect です。AWS へのモダナイゼーションに関する複数の記事やソリューションガイドを発表し、AWS re:Invent や AWS Summit などのカンファレンスで発表を行ってきました。現在の役職では、メインフレームとレガシーシステムのモダナイゼーションに AWS のバリュープロポジションと生成 AI 機能を最大限に活用する方法について、お客様やパートナーに助言しています。 Subhajit Maitra Subhajit は AWS の Worldwide Mainframe Partner Solution Architect であり、メインフレームモダナイゼーションコンピテンシープログラムの構築を支援しました。また、IBM MQ 連携に寄与する AWS Mainframe Modernization サービスのビルダーでもあります。彼の専門分野には、メインフレームモダナイゼーション、メッセージ指向ミドルウェア、分散型イベントストリーミングプラットフォーム、マイクロサービスなどがあります。 この投稿の翻訳は Mainframe Modernization Specialist Solutions Architect の皆川が担当致しました。原文記事は こちら です。
こんにちは、LuupのUser Product Group Backend Teamのバックエンドエンジニア、Jang(チャン)です。 「成功しても何も起きない」が正しい結果になる仕事、というものがあります。追加38,000行・削除13,000行におよぶレガシー移行を、外部から観測できる動作に未承認の差分を1つも作らずにやり切る。今回Claude Codeと一緒に取り組んだのは、そういうプロジェクトでした。この記事は、その1か月の記録です。うまくいったことだけでなく、AIエージェントに足をすくわれかけたことも含めて書きます。 TL;DR 課題: あるドメインのコードがDDD Modu
はじめに こんにちは、RevComm AI Div. の id:tmotegi です。 RevComm では Copilot ・要約・コーチングなど、LLM を活用した機能が急速に増えています。当初は1〜2つのサービスが LLM を直接呼び出すだけでしたが、新機能のリリースと並行して利用するプロバイダーも広がり、気づけば各サービスが個別に Claude(Bedrock)、OpenAI(Azure)を呼び出す構成になっていました。 しばらくはそれでも回っていましたが、LLM を利用するチームが増え、利用するモデルやプロバイダーも広がるにつれ、いくつかの問題が表面化してきました。 クォータ・レートリミット対応がサービスごとに分散 ─ 以前はクォータの上限が低く、サービスごとに複数アカウントを作成してレートリミットを回避していました。レートリミットに引っかからないよう、各チームが個別にリトライや切り替え処理を書いており、同じエラーハンドリングコードが各所に散在していました。 新モデル対応のコストが高い ─ 新しいモデルが出るたびに、複数サービスでクライアントコードやモデル名を個別に更新する必要がありました。 コストの内訳が見えない ─ 「どの機能が、どのテナントで、どのモデルをどれくらい使っているか」がプロバイダーをまたいで把握できず、プロバイダーの請求書を見ても機能別・テナント別の内訳がわかりませんでした。コスト増の原因を特定するだけで時間がかかっていました。 国内処理の適用漏れリスク ─ 顧客要件でデータを国外に出せない機能では、利用できるモデルが制限されます。その制約を各サービスで個別に管理していたため、適用漏れが起きる潜在的なリスクがありました。 これらを解決するために、社内の LLM 呼び出しを一本化する LLM Gateway を開発しました。 目的は大きく2つです。 マルチプロバイダーの統一 ─ 単一インターフェイスで Bedrock / Azure OpenAI / Vertex AI を透過的に扱い、クライアント側のコードを変えずにモデルを切り替えられるようにすること。 コストの可視化 ─ リクエストごとの利用状況を記録し、テナント・機能・モデル別にコストを集計できるようにすること。 最初から自分たちで実装すると決めていたわけではありません。まずは既製の LiteLLM Proxy Server をそのまま使うことを検討し、最終的に litellm をライブラリとして使って自分たちで実装する形に落ち着きました。 なぜ LiteLLM Proxy Server を最初の選択肢にしたのか? LLM Gateway の構築を決めたとき、まず検討したのは LiteLLM Proxy Server です。100 以上のプロバイダーを OpenAI API 互換の単一エンドポイントで束ねる OSS で、フォールバック制御・コスト追跡・Observability 連携が標準で揃っています。 はてな や 弁護士ドットコム など、国内企業の技術ブログでも導入事例が多く公開されており、LLM Gateway が必要になった企業が最初に検討する選択肢です。 LiteLLM Proxy Server が標準で持つ機能は非常に充実しています。 OpenAI API 互換エンドポイント(既存の OpenAI クライアントを向き先だけ変えてそのまま使える) 複数プロバイダーへのルーティングとロードバランシング リクエストボディで fallbacks フィールドを指定するフォールバック制御 コスト追跡・予算管理(モデルごとのトークン単価を設定しコストを自動計算) Langfuse、Datadog などの Observability 連携 特に「リクエストにフォールバック順序を書ける」機能は、私たちが必要としていた要件と重なっていました。 { " model ": " claude-sonnet-4 ", " messages ": [ ... ] , " fallbacks ": [ " gpt-4o ", " gemini-2.0-flash " ] } クライアントがフォールバック順序をリクエストに含めて送るだけで、LiteLLM Proxy Server 側がエラー時に次のモデルへ切り替えてくれます。導入するだけで多くの機能が手に入り、運用面の作り込みも不要になる魅力的な選択肢でした。 なぜ自分たちで実装したのか 「国内処理の制約」と「フォールバック戦略」を連動させる複雑なルーティングロジックを、LiteLLM Proxy Server の async_pre_call_hook などのフック処理内に無理に詰め込みたくなかった、というのが大きな理由です。 LiteLLM Proxy Server には async_pre_call_hook でリクエストを受け取り、 data["model"] を書き換えることで動的なルーティングを実現するカスタムハンドラーがあります。私たちの要件もこれで実装できます。ただし私たちのルーティングには、単純なモデル切り替えにとどまらない要件が重なっていました。 リクエスト単位で国内処理を強制できる ─ 特定のリクエストは日本国内リージョンで動作するモデルのみ使用する フォールバック先も国内リージョンのモデルに限定する ─ 国内処理が必要なリクエストがフォールバックしても、海外リージョンには流れない クライアントがフォールバック順序を指定できる ─ 「まず Claude、だめなら OpenAI」という優先順位をリクエストに書ける 要件1だけなら async_pre_call_hook でモデルを国内リージョンのものに差し替えれば済みます。要件3だけなら LiteLLM Proxy Server 標準の fallbacks フィールドをそのまま使えます。問題は1・2・3の 組み合わせ です。「国内処理を要求しつつ、かつクライアント指定の優先順位でフォールバックし、かつフォールバック先も国内に限定する」という連動した制御は、カスタムハンドラーとフォールバック機構をまたいだロジックになります。 async_pre_call_hook はシンプルなモデル切り替えやロギングには向いていますが、複数の制約を連動させるルーティングには向きません。そこで、この部分は専用のロジックとして自前で持つことにしました。 なお、LiteLLM Proxy Server は litellm という Python ライブラリをベースに作られており、litellm は単体でもライブラリとして利用できます。そこで Proxy Server は使わず、 litellm をプロバイダー抽象化のライブラリとして使い、ビジネスロジックは自分たちで設計・実装する 方が長期的な見通しが良いと判断し、自分たちで実装することを選びました。 litellm をどのようにライブラリとして組み込んだか? EKS 上の LLM Gateway アーキテクチャ図 FastAPI ベースの Python サービスとして実装し、DDD のレイヤー構成を採用しています。 litellm はインフラストラクチャ層の LLMClient クラス内だけで使い、ドメイン層はどのプロバイダーを使っているかを知りません。Bedrock / Azure OpenAI / Vertex AI の 3 プロバイダーに対応しながらも、上位レイヤーのビジネスロジックはプロバイダーの違いを意識せずに済みます。 class LLMClient: async def create_completion( self, deployment: ModelDeployment, request: ChatCompletionRequest ) -> ChatCompletion: response = await litellm.acompletion(model=model_string, ...) return ChatCompletion.model_validate(response.model_dump()) litellm が担うのは「Bedrock / Azure / Vertex AI の差異を吸収する HTTP クライアント」という役割だけです。各プロバイダーは認証方式と API の形式が異なりますが、litellm がその差異を吸収します。 フォールバックの判断やモデル選択といったルーティングロジックは、すべて自分たちのドメイン層に置いています。レイヤーを分けることでプロバイダーへの依存がコードベース全体に広がるのを防ぎ、ルーティングロジックの単体テストも書きやすくなりました。 設計で工夫したこと ① フォールバック戦略をクライアントが選べるようにする フォールバック戦略は auto / specified / none の 3 種類から、リクエストごとに revcomm_options.fallback_strategy で指定します。処理の特性に合わせて可用性・品質・エラー伝播の挙動を選べるようにした設計です。 戦略 動作 使いどころ auto 同一モデルの別リージョン・別アカウントに自動でフォールバック とにかく止めたくない処理 specified クライアントが指定した順番でフォールバック モデルの品質差が許容できない処理 none フォールバックしない(エラーをそのまま返す) ─ auto は可用性を優先するモードです。あるアカウントの Bedrock がレートリミットに引っかかった場合、同一モデルを提供する別アカウント・別リージョンのデプロイメントへ自動で切り替えます。国内処理を要求しているリクエストでは、切り替え先も国内処理に対応したデプロイメントに限定されます。 specified はクライアントが「まず Claude、だめなら OpenAI」という形で優先順位を明示するモードです。出力品質に敏感な処理では、意図しない品質の異なるモデルへの切り替えを避けたいためこちらを使います。 none はエラーをそのまま返します。 なお、フォールバックが発動するのは、レートリミットやタイムアウト・サーバーエラーなどの一時的なエラーに限られています。リクエスト内容の不備(不正なパラメータ、コンテキストウィンドウ超過など)ではフォールバックせず、そのままエラーを返します。意図しないモデルへの切り替えが起きるリスクを抑えるためです。 国内処理を要求するリクエストでは、フォールバック先も国内リージョンのモデルに絞られます。国内制約とフォールバック順序が連動して動く部分です。 ② データが国内で処理されることを保証する 顧客との契約でデータの国内処理が義務付けられているケースでは、一つでも適用漏れがあるとビジネスリスクになります。LLM Gateway ではモデル設定に国内・グローバルのフラグを持たせ、ゲートウェイがリクエスト単位で国内処理を強制します。この判断をアプリケーション側に委ねず、ゲートウェイで一元管理する設計です。 モデルごとのリージョン・プロバイダー設定は YAML で管理しています。 gateway_region: ap-northeast-1 deployments: - model_name: claude-sonnet-4 provider: bedrock region_scope: regional # 国内リージョン region: ap-northeast-1 - model_name: gpt-4o provider: azure region_scope: global # グローバルリージョン region: japaneast region_scope: regional のモデルが「国内処理」として扱われます。リクエストで国内処理を要求した場合、ゲートウェイが該当するモデルを選択します。 この設計の利点は、国内処理の判定ロジックがゲートウェイ内に閉じていることです。新しいモデルを追加するときも、YAML に region_scope を適切に設定するだけで国内処理の制約が適用されます。環境ごとの設定差分は別ファイルで管理しているため、呼び出し元のサービスは環境を意識せず同じリクエストを送るだけで済みます。 ③ モデルを切り替えても呼び出し元のコードを変えずに済むようにする ゲートウェイは OpenAI Chat Completions API 互換のインターフェースを提供しています。既存の OpenAI クライアントはエンドポイントの向き先を変えるだけで移行でき、モデルを切り替えるときも model フィールドの値を変えるだけです。RevComm 固有の制御は revcomm_options フィールドに集約しています。OpenAI クライアントからは extra_body={"revcomm_options": {...}} として渡すため、標準 API との後方互換性を維持しています。 { " model ": " claude-sonnet-4 ", " messages ": [ ... ] , " revcomm_options ": { " require_domestic_processing ": true , " prefer_prompt_caching ": true , " fallback_strategy ": " specified ", " fallback_models ": [ " gpt-4o ", " gemini-2.0-flash " ] , " labels ": { " tenant_id ": " tenant-123 ", " service ": " transcription ", " team ": " asr " } } } オプションを省略すれば通常の OpenAI API リクエストとほぼ同じ形式です。 レスポンスには revcomm_metadata を付与し、実際に使ったプロバイダーやフォールバックの発生有無を呼び出し元に返します。 { " revcomm_metadata ": { " actual_provider ": " bedrock ", " actual_model ": " claude-sonnet-4 ", " fallback_used ": true , " fallback_reason ": " RateLimitError: ... ", " gateway_latency_ms ": 42 , " domestic_processing ": true } } フォールバックが透過的に起きると、呼び出し元からは「なぜこのモデルが使われたのか」が見えなくなります。メタデータをレスポンスに含めることで、デバッグ時にフォールバックの発生をすぐに確認でき、コスト分析にも活用できます。フォールバックが頻発している場合は、特定のプロバイダーや時間帯に問題がある兆候として検知できます。 ④ 誰がどのモデルをどれだけ使っているかを把握できるようにする LLM Gateway のもうひとつの柱がコストの可視化です。LiteLLM Proxy Server には Cost Tracking 機能が標準で備わっていますが、litellm をライブラリとして使う場合はリクエストごとのコスト計算値は得られるものの、保存・集計・可視化は自前で用意する必要があります。リクエストごとのトークン数・プロバイダー・モデル・レイテンシを PostgreSQL に記録し、Redash でテナント別・機能別に可視化しています。ロギングはレスポンスを返した後にバックグラウンドで行うため、ゲートウェイのレイテンシには影響しません。 labels は JSONB カラムで、リクエスト時にオプションとして渡したキーバリューをそのまま保存します。JSONB にしているのは、ラベルのキーをあらかじめ固定せず、各サービスが必要なディメンションを自由に付与できるようにするためです。 SELECT labels->> ' tenant_id ' AS tenant_id, actual_model, SUM (total_tokens) AS total_tokens FROM llm_usage_logs WHERE created_at >= now() - INTERVAL ' 30 days ' GROUP BY labels->> ' tenant_id ' , actual_model ORDER BY total_tokens DESC ; テナント別・サービス別・チーム別など、集計軸をスキーマ変更なしに追加できます。「新しいチームが使い始めたのでチーム別集計を出したい」という要望があれば、そのチームが team ラベルをリクエストに含めるだけで対応できます。テーブル定義の変更もマイグレーションも不要です。 各サービスは推論リクエスト時に tenant_id や service をラベルとして渡すだけで、コスト集計の基盤が整います。プロバイダーの請求書を見ていてもわからなかった「どのテナントの、どの機能が、どのモデルをどれくらい使っているか」が一本のクエリで出せるようになりました。 テナント別・機能別コストを可視化するアナリティクスダッシュボードのイメージ 振り返って LiteLLM Proxy Server のカスタムハンドラーでも、技術的には実現できたはずです。ルーティングロジックとラベル集計を自社のドメインロジックとして持ったことで、要件の変化にコードで素直に対応できています。 フォールバックロジックとモデル選択ロジックを外部依存のない純粋な Python クラスで実装したため、単体テストも書きやすくなりました。「国内処理を要求した場合に region_scope: global のモデルは候補から除外される」「フォールバック戦略が none のときはエラーがそのまま伝播する」といったロジックを、LiteLLM Proxy Server を起動せずにテストできます。 一方で、コスト管理 UI や API キーのセルフサービス発行など、LiteLLM Proxy Server が標準で持つ運用機能は自前で用意する必要がありました。現時点では、コスト集計は Redash のダッシュボードで対応していますが、API キーのセルフサービス発行など長期的には整備が必要な領域もあります。 カスタム性が単純なうちは LiteLLM Proxy Server で十分です。 まとめ 各サービスに分散していた LLM 呼び出しを一本化するため、マルチプロバイダー統一とコスト可視化を目的に社内 LLM Gateway を開発しました LiteLLM Proxy Server を検討しましたが、国内処理制約 × フォールバック戦略の連動が設計想定外になるため、自分たちで実装することにしました litellm はプロバイダー抽象化のライブラリとして使い、ルーティングロジックは自分たちのドメインとして設計しました リクエストに付与する labels(テナント ID・サービス名など)を PostgreSQL の JSONB カラムに記録することで、スキーマを変えずに集計軸を追加できるようにしました





















