{"id":1173,"date":"2025-07-09T17:10:30","date_gmt":"2025-07-09T17:10:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/all-things-azure\/?p=1173"},"modified":"2025-07-16T09:17:39","modified_gmt":"2025-07-16T09:17:39","slug":"how-we-use-ai-agents-for-cobol-migration-and-mainframe-modernization","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/all-things-azure\/how-we-use-ai-agents-for-cobol-migration-and-mainframe-modernization\/","title":{"rendered":"How We Use AI Agents for COBOL Migration and Mainframe Modernization"},"content":{"rendered":"<p><span style=\"font-family: arial, helvetica, sans-serif;\">Legacy modernization is one of the most frequently raised challenges customers approach us with. They want to eliminate technical debt and run applications cloud-native. Obviously, there are different levels of complexity in legacy modernization, but the most challenging cases remain mainframe languages like COBOL and PL\/1.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">COBOL still powers mission-critical systems in banking, insurance, and government. Modernizing away from the mainframe comes with increased complexity due to fewer experts, rising maintenance costs, and the loss of institutional knowledge \u2014 and the millions of lines of code certainly don\u2019t help either.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Mainframe modernization is still overly reliant on specialized partners and Global System Integrators (GSIs), who dominate the market with their tooling and expertise. Despite existing efforts and tools, mainframe modernization projects are invariably long-term. Most customers we\u2019ve talked to no longer favor an approach led by a GSI or specialized partner. They want to stay in control of their intellectual property, project progress, and costs \u2014 choosing their own partners or leveraging in-house expertise.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">One example that illustrates this shift in modernization approach is Bankdata.<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime.png\"><img decoding=\"async\" class=\"alignnone size-medium wp-image-1187\" src=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime-300x107.png\" alt=\"BankData Green Lime image\" width=\"300\" height=\"107\" srcset=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime-300x107.png 300w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime-1024x365.png 1024w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime-768x274.png 768w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/BankData-Green-Lime.png 1401w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\"><a href=\"https:\/\/www.bankdata.dk\/\"><strong>Bankdata<\/strong><\/a> is a technology company established by a consortium of Danish banks. It provides comprehensive IT platforms and services to its eight member banks, which together represent over 30% of the Danish banking market. Having existed since the 1960s, this includes tech stacks all the way from traditional mainframe workloads to modern cloud and cloud native compute platforms, all supporting critical financial services in Denmark.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Almost all newer development in Bankdata is aimed towards cloud and cloud-native platforms, however over 70 million lines of code still exist on the mainframe today. While most of those systems are a good fit for the mainframe, some are not and would benefit from being re-platformed. Historically however, doing so has been a tremendous manual, time-consuming and costly affair.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">But even before discussing re-platforming, there\u2019s a critical question: <strong>is the COBOL code actually modernizable?<\/strong><\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Many COBOL modules aren\u2019t just about business logic \u2014 they\u2019re deeply tied to the non-functional behaviors of the mainframe: batch throughput, I\/O handling, JCL orchestration, strict SLAs. These characteristics are hard to replicate and can\u2019t be handwaved away.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">That\u2019s why we don\u2019t treat all COBOL as equally \u201cmigratable.\u201d Some modules need a redesign. Others demand a smarter, critical look at their non-functional dependencies \u2014 not to avoid modernization, but to approach it thoughtfully.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">It\u2019s a dimension we\u2019re still actively exploring \u2014 and we believe it deserves just as much attention as the code transformation itself.<\/span><\/p>\n<h2><span style=\"font-family: arial, helvetica, sans-serif;\">Rethinking COBOL Modernization with Agentic AI<\/span><\/h2>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">With the development of incrementally capable Large and Small Language Models and the rise of AI agents, we saw a chance to tackle this inhumane problem of mainframe migration from a fresh and hopefully more successful angle.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">In the context of early technical development, our first iterations began at the end of 2024 with simple back-and-forth chat interactions with GPT-4, later exploring the integrated coding experience through GitHub Copilot and its dedicated coding LLMs. We faced massive challenges: limited token windows led to loss of relevant context, and the general capabilities of language models to understand COBOL were very limited. We ended up with a good mix of educated guesses (from us and the model) and hallucinational gibberish.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">A positive side effect of our early experimentation was that it forced us to spend dedicated time thinking about how to structure and orchestrate a migration approach \u2014 which helped immensely as we began prompting different worker and orchestration agents.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">From this, we abstracted a set of key steps (though the exact order may vary between use cases):<\/span><\/p>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">Preparation<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Reverse engineering:<\/strong> Extracting the essence of business logic from the code, existing comments, technical documentation, user handbooks, and human SMEs.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Prepare code for AI understanding:<\/strong> Removing comments or information that don\u2019t add value to the context, such as change logs at the top of files.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Translate code and comments:<\/strong> Important when engineers and\/or the LLM don\u2019t understand the language \u2014 in Bankdata\u2019s case, the code was in Danish, a niche language not trained into every model.<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">Enrichment<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Add meaningful comments<\/strong>: Sometimes the opposite of stripping is true \u2014 good comments can help the AI work more efficiently and stay in context.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Identify recurring deterministic structures:<\/strong> Useful for agent orchestration and chunking.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Document temporary results and use them in context:<\/strong> We noticed that a well-structured markdown \u2014 especially content previously written by AI \u2014 proved very helpful for continuity.<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">Automation Aids<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Flow analysis and visualization:<\/strong> Using existing or generated call chains of COBOL modules, visualized in Mermaid or flow diagrams (mainly as a support for human engineers).<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Test generation:<\/strong> If test files still exist, it may make sense to build upon them or even experiment with a test-driven development (TDD) approach.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Identify and isolate utility functions:<\/strong> Much COBOL code includes logic we\u2019d now handle via libraries. Isolating and removing this early can speed up migration and reduce token usage.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This structured thinking ultimately informed the architecture of what would become our COBOL Agentic Migration Factory (CAMF) \u2014 built on top of <a href=\"https:\/\/github.com\/microsoft\/autogen\">AutoGen<\/a>.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Our first agentic iteration featured three main worker agents:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>COBOL Expert<\/strong>: Analyzes COBOL code structure, business logic, and copybook dependencies.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Java Expert<\/strong>: Converts COBOL patterns into modern Java Quarkus implementations.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Test Expert<\/strong>: Creates comprehensive test suites for the converted code.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Workflow orchestration was managed through the control and logging of the agents\u2019 chat conversations \u2014 which quickly became our main interface to evaluate performance and reasoning.<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen.png\"><img decoding=\"async\" class=\" wp-image-1180 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen-300x191.png\" alt=\"camf autogen image\" width=\"846\" height=\"539\" srcset=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen-300x191.png 300w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen-1024x651.png 1024w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen-768x488.png 768w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_autogen.png 1384w\" sizes=\"(max-width: 846px) 100vw, 846px\" \/><\/a><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">We began our initial experiments but quickly realized that the few COBOL examples available on GitHub weren\u2019t representative of real-world complexity. In continued collaboration with Bankdata, they agreed to provide us with a small COBOL module for testing. This helped refine the framework before we decided to hack together for two days and push further \u2014 testing more complex COBOL call chains and re-evaluating both agent composition and prompting.<\/span><\/p>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">Our main learnings were:<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">When we provided too much context, the agents appeared to run out of memory, lost coherence, and either hallucinated heavily or stopped coding altogether. In contrast, when the context was kept sufficiently short, the output quality was surprisingly good.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">One of the hardest challenges was managing the call-chain structure &#8211; understanding which module calls which, and at what depth. We managed to reach level 3, but not beyond.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Deterministic control structures, especially tests, were crucial for verifying and validating the agents&#8217; output.<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">To tackle these challenges, we explored several strategies:<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Adding a pre-processing step to ingest COBOL code (and additional resources) into a Graph RAG database to make more effective use of LLM context.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Considering additional chunking strategies when the COBOL Expert Agent attempts to interpret the source code.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Introducing a more effective planner or orchestration agent.<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Or, of course, combining all of the above.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This exploration ultimately led us toward <strong>Semantic Kernel<\/strong>. Thanks to its maturity and more robust orchestration capabilities, we were able to more effectively coordinate multiple AI agents working together to analyze and migrate COBOL code to modern languages like Java or .NET.<\/span><\/p>\n<h2><span style=\"font-family: arial, helvetica, sans-serif;\">From Concept to Code: Our COBOL Migration Stack<\/span><\/h2>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">For a full deep dive, check out the repository: <a href=\"https:\/\/aka.ms\/cobol\">https:\/\/aka.ms\/cobol<\/a><\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The COBOL Agentic Migration Factory was originally designed as a tool to help modernize COBOL applications by migrating them to Java Quarkus. It uses a set of modular, AI-powered agents orchestrated via Microsoft Semantic Kernel.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Today, it\u2019s designed to support freely choosing both source and target languages.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">It automates and streamlines migration tasks\u2014analysis, transformation, dependency mapping, and reporting\u2014by distributing them across specialized, cooperating agents.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The following system prompt is used for initiating the process as follows:<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">You are an expert in converting COBOL programs to Java with Quarkus framework. Your task is to convert COBOL source code to \r\nmodern, maintainable Java code that runs on the Quarkus framework.\r\n\r\nFollow these guidelines:\r\n\r\n1. Create proper Java class structures from COBOL programs\r\n2. Convert COBOL variables to appropriate Java data types\r\n3. Transform COBOL procedures into Java methods\r\n4. Handle COBOL-specific features (PERFORM, GOTO, etc.) in an idiomatic Java way\r\n5. Implement proper error handling\r\n6. Include comprehensive comments explaining the conversion decisions\r\n7. Make the code compatible with Quarkus framework\r\n8. Apply modern Java best practices<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Step 4 is key for converting traditional COBOL control-flow statements, like PERFORM loops (used for repeating code blocks) and GOTO statements (for unconditional jumps), into equivalent structures that align with modern Java programming practices. This specifically involves:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Replacing PERFORM statements with structured loops (for, while, do-while) or method calls<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Eliminating GOTO by restructuring logic using modern Java control statements (if-else, switch-case, loops) or clearly defined methods<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Ensuring the resulting Java code is readable, maintainable, and follows current best practices (instead of directly replicating COBOL\u2019s structure \u2014 sometimes referred to as \u201cJOBOL\u201d)<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">We specifically aimed to use so-called reasoning models\u2014particularly GPT-4.1\u2014which we found highly effective. In our context, reasoning refers to the AI\u2019s ability to logically analyze COBOL code structure, decision paths, and control flow\u2014ensuring the converted Java code accurately reflects the original business logic and intent.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The COBOL migration factory\u2019s goal is to modernize software engineering for legacy system transformation, and we believe the same approach could be extended to other legacy code projects. That\u2019s out of scope for this project.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This blog demonstrates how we analyze, map, and transform COBOL systems into modern, cloud-ready Java (Quarkus, if you desire) applications using a modular, AI-powered, agent-based approach built on Microsoft\u2019s Semantic Kernel and Process Function.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">At the core of the system is a main workflow controller that initializes all agents and coordinates their work. It handles file discovery, calls to analysis agents, manages code conversion, and collects outputs for reporting and logging.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Each agent focuses on a specific step of the migration process. They operate independently but share a common Semantic Kernel foundation.<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>COBOLAnalyzerAgent<\/strong>: Scans COBOL files to understand their structure and logic<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>JavaConverterAgent<\/strong>: Converts COBOL source code to Java (Quarkus)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>DependencyMapperAgent<\/strong>: Analyzes relationships (such as copybook usage), maps dependencies, and generates diagrams<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The following flowchart illustrates how agents interact with each other:<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_sk.png\"><img decoding=\"async\" class=\" wp-image-1182 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_sk-300x74.png\" alt=\"camf sk image\" width=\"730\" height=\"180\" srcset=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_sk-300x74.png 300w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_sk-768x189.png 768w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_sk.png 904w\" sizes=\"(max-width: 730px) 100vw, 730px\" \/><\/a><\/p>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">Agent Breakdown: Inside the DependencyMapperAgent<\/span><\/h3>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Analyzes COBOL program relationships, including copybook usage, and builds a map of dependencies and reverse dependencies<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Uses AI to extract higher-level insights about coupling, modularity, and architectural complexity<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Generates Mermaid diagrams to visualize these relationships<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Calculates metrics to help guide modernization decisions<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The <strong>DependencyMapperAgent<\/strong> acts as the <em>architectural brain<\/em> of the framework, offering crucial insights into how COBOL programs are interconnected. It leverages two specialized AI prompts that work in tandem to build an architectural understanding.<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">\/\/ Prompt 1\r\n\r\nYou are an expert in creating Mermaid diagrams for software architecture visualization.\r\n\r\nYour task is to create a clear, well-organized Mermaid flowchart that shows COBOL program dependencies.\r\n\r\nGuidelines:\r\n\r\n1. Use 'graph TB' (top-bottom) or 'graph LR' (left-right) layout based on complexity\r\nGroup related items using subgraphs\r\n2. Use different colors\/styles for programs (.cbl) vs copybooks (.cpy)\r\n3. Show clear dependency arrows\r\n4. Keep the diagram readable and not overcrowded\r\n5. Use meaningful node IDs and labels\r\n6. Add styling for better visual appeal\r\n\r\nReturn only the Mermaid diagram code, no additional text.<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">What this prompt accomplishes:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Visual Architecture Mapping<\/strong>: Generates flowcharts visualizing relationships between programs and copybooks<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Structural Organization<\/strong>: Uses subgraphs to group related components (e.g., programs vs. copybooks)<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Dependency Flow Visualization<\/strong>: Shows directional arrows to indicate data flow and copybook inclusion patterns<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\"><strong>Complexity Management<\/strong>: Dynamically selects layout (e.g., top-down vs. left-right) based on graph complexity<\/span><\/li>\n<\/ul>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\"> \u00a0\u00a0 foreach (var kvp in dependencyMap.CopybookUsage)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var program = kvp.Key;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var copybooks = kvp.Value;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 foreach (var copybook in copybooks)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var dependency = new DependencyRelationship\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SourceFile = program,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TargetFile = copybook,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DependencyType = \"COPY\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Context = \"Copybook inclusion\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dependencyMap.Dependencies.Add(dependency);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ Perform AI-powered analysis for additional insights\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (cobolFiles.Any())\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var systemPrompt = @\"\r\n\r\n\/\/ Prompt 2\r\n\r\nYou are an expert COBOL dependency analyzer. Analyze the provided COBOL code structure and identify:\r\n\r\n1. Data flow dependencies between copybooks\r\n2. Potential circular dependencies\r\n3. Modularity recommendations\r\n4. Legacy patterns that affect dependencies\r\n\r\nProvide a brief analysis of the dependency structure and any recommendations.\r\n\r\n\";<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Prompt 2 is critical, as it feeds essential context into both the COBOLAnalyzerAgent and the JavaConverterAgent.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">For the COBOL agent, it provides usage patterns showing which program uses which data structure, how data moves between modules, flags problematic architectural patterns, and offers recommendations for breaking down monolithic structures.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">For the Java agent, it organizes class structure based on COBOL relationships, suggests where to define microservice boundaries in Quarkus (or Spring, depending on instructions), maps COBOL data structures to Java entities, and identifies which components should communicate in the new architecture.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This architectural context is essential for accurate COBOL-to-Java conversion.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The pattern detection performed by the DependencyMapperAgent delivers insights that directly guide migration decisions:<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">dependencyMap.Metrics.TotalPrograms = programs.Count;\r\ndependencyMap.Metrics.TotalCopybooks = copybooks.Count;\r\ndependencyMap.Metrics.AverageDependenciesPerProgram =\r\n\u00a0\u00a0\u00a0 (double)dependencyMap.Dependencies.Count \/ programs.Count;<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This process generates a complexity score for each program based on its dependencies and copybook usage. Heavily used copybooks may become candidates for shared services. These insights help prioritize which components to migrate first and identify changes with the highest potential impact.<\/span><\/p>\n<h3><span style=\"font-family: arial, helvetica, sans-serif;\">The COBOLAnalyzerAgent<\/span><\/h3>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The COBOLAnalyzerAgent is the core parsing engine that transforms unstructured COBOL code into structured, machine-readable analysis data for automated Java conversion. Its primary function is to ingest raw COBOL source files and perform deep semantic analysis using AI to extract:<\/span><\/p>\n<ul>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Program structure and data divisions<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Variable definitions and hierarchies<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Procedure flow and business logic<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">SQL\/DB2 embedded statements<\/span><\/li>\n<li><span style=\"font-family: arial, helvetica, sans-serif;\">Copybook dependencies<\/span><\/li>\n<\/ul>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The core implementation is as follows:<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">public async Task&lt;CobolAnalysis&gt; AnalyzeCobolFileAsync(CobolFile cobolFile)\r\n{\r\n\u00a0\u00a0\u00a0 var kernel = _kernelBuilder.Build();\r\n\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0 \/\/ AI-powered analysis prompt\r\n\u00a0\u00a0\u00a0 var systemPrompt = @\"\r\n\r\nYou are an expert COBOL analyzer. Extract:\r\n\r\n1. Data divisions and purpose\r\n2. Procedure divisions and logic flow\r\n3. Variables (level, type, size, group structure)\r\n4. Paragraphs\/sections with call relationships\r\n5. Embedded SQL\/DB2 statements\r\n6. File access patterns and FD linkage\";\r\n\r\n\r\nvar prompt = $@\"\r\nAnalyze the following COBOL program:\r\n```cobol\r\n{cobolFile.Content}\r\n\/\/ Execute AI analysis with optimized settings\r\n\r\nvar executionSettings = new OpenAIPromptExecutionSettings\r\n{\r\n\u00a0\u00a0\u00a0 MaxTokens = 32768,\u00a0\u00a0\u00a0 \/\/ Handle large legacy programs\r\n\u00a0\u00a0\u00a0 Temperature = 0.1,\u00a0\u00a0\u00a0 \/\/ Deterministic analysis\r\n\u00a0\u00a0\u00a0 TopP = 0.5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Focused output\r\n};\r\n\r\nvar functionResult = await kernel.InvokePromptAsync(\r\n\u00a0\u00a0\u00a0 $\"{systemPrompt}\\n\\n{prompt}\",\r\n\u00a0\u00a0\u00a0 new KernelArguments(executionSettings));\r\nreturn new CobolAnalysis\r\n\r\n{\r\n\u00a0\u00a0\u00a0 FileName = cobolFile.FileName,\r\n\u00a0\u00a0\u00a0 RawAnalysisData = functionResult.GetValue&lt;string&gt;()\r\n};<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The analysis is configured using the following settings:<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">\r\nvar executionSettings = new OpenAIPromptExecutionSettings\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MaxTokens = 32768, \/\/ Setting max limit within model\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Temperature = 0.1,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TopP = 0.5\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Model ID\/deployment name is handled at the kernel level\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\r\nvar functionResult = await kernel.InvokePromptAsync(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 fullPrompt,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 kernelArguments);\r\n\r\n\/\/ Parse the analysis into a structured object\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var analysis = new CobolAnalysis\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FileName = cobolFile.FileName,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FilePath = cobolFile.FilePath,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RawAnalysisData = analysisText\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 };\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ In a real implementation, we would parse the analysis text to\u00a0\u00a0 extract structured data\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ For this example, we'll just set some basic information\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 analysis.ProgramDescription = \"Extracted from AI analysis\";<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">An engineering benefit of using a batch processing approach is that it can handle enterprise-scale COBOL codebases while supporting progress tracking. The service generates structured output by converting unstructured legacy code into parsable analysis objects. Each call is tracked with its associated token size to monitor usage and optimize cost.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The <strong>COBOLAnalyzerAgent<\/strong> serves as the foundational intelligence layer that enables downstream Java agents to understand COBOL semantics and generate equivalent modern code structures.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The <strong>JavaConverterAgent<\/strong> is the core transformation engine that converts analyzed COBOL legacy code into modern Java Quarkus applications using AI-powered code generation. Its primary function is to take structured COBOL analysis data and generate production-ready Java code\u2014including error handling, retry logic, and content filtering\u2014suitable for enterprise deployment.<\/span><\/p>\n<p>&nbsp;<\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">public async Task&lt;JavaFile&gt; ConvertToJavaAsync(CobolFile cobolFile, CobolAnalysis cobolAnalysis)\r\n{\r\n\u00a0\u00a0\u00a0 var kernel = _kernelBuilder.Build();\r\n\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0 \/\/ AI conversion prompt with Quarkus-specific guidelines\r\n\u00a0\u00a0\u00a0 var systemPrompt = @\"\r\nYou are an expert in converting COBOL programs to Java with Quarkus framework.\r\n\r\n1. Create proper Java class structures from COBOL programs\r\n2. Convert COBOL variables to appropriate Java data types\r\n3. Transform COBOL procedures into Java methods\r\n4. Handle COBOL-specific features (PERFORM, GOTO, etc.) idiomatically\r\n5. Apply modern Java best practices with Quarkus features\r\n6. Implement proper exception handling and logging\";\r\n\u00a0\u00a0\u00a0 \/\/ Enterprise-grade execution settings\r\n\u00a0\u00a0\u00a0 var executionSettings = new OpenAIPromptExecutionSettings\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MaxTokens = 32768,\u00a0\u00a0\u00a0 \/\/ Handle large legacy programs, highest limit intake\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Temperature = 0.1,\u00a0\u00a0\u00a0 \/\/ Deterministic conversion\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TopP = 0.5\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Focused output\r\n\u00a0\u00a0\u00a0 };\r\n\r\n\u00a0\u00a0\u00a0 \/\/ Retry logic for production reliability\u00a0\r\n\u00a0\u00a0\u00a0 string javaCode = string.Empty;\r\n\u00a0\u00a0\u00a0 int maxRetries = 3;\r\n\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0 for (int attempt = 1; attempt &lt;= maxRetries; attempt++)\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var functionResult = await kernel.InvokePromptAsync(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $\"{systemPrompt}\\n\\n{prompt}\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 new KernelArguments(executionSettings));\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 javaCode = functionResult.GetValue&lt;string&gt;() ?? string.Empty;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 break; \/\/ Success\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 catch (Exception ex) when (attempt &lt; maxRetries &amp;&amp;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 (ex.Message.Contains(\"content_filter\") || ex.Message.Contains(\"timeout\")))\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 await Task.Delay(retryDelay);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 retryDelay *= 2; \/\/ Exponential backoff\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\r\n\u00a0\u00a0\u00a0 return new JavaFile\r\n\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FileName = $\"{GetClassName(javaCode)}.java\",\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Content = ExtractJavaCode(javaCode),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ClassName = GetClassName(javaCode),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PackageName = GetPackageName(javaCode),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 OriginalCobolFileName = cobolFile.FileName\r\n\u00a0\u00a0\u00a0 };\r\n}<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">A key engineering feature is content sanitization, which automatically cleans language and international text to avoid triggering Azure OpenAI\u2019s content filtering. The system also includes a retry mechanism for failed requests and implements exponential backoff in cases of timeouts or content filter violations.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The <strong>JavaConverterAgent<\/strong> performs code extraction by intelligently parsing AI-generated Java from markdown blocks. It also generates modern, microservice-ready Quarkus code with proper annotations. It focuses on transforming legacy COBOL business logic into cloud-native Java while preserving functionality and applying modern enterprise design patterns.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">To enable agent communication, we need to ensure that the orchestrator manages each sequence correctly. We follow this simplified approach:<\/span><\/p>\n<pre class=\"prettyprint language-cs language-csharp\"><code class=\"language-cs language-csharp\">\/\/ Discover COBOL files and copybooks\r\nvar cobolFiles = fileHelper.FindCobolFiles();\r\nvar copybooks = fileHelper.FindCopybooks();\r\n\r\n\/\/ 1. Analyze COBOL files for structure and logic\r\nvar cobolAnalyses = await _cobolAnalyzerAgent.AnalyzeCobolFilesAsync(cobolFiles);\r\n\r\n\/\/ 2. Map dependencies (program-to-copybook, reverse, and more)\r\nvar dependencyMap = await _dependencyMapperAgent.AnalyzeDependenciesAsync(cobolFiles, cobolAnalyses);\r\n\r\n\/\/ 3. Convert COBOL programs to Java (using analysis and dependency context)\r\nforeach (var analysis in cobolAnalyses)\r\n{\r\n\u00a0\u00a0\u00a0 var javaClass = await _javaConverterAgent.ConvertCobolToJavaAsync(analysis, dependencyMap);\r\n\u00a0\u00a0\u00a0 fileHelper.SaveJavaClass(javaClass);\r\n}\r\n\r\n\/\/ 4. Generate reports and diagrams based on dependency analysis\r\nreportGenerator.CreateMigrationReport(dependencyMap, cobolAnalyses);<\/code><\/pre>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Each agent returns structured outputs (e.g., COBOLAnalysis, DependencyMap) that serve as inputs for the next agent in the pipeline\u2014enabling a clean, testable, and extensible workflow.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">The following diagram shows the end-to-end flow of how the framework operates:<\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow.png\"><img decoding=\"async\" class=\" wp-image-1183 aligncenter\" src=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow-286x300.png\" alt=\"camf flow image\" width=\"679\" height=\"712\" srcset=\"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow-286x300.png 286w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow-768x805.png 768w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow-24x24.png 24w, https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-content\/uploads\/sites\/83\/2025\/07\/camf_flow.png 904w\" sizes=\"(max-width: 679px) 100vw, 679px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Running the migration tool produces a dependency diagram, a full chat log of all agent conversations, the generated Java code, and conversion metrics.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Since the COBOL code was generously donated by Bankdata, we cannot publish a detailed report due to its sensitive nature. We\u2019re deeply grateful to Bankdata for their contribution\u2014without their code, building this tool wouldn\u2019t have been possible.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">We hope this framework will help modernize and document COBOL code across a variety of legacy systems.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">There\u2019s no one-size-fits-all approach to COBOL modernization\u2014which is why you can dive into the source at <a href=\"http:\/\/aka.ms\/cobol\">aka.ms\/cobol<\/a> and customize each agent\u2019s persona to fit your specific use case.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">We see this not just as a framework for code migration\u2014but as a foundation for rethinking how we approach legacy systems in the age of AI.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">This is just the beginning. Whether you\u2019re deep in COBOL or working with another legacy stack, we hope this gives you the tools\u2014and the freedom\u2014to build, break, and modernize on your own terms.<\/span><\/p>\n<p><span style=\"font-family: arial, helvetica, sans-serif;\">Project Team: <a href=\"https:\/\/www.linkedin.com\/in\/julia-kordick\/\">Julia Kordick (MSFT)<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/gustav-kaleta-7a18661a\/\">Gustav Kaleta (MSFT)<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/omar-alhajj\/\">Omar Alhajj (Bankdata)<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/michael-munch-156298100\/\">Michael Munch (Bankdata)<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/morten-lilb%C3%A6k-pedersen\/\">Morten Lilb\u00e6k Pedersen (Bankdata)<\/a>, <a href=\"https:\/\/www.linkedin.com\/in\/illio\/\">Michael Lind Mortensen (Bankdata)<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Legacy modernization is one of the most frequently raised challenges customers approach us with. They want to eliminate technical debt and run applications cloud-native. Obviously, there are different levels of complexity in legacy modernization, but the most challenging cases remain mainframe languages like COBOL and PL\/1. COBOL still powers mission-critical systems in banking, insurance, and [&hellip;]<\/p>\n","protected":false},"author":172702,"featured_media":1198,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[35,1,38,20],"tags":[],"class_list":["post-1173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-agents","category-azure","category-app-development","category-developer-productivity"],"acf":[],"blog_post_summary":"<p>Legacy modernization is one of the most frequently raised challenges customers approach us with. They want to eliminate technical debt and run applications cloud-native. Obviously, there are different levels of complexity in legacy modernization, but the most challenging cases remain mainframe languages like COBOL and PL\/1. COBOL still powers mission-critical systems in banking, insurance, and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts\/1173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/users\/172702"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/comments?post=1173"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/posts\/1173\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/media\/1198"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/media?parent=1173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/categories?post=1173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/all-things-azure\/wp-json\/wp\/v2\/tags?post=1173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}