[이것도 AI로 될까? — 차 관리 편] 2부 — 사진을 AI에게 보내지 않기로 했다

[이것도 AI로 될까? — 차 관리 편] 2부 — 사진을 AI에게 보내지 않기로 했다
이번 편의 요청의 요지
사진을 외부 서비스에 보내지 않고도 필요한 값만 읽어 정비 기록으로 바꿔 줘.

AI에게 사진을 보내면 더 쉬웠다

1부에서 사진 한 장으로 정비 기록이 들어가게 만든 이야기를 썼다. 그때 AI에게 사진을 보내면 훨씬 간단하게 끝낼 수 있다는 방법도 함께 보였다. 그런데 그 구조에 이르기 전에 먼저 만들었다가 쓰지 않기로 한 것이 하나 있다.

처음 계획은 훨씬 단순했다. 텔레그램 봇을 하나 만들고, 명세서 사진을 그 방에 던지면, n8n이 사진을 받아 이미지를 읽을 수 있는 모델에게 보내고, 정리된 결과를 돌려받아 데이터베이스에 넣는다. 요즘 모델들은 이미지를 그대로 이해하니 글자를 읽는 규칙을 짤 필요조차 없다. 정규식도, 항목 사전도, 총액 고르는 순서도 필요 없다.

실제로 만들었다. 봇을 파고, 사진 받는 노드를 놓고, 모델에 보내고, 결과를 정리해 저장하는 흐름까지 다 짰다. 돌려 보지도 않고 멈춘 것은 아니다. 구조가 완성된 뒤에 껐다.

이유는 사진 그 자체에 있었다. AI가 편리한 답을 내놓았지만, 그 답을 그대로 쓰는지는 사람이 결정해야 했다.

정비명세서에는 차량번호와 연락처가 찍혀 있다

명세서를 다시 들여다봤다.

위쪽에 차량번호가 있다. 내 이름과 전화번호가 있다. 정비소의 상호와 주소와 사업자등록번호와 대표자 이름이 있다. 아래쪽에는 어떤 부품을 얼마에 갈았는지가 줄줄이 적혀 있다.

내가 필요한 것은 이 중 넷뿐이었다. 날짜, 주행거리, 항목, 총액. 나머지는 읽을 필요도 없는데 함께 넘어가는 것들이다.

그리고 이건 내 정보만 담긴 종이가 아니었다. 정비소의 정보도 함께 있다. 내가 동의할 수 있는 것은 내 몫뿐이다. 차량번호와 내 연락처는 내가 감수하겠다고 정할 수 있지만, 남의 사업자등록번호와 대표자 이름은 내가 정할 문제가 아니다.

사진 한 장을 보내는 것과 필요한 값 넷을 보내는 것은 전혀 다른 일이었다.

무료 티어의 약관을 읽어 보았다

그래도 편의를 생각하면 아까웠다. 그래서 약관을 읽었다.

무료로 제공되는 쪽에는 이렇게 적혀 있었다. 입력한 내용을 서비스 개선에 쓸 수 있고, 사람이 검토할 수도 있다. 같은 회사의 유료 요금제 약관에는 그렇게 하지 않는다고 따로 명시돼 있었다.

무료와 유료의 차이가 성능이나 한도가 아니라 내가 넣은 것을 어떻게 다루는가에 있었다. 공짜인 이유가 거기 적혀 있는 셈이다.

한도만 보면 무료로도 넉넉했다. 명세서는 한 달에 한두 장이다. 한도의 백분의 일도 안 쓴다. 그런데 그 한두 장에 차량번호와 연락처가 들어 있다.

결제를 붙이면 그 조항에서는 벗어난다. 그 방법도 생각해 봤다. 다만 그러고 나니 내가 왜 이걸 시작했는지를 다시 보게 됐다. 서랍의 종이 몇 장을 정리하겠다고 매달 돈을 내는 것이 맞나. 그리고 돈을 내더라도 사진은 여전히 남의 서버에 한 번 올라간다. 약관은 지금 그렇게 적혀 있을 뿐이고, 약관은 바뀐다.

