diff --git a/03.Code/업로드용/converters/pipeline/step3_domain.py b/03.Code/업로드용/converters/pipeline/step3_domain.py index 3b26e86..9545020 100644 --- a/03.Code/업로드용/converters/pipeline/step3_domain.py +++ b/03.Code/업로드용/converters/pipeline/step3_domain.py @@ -5,24 +5,32 @@ load_dotenv() domain_prompt.py 기능: -- D:\\test\\report 내의 텍스트 파일들을 읽어 내용 요약을 생성합니다. -- 추출된 정보를 바탕으로, 해당 문서 묶음이 어떤 도메인/업종의 문서인지 분석합니다. -- 분석 결과는 텍스트 형태의 프롬프트(domain_prompt.txt)로 저장됩니다. -- 향후 단계에서 모든 GPT 호출(system role)에 이 분석 내용을 주입하여 사용합니다. +- D:\\test\\report 안의 모든 pdf/xlsx/png/txt/md 파일들을 + 파일명과 내용 일부를 샘플링한다. +- 이 샘플을 기반으로, 문서 성격의 분야/직무 영역을 파악하고 + "너는 ~~ 분야의 전문가이다. 너는 ~~를 하고 있다..." 형식의 + 도메인 전용 시스템 프롬프트(persona)를 자동 생성한다. +- 결과물은 output/context/domain_prompt.txt 로 저장된다. + +이 domain_prompt.txt 내용은 이후 모든 GPT 호출(system role)에 공통적으로 붙여 사용하게 된다. """ + import os import sys import json from pathlib import Path + import pdfplumber import fitz # PyMuPDF import pandas as pd from openai import OpenAI -# ===== OpenAI 설정 (구조 유지, 현재 단계에서는 실제 키가 없어도 코드 작성 가능) ===== +# ===== OpenAI 설정 (구조화된 키, 모델 설정 등 직접 입력) ===== OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") +GPT_MODEL = "gpt-4o" + client = OpenAI(api_key=OPENAI_API_KEY) -GPT_MODEL = "gpt-5-2025-08-07" + SKIP_DIR_NAMES = {"System Volume Information", "$RECYCLE.BIN", ".git", "__pycache__"} @@ -43,7 +51,7 @@ def sample_from_pdf(p: Path, max_chars: int = 1000) -> str: texts = [] try: with pdfplumber.open(str(p)) as pdf: - # 상단 몇 페이지만 샘플링 + # 상위 3페이지만 샘플링 for page in pdf.pages[:3]: t = page.extract_text() or "" if t: @@ -64,10 +72,10 @@ def sample_from_xlsx(p: Path, max_chars: int = 1000) -> str: try: df = xls.parse(sheet_name) except Exception as e: - log(f"[WARN] 엑셀 로드 실패: {safe_rel(p)} | {sheet_name} | {e}") + log(f"[WARN] 시트 로딩 실패: {safe_rel(p)} | {sheet_name} | {e}") continue - texts.append(f"\n[시트명] {sheet_name}") - texts.append("컬럼: " + ", ".join(map(str, df.columns))) + texts.append(f"\n[시트] {sheet_name}") + texts.append("컬럼명: " + ", ".join(map(str, df.columns))) head = df.head(5) texts.append(head.to_string(index=False)) if sum(len(x) for x in texts) >= max_chars: @@ -108,7 +116,7 @@ def gather_file_samples( fpath = cur_dir / fname ext = fpath.suffix.lower() - # 전체 문서 목록은 모두 수집하여 리스트업 + # 파일명은 전체 다 확보하고, 샘플 추출은 제한 file_names.append(safe_rel(fpath)) if len(samples) >= max_total_samples: @@ -137,7 +145,7 @@ def gather_file_samples( continue except Exception as e: - log(f"[WARN] 파일 샘플 추출 실패: {safe_rel(fpath)} | {e}") + log(f"[WARN] 샘플 추출 실패: {safe_rel(fpath)} | {e}") continue return file_names, samples @@ -145,39 +153,48 @@ def gather_file_samples( def build_domain_prompt(): """ - 파일명 + 샘플 내용을 바탕으로 GPT에 질의하여 - '본 시스템은 ~~ 분야의 전문 문서를 다루는...' 형태의 프롬프트를 생성합니다. + 파일명 + 내용 샘플을 GPT에게 넘겨서 + '너는 ~~ 분야의 전문가다...' 형식의 시스템 프롬프트를 생성한다. """ - log("도메인 정보 수집 및 분석 시작...") + log("도메인 프롬프트 생성을 위한 샘플링 중...") file_names, samples = gather_file_samples() if not file_names and not samples: - log("분석할 수 있는 문서 데이터가 없습니다.") + log("파일 샘플이 없어 도메인 프롬프트를 생성할 수 없습니다.") sys.exit(1) file_names_text = "\n".join(file_names[:80]) sample_text = "\n\n".join(samples[:30]) prompt = f""" -다음은 특정 기술 분야의 문서 데이터 샘플입니다. +다음은 한 업무 폴더의 파일 목록과 그 파일에서 추출한 샘플 내용이다. -[문서 리스트/내용 샘플] +[파일명 목록] +{file_names_text} + +[내용 샘플] {sample_text} -이 정보들을 바탕으로 이 문서 묶음이 어떤 산업, 업무, 분야의 것인지, -주요 용어와 특징은 무엇인지 요약한 2~3문장 정도의 시스템 가이드 문구를 작성하세요. -또한, 이 분야의 전문가가 사용하는 AI로서의 페르소나(persona)를 정의하세요. +위 자료를 바탕으로 다음을 수행하라. -작성 규칙: - - 첫 문장: "본 시스템은 ~~ 분야의 전문 문서를 다룹니다." 형식으로, 이 문서 묶음의 성격을 정의하세요. - - 두 번째 문장 이후: "주요 내용은 ~~를 포함합니다.", "우리는 ~~ 분야의 전문가를 돕기 위한 보고서 자동 생성 가이드를 제공합니다." 형식으로 - 사용자 및 AI의 전문성과 목적을 서술하세요. - - 출력은 반드시 한글로 작성하세요. - - 이 내용이 프롬프트(보고서 요약, RAG, 보고서 작성 등)의 앞단에 연결될 것이므로 역할(role), 목적, 기준(측량 기준, 사용 기법 등)이 - 잘 포함되어야 합니다. +1) 이 문서 뭉치들이 어떤 분야, 업무, 도메인에 관한 것인지, + 핵심 키워드를 포함하여 2~3문장 정도로 요약하라. -출력은 반드시 설명이나 머리말 없이 분석 내용만 텍스트로 작성하세요. -이 내용 전체를 domain_prompt.txt로 저장할 것입니다. +2) 이후, 이 문서들을 다루는 AI에게 쓰일 "프롬프트 가이드라인"을 작성하라. + 이 가이드라인은 반드시 "너는 ~~ 분야의 전문 AI이다."로 시작하며, + 다음 조건을 만족해야 한다. + + - 페르소나: "너는 ~~ 분야의 전문가다." 형식으로, 이 문서 뭉치의 분야와 역할을 정의한다. + - 역할과 역량: 너는 ~~를 하고 있다.", "우리는 ~~의 문제를 해결하고 개선안을 찾고 있다." 등의 + 사용자와 AI에게 부여되는 전문지식 수준과 관점을 정의한다. + - 주의사항 5~7문장 정도로 작성하라. + - 이 분야에서 쓰는 프롬프트(작업자, 역할, RAG, 보고서 작성 등)의 전체 스택에 연결될 수 있도록, + 역할(role), 목적, 기준(출처 기반), 용어 사용, 규격 준수 등을 모두 포괄하여 작성하라. + +출력 형식: +- 요약과 가이드라인을 한 번에 출력하되, + 별도의 마크다운 없이 순수 텍스트로만 작성하라. +- 이 출력 전체를 domain_prompt.txt에 그대로 저장할 것이다. """ resp = client.chat.completions.create( @@ -185,7 +202,7 @@ def build_domain_prompt(): messages=[ { "role": "system", - "content": "당신은 문서 묶음의 성격을 분석하여, 향후 AI 시스템의 시스템 프롬프트를 구성하는 도메인 분석 전문가입니다." + "content": "너는 문서 뭉치의 도메인을 분석하고, 그에 맞는 AI 시스템 프롬프트와 가이드라인을 작성하는 지침 설계자이다." }, { "role": "user", @@ -213,11 +230,11 @@ def main(input_dir, output_dir): log("=== 도메인 프롬프트 생성 시작 ===") out_path = CONTEXT_DIR / "domain_prompt.txt" if out_path.exists(): - log(f"이미 존재함: {out_path}") - log("기존 정보를 사용하려면 건너뛰고, 새로 생성하려면 파일을 삭제 후 다시 실행하십시오.") + log(f"이미 domain_prompt.txt가 존재합니다: {out_path}") + log("기존 파일을 사용하려면 종료하고, 재생성이 필요하면 파일을 삭제 후 다시 실행하십시오.") else: build_domain_prompt() - log("=== 도메인 프롬프트 생성 완료 ===") + log("=== 도메인 프롬프트 작업 종료 ===") if __name__ == "__main__":