Files
ExperionCrawler/.rooBackup/2026-05-05-105400/P&ID-재설계-plan-코딩계획.md
2026-05-08 17:22:10 +09:00

13 KiB

P&ID 재설계 - 코딩 계획

작성일: 2026-05-04 상태: 진행 중 목표: No-10_Plant_PID.dxf(28,819 엔티티) 처리 시 30분 타임아웃 해결


현황 요약

단계 내용 상태
Step 1 현황 분석 (DXF 구조 파악) 완료
Step 2 성공 테스트 분석 (분할+병렬 성공 요인) 완료
Step 3 레전드 페이지 분석 (legend_parser.py 생성) 완료
Step 4 해결 방향 정의 완료
Step 5~10 구현 (아래 상세 계획) 🔲 미시작

핵심 전략

  1. 도면 분할 — 한 DXF 파일 내 여러 도면을 좌표 기반으로 분리 (9개 도면 → 각각 독립 처리)
  2. 계측기 유형별 병렬 LLM 호출 — Sensor/Valve/System/Gauge/Pump 동시 처리
  3. 위치 정보 저장 — 태그의 DXF 상 좌표 + 근처 텍스트
  4. AREA 그룹핑 — 태그명에서 플랜트 번호 유추

변경 대상 파일

파일 변경 내용
mcp-server/pipeline/extractor.py 도면 분할 로직 추가
mcp-server/worker/pid_worker.py 도면 분할 + 병렬 LLM 호출
mcp-server/pipeline/mapper.py 기존 유지 (이미 배치 처리 구현됨)
mcp-server/pipeline/topology.py 기존 유지 (이미 SpatialGrid 구현됨)
mcp-server/pipeline/legend_parser.py 기존 유지 (이미 계측기 그룹 정의됨)

상세 코딩 계획

Phase 1: 도면 분할 로직 (extractor.py)

1-1. 도면 분할 테스트 스크립트 작성

  • 파일: test_drawing_split.py (신규)
  • 목표: No-10_Plant_PID.dxf를 TITLE 레이어 LINE으로 분할하는 로직 프로토타입
  • 작업 내용:
    • ezdxf로 DXF 로드
    • TITLE 레이어의 LINE 엔티티 탐색
    • 수직 LINE(X 좌표가 일정)을 도면 경계로 감지
    • 각 도면별 X/Y 범위 출력
  • 검증: 9개 도면 영역이 올바르게 분리되는지 확인
  • 완료 기준: 콘솔에 9개 도면의 X/Y 범위가 출력됨

1-2. PidGeometricExtractor에 도면 분할 메서드 추가

  • 파일: mcp-server/pipeline/extractor.py
  • 목표: split_drawings() 메서드 추가
  • 작업 내용:
    • split_drawings() -> List[DrawingRegion] 메서드 추가
    • DrawingRegion 데이터클래스 정의 (drawing_no, x_min, x_max, y_min, y_max)
    • TITLE 레이어 LINE 기반 경계 감지
    • 레전드 페이지(X < 2000) 제외
    • FFD 페이지도 제외 (최상단 텍스트 기반)
  • 완료 기준: split_drawings() 호출 시 9개 DrawingRegion 반환

1-3. 영역별 추출 메서드 추가

  • 파일: mcp-server/pipeline/extractor.py
  • 목표: extract_region() 메서드 추가
  • 작업 내용:
    • extract_region(region: DrawingRegion) -> List[GeometricEntity] 메서드 추가
    • bbox가 region 범위 내에 있는 엔티티만 필터링
    • 기존 extract_and_save() 로직 재사용
  • 완료 기준: 각 도면별 엔티티 수 합계가 전체 엔티티 수와 일치

1-4. 도면 분할 통합 테스트

  • 파일: test_drawing_split.py
  • 목표: 전체 파이프라인 테스트
  • 작업 내용:
    • DXF 로드 → 분할 → 영역별 추출 → 결과 검증
    • 각 도면별 엔티티 수, 태그 수 확인
    • 처리 시간 측정
  • 완료 기준: 9개 도면 모두 정상 추출, 총 처리 시간 < 30초

Phase 2: 계측기 유형별 병렬 LLM 호출 (pid_worker.py)

2-1. 계측기 유형별 프롬프트 정의

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: 각 유형별 전용 프롬프트 상수 정의
  • 작업 내용:
    • _SENSOR_EXTRACT_SYSTEM — FT, FIT, LT, PT, TE, PG, LG, TG 추출
    • _VALVE_EXTRACT_SYSTEM — FCV, TCV, LCV, PCV, XV, FV, LV, PV, TV 추출
    • _SYSTEM_EXTRACT_SYSTEM — LI, PI, TI, FIQ, FICQ, TICA, PICA, LICA 추출
    • _GAUGE_EXTRACT_SYSTEM — PG, TG, LG 추출
    • _PUMP_EXTRACT_SYSTEM — P-10101, VP-10117, DP-10101 등 펌프 추출
    • 각 프롬프트는 max_tokens=65536 적용
  • 완료 기준: 5개 프롬프트 상수 정의 완료