만들어 둔 봇은 지우지 않고 껐다. 언젠가 판단이 바뀔 수도 있으니 구조는 남겨 두기로 했다.

집에 있는 것으로 해보기로 했다

집에 NAS가 있다. 사진과 문서를 넣어 두는 용도로 몇 년째 돌고 있다. 늘 켜져 있고, 이미 내 것들이 들어 있다. 여기서 글자를 읽으면 사진이 집 밖으로 나가지 않는다.

글자를 읽는 도구는 이미 여럿 공개돼 있다. 성능 비교표도 잘 정리돼 있다. 한글을 잘 읽는다는 것을 고르고, 설치해서 돌리면 된다. 그렇게 생각했다.

비교표에 없던 것이 하나 있었다. 그 도구가 내 CPU에서 도는가.

10년 전 CPU에는 AVX가 없었다

먼저 요즘 많이 쓰는 것을 설치했다. 명령을 치자 한 줄이 나왔다.

Illegal instruction

이게 전부였다. 오류 메시지도, 어디서 죽었는지도 없었다.

설정이 잘못됐나 싶어 다시 설치했다. 같은 줄이 나왔다. 다른 버전을 받아도 마찬가지였다.

원인은 CPU였다. 내 NAS는 DS918+이고 그 안에는 인텔 셀러론 J3455가 들어 있다. 2016년에 나온 저전력 칩이다. 이 세대에는 AVX라는 명령어 묶음이 없다. SSE4.2까지만 있다.

AVX는 여러 개의 숫자를 한 번에 계산하는 명령들이다. 기계학습에는 그런 계산이 많아서, 있으면 몇 배 빠르다. 그래서 요즘 도구들은 대개 AVX가 있다고 가정하고 미리 빌드된 파일을 배포한다. 소스를 직접 다시 빌드하면 될 수도 있지만, 그건 그것대로 며칠 걸리는 일이다.

없는 명령을 만나면 프로그램은 설명 없이 그 자리에서 멈춘다. Illegal instruction은 정확한 표현이었다. 이 CPU가 모르는 명령이 들어온 것이다. 오류 메시지가 불친절했던 게 아니라, 메시지를 만들 코드에 닿기도 전에 죽은 것이다.

AVX를 요구하지 않는 도구도 있었다. 그건 떴다. 대신 사진 한 장에 수십 초에서 몇 분이 걸렸다. 명세서를 찍고 결과를 기다리는 시간이라고 하기에는 길다. 정비소 앞에서 폰을 들고 1분을 서 있을 수는 없다.

장비가 할 수 있는 일과 내가 하려던 일 사이에 선이 그어졌다. 이 일이 있고 나서는 새 도구를 붙일 때 성능보다 먼저 그 선을 확인하게 됐다.

죽지 않고 도는 것을 찾았다

결국 Tesseract로 돌아갔다. 1985년에 시작해서 지금도 유지되는 물건이다. 순수한 C++로 쓰였고 특별한 명령어를 요구하지 않는다. 요즘 나오는 것들에 비하면 정확도가 떨어진다고 알려져 있다.

HTTP로 부를 수 있게 감싼 도커 이미지가 있어서 그걸 NAS 스택에 한 줄 추가했다. 포트는 밖으로 열지 않았다. 같은 도커 네트워크 안의 n8n만 부르면 되니 컨테이너 이름으로 접근한다.

한국어 데이터를 넣고 명세서를 넣었더니 작은 이미지 한 장을 1초 만에 읽었다. 정확도도 명세서 정도의 인쇄물에는 쓸 만했다.

한 가지 헷갈리는 것이 있었다. 실행할 때마다 오류 메시지가 함께 나왔다. 요청하지도 않은 번체 중국어 데이터를 열려다 실패하는 메시지였다. 처음에는 이것 때문에 실패한 줄 알았다. 그런데 종료 코드는 정상이고 한글은 제대로 읽혔다.

