Files
HC900-Crawler/mcp-server/eval/TASK-nl2sql-schema-gap.md
windpacer 16fc7a2598 Initial commit: HC900 Crawler
Honeywell HC900을 Modbus TCP로 직접 폴링 → gRPC → C# 크롤러 → PostgreSQL.
기존 Experion OPC UA 데이터 경로를 HC900 직접 통신으로 대체.

- industrial-comm/cpp: C++ Modbus 게이트웨이 (gRPC 서버)
- src: C# .NET 8 ASP.NET Core 크롤러 + 웹 UI (3-Layer)
- mcp-server: Python FastMCP (RAG/NL2SQL/P&ID)
- 다중 컨트롤러(N-Controller) 지원

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 20:28:14 +09:00

5.8 KiB
Raw Permalink Blame History

작업지시서 — NL2SQL 스키마 갭 수정 (플랜트 뷰 추가)

대상: 코딩 LLM. 이 문서만 보고 독립 수행 가능하도록 작성됨. 예상 분량: 단일 파일의 문자열 상수 1곳 편집 + 검증. 로직 변경 없음.

1. 배경 (왜)

Phase 0 골든 평가에서 Qwen3-8B가 전체 85%인데 nl2sql만 50%(5/10) 로 떨어짐. 실패 5건(nl2sql-0206)은 전부 플랜트 전용 뷰(v_plant_running_state, v_plant_running_state_corroborated, v_instrument_range)를 써야 하는 질문인데, NL2SQL 프롬프트의 스키마(DB_SCHEMA)에 그 뷰들이 문서화돼 있지 않아 모델이 모르는 뷰를 쓸 수 없었음. 기본 테이블 질문(nl2sql-01,0710)은 모두 통과 → 모델·채점 문제 아님, 스키마 문서 갭.

이 갭은 production NL2SQL(query_with_nl/run_sql 생성기)도 동일하게 가짐. 프롬프트가 단일 소스(worker/sql_prompt.py)라 여기만 고치면 eval·production 동시 개선.

2. 수정 대상 (딱 하나)

mcp-server/worker/sql_prompt.pyDB_SCHEMA 문자열 상수 한 곳.

  • ⚠️ nl2sql_worker.py는 이 상수를 import만 함 — 건드리지 말 것.
  • ⚠️ SQL_SYSTEM_PROMPT은 자동으로 DB_SCHEMA를 포함하므로 별도 수정 불필요.

3. 추가할 내용 (정확히 이 텍스트를 DB_SCHEMA에 삽입)

DB_SCHEMA 안에서 뷰: v_tag_summary ... 블록 바로 다음, 새로운 태그 타입: 줄 앞에 아래 블록을 그대로 삽입한다 (기존 서술 스타일·들여쓰기 유지):

뷰: v_plant_running_state  (area별 펌프 운전 판정 — "어떤 플랜트가 운전 중" 질문 1순위)
  area_code         TEXT     - 정규화 area (예: P3, P4, P5, P6, P8)
  status            TEXT     - 'RUNNING' / 'TRIPPED' / 'STOPPED' (펌프 1대라도 RUN이면 RUNNING)
  running_pumps     INT      - R-RUN/L-RUN 펌프 수
  tripped_pumps     INT      - R-TRIP/L-TRIP 펌프 수
  stopped_pumps     INT      - R-STOP/L-STOP 펌프 수
  total_pumps       INT      - 펌프 enum 보유 태그 수
  running_pump_tags TEXT[]   - 현재 RUN 상태 펌프 base_tag 배열
  ※ "운전 중인 플랜트/펌프", "트립 펌프" 류 질문은 이 뷰를 직접 SELECT (펌프 상태 SQL 직접 작성 금지)
  ※ 결과에 없는 area = 펌프 미등록 → 운전 여부 단정 금지. 이 뷰는 area 레벨(sub_area 없음)

