안녕하세요! LLM(거대 언어 모델)을 활용한 비즈니스 분석은 현대 데이터 과학의 핵심 트렌드입니다. 특히 Python과 Pandas를 이용해 운영 및 재무 데이터를 처리하고, Qwen과 같은 로컬 LLM으로 인사이트를 도출하는 파이프라인은 강력한 비즈니스 의사결정 도구가 될 수 있습니다. 하지만 이 과정에서 예상치 못한 문제가 발생하기도 합니다. 오늘 다룰 내용은 Pandas DataFrame에 분명히 데이터가 존재하는데도 Qwen LLM이 “사용 가능한 비즈니스 지표가 없다”고 응답하는 당혹스러운 상황에 대한 분석과 해결책입니다.
이 문서는 로컬 LLM을 활용하여 비즈니스 통찰을 얻으려는 개발자들이 데이터 전처리 과정에서 정보 손실을 방지하고, LLM이 데이터를 정확하게 해석하도록 돕는 구체적인 디버깅 방법과 최적화 팁을 제공합니다. 지금부터 함께 문제의 원인을 파헤치고, 효과적인 해결 방안을 모색해 봅시다.
1. 에러 발생 상황
한 개발자가 Jupyter Notebook 환경에서 Python, Pandas, Qwen 2.5 1.5B Instruct (llama-cpp-python 기반)를 활용하여 예측 및 비즈니스 분석 파이프라인을 구축하고 있었습니다. 이 파이프라인은 운영, 재무 데이터를 처리하고, 통계 예측을 생성한 뒤, 로컬 LLM을 통해 비즈니스 인사이트를 도출하는 구조입니다.
발생한 문제
op (일별 운영 데이터), fin (재무 거래 데이터), rv (필터링된 수익 거래), BT (백테스팅 예측 및 실제 값)와 같은 여러 Pandas DataFrames에는 분명히 유효한 데이터가 채워져 있었습니다. 개발자는 DataFrame을 자동으로 발견하고, 관련 열을 선택하며, 기술 통계를 계산한 뒤, 이 요약 정보를 JSON 형태로 Qwen LLM에 전달하는 함수를 작성했습니다.
그러나 LLM으로부터 다음과 같은 예상치 못한 응답을 받았습니다.
{
"project_health": "Data Belum Cukup",
"insight": "Tidak ada indikator yang tersedia untuk menilai kesehatan proyek, performa keuangan, atau kinerja operasional.",
"risk": "Tidak ada indikator yang tersedia untuk menilai risiko.",
"recommendation": "Perlu penambahan data untuk memenuhi kriteria penilaian kesehatan bisnis."
}
이는 인도네시아어로 “데이터가 충분하지 않습니다”, “프로젝트 상태, 재무 성과, 운영 성과를 평가할 수 있는 지표가 없습니다”, “위험을 평가할 수 있는 지표가 없습니다”, “비즈니스 건강 평가 기준을 충족하려면 추가 데이터가 필요합니다”라는 의미입니다. DataFrame이 데이터를 포함하고 있음에도 불구하고, LLM은 어떠한 지표도 찾을 수 없다고 응답한 것입니다.
관련 코드 스니펫
DataFrame을 발견하고 관련 열을 식별하는 로직은 다음과 같습니다:
frames = {
name: obj
for name, obj in list(globals().items())
if isinstance(obj, pd.DataFrame) and not obj.empty
}
keywords = [
"revenue", "budget", "actual", "spend",
"cost", "profit", "forecast", "ticket",
"problem", "provision", "register",
"branch", "target"
]
relevant_cols = [
col for col in df.columns
if any(k in str(col).lower() for k in keywords)
]
이후 숫자형 열에 대해 최소, 최대, 평균, 총계, 중앙값 등의 통계를 계산하고 JSON으로 직렬화됩니다. LLM에 전달하기 전에는 토큰 예산(token budget)을 관리하는 로직이 있습니다.
max_input_tokens = 950
while len(llm.tokenize(
compact_text.encode("utf-8")
)) > max_input_tokens:
# Remove categorical distributions first.
# If necessary, remove additional table summaries.
...
그리고 LLM은 다음과 같이 호출됩니다.
response = llm.create_chat_completion(
messages=messages,
temperature=0.1,
max_tokens=350,
response_format={"type": "json_object"}
)
개발자는 JSON 요약 생성 또는 토큰 예산 축소 로직에서 필요한 정보가 손실되었을 가능성을 의심하고 있습니다. 또한, LLM이 재무, 운영, 예측 지표 간의 관계를 이해할 만큼 충분한 컨텍스트를 받지 못했을 수도 있다는 우려도 있습니다.
2. 명확한 발생 원인
문제의 핵심은 LLM이 ‘사용 가능한 지표가 없다’고 응답하는 것이 DataFrames에 데이터가 없기 때문이 아니라, 필요한 정보가 LLM에 정확히 도달하지 못했거나, 도달했더라도 LLM이 해석하기 어려운 형태로 가공되었을 가능성이 매우 높다는 것입니다.
가장 유력한 원인: 토큰 예산 축소 로직에서의 정보 유실
제공된 코드에서 while len(llm.tokenize(...)) > max_input_tokens: 부분은 토큰 예산을 초과할 경우 입력 데이터를 축소하는 역할을 합니다. 이때 # Remove categorical distributions first. # If necessary, remove additional table summaries. 주석이 달린 부분이 핵심입니다. 숫자형 지표의 요약 통계(최소, 최대, 평균, 총계, 중앙값)가 “additional table summaries”로 간주되어 제거되었을 가능성이 큽니다.
- 중요 지표 제거: 비즈니스 인사이트를 도출하는 데 필수적인
revenue,cost,profit등의 핵심 통계값(평균, 총계 등)이 토큰 예산을 맞추기 위해 가장 먼저 삭제되었을 수 있습니다. LLM은 결국 “텅 빈” 요약본을 받게 되어 지표를 찾을 수 없다고 판단합니다.
두 번째 원인: JSON 요약 구조의 불충분성 또는 모호성
JSON으로 요약된 데이터의 구조 자체가 LLM이 쉽게 이해하기 어려울 수 있습니다.
- 컨텍스트 부족: 각 DataFrame의 요약이 서로 어떤 관계를 가지는지, 각 숫자가 무엇을 의미하는지(예: 단위, 기간)에 대한 명시적인 설명 없이 단순 숫자 나열에 그쳤다면 LLM은 이를 비즈니스 지표로 해석하기 어렵습니다.
- 모호한 키-값 쌍: JSON 키-값 쌍이 지표의 의미를 명확하게 전달하지 못하거나, LLM이 학습한 지식 베이스와 일치하지 않을 경우 해석에 실패할 수 있습니다.
세 번째 원인: LLM 프롬프트의 컨텍스트 부족
LLM 모델 자체가 특정 유형의 데이터에 대한 “일반적인 비즈니스 분석” 프롬프트만 받았다면, 제공된 JSON 요약본을 그 자체로 해석하기 어려울 수 있습니다.
- 관계 설명 부재:
op(운영) 데이터와fin(재무) 데이터가 어떻게 상호작용하며 비즈니스 성과를 나타내는지,BT(백테스팅) 데이터가 예측의 정확도를 어떻게 반영하는지에 대한 명확한 지시나 배경 설명이 프롬프트에 없었을 가능성도 있습니다.
결론적으로, 핵심 정보가 LLM에 도달하기 전에 사라졌거나, 도달했더라도 모델이 효과적으로 처리할 수 없는 형태로 전달되었을 때 이러한 문제가 발생합니다.
3. 해결 방법 및 코드 예시
가장 효과적인 해결 방법은 LLM에 실제로 전달되는 최종 JSON 페이로드(payload)를 면밀히 검토하여, 정보 유실이 어느 단계에서 발생하는지 정확히 파악하는 것입니다. 다음은 단계별 디버깅 전략과 해결책입니다.
단계별 디버깅 전략
1. JSON 요약본 중간 확인 (토큰 축소 전)
토큰 축소 로직이 실행되기 전, compact_text 변수에 어떤 내용이 담겨 있는지 확인하여 생성된 JSON 요약이 애초에 올바른 정보를 포함하고 있는지 검사합니다.
# JSON 요약본 생성 직후, 토큰 축소 로직 이전
print("----- 1. Original JSON Summary (before token reduction) -----")
print(compact_text)
# 여기에 breakpoint를 걸거나 실행하여 내용을 확인합니다.
이 단계에서 이미 중요한 지표가 누락되었다면, DataFrame 요약 생성 로직(통계 계산 및 JSON 직렬화)을 수정해야 합니다.
2. 토큰 축소 후 JSON 확인
가장 유력한 문제 지점인 토큰 축소 로직 내부 또는 직후에 compact_text를 다시 출력하여, 어떤 정보가 제거되었는지 확인합니다.
max_input_tokens = 950
while len(llm.tokenize(compact_text.encode("utf-8"))) > max_input_tokens:
# 기존 토큰 축소 로직 (예: 특정 정보 제거 함수 호출)
# remove_some_data_from_compact_text(compact_text)
# 토큰 축소 후 중간 JSON 확인
print("----- 2. JSON Summary after a reduction step -----")
print(compact_text)
# 여기에 breakpoint를 걸어 각 축소 단계에서 무엇이 사라지는지 추적합니다.
# 필요하다면, compact_text를 복사하여 단계별 변화를 기록할 수도 있습니다.
이 단계에서 핵심 비즈니스 지표(예: 매출 총액, 평균 이익, 예측 정확도)가 사라진다면, 토큰 축소 로직의 우선순위를 재조정해야 합니다.
3. LLM 프롬프트에 디버깅 정보 추가
정보가 LLM에 잘 전달되는지 최종적으로 확인하기 위해, LLM 프롬프트에 compact_text 전체를 포함시켜 LLM이 직접 이를 분석하게 하고, 어떤 정보가 중요한지 또는 누락되었는지 피드백을 요청합니다.
# LLM 호출 전
# 메시지 구성에 compact_text를 직접 포함
messages = [
{"role": "system", "content": "You are a helpful assistant analyzing business data. Your task is to identify key business indicators from the provided JSON data and explain any missing information or ambiguities."},
{"role": "user", "content": f"Here is a JSON summary of our business data. Please analyze it for key business indicators. If you cannot find any, or if the data is insufficient, clearly state what information is missing or unclear, and point out any parts of the JSON you found problematic:\n\n{compact_text}"}
]
response = llm.create_chat_completion(
messages=messages,
temperature=0.1,
max_tokens=500, # 디버깅을 위해 max_tokens를 충분히 늘립니다.
response_format={"type": "json_object"}
)
print("----- 3. LLM's Debugging Response -----")
print(response.choices[0].message.content)
이 방법을 통해 LLM 자체의 “의견”을 들어볼 수 있어, 데이터 해석 능력의 문제인지, 아니면 정말로 데이터가 부족한 것인지 판단하는 데 큰 도움이 됩니다.
근본적인 해결책 제안
1. 토큰 예산 관리 로직 최적화
- 핵심 지표 우선순위: 토큰 축소 시, 범주형 분포나 상세 테이블 요약보다 매출, 비용, 이익, 예측 정확도 등 비즈니스 통찰에 필수적인 숫자형 요약 통계(평균, 합계, 최소/최대)는 가장 나중에 제거하거나, 절대 제거하지 않도록 로직을 수정합니다.
- 점진적 축소: 한 번에 많은 정보를 제거하기보다, 중요도가 낮은 정보부터 점진적으로 제거하는 전략을 채택합니다.
- 요약의 요약: 핵심 지표가 너무 많아 토큰 예산을 초과할 경우, 각 지표의 “메타 요약”(예: “지난 분기 매출은 평균적으로 5% 성장했습니다”와 같은 자연어 요약)을 생성하여 전달하는 방법도 고려할 수 있습니다.
2. JSON 요약 구조 개선
LLM이 데이터를 명확하게 이해할 수 있도록 JSON 요약 구조를 개선합니다.
- 의미 있는 키: 각 지표의 이름과 값이 명확하게 연결되도록 키 이름을 구체적으로 작성합니다 (예:
"revenue_total_usd": 123456.78). - 컨텍스트 추가: 각 DataFrame 요약에 해당 데이터가 무엇을 나타내는지 간략한 설명(예:
"description": "Daily operational metrics including ticket counts and problem resolutions.")을 포함시킵니다. - 구조화된 요약: 각 DataFrame별 요약을 별도의 객체로 묶고, 각 객체 안에 지표, 값, 단위, 기간 등을 포함하는 구조를 만듭니다.
# 개선된 JSON 요약 구조 예시
{
"summary_date": "2023-10-26",
"operational_data_summary": {
"description": "Daily operational data summary.",
"ticket_count_total": 5432,
"avg_resolution_time_hours": 2.5,
"problem_ticket_ratio": 0.15
},
"financial_data_summary": {
"description": "Financial transaction data summary.",
"revenue_total_usd": 1234567.89,
"cost_total_usd": 789012.34,
"profit_margin_percent": 36.19
},
"backtesting_summary": {
"description": "Walk-forward backtesting results for forecasts.",
"mape_percent": 12.3,
"rmse_value": 50.2,
"forecast_accuracy_rating": "Good"
}
}
3. 프롬프트 엔지니어링 강화
LLM에게 데이터의 의미와 각 지표 간의 관계를 더 명확하게 설명하는 프롬프트를 제공합니다.
- 역할 부여 및 목표 명시: “당신은 전문 비즈니스 분석가이며, 다음 데이터를 기반으로 [회사명]의 재무 및 운영 성과에 대한 통찰을 제공해야 합니다.”
- 지표 설명: “제공된 JSON 데이터에는 매출(revenue), 비용(cost), 이익(profit) 등 핵심 지표가 포함되어 있습니다. 이 지표들을 사용하여 비즈니스 건강을 평가하고, 주요 위험 요소와 개선 권장 사항을 도출해 주세요.”
- 기대 결과 명시: “분석 결과는 프로젝트 상태, 통찰, 위험, 권장 사항을 포함하는 JSON 형식으로 제공되어야 합니다.”
4. 향후 예방을 위한 팁
미래에 유사한 문제가 발생하지 않도록 다음과 같은 예방책을 고려할 수 있습니다.
- LLM 피드백 루프 자동화: 개발 단계에서 LLM에게 요약된 데이터에 대한 피드백을 요청하는 자동화된 테스트 스위트를 구축합니다. 예를 들어, 특정 키워드(예: “지표 없음”, “데이터 부족”)가 응답에 포함되면 경고를 발생시키고 자세한 디버깅 로그를 생성하도록 합니다.
- 토큰 사용량 모니터링 및 경고: LLM에 전달되는 데이터의 토큰 사용량을 지속적으로 모니터링하고, 특정 임계값 이하로 떨어지거나, 핵심 지표가 제외될 경우 알림을 받는 시스템을 구축합니다.
- 콘텐츠 압축 기술 활용: 단순히 정보를 제거하는 것을 넘어, 의미를 보존하면서 토큰 효율성을 높이는 고급 압축 기술(예: K-means 클러스터링을 통한 요약, 임베딩 기반 정보 축소)을 연구하고 적용해 볼 수 있습니다.
- 프롬프트 템플릿 표준화 및 버전 관리: 다양한 비즈니스 분석 시나리오에 대해 LLM이 일관성 있게 정보를 해석할 수 있도록 잘 정의된 프롬프트 템플릿을 표준화하고 버전 관리합니다. 이는 LLM 응답의 예측 가능성을 높이는 데 기여합니다.
Qwen LLM과 Pandas를 활용한 비즈니스 분석 파이프라인은 복잡할 수 있지만, 체계적인 디버깅과 최적화를 통해 강력한 통찰력을 제공할 수 있습니다. 이 가이드가 여러분의 프로젝트에서 발생하는 데이터 지표 누락 문제 해결에 도움이 되기를 바랍니다.
![[에러 해결] [Pandas] 'AttributeError' (리스트/딕셔너리 객체에 .items() 사용 오류)와 효율적인 데이터 매핑 방법 [에러 해결] [Pandas] 'AttributeError' (리스트/딕셔너리 객체에 .items() 사용 오류)와 효율적인 데이터 매핑 방법](https://dev-error.com/wp-content/plugins/contextual-related-posts/default.png)