2-2. 유형별 추출 함수 작성

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: _extract_tags_by_type() 함수 추가
  • 작업 내용:
    • _extract_tags_by_type(text: str, type_name: str, system_prompt: str) -> List[dict] 함수
    • LLM 호출 → JSON 파싱 → 태그 목록 반환
    • max_tokens=65536 적용
    • finish_reason=length 복구 로직 포함
  • 완료 기준: 단일 유형 추출 테스트 통과

2-3. 병렬 호출 로직 구현

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: _extract_all_types_parallel() async 함수 추가
  • 작업 내용:
    • asyncio.gather()로 5개 유형 동시 호출
    • 각 유형별 결과 통합
    • 중복 태그 제거 (tagNo 기준)
  • 완료 기준: 5개 유형 병렬 호출 테스트, 총 처리 시간 < 120초

2-4. _build_pid_graph_parallel() 리팩토링

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: 기존 함수를 도면 분할 + 병렬 LLM 호출로 변경
  • 작업 내용:
    • Phase 1: 도면 분할 (extractor.split_drawings())
    • Phase 2: 각 도면별 기하 추출 (extractor.extract_region())
    • Phase 3: 각 도면별 유형별 병렬 LLM 호출
    • Phase 4: 결과 통합 + 그래프 빌드
    • Phase 5: 저장
  • 완료 기준: 기존 API 호환 유지, 처리 시간 30분 → 5분 이내

2-5. 병렬 처리 통합 테스트

  • 파일: test_parallel_extraction.py (신규)
  • 목표: 전체 병렬 처리 파이프라인 테스트
  • 작업 내용:
    • No-10_Plant_PID.dxf 전체 처리
    • 각 단계별 시간 측정
    • 추출된 태그 수, 매핑 수 확인
  • 완료 기준: 전체 처리 < 5분, 태그 추출 수 > 기존

Phase 3: 위치 정보 저장

3-1. 위치 정보 스키마 정의

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: 태그 추출 결과에 위치 정보 포함
  • 작업 내용:
    • 각 태그에 bbox (min_x, min_y, max_x, max_y) 필드 추가
    • drawing_no (도면 번호) 필드 추가
    • nearby_text (근처 텍스트) 필드 추가
  • 완료 기준: 추출 결과 JSON에 위치 정보 포함

3-2. 근처 텍스트 추출 로직

  • 파일: mcp-server/pipeline/extractor.py
  • 목표: get_nearby_text() 메서드 추가
  • 작업 내용:
    • 특정 좌표 주변 threshold 이내 TEXT 엔티티 검색
    • SpatialGrid 활용 (O(1) 조회)
    • 상하좌우 위치 파악 (direction 필드)
  • 완료 기준: 태그 주변 텍스트 정상 추출

3-3. 위치 정보 통합 테스트

  • 파일: test_location_info.py (신규)
  • 목표: 위치 정보 정확도 검증
  • 작업 내용:
    • 알려진 태그 위치와 추출된 위치 비교
    • 근처 텍스트 정확도 확인
  • 완료 기준: 위치 정보 정확도 > 90%

Phase 4: AREA 그룹핑

4-1. AREA 추출 로직 개선

  • 파일: mcp-server/pipeline/legend_parser.py
  • 목표: extract_area_from_tag() 정확도 향상
  • 작업 내용:
    • FICQ-6113 → "6" (6호 플랜트)
    • FICQ-10113 → "10" (10호 플랜트)
    • 패턴 매칭 개선 (정규식 튜닝)
  • 완료 기준: 테스트 케이스 10개 모두 정확

4-2. AREA별 그룹핑 함수

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: _group_by_area() 함수 추가
  • 작업 내용:
    • 추출된 태그 목록을 AREA별로 그룹핑
    • AREA 번호가 없는 태그는 "unknown" 그룹
    • 그룹별 통계 출력
  • 완료 기준: AREA별 그룹핑 결과 정상 출력

Phase 5: Experion 태그 매핑

5-1. 기존 매핑 로직 확인

  • 파일: mcp-server/pipeline/mapper.py
  • 목표: 기존 IntelligentMapper 동작 확인
  • 작업 내용:
    • _batch_gather() 배치 처리 확인 (이미 구현됨)
    • RapidFuzz 기반 후보 추출 확인
    • LLM 기반 최종 매핑 확인
  • 완료 기준: 기존 매핑 정확도 확인

5-2. 매핑 결과 통합

  • 파일: mcp-server/worker/pid_worker.py
  • 목표: _build_pid_graph_parallel()에 매핑 결과 통합
  • 작업 내용:
    • Phase 3 결과 (추출된 태그)를 IntelligentMapper에 전달
    • 매핑 결과를 그래프에 추가
    • 매핑 통계 출력
  • 완료 기준: 매핑 결과 그래프에 정상 반영

Phase 6: UI 연동

6-1. API 엔드포인트 확인

  • 파일: src/Web/Controllers/PidController.cs
  • 목표: 기존 API 엔드포인트 확인
  • 작업 내용:
    • 태그 검색 API 확인
    • 위치 정보 반환 여부 확인
  • 완료 기준: API 스펙 파악