뷰: v_plant_running_state_corroborated  (펌프별 실질 운전 — 유량/진공 교차검증, sub_area 지원)
  base_tag            TEXT             - 펌프 base_tag (예: 'p-6102', 'vp-6117')
  area_code           TEXT             - 정규화 area
  sub_area            TEXT             - 세부 area (예: 'P6-1'; 공용은 'P6-1,P6-2'). 필터는 LIKE '%P6-1%'
  corroborated_status TEXT             - CONFIRMED_RUNNING / SUSPICIOUS_RUNNING / STALE / INDETERMINATE_RUNNING / STOPPED / TRIPPED
  flow_kg_hr          DOUBLE PRECISION - 연결 유량(kg/hr)
  vacuum_torr         DOUBLE PRECISION - 연결 진공압(torr=mmHg)
  ※ "6-1차/6-2차" 등 sub_area 필터가 필요한 질문은 **반드시 이 뷰** 사용 (아래 agg/기본뷰는 sub_area 없음)

뷰: v_instrument_range  (계기 단위/레인지 — tag_metadata에서 추출)
  base_tag  TEXT             - 기본 태그명, 접미사 없음 (예: 'ficq-6113', 'pica-6111')
  unit      TEXT             - 단위 (예: 'kg/hr', 'mmHg')
  eu_lo     DOUBLE PRECISION - 레인지 하한
  eu_hi     DOUBLE PRECISION - 레인지 상한
  ※ 계기 레인지/상하한/단위 질문에 사용. base_tag는 '.pv' 등 접미사를 떼고 매칭

참고(직접 쓰지 말 것): v_plant_running_state_agg 도 있으나 area 레벨 집계라 sub_area가 없음.
sub_area 질문엔 위 v_plant_running_state_corroborated 를 사용.

컬럼/뷰 정의 출처: src/Infrastructure/Database/ExperionDbContext.cs (boot DDL). 변경 전 그 파일에서 위 3개 뷰의 SELECT를 한 번 대조해 컬럼명이 위와 일치하는지 확인할 것.

4. 검증 (순서대로)

cd mcp-server
# 1) 컴파일 — 프롬프트 단일소스/워커 둘 다
python3 -m py_compile worker/sql_prompt.py worker/nl2sql_worker.py

# 2) 모델 서빙 (표준 FP8만! FP8-dynamic은 출력 손상되니 금지)
cd ..
bash scripts/run-vllm-eval-model.sh Qwen/Qwen3-8B-FP8 Qwen3-8B 0.30 32768 8001

# 3) nl2sql 카테고리만 재실행 (Qwen3는 --no-think 필수)
cd mcp-server/eval
../.venv/bin/python run_eval.py --model Qwen3-8B --no-think --categories nl2sql

# 4) 회귀 확인 — 전체 재실행 + 이전 결과 대비
../.venv/bin/python run_eval.py --model Qwen3-8B --no-think \
  --baseline results/Qwen3-8B_20260526_103459.json

5. 수용 기준 (Acceptance)

  • py_compile 통과 (sql_prompt.py, nl2sql_worker.py)
  • nl2sql ≥ 9/10 (목표: 02~06 통과. 특히 06은 v_plant_running_state_corroborated+p6-1 포함, v_plant_running_state_agg 미포함이어야 PASS)
  • 다른 카테고리(abstain/scaffold/tool_call/grounding) 회귀 없음 (--baseline 비교에서 PASS→FAIL 0건)
  • DB_SCHEMA 외 다른 코드(워커 로직·채점기·골든셋) 변경 없음

6. 하지 말 것 (금지)

  • 골든셋(golden.jsonl)이나 채점기(run_eval.py)를 고쳐서 점수를 맞추기 — 측정자를 왜곡함
  • 존재하지 않는 뷰/컬럼을 스키마에 추가 (반드시 ExperionDbContext.cs DDL과 대조)
  • nl2sql_worker.py의 생성 로직·SQL_SYSTEM_PROMPT 규칙 변경 (스키마 문서만 보강)
  • FP8-dynamic 양자화 모델 사용 (이 스택에서 출력 문자 손상 — 표준 FP8/bf16만)

7. 산출물

  • 변경 파일: mcp-server/worker/sql_prompt.py (DB_SCHEMA 뷰 3개 추가) 1개
  • 새 eval 결과: mcp-server/eval/results/Qwen3-8B_*.json (nl2sql 개선 확인)
  • 한 줄 보고: 변경 전/후 nl2sql 점수, 회귀 유무