Insights·2026-09-11

필첵 OCR — 처방전 사진 한 장으로 약 목록 만들기

필첵 OCR은 QR이 없는 처방전이나 다른 약국에서 받은 약봉투를 사진으로 찍어 약 목록으로 바꾸는 필첵(PillCheck)의 등록 기능입니다. www.pillcheck.co.kr에 로그인한 뒤 화면 아래 「스캔」 메뉴의 처방전·약봉투 탭에서 씁니다. 문자 인식 AI가 사진 속 글자와 표를 읽고, 읽어 낸 약은 약품 데이터와 맞춰 알약 사진·약효 분류·복용법까지 함께 보여 줍니다. 처방전 사진은 문자 인식에만 쓰이고 서버에 저장하지 않습니다. 읽지 못한 줄은 지우거나 비슷한 약으로 채우지 않고 「모름」으로 남겨, 사용자가 직접 검색해 채우게 했습니다.

이어지는 글조제 단위로 읽는 복약안내 — 필첵은 봉투를 통째로 본다
필첵 OCR 화면 세 장 — 처방전 탭 촬영 화면, 약 목록 결과 화면, 「모름」 줄을 채우는 창
처방전 촬영 · 약 목록 · 못 읽은 줄 채우기. 화면 속 처방전은 이름과 번호를 전부 지어낸 합성본이다.

필첵 OCR은 무엇을 하는 기능인가

필첵은 내가 먹는 약의 효능·부작용·상호작용과 조제 이력을 한곳에서 보는 서비스입니다. 약을 기록하는 가장 빠른 길은 약봉투나 처방전의 QR을 비추는 것인데, QR이 인쇄되지 않은 처방전도 많고 다른 약국에서 받은 약봉투는 형식이 제각각입니다. 그 빈자리를 채우는 것이 사진 등록입니다.

OCR은 사진 속 글자를 읽어 컴퓨터가 다룰 수 있는 글자로 바꾸는 기술입니다. 필첵 OCR은 이 기술로 처방전과 약봉투의 약품 표를 읽어 약 목록을 만듭니다. 등록하기 화면은 처방전·약봉투·낱알 세 탭으로 나뉘어 있고, 사진 등록은 앞의 두 탭에 있습니다. 낱알 탭은 알약 사진으로 약을 알아보는 별도 기능입니다.

처방전 탭 아래쪽 회색 글씨가 이 기능의 약속입니다. 원문 그대로 옮기면 「본인의 처방전만 등록해 주세요. 사진은 문자 인식(Microsoft Azure · 한국 중부)에만 쓰이고 서버에 저장하지 않습니다. 문서에 인쇄된 이름·연락처는 저장하지 않습니다.」 이 약속을 코드가 어떻게 지키는지는 아래에서 설명합니다.

pillcheck.co.kr에서 쓰는 순서

앱을 설치하지 않아도 됩니다. 휴대폰 브라우저에서 www.pillcheck.co.kr을 열고 네 단계를 따르면 됩니다.

첫째, 로그인합니다. 사진 판독은 로그인한 사용자만 쓸 수 있습니다. 둘째, 화면 아래 메뉴에서 「스캔」을 누르면 등록하기 화면이 열립니다. 셋째, 손에 든 문서에 맞춰 「처방전」 또는 「약봉투」 탭을 고릅니다. 넷째, 「처방전 사진으로 등록」을 눌러 찍습니다. 약봉투 탭에서는 같은 자리의 버튼이 「약봉투 사진으로 등록」입니다.

약봉투는 약 이름과 복용법 표가 잘 보이게 평평하게 두고 찍는 것이 요령입니다. 문서에 QR이 있다면 사진보다 QR이 빠릅니다. 같은 화면의 사각형 안에 QR을 맞추면 자동으로 인식됩니다.

전 과정을 1분 남짓한 사용법 영상으로도 정리했습니다. https://youtu.be/q5hYerY6ZO0

찍은 뒤에 무슨 일이 일어나는가

필첵 등록하기 화면 두 장 — 왼쪽은 처방전 탭 카메라에 약품 표가 비치고 아래에 개인정보 고지와 「처방전 사진으로 등록」 버튼이 있는 화면, 오른쪽은 「처방전을 읽고 있어요 · 보통 9초쯤 걸려요 · 0초 지남 · 예상 9초」가 뜬 판독 중 화면.
처방전 탭과 판독 중 화면. 카메라에 비친 처방전은 이름과 번호를 전부 지어낸 합성본이다.