메시지가 나온다고 실패한 것이 아니었다. 그 뒤로는 오류 메시지가 아니라 종료 코드로 판정하게 고쳤다. 메시지만 보고 성공 여부를 정했다면 되는 것을 안 된다고 판단하고 다른 길을 찾아 헤맸을 것이다.

같은 도구인데 기계마다 다르게 읽었다

읽기는 읽는데 결과가 좀 이상했다. 같은 사진을 맥에서 돌렸을 때와 NAS에서 돌렸을 때의 출력이 달랐다.

맥    엔진오일 66000
NAS   엔 진 오 일 66000

한글 글자 사이에 공백이 들어갔다. 같은 도구, 같은 설정, 같은 사진인데 결과가 달랐다. 버전 차이인지 학습 데이터 차이인지는 끝까지 알아내지 못했다.

원인을 모르니 견디는 쪽으로 갔다. 읽어낸 글자에서 공백을 털어낸 다음에 항목 이름을 찾도록 규칙을 고쳤다.

여기에 함정이 하나 있다. 이 방어를 빼도 맥에서 돌리는 시험은 그대로 통과한다. 맥에서는 공백이 안 들어가니까. 깨지는 것은 NAS에서뿐이고, 거기서는 아무도 시험을 돌리지 않는다. 시험은 초록불인데 실제로 도는 곳에서만 깨지는 상황이 만들어진다.

그래서 NAS가 내놓은 그 이상한 출력을 시험 자료로 따로 넣어 뒀다. 실제로 겪은 형태를 그대로 남겨 두지 않으면, 나중에 누군가 "이 공백 제거는 왜 있지" 하고 지울 것이다. 그 누군가는 아마 나일 것이다.

더 성가신 것은 사진의 방향이었다. 명세서를 책상에 놓고 찍으면 종이가 눕는다. 이 도구는 방향을 알아서 잡아 주지 않았다. 방향을 추정하는 기능이 따로 있기는 한데, 실제 사진 두 장에서 신뢰도가 들쭉날쭉했다. 네 방향으로 돌려 가며 시도하는 방법도 있지만, 한 번에 5초에서 10초가 걸리는 장비에서 네 번이면 40초다.

결국 사진은 주머니 안에서 읽혔다

방향을 맞추는 방법을 찾다가 잠깐 멈췄다. 사진을 찍는 것도 폰이고, 결과를 보는 것도 폰이다. 그 사이에만 NAS가 끼어 있다.

아이폰에는 사진 속 글자를 읽는 기능이 이미 들어 있다. 사진 앱에서 글자를 손가락으로 끌어다 복사할 수 있는 Live Text다. 별도로 설치할 것도 없고, 사진이 기기 밖으로 나가지도 않는다. 나는 그 기능을 사람이 손으로 쓰는 것으로만 생각하고 있었다.

그런데 단축어에 같은 것을 부르는 동작이 있다. 그리고 그 아래에는 애플의 Vision 프레임워크가 있다.

확인은 폰이 아니라 맥에서 했다. Vision은 macOS에서도 부를 수 있어서, Swift로 스무 줄짜리 스크립트를 짜서 VNRecognizeTextRequest에 한국어와 영어를 지정하고 같은 사진 두 장을 넣었다.

두 장 다 정확히 읽었다. 날짜도 주행거리도 항목도 나왔다. HEIC를 변환할 필요도 없었고, 종이가 눕게 찍힌 사진도 그대로 읽었다. NAS에서 40초를 들여 해결하려던 방향 문제가 여기서는 문제가 아니었다.

찾던 답이 서버가 아니라 주머니에 있었다.

만든 것을 지우지 않고 남겨 뒀다

그러면 NAS에 올린 Tesseract는 헛수고였을까. 지우지 않고 남겨 뒀다.

