Then we started the third iteration where we put the same prompt as before, but we also gave a step-by-step migration instructions which told the LLM how to handle this case and also cleared any ambiguity that LLM had. The results were definitely better this time. However, there was still some inconsistency. Some of the more complex business logic was not migrated. Some of the things like cleaning up the old imports or unused variables was also not correctly done. At this stage, we started researching like what can we do to improve the output? For example, we looked around and looked at different research papers and so on and what we figured out is that if we provide patterns that could actually increase the accuracy of the LLM and that's exactly what we did.
Along with the previous context, we also passed a set of transformation examples which were just before and after examples and we passed that. And with this thing, the accuracy of LLM was pretty good. It had a 90% accuracy and we were quite satisfied with it and then decided to proceed further. A small note on accuracy like we used a matrix to calculate how well LLM was behaving and this accuracy matrix was just number of lines that were correctly migrated by LLM divided by the total lines of code migrated. By correctly, I mean like if there was import not migrated correctly or some unused variables or some bugs, those were excluded and then we calculated this matrix.
Now, once the prompt structure or the was defined, this is how the final prompt looked like. It had four sections. The first three sections like I talked before is just interface mapping instructions and examples that were generated and the final section was the file which was needed which was to be transformed. One thing to note here is that we kept the interface instructions and examples at the top because these did not differ from file to file. For one component, they were always the same and this way, we could this way, this could be cached and we could save some cost on the LLM side due to prompt caching. Once the prompt was there, we decided to build a small tool which was a CLI tool. This tool, what it did was at the first step, it scanned through the whole repository to find out all the files that contained the components that we wanted to migrate.
Then it built the prompt with the components like I showed in the previous slide and the file and then submitted it to the LLM for transformation. LLM will take the file, transform it and send it as a response which was then extracted by the tool and it applied it to the existing file and committed it and then a review was created for the engineer to verify, test it and then merge and deploy. Now talking a little bit about the technical details, we used a lot of different tools. These tools were open source but they actually helped us reduce a lot of effort and also a lot of time. We used a tool called continue.dev. Continue.dev made it very easy to create the prompts. All we had to do was give the source files to the tool and then ask it to generate the instructions interface and examples and it was easily able to do it. Then we also used LLM SDK by Dataset. This had a very nice conversation API that allowed us to interact with LLM and also continue responses if it got cut off and so on. Finally, we also used a tool AIDAR which was also AI-based. This tool helped us in automating the git commits and it also helped in creating a nice commit message and description so that the user who is going to review the pull request, they know what has been done and it makes the request reviews easier for them. For the tool, we also had a regression testing framework in place.
Comments