사진은 곧바로 서버로 가지 않습니다. 휴대폰이 먼저 사진을 검사합니다. 너무 작거나, 너무 어둡거나 밝거나, 흔들려 흐리면 그 자리에서 다시 찍어 달라고 합니다. 읽을 수 없는 사진은 보내 봐야 틀리거나 빈 결과로 돌아올 뿐이기 때문입니다.

검사를 통과한 처방전 사진은 크기를 줄여 서버로 가고, 서버는 마이크로소프트의 문자 인식 AI인 Azure Document Intelligence에 넘깁니다. 이 AI는 글자만 읽는 것이 아니라 표의 칸 구조까지 읽어서, 어느 숫자가 몇 번째 약의 투약량인지 가려냅니다. 판독의 신뢰도가 낮으면 서버는 값을 하나도 돌려주지 않고 다시 찍어 달라고만 답합니다. 틀린 값이 읽힌 값처럼 보이지 않게 하려는 설계입니다.

약 이름은 사진에서 베끼지 않습니다. 처방전에는 약마다 EDI 코드가 인쇄돼 있습니다. 건강보험에서 약마다 붙인 9자리 번호입니다. 필첵은 이 번호를 읽어 약품 데이터베이스에서 정식 이름을 찾아 붙이고, 같은 자리에서 알약 사진과 약효 분류, 복약 안내도 가져옵니다. 흐릿하게 인쇄된 약 이름을 글자 그대로 옮기는 것보다 번호로 찾는 편이 이름이 틀어질 여지가 적습니다.

약봉투는 한 단계가 더 있습니다. 약봉투에는 이 번호가 인쇄돼 있지 않아서, 문자 인식이 읽어 낸 글을 언어 모델이 한 번 더 정리해 약 이름과 복용 숫자를 뽑습니다. 언어 모델은 ChatGPT처럼 문장을 이해하고 정리하는 AI입니다. 이 모델에 준 지시문의 핵심 문장은 이렇습니다. 「읽을 수 없으면 null 이다. 비슷한 약 이름으로 바꾸거나 완성하지 마라. 글자를 만들어 내는 것은 빠뜨리는 것보다 나쁘다.」 여기서 null은 '값 없음'이라는 뜻입니다.

기다리는 동안 화면은 지금 무엇을 하는지와 얼마나 걸리는지를 알려 줍니다. 처방전은 「보통 9초쯤 걸려요」라고 적고 지난 시간을 셉니다. 예상보다 한참 길어지면 숫자를 거두고 「조금 더 걸리고 있어요」로 문구를 바꿉니다. 지킬 수 없는 숫자를 계속 보여 주지 않기 위해서입니다.

읽지 못한 줄은 「모름」으로 남긴다

판독 결과와 채우기 창 — 왼쪽은 처방 약품 5개 중 네 줄에 약 이름·알약 사진·복용법·약효 분류가 붙고 마지막 줄이 「모름 · 어떤 약인지 알려주세요」와 「채우기」 버튼으로 남은 화면, 오른쪽은 「어떤 약인지 알려주세요」 창에 약 이름 검색칸과 「이 약을 기록에서 지우기」·「닫기」 버튼이 있는 화면.
결과 화면과 「모름」 줄의 채우기 창.

결과 화면에는 읽어 낸 약이 목록으로 들어옵니다. 이름 옆에 알약 사진과 약효 분류가 붙고, 아래 줄에 1회 투약량·횟수·일수와 복용법이 적힙니다.

그런데 OCR은 모든 줄을 읽지 못합니다. 구겨진 종이, 번진 잉크, 비스듬한 각도가 늘 있습니다. 이때 쉬운 길은 둘입니다. 못 읽은 줄을 조용히 지우거나, 가장 비슷한 약으로 채우는 것입니다. 필첵은 둘 다 하지 않습니다. 약 기록에서 한 줄이 사라지면 상호작용 확인에서 그 약이 빠지고, 비슷한 이름의 다른 약이 들어가면 틀린 약으로 안내하게 되기 때문입니다.

그래서 읽지 못한 줄은 「모름」이라는 자리로 남습니다. 몇 번째 줄이 비었는지가 기록에 그대로 남고, 사용자가 「채우기」를 누르면 약 이름을 검색해 고르거나 그 줄을 기록에서 지울 수 있습니다. 약을 바꾸는 방법은 검색해서 고르는 것 하나뿐입니다. 이름을 자유롭게 타이핑하게 두면 약품 데이터와 이어지지 않는 기록이 생기기 때문입니다. 1회 투약량·횟수·일수는 직접 고칠 수 있습니다.

