メニューボタン
IBMiコラム2025.10.22

IBM i のウンチクを語ろう:その112
- IBM watsonx Code Assistant for i ベータ版に触ってみた -

安井 賢克 著

皆さん、こんにちは。IBM i のプログラミングにおける今年最大の革新と言えば、Graniteと呼ばれるIBM独自のLLM(大規模言語モデル)による生成AIとの融合、すなわちIBM watsonx Code Assistant for i (以降WCA4i)の登場ではないしょうか。当コラムを執筆している9月末時点では公式発表されていませんが、IBMは昨年10月にWCA4iの当時の仮称である「code assistant for RPG」プロジェクトを進める旨を表明しました。そして私の知る限りその予定登場時期は2025年10-12月期であり、それを目指して8月初めにベータ・プログラムが開始されています。

IBMはプロジェクトの公表以来、LLMをトレーニングするために、実用化されているRPGソースコードを提供するよう広くユーザーの協力を仰いだり、フィードバックを受けて品質向上を図るために、GA前にアルファ版・ベータ版を利用可能にするなどして準備を進めています。読者の中にも既に何らかの関わりを持っている方がいらっしゃるかもしれませんね。かく言う私もプログラミングの経験もスキルも欠落していることを棚に上げ、ただ単に先進的で面白そう、というだけでベータ版を利用するべく手を挙げた一人です。今回コラムの目的は、そのWCA4i ベータ版を利用してみた感触をお伝えしようというものです。なお、機能や品質などは私が試した時点のものであり、正式版においては大きく改善される可能性があることはご承知おきください。

現在は生成AIブームの渦中にあるとは言っても、IBM i のコミュニティにとっては全く新しい製品です。簡単に使えるのか、効果はあるのか、といったところが主な関心事ではないかと思います。結論から言いますと、VS CodeのインストールとIBM i への接続ができていれば、日常的に製品に触れることを生業としていない私でも、構成・設定するのにあまり苦労することはありませんでしたし、得られる結果も結構役に立ちそうだといった感触を持っています。ただ詳細は後で述べますが、日本語を利用しようとすると一部手間がかかるケースがありました。

WCA4iの狙いはどこにあるのかを確認しておきましょう。プログラミングにおける生成AIと聞くと、普通の日本語で書かれた文章に基づいて、ソースコードを自動生成してくれる機能を想起しがちですが、実際にはそれだけではない様々な局面があります。すなわち既存のプログラムを理解する、機能強化のために既存プログラムを改修する、品質向上のためのテスト・プログラムを開発する、テクノロジー刷新のために既存プログラムを変換する、といったようなものです。プログラムは開発したらそれで終わりというわけにはいかないものですよね。そして2025年内にGAを迎えようとしているのは、既存プログラムを説明してくれる機能であり、以降は随時機能強化が図られる予定だと聞いています。

随時というのは、WCA4iはIBM i の機能には直接依存しないので、機能強化のサイクルはIBM i の新バージョンとかTRリリースのタイミングとは必ずしも同期しないということです。WCA4iがユニークなのは、開発部門はLLMをトレーニングして品質を確認し、これならばといったレベルに達したらGAを迎える、といった具合にプロジェクトを進めようとしている点です。機能強化計画があったとしても、どのような学習をどれだけの量こなせば合格ラインに達する、といった見極めが手探り状態にあるからなのかもしれません。

WCA4iは厳密には、マイクロソフト社が開発・提供する、クライアント上の無償開発ツール「VS Code」用の拡張機能です。SSH経由でVS Codeから自社のIBM i に接続できる環境を用意して、あらかじめCode for IBM i を含むもう一つの拡張機能「IBM i Development Pack」をインストールし利用可能な状態にします。この段階でRPGプログラミングやDb2 for i へのアクセスが可能になります。社外に出られるネットワーク環境があれば、さらにWCA4i拡張機能を追加インストールすることで、RPGプログラミングのトレーニングを受けたGraniteに接続されます。これで準備作業は済むのですが、もしかしたらVS CodeのSSH接続に苦労される方がいらっしゃるかもしれません。

