
Excel 지시서를 AI가 읽지 못하는 이유 ─ 의미가 '서식'에 담겨 있을 때
요약
Excel 파일의 서식(글자 색상, 굵기 등)에 담긴 지시 사항이 AI에게 전달될 때 손실되는 문제를 분석합니다. 특히 openpyxl을 사용할 때 셀 내부의 부분적인 서식이 누락되는 원인과 이를 해결하기 위한 접근 방식을 다룹니다.
핵심 포인트
- Excel의 서식(색상, 굵기 등)이 단순 장식이 아닌 지시 사항인 경우 데이터 손실 발생
- openpyxl의 일반적인 로드 방식은 셀 내부의 부분적 글자 색상 정보를 놓침
- 말풍선이나 도형 내 텍스트는 일반적인 셀 스캔 방식으로 추출 불가
- 입력 형식을 바꿀 수 없는 환경에서는 읽기 측(AI 처리 로직)의 대응이 필수적
수탁 업무로 WordPress 사이트 유지보수를 하고 있습니다. 고객으로부터 전달받는 수정 지시서에 따라 사이트를 수정하는 작업을 Claude Code에 맡기는 메커니즘을 만들었습니다.
대체로 잘 작동하고 있습니다만, 지시 사항을 놓치는 일이 발생합니다.
원인을 추적해 본 결과, AI의 독해력 문제가 아니었습니다. 애초에 지시 사항이 AI에게 전달되지 않았다는 것이 결론입니다.
동일한 구조의 문제는 Excel을 입력값으로 사용하는 AI 처리에서 널리 발생할 것이라고 생각합니다. 검증 코드와 함께 공유합니다.
- Excel의 지시가 '서식'에 담겨 있을 때, 텍스트 추출 시 무엇이 손실되는가
openpyxl의 일반적인 로드(loading) 방식으로는 셀 내부의 부분적인 글자 색상이 완전히 사라진다는 점- 말풍선·도형 내의 텍스트는 셀 스캔(cell scanning) 시 전혀 가져올 수 없다는 점
- 서식의 의미를 유지한 채 텍스트화하는 구현
검증 환경은 Python 3 / openpyxl 3.1.5입니다.
수탁 현장에서 전달되는 수정 지시서는 다음과 같은 구조로 되어 있는 경우가 있습니다.
- 빨간 글씨 = 교체할 문구
- 굵은 글씨 (Bold) = 변경箇所
- 셀 배경색 = 대응 완료 / 미대응
- 취소선 = 삭제할 내용
- 스크린샷 위의 말풍선 = 지시의 본체
사람이 열어보면 한눈에 알 수 있습니다. 고객이 정성스럽게 만들어 주신 결과물이기도 합니다.
문제는, 이 색상이나 굵기가 단순한 장식이 아니라 지시 그 자체라는 점입니다.
그리고 텍스트로 추출하는 시점에서 서식은 탈락합니다. 남는 것은 문자열뿐입니다.
# 사람이 보고 있는 것
B3: 새로운 헤드라인 텍스트 ← 빨간 글씨이므로 "이것으로 교체한다"는 것을 알 수 있음
# AI에게 전달되는 것
...
수탁 업무이므로, 고객에게 "AI에게 읽히고 싶으니 작성 방식을 바꿔달라"고 말할 수 없습니다. 입력 측을 정형화하는 접근 방식은 선택지에 없습니다. 읽기 측에서 대응해야 합니다.
먼저 기본부터 확인하겠습니다. 검증용 파일을 만듭니다.
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill
bw = Workbook(); ws = wb.active
...
단순하게 값만 가져오면 당연하게도 서식은 사라집니다.
from openpyxl import load_workbook
ws = load_workbook("shijisho.xlsx").active
for row in ws.iter_rows():
...
B2 헤드라인을 변경해 주세요
B3 새로운 헤드라인 텍스트 ← 빨간 글씨였던 정보가 사라짐
B4 사업 내용의 세 번째 ← 굵은 글씨였던 정보가 사라짐
...
cell.font와 cell.fill을 보면 가져올 수 있습니다. 여기까지는 예상대로입니다.
여기서부터가 본론입니다.
실제 지시서에서는 하나의 셀 안에서 일부만 색상이 바뀌어 있는 경우가 있습니다.
헤드라인을 새로운 텍스트로 변경
~~~~~~~~~~~~ 이 부분만 빨강
이 경우, 일반적인 load_workbook()으로는 빨간색 정보가 완전히 손실됩니다.
from openpyxl import Workbook, load_workbook
from openpyxl.cell.rich_text import CellRichText, TextBlock
from openpyxl.cell.text import InlineFont
...
cell.value는 결합된 문자열이 되며, cell.font에도 색상이 들어가지 않습니다. 셀 전체로서는 서식이 지정되지 않은 상태로 취급됩니다.
이것이 지시 사항을 놓치게 만드는 주범이었습니다. "셀의 폰트를 보면 괜찮겠지"라고 생각하면 여기서 막히게 됩니다.
openpyxl 3.1 이후 버전은 로드 시 rich_text=True를 지정하면 CellRichText로 가져올 수 있습니다.
from openpyxl import load_workbook
c = load_workbook("rich.xlsx", rich_text=True).active["A1"]
for part in c.value:
...
plain: 헤드라인을
color: FFFF0000 text: 새로운 텍스트
plain: 로 변경
부분적인 서식이 추출되었습니다.
지시서에 스크린샷이 붙어 있고, 그 위에 말풍선으로 지시 사항이 적혀 있는 경우입니다.
도형 내의 텍스트는 셀이 아니라 xl/drawings/*.xml에 저장되어 있습니다.
.xlsx는 ZIP 형식이므로 직접 읽을 수 있습니다.
import zipfile, re
with zipfile.ZipFile("shijisho.xlsx") as z:
for name in z.namelist():
...
xl/drawings/drawing1.xml 이 헤드라인을 교체해 주세요
xl/drawings/drawing1.xml 이미지는 별도로 보냅니다
동일한 파일을 iter_rows()로 순회해도, 이 2건은 전혀 나타나지 않습니다. 셀에는 존재하지 않기 때문입니다.
지시서가 「스크린샷 + 말풍선」 형식일 경우, 셀 순회만으로 끝내려 하면 지시 사항의 본체를 통째로 놓치게 됩니다.
구현 시 빠졌던 함정입니다.
글자 색상이 테마 색상(Theme Color)으로 지정되어 있는 경우, color.rgb는 ARGB 문자열을 반환하지 않습니다.
col = ws["A2"].font.color
print(col.type) # 'theme'
print(col.theme) # 4
...
col.rgb가 에러 메시지 문자열을 반환합니다. 따라서 다음과 같은 판정은 통과되어 버립니다.
# NG: 테마 색상일 때 에러 메시지가 "색"으로 취급됨
if isinstance(col.rgb, str):
...
color.type을 먼저 확인해야 합니다.
# OK
if getattr(col, "type", None) == "rgb":
rgb = col.rgb
게다가 기본 글자 색상(검정)은 theme=1로 모든 셀에 붙어 있습니다. 이를 제외하지 않으면 출력이 노이즈로 가득 차게 됩니다.
이상의 내용을 바탕으로 작성한 추출 스크립트입니다.
"""Excel 지시서를 서식의 의미를 유지한 채 텍스트화한다."""
import re
import sys
...
실행 결과입니다.
## 셀
A1 페이지
B1 수정 내용
...
서식의 의미가 【】로서 문자열에 포함되었습니다. 이 형태로 만든 뒤 AI에게 전달하면, 적어도 정보가 전달되지 않는 상태는 피할 수 있습니다.
색상 코드의 의미(FFFF0000 = 교체 문구 등)는 프로젝트마다 다르기 때문에, 대응표를 별도로 프롬프트에 포함하고 있습니다.
솔직히 말씀드리면, 이것으로 모든 문제가 해결된 것은 아닙니다.
색상 코드와 의미의 대응은 프로젝트마다 사람이 정의해야 한다. 고객이 도중에 운영 방식을 바꿀 수도 있다 -
스크린샷 이미지 자체에 적힌 지시 (이미지 편집 소프트웨어로 화살표나 글자를 입힌 것)는 이 방법으로 가져올 수 없다. 이미지로서 별도로 읽게 해야 한다 -
결국, 최종 확인은 사람이 한다는 전제하에 운영하고 있다
그럼에도 불구하고, "지시가 전달되지 않은 것"과 "지시는 전달되었으나 해석을 잘못한 것"은 별개의 문제입니다. 전자를 해결해 두면 원인 파악이 훨씬 쉬워집니다.
Excel을 입력으로 사용하는 AI 처리에서는, 의미가 서식에 실려 있지 않은가를 가장 먼저 의심하는 것이 빠를 것이라고 생각합니다. 특히 사람이 사람을 향해 쓴 문서는 서식에 의미를 담는 경향이 있습니다.
이 메커니즘을 포함한 운영 전체(유지보수 작업을 건당 2시간에서 15분으로 단축한 이야기와, 굳이 완전 자동화하지 않은 이유)는 note에 작성했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기