약봉투 지시문의 「글자를 만들어 내는 것은 빠뜨리는 것보다 나쁘다」와 같은 원칙입니다. 약 기록에서는 모르는 것을 모른다고 표시하는 쪽이 아는 척하는 쪽보다 안전합니다.

개인정보는 어떻게 피해 갔나

처방전 한 장에는 환자 이름, 주민등록번호, 의료기관과 연락처가 함께 인쇄돼 있습니다. 필첵에 필요한 것은 그중 약품 표입니다. 그렇다고 사진에서 필요한 부분만 골라 보낼 수는 없어서, 사진은 서버와 문자 인식 서비스를 지나갑니다. 이 사실은 숨기지 않고 화면 고지에 적었습니다. 대신 설계의 목표를 '남기지 않는 것'에 두었습니다.

남기지 않는 장치는 세 겹입니다. 첫째, 필첵 서버는 사진을 저장하지 않습니다. 판독이 끝나면 약 목록으로 옮길 값만 남습니다. 둘째, 서버가 휴대폰에 돌려주는 판독 결과에는 환자 이름·주민등록번호·전화번호를 담을 칸이 처음부터 없습니다. 칸이 없으니 실수로 담길 자리도 없습니다. 그 위에 결과를 내보내기 직전 주민등록번호나 전화번호 모양의 글자가 섞였는지 한 번 더 검사합니다. 셋째, 서버 기록에는 몇 줄을 읽었는지 같은 개수만 남기고 읽은 내용은 남기지 않습니다.

고지 문구 자체도 코드로 묶었습니다. 고지의 핵심 문장은 자동 테스트가 지키고 있어서, 그 문장이 빠지거나 바뀌면 테스트가 먼저 알립니다. 약속한 문장과 실제 동작이 아무도 모르게 달라지는 일을 막으려는 것입니다.

「본인의 처방전만 등록해 주세요」라는 첫 문장도 의도한 것입니다. 가족의 처방전을 찍어 보라고 권하는 문구는 일부러 두지 않았습니다. 기록의 주인이 모르는 기록을 만들지 않기 위해서입니다. 약봉투 탭은 처리 단계가 하나 더 있는 만큼 고지 문구도 따로 두었고, 찍기 전에 같은 자리에서 확인할 수 있습니다.

시험 데이터는 지어낸 처방전과 가린 처방전

OCR을 만들려면 처방전이 많이 필요합니다. 읽고, 채점하고, 고치고, 다시 읽어야 하기 때문입니다. 여기에 실제 처방전을 그대로 쓰면 개발 과정 자체가 개인정보를 돌리는 일이 됩니다. 그래서 재료를 두 가지로 제한했습니다.

첫째는 합성 처방전입니다. 합성 데이터는 실제를 본떠 새로 지어낸 데이터를 말합니다. 처방전 서식 네 가지에 환자·의사·의료기관·연락처·번호를 전부 지어내 넣었고, 약품 칸에만 실제 약 목록을 썼습니다. 주민등록번호는 마지막 검증 숫자를 일부러 틀리게 만들어, 우연으로라도 실존하는 번호와 겹칠 수 없게 했습니다. 깨끗한 원본 외에 휴대폰으로 찍은 것처럼 조금 줄이고 기울이고 흐리게 만든 판도 함께 만들었습니다. 이 글의 화면과 사용법 영상에 비친 처방전이 이 합성본입니다.

둘째는 가린 실물입니다. 실제 문서는 약품 표만 남기고 나머지를 전부 검게 가린 것만 썼습니다. 요점은 가리는 기준을 '지울 곳'이 아니라 '남길 곳'으로 정한 데 있습니다. 표의 머리글을 기준으로 표 영역만 남기고, 머리글을 찾지 못하면 파일 자체를 만들지 않습니다. 실패해도 덜 가려진 문서가 새어 나올 길이 없습니다. 자동 검사를 통과한 뒤에도 사람이 한 장씩 다시 봤습니다.

만드는 과정에서 AI를 어떻게 썼나

