Azure-Samples/Legacy-Modernization-Agents
요약
이 오픈 소스 프레임워크는 COBOL 같은 레거시 코드를 Java 또는 C# .NET으로 변환하는 AI 에이전트 기능을 시연합니다. Azure OpenAI, GitHub Copilot 등 다중 공급자 아키텍처를 활용하여 코드 분석 및 변환을 수행하며, 웹 포털에서 진행 상황과 의존성 그래프를 실시간으로 시각화할 수 있습니다.
핵심 포인트
- COBOL 레거시 코드를 Java/C# .NET으로 변환하는 AI 에이전트 프레임워크입니다.
- Azure OpenAI와 GitHub Copilot 등 다중 공급자 아키텍처를 지원합니다.
- 웹 포털을 통해 마이그레이션 진행 상황과 의존성 그래프를 시각화할 수 있습니다.
- 사용 전 Azure/GitHub 계정 로그인 및 권한 설정이 필수적입니다.
이 오픈 소스 마이그레이션 프레임워크는 COBOL과 같은 레거시 코드를 Java 또는 C# .NET으로 변환하는 AI 에이전트의 기능을 시연하기 위해 개발되었습니다. 각 에이전트는 원하는 결과에 따라 수정할 수 있는 페르소나를 가지고 있습니다.
마이그레이션은 Microsoft Agent Framework와 다중 공급자 아키텍처(multi-provider architecture)를 사용하며, Azure OpenAI (Responses API + Chat Completions), GitHub Copilot (PAT 또는 CLI 기반 SDK), 그리고 직접적인 OpenAI를 지원하여 COBOL 코드와 그 의존성을 분석한 후 Java Quarkus 또는 C# .NET 중 하나(사용자 선택)으로 변환합니다.
웹 포털을 통해 마이그레이션 진행 상황, 의존성 그래프, AI 기반 Q&A를 실시간으로 시각화할 수 있습니다.
중요 사항
모델을 호출하는 어떤 작업도 실행하기 전에 반드시 로그인해야 합니다. 이 프레임워크는 로컬 로그인에서 토큰을 가져오므로 별도로 요청하지 않습니다.
| 공급자 (Provider) | 로그인 방법 (Sign in with) | 이후 조치 (Then) |
|---|---|---|
| Azure OpenAI / Azure AI Foundry (Entra ID) | az login (--tenant <id>를 추가하여 리소스가 다른 테넌트에 있는 경우) | |
| 귀하의 계정은 해당 리소스에 대한 Cognitive Services OpenAI 사용자 역할이 필요합니다. az login 인증을 참조하세요 | ||
| GitHub Copilot SDK | gh auth login | gh auth status로 확인하세요. 계정에 Copilot 라이선스가 필요합니다 |
유효한 로그인(또는 Config/ai-config.local.env 파일의 API 키) 없이는 첫 모델 호출에서 변환 및 역공학(reverse engineering)이 실패합니다. ./doctor.sh rekt-full, ./doctor.sh estate, 그리고 ./doctor.sh jcl은 모델을 호출하지 않으므로 로그인할 필요가 없습니다.
팁
여기서 시작하세요: 빠른 실행. 이 명령어들을 저장소 루트에서 순서대로 실행하세요:
| 단계 | 명령어 | 기능 |
|---|---|---|
| 1 | (파일 복사) | 소스 코드(COBOL 프로그램(source/.cbl)), 카피북(.cpy), BMS 맵(.bms), CICS 정의, JCL 작업(.jcl)과 그 절차 및 INCLUDE 멤버(.proc, .prc, .inc)를 지정된 위치에 넣으세요. 하위 폴더도 괜찮습니다. |
| 2 | ./doctor.sh setup | 프레임워크 구성: AI 제공업체, 자격 증명(credentials), 모델 및 로컬 서비스 설정 |
| 3 | ./doctor.sh rekt-full | 에스테이트 파싱 (변환 전): COBOL을 REKT로 파싱하여 REKT Neo4j 그래프를 만들고 JCL을 output/rekt/에 저장합니다. 모델은 호출되지 않습니다. 먼저 'Parse first: rekt-full'을 참조하세요. |
| 4 | ./doctor.sh portal | http://localhost:5028에서 포털 열기 |
| 5 | (포털) | 🛰 에스테이트 미션 컨트롤(Estate Mission Control)에서 마이그레이션할 대상을 선택합니다: ✂️ 카브아웃(Carve-out) 계획으로 전환하고, 클러스터를 클릭한 다음, 📦 스테이지 슬라이스(Stage slice)를 누릅니다. 패널에는 프로그램 목록, 호출하는 대상, 그리고 source/에서 누락된 항목이 나열되며, 실행할 정확한 명령어를 제공합니다. 🔁 AI 루프로 전송하면 포털에서 변환을 시작합니다. 'Estate Mission Control'을 참조하세요. |
| 6 | (제안된 명령어) | 슬라이스 변환: 예를 들어 ./doctor.sh convert-only --program BNK1CCA.cbl,BNK1CCS.cbl |
예시 명령어:
| 명령어 | 기능 |
|---|---|
./doctor.sh estate | 터미널에 카브아웃 웨이브 계획을 출력합니다 (Estate Mission Control과 동일한 데이터). |
./doctor.sh estate C01 | 클러스터 하나와 해당 슬라이스에 대한 convert-only 명령어를 출력합니다. |
./doctor.sh run --program X.cbl --language Java --dry-run | 모델을 호출하지 않고 변환에 포함될 프로그램을 미리 보여줍니다. |
./doctor.sh convert-only --program A.cbl --program B.cbl | 이 프로그램들만 변환합니다 ( --program을 반복하거나 쉼표로 구분). |
./doctor.sh run --program X.cbl --include-callees --clean-output | 프로그램을 호출하는 모든 것과 함께, 깨끗한 출력 폴더에 변환합니다. |
./doctor.sh reverse-eng | 비즈니스 로직만 추출합니다 (변환 없음). |
./doctor.sh run | source/의 모든 것을 전체 마이그레이션합니다. |
Estate Mission Control은 source/에서만 구축됩니다.
포털의 채팅 및 리포트 페이지는 최소한 한 번 실행(./doctor.sh reverse-eng, convert-only 또는 run)이 필요합니다.
JCL 작업: .jcl 파일을 (.proc, .prc, .inc 멤버와 함께) source/에 넣은 다음, 다음을 수행합니다:
| 명령어 | 기능 |
|---|---|
./doctor.sh jcl --language CSharp (또는 Java) | JCL만, 모델 없음, 초: 각 JCL 작업당 하나의 작업을 output/<language>/<run>/에 생성하고, 컴파일하며 (dotnet build 또는 Java의 경우 mvn compile), 해당 작업에서 여전히 누락된 프로그램과 프로시저를 목록으로 보여줍니다. |
./doctor.sh run --job NAME --language CSharp | 작업 및 그 프로그램: 해당 작업이 실행하는 COBOL 프로그램을 변환하고 (미리 보려면 --dry-run 추가), 최종적으로 끝까지 실행할 수 있도록 작업을 생성합니다. |
자세한 내용은 JCL을 참조하세요.
doctor 스크립트는 종속성을 확인하고 필요한 서비스를 시작합니다.
flowchart LR
A[📁 COBOL, copybook,<br/>BMS, JCL을 source/에 복사] --> B[⚙ ./doctor.sh setup<br/>provider, models, passwords]
B --> C[⌎ ./doctor.sh rekt-full<br/>parse + load graph<br/><i>모델 없음</i>]
...
| 단계 | 모델 호출? | Docker 필요 여부? | 기록 위치 |
|---|---|---|---|
setup | 아니요 (모델 목록만 표시) | Neo4j 이미지를 가져옴 | Config/ai-config.local.env |
rekt-full | 아니요 | 예 (REKT 파서 + REKT Neo4j) | source/.preprocessed/, output/rekt/, REKT Neo4j |
portal | 채팅 전용 | Estate Mission Control의 경우 필요 없음; 그래프 탭은 Neo4j 사용 | 아무것도 아님 (읽기만 함) |
estate / Estate Mission Control | 아니요 | 아니요 (source/에서만 구축됨) | output/estate/ |
convert-only / run | 예 | 마이그레이션 Neo4j (사용자를 위해 시작됨) | output/<language>/<run>/, Data/migration.db, 마이그레이션 Neo4j |
reverse-eng | 예 | 마이그레이션 Neo4j | output/reverse-engineering-details.md, Data/migration.db |
jcl | 아니요 | 아니요 | output/<language>/<run>/ |
flowchart LR
subgraph HOST[🍞 귀하의 컴퓨터]
direction TB
...
모델을 제외한 모든 것이 로컬에서 실행됩니다. 소스 코드는 구성한 제공업체(provider)로 전송되는 프롬프트 내부에만 기기 외부로 나갑니다.
두 개의 Neo4j 인스턴스.
REKT 그래프 (파싱 트리 및 제어 흐름, :7688)와 마이그레이션 그래프 (실행 중 발견된 종속성, :7687)가 있습니다. 포트 및 컨테이너 이름은 Config/ai-config.local.env에서 변경할 수 있습니다.
포털은 호스트에서 실행됩니다 (dotnet run --project McpChatWeb).
만약 컨테이너로 사용하고 싶다면, docker-compose.yml에도 portal 서비스를 추가할 수 있습니다.
Estate Mission Control 및 모델이나 Docker가 필요하지 않습니다.
flowchart TB
S["선택된 프로그램<br/>(--program, --job, 또는 단계별 슬라이스)"] --> FACTS["REKT 파싱에서 가져온 프로그램 사실,<br/>카피북 및 호출 계약<br/>(결정론적, 모델 없음)"]
FACTS --> ANALYZE["CobolAnalyzerAgent<br/>구조 및 로직"]
...
Java 출력물에는 아직 컴파일 게이트가 없습니다. mvn compile로 빌드하여 출력 폴더에서 확인할 수 있습니다. 패리티 검사(parity check)는 보고서를 생성하고 실행을 중지시킬 수 있습니다 (ON_LOW_SCORE=stop), 하지만 복구하지는 않습니다. 'Conversion parity' 및 'Using the generated output'를 참조하십시오.
여기에 표시된 내용은 source/에 있는 공개 IBM Bank-of-Z 샘플을 사용한 것입니다.
Estate 개요: 비즈니스 기능별로 그룹화된 모든 프로그램, 트랜잭션, 화면, 테이블 및 카피북입니다.
Carve-out 계획: 리스크 티어(risk tier), 응집도(cohesion) 및 carve 점수로 순서가 지정된 웨이브(waves) 클러스터링입니다.
단계별 슬라이스 (Stage slice): 변환해야 할 프로그램, 필요한 추가 요소, source/에서 누락된 항목, 그리고 실행할 명령어를 포함합니다.
- 구성 방식
- 빠른 시작
- 사용법: doctor.sh
- 포털
- 리버스 엔지니어링 보고서
- 폴더 구조
- 에이전트 동작 사용자 정의
- 파일 분할 및 명명 규칙
- 아키텍처
- 스마트 청킹(Smart Chunking) 및 토큰 전략
| 요구 사항 | 버전 | 참고 사항 |
|---|---|---|
| .NET SDK | 10.0+ | 다운로드 |
| Docker Desktop | 최신 버전 | Neo4j 실행을 위해 반드시 실행되어야 함 |
| AI Endpoint | — | Azure endpoint + az login 또는 GitHub gh auth login, 또는 API 키 |
이 프로젝트는 모델 기능 자동 감지 기능을 통해 네 개의 AI 제공업체를 지원합니다:
| 제공업체 | 서비스 유형 | 모델 | 인증 방식 | 인터페이스 |
|---|---|---|---|---|
| Azure OpenAI | AzureOpenAI | gpt-5.1-codex-mini, gpt-5.2-chat | API Key 또는 az login (Entra ID) | ResponsesApiClient (Codex) + IChatClient |
| GitHub Copilot | GitHubCopilot | Claude Opus/Sonnet, Codex, GPT, Grok | GitHub PAT (GITHUB_TOKEN) | IChatClient via models.github.ai |
| GitHub Copilot SDK | GitHubCopilotSDK | 모든 Copilot 모델 | gh auth login (CLI) | CopilotChatClient via stdio |
| OpenAI | OpenAI | GPT-4o, o3 등 | OpenAI API key | IChatClient |
모델 인식 추론(Model-Aware Reasoning) — 이 프레임워크는 모델 ID에서 모델 기능을 자동으로 감지하고 그에 맞춰 추론 전략을 조정합니다:
| 모델 계열 | 감지 조건 | 추론 전략 | 적용 방식 |
|---|---|---|---|
| Codex/o-series | 모델 ID에 codex, o1, o3 포함 | reasoning.effort (낮음/중간/높음) | Responses API 또는 AdditionalProperties |
| Claude | 모델 ID에 claude 포함 | budget_tokens를 사용한 확장된 사고 과정 | `AdditionalProperties[ |
| 할당량 (Quota) | 경험치 (Experience) |
|---|---|
| 300K TPM | 작동은 하지만 속도 제한(throttling pauses)으로 인해 느려짐 |
| 1M TPM | 권장 - 원활한 병렬 처리 |
할당량이 높을수록 마이그레이션 속도가 빠릅니다. 이 도구는 여러 파일과 청크를 병렬로 처리하므로, TPM(Tokens Per Minute)이 높을수록 대기 시간이 줄어듭니다.
할당량을 늘리려면: Azure Portal → 사용자의 OpenAI 리소스 → 모델 배포(Model deployments) → 편집(Edit) → 분당 토큰 수(Tokens per Minute)
속도 제한(429 에러)을 피하려면 다음 공식을 사용하여 안전한 병렬 작업 한도를 계산하세요:
TPM × 안전 계수 (SafetyFactor)
MaxParallelJobs = ─────────────────────────────────
토큰당 요청 수 (TokensPerRequest) × 분당 요청 수 (RequestsPerMinute)
여기서:
TPM = 사용자의 Azure 할당량 (분당 토큰 수)
안전 계수 (SafetyFactor) = 0.7 (권장, 아래 참조)
토큰당 요청 수 (TokensPerRequest) = 입력 + 출력 토큰 (~코드 변환의 경우 30,000)
분당 요청 수 (RequestsPerMinute) = 60 / 초당 요청 수 (SecondsPerRequest)
안전 계수(SafetyFactor) 이해하기 (0.7 = 70%):
안전 계수는 할당량 한도 아래에 여유 공간을 확보하여 다음 사항들을 처리합니다:
| 헤드룸이 필요한 이유 | 헤드룸이 없을 때 발생하는 일 |
|---|---|
| 토큰 추정치 편차 | AI 응답 길이는 다양함 - 25K 추정치가 실제로는 35K일 수 있음 |
| 버스트 보호 (Burst protection) | 여러 요청이 동시에 완료될 경우 토큰 사용량이 급증할 수 있음 |
| 재시도 오버헤드 (Retry overhead) | 실패한 요청이 재시도될 때 추가적인 토큰을 소모함 |
| 공유 할당량 (Shared quota) | 동일한 Azure 배포를 사용하는 다른 애플리케이션 |
| 안전 계수 (SafetyFactor) | 사용 사례 (Use Case) |
|---|---|
| 0.5 (50%) | 공유 배포, 보수적, 재시도가 많이 예상됨 |
| 0.7 (70%) | 권장 - 속도와 안전성의 좋은 균형 |
| 0.85 (85%) | 전용 배포, 안정적인 워크로드 |
| 0.95+ |
예시 계산:
| 사용자의 할당량 | 요청당 토큰 수 | 요청 시간 | 안전한 병렬 작업 수 (Safe Parallel Jobs) |
|---|---|
| 300K TPM | 30K | 30초 | (300,000 × 0.7) / (30,000 × 2) = 3-4개 작업 |
| ... |
appsettings.json에 설정:
{
이 프로젝트는 Semantic Kernel 대신 **Microsoft Agent Framework** (`Microsoft.Agents.AI.*`)를 사용합니다.
Semantic Kernel 대신 Agent Framework를 사용하는 이유?
IChatClient추상화: Responses API와 Chat Completions API 모두에 대한 네이티브 지원을 제공하여 LLM API 측면에서 미래 지향적(future proof)입니다.- 더 나은 스트리밍 및 비동기 패턴
- 가벼운 의존성 구조 (Lighter dependency footprint)
git clone https://github.com/Azure-Samples/Legacy-Modernization-Agents.git
cd Legacy-Modernization-Agents
./doctor.sh setup # 1. AI 공급자 및 자격 증명 구성
...
설정 마법사 없이 수동으로 설정하기
# 1. Azure OpenAI 구성
cp Config/ai-config.env.example Config/ai-config.local.env
# 수정: _MAIN_ENDPOINT (필수), _CODE_MODEL / _CHAT_MODEL (선택)
...
마이그레이션을 실행할 때는 항상 dotnet run을 직접 사용하지 말고 ./doctor.sh run을 사용하세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub Codex tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기