6-2. 위치 정보 API 추가

  • 파일: src/Web/Controllers/PidController.cs
  • 목표: 태그 위치 조회 API 추가
  • 작업 내용:
    • GET /api/pid/tags/{tagName}/location 엔드포인트 추가
    • DXF 좌표, 도면 번호, 근처 텍스트 반환
    • 현재 실시간 값 연동
  • 완료 기준: API 테스트 통과

6-3. 프론트엔드 UI 수정

  • 파일: src/Web/wwwroot/js/app.js
  • 목표: 태그 검색 시 위치 표시
  • 작업 내용:
    • 태그 검색 결과에 위치 정보 표시
    • "6호 정제탑, 밑에서 3번째 온도 센서입니다. 현재 온도 105도" 형식
    • DXF 도면 상 위치 시각화 (선택사항)
  • 완료 기준: UI에서 위치 정보 확인 가능

실행 순서 및 의존성

Phase 1 (도면 분할)
  ├── 1-1 → 1-2 → 1-3 → 1-4  (순차)
  │
Phase 2 (병렬 LLM)
  ├── 2-1 → 2-2 → 2-3 → 2-4 → 2-5  (순차, Phase 1 완료 후)
  │
Phase 3 (위치 정보)
  ├── 3-1 → 3-2 → 3-3  (순차, Phase 2 완료 후)
  │
Phase 4 (AREA 그룹핑)
  ├── 4-1 → 4-2  (순차, 독립 실행 가능)
  │
Phase 5 (매핑 통합)
  ├── 5-1 → 5-2  (순차, Phase 2+3 완료 후)
  │
Phase 6 (UI 연동)
  ├── 6-1 → 6-2 → 6-3  (순차, Phase 5 완료 후)

각 단계 완료 기준

단계 완료 기준 예상 시간
1-1 9개 도면 영역 콘솔 출력 30분
1-2 split_drawings() 9개 Region 반환 1시간
1-3 extract_region() 정상 동작 30분
1-4 전체 분할 테스트 통과 30분
2-1 5개 프롬프트 상수 정의 30분
2-2 단일 유형 추출 테스트 통과 1시간
2-3 5개 유형 병렬 호출 테스트 1시간
2-4 _build_pid_graph_parallel() 리팩토링 완료 2시간
2-5 전체 병렬 처리 테스트 통과 1시간
3-1 위치 정보 JSON 필드 추가 30분
3-2 get_nearby_text() 구현 1시간
3-3 위치 정보 정확도 검증 30분
4-1 AREA 추출 테스트 10개 통과 30분
4-2 AREA별 그룹핑 결과 출력 30분
5-1 기존 매핑 정확도 확인 30분
5-2 매핑 결과 그래프 반영 1시간
6-1 API 스펙 파악 30분
6-2 위치 조회 API 추가 1시간
6-3 UI 수정 완료 1시간

총 예상 시간: 약 18시간


체크리스트

Phase 1: 도면 분할

  • 1-1. 도면 분할 테스트 스크립트 작성
  • 1-2. PidGeometricExtractor에 도면 분할 메서드 추가
  • 1-3. 영역별 추출 메서드 추가
  • 1-4. 도면 분할 통합 테스트

Phase 2: 계측기 유형별 병렬 LLM 호출

  • 2-1. 계측기 유형별 프롬프트 정의
  • 2-2. 유형별 추출 함수 작성
  • 2-3. 병렬 호출 로직 구현
  • 2-4. _build_pid_graph_parallel() 리팩토링
  • 2-5. 병렬 처리 통합 테스트

Phase 3: 위치 정보 저장

  • 3-1. 위치 정보 스키마 정의
  • 3-2. 근처 텍스트 추출 로직
  • 3-3. 위치 정보 통합 테스트

Phase 4: AREA 그룹핑

  • 4-1. AREA 추출 로직 개선
  • 4-2. AREA별 그룹핑 함수

Phase 5: Experion 태그 매핑

  • 5-1. 기존 매핑 로직 확인
  • 5-2. 매핑 결과 통합

Phase 6: UI 연동

  • 6-1. API 엔드포인트 확인
  • 6-2. 위치 정보 API 추가
  • 6-3. 프론트엔드 UI 수정

주의 사항

  1. 백업 필수: 각 파일 수정 전 .rooBackup/에 백업
  2. diff 제시: 변경 내용 diff 형식으로 제시 후 확인
  3. 작은 단계: 각 단계를 독립적으로 완료하고 검증
  4. 테스트 우선: 테스트 스크립트 먼저 작성 후 구현
  5. 기존 코드 유지: topology.py, mapper.py는 기존 유지 (이미 잘 구현됨)

다음 시작 시

  1. 이 파일의 체크리스트에서 첫 번째 미완료 항목부터 시작
  2. 각 단계 완료 시 체크리스트 업데이트
  3. 문제가 발생하면 해당 단계에서 중단하고 원인 분석
  4. 완료 기준을 충족해야 다음 단계로 진행