# 100처방 마스터 데이터 등록 가이드 > AI Agent가 `official_formulas` / `official_formula_ingredients` 테이블을 채울 때 따라야 할 절차와 규칙. --- ## 1. DB 구조 ### 1-1. `official_formulas` (처방 기본 정보) | 컬럼 | 타입 | 설명 | 채워야 하는 값 | |------|------|------|---------------| | `official_formula_id` | INTEGER PK | 자동생성 | (이미 존재) | | `formula_number` | INTEGER | 연번 1~100 | (이미 존재) | | `formula_name` | TEXT | 처방명 (한글) | (이미 존재) | | `formula_name_hanja` | TEXT | **한자명** | ✅ 채워야 함 | | `source_text` | TEXT | 출전 | (이미 존재) | | `description` | TEXT | **효능 요약** | ✅ 채워야 함 | | `reference_notes` | TEXT | **상담 참고자료** | ✅ 채워야 함 | ### 1-2. `official_formula_ingredients` (구성 약재) | 컬럼 | 타입 | 설명 | |------|------|------| | `ingredient_id` | INTEGER PK | 자동생성 | | `official_formula_id` | INTEGER FK | 처방 ID | | `ingredient_code` | TEXT | **herb_masters.ingredient_code** (예: `3400H1AHM`) | | `grams_per_cheop` | REAL | **1첩당 그램수** | | `notes` | TEXT | **역할** (군약/신약/좌약/사약 등) | | `sort_order` | INTEGER | 정렬 순서 (1부터) | --- ## 2. 등록 절차 (Step-by-Step) ### Step 1: 대상 처방 확인 ```sql -- 미등록 처방 확인 (formula_name_hanja가 NULL이면 미등록) SELECT official_formula_id, formula_number, formula_name, source_text FROM official_formulas WHERE formula_name_hanja IS NULL ORDER BY formula_number; ``` ### Step 2: 원방 조사 출전 서적 기반으로 아래 정보를 조사한다: 1. **한자명** — 예: 四君子湯 2. **효능 요약** — 한의학 용어 + 한자 병기. 예: `보기건비 (補氣健脾)` 3. **구성 약재** — 약재명, 1첩당 그램수, 군신좌사 역할 4. **상담 참고자료** — 출전, 주치, OTC 대비 장점 (1~2문장) #### 용량 기준 원칙 - **출전(원방)의 현대 환산 용량**을 우선 적용 - 1전(錢) = 3.75g, 1냥(兩) = 37.5g 기준 환산 - 감초는 대부분 사약으로 2~3g (다른 약재보다 적은 것이 일반적) - 동량(等分) 처방이라도 현대 임상 표준이 차등이면 표준을 따름 #### description 작성 규칙 ``` 한글효능 (한자효능) ``` 예시: - `발한해기, 생진서근 (發汗解肌, 生津舒筋)` - `온보기혈 (溫補氣血)` - `익기해표, 이기화담 (益氣解表, 理氣化痰)` #### reference_notes 작성 규칙 1문장: 출전 + 주치 증상 나머지: OTC 대비 차별점 또는 첩제만의 장점 ``` 예: "상한론 원방. 외감풍한으로 인한 두통, 발열, 오한, 항강 증상에 사용. OTC 갈근탕 대비 생약량 2.16배, 생강→건강 대체 없이 원물 사용으로 발한 효과 우수." ``` #### notes(역할) 작성 규칙 | 값 | 의미 | |----|------| | `군약` | 주약 (主藥) — 처방의 핵심 | | `신약` | 보조약 (臣藥) — 군약을 도움 | | `좌약` | 보좌약 (佐藥) — 부작용 완화 또는 보조 | | `사약` | 조화약 (使藥) — 제약 조화 (대부분 감초) | 복합 역할인 경우 괄호로 추가 설명: - `군약(보기)` — 보기 역할의 군약 - `신약(보혈)` — 보혈 역할의 신약 ### Step 3: ingredient_code 조회 ```sql -- 약재명으로 성분코드 조회 (정확 매칭 우선) SELECT ingredient_code, herb_name FROM herb_masters WHERE herb_name = '인삼'; -- 정확 매칭 없으면 LIKE 검색 SELECT ingredient_code, herb_name FROM herb_masters WHERE herb_name LIKE '%복령%'; ``` #### 주의: 동명이약 구분 | 약재 | 올바른 코드 | 주의 | |------|------------|------| | 진피(陳皮) | `3466H1AHM` | 진피(秦皮) `3467H1AHM`과 구분 | | 백출 | `3204H1AHM` | 백출초 `3611H1AHM`, 백출미감침 `3610H1AHM`과 구분 | | 감초 | `3007H1AHM` | 감초초 `3010H1AHM`, 감초밀자 `3009H1AHM`과 구분 | | 반하 | `3182H1AHM` | 반하생강백반제 등 포제품과 구분 | | 마황 | `3147H1AHM` | 마황탕포 `3606H1AHM`과 구분 | ### Step 4: SQL 실행 ```sql -- (1) 기본 정보 업데이트 UPDATE official_formulas SET formula_name_hanja = '四君子湯', description = '보기건비 (補氣健脾)', reference_notes = '화제국방 원방. 비기허로 인한 ...', updated_at = CURRENT_TIMESTAMP WHERE official_formula_id = 38; -- (2) 구성 약재 INSERT (sort_order는 1부터 순서대로) INSERT INTO official_formula_ingredients (official_formula_id, ingredient_code, grams_per_cheop, notes, sort_order) VALUES (38, '3400H1AHM', 4.0, '군약', 1), -- 인삼 (38, '3204H1AHM', 4.0, '신약', 2), -- 백출 (38, '3215H1AHM', 4.0, '좌약', 3), -- 복령 (38, '3007H1AHM', 2.0, '사약', 4); -- 감초 ``` ### Step 5: 검증 ```sql -- 등록 결과 확인 SELECT hm.herb_name, ofi.ingredient_code, ofi.grams_per_cheop, ofi.notes FROM official_formula_ingredients ofi JOIN herb_masters hm ON ofi.ingredient_code = hm.ingredient_code WHERE ofi.official_formula_id = ? ORDER BY ofi.sort_order; ``` 검증 체크리스트: - [ ] herb_masters에 없는 ingredient_code가 없는지 - [ ] grams_per_cheop이 0 이하인 것이 없는지 - [ ] 중복 ingredient_code가 없는지 - [ ] 1첩 총량이 상식적 범위(10~50g)인지 - [ ] 군약이 최소 1개 이상인지 --- ## 3. 등록 완료 예시 ### 사군자탕 (四君子湯) — ID:38 | 순서 | 약재 | 성분코드 | 1첩량 | 역할 | |------|------|----------|-------|------| | 1 | 인삼 | 3400H1AHM | 4.0g | 군약 | | 2 | 백출 | 3204H1AHM | 4.0g | 신약 | | 3 | 복령 | 3215H1AHM | 4.0g | 좌약 | | 4 | 감초 | 3007H1AHM | 2.0g | 사약 | - 한자명: 四君子湯 - 설명: `보기건비 (補氣健脾)` - 1첩 총량: 14.0g ### 갈근탕 (葛根湯) — ID:3 | 순서 | 약재 | 성분코드 | 1첩량 | 역할 | |------|------|----------|-------|------| | 1 | 갈근 | 3002H1AHM | 8.0g | 군약 | | 2 | 마황 | 3147H1AHM | 4.0g | 신약 | | 3 | 계지 | 3033H1AHM | 3.0g | 좌약 | | 4 | 작약 | 3419H1AHM | 3.0g | 좌약 | | 5 | 생강 | 3260H1AHM | 3.0g | 좌약 | | 6 | 대추 | 3115H1AHM | 4.0g | 좌약 | | 7 | 감초 | 3007H1AHM | 2.0g | 사약 | - 한자명: 葛根湯 - 설명: `발한해기, 생진서근 (發汗解肌, 生津舒筋)` - 1첩 총량: 27.0g --- ## 4. 자주 사용되는 성분코드 (Quick Reference) | 약재 | ingredient_code | 비고 | |------|----------------|------| | 감초 | 3007H1AHM | 사약 역할 빈출 | | 갈근 | 3002H1AHM | | | 건강 | 3017H1AHM | 생강 포제품 | | 계지 | 3033H1AHM | | | 길경 | 3077H1AHM | | | 당귀 | 3105H1AHM | | | 대추 | 3115H1AHM | | | 마황 | 3147H1AHM | | | 반하 | 3182H1AHM | | | 백출 | 3204H1AHM | | | 복령 | 3215H1AHM | | | 생강 | 3260H1AHM | | | 석고 | 3265H1AHM | | | 세신 | 3285H1AHM | | | 숙지황 | 3299H1AHM | | | 오미자 | 3342H1AHM | | | 인삼 | 3400H1AHM | | | 자소엽 | 3411H1AHM | | | 작약 | 3419H1AHM | | | 전호 | 3433H1AHM | | | 지각 | 3454H1AHM | | | 진피(陳皮) | 3466H1AHM | ⚠️ 秦皮와 구분 | | 천궁 | 3475H1AHM | | | 황기 | 3583H1AHM | | | 육계 | 3384H1AHM | | --- ## 5. 미등록 처방 목록 (93개) | # | 처방명 | 출전 | |---|--------|------| | 1 | 가미온담탕 | 의종금감 | | 4 | 강활유풍탕 | 의학발명 | | 5 | 계지가용골모려탕 | 금궤요략 | | 6 | 계지작약지모탕 | 금궤요략 | | 7 | 곽향정기산 | 화제국방 | | 8 | 구미강활탕 | 차사난지 | | 9 | 궁귀교애탕 | 금궤요략 | | 10 | 귀비탕 | 제생방 | | 11 | 귀출파징탕 | 동의보감 | | 12 | 금수육군전 | 경악전서 | | 13 | 녹용대보탕 | 갑병원류서촉 | | 14 | 당귀사역가오수유생강탕 | 상한론 | | 15 | 당귀수산 | 의학입문 | | 16 | 당귀육황탕 | 난실비장 | | 17 | 당귀작약산 | 금궤요략 | | 18 | 대강활탕 | 위생보감 | | 19 | 대건중탕 | 금궤요략 | | 20 | 대금음자 | 화제국방 | | 21 | 대방풍탕 | 화제국방 | | 22 | 대청룡탕 | 상한론 | | 23 | 대황목단피탕 | 금궤요략 | | 24 | 독활기생탕 | 천금방 | | 25 | 마행의감탕 | 금궤요략 | | 26 | 마황부자세신탕 | 상한론 | | 27 | 반하백출천마탕 | 의학심오 | | 28 | 반하사심탕 | 상한론 | | 29 | 반하후박탕 | 금궤요략 | | 30 | 방기황기탕 | 금궤요략 | | 31 | 방풍통성산 | 선명논방 | | 32 | 배농산급탕 | 춘림헌방함 | | 33 | 백출산 | 외대비요 | | 34 | 보생탕 | 부인양방 | | 35 | 보중익기탕 | 비위론 | | 36 | 복령음 | 외대비요 | | 37 | 분심기음 | 직지방 | | 39 | 사물탕 | 화제국방 | | 40 | 삼령백출산 | 화제국방 | | 42 | 삼출건비탕 | 동의보감 | | 43 | 삼환사심탕 | 금궤요략 | | 44 | 생혈윤부탕 | 의학정전 | | 45 | 세간명목탕 | 중보만병회춘 | | 46 | 소건중탕 | 상한론 | | 47 | 소시호탕 | 상한론 | | 48 | 소요산 | 화제국방 | | 49 | 소자강기탕 | 화제국방 | | 50 | 소적정원산 | 의학입문 | | 52 | 소풍산 | 외과정종 | | 53 | 소풍활혈탕 | 심씨존생서 | | 54 | 속명탕 | 금궤요략 | | 55 | 승마갈근탕 | 염씨소아방론 | | 56 | 시함탕 | 중정통속상한론 | | 57 | 시호계강탕 | 상한론 | | 58 | 시호억간탕 | 의학입문 | | 59 | 시호청간탕 | 구치유요 | | 62 | 안중산 | 화제국방 | | 63 | 양격산 | 화제국방 | | 64 | 연령고본단 | 만병회춘 | | 65 | 영감강미신하인탕 | 금궤요략 | | 66 | 영계출감탕 | 상한론 | | 67 | 오약순기산 | 화제국방 | | 68 | 오적산 | 화제국방 | | 69 | 온경탕 | 금궤요략 | | 70 | 온백원 | 화제금궤 | | 71 | 용담사간탕 | 의종금감 | | 73 | 위령탕 | 만병회춘 | | 74 | 육군자탕 | 부인양방 | | 75 | 육미지황환 | 소아약증직결 | | 76 | 육울탕 | 단계심법 | | 77 | 이기거풍산 | 고금의감 | | 78 | 이중환 | 상한론 | | 79 | 이진탕 | 화제국방 | | 80 | 인삼양영탕 | 화제국방 | | 81 | 인삼양위탕 | 화제국방 | | 82 | 인삼패독산 | 소아약증질결 | | 83 | 인진오령산 | 금궤요략 | | 84 | 자감초탕 | 상한론 | | 85 | 자음강화탕 | 만병회춘 | | 86 | 자음건비탕 | 만병회푼 | | 87 | 저령탕 | 상한론 | | 88 | 조경종옥탕 | 고금의감 | | 89 | 지황음자 | 선명논방 | | 90 | 진무탕 | 상한론 | | 91 | 청간해올탕 | 증치준승 | | 92 | 청금강화탕 | 고금의감 | | 93 | 청상방풍탕 | 만병회춘 | | 94 | 청서익기탕 | 비위론 | | 95 | 청심연자음 | 화제국방 | | 96 | 평위산 | 화제국방 | | 97 | 형계연교탕 | 일관당 | | 98 | 형방패독산 | 섭생중묘방 | | 99 | 황련아교탕 | 상한론 | | 100 | 황련해독탕 | 외대비요 | --- ## 6. Agent 실행 시 Python 코드 템플릿 ```python import sqlite3 DB_PATH = '/root/kdrug/database/kdrug.db' conn = sqlite3.connect(DB_PATH) c = conn.cursor() # === 대상 처방 === FORMULA_ID = 38 # official_formula_id HANJA = '四君子湯' DESCRIPTION = '보기건비 (補氣健脾)' REFERENCE = '화제국방 원방. 비기허로 인한 ...' # === Step 1: 기본 정보 업데이트 === c.execute('''UPDATE official_formulas SET formula_name_hanja = ?, description = ?, reference_notes = ?, updated_at = CURRENT_TIMESTAMP WHERE official_formula_id = ?''', (HANJA, DESCRIPTION, REFERENCE, FORMULA_ID)) # === Step 2: 구성 약재 등록 === # (official_formula_id, ingredient_code, grams_per_cheop, notes, sort_order) ingredients = [ (FORMULA_ID, '3400H1AHM', 4.0, '군약', 1), # 인삼 (FORMULA_ID, '3204H1AHM', 4.0, '신약', 2), # 백출 (FORMULA_ID, '3215H1AHM', 4.0, '좌약', 3), # 복령 (FORMULA_ID, '3007H1AHM', 2.0, '사약', 4), # 감초 ] for ing in ingredients: c.execute('''INSERT INTO official_formula_ingredients (official_formula_id, ingredient_code, grams_per_cheop, notes, sort_order) VALUES (?, ?, ?, ?, ?)''', ing) conn.commit() # === Step 3: 검증 === c.execute('''SELECT hm.herb_name, ofi.ingredient_code, ofi.grams_per_cheop, ofi.notes FROM official_formula_ingredients ofi JOIN herb_masters hm ON ofi.ingredient_code = hm.ingredient_code WHERE ofi.official_formula_id = ? ORDER BY ofi.sort_order''', (FORMULA_ID,)) total = 0 for r in c.fetchall(): total += r[2] print(f' {r[0]} ({r[1]}): {r[2]}g ({r[3]})') print(f' 1첩 총량: {total}g') conn.close() ``` --- ## 7. 주의사항 1. **ingredient_code는 반드시 herb_masters 테이블에 존재해야 한다** — JOIN이 실패하면 UI에 표시 안 됨 2. **한 처방에 같은 ingredient_code 중복 불가** — UNIQUE 제약 3. **기존 데이터 확인 후 INSERT** — 이미 등록된 처방에 중복 INSERT하면 에러 4. **출전(source_text)은 이미 seed 데이터로 들어가 있음** — UPDATE 불필요 5. **grams_per_cheop은 소수점 1자리까지** — 예: 4.0, 3.5, 2.0 6. **DB 경로**: `/root/kdrug/database/kdrug.db` --- *이 문서는 kdrug 시스템의 100처방 마스터 데이터 일괄 등록을 위해 작성되었습니다.* *최종 수정: 2026-02-18*