리피치
경력근거: 병원 처방 단계에서 의약품 안전사용 정보(DUR)를 실시간으로 점검하는 서비스입니다
※ 실제 산출물이 아닌 AI 예측 시안입니다.
공고가 만드는 제품을 두고 '병원 처방 단계에서 의약품 안전사용 정보(DUR)를 실시간으로 점검하는 서비스입니다' 라고 적었고, 그 구성으로 '의사용 웹(Next.js)' 을 먼저 들었습니다. 이 제품의 사용자는 처방을 내는 의사이고, 그 사람이 보는 자리에서 답이 떠야 값이 납니다. 이 포트폴리오는 그 화면을 공개된 기준표와 규칙으로 만듭니다. '외부 공공기관(심평원 등) 연동 구조를 설계 및 고도화합니다' 도 그 기준표가 어디서 오는지를 가리킵니다. 이 포트폴리오가 보여주는 것은 공개된 기준표를 데이터로 두고 처방과 맞춰 걸리는 줄을 띄우는 기술이며, 약물 상호작용의 임상적 판단이나 대체 약 제안은 주장하지도 하지도 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
'병원 처방 단계에서 의약품 안전사용 정보(DUR)를 실시간으로 점검하는 서비스입니다'. 이 편은 그 화면을 만듭니다.
'의사용 웹(Next.js)'. 터미널이 아니라 진료 화면 위에서 답이 보여야 합니다.
'실시간 처방 점검 시스템의 백엔드 도메인 모델과 외부 공공기관(심평원 등) 연동 구조를 설계'. 기준표가 그 연동으로 들어옵니다.
의사가 방금 입력한 처방을 공개된 안전사용 기준표와 맞춰 걸리는 줄을 화면에 띄웁니다. 기준표에 함께 쓰지 않는 조합과 나이 제한, 같은 성분 중복, 하루 용량 상한을 두고 처방 줄과 맞춰, 걸리는 것이 없으면 통과로 두고 걸리면 병용 금기·연령 금기·성분 중복·용량 초과 중 어느 쪽인지 사유로 묶어 보여줍니다. 기준표에 없는 약은 점검하지 못했다고 그대로 띄우고, 나이가 안 들어온 줄은 적용하지 못한 규칙을 함께 표시합니다. 처방과 환자 정보는 실 진료 자료 대신 지원자가 공개된 의약품 코드 규격으로 지어낸 것이며 실제 환자 정보를 쓰지 않습니다.
외래에서 처방을 입력하는 의사입니다. 터미널을 쓰지 않고 진료 화면만 보는 사람이라, 함께 쓰면 안 되는 조합을 약국에서 연락받고 나서야 알거나 이미 저장된 처방을 다시 부르던 자리에 있습니다.
공개된 안전사용 기준을 표로 두고 방금 입력한 처방 줄과 맞추면, 걸리는 줄이 저장 전에 화면에 뜨고 왜 걸렸는지가 근거로 함께 보인다는 가정입니다. 기준표에 없는 약은 점검하지 못했다고 드러나므로 모르는 것을 아는 것처럼 보여주지 않습니다.
처방 줄과 안전사용 기준표를 넣으면 줄마다 통과·걸림을 판정하고, 걸리면 병용 금기·연령 금기·성분 중복·용량 초과·미등록 중 어느 쪽인지 붙여 사유별로 묶어 보여주는 화면이 도는 완결품입니다. 카드를 펼치면 걸린 규칙과 근거 값이 나옵니다.
공개 코드 규격으로 만든 처방 800줄에 손으로 붙인 정답 판정과 대조해 일치율을 내고, 미등록이 몰리는 약을 모아 기준이 없는 자리를 목록으로 냅니다.
같은 성분이 여러 줄에 나뉘어 들어간 처방을 성분 기준으로 합쳐 하루 용량을 다시 세고, 한 줄씩 보면 안 걸리는데 합치면 넘는 경우를 따로 보여주는 단계입니다.
의사가 처방을 입력하면 줄마다 걸림 여부와 걸린 규칙이 사유별로 묶여 화면에 뜨는 과정을 시연합니다.
공개 코드 규격으로 지어낸 처방 800줄과 손으로 붙인 정답 판정을 대조해 일치율을 냅니다. 단, 정답과 처방을 모두 작성자가 만든 합성 기준이라 성능 검증이 아니라 데모 조건 동작입니다.
나이가 비었거나 성분이 안 적혔거나 기준표에 없는 약이 섞인 입력 30종을 넣어도 화면이 안 깨지고 사유별로 빠지는 비율을 보여줍니다.
성분 합산을 켰을 때 한 줄씩 보면 안 걸리던 처방이 몇 건 걸리는지 회귀로 확인합니다.
진짜 성능 검증은 여기서 멈춥니다. 위 수치는 작성자가 지어낸 처방의 자가채점이며, 실제 점검 정확도는 리피치가 연동하는 실 기준 데이터와 실 처방이 있어야 측정됩니다. 임상적 타당성은 이 포트폴리오가 다루지 않습니다.
수치는 합성 데이터 자가채점이라 성능 증명이 아니므로, 면접에서는 데모 동작과 실검증 준비 상태로 솔직히 설명합니다.
정답을 작성자가 붙였으니 잘 맞는 게 당연하므로, 나이 결측과 성분이 나뉜 처방, 기준표에 없는 약을 일부러 섞어 쉬운 줄만 푸는 함정을 피합니다.
이 포트폴리오가 보여주는 것은 공개된 기준표를 데이터로 두고 처방과 맞춰 걸리는 줄을 띄우는 기술이며, 약물 상호작용의 임상적 판단이나 대체 약 제안은 주장하지도 하지도 않습니다. 판정은 코드 대조와 수치 비교가 하고 LLM 은 의사가 읽을 사유 문장만 맡습니다.
기준표에 없는 약은 안전하다는 뜻이 아니라 점검하지 못했다는 뜻이라, 화면에 그 문구를 그대로 띄우고 통과와 다른 자리에 묶습니다.
실제 도입 때는 기준 데이터가 공공기관에서 주기적으로 갱신되므로, 표를 언제 받아 언제 반영할지 정하는 일을 도입 단계 과제로 둡니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
의사가 입력한 처방을 줄 단위로 편 것입니다. 줄 번호와 처방 번호, 환자 나이, 약 코드, 약 이름, 성분, 하루 용량, 투약 일수, 입력 시각을 한 행에 둡니다. 한 처방에 줄이 여럿이라 조합과 성분 중복은 같은 처방 안에서 갈립니다. 나이가 안 들어온 줄, 성분이 안 적힌 줄, 같은 성분이 두 줄에 나뉜 처방, 기준표에 없는 약을 일부러 섞어 두어 사유가 갈리게 둡니다. 모든 값은 지어낸 것이며 실제 환자 정보를 담지 않습니다.
| line_no | rx_no | patient_age | drug_code_raw | drug_name_raw | ingredient_raw | daily_dose_mg | days | prescribed_at |
|---|---|---|---|---|---|---|---|---|
| RX-001 | P-2001 | 52 | A11001 | 아목시실린캡슐 500mg | 아목시실린 | 1,500 | 5 | 2026-08-24T09:10:00 |
| RX-002 | P-2001 | 52 | B22010 | 이부프로펜정 200mg | 이부프로펜 | 600 | 5 | 2026-08-24T09:10:00 |
| RX-003 | P-2002 | 8 | C33005 | 독시사이클린정 100mg | 독시사이클린 | 200 | 7 | 2026-08-24T10:00:00 |
| RX-004 | P-2003 | 67 | D44002 | 와파린정 5mg | 와파린 | 5 | 30 | 2026-08-24T11:00:00 |
| RX-005 | P-2003 | 67 | B22010 | 이부프로펜정 200mg | 이부프로펜 | 800 | 5 | 2026-08-24T11:00:00 |
아래 JSON Schema 를 그대로 만족하는 처방 줄을 800개 더 만들어 주세요. 처방을 삼백 건쯤 두고 처방마다 줄을 하나에서 넷까지 붙이며, 약 코드는 영문 한 글자와 숫자 다섯 자리로 짓습니다. 나이를 3세에서 90세 사이로 흩어 놓고, 2할은 나이나 성분을 비웁니다. 몇 처방에는 같은 성분을 두 줄에 나눠 넣고, 몇 줄은 하루 용량을 상한보다 크게 두세요. 기준표에 없는 약 코드도 몇 줄 넣습니다. 실제 사람의 정보를 쓰지 말고 판정 결과도 넣지 마세요.
{"type": "object", "properties": {"line_no": {"type": "string"}, "rx_no": {"type": "string"}, "patient_age": {"type": ["integer", "null"]}, "drug_code_raw": {"type": "string"}, "drug_name_raw": {"type": "string"}, "ingredient_raw": {"type": ["string", "null"]}, "daily_dose_mg": {"type": ["number", "null"]}, "days": {"type": ["integer", "null"]}, "prescribed_at": {"type": "string"}}, "required": ["line_no", "rx_no", "patient_age", "drug_code_raw", "drug_name_raw", "ingredient_raw", "daily_dose_mg", "days", "prescribed_at"]}{"type": "object", "properties": {"line_no": {"type": "string"}, "rx_no": {"type": "string"}, "patient_age": {"type": ["integer", "null"]}, "drug_code_raw": {"type": "string"}, "drug_name_raw": {"type": "string"}, "ingredient_raw": {"type": ["string", "null"]}, "daily_dose_mg": {"type": ["number", "null"]}, "days": {"type": ["integer", "null"]}, "prescribed_at": {"type": "string"}}, "required": ["line_no", "rx_no", "patient_age", "drug_code_raw", "drug_name_raw", "ingredient_raw", "daily_dose_mg", "days", "prescribed_at"]}공개된 의약품 안전사용 기준을 표로 옮긴 것입니다. 규칙 번호와 종류, 약 코드 짝, 나이 하한·상한, 하루 용량 상한, 등급, 담당을 한 행에 둡니다. 종류마다 보는 항목이 달라 함께 쓰는 조합은 두 코드를, 나이 제한은 한 코드와 나이를, 용량 상한은 한 코드와 용량을 씁니다. 처방에 나오는 약 중 일부는 일부러 넣지 않아 미등록이 도출되게 둡니다.
| rule_no | kind_raw | code_a | code_b | min_age | max_age | max_daily_dose_mg | severity_raw | owner_name |
|---|---|---|---|---|---|---|---|---|
| DR-01 | co_ban | D44002 | B22010 | — | — | — | 금기 | 임상 |
| DR-02 | age_ban | C33005 | — | 12 | — | — | 금기 | 임상 |
| DR-03 | dup_ingredient | E55020 | E55021 | — | — | — | 주의 | 임상 |
| DR-04 | dose_limit | E55020 | — | — | — | 4,000 | 금기 | 임상 |
| DR-05 | dose_limit | B22010 | — | — | — | 1,200 | 주의 | 임상 |
아래 JSON Schema 를 그대로 만족하는 기준 행을 40개 더 만들어 주세요. 종류를 함께 쓰지 않는 조합·나이 제한·성분 중복·용량 상한으로 고루 섞고, 조합과 중복 규칙에는 두 번째 코드를 채우며 나이·용량 규칙에는 비웁니다. 등급을 금기와 주의로 나눕니다. 처방에 나오는 약 중 일부는 일부러 넣지 마세요 — 미등록이 있어야 점검하지 못한 자리가 드러납니다. 판정 결과는 넣지 마세요.
{"type": "object", "properties": {"rule_no": {"type": "string"}, "kind_raw": {"type": "string", "enum": ["co_ban", "age_ban", "dup_ingredient", "dose_limit"]}, "code_a": {"type": "string"}, "code_b": {"type": ["string", "null"]}, "min_age": {"type": ["integer", "null"]}, "max_age": {"type": ["integer", "null"]}, "max_daily_dose_mg": {"type": ["number", "null"]}, "severity_raw": {"type": "string", "enum": ["금기", "주의"]}, "owner_name": {"type": "string"}}, "required": ["rule_no", "kind_raw", "code_a", "code_b", "min_age", "max_age", "max_daily_dose_mg", "severity_raw", "owner_name"]}{"type": "object", "properties": {"rule_no": {"type": "string"}, "kind_raw": {"type": "string", "enum": ["co_ban", "age_ban", "dup_ingredient", "dose_limit"]}, "code_a": {"type": "string"}, "code_b": {"type": ["string", "null"]}, "min_age": {"type": ["integer", "null"]}, "max_age": {"type": ["integer", "null"]}, "max_daily_dose_mg": {"type": ["number", "null"]}, "severity_raw": {"type": "string", "enum": ["금기", "주의"]}, "owner_name": {"type": "string"}}, "required": ["rule_no", "kind_raw", "code_a", "code_b", "min_age", "max_age", "max_daily_dose_mg", "severity_raw", "owner_name"]}| TypeScript | 처방 줄과 기준표를 맞춰 조합·나이·용량을 견주는 판정기를 맡습니다. |
| Next.js | 의사가 보는 처방 점검 화면을 맡습니다. |
| NestJS | 처방을 받아 판정을 돌리고 결과를 화면에 넘기는 API 를 맡습니다. |
| PostgreSQL | 안전사용 기준표와 판정 결과를 담습니다. |
✗ fail → 미등록이 절반을 넘으면 기준표를 먼저 채웁니다.
✓ pass → 2주차 정답 대조로 넘어갑니다.
✗ fail → 어긋난 약을 모아 코드·성분 대응을 다시 봅니다.
✓ pass → 3주차 성분 합산으로 넘어갑니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
dur_code사유 라벨 · line_no + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
co_prescribe_ban병용 금기age_ban연령 금기dose_over용량 초과ingredient_duplicate성분 중복code_unmapped점검 못 함safe통과처방 줄 하나와 안전사용 기준이 만나는 자리마다 걸리는지 정합니다. 걸리면 병용 금기·연령 금기·성분 중복·용량 초과 중 어느 쪽인지, 조합이면 짝이 된 줄까지 싣습니다. 화면은 이 사유 코드로 묶습니다.
{"type": "object", "properties": {"check_no": {"type": "string"}, "line_no": {"type": "string"}, "rx_no": {"type": "string"}, "drug_code_raw": {"type": "string"}, "rule_no": {"type": ["string", "null"]}, "dur_code": {"type": "string", "enum": ["safe", "co_prescribe_ban", "age_ban", "ingredient_duplicate", "dose_over", "code_unmapped"]}, "peer_line_no": {"type": ["string", "null"]}, "severity_raw": {"type": ["string", "null"]}, "owner_name": {"type": ["string", "null"]}, "evidence": {"type": "array", "items": {"type": "object", "properties": {"field": {"type": "string"}, "agg": {"type": ["string", "null"]}, "value": {}}, "required": ["field", "value"]}}, "summary": {"type": "string"}, "hedge": {"type": ["string", "null"]}}, "required": ["check_no", "line_no", "rx_no", "drug_code_raw", "dur_code", "evidence", "summary"]}[
{
"check_no": "DC-001",
"line_no": "RX-001",
"rx_no": "P-2001",
"drug_code_raw": "A11001",
"rule_no": "DR-12",
"dur_code": "safe",
"peer_line_no": null,
"severity_raw": "주의",
"owner_name": "임상",
"evidence": [
{
"field": "daily_dose_mg",
"agg": null,
"value": 1500
},
{
"field": "max_daily_dose_mg",
"agg": null,
"value": 3000
}
],
"summary": "하루 용량이 상한 안이고 함께 처방한 약과 걸리는 규칙도 없습니다.",
"hedge": null
},
{
"check_no": "DC-002",
"line_no": "RX-005",
"rx_no": "P-2003",
"drug_code_raw": "B22010",
"rule_no": "DR-01",
"dur_code": "co_prescribe_ban",
"peer_line_no": "RX-004",
"severity_raw": "금기",
"owner_name": "임상",
"evidence": [
{
"field": "drug_code_raw",
"agg": null,
"value": "B22010"
},
{
"field": "code_a",
"agg": null,
"value": "D44002"
}
],
"summary": "같은 처방에 있는 와파린과 함께 쓰지 않도록 되어 있는 조합입니다.",
"hedge": null
},
{
"check_no": "DC-003",
"line_no": "RX-003",
"rx_no": "P-2002",
"drug_code_raw": "C33005",
"rule_no": "DR-02",
"dur_code": "age_ban",
"peer_line_no": null,
"severity_raw": "금기",
"owner_name": "임상",
"evidence": [
{
"field": "patient_age",
"agg": null,
"value": 8
},
{
"field": "min_age",
"agg": null,
"value": 12
}
],
"summary": "12세부터 쓰도록 되어 있는 약인데 환자가 8세입니다.",
"hedge": null
},
{
"check_no": "DC-004",
"line_no": "RX-007",
"rx_no": "P-2004",
"drug_code_raw": "E55021",
"rule_no": "DR-03",
"dur_code": "ingredient_duplicate",
"peer_line_no": "RX-006",
"severity_raw": "주의",
"owner_name": "임상",
"evidence": [
{
"field": "ingredient_raw",
"agg": null,
"value": "아세트아미노펜"
},
{
"field": "code_b",
"agg": null,
"value": "E55021"
}
],
"summary": "같은 성분이 감기약에도 들어 있어 합치면 하루 용량이 늘어납니다.",
"hedge": "두 줄을 합친 용량은 4500mg 으로 상한을 넘어 함께 봐야 합니다."
},
{
"check_no": "DC-005",
"line_no": "RX-008",
"rx_no": "P-2005",
"drug_code_raw": "E55020",
"rule_no": "DR-04",
"dur_code": "dose_over",
"peer_line_no": null,
"severity_raw": "금기",
"owner_name": "임상",
"evidence": [
{
"field": "daily_dose_mg",
"agg": null,
"value": 5000
},
{
"field": "max_daily_dose_mg",
"agg": null,
"value": 4000
}
],
"summary": "하루 5000mg 는 상한 4000mg 를 넘습니다.",
"hedge": null
},
{
"check_no": "DC-006",
"line_no": "RX-009",
"rx_no": "P-2006",
"drug_code_raw": "C33005",
"rule_no": "DR-02",
"dur_code": "safe",
"peer_line_no": null,
"severity_raw": "금기",
"owner_name": "임상",
"evidence": [
{
"field": "patient_age",
"agg": null,
"value": null
},
{
"field": "min_age",
"agg": null,
"value": 12
}
],
"summary": "나이가 안 들어와 연령 규칙을 적용하지 못했습니다. 화면에 그 사실을 함께 띄웁니다.",
"hedge": "나이를 채우면 판정이 바뀔 수 있어 확인 표시를 답니다."
},
{
"check_no": "DC-007",
"line_no": "RX-010",
"rx_no": "P-2007",
"drug_code_raw": "Z99999",
"rule_no": null,
"dur_code": "code_unmapped",
"peer_line_no": null,
"severity_raw": null,
"owner_name": null,
"evidence": [
{
"field": "drug_code_raw",
"agg": null,
"value": "Z99999"
},
{
"field": "rule_no",
"agg": "count",
"value": 12
}
],
"summary": "규칙 열두 행에 없는 코드라 점검하지 못했다고 화면에 그대로 띄웁니다.",
"hedge": null
},
{
"check_no": "DC-008",
"line_no": "RX-012",
"rx_no": "P-2008",
"drug_code_raw": "E55020",
"rule_no": "DR-04",
"dur_code": "safe",
"peer_line_no": null,
"severity_raw": "금기",
"owner_name": "임상",
"evidence": [
{
"field": "daily_dose_mg",
"agg": null,
"value": 2000
},
{
"field": "max_daily_dose_mg",
"agg": null,
"value": 4000
}
],
"summary": "용량이 상한 안이고 같은 처방의 다른 약과도 걸리는 규칙이 없습니다.",
"hedge": null
}
][자동 검증 · 코드가 판정합니다] 1. dur_code 가 enum 여섯 값 중 하나인지 확인합니다. 2. check_no·line_no·rx_no·drug_code_raw·dur_code·evidence·summary 가 모두 채워졌는지 확인합니다. 3. line_no 가 처방 줄에 실재하는 번호인지 대조합니다. 4. rule_no 가 있으면 기준표에 실재하는 행 번호인지 대조합니다. 5. rule_no 가 있으면 severity_raw·owner_name 이 그 규칙 행의 값과 같은지 대조합니다. 6. drug_code_raw 가 기준표의 어느 코드에도 없으면 dur_code 가 code_unmapped 인지 확인합니다. 7. dur_code 가 co_prescribe_ban 이면 peer_line_no 가 같은 rx_no 의 다른 줄이고 두 약 코드가 그 규칙의 코드 짝과 맞는지 대조합니다. 8. dur_code 가 age_ban 이면 patient_age 가 min_age 미만이거나 max_age 초과인지 다시 계산합니다. 9. dur_code 가 ingredient_duplicate 이면 같은 rx_no 안에 같은 ingredient_raw 가 두 줄 있는지 다시 셉니다. 10. dur_code 가 dose_over 이면 daily_dose_mg 가 max_daily_dose_mg 를 넘는지 다시 계산합니다. 11. patient_age 가 비어 있으면 연령 규칙을 적용하지 않고 그 사실을 hedge 에 남겼는지 확인합니다. 12. dur_code 가 safe 이면 그 줄에 걸리는 규칙이 하나도 없는지 다시 확인합니다. 13. summary 에 대체 약 이름이나 복용 지시가 들어 있지 않은지 확인합니다. 14. evidence 의 field 이름이 처방 줄과 기준표에 실재하는 컬럼인지 대조합니다. 15. agg 가 없는 evidence 의 value 가 그 컬럼에 수록된 행 값과 같은지 확인합니다. 16. summary 가 존댓말로 끝나는지 확인합니다. [평가 러너 · 2주차] 공개 코드 규격으로 지어낸 처방 800줄에 손으로 붙인 정답 판정과 대조해 일치율과 사유 코드별 분포를 내고, 미등록이 몰리는 약을 목록으로 냅니다. [수동 검증 · 사람이 봅니다] 1. 걸린 처방을 그대로 낼지 바꿀지는 의사가 정합니다. 이 화면은 정하지 않습니다. 2. 기준표에 없는 약을 언제 등록할지 임상 담당이 정합니다.