필첵 OCR은 AI 코딩 에이전트와 함께 만들었습니다. AI 코딩 에이전트는 사람의 지시를 받아 코드를 직접 읽고 고치고 실행해 보는 AI입니다. 여기서는 Claude Code를 썼고, OCR 관련 코드 변경 기록 대부분에 이 에이전트가 공동 작성자로 올라 있습니다.

다만 AI에게 맡기지 않은 것이 있습니다. 무엇을 합격으로 볼지의 기준입니다. AI가 낸 결과를 세 가지 방식으로 묶었습니다.

하나, 합격선을 먼저 적었습니다. 채점하기 전에 '이 정도는 맞아야 한다'는 기준값을 파일로 적어 저장해 두고, 기준을 적은 시점이 채점보다 늦으면 그 점수는 무효로 처리합니다. 결과를 본 뒤 합격선을 슬쩍 옮기는 일을 사람도 AI도 할 수 없게 만든 것입니다.

둘, 일부러 망가뜨려 봤습니다. 테스트가 정말 지켜 주는지 확인하려고 코드의 핵심 연결을 일부러 끊은 판을 만들고, 테스트가 실패를 알리는지 봅니다. 이것을 뮤테이션 테스트라고 합니다. 예를 들어 「모름」 줄을 검색으로 채웠는데 그 약의 식별 번호가 기록되지 않도록 망가뜨리면 반드시 실패해야 하는 테스트가 있습니다.

셋, 다른 AI에게 반대편을 맡겼습니다. 기획서는 계획·설계·비판 역할을 나눈 AI들이 합의할 때까지 다듬었고, 구현은 다른 회사의 AI 모델에게 흠을 찾으라고 따로 검토시켰습니다. 같은 모델이 쓰고 같은 모델이 검토하면 같은 곳을 못 보기 때문입니다.

AI 에이전트가 개인정보를 보지 않게 하는 것도 같은 원칙입니다. 실물 문서를 가리는 작업의 문자 인식은 외부 서비스가 아니라 작업하는 컴퓨터 안에서 돌렸고, 에이전트에게는 가려진 결과만 넘겼습니다. 가리기 전의 글자는 에이전트의 대화창에 들어가지 않았습니다.

사용법 영상도 같은 원칙으로 만들었다

1분 남짓한 사용법 영상도 AI로 만들었습니다. 화면은 자동으로 조작하는 브라우저로 실제 운영 중인 www.pillcheck.co.kr에서 찍었고, 내레이션은 AI 음성으로 합성했고, 장면은 코드로 조립했습니다.

카메라에 비친 처방전은 앞에서 말한 합성본입니다. 판독 결과를 얻으려고 실제 계정으로 로그인해 판독을 돌리지도 않았습니다. 판독 요청 하나만 합성 처방전의 정답표로 만든 응답을 대신 돌려주게 하고, 알약 사진·약효 분류·검색 결과 같은 나머지 화면은 운영 중인 서비스의 실제 값을 그대로 받았습니다. 정답표는 합성할 때 함께 적어 둔 그 처방전의 내용입니다. 그래서 영상을 만들면서 판독 비용이 들지도, 누군가의 계정에 기록이 남지도 않았습니다.

영상은 여기서 볼 수 있습니다. https://youtu.be/q5hYerY6ZO0

개인정보가 걸린 AI 기능을 만들 때 가져갈 것

필첵 OCR에서 쓴 방법 중 다른 업무에도 옮길 수 있는 것은 셋입니다.

첫째, 보내는 것과 남기는 것을 나눠서 약속합니다. 사진을 보내야 기능이 돌아간다면 보낸다고 적고, 대신 무엇을 남기지 않는지를 구체적으로 적습니다. '안전하게 처리합니다' 같은 문장은 약속이 아닙니다.

둘째, 시험 데이터는 지어낸 것부터 씁니다. AI에게 실제 고객 문서를 붙여 넣기 전에, 같은 서식에 가짜 값을 채운 문서로 먼저 돌려 보십시오. 합성본으로 확인할 수 있는 것은 합성본에서 끝냅니다.

셋째, 모르는 것을 모른다고 표시할 자리를 만듭니다. AI가 빈칸을 그럴듯하게 채우면 편해 보이지만, 약·돈·계약처럼 틀리면 곤란한 일에서는 비어 있다고 알려 주는 쪽이 낫습니다. 오늘 AI에게 문서 정리를 맡긴다면 지시문에 한 줄을 넣어 보십시오. 「읽을 수 없으면 비워 두고, 비슷한 값으로 채우지 마라.」