
Amazon Connect 플로우의 JSON 차분을 Mermaid 다이어그램으로 시각화하여 확인 작업을 쾌적하게 만들기
요약
Amazon Connect의 컨택트 플로우 JSON 차분을 Mermaid 다이어그램으로 시각화하여 코드 리뷰 효율을 높이는 방법을 소개합니다. LLM을 활용해 복잡한 JSON 변경 사항 중 본질적인 로직 변화만 추출하여 시각적으로 확인하는 워크플로우를 제안합니다.
핵심 포인트
- Amazon Connect JSON의 ID/좌표 변경으로 인한 노이즈 해결
- LLM 프롬프트를 활용한 JSON 차분의 Mermaid 다이어그램 변환
- Claude 및 Codex CLI를 이용한 시각화 결과 비교
- PR 리뷰어의 부담 경감 및 배포 안정성 확보
안녕하세요, miruky입니다.
Amazon Connect의 컨택트 플로우 (Contact Flow)를 에스포트(Export)한 JSON으로 Git 관리할 때, PR(Pull Request)을 올리기 전의 차분(Diff) 확인에서 어려움을 겪습니다. 플로우를 조금만 바꿔도 GitHub의 차분이 온통 빨갛게 변하며 대량으로 발생하여, 본질적인 변경 사항을 읽기 어려워지기 때문입니다. Amazon Connect를 사용하는 프로젝트에서는 흔히 발생하는 일이라고 생각합니다. 물론, PR을 리뷰하는 쪽의 부담도 커집니다.
JSON의 차분을 추출하는 도구는 예전부터 있었지만, Amazon Connect에 적합한 형태로 비주얼적으로 알기 쉽게 출력해 주는 것은 많지 않습니다. 그렇다면, AI를 사용합시다.
이 기사에서는 기본적으로 PR을 올리는 쪽의 관점에서, 에스포트한 플로우의 JSON으로부터 develop 브랜치와의 분기점 이후의 차분을 추출하여, Mermaid 다이어그램으로 보는 방법을 소개합니다. 이 방법을 사용하면 결과적으로 리뷰어의 부담도 경감할 수 있습니다.
착상은 AWS 공식 샘플에서 얻었지만, 결국 프롬프트(Prompt) 하나입니다. AWS 샘플에서는 Amazon Bedrock을 경유하지만, 이 기사에서는 간편함을 중시하여 수중에 있는 Claude나 Codex를 사용하여 실현합니다. 이 기사에서는 Codex CLI (gpt-5.5)와 Claude Opus 4.8 모두에서 동일한 JSON과 프롬프트를 시도하여, 출력되는 모습도 비교합니다.
- 생(Raw) JSON 차분이 리뷰하기 어려운 이유
- 착상 원천인 AWS 샘플의 내용
- 로컬 LLM으로 develop 브랜치와의 차분을 Mermaid화 하기
- 셋업 및 실행 절차
- 실전, Codex CLI (gpt-5.5)
- 실전, Claude Opus 4.8
- Claude Opus 4.8과 Codex CLI (gpt-5.5) 비교
- 실무에서 사용할 때는 어떻게 해야 하는가
전제로 하는 운용은 심플합니다. 컨택트 플로우를 JSON으로 에스포트하여 GitHub에서 관리하고, 배포는 Amazon Connect 인스턴스 상에서 수동으로 실행합니다. feature 브랜치에서 작업하여 develop 브랜치로 집약하고, PR을 내기 전에 로컬 단계에서 변경 사항을 파악하고 싶다는 것입니다.
그런데 컨택트 플로우의 JSON은 각 액션(Action)이 고유한 Identifier를 가지며, Metadata에 디자이너 상의 좌표를 가집니다. 이 때문에 ID가 재부여되거나 블록을 움직이는 것만으로도, 로직이 동일하더라도 차분이 대량으로 발생합니다. 문구를 하나만 바꿔도 다음과 같이 됩니다.
{
- "Identifier": "a1b2c3d4-1111-1111-1111-111111111111",
+ "Identifier": "f9e8d7c6-9999-9999-9999-999999999999",
...
}
문구가 하나 바뀌었을 뿐인데, ID와 좌표가 상당히 방해가 됩니다. PR을 올리는 쪽으로서도 어디가 본질적인 변경인지 설명하기 어려워집니다. 아마콘(Amazon Connect) 프로젝트에 종사해 보신 분이라면 공감하시겠지만, 이 작업은 상당히 번거롭습니다. 그래서 차분을 꼼꼼히 쫓기 전에, 실제로 구동하여 예상한 플로우대로 작동하는지 체크하고 OK라고 확인하고 싶어지는 상황도 있습니다.
다만, 말할 필요도 없겠지만, 플로우 블록이 의도치 않게 사라져서 디그레션(Degression)이 발생했을 가능성도 있으므로 평범하게 위험합니다 (플로우가 연결되어 있지 않으면 아마콘 인스턴스 상에서 경고가 뜨지만, 만약 연결되어 버렸다면 알아차릴 수 없습니다).
PR을 올리기 전에 스스로 차분을 설명할 수 있는 상태로 만들어 두는 것이 안전하며, 결과적으로 리뷰어의 부담 경감으로도 이어집니다.
aws-samples는 AWS가 GitHub 상에서 공개하고 있는 샘플 코드 모음입니다. AWS Samples의 설명에 따르면, AWS 서비스의 구체적인 유즈케이스(Use Case)나 시나리오를 보여주는 교육용 구현 예시이며, 지원 대상 프로덕트 그 자체는 아니라고 되어 있습니다.
이 안에 컨택트 플로우의 차분을 시각화하는 connect-contact-flow-comparison-github-action이 있습니다. 플로우의 JSON이 push되면 기동하며, 직전 커밋과 현재 커밋을 비교하여 Mermaid가 포함된 HTML 리포트를 출력하는 GitHub Action입니다. 내부에서는 GitHub API를 경유하여 변경 전후의 JSON을 취득하고, Amazon Bedrock 상의 Claude 3.5 Sonnet에 비교를 의뢰합니다.
아래의 README에서는 지정한 컨택트 플로우 (Contact Flow) 디렉토리 하위에 변경 사항이 push되면 워크플로우가 동작하여, 비교 결과인 HTML과 Bedrock API의 메트릭스 리포트 (Metrics Report)를 GitHub Actions의 artifact로 출력하는 흐름이 설명되어 있습니다.
주목해야 할 점은 차분 판정의 본체인 compare_contact_flows()입니다.
여기서 수행하는 작업은 "① 두 개의 JSON을 읽기", "② 비교를 의뢰할 프롬프트 (Prompt) 구성하기", "③ Bedrock을 경유하여 Claude에게 전달하기", "④ 반환된 코드 블록을 저장하기"의 4가지뿐입니다.
제공되는 프롬프트는 "Mermaid로 차분을 그리고, 삭제는 빨간색, 추가는 초록색, 변경은 주황색으로 표시하며, Lambda나 큐 (Queue)의 ARN 및 이름까지 빠짐없이 요약하라"는 내용입니다.
아래 src/get_flows.py의 compare_contact_flows() 주변에서는 JSON 읽기, 프롬프트 생성, Bedrock 호출, 생성된 HTML 저장 처리가 모여 있습니다.
Bedrock 호출, 재시도 (Retry), 토큰 수 및 레이턴시 (Latency) 메트릭스 수집은 src/bedrock_utils.py 측으로 분리되어 있습니다.
여기서 중요한 점은, 컨택트 플로우를 구조 해석하는 코드가 단 한 줄도 없다는 것입니다. 대조 작업도 도표 생성도 모두 LLM에 맡기고 있으며, Bedrock의 용도는 말하자면 Claude를 구동하기 위한 장소일 뿐입니다. 따라서, 수중에 있는 Claude나 Codex에서 동일한 프롬프트를 실행하면, 동일한 사고방식을 로컬에서도 재현할 수 있습니다.
AWS 샘플이 CI와 Bedrock으로 수행하던 처리를 로컬의 git과 LLM 에이전트 (Agent)로 대체합니다.
비교의 기점을 직전 커밋이 아닌 develop 브랜치와의 분기점으로 잡는 것이 포인트이며, 이를 통해 브랜치 전체의 변경 사항을 커밋되지 않은 상태에서도 확인할 수 있습니다. 게다가 LLM에게 비교를 시키면, ID나 좌표의 변동 (Fluctuation)을 무시하고 의미적인 차분만을 추출할 수 있기 때문에, PR을 올리기 전의 셀프 리뷰와 설명 준비가 상당히 수월해집니다. 또한, 이를 PR의 description (코멘트)에 붙여넣으면 리뷰어도 확인하기가 훨씬 편해질 것입니다.
여기서 해야 할 일은, 비교용으로 변경 전 JSON과 변경 후 JSON 두 개를 준비하여 이를 Claude나 Codex에 전달하는 것입니다.
이 기사에서는 다음 상태를 전제로 합니다.
- 컨택트 플로우의 JSON을 Git으로 관리하고 있음
- 작업 브랜치는 feature 브랜치임
- 비교 원본은 develop 브랜치와의 분기점임
- 변경된 JSON은 아직 커밋 전이어도 무방함
- 로컬에서 Claude Code 또는 Codex CLI를 사용할 수 있음
먼저, develop 브랜치와 현재 작업 브랜치가 어디서 갈라졌는지 가져옵니다.
BASE=develop
MB=$(git merge-base "$BASE" HEAD)
MB는 develop 브랜치와 현재 브랜치의 분기점입니다. 이곳을 비교 원본으로 설정하면, 커밋된 변경 사항뿐만 아니라 작업 트리 (Working Tree)에 남아 있는 미커밋 변경 사항도 한꺼번에 볼 수 있습니다.
다음으로, 분기점 기준으로 변경된 JSON을 나열합니다.
git diff --name-only "$MB" -- '*.json'
예를 들어, 다음과 같은 결과가 나왔다고 가정해 봅시다.
backend/connect/dev/CustomerLookup-AI-Analyzer.json
이 파일을 비교 대상인 컨택트 플로우 JSON으로 취급합니다.
기존 플로우를 변경한 경우에는, develop 브랜치와의 분기점에 있는 JSON과 현재 작업 트리 측의 JSON을 각각 파일로 내보냅니다.
FLOW_PATH=backend/connect/dev/CustomerLookup-AI-Analyzer.json
git show "$MB:$FLOW_PATH" > flow.base.json
cp "$FLOW_PATH" flow.current.json
여기서 생성되는 파일은 다음 두 가지입니다.
flow.base.json: develop 브랜치와의 분기점에 있는 변경 전 JSONflow.current.json: 현재 작업 트리 측의 변경 후 JSON
기존 플로우를 비교하는 것이라면, 이 두 파일을 LLM에 전달하는 것으로 준비가 완료됩니다.
새로 추가된 플로우는 develop 브랜치와의 분기점 쪽에 파일이 존재하지 않습니다. 그 경우 git show는 실패합니다.
신규 플로우로서 비교하고 싶은 경우에는 변경 전을 빈 JSON으로 만듭니다.
FLOW_PATH=backend/connect/dev/new-inquiry-flow.json
printf '{}\n' > flow.base.json
cp "$FLOW_PATH" flow.current.json
프롬프트 측에서 "Flow1이 비어 있다면 신규 생성으로 취급한다"라고 지시해 두면, 모두 추가된 것으로 간주하여 Mermaid로 시각화할 수 있습니다.
마지막으로, flow.base.json과 flow.current.json을 Claude Code 또는 Codex CLI에 읽히고 다음 프롬프트를 전달합니다. AWS 샘플 지시사항을 활용하면서, 출력 대상을 Mermaid와 Markdown으로 변경했습니다.
2개의 Amazon Connect 컨택트 플로우 (Contact Flow) JSON (변경 전=Flow1/develop 브랜치와의 분기점 측, 변경 후=Flow2/작업 트리 측)을 비교하여,
차이점을 하나의 flowchart TD와 변경 요약(Summary)으로 출력해 주세요.
요건:
...
실제로는 작업 디렉토리에 flow.base.json과 flow.current.json을 둔 상태에서, Claude Code나 Codex CLI에 "이 두 파일을 읽고 위 프롬프트대로 차이점을 출력해 주세요"라고 요청하기만 하면 됩니다.
매번 붙여넣는 것이 번거롭다면, 에이전트(Agent)에게 절차 자체를 학습시킵니다. Claude Code라면 ~/.claude/skills/amazon-connect-flow-diff/SKILL.md에, Codex라면 프로젝트 직하의 AGENTS.md에 위의 git 절차와 프롬프트를 적어 두면, 컨택트 플로우의 차이점을 요청하는 것만으로 동작합니다.
예제로 CustomerLookup-AI-Analyzer.json이라는 컨택트 플로우를 사용하겠습니다.
이번 변경 사항은 Lambda의 에러 시 전이(Transition)입니다.
변경 전에는 ConnectCustomerLookup (Lambda)의 에러가 일반적인 인사 메시지로 돌아가도록 되어 있었습니다. 변경 후에는 에러 안내 메시지를 재생한 뒤 연결을 끊는 전용 루트로 교체되었습니다.
먼저 GitHub의 차이점(Diff)만 보면 ID나 좌표 변경이 많아 보입니다.
이 차이점만으로도 읽지 못하는 것은 아니지만, conditionMetadata.id나 position의 추가가 섞여 있기 때문에 실제로 어떤 전이가 바뀌었는지 추적하기 어렵습니다.
그래서 flow.base.json과 flow.current.json을 준비하고, Codex CLI에 제4장의 프롬프트를 전달했습니다.
Codex는 connect-flow-diff.mmd와 connect-flow-diff.md를 생성했습니다. 생성된 Mermaid는 전체 플로우를 포함하고 있었지만, 기사에서는 차이점을 알 수 있는 주요 부분으로 압축하여 게재합니다.
출력된 변경 요약 또한 GitHub의 JSON 차이점보다 훨씬 읽기 쉬워졌습니다.
개요
Lambda ConnectCustomerLookup의 에러 시 전이가,
일반적인 인사 메시지로 돌아가는 루트에서,
...
GitHub의 차이점에서는 ID나 좌표 변경에 묻혀 있었지만, Codex의 출력에서는 "Lambda의 에러 시 전이가 바뀌었다", "에러 안내 메시지와 연결 끊기가 추가되었다"와 같이 논리적인 차이점으로 정리되어 있습니다.
실제로 생성된 Markdown에는 Lambda ARN, Lex Alias ARN, TransferContactToQueue 및 InvokeFlowModule가 차이점에 해당하지 않는다는 사실도 기록되어 있었습니다.
Claude Opus 4.8에서도 동일한 flow.base.json, flow.current.json, 프롬프트를 사용하여 확인했습니다. 입력 조건은 Codex 버전과 동일합니다. 다른 점은 실행하는 에이전트뿐입니다.
Claude도 무사히 connect-flow-diff.mmd와 connect-flow-diff.md를 생성해 주었습니다. Claude 측의 출력은 차이점만을 짧게 요약하기보다는, 기존 컨택트 플로우 전체를 유지한 상태에서 추가·변경·삭제된 전이를 색상으로 나타내는 형식이었습니다.
기사 게재를 위해 조금 짧게 줄이면 다음과 같은 그림이 됩니다.
Claude의 도표가 읽기 쉬운 점은, 통상적인 플로우 (Flow)를 남겨두면서 Lambda 에러 발생 시의 구 경로와 신 경로를 같은 위치에 나란히 배치했다는 점입니다. NoMatchingError가 이전에는 통상적인 인사로 흘러갔던 점과, 변경 후에는 에러 안내로 흘러간다는 점을 도표만으로도 쉽게 추적할 수 있습니다.
검출 결과로는 Codex와 마찬가지로 다음 변경 사항을 포착했습니다.
MessageParticipant
의 에러 안내 문구가 추가됨 -
DisconnectParticipant
가 추가됨 -
InvokeLambdaFunction
의 NoMatchingError 전이가 교체됨 - 기존 전이인
NoMatchingError -> お電話ありがとうございます。
가 삭제됨
출력된 요약을 기사용으로 정리하면 다음과 같습니다.
Claude 측 생성 결과
추가
- MessageParticipant
...
Claude 측에서 특히 좋았던 점은, ID만 변경된 액션(Action)을 '의미적으로 동일'하게 분류했다는 점입니다. Amazon Connect의 JSON에서는 ID만 바뀌어도 Git 차분 (Diff)이 크게 보이기 때문에, PR (Pull Request)에서 설명해야 할 차분과 보지 않아도 되는 차분을 구분해 주는 것은 실무상 상당히 도움이 됩니다.
한편, Claude가 생성한 Mermaid는 전체 플로우를 상세하게 포함하고 있어, 그대로 PR 설명란이나 기사에 붙이기에는 다소 길었습니다. 하지만 검출한 내용은 Codex 버전과 동일합니다. 실무상으로는 Claude와 Codex 모두 문제없이 사용할 수 있습니다.
동일한 입력과 프롬프트(Prompt)를 사용하더라도, 에이전트(Agent)에 따라 도표를 만드는 방식이나 요약의 입도 (Granularity)는 달라집니다. 이번 검증에서는 Claude Opus 4.8과 Codex CLI (gpt-5.5) 모두 본질적인 차분을 포착했습니다.
결론적으로, 어느 쪽을 사용해도 문제없습니다 . 차이가 발생하는 지점은 검출 정밀도라기보다, 출력 방식과 요약의 입도입니다.
이미지에서 보듯, 변경 검출과 전이 이해 모두 문제없었습니다. 차이점은 Claude는 전체 플로우에 가깝게 조금 더 상세하고, Codex는 차분 중심으로 짧게 요약하기 쉽다는 점입니다. PR 전의 셀프 리뷰 (Self-review)라는 목적이라면 어느 쪽을 사용해도 충분합니다.
LLM으로 비교하는 이상, 출력은 실행할 때마다 조금씩 흔들립니다. PR을 올리기 전 확인 시에는 도표에만 의존하지 말고 원래의 JSON 차분과 함께 확인하는 것을 권장합니다.
이 방법은 PR을 올리기 전의 셀프 리뷰로 사용하는 것이 가장 자연스럽습니다. 동작을 확인하기 전에 Git 상에서 "어떤 블록이 늘어났는지", "어떤 전이가 바뀌었는지"를 대략적으로 파악할 수 있습니다.
또한, PR 작성자가 차분의 요점을 도표와 짧은 요약으로 덧붙여 놓으면, 리뷰어 (Reviewer)는 가공되지 않은 JSON 차분을 처음부터 전부 쫓아가지 않아도 확인해야 할 부분으로 쉽게 진입할 수 있습니다.
PR을 올리는 입장에서는 Claude나 Codex가 출력한 내용을 그대로 전부 붙여넣기보다, 다음 3가지로 압축하는 것이 읽기 편합니다.
- Mermaid 도표
- 추가, 변경, 삭제에 대한 짧은 요약
- 확인이 필요한 전이

