Sweet Talking the Bot: Adventures in AI-Assisted Coding on IBM i
IBM i consultant Rick Flagler shares his experience using generative AI as a coding assistant, including a case study involving EDI
You can’t turn on the TV, your email or a web browser, without hearing something about AI. Artificial Intelligence was one of the most popular topics in 2025. For 2026, it appears, matters will be no different.
IBM i developers have a number of choices to employ AI in their day-to-day activities. There is OpenAI’s ChatGPT, GitHub’s Copilot, which is integrated into Visual Studio Code (VS Code), and Google’s Gemini, which responds to browser searches. I’ve made use of ChatGPT and Google searches over the past year and more recently experimented with Copilot while editing in Code for i.
I’ve found that I can ask my Google browser window almost any question about coding and get some sort of response. That’s pretty good. The results are often accompanied by a “deeper dive in AI” button that allows further drill-down into the topic. Code examples for many languages can be obtained in this way and are often accurate but not perfect, requiring some tweaking to achieve desired results.
The questions I ask are usually centered around syntax for SQL, CLLE or RPGLE free form, which are my primary programming languages. The bots, as I call them, are quite responsive, but in the past, returned RPG in fixed format. Now luckily, tools appear to have learned modern free-format RPGLE.
An Iterative Approach
When you “speak” to these bots, you have to be specific in what you say or type in order to get the best responses. Furthermore, if you don’t get the response you want on the first try, you can generally say something like, “No that’s not what I meant; please do it again and ….” to be more specific about what you really wanted.
An example of this type of prompting might be:
“Please provide the syntax for an SQL case statement to check whether a zip code is located in New England.”
On the first try I got the following:
SELECT
ZipCodeColumn,
CASE
WHEN ZipCodeColumn BETWEEN 01000 AND 06999 THEN 'New England'
ELSE 'Not New England'
END AS Region
FROM
YourTableName;
This was good, but was not what I was thinking. Therefore, I revised my prompt to the following:
“Please provide the syntax for an SQL case statement to check whether a zip code is in New England and return the state.”
The results are similar, but you can see how the phrasing of the prompt caused a different result:
SELECT
ZipCode,
CASE
WHEN ZipCode BETWEEN '01000' AND '02799' THEN 'MA' -- Massachusetts
WHEN ZipCode BETWEEN '02800' AND '02999' THEN 'RI' -- Rhode Island
WHEN ZipCode BETWEEN '03000' AND '03899' THEN 'NH' -- New Hampshire
WHEN ZipCode BETWEEN '03900' AND '04999' THEN 'ME' -- Maine
WHEN ZipCode BETWEEN '05000' AND '05999' THEN 'VT' -- Vermont
WHEN ZipCode BETWEEN '06000' AND '06999' THEN 'CT' -- Connecticut
ELSE 'Not New England'
END AS NewEnglandState
FROM
YourTableName;
This is better because it added the granularity of state level I was expecting.
With regard to RPG, when I first created a free ChatGPT account and asked it to provide RPG logic, it gave me pretty ugly fixed-format code. At first, I thought I was wasting my time, but then I re-prompted it and said, “No, I wanted this program in RPGLE free format,” which caused a response within seconds yielding a re-written free-format example. Perhaps the model behind ChatGPT can remember users wanting free-format RPG rather than fixed, because as time passed, it seemed more likely to give free-format on the first prompt.
Trying out ChatGPT on an EDI Project
Recently, while working on a project involving EDI, it occurred to me that I should try ChatGPT again, since ChatGPT version 5 had been announced that week. My objective was specifically the parsing of EDI documents. EDI documents are defined by version and transaction types. A transaction is made up of segments identified by some two- or three-character abbreviation and delimited by a specific character, sometimes a tilde (~).
Within each segment are elements. The elements consist of codes or values and are often delimited by an asterisk (*). EDI type 834 and 837 documents can be used by the healthcare industry to transmit membership and claims information about an individual within a plan. My thought was to see if I could get it to write me an entire program to handle the import and conversion of an EDI stream file into a DB2 table.
My first prompt to ChatGPT5 was:
“Write an RPGLE free format program to parse an EDI 834 transaction into database columns containing the specific EDI segment information.”
This resulted in a reply containing an SQL create table statement which would make the table to contain the result data. It also provided the SQLRPGLE code to read the file from the IFS and parse the segments and insert records into the table.
Both of these were impressive, given the 20-seconds of thought given. However, the RPG had a few problems that stopped it from compiling. It included some in-line DCL-S declaration statements, which belonged at the top of the code, not within executable calculations. The code included NEXT instead of ITER to escape from an IF statement. Another issue was that the developed code contained a number of occurrences of an operation that RPGLE did not like:
// element positions: 3 = entity type code, 4 = last name, 5 = first, 6 = MI
memberLast = (elemCount >= 4) ? elemList(4) : '';
memberFirst = (elemCount >= 5) ? elemList(5) : '';
memberMI = (elemCount >= 6) ? elemList(6) : '';
This code appears to use “Ternary operator ?” that another language such as C, VB might use. I needed to convert these code occurrences to IF ELSE END logic.
After providing the SQL and RPG code, ChatGPT gave notes about how it came to its conclusions and the assumptions it made. It even provided a brief sample of EDI834 transaction which I assumed could be used for testing. Rather than waste time trying to correct the issues I saw in the RPG code, I instead gave a qualifying prompt to see if I could get a better result:
“This program is incorrect because DCL-S declaration statements are not allowed within executable code. All DCL statements must be before executable code except when used in a sub-procedure context. Please regenerate the above code with all DCL-S moved to beginning of program.”
The reply was “Nice Catch!” followed by revised RPG source that moved all the declarations to the top of the code.
Further Corrections
I saw some other things that were incorrect.
- Use of data type LongVarChar, which the RPG compiler rejected.
- Use of function %UPCASE, which needed to be replaced with RPG’s %UPPER function.
- The program did not handle all the segments expected in an 834 document.
- The IFS reading routine it used, QSYS2.READ_FILE_TEXT, was not found because the preferred function is named QSYS2.IFS_READ (or QSYS2.IFS_READ_UTF8 for Unicode files)
- The continued use of ternary operators not supported in RPG needed to be replaced by IF/ELSE/END logic.
For the above items, I changed from LongVarChar to varchar(16773014), replaced all %UPCASE with %UPPER and corrected the QSYS2 library routine to read from the IFS.
For the case of not handling all EDI segments, I prompted again to get a better program version:
“Update the code to no longer use ternary operations and to support these 834 segments:
INS*Y*18*030*XN*A*E**FT~
REF*0F*033287159~
REF*1L*212~
REF*ZZ*00~
DTP*336*D8*20180905~
DTP*356*D8*20250101~
NM1*IL*1*Rabbit*Bunny****34*033229999~
PER*IP**HP*6034520006~
N3*1115 Best Road*First Floor~
N4*Jamaica*VT*05434~
DMG*D8*19780401*F~
HD*030**HLT**EMP~
DTP*348*D8*20250101~”
In the resulting version, the bot cleaned up a number of the issues and added some processing for segments that had been missing. I had to modify the SQL code for the Create table to add missing columns that the RPG now referenced.
The resulting code was intended to accept one parameter, containing the IFS path and file name of the EDI file as an entry parameter. With minimal effort I was able to get a clean compile of my SQLRPGLE program, but when called, it failed immediately on the first line of the code after the filename was passed and then accessed. After creating a new variable and assigning its value to the filename, I was able to get further, with the program able to read the IFS file data.
Complexity Grows
Now we get to the heart of the issue, parsing the complete EDI character string into segments and elements. Well, the AI-generated logic to tear apart the segments and put each of them into an array was quite complex. Each segment was to be placed into an array. Then the program had to read through the array of individual segments and parse the elements in the segment into fields. Between these two things, there were many lines of code.
One of the newer features in the RPG language is the split function defined as %SPLIT. Interestingly, this single function could be used to replace the 30+ lines of code, to separate whatever segments existed in the data into an array of segments. The comment and one line of code:
// split the long character value in ediContent, terminated by ‘~’ characters into the array Segments Segments = %SPLIT(ediContent : segterm);
Likewise, once the segment array is loaded, it should be possible to parse each segment into an array of Elements. Again, one line of code.
The SPLIT function is versatile, in that it can split based on one, two or more characters being located. I used it here for the asterisk (*) element separator or the tilde (~) segment separator.
// split the segment occurrence on either character * or ~ elemList= %SPLIT(segments(segListIndex) : '*~');
The elements are where the data about the people is stored, so the program still has to interrogate the elements using the abbreviations like those shown in figure 1. As these elements are seen, program logic can place the values into the specific record columns that relate to each element. The AI did a pretty complete job in handling these various element headers and their content.
I added logic to “break” on the first element for a person. When a new person is found, the data gathered from the prior person is used to perform an SQL insert of the prior person’s record.
A Helper, Not a Replacement
The big takeaway from this exercise is that AI can give you a leg up on your project but far from being a programmer replacement, AI is an assistant. This is exactly how IBM is billing their Project Bob, which is supposed to explain, document, refactor and develop code within VS Code.