텔레그램으로 사진을 보내는 경로가 따로 있다. 폰에서 단축어를 쓸 수 없는 상황이거나, 다른 기기에서 급히 넣어야 할 때를 위한 것이다. 그쪽에서는 여전히 NAS가 글자를 읽는다.

그 봇은 결국 처음 계획과 아주 다른 물건이 됐다. AI에게 사진을 보내는 대신, 버튼을 눌러 고르는 대화형으로 만들었다. 사진을 보내면 Tesseract가 읽어서 화면을 미리 채워 주지만, 못 읽어도 버튼으로 끝까지 갈 수 있다.

이 순서가 중요했다. 처음에는 사진을 주 경로로 두고 버튼을 예비로 둘 생각이었다. 그런데 그렇게 하면 읽기가 실패한 날에는 기록 자체를 못 한다. 그래서 뒤집었다. 버튼이 본체고 사진은 거들 뿐이다. 그 봇을 만들면서 겪은 일은 다음 편에서 따로 쓴다.

길이 하나뿐이면 그 길이 막혔을 때 기록 자체가 멈춘다. 읽기가 실패해도 기록은 남길 수 있어야 한다는 것이 이 시스템의 규칙이 됐다.

그리고 그 규칙이 실제로 한 번 지켜졌다. 단축어가 다섯 번 실패하는 동안에도 텔레그램 쪽은 멀쩡히 돌고 있었다.

느린 장비가 설계를 정했다

돌아보면 순서가 뒤바뀌어 있었다. 나는 "어디에 맡길까"부터 정하고 그다음에 방법을 찾고 있었다. 처음에는 남의 서버, 그다음에는 내 서버였다. 기기에서 하는 길은 끝에 가서야 보였다.

느린 장비가 아니었다면 첫 번째 도구가 그냥 돌았을 것이고, 나는 거기서 멈췄을 것이다. NAS가 사진을 받아 글자를 읽고 결과를 돌려주는 구조로 만들었을 것이다. 그것도 동작은 한다. 다만 사진이 한 번 더 이동하고, 서버가 꺼져 있으면 기록도 못 한다.

지금 구조에서는 사진이 기기를 떠나지 않는다. 글자만 떠난다. 그리고 그 글자에는 이미 필요한 것만 남아 있다.

제약이 답을 좁혀 준 셈이다. 할 수 없는 것이 명확하면 할 수 있는 것을 정확히 보게 된다. 요즘 도구를 다 쓸 수 있었다면 나는 아마 가장 편한 것을 골랐을 테고, 사진은 지금도 어딘가로 올라가고 있었을 것이다.

결과적으로 편해진 것은 AI를 덜 쓰게 된 것이 아니다. 사진은 폰 안에 남겨 두고, 필요한 글자만 다음 단계로 넘기게 됐다. 정비소에서 찍은 사진을 나중에 지워도 기록은 남고, 기록을 만들기 위해 개인정보 전체를 외부 서비스에 맡길 필요도 없어졌다.

AI에게 모든 일을 맡기는 대신, 어디까지 맡길지 내가 정하는 구조가 된 것이다. 생활 도구에서 편리함과 개인정보 보호가 부딪힐 때 무엇을 선택할지 알게 된 것도 이 편의 결과다.

다음 3부에서는 사진 자체가 실패하는 날을 다룬다. 읽기가 안 되더라도 기록이 멈추지 않게 하려면, AI가 알아서 이해하는 대화보다 사람이 고를 수 있는 버튼이 필요했다.


제작 기록

이 글의 초고 작성과 자료 정리, 그리고 글에 나오는 읽기 도구의 설치와 시험, 규칙 구현에는 Claude Code가 사용됐다. 시리즈의 제목·본문 윤문과 재구성, 게시용 이미지 편집과 Ghost 드래프트 반영에는 ChatGPT(Codex)가 함께했다. 공개 발행 전 전체 내용은 사람이 직접 검토하고 수정했다. 약관 내용은 확인 시점 기준이며 특정 서비스를 지목하지 않았다.