이번 사례라면, "Lambda 에러 발생 시의 NoMatchingError가 통상적인 인사가 아닌 에러 안내로 향하게 되었다"는 것을 파악할 수 있다면 충분합니다.
수동으로 빠르게 확인하고 싶다면 Claude Code나 Codex CLI로도 충분합니다. flow.base.json과 flow.current.json을 만들고 프롬프트를 던지면, 몇 분 안에 PR 설명용 도표와 요약을 만들 수 있습니다.
팀 전체가 동일한 형식의 리포트를 남기고 싶다면, 제2장의 AWS 샘플 Action처럼 GitHub Actions로 통합하는 것이 운영하기 쉽습니다. 로컬 확인은 PR 작성자의 셀프 리뷰, CI 확인은 팀 공통의 보조 자료라는 식으로 용도를 구분하여 사용하는 것을 추천합니다.
규모가 큰 컨택트 플로우 (Contact Flow)를 통째로 전달하면 도표가 너무 커집니다. 토큰 (Token) 제한에 가까워질 수도 있고, 도표를 읽기 어려워질 수도 있습니다.
그럴 경우에는 변경된 액션과 그 전후의 전이만을 추출하여 전달합니다. 전체 플로우를 직접 확인하고 싶은 경우라도, PR에 첨부하는 도표는 차분 주변부로 한정하는 것이 전달력이 더 높습니다.
실제 운영 시에는 생성된 Markdown을 그대로 PR이나 문서 (Confluence 등의 러프한 문서)에 붙여넣기 전에, 공개해도 좋은 정보만 남아 있는지 확인합니다. 특히 LLM은 "변경 요약에 포함해 달라"고 요청한 항목을 그대로 써 내려가기 때문에, 편리한 반면 확인 누락이 발생하기 쉽습니다.
여기까지 읽어주셔서 감사합니다.
이번 내용의 요점입니다.
- Amazon Connect의 플로우는 ID나 좌표 노이즈로 인해, 생(raw) JSON 차분(diff)을 리뷰하기 어렵다
- AWS 샘플 비교 도구의 본체를 프롬프트 1개로 분해할 수 있었기에, 로컬에서도 작게 재현할 수 있었다
- 동일한 프롬프트를 수중에 있는 Claude나 Codex에서 실행하면, develop 브랜치와의 분기점 이후 차분을 Mermaid로 시각화할 수 있어 PR(Pull Request) 전 셀프 리뷰에 활용할 수 있다
- Claude와 Codex 모두 실무상 문제는 없었으며, 차이점은 도표를 보여주는 방식과 요약(summary)의 입도(granularity)였다
먼저 가지고 계신 플로우 하나로 시도해 보세요.
그럼 다음에 또 만납시다.
- aws-samples/connect-contact-flow-comparison-github-action - GitHub
- README.MD - aws-samples/connect-contact-flow-comparison-github-action
- get_flows.py - aws-samples/connect-contact-flow-comparison-github-action
- bedrock_utils.py - aws-samples/connect-contact-flow-comparison-github-action
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기