日本の多くのお客様システムにおいては、言語環境を決定するシステム値QCCSID=65535に手を入れないまま、日本語モジュールがインストールされています。これだとどうもSSHが機能しないので、CHGUSRPRFコマンドによって、ユーザー・プロファイルの中のCCSIDを5035か1399に変更しておく必要があります。こうすることで当該ユーザーが起動するジョブ環境は英語環境と互換性が維持されるため、問題無くSSHを利用できるようになります。

では実際のプログラムを対象に、最初に公式登場するとされているRPGプログラムの説明機能を試してみましょう。どれでも良いのですが、サンプルとしてGithubに一般公開されているフリーフォームの RPGプログラム「BPL020@YU2.RPGLE」を適当に選んでみました。関連するモジュール一式のライブラリは「IBMCJ-2023-C06/020-FF_RPG_samples」にSAVF形式で公開されてますので、必要な方はダウンロードいただくことができます。私もQiita上のガイドにしたがってQEOLFFライブラリを作成しました。

なおVS CodeやCode for IBM i の設定に関しては、iWorldサイトの「VS CodeでIBM i エンジニア人生を楽しくしよう」などが参考になると思います。ついでながらダウンロード用ライブラリ全体の解説は、「IBM CJ 2023 C06-020 FF-RPGサンプルコード Indexページ」にあります。

VS Codeの「OBJECT BROWSER」内「BPL020@YU2.RPGLE」でマウスを右クリックすると、「watsonx Code Assistant for i」内で、「Summarize Member」すなわちメンバーの要約と、「Explain Member」すなわちメンバーの詳細説明の二つが選択可能になります。以下は前者の要約機能を使ってみた結果です。

>>> 引用ここから
This ILE RPG program retrieves data from two files, "JUMIDL01" and "TOKMSP," and generates a report with customer details, order information, and totals. The report includes headers, itemized details, and a summary of the total records and total sales amount. It handles overflow conditions and ensures accurate printing of data.
<<< 引用ここまで

これでも十分という方もいらっしゃるかもしれませんが、ここで「日本語でお願い」と入力してみます。

>>> 引用ここから
このRPGプログラムは、2つのファイルからデータを取得し、受注詳細を印刷します。プログラムは、受注見出し、明細、および合計を含むレポートを生成します。オーバーフローを処理し、印刷処理を制御するためのフラグを使用します。また、レポートの合計を計算し、レポートの最後に出力します。
<<< 引用ここまで

実際にソースコードと対比してみると概ね正しいようです。ただ日本語化すると、具体的な二つのデータベース・ファイル名が欠落するなど、細かな点が省略されています。必要であれば英文をコピーして翻訳ソフトを使えば良さそうです。

回答は長くなりますが、Explainすなわち詳細説明を求めてみます。一度日本語でやり取りしたにも関わらず、英文になってしまいましたが、メインを含めて各サブルーチンについてもそれなりに細かく説明されています。内容は概ね正しいようです。なお、所々茶色文字になっているのは、VS Code出力をマークダウン記法でコピーしたものを、単純にWORD文書に変換したことによるものです。変数名がハイライトされるので読み取り易くなっています。

>>> ここから引用
1. Purpose
The purpose of this RPG program is to generate a report of customer orders, including details such as customer number, order number, date, amount, and total sales. The report includes a header, detail lines for each order, and a summary at the end.
2. Main Execution Flow
Main Logic
  1. Initialize variables and system timestamp:
    • Set the system timestamp to WTIMESTAMP.
    • Extract the date and time components into WDATE8 and WTIME6.
    • Initialize counters and flags, such as W#CNTP (number of printed records) and W#FG_OF (overflow indicator).
    • Clear the print files PHEAD1 and PITEM1.
  2. Process each record from the JUMIDL01 file (customer order detail file):
    • Perform a SETLL operation to position at the beginning of the file.
    • Enter a loop that continues until the end of file is reached.
    • Read a record from JUMIDL01.
    • If the end of file is encountered, exit the loop.
    • Call the @PITEM1 subroutine to process the current order detail.
  3. Print the header if necessary:
    • Check if W#CNTP is zero (no records processed).
    • If true, call the @PHEAD1 subroutine to print the header.
  4. Print the total:
    • Call the @PTOTAL1 subroutine to calculate and print the totals.
  5. End processing:
    • Set the *INLR indicator to *ON to indicate program termination.
    • Return control to the calling program.
Subroutine Breakdown
• @INZ (Initialization)
  Sets the system timestamp and extracts date and time components.
  Initializes variables and flags.
  Clears print files PHEAD1 and PITEM1.

(注: 以降の各サブルーチン毎の説明は省略)
This RPG program demonstrates basic file operations, conditional logic, looping, and subroutine invocation. It reads records from one file, processes them, and generates a formatted report with headers, details, and totals. The use of indicators like W#FG_OF manages overflow conditions during printing. The program structure follows a clear main routine with distinct subroutines for initialization, header printing, detail printing, total calculation, and termination.
<<< 引用ここまで

しぶとく再び「日本語でお願い」と頼んでみたら、詳細情報が無くなってしまいました。

>>> 引用ここから
このRPGプログラムは、受注詳細を印刷するレポートを生成します。プログラムは、受注見出し、明細、および合計を含むレポートを印刷します。オーバーフローを処理し、印刷処理を制御するためのフラグを使用し、レポートの合計を計算します。
<<< 引用ここまで

願わくは日本語においても一発で英文回答と同様のものを得たいところです。開発部門に投げ掛けたら、不便であることは承知しているが現時点における制約との回答が返ってきました。取り敢えず課題としては認識されたので今後に期待したいと思います。

少し突っ込んでみましょう。「BPL020@YU2.RPGLEプログラムで受注金額の合計を扱っている変数は何ですか」と投げ掛けたら、以下の回答が得られました。正しい答えが返ってきています。ただ丁寧なのはわかりますが、聞いてもいない平均についても答えているので少々戸惑いました。

>>> 引用ここから
BPL020@YU2.RPGLE プログラムでは、受注金額の合計を扱う変数は、PT1GOKEIPT1HEIKIN です。PT1GOKEI は、受注金額の合計を蓄積する変数で、@PTOTAL1 サブルーチンで計算されます。PT1HEIKIN は、受注金額の平均値を計算するために使用され、レポートの合計部分に出力されます。
<<< 引用ここまで

ついでにもう一つ。「オーバーフロー」という言葉が目立ったので、この標識がONになる条件を聞いてみます。なるほど、という感じですね。明細80行毎に改ページする、というフォーマットになっていることがうかがえます。ただ日本語に少々違和感がありますね。最初の文章の「・・・ONになった時は」は「・・・ONになるのは」にした方が自然です。想像するに後続部分の「・・・達したときです。」が過去形に見えるので、時制を合わせようという意図が働いたのでしょうか。本当は過去形ではないのですが、日本語の難しさを感じますね。

>>> 引用ここから
BPL020@YU2.RPGLE プログラムでは、オーバーフロー標識がONになった時は、印刷行の数が80に達したときです。この状況を検知するため、プログラムはオーバーフローインジケータ(*IN(80))を使用し、オーバーフローが発生した場合に印刷処理を停止させます。また、W#FG_OFというフラグを使用し、オーバーフローが発生した際にこのフラグをONに設定します。このフラグは、印刷処理の中でも確認できます。
<<< 引用ここまで

各サブルーチンについては、C仕様書相当の前に自動的に「Summarize / Explain / Usage / Document」という選択メニューが追加されます。ここから比較的長い@PITEM1ルーチンの詳細説明(Explain)を求めると、順を追って結構細かく説明してくれます。

>>> 引用ここから 1. Purpose
The subroutine @PITEM1 processes order header details and prints them out when certain conditions are met. It retrieves data related to the customer order, populates printing fields, and updates counters.
2. Main Execution Flow
Step-by-step explanation:
  6. Initialization: The subroutine begins by checking if the indicator W#FG_OF is turned on. If it is, it calls another subroutine @PHEAD1, presumably for printing headers.

IF W#FG_OF  = *ON       ;
EXSR @PHEAD1                               ;
ENDIF                   ;
  7. Clear Print Record: It clears the print record structure PITEM1 to prepare for new data.
CLEAR PITEM1                                    ;
  8. Assign Customer Details: It assigns values from the input record JUMIDR to corresponding output fields in PITEM1:
    • Customer Number (JHTOKB):
PI1JHTOKB  =  JHTOKB                            ;
    • Customer Name (in Japanese): It attempts to fetch the name from TOKMSR using JHTOKB as the key. If found, it populates PI1TKNAKJ; otherwise, it sets it to asterisks.
TOKMSKEY1.TKBANG     = JHTOKB          ;
CHAIN %KDS(TOKMSKEY1   ) TOKMSR        ;
IF %FOUND              ;
PI1TKNAKJ  =  TKNAKJ                          ;
ELSE                   ;
PI1TKNAKJ  =  *ALL'*'                         ;
ENDIF                  ;
  9. Assign Order Details: It copies additional order-related fields to the print record.
    • Order Number (JHCHUB):
PI1JHCHUB  =  JHCHUB                            ;
    • Number of Lines (JHGYOS):
PI1JHGYOS  =  JHGYOS                            ;
    • Order Amount (JHKING):
PI1JHKING  =  JHKING                            ;
  10. Print Record: It writes the populated print record PITEM1 to the output.
WRITE PITEM1                                    ;
  11. Update Counters: It increments the print counter W#CNTP and updates the total records printed PT1KENSU, as well as the accumulated order amount PT1GOKEI.
W#CNTP  += 1                                    ;
PT1KENSU   =  W#CNTP                            ;
PT1GOKEI  +=  JHKING                            ;
  12. End of Subroutine: The subroutine ends with the ENDSR statement, marking the conclusion of its execution.
ENDSR                                       ;
Indicators:
W#FG_OF: Controls whether header printing occurs.
%FOUND: Indicates success in finding the customer name in TOKMSR.
This subroutine systematically processes order header data, enhances it with additional information, and prepares it for printing, managing counters for tracking progress.
<<< 引用ここまで

さらに各行の説明を求めることも可能でした。きりが無いので今回はこのあたりでまとめておきましょう。

日本語環境においては少々手間がかかる可能性があるとか、もしかしたら言及するべきポイントが詳細説明から欠落している、といった指摘もあるのかもしれません。ベータ版ではあっても、プログラム保守の生産性向上という観点から眺めた時、まずはWCA4iを活かして全貌を把握して、それから詳細を見てゆく、というやり方が十分に通用するのではないでしょうか。少なくともまっさらな状態からソースプログラムに取り組むよりも、はるかに生産性が高くなるに違いありません。結果的にRPGプログラミングにおける人材・後継者不足の解消にもつながるはずですね。

ではまた

あわせて読みたい記事

サイト内全文検索

著者プロフィール

パワーシステム・エバンジェリスト

安井 賢克
やすい まさかつ

2017 年 11 月付けで、日本アイ・ビー・エム株式会社パワーシステム製品企画より、ベル・データ株式会社東日本サービス統括部に転籍。日本アイ・ビー・エム在籍時はエバンジェリストとして、IBM i とパワーシステムの優位性をお客様やビジネス・パートナー様に訴求する活動を行うと共に、大学非常勤講師や社会人大学院客員教授として、IT とビジネスの関わり合いを論じる講座を担当しました。ベル・データ移籍後は、エバンジェリストとしての活動を継続しながら、同社のビジネス力強化にも取り組んでいます。